From f828f86e290f1a359c8b73a49337534ac3eb7cb3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 27 Jan 2022 12:10:00 +0300 Subject: [PATCH 001/112] Replace light model for 3ds --- CHANGELOG.md | 2 + build.gradle.kts | 2 +- .../src/main/kotlin/JsPlaygroundApp.kt | 7 +- .../src/main/kotlin/gravityDemo.kt | 12 ++- .../mipt/npm/muon/monitor/MMAppComponent.kt | 7 +- .../kscience/visionforge/solid/demo/demo.kt | 7 +- .../tutorial-solids.md} | 54 ++++++------- .../ThreeViewWithControls.kt | 4 + .../visionforge/solid/OrbitControls.kt | 2 +- .../kscience/visionforge/solid/LightSource.kt | 44 +++++++++++ .../kscience/visionforge/solid/SolidGroup.kt | 4 +- .../visionforge/solid/SolidMaterial.kt | 21 ++++- .../kscience/visionforge/solid/Solids.kt | 3 + .../specifications/{Axes.kt => AxesScheme.kt} | 10 +-- .../{Camera.kt => CameraScheme.kt} | 18 ++--- .../solid/specifications/Canvas3DOptions.kt | 69 +++++++--------- .../{Controls.kt => ControlsScheme.kt} | 4 +- .../visionforge/solid/specifications/Light.kt | 8 -- .../solid/specifications/PointScheme.kt | 19 +++++ .../visionforge/solid/SerializationTest.kt | 15 ++++ .../solid/three/MeshThreeFactory.kt | 2 + .../solid/three/ThreeAmbientLightFactory.kt | 19 +++++ .../visionforge/solid/three/ThreeCanvas.kt | 49 +++++++----- .../visionforge/solid/three/ThreeFactory.kt | 3 +- .../visionforge/solid/three/ThreeMaterials.kt | 78 ++++++++++++------- .../visionforge/solid/three/ThreePlugin.kt | 6 +- .../solid/three/ThreePointLightFactory.kt | 28 +++++++ 27 files changed, 340 insertions(+), 157 deletions(-) rename docs/{tutorial.md => tutorials/tutorial-solids.md} (91%) create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt rename visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/{Axes.kt => AxesScheme.kt} (79%) rename visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/{Camera.kt => CameraScheme.kt} (77%) rename visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/{Controls.kt => ControlsScheme.kt} (56%) delete mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Light.kt create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/PointScheme.kt create mode 100644 visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt create mode 100644 visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ffcb3c9..d2cf0882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Added ### Changed +- Naming of Canvas3D options +- Lights are added to the scene instead of 3D options ### Deprecated diff --git a/build.gradle.kts b/build.gradle.kts index 0f892c76..0cd9f7da 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ val fxVersion by extra("11") allprojects{ group = "space.kscience" - version = "0.2.0" + version = "0.2.1-dev-1" } subprojects { diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index a1ffa4ff..5e09911b 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -1,6 +1,5 @@ import kotlinx.browser.document import kotlinx.css.* -import react.child import react.dom.render import ringui.SmartTabs import ringui.Tab @@ -8,6 +7,7 @@ import space.kscience.dataforge.context.Context import space.kscience.plotly.models.Trace import space.kscience.plotly.scatter import space.kscience.visionforge.Application +import space.kscience.visionforge.Colors import space.kscience.visionforge.VisionClient import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.ring.ThreeCanvasWithControls @@ -48,7 +48,7 @@ private class JsPlaygroundApp : Application { } SmartTabs("gravity") { Tab("gravity") { - GravityDemo{ + GravityDemo { attrs { this.context = playgroundContext } @@ -73,6 +73,9 @@ private class JsPlaygroundApp : Application { attrs { context = playgroundContext solid { + ambientLight { + color(Colors.white) + } repeat(100) { sphere(5, name = "sphere[$it]") { x = random.nextDouble(-300.0, 300.0) diff --git a/demo/js-playground/src/main/kotlin/gravityDemo.kt b/demo/js-playground/src/main/kotlin/gravityDemo.kt index 716cc2c3..4d420cc7 100644 --- a/demo/js-playground/src/main/kotlin/gravityDemo.kt +++ b/demo/js-playground/src/main/kotlin/gravityDemo.kt @@ -7,6 +7,7 @@ import react.fc import space.kscience.dataforge.context.Context import space.kscience.plotly.layout import space.kscience.plotly.models.Trace +import space.kscience.visionforge.Colors import space.kscience.visionforge.markup.VisionOfMarkup import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls @@ -21,10 +22,10 @@ external interface DemoProps : Props { } val GravityDemo = fc { props -> - val velocityTrace = Trace{ + val velocityTrace = Trace { name = "velocity" } - val energyTrace = Trace{ + val energyTrace = Trace { name = "energy" } val markup = VisionOfMarkup() @@ -41,6 +42,11 @@ val GravityDemo = fc { props -> attrs { context = props.context solid { + pointLight(200, 200, 200, name = "light"){ + color(Colors.white) + } + ambientLight() + sphere(5.0, "ball") { detail = 16 color("red") @@ -91,7 +97,7 @@ val GravityDemo = fc { props -> height = 50.vh - 50.pt } plotly { - traces(velocityTrace,energyTrace) + traces(velocityTrace, energyTrace) layout { xaxis.title = "time" } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index 558317cb..350d25f3 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -17,12 +17,13 @@ import react.fc import react.useMemo import react.useState import space.kscience.dataforge.context.Context +import space.kscience.dataforge.meta.invoke import space.kscience.dataforge.names.Name import space.kscience.visionforge.react.flexColumn import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.tab -import space.kscience.visionforge.solid.specifications.Camera +import space.kscience.visionforge.solid.ambientLight import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.edges import styled.css @@ -42,17 +43,19 @@ val MMApp = fc("Muon monitor") { props -> val mmOptions = useMemo { Canvas3DOptions { - camera = Camera { + camera { distance = 2100.0 latitude = PI / 6 azimuth = PI + PI / 6 } + } } val root = useMemo(props.model) { props.model.root.apply { edges() + ambientLight() } } diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index a0ab9273..5631de56 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -18,7 +18,11 @@ fun VisionLayout.demo(name: String, title: String = name, block: SolidGro val meta = Meta { "title" put title } - val vision = SolidGroup(block) + val vision = SolidGroup(block).apply { + ambientLight{ + color(Colors.white) + } + } render(Name.parse(name), vision, meta) } @@ -39,6 +43,7 @@ val canvasOptions = Canvas3DOptions { @OptIn(DelicateCoroutinesApi::class) fun VisionLayout.showcase() { demo("shapes", "Basic shapes") { + ambientLight() box(100.0, 100.0, 100.0) { z = -110.0 color("teal") diff --git a/docs/tutorial.md b/docs/tutorials/tutorial-solids.md similarity index 91% rename from docs/tutorial.md rename to docs/tutorials/tutorial-solids.md index 8989bd49..2b1e7b57 100644 --- a/docs/tutorial.md +++ b/docs/tutorials/tutorial-solids.md @@ -59,7 +59,7 @@ box(10, 10, 10, name = "small box"){ rotation = Point3D(0, 0, 0) } ``` -![](../docs/images/small-box.png) +![](../images/small-box.png) The `big box` will have properties with custom values. ```kotlin @@ -72,7 +72,7 @@ box(40, 40, 40, name = "big box"){ rotation = Point3D(60, 80, 0) } ``` -![](../docs/images/big-rotated-box.png) +![](../images/big-rotated-box.png) If we compare these boxes, we will see all differences. Here is the function `main` with both boxes. @@ -111,8 +111,8 @@ fun main(){ } } ``` -![](../docs/images/two-boxes-1.png) -![](../docs/images/two-boxes-2.png) +![](../images/two-boxes-1.png) +![](../images/two-boxes-2.png) ***There is plenty of other properties, especially those, which you can create by yourself. Here we mention just a small part.*** @@ -142,8 +142,8 @@ polyline(Point3D(30, 20, 10), Point3D(30, -100, 30), Point3D(30, -100, 30), Poin } ``` -![](../docs/images/polyline-points.png) -![](../docs/images/polyline-points-2.png) +![](../images/polyline-points.png) +![](../images/polyline-points-2.png) ### 2) Box @@ -165,7 +165,7 @@ Let's create just usual `box` with equal ribs. color("pink") } ``` - ![](../docs/images/box.png) + ![](../images/box.png) Now, let's make `box` with bigger `y` value. ```kotlin @@ -175,7 +175,7 @@ Now, let's make `box` with bigger `y` value. ``` As you can see, only the rib of `y-axis` differs from other ribs. - ![](../docs/images/high-box.png) + ![](../images/high-box.png) For a final trial, let's create a `box` with a bigger `x` value. @@ -189,7 +189,7 @@ For a final trial, let's create a `box` with a bigger `x` value. ``` Predictably, only the `x-axis` rib is bigger than other ribs. - ![](../docs/images/wide-box.png) + ![](../images/wide-box.png) ### 3) Sphere @@ -206,7 +206,7 @@ As for `radius`, it has `Float` type, and, as you can guess, it sets the radius color("blue") } ``` - ![](../docs/images/sphere.png) + ![](../images/sphere.png) ### 4) Hexagon @@ -220,7 +220,7 @@ It is solid which has six edges. It is set by eight values: `node1`,..., `node8` 5) Edge with vertices `node1`, `node5`, `node8`, `node4` 6) Edge with vertices `node8`, `node5`, `node6`, `node7` -![](../docs/images/scheme.png) +![](../images/scheme.png) As the hexagon takes in specific points, we understand that this solid cannot be moved, it is fixed in space, and it can't make pivots. @@ -239,7 +239,7 @@ Let's make classic parallelepiped. color("green") } ``` - ![](../docs/images/classic-hexagon.png) + ![](../images/classic-hexagon.png) Now, let's make a custom hexagon. @@ -258,7 +258,7 @@ hexagon( color("brown") } ``` - ![](../docs/images/custom-hexagon.png) + ![](../images/custom-hexagon.png) ### 3) Cone It takes in six values: `bottomRadius`, `height`, `upperRadius`, `startAngle`, `angle`, and `name`. @@ -274,8 +274,8 @@ Let's build a classic cone: color("beige") } ``` - ![](../docs/images/cone-1.png) - ![](../docs/images/cone-2.png) + ![](../images/cone-1.png) + ![](../images/cone-2.png) First of all, we have to try to build a frustum cone: ```kotlin @@ -283,7 +283,7 @@ cone(60, 80, name = "cone") { color(0u, 40u, 0u) } ``` -![](../docs/images/frustum-cone.png) +![](../images/frustum-cone.png) Now, we need to make a try to build a cone segment: @@ -292,8 +292,8 @@ cone(60, 80, angle = PI, name = "cone") { color(0u, 0u, 200u) } ``` -![](../docs/images/cone-segment-1.png) -![](../docs/images/cone-segment-2.png) +![](../images/cone-segment-1.png) +![](../images/cone-segment-2.png) Finally, the segment of frustum cone is left for a try: ```kotlin @@ -301,7 +301,7 @@ cone(60, 100, 20, PI*3/4, angle = PI/3, name = "cone") { color(190u, 0u, 0u) } ``` -![](../docs/images/frustum-cone-segment.png) +![](../images/frustum-cone-segment.png) ### 4) Cone Surface This solid is set by seven values:`bottomOuterRadius`, `bottomInnerRadius`, `height`, `topOuterRadius`, `topInnerRadius`, `startAngle`, and `angle`. @@ -318,8 +318,8 @@ Let's build usual cone surface with almost all properties set: rotation = Point3D(2, 50, -9) } ``` -![](../docs/images/cone-surface-1.png) -![](../docs/images/cone-surface-2.png) +![](../images/cone-surface-1.png) +![](../images/cone-surface-2.png) Now, let's create a cone surface and set all it's properties: @@ -329,8 +329,8 @@ coneSurface(30, 25, 10, 10, 8,0f, pi*3/4, name = "cone surface") { rotation = Point3D(2, 50, -9) } ``` -![](../docs/images/cone-surface-fragment.png) -![](../docs/images/cone-surface-fragment-2.png) +![](../images/cone-surface-fragment.png) +![](../images/cone-surface-fragment-2.png) ### 5) Cylinder @@ -344,8 +344,8 @@ cylinder(40, 100, "cylinder"){ color("indigo") } ``` -![](../docs/images/cylinder-1.png) -![](../docs/images/cylinder-2.png) +![](../images/cylinder-1.png) +![](../images/cylinder-2.png) ### 6) Tube `tube` takes in `radius`, `height`, `innerRadius`, `startAngle`, `angle`, and `name`. *All values are familiar from `cone`, and `coneSurface` solids.* @@ -356,7 +356,7 @@ tube(50, 40, 20, name = "usual tube"){ opacity = 0.4 } ``` -![](../docs/images/tube.png) +![](../images/tube.png) This is an example of tube fragment: @@ -365,7 +365,7 @@ tube(50, 40, 20, 0f, PI, name = "fragmented tube"){ color("white") } ``` -![](../docs/images/tube-fragment.png) +![](../images/tube-fragment.png) ### 7) Extruded `extruded` is set by two values: `shape`, and `layer`. diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index 5cdcf5c0..fa3fab99 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -38,6 +38,10 @@ public fun ThreeCanvasWithControlsProps.solid(block: SolidGroup.() -> Unit) { } } +public fun ThreeCanvasWithControlsProps.options(block: Canvas3DOptions.() -> Unit){ + options = Canvas3DOptions(block) +} + public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.() -> Unit) { additionalTabs = (additionalTabs ?: emptyMap()) + (title to block) } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/OrbitControls.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/OrbitControls.kt index 2fe573e0..9c4ab664 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/OrbitControls.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/OrbitControls.kt @@ -17,7 +17,7 @@ import kotlin.math.PI import kotlin.math.cos import kotlin.math.max import kotlin.math.sin -import space.kscience.visionforge.solid.specifications.Camera as CameraSpec +import space.kscience.visionforge.solid.specifications.CameraScheme as CameraSpec public class OrbitControls internal constructor(camera: Camera, canvas: SubScene, spec: CameraSpec) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt new file mode 100644 index 00000000..3b85b469 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -0,0 +1,44 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import space.kscience.dataforge.names.asName +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.VisionContainerBuilder +import space.kscience.visionforge.numberProperty +import space.kscience.visionforge.set + +@Serializable +public abstract class LightSource : SolidBase() { + @Transient + public val color: ColorAccessor = ColorAccessor(meta, "color".asName()) + public var intensity: Number by numberProperty(includeStyles = false) { 1.0 } +} + +@Serializable +@SerialName("solid.light.ambient") +public class AmbientLightSource : LightSource() + +@VisionBuilder +public fun VisionContainerBuilder.ambientLight( + name: String? = "@ambientLight", + block: AmbientLightSource.() -> Unit = {}, +): AmbientLightSource = AmbientLightSource().apply(block).also { set(name, it) } + +@Serializable +@SerialName("solid.light.point") +public class PointLightSource : LightSource() + + +@VisionBuilder +public fun VisionContainerBuilder.pointLight( + x: Number, + y: Number, + z: Number, + name: String? = null, + block: PointLightSource.() -> Unit = {}, +): PointLightSource = PointLightSource().apply(block).also { + it.position = Point3D(x, y, z) + set(name, it) +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index a501f7a0..76d0708b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -72,9 +72,7 @@ public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder { } @Suppress("FunctionName") -public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup { - return SolidGroup().apply(block) -} +public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block) @VisionBuilder public fun VisionContainerBuilder.group( diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index fa5b0d76..75d1f5a3 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -27,7 +27,7 @@ public class SolidMaterial : Scheme() { */ public val specularColor: ColorAccessor = ColorAccessor(meta, SPECULAR_COLOR_KEY) - public val emissiveColor: ColorAccessor = ColorAccessor(meta, "emissiveColor".asName()) + public val emissiveColor: ColorAccessor = ColorAccessor(meta, EMISSIVE_COLOR_KEY) /** * Opacity @@ -43,12 +43,15 @@ public class SolidMaterial : Scheme() { public val MATERIAL_KEY: Name = "material".asName() public val COLOR_KEY: Name = "color".asName() - public val MATERIAL_COLOR_KEY: Name = MATERIAL_KEY + COLOR_KEY + public val TYPE_KEY: Name = "type".asName() public val SPECULAR_COLOR_KEY: Name = "specularColor".asName() - public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY + public val EMISSIVE_COLOR_KEY: Name = "emissiveColor".asName() public val OPACITY_KEY: Name = "opacity".asName() public val MATERIAL_OPACITY_KEY: Name = MATERIAL_KEY + OPACITY_KEY public val WIREFRAME_KEY: Name = "wireframe".asName() + public val MATERIAL_COLOR_KEY: Name = MATERIAL_KEY + COLOR_KEY + public val MATERIAL_EMISSIVE_COLOR_KEY: Name = MATERIAL_KEY + EMISSIVE_COLOR_KEY + public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY public val MATERIAL_WIREFRAME_KEY: Name = MATERIAL_KEY + WIREFRAME_KEY public override val descriptor: MetaDescriptor by lazy { @@ -56,6 +59,12 @@ public class SolidMaterial : Scheme() { MetaDescriptor { inherited = true + value(TYPE_KEY, ValueType.STRING){ + inherited = true + allowedValues = listOf("default".asValue(), "simple".asValue()) + default("default") + } + value(COLOR_KEY, ValueType.STRING, ValueType.NUMBER) { inherited = true widgetType = "color" @@ -67,6 +76,12 @@ public class SolidMaterial : Scheme() { hide() } + value(EMISSIVE_COLOR_KEY, ValueType.STRING, ValueType.NUMBER) { + inherited = true + widgetType = "color" + hide() + } + value(OPACITY_KEY, ValueType.NUMBER) { inherited = true default(1.0) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 12a22ab6..7e52d709 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -39,6 +39,9 @@ public class Solids(meta: Meta) : VisionPlugin(meta) { subclass(PolyLine.serializer()) subclass(SolidLabel.serializer()) subclass(Sphere.serializer()) + + subclass(AmbientLightSource.serializer()) + subclass(PointLightSource.serializer()) } public val serializersModuleForSolids: SerializersModule = SerializersModule { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Axes.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt similarity index 79% rename from visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Axes.kt rename to visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt index 485cc8bd..d4eb8e2b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Axes.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt @@ -7,24 +7,24 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.meta.double -public class Axes : Scheme() { +public class AxesScheme : Scheme() { public var visible: Boolean by boolean(false) public var size: Double by double(AXIS_SIZE) public var width: Double by double(AXIS_WIDTH) - public companion object : SchemeSpec(::Axes) { + public companion object : SchemeSpec(::AxesScheme) { public const val AXIS_SIZE: Double = 1000.0 public const val AXIS_WIDTH: Double = 3.0 override val descriptor: MetaDescriptor by lazy { MetaDescriptor { - value(Axes::visible){ + value(AxesScheme::visible){ default(false) } - value(Axes::size){ + value(AxesScheme::size){ default(AXIS_SIZE) } - value(Axes::width){ + value(AxesScheme::width){ default(AXIS_WIDTH) } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Camera.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/CameraScheme.kt similarity index 77% rename from visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Camera.kt rename to visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/CameraScheme.kt index b8cb05d4..f884bc1e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Camera.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/CameraScheme.kt @@ -8,7 +8,7 @@ import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.int import kotlin.math.PI -public class Camera : Scheme() { +public class CameraScheme : Scheme() { public var fov: Int by int(FIELD_OF_VIEW) //var aspect by double(1.0) @@ -19,7 +19,7 @@ public class Camera : Scheme() { public var azimuth: Double by double(INITIAL_AZIMUTH) public var latitude: Double by double(INITIAL_LATITUDE) - public companion object : SchemeSpec(::Camera) { + public companion object : SchemeSpec(::CameraScheme) { public const val INITIAL_DISTANCE: Double = 300.0 public const val INITIAL_AZIMUTH: Double = 0.0 public const val INITIAL_LATITUDE: Double = PI / 6 @@ -29,22 +29,22 @@ public class Camera : Scheme() { override val descriptor: MetaDescriptor by lazy { MetaDescriptor { - value(Camera::fov) { + value(CameraScheme::fov) { default(FIELD_OF_VIEW) } - value(Camera::nearClip) { + value(CameraScheme::nearClip) { default(NEAR_CLIP) } - value(Camera::farClip) { + value(CameraScheme::farClip) { default(FAR_CLIP) } - value(Camera::distance) { + value(CameraScheme::distance) { default(INITIAL_DISTANCE) } - value(Camera::azimuth) { + value(CameraScheme::azimuth) { default(INITIAL_AZIMUTH) } - value(Camera::latitude) { + value(CameraScheme::latitude) { default(INITIAL_LATITUDE) } } @@ -52,4 +52,4 @@ public class Camera : Scheme() { } } -public val Camera.zenith: Double get() = PI / 2 - latitude \ No newline at end of file +public val CameraScheme.zenith: Double get() = PI / 2 - latitude \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt index 4a819ff7..e74b47f0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt @@ -8,38 +8,34 @@ import space.kscience.dataforge.names.Name import space.kscience.visionforge.hide import space.kscience.visionforge.widgetType -public class Clipping : Scheme() { - public var x: Double? by double() - public var y: Double? by double() - public var z: Double? by double() - public companion object : SchemeSpec(::Clipping) { - override val descriptor: MetaDescriptor = MetaDescriptor { - value(Clipping::x) { - widgetType = "range" - attributes["min"] = 0.0 - attributes["max"] = 1.0 - attributes["step"] = 0.01 - default(1.0) - } - value(Clipping::y) { - widgetType = "range" - attributes["min"] = 0.0 - attributes["max"] = 1.0 - attributes["step"] = 0.01 - default(1.0) - } - value(Clipping::z) { - widgetType = "range" - attributes["min"] = 0.0 - attributes["max"] = 1.0 - attributes["step"] = 0.01 - default(1.0) - } +public object Clipping : SchemeSpec(::PointScheme) { + override val descriptor: MetaDescriptor = MetaDescriptor { + value(PointScheme::x) { + widgetType = "range" + attributes["min"] = 0.0 + attributes["max"] = 1.0 + attributes["step"] = 0.01 + default(1.0) + } + value(PointScheme::y) { + widgetType = "range" + attributes["min"] = 0.0 + attributes["max"] = 1.0 + attributes["step"] = 0.01 + default(1.0) + } + value(PointScheme::z) { + widgetType = "range" + attributes["min"] = 0.0 + attributes["max"] = 1.0 + attributes["step"] = 0.01 + default(1.0) } } } + public class CanvasSize : Scheme() { public var minSize: Int by int(400) public var minWith: Number by number { minSize } @@ -62,16 +58,15 @@ public class CanvasSize : Scheme() { } public class Canvas3DOptions : Scheme() { - public var axes: Axes by spec(Axes) - public var light: Light by spec(Light) - public var camera: Camera by spec(Camera) - public var controls: Controls by spec(Controls) + public var axes: AxesScheme by spec(AxesScheme) + public var camera: CameraScheme by spec(CameraScheme) + public var controls: ControlsScheme by spec(ControlsScheme) public var size: CanvasSize by spec(CanvasSize) public var layers: List by numberList(0) - public var clipping: Clipping by spec(Clipping) + public var clipping: PointScheme by spec(Clipping) public var onSelect: ((Name?) -> Unit)? = null @@ -79,7 +74,7 @@ public class Canvas3DOptions : Scheme() { public companion object : SchemeSpec(::Canvas3DOptions) { override val descriptor: MetaDescriptor by lazy { MetaDescriptor { - scheme(Canvas3DOptions::axes, Axes) + scheme(Canvas3DOptions::axes, AxesScheme) value(Canvas3DOptions::layers) { multiple = true @@ -90,15 +85,11 @@ public class Canvas3DOptions : Scheme() { scheme(Canvas3DOptions::clipping, Clipping) - scheme(Canvas3DOptions::light, Light){ - hide() - } - - scheme(Canvas3DOptions::camera, Camera) { + scheme(Canvas3DOptions::camera, CameraScheme) { hide() } - scheme(Canvas3DOptions::controls, Controls) { + scheme(Canvas3DOptions::controls, ControlsScheme) { hide() } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Controls.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/ControlsScheme.kt similarity index 56% rename from visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Controls.kt rename to visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/ControlsScheme.kt index ee8ebb9d..5e68f37c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Controls.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/ControlsScheme.kt @@ -4,6 +4,6 @@ import space.kscience.dataforge.meta.Scheme import space.kscience.dataforge.meta.SchemeSpec -public class Controls : Scheme() { - public companion object : SchemeSpec(::Controls) +public class ControlsScheme : Scheme() { + public companion object : SchemeSpec(::ControlsScheme) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Light.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Light.kt deleted file mode 100644 index 39b79466..00000000 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Light.kt +++ /dev/null @@ -1,8 +0,0 @@ -package space.kscience.visionforge.solid.specifications - -import space.kscience.dataforge.meta.Scheme -import space.kscience.dataforge.meta.SchemeSpec - -public class Light : Scheme() { - public companion object : SchemeSpec(::Light) -} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/PointScheme.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/PointScheme.kt new file mode 100644 index 00000000..33b8c180 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/PointScheme.kt @@ -0,0 +1,19 @@ +package space.kscience.visionforge.solid.specifications + +import space.kscience.dataforge.meta.Scheme +import space.kscience.dataforge.meta.SchemeSpec +import space.kscience.dataforge.meta.double + +public class PointScheme: Scheme(){ + public var x: Double? by double() + public var y: Double? by double() + public var z: Double? by double() + + public companion object: SchemeSpec(::PointScheme) +} + +public operator fun PointScheme.invoke(x: Number?, y: Number?, z: Number?){ + this.x = x?.toDouble() + this.y = y?.toDouble() + this.z = z?.toDouble() +} \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index f8af54a0..558d005c 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -1,6 +1,7 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Colors import space.kscience.visionforge.MutableVisionGroup import space.kscience.visionforge.get import kotlin.test.Test @@ -55,4 +56,18 @@ class SerializationTest { assertEquals(group["cube"]?.meta, reconstructed["cube"]?.meta) } + @Test + fun lightSerialization(){ + val group = SolidGroup { + ambientLight { + color(Colors.white) + intensity = 100.0 + } + } + val serialized = Solids.encodeToString(group) + + val reconstructed = Solids.decodeFromString(serialized) as SolidGroup + assertEquals(100.0, (reconstructed["@ambientLight"] as AmbientLightSource).intensity.toDouble()) + } + } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt index 1d5fd3d9..7ac4f13e 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt @@ -10,6 +10,7 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.values.boolean +import space.kscience.visionforge.VisionBuilder import space.kscience.visionforge.computePropertyNode import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.setProperty @@ -75,6 +76,7 @@ public abstract class MeshThreeFactory( } } +@VisionBuilder public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { setProperty(EDGES_ENABLED_KEY, enabled) meta.getOrCreate(EDGES_MATERIAL_KEY).updateWith(SolidMaterial, block) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt new file mode 100644 index 00000000..c3d6bfa0 --- /dev/null +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt @@ -0,0 +1,19 @@ +package space.kscience.visionforge.solid.three + +import info.laht.threekt.lights.AmbientLight +import info.laht.threekt.math.Color +import space.kscience.visionforge.solid.AmbientLightSource +import kotlin.reflect.KClass + +public object ThreeAmbientLightFactory : ThreeFactory { + override val type: KClass get() = AmbientLightSource::class + + override fun invoke(three: ThreePlugin, obj: AmbientLightSource): AmbientLight { + val res = AmbientLight().apply { + color = obj.color.threeColor() ?: Color(0x404040) + intensity = obj.intensity.toDouble() + } + + return res + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index ef9944e0..586abe32 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -8,12 +8,8 @@ import info.laht.threekt.external.controls.OrbitControls import info.laht.threekt.external.controls.TrackballControls import info.laht.threekt.geometries.EdgesGeometry import info.laht.threekt.helpers.AxesHelper -import info.laht.threekt.lights.AmbientLight import info.laht.threekt.materials.LineBasicMaterial -import info.laht.threekt.math.Box3 -import info.laht.threekt.math.Plane -import info.laht.threekt.math.Vector2 -import info.laht.threekt.math.Vector3 +import info.laht.threekt.math.* import info.laht.threekt.objects.LineSegments import info.laht.threekt.objects.Mesh import info.laht.threekt.scenes.Scene @@ -35,7 +31,7 @@ import kotlin.math.cos import kotlin.math.sin /** - * + * A canvas for three-js rendering */ public class ThreeCanvas( public val three: ThreePlugin, @@ -60,19 +56,19 @@ public class ThreeCanvas( add(axesObject) } - //Set up light - options.useProperty(Canvas3DOptions::light, this) { lightConfig -> - //remove old light if present - getObjectByName(LIGHT_NAME)?.let { remove(it) } - //add new light - val lightObject = buildLight(lightConfig) - lightObject.name = LIGHT_NAME - add(lightObject) - } +// //Set up light +// options.useProperty(Canvas3DOptions::light, this) { lightConfig -> +// //remove old light if present +// getObjectByName(LIGHT_NAME)?.let { remove(it) } +// //add new light +// val lightObject = buildLight(lightConfig) +// lightObject.name = LIGHT_NAME +// add(lightObject) +// } } - private fun buildCamera(spec: Camera) = PerspectiveCamera( + private fun buildCamera(spec: CameraScheme) = PerspectiveCamera( spec.fov, 1.0, spec.nearClip, @@ -231,9 +227,24 @@ public class ThreeCanvas( } } - private fun buildLight(spec: Light?): info.laht.threekt.lights.Light = AmbientLight(0x404040) +// private fun buildLight(spec: AmbientLightScheme?): info.laht.threekt.lights.Light = when (spec?.type) { +// AmbientLightScheme.Type.POINT -> PointLight().apply { +// position.x = spec.position.x ?: 0.0 +// position.y = spec.position.y ?: 0.0 +// position.z = spec.position.z ?: 0.0 +// } +// else -> AmbientLight().apply { +// +// } +// }.apply { +// this.color = spec?.color?.threeColor() ?: Color(0x404040) +// +// spec?.intensity?.coerceIn(0.0, 1.0)?.let { +// this.intensity = it +// } +// } - private fun addControls(element: Node, controls: Controls) { + private fun addControls(element: Node, controls: ControlsScheme) { when (controls.meta["type"].string) { "trackball" -> TrackballControls(camera, element) else -> OrbitControls(camera, element) @@ -311,7 +322,7 @@ public class ThreeCanvas( private const val SELECT_NAME = "@select" private const val LIGHT_NAME = "@light" private const val AXES_NAME = "@axes" - private const val CLIP_HELPER_NAME = "@clipping" + //private const val CLIP_HELPER_NAME = "@clipping" } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index df9f2c94..6e540f71 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -8,7 +8,6 @@ import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperty import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY import space.kscience.visionforge.solid.three.ThreeFactory.Companion.TYPE @@ -58,7 +57,7 @@ public fun Object3D.updatePosition(obj: Vision) { * Update non-position non-geometry property */ public fun Object3D.updateProperty(source: Vision, propertyName: Name) { - console.log("$source updated $propertyName with ${source.computeProperty(propertyName)}") + // console.log("$source updated $propertyName with ${source.computeProperty(propertyName)}") if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) { updateMaterialProperty(source, propertyName) } else if ( diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 522c0362..5b4fa220 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -3,39 +3,52 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.materials.LineBasicMaterial import info.laht.threekt.materials.Material import info.laht.threekt.materials.MeshBasicMaterial +import info.laht.threekt.materials.MeshStandardMaterial import info.laht.threekt.math.Color import info.laht.threekt.objects.Mesh import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.* import space.kscience.visionforge.Colors import space.kscience.visionforge.Vision import space.kscience.visionforge.computePropertyNode import space.kscience.visionforge.getStyleNodes +import space.kscience.visionforge.solid.ColorAccessor import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.SolidReference public object ThreeMaterials { public val DEFAULT_COLOR: Color = Color(Colors.darkgreen) - public val DEFAULT: MeshBasicMaterial = MeshBasicMaterial().apply { + + public val DEFAULT: MeshStandardMaterial = MeshStandardMaterial().apply { color.set(DEFAULT_COLOR) cached = true } - public val DEFAULT_LINE_COLOR: Color = Color(Colors.black) + + public val BLACK_COLOR: Color = Color(Colors.black) + + public val DEFAULT_EMISSIVE_COLOR: Color = BLACK_COLOR + + public val DEFAULT_LINE_COLOR: Color get() = BLACK_COLOR + public val DEFAULT_LINE: LineBasicMaterial = LineBasicMaterial().apply { color.set(DEFAULT_LINE_COLOR) + cached = true } public val SELECTED_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { color.set(Colors.ivory) linewidth = 8.0 + cached = true } public val HIGHLIGHT_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { color.set(Colors.blue) linewidth = 8.0 + cached = true } private val lineMaterialCache = HashMap() @@ -58,34 +71,21 @@ public object ThreeMaterials { private val materialCache = HashMap() - internal fun buildMaterial(meta: Meta): Material = MeshBasicMaterial().apply { - color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR + internal fun buildMaterial(meta: Meta): Material = when (meta[SolidMaterial.TYPE_KEY]?.string) { + "simple" -> MeshBasicMaterial().apply { + color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR + wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false + } + else -> MeshStandardMaterial().apply { + color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR + emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR + wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false + } + }.apply { opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0 transparent = opacity < 1.0 - wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false needsUpdate = true } -// val material = SolidMaterial.read(meta) -// return meta[SolidMaterial.SPECULAR_COLOR_KEY]?.let { specularColor -> -// MeshPhongMaterial().apply { -// color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR -// specular = specularColor.threeColor() -// emissive = material.emissiveColor.threeColor() ?: specular -// reflectivity = 0.5 -// refractionRatio = 1.0 -// shininess = 100.0 -// opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0 -// transparent = opacity < 1.0 -// wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false -// needsUpdate = true -// } -// } ?: MeshBasicMaterial().apply { -// color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR -// opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0 -// transparent = opacity < 1.0 -// wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false -// needsUpdate = true -// } internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta) { buildMaterial(meta).apply { @@ -115,6 +115,16 @@ public fun Meta.threeColor(): Color? { } } +public fun ColorAccessor.threeColor(): Color? { + val value = value + return when { + value == null -> null + value === Null -> null + value.type == ValueType.NUMBER -> Color(value.int) + else -> Color(value.string) + } +} + private var Material.cached: Boolean get() = userData["cached"] == true set(value) { @@ -139,7 +149,11 @@ public fun Mesh.updateMaterial(vision: Vision) { } public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { - if (material.cached || propertyName == SolidMaterial.MATERIAL_KEY) { + if ( + material.cached + || propertyName == SolidMaterial.MATERIAL_KEY + || propertyName == SolidMaterial.MATERIAL_KEY + SolidMaterial.TYPE_KEY + ) { //generate a new material since cached material should not be changed updateMaterial(vision) } else { @@ -149,6 +163,16 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { ?: ThreeMaterials.DEFAULT_COLOR material.needsUpdate = true } + SolidMaterial.SPECULAR_COLOR_KEY -> { + material.asDynamic().specular = vision.computePropertyNode(SolidMaterial.SPECULAR_COLOR_KEY)?.threeColor() + ?: ThreeMaterials.DEFAULT_COLOR + material.needsUpdate = true + } + SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { + material.asDynamic().emissive = vision.computePropertyNode(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY)?.threeColor() + ?: ThreeMaterials.BLACK_COLOR + material.needsUpdate = true + } SolidMaterial.MATERIAL_OPACITY_KEY -> { val opacity = vision.getPropertyValue( SolidMaterial.MATERIAL_OPACITY_KEY, diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index aa5c2a14..8c32551a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -1,7 +1,6 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.core.Object3D -import kotlinx.coroutines.CoroutineScope import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* @@ -27,8 +26,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { private val objectFactories = HashMap, ThreeFactory<*>>() private val compositeFactory = ThreeCompositeFactory(this) - //TODO generate a separate supervisor update scope - internal val updateScope: CoroutineScope get() = context +// internal val updateScope: CoroutineScope get() = context init { //Add specialized factories here @@ -38,6 +36,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { objectFactories[ConeSegment::class] = ThreeConeFactory objectFactories[PolyLine::class] = ThreeLineFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory + objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory + objectFactories[PointLightSource::class] = ThreePointLightFactory } @Suppress("UNCHECKED_CAST") diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt new file mode 100644 index 00000000..a7a6d758 --- /dev/null +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt @@ -0,0 +1,28 @@ +package space.kscience.visionforge.solid.three + +import info.laht.threekt.lights.PointLight +import info.laht.threekt.math.Color +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.PointLightSource +import kotlin.reflect.KClass + +public object ThreePointLightFactory : ThreeFactory { + override val type: KClass get() = PointLightSource::class + + override fun invoke(three: ThreePlugin, obj: PointLightSource): PointLight { + val res = PointLight().apply { + matrixAutoUpdate = false + color = obj.color.threeColor() ?: Color(0x404040) + intensity = obj.intensity.toDouble() + updatePosition(obj) + } + + obj.onPropertyChange { name -> + when { + else -> res.updateProperty(obj, name) + } + } + + return res + } +} \ No newline at end of file From 7ee40679b974b4f39b35800e0d6137b0c2bf4185 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 28 Jan 2022 14:17:37 +0300 Subject: [PATCH 002/112] Update light descriptor --- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 7 ++- .../mipt/npm/muon/monitor/MMAppComponent.kt | 6 ++- kotlin-js-store/yarn.lock | 8 ++-- .../visionforge/solid/ColorAccessor.kt | 11 ++++- .../kscience/visionforge/solid/LightSource.kt | 46 +++++++++++++++---- visionforge-threejs/build.gradle.kts | 2 +- .../solid/three/ThreePointLightFactory.kt | 6 ++- 7 files changed, 68 insertions(+), 18 deletions(-) diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 2dab49a2..06501374 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -8,6 +8,12 @@ import space.kscience.visionforge.removeAll import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.setProperty import space.kscience.visionforge.solid.* +import kotlin.collections.HashMap +import kotlin.collections.HashSet +import kotlin.collections.filter +import kotlin.collections.forEach +import kotlin.collections.set +import kotlin.collections.toTypedArray import kotlin.math.PI class Model(val manager: VisionManager) { @@ -39,7 +45,6 @@ class Model(val manager: VisionManager) { val root: SolidGroup = SolidGroup().apply { setAsRoot(this@Model.manager) material { - wireframe color("darkgreen") } rotationX = PI / 2 diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index 350d25f3..f9c03756 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -19,11 +19,13 @@ import react.useState import space.kscience.dataforge.context.Context import space.kscience.dataforge.meta.invoke import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Colors import space.kscience.visionforge.react.flexColumn import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.tab import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.edges import styled.css @@ -55,7 +57,9 @@ val MMApp = fc("Muon monitor") { props -> val root = useMemo(props.model) { props.model.root.apply { edges() - ambientLight() + ambientLight{ + color(Colors.white) + } } } diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index df058368..bf21978a 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -8244,10 +8244,10 @@ three-csg-ts@3.1.9: resolved "https://registry.yarnpkg.com/three-csg-ts/-/three-csg-ts-3.1.9.tgz#1438de3b6747b9b55deb88d9e0acdc6e47681979" integrity sha512-Qke0+07AKDfeiRjh46sOF2iiilSMcKnfgHjuArdMB4poZs3X0FQLHGFIEBbGrv3ejrkHASW9o5pLRfFFQhk9hg== -three@0.130.1: - version "0.130.1" - resolved "https://registry.yarnpkg.com/three/-/three-0.130.1.tgz#797588b2877ace31603bbbc864eb2e3022f0b3b4" - integrity sha512-OSPPKcGvFSiGkG3jFrwwC76PBV/ZSrGxpBbg28bW8s9GU8r/y2spNGtEXHEb/CVqo0Ctf5Lx2rVaxQZB6OasaA== +three@0.137.4: + version "0.137.4" + resolved "https://registry.yarnpkg.com/three/-/three-0.137.4.tgz#ec73b6a6c40b733d56544b13d0c3cdb0bce5d0a7" + integrity sha512-kUyOZNX+dMbvaS0mGYM1BaXHkHVNQdpryWH8dBg3mn725dJcTo9/5rjyH+OJ8V0r+XbZPz7sncV+c3Gjpc9UBA== through2@^0.6.3: version "0.6.5" diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index 57f868f2..0f9abc4d 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -1,15 +1,18 @@ package space.kscience.visionforge.solid +import space.kscience.dataforge.meta.Configurable import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.* import space.kscience.visionforge.Colors import space.kscience.visionforge.VisionBuilder +import kotlin.properties.ReadOnlyProperty @VisionBuilder public class ColorAccessor( private val provider: MutableValueProvider, - private val colorKey: Name + private val colorKey: Name, ) : MutableValueProvider { public var value: Value? get() = provider.getValue(colorKey) @@ -24,8 +27,12 @@ public class ColorAccessor( } } +public fun Configurable.color(): ReadOnlyProperty = ReadOnlyProperty { _, property -> + ColorAccessor(meta, property.name.asName()) +} + public var ColorAccessor?.string: String? - get() = this?.value?.let { if(it == Null) null else it.string } + get() = this?.value?.let { if (it == Null) null else it.string } set(value) { this?.value = value?.asValue() } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt index 3b85b469..6bab2cf3 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -2,18 +2,48 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import space.kscience.dataforge.names.asName -import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.numberProperty -import space.kscience.visionforge.set +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.node +import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.values.ValueType +import space.kscience.visionforge.* @Serializable public abstract class LightSource : SolidBase() { - @Transient - public val color: ColorAccessor = ColorAccessor(meta, "color".asName()) + override val descriptor: MetaDescriptor get() = LightSource.descriptor + + public val color: ColorAccessor by color() public var intensity: Number by numberProperty(includeStyles = false) { 1.0 } + + public companion object{ + public val descriptor: MetaDescriptor by lazy { + MetaDescriptor { + value(Vision.VISIBLE_KEY, ValueType.BOOLEAN) { + inherited = false + default(true) + } + + value(LightSource::color.name, ValueType.STRING, ValueType.NUMBER) { + inherited = false + widgetType = "color" + } + + value(LightSource::intensity.name, ValueType.NUMBER) { + inherited = false + default(1.0) + } + + value(SolidMaterial.COLOR_KEY, ValueType.STRING, ValueType.NUMBER) { + inherited = false + widgetType = "color" + } + + node(Solid.POSITION_KEY) { + hide() + } + } + } + } } @Serializable diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index 5ae86f41..3aa1ef5e 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -10,6 +10,6 @@ kotlin{ dependencies { api(project(":visionforge-solid")) - implementation(npm("three", "0.130.1")) + implementation(npm("three", "0.137.4")) implementation(npm("three-csg-ts", "3.1.9")) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt index a7a6d758..727aa098 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt @@ -2,7 +2,9 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.lights.PointLight import info.laht.threekt.math.Color +import space.kscience.dataforge.names.asName import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.LightSource import space.kscience.visionforge.solid.PointLightSource import kotlin.reflect.KClass @@ -18,7 +20,9 @@ public object ThreePointLightFactory : ThreeFactory { } obj.onPropertyChange { name -> - when { + when (name) { + LightSource::color.name.asName() -> res.color = obj.color.threeColor() ?: Color(0x404040) + LightSource::intensity.name.asName() -> res.intensity = obj.intensity.toDouble() else -> res.updateProperty(obj, name) } } From 9648533ac88f21bfb1d8a65a17260c1f78239a60 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 13 Apr 2022 15:02:35 +0300 Subject: [PATCH 003/112] Update build tools --- build.gradle.kts | 2 +- demo/muon-monitor/build.gradle.kts | 4 +- gradle.properties | 7 +- kotlin-js-store/yarn.lock | 9201 ----------------- ui/ring/build.gradle.kts | 2 +- visionforge-gdml/build.gradle.kts | 2 +- visionforge-server/build.gradle.kts | 6 +- .../build.gradle.kts | 2 +- 8 files changed, 10 insertions(+), 9216 deletions(-) delete mode 100644 kotlin-js-store/yarn.lock diff --git a/build.gradle.kts b/build.gradle.kts index 0cd9f7da..c3148a64 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("ru.mipt.npm.gradle.project") - id("org.jetbrains.kotlinx.kover") version "0.5.0-RC" +// id("org.jetbrains.kotlinx.kover") version "0.5.0" } val dataforgeVersion by extra("0.5.2") diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index d33cd455..59d3495a 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -45,8 +45,8 @@ kotlin { jvmMain { dependencies { implementation("org.apache.commons:commons-math3:3.6.1") - implementation(npmlibs.ktor.server.cio) - implementation(npmlibs.ktor.serialization) + implementation("io.ktor-server-cio:${npmlibs.versions.ktor}") + implementation("io.ktor:ktor-serialization-kotlinx-json:${npmlibs.versions.ktor}") } } jsMain { diff --git a/gradle.properties b/gradle.properties index e029eef4..1d420172 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,12 +1,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true - kotlin.jupyter.add.scanner=false -org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G org.gradle.parallel=true -publishing.github=false -publishing.sonatype=false - -toolsVersion=0.11.1-kotlin-1.6.10 \ No newline at end of file +toolsVersion=0.11.4-kotlin-1.6.20 \ No newline at end of file diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock deleted file mode 100644 index bf21978a..00000000 --- a/kotlin-js-store/yarn.lock +++ /dev/null @@ -1,9201 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"3d-view@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/3d-view/-/3d-view-2.0.1.tgz#2e174571c48215736b376bb66938a3513dad2179" - integrity sha512-YSLRHXNpSziaaiK2R0pI5+JKguoJVbtWmIv9YyBFtl0+q42kQwJB/JUulbFR/1zYFm58ifjKQ6kVdgZ6tyKtCA== - dependencies: - matrix-camera-controller "^2.1.1" - orbit-camera-controller "^4.0.0" - turntable-camera-controller "^3.0.0" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" - integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA== - dependencies: - "@babel/highlight" "^7.16.0" - -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.0", "@babel/compat-data@^7.16.4": - version "7.16.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" - integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== - -"@babel/core@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4" - integrity sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ== - dependencies: - "@babel/code-frame" "^7.16.0" - "@babel/generator" "^7.16.0" - "@babel/helper-compilation-targets" "^7.16.0" - "@babel/helper-module-transforms" "^7.16.0" - "@babel/helpers" "^7.16.0" - "@babel/parser" "^7.16.0" - "@babel/template" "^7.16.0" - "@babel/traverse" "^7.16.0" - "@babel/types" "^7.16.0" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.1.2" - semver "^6.3.0" - source-map "^0.5.0" - -"@babel/generator@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2" - integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew== - dependencies: - "@babel/types" "^7.16.0" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d" - integrity sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.0.tgz#f1a686b92da794020c26582eb852e9accd0d7882" - integrity sha512-9KuleLT0e77wFUku6TUkqZzCEymBdtuQQ27MhEKzf9UOOJu3cYj98kyaDAzxpC7lV6DGiZFuC8XqDsq8/Kl6aQ== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.0", "@babel/helper-compilation-targets@^7.16.3": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz#5b480cd13f68363df6ec4dc8ac8e2da11363cbf0" - integrity sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA== - dependencies: - "@babel/compat-data" "^7.16.0" - "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.17.5" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz#090d4d166b342a03a9fec37ef4fd5aeb9c7c6a4b" - integrity sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-function-name" "^7.16.0" - "@babel/helper-member-expression-to-functions" "^7.16.0" - "@babel/helper-optimise-call-expression" "^7.16.0" - "@babel/helper-replace-supers" "^7.16.0" - "@babel/helper-split-export-declaration" "^7.16.0" - -"@babel/helper-create-regexp-features-plugin@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz#06b2348ce37fccc4f5e18dcd8d75053f2a7c44ff" - integrity sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - regexpu-core "^4.7.1" - -"@babel/helper-define-polyfill-provider@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz#c5b10cf4b324ff840140bb07e05b8564af2ae971" - integrity sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg== - dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - -"@babel/helper-explode-assignable-expression@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz#753017337a15f46f9c09f674cff10cee9b9d7778" - integrity sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-function-name@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481" - integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog== - dependencies: - "@babel/helper-get-function-arity" "^7.16.0" - "@babel/template" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/helper-get-function-arity@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa" - integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-hoist-variables@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a" - integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-member-expression-to-functions@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4" - integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3" - integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-module-transforms@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5" - integrity sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA== - dependencies: - "@babel/helper-module-imports" "^7.16.0" - "@babel/helper-replace-supers" "^7.16.0" - "@babel/helper-simple-access" "^7.16.0" - "@babel/helper-split-export-declaration" "^7.16.0" - "@babel/helper-validator-identifier" "^7.15.7" - "@babel/template" "^7.16.0" - "@babel/traverse" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/helper-optimise-call-expression@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338" - integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" - integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== - -"@babel/helper-remap-async-to-generator@^7.16.0", "@babel/helper-remap-async-to-generator@^7.16.4": - version "7.16.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.4.tgz#5d7902f61349ff6b963e07f06a389ce139fbfe6e" - integrity sha512-vGERmmhR+s7eH5Y/cp8PCVzj4XEjerq8jooMfxFdA5xVtAk9Sh4AQsrWgiErUEBjtGrBtOFKDUcWQFW4/dFwMA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-wrap-function" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/helper-replace-supers@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17" - integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.16.0" - "@babel/helper-optimise-call-expression" "^7.16.0" - "@babel/traverse" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/helper-simple-access@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517" - integrity sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" - integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-split-export-declaration@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438" - integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-validator-identifier@^7.15.7": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== - -"@babel/helper-validator-option@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" - integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== - -"@babel/helper-wrap-function@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.0.tgz#b3cf318afce774dfe75b86767cd6d68f3482e57c" - integrity sha512-VVMGzYY3vkWgCJML+qVLvGIam902mJW0FvT7Avj1zEe0Gn7D93aWdLblYARTxEw+6DhZmtzhBM2zv0ekE5zg1g== - dependencies: - "@babel/helper-function-name" "^7.16.0" - "@babel/template" "^7.16.0" - "@babel/traverse" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/helpers@^7.16.0": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.3.tgz#27fc64f40b996e7074dc73128c3e5c3e7f55c43c" - integrity sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w== - dependencies: - "@babel/template" "^7.16.0" - "@babel/traverse" "^7.16.3" - "@babel/types" "^7.16.0" - -"@babel/highlight@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" - integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g== - dependencies: - "@babel/helper-validator-identifier" "^7.15.7" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.16.0", "@babel/parser@^7.16.3": - version "7.16.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e" - integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng== - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.2": - version "7.16.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz#2977fca9b212db153c195674e57cfab807733183" - integrity sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz#358972eaab006f5eb0826183b0c93cbcaf13e1e2" - integrity sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-proposal-optional-chaining" "^7.16.0" - -"@babel/plugin-proposal-async-generator-functions@^7.16.4": - version "7.16.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.4.tgz#e606eb6015fec6fa5978c940f315eae4e300b081" - integrity sha512-/CUekqaAaZCQHleSK/9HajvcD/zdnJiKRiuUFq8ITE+0HsPzquf53cpFiqAwl/UfmJbR6n5uGPQSPdrmKOvHHg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.16.4" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz#c029618267ddebc7280fa286e0f8ca2a278a2d1a" - integrity sha512-mCF3HcuZSY9Fcx56Lbn+CGdT44ioBMMvjNVldpKtj8tpniETdLjnxdHI1+sDWXIM1nNt+EanJOZ3IG9lzVjs7A== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-proposal-class-static-block@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.0.tgz#5296942c564d8144c83eea347d0aa8a0b89170e7" - integrity sha512-mAy3sdcY9sKAkf3lQbDiv3olOfiLqI51c9DR9b19uMoR2Z6r5pmGl7dfNFqEvqOyqbf1ta4lknK4gc5PJn3mfA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-dynamic-import@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.0.tgz#783eca61d50526202f9b296095453977e88659f1" - integrity sha512-QGSA6ExWk95jFQgwz5GQ2Dr95cf7eI7TKutIXXTb7B1gCLTCz5hTjFTQGfLFBBiC5WSNi7udNwWsqbbMh1c4yQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.0.tgz#9c01dee40b9d6b847b656aaf4a3976a71740f222" - integrity sha512-CjI4nxM/D+5wCnhD11MHB1AwRSAYeDT+h8gCdcVJZ/OK7+wRzFsf7PFPWVpVpNRkHMmMkQWAHpTq+15IXQ1diA== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.0.tgz#cae35a95ed1d2a7fa29c4dc41540b84a72e9ab25" - integrity sha512-kouIPuiv8mSi5JkEhzApg5Gn6hFyKPnlkO0a9YSzqRurH8wYzSlf6RJdzluAsbqecdW5pBvDJDfyDIUR/vLxvg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.0.tgz#a711b8ceb3ffddd3ef88d3a49e86dbd3cc7db3fd" - integrity sha512-pbW0fE30sVTYXXm9lpVQQ/Vc+iTeQKiXlaNRZPPN2A2VdlWyAtsUrsQ3xydSlDW00TFMK7a8m3cDTkBF5WnV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.0.tgz#44e1cce08fe2427482cf446a91bb451528ed0596" - integrity sha512-3bnHA8CAFm7cG93v8loghDYyQ8r97Qydf63BeYiGgYbjKKB/XP53W15wfRC7dvKfoiJ34f6Rbyyx2btExc8XsQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.0.tgz#5d418e4fbbf8b9b7d03125d3a52730433a373734" - integrity sha512-FAhE2I6mjispy+vwwd6xWPyEx3NYFS13pikDBWUAFGZvq6POGs5eNchw8+1CYoEgBl9n11I3NkzD7ghn25PQ9Q== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.0.tgz#5fb32f6d924d6e6712810362a60e12a2609872e6" - integrity sha512-LU/+jp89efe5HuWJLmMmFG0+xbz+I2rSI7iLc1AlaeSMDMOGzWlc5yJrMN1d04osXN4sSfpo4O+azkBNBes0jg== - dependencies: - "@babel/compat-data" "^7.16.0" - "@babel/helper-compilation-targets" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.16.0" - -"@babel/plugin-proposal-optional-catch-binding@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.0.tgz#5910085811ab4c28b00d6ebffa4ab0274d1e5f16" - integrity sha512-kicDo0A/5J0nrsCPbn89mTG3Bm4XgYi0CZtvex9Oyw7gGZE3HXGD0zpQNH+mo+tEfbo8wbmMvJftOwpmPy7aVw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.0.tgz#56dbc3970825683608e9efb55ea82c2a2d6c8dc0" - integrity sha512-Y4rFpkZODfHrVo70Uaj6cC1JJOt3Pp0MdWSwIKtb8z1/lsjl9AmnB7ErRFV+QNGIfcY1Eruc2UMx5KaRnXjMyg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.0.tgz#b4dafb9c717e4301c5776b30d080d6383c89aff6" - integrity sha512-IvHmcTHDFztQGnn6aWq4t12QaBXTKr1whF/dgp9kz84X6GUcwq9utj7z2wFCUfeOup/QKnOlt2k0zxkGFx9ubg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-proposal-private-property-in-object@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.0.tgz#69e935b2c5c79d2488112d886f0c4e2790fee76f" - integrity sha512-3jQUr/HBbMVZmi72LpjQwlZ55i1queL8KcDTQEkAHihttJnAPrcvG9ZNXIfsd2ugpizZo595egYV6xy+pv4Ofw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-create-class-features-plugin" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.16.0", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.0.tgz#890482dfc5ea378e42e19a71e709728cabf18612" - integrity sha512-ti7IdM54NXv29cA4+bNNKEMS4jLMCbJgl+Drv+FgYy0erJLAxNAIXcNjNjrRZEcWq0xJHsNVwQezskMFpF8N9g== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.0.tgz#f9624394317365a9a88c82358d3f8471154698f1" - integrity sha512-8zv2+xiPHwly31RK4RmnEYY5zziuF3O7W2kIDW+07ewWDh6Oi0dRq8kwvulRkFgt6DB97RlKs5c1y068iPlCUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-top-level-await@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz#2feeb13d9334cc582ea9111d3506f773174179bb" - integrity sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-arrow-functions@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.0.tgz#951706f8b449c834ed07bd474c0924c944b95a8e" - integrity sha512-vIFb5250Rbh7roWARvCLvIJ/PtAU5Lhv7BtZ1u24COwpI9Ypjsh+bZcKk6rlIyalK+r0jOc1XQ8I4ovNxNrWrA== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-async-to-generator@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.0.tgz#df12637f9630ddfa0ef9d7a11bc414d629d38604" - integrity sha512-PbIr7G9kR8tdH6g8Wouir5uVjklETk91GMVSUq+VaOgiinbCkBP6Q7NN/suM/QutZkMJMvcyAriogcYAdhg8Gw== - dependencies: - "@babel/helper-module-imports" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.16.0" - -"@babel/plugin-transform-block-scoped-functions@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.0.tgz#c618763233ad02847805abcac4c345ce9de7145d" - integrity sha512-V14As3haUOP4ZWrLJ3VVx5rCnrYhMSHN/jX7z6FAt5hjRkLsb0snPCmJwSOML5oxkKO4FNoNv7V5hw/y2bjuvg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-block-scoping@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.0.tgz#bcf433fb482fe8c3d3b4e8a66b1c4a8e77d37c16" - integrity sha512-27n3l67/R3UrXfizlvHGuTwsRIFyce3D/6a37GRxn28iyTPvNXaW4XvznexRh1zUNLPjbLL22Id0XQElV94ruw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-classes@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.0.tgz#54cf5ff0b2242c6573d753cd4bfc7077a8b282f5" - integrity sha512-HUxMvy6GtAdd+GKBNYDWCIA776byUQH8zjnfjxwT1P1ARv/wFu8eBDpmXQcLS/IwRtrxIReGiplOwMeyO7nsDQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-function-name" "^7.16.0" - "@babel/helper-optimise-call-expression" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.16.0" - "@babel/helper-split-export-declaration" "^7.16.0" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.0.tgz#e0c385507d21e1b0b076d66bed6d5231b85110b7" - integrity sha512-63l1dRXday6S8V3WFY5mXJwcRAnPYxvFfTlt67bwV1rTyVTM5zrp0DBBb13Kl7+ehkCVwIZPumPpFP/4u70+Tw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-destructuring@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.0.tgz#ad3d7e74584ad5ea4eadb1e6642146c590dee33c" - integrity sha512-Q7tBUwjxLTsHEoqktemHBMtb3NYwyJPTJdM+wDwb0g8PZ3kQUIzNvwD5lPaqW/p54TXBc/MXZu9Jr7tbUEUM8Q== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-dotall-regex@^7.16.0", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.0.tgz#50bab00c1084b6162d0a58a818031cf57798e06f" - integrity sha512-FXlDZfQeLILfJlC6I1qyEwcHK5UpRCFkaoVyA1nk9A1L1Yu583YO4un2KsLBsu3IJb4CUbctZks8tD9xPQubLw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-duplicate-keys@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.0.tgz#8bc2e21813e3e89e5e5bf3b60aa5fc458575a176" - integrity sha512-LIe2kcHKAZOJDNxujvmp6z3mfN6V9lJxubU4fJIGoQCkKe3Ec2OcbdlYP+vW++4MpxwG0d1wSDOJtQW5kLnkZQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-exponentiation-operator@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.0.tgz#a180cd2881e3533cef9d3901e48dad0fbeff4be4" - integrity sha512-OwYEvzFI38hXklsrbNivzpO3fh87skzx8Pnqi4LoSYeav0xHlueSoCJrSgTPfnbyzopo5b3YVAJkFIcUpK2wsw== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-for-of@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.0.tgz#f7abaced155260e2461359bbc7c7248aca5e6bd2" - integrity sha512-5QKUw2kO+GVmKr2wMYSATCTTnHyscl6sxFRAY+rvN7h7WB0lcG0o4NoV6ZQU32OZGVsYUsfLGgPQpDFdkfjlJQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-function-name@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.0.tgz#02e3699c284c6262236599f751065c5d5f1f400e" - integrity sha512-lBzMle9jcOXtSOXUpc7tvvTpENu/NuekNJVova5lCCWCV9/U1ho2HH2y0p6mBg8fPm/syEAbfaaemYGOHCY3mg== - dependencies: - "@babel/helper-function-name" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-literals@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.0.tgz#79711e670ffceb31bd298229d50f3621f7980cac" - integrity sha512-gQDlsSF1iv9RU04clgXqRjrPyyoJMTclFt3K1cjLmTKikc0s/6vE3hlDeEVC71wLTRu72Fq7650kABrdTc2wMQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-member-expression-literals@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.0.tgz#5251b4cce01eaf8314403d21aedb269d79f5e64b" - integrity sha512-WRpw5HL4Jhnxw8QARzRvwojp9MIE7Tdk3ez6vRyUk1MwgjJN0aNpRoXainLR5SgxmoXx/vsXGZ6OthP6t/RbUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-modules-amd@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.0.tgz#09abd41e18dcf4fd479c598c1cef7bd39eb1337e" - integrity sha512-rWFhWbCJ9Wdmzln1NmSCqn7P0RAD+ogXG/bd9Kg5c7PKWkJtkiXmYsMBeXjDlzHpVTJ4I/hnjs45zX4dEv81xw== - dependencies: - "@babel/helper-module-transforms" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-commonjs@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.0.tgz#add58e638c8ddc4875bd9a9ecb5c594613f6c922" - integrity sha512-Dzi+NWqyEotgzk/sb7kgQPJQf7AJkQBWsVp1N6JWc1lBVo0vkElUnGdr1PzUBmfsCCN5OOFya3RtpeHk15oLKQ== - dependencies: - "@babel/helper-module-transforms" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-simple-access" "^7.16.0" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-systemjs@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.0.tgz#a92cf240afeb605f4ca16670453024425e421ea4" - integrity sha512-yuGBaHS3lF1m/5R+6fjIke64ii5luRUg97N2wr+z1sF0V+sNSXPxXDdEEL/iYLszsN5VKxVB1IPfEqhzVpiqvg== - dependencies: - "@babel/helper-hoist-variables" "^7.16.0" - "@babel/helper-module-transforms" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-identifier" "^7.15.7" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-umd@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.0.tgz#195f26c2ad6d6a391b70880effce18ce625e06a7" - integrity sha512-nx4f6no57himWiHhxDM5pjwhae5vLpTK2zCnDH8+wNLJy0TVER/LJRHl2bkt6w9Aad2sPD5iNNoUpY3X9sTGDg== - dependencies: - "@babel/helper-module-transforms" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.0.tgz#d3db61cc5d5b97986559967cd5ea83e5c32096ca" - integrity sha512-LogN88uO+7EhxWc8WZuQ8vxdSyVGxhkh8WTC3tzlT8LccMuQdA81e9SGV6zY7kY2LjDhhDOFdQVxdGwPyBCnvg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.0" - -"@babel/plugin-transform-new-target@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.0.tgz#af823ab576f752215a49937779a41ca65825ab35" - integrity sha512-fhjrDEYv2DBsGN/P6rlqakwRwIp7rBGLPbrKxwh7oVt5NNkIhZVOY2GRV+ULLsQri1bDqwDWnU3vhlmx5B2aCw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-object-super@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.0.tgz#fb20d5806dc6491a06296ac14ea8e8d6fedda72b" - integrity sha512-fds+puedQHn4cPLshoHcR1DTMN0q1V9ou0mUjm8whx9pGcNvDrVVrgw+KJzzCaiTdaYhldtrUps8DWVMgrSEyg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.16.0" - -"@babel/plugin-transform-parameters@^7.16.0", "@babel/plugin-transform-parameters@^7.16.3": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.3.tgz#fa9e4c874ee5223f891ee6fa8d737f4766d31d15" - integrity sha512-3MaDpJrOXT1MZ/WCmkOFo7EtmVVC8H4EUZVrHvFOsmwkk4lOjQj8rzv8JKUZV4YoQKeoIgk07GO+acPU9IMu/w== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-property-literals@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.0.tgz#a95c552189a96a00059f6776dc4e00e3690c78d1" - integrity sha512-XLldD4V8+pOqX2hwfWhgwXzGdnDOThxaNTgqagOcpBgIxbUvpgU2FMvo5E1RyHbk756WYgdbS0T8y0Cj9FKkWQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-react-display-name@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.0.tgz#9a0ad8aa8e8790883a7bd2736f66229a58125676" - integrity sha512-FJFdJAqaCpndL+pIf0aeD/qlQwT7QXOvR6Cc8JPvNhKJBi2zc/DPc4g05Y3fbD/0iWAMQFGij4+Xw+4L/BMpTg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-react-jsx-development@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.0.tgz#1cb52874678d23ab11d0d16488d54730807303ef" - integrity sha512-qq65iSqBRq0Hr3wq57YG2AmW0H6wgTnIzpffTphrUWUgLCOK+zf1f7G0vuOiXrp7dU1qq+fQBoqZ3wCDAkhFzw== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.16.0" - -"@babel/plugin-transform-react-jsx@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.0.tgz#55b797d4960c3de04e07ad1c0476e2bc6a4889f1" - integrity sha512-rqDgIbukZ44pqq7NIRPGPGNklshPkvlmvqjdx3OZcGPk4zGIenYkxDTvl3LsSL8gqcc3ZzGmXPE6hR/u/voNOw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-module-imports" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-jsx" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/plugin-transform-react-pure-annotations@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.0.tgz#23db6ddf558d8abde41b8ad9d59f48ad5532ccab" - integrity sha512-NC/Bj2MG+t8Ef5Pdpo34Ay74X4Rt804h5y81PwOpfPtmAK3i6CizmQqwyBQzIepz1Yt8wNr2Z2L7Lu3qBMfZMA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-regenerator@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.0.tgz#eaee422c84b0232d03aea7db99c97deeaf6125a4" - integrity sha512-JAvGxgKuwS2PihiSFaDrp94XOzzTUeDeOQlcKzVAyaPap7BnZXK/lvMDiubkPTdotPKOIZq9xWXWnggUMYiExg== - dependencies: - regenerator-transform "^0.14.2" - -"@babel/plugin-transform-reserved-words@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.0.tgz#fff4b9dcb19e12619394bda172d14f2d04c0379c" - integrity sha512-Dgs8NNCehHSvXdhEhln8u/TtJxfVwGYCgP2OOr5Z3Ar+B+zXicEOKNTyc+eca2cuEOMtjW6m9P9ijOt8QdqWkg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-runtime@^7.14.3": - version "7.16.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.4.tgz#f9ba3c7034d429c581e1bd41b4952f3db3c2c7e8" - integrity sha512-pru6+yHANMTukMtEZGC4fs7XPwg35v8sj5CIEmE+gEkFljFiVJxEWxx/7ZDkTK+iZRYo1bFXBtfIN95+K3cJ5A== - dependencies: - "@babel/helper-module-imports" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.4.0" - babel-plugin-polyfill-regenerator "^0.3.0" - semver "^6.3.0" - -"@babel/plugin-transform-shorthand-properties@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.0.tgz#090372e3141f7cc324ed70b3daf5379df2fa384d" - integrity sha512-iVb1mTcD8fuhSv3k99+5tlXu5N0v8/DPm2mO3WACLG6al1CGZH7v09HJyUb1TtYl/Z+KrM6pHSIJdZxP5A+xow== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-spread@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.0.tgz#d21ca099bbd53ab307a8621e019a7bd0f40cdcfb" - integrity sha512-Ao4MSYRaLAQczZVp9/7E7QHsCuK92yHRrmVNRe/SlEJjhzivq0BSn8mEraimL8wizHZ3fuaHxKH0iwzI13GyGg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - -"@babel/plugin-transform-sticky-regex@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.0.tgz#c35ea31a02d86be485f6aa510184b677a91738fd" - integrity sha512-/ntT2NljR9foobKk4E/YyOSwcGUXtYWv5tinMK/3RkypyNBNdhHUaq6Orw5DWq9ZcNlS03BIlEALFeQgeVAo4Q== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-strict-mode@^7.12.13": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-strict-mode/-/plugin-transform-strict-mode-7.16.0.tgz#2be5ad4f087c188cfed6f01e327a9ccd4dc0c488" - integrity sha512-lcLX2TEX4EI5fRQDV7dIWNJdLnyhVE7K5oHZkKpo/lnOP+7LdkrV9v/enjBxts+xLn56TGf6zbyB2rvYl1zbYQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-template-literals@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.0.tgz#a8eced3a8e7b8e2d40ec4ec4548a45912630d302" - integrity sha512-Rd4Ic89hA/f7xUSJQk5PnC+4so50vBoBfxjdQAdvngwidM8jYIBVxBZ/sARxD4e0yMXRbJVDrYf7dyRtIIKT6Q== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-typeof-symbol@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.0.tgz#8b19a244c6f8c9d668dca6a6f754ad6ead1128f2" - integrity sha512-++V2L8Bdf4vcaHi2raILnptTBjGEFxn5315YU+e8+EqXIucA+q349qWngCLpUYqqv233suJ6NOienIVUpS9cqg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-typescript@^7.16.0": - version "7.16.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz#cc0670b2822b0338355bc1b3d2246a42b8166409" - integrity sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-typescript" "^7.16.0" - -"@babel/plugin-transform-unicode-escapes@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.0.tgz#1a354064b4c45663a32334f46fa0cf6100b5b1f3" - integrity sha512-VFi4dhgJM7Bpk8lRc5CMaRGlKZ29W9C3geZjt9beuzSUrlJxsNwX7ReLwaL6WEvsOf2EQkyIJEPtF8EXjB/g2A== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-unicode-regex@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.0.tgz#293b80950177c8c85aede87cef280259fb995402" - integrity sha512-jHLK4LxhHjvCeZDWyA9c+P9XH1sOxRd1RO9xMtDVRAOND/PczPqizEtVdx4TQF/wyPaewqpT+tgQFYMnN/P94A== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/preset-env@^7.14.4": - version "7.16.4" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.4.tgz#4f6ec33b2a3fe72d6bfdcdf3859500232563a2e3" - integrity sha512-v0QtNd81v/xKj4gNKeuAerQ/azeNn/G1B1qMLeXOcV8+4TWlD2j3NV1u8q29SDFBXx/NBq5kyEAO+0mpRgacjA== - dependencies: - "@babel/compat-data" "^7.16.4" - "@babel/helper-compilation-targets" "^7.16.3" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.2" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.0" - "@babel/plugin-proposal-async-generator-functions" "^7.16.4" - "@babel/plugin-proposal-class-properties" "^7.16.0" - "@babel/plugin-proposal-class-static-block" "^7.16.0" - "@babel/plugin-proposal-dynamic-import" "^7.16.0" - "@babel/plugin-proposal-export-namespace-from" "^7.16.0" - "@babel/plugin-proposal-json-strings" "^7.16.0" - "@babel/plugin-proposal-logical-assignment-operators" "^7.16.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0" - "@babel/plugin-proposal-numeric-separator" "^7.16.0" - "@babel/plugin-proposal-object-rest-spread" "^7.16.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.16.0" - "@babel/plugin-proposal-optional-chaining" "^7.16.0" - "@babel/plugin-proposal-private-methods" "^7.16.0" - "@babel/plugin-proposal-private-property-in-object" "^7.16.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.16.0" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.16.0" - "@babel/plugin-transform-async-to-generator" "^7.16.0" - "@babel/plugin-transform-block-scoped-functions" "^7.16.0" - "@babel/plugin-transform-block-scoping" "^7.16.0" - "@babel/plugin-transform-classes" "^7.16.0" - "@babel/plugin-transform-computed-properties" "^7.16.0" - "@babel/plugin-transform-destructuring" "^7.16.0" - "@babel/plugin-transform-dotall-regex" "^7.16.0" - "@babel/plugin-transform-duplicate-keys" "^7.16.0" - "@babel/plugin-transform-exponentiation-operator" "^7.16.0" - "@babel/plugin-transform-for-of" "^7.16.0" - "@babel/plugin-transform-function-name" "^7.16.0" - "@babel/plugin-transform-literals" "^7.16.0" - "@babel/plugin-transform-member-expression-literals" "^7.16.0" - "@babel/plugin-transform-modules-amd" "^7.16.0" - "@babel/plugin-transform-modules-commonjs" "^7.16.0" - "@babel/plugin-transform-modules-systemjs" "^7.16.0" - "@babel/plugin-transform-modules-umd" "^7.16.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.0" - "@babel/plugin-transform-new-target" "^7.16.0" - "@babel/plugin-transform-object-super" "^7.16.0" - "@babel/plugin-transform-parameters" "^7.16.3" - "@babel/plugin-transform-property-literals" "^7.16.0" - "@babel/plugin-transform-regenerator" "^7.16.0" - "@babel/plugin-transform-reserved-words" "^7.16.0" - "@babel/plugin-transform-shorthand-properties" "^7.16.0" - "@babel/plugin-transform-spread" "^7.16.0" - "@babel/plugin-transform-sticky-regex" "^7.16.0" - "@babel/plugin-transform-template-literals" "^7.16.0" - "@babel/plugin-transform-typeof-symbol" "^7.16.0" - "@babel/plugin-transform-unicode-escapes" "^7.16.0" - "@babel/plugin-transform-unicode-regex" "^7.16.0" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.16.0" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.4.0" - babel-plugin-polyfill-regenerator "^0.3.0" - core-js-compat "^3.19.1" - semver "^6.3.0" - -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/preset-react@^7.13.13": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.16.0.tgz#f71d3e8dff5218478011df037fad52660ee6d82a" - integrity sha512-d31IFW2bLRB28uL1WoElyro8RH5l6531XfxMtCeCmp6RVAF1uTfxxUA0LH1tXl+psZdwfmIbwoG4U5VwgbhtLw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-transform-react-display-name" "^7.16.0" - "@babel/plugin-transform-react-jsx" "^7.16.0" - "@babel/plugin-transform-react-jsx-development" "^7.16.0" - "@babel/plugin-transform-react-pure-annotations" "^7.16.0" - -"@babel/preset-typescript@^7.14.5": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.0.tgz#b0b4f105b855fb3d631ec036cdc9d1ffd1fa5eac" - integrity sha512-txegdrZYgO9DlPbv+9QOVpMnKbOtezsLHWsnsRF4AjbSIsVaujrq1qg8HK0mxQpWv0jnejt0yEoW1uWpvbrDTg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-transform-typescript" "^7.16.0" - -"@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" - integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6" - integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A== - dependencies: - "@babel/code-frame" "^7.16.0" - "@babel/parser" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3", "@babel/traverse@^7.4.5": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.3.tgz#f63e8a938cc1b780f66d9ed3c54f532ca2d14787" - integrity sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag== - dependencies: - "@babel/code-frame" "^7.16.0" - "@babel/generator" "^7.16.0" - "@babel/helper-function-name" "^7.16.0" - "@babel/helper-hoist-variables" "^7.16.0" - "@babel/helper-split-export-declaration" "^7.16.0" - "@babel/parser" "^7.16.3" - "@babel/types" "^7.16.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.16.0", "@babel/types@^7.2.0", "@babel/types@^7.4.4": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" - integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg== - dependencies: - "@babel/helper-validator-identifier" "^7.15.7" - to-fast-properties "^2.0.0" - -"@choojs/findup@^0.2.0": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@choojs/findup/-/findup-0.2.1.tgz#ac13c59ae7be6e1da64de0779a0a7f03d75615a3" - integrity sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw== - dependencies: - commander "^2.15.1" - -"@csstools/convert-colors@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-2.0.0.tgz#6dd323583b40cfe05aaaca30debbb30f26742bbf" - integrity sha512-P7BVvddsP2Wl5v3drJ3ArzpdfXMqoZ/oHOV/yFiGFb3JQr9Z9UXZ9tnHAKJsO89lfprR1F9ExW3Yij21EjEBIA== - -"@discoveryjs/json-ext@^0.5.0": - version "0.5.5" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3" - integrity sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA== - -"@emotion/is-prop-valid@^0.8.8": - version "0.8.8" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" - integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== - dependencies: - "@emotion/memoize" "0.7.4" - -"@emotion/memoize@0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" - integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== - -"@emotion/stylis@^0.8.4": - version "0.8.5" - resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" - integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== - -"@emotion/unitless@^0.7.4": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" - integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== - -"@jetbrains/angular-elastic@^2.5.1": - version "2.5.1" - resolved "https://registry.yarnpkg.com/@jetbrains/angular-elastic/-/angular-elastic-2.5.1.tgz#ddfffdd3941eaf839fd29069fc8faf7536329988" - integrity sha512-/XU38+J5c3vKKoiwGmqze0UaKt7mnrR0mQJg1WxuZFBSTf6e1co8rN8bgxik0jAX5s8yXUMWhPhmrIYKaR140Q== - dependencies: - angular ">=1.0.6" - -"@jetbrains/babel-preset-jetbrains@^2.3.2": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@jetbrains/babel-preset-jetbrains/-/babel-preset-jetbrains-2.3.2.tgz#b62fab630080c5e78513e2cdbe85d4940f4e3164" - integrity sha512-hC8HpdxftzMc2OwwzKIsBzq/8paGT/+IcH7TZfy0RWusq0K1wWnjRQMH5o9J0RkdARlDnOxDxEHYA9fE6DFKLw== - dependencies: - "@babel/plugin-transform-runtime" "^7.14.3" - "@babel/plugin-transform-strict-mode" "^7.12.13" - "@babel/preset-env" "^7.14.4" - "@babel/preset-react" "^7.13.13" - "@babel/preset-typescript" "^7.14.5" - "@babel/runtime" "^7.14.0" - babel-plugin-angularjs-annotate "^0.10.0" - -"@jetbrains/icons@^3.18.0": - version "3.18.0" - resolved "https://registry.yarnpkg.com/@jetbrains/icons/-/icons-3.18.0.tgz#96d3ff8f9029b9f196a9a936cd2c6797aa2c17f2" - integrity sha512-aaKe4KVwjbnnbXEdWCVWMNwHrE1WCdwpVZYt468NXHukPX8KfnE8pGGuUcyEC/j4lXm+V8N24yGZ3GGMfq/wFA== - -"@jetbrains/logos@^1.4.27": - version "1.4.27" - resolved "https://registry.yarnpkg.com/@jetbrains/logos/-/logos-1.4.27.tgz#4412ed2abaf74756e44bb84643431fc270ec3031" - integrity sha512-1+S4mjh7Z9HliTlgJeemr+my4mD6HeEY0GH/qc8FKsY7jprFPsbJnfgiVdrhRFMtx7Rb4AKRjiM4CIqqweF+zA== - -"@jetbrains/postcss-require-hover@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@jetbrains/postcss-require-hover/-/postcss-require-hover-0.1.2.tgz#927f24fa7cb27e3a3ed2c4eca716e5a206577e18" - integrity sha512-U094mXSp0KOfqZLTlkPLz4vHdIZYm1gJFRFJP7nMrGA1OI4Nigwl0TUwFt/7YDNAff57Eo9Zttu9Ln5QoXguAw== - dependencies: - postcss "^6.0.1" - -"@jetbrains/ring-ui@^4.1.5": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@jetbrains/ring-ui/-/ring-ui-4.1.6.tgz#bb1d95a169dc5b8b0915258d772fbbd99ad739bf" - integrity sha512-/HFw77+gzN6YxsaGG5Wga4ZOwfs65GfailwCoY4Xdm05OqWHKIJmzTr0+Tc0w12Lg9Km7ymxrRIOQKcXOdjSFQ== - dependencies: - "@babel/core" "^7.16.0" - "@jetbrains/angular-elastic" "^2.5.1" - "@jetbrains/babel-preset-jetbrains" "^2.3.2" - "@jetbrains/icons" "^3.18.0" - "@jetbrains/logos" "^1.4.27" - "@jetbrains/postcss-require-hover" "^0.1.2" - "@ungap/url-search-params" "^0.2.2" - babel-loader "^8.2.3" - babel-plugin-transform-define "^2.0.1" - browserslist "^4.16.6" - change-case "^4.1.1" - classnames "^2.3.1" - combokeys "^3.0.1" - compile-code-loader "^1.0.0" - conic-gradient "^1.0.0" - css-loader "^6.5.1" - date-fns "^2.27.0" - deep-equal "^2.0.4" - element-resize-detector "^1.2.3" - es6-error "^4.1.1" - eslint-plugin-react-hooks "^4.3.0" - extricate-loader "^3.0.0" - fastdom "^1.0.10" - file-loader "^6.2.0" - focus-trap "^6.7.1" - focus-visible "^5.2.0" - highlight.js "^10.7.2" - html-loader "^3.0.1" - interpolate-loader "^2.0.1" - just-debounce-it "^3.0.1" - memoize-one "^6.0.0" - postcss "^8.4.4" - postcss-calc "^8.0.0" - postcss-flexbugs-fixes "^5.0.2" - postcss-font-family-system-ui "^5.0.0" - postcss-loader "^6.2.1" - postcss-modules-values-replace "^3.4.0" - postcss-preset-env "^7.0.1" - prop-types "^15.7.2" - react-markdown "^5.0.3" - react-movable "^3.0.2" - react-virtualized "^9.22.3" - react-waypoint "^10.1.0" - remark-breaks "^3.0.2" - remark-gfm "^1.0.0" - scrollbar-width "^3.1.1" - simply-uuid "^1.0.1" - sniffr "^1.2.0" - style-inject "^0.3.0" - style-loader "~3.3.1" - url-loader "^4.1.1" - util-deprecate "^1.0.2" - -"@mapbox/geojson-rewind@^0.5.0": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.1.tgz#adbe16dc683eb40e90934c51a5e28c7bbf44f4e1" - integrity sha512-eL7fMmfTBKjrb+VFHXCGv9Ot0zc3C0U+CwXo1IrP+EPwDczLoXv34Tgq3y+2mPSFNVUXgU42ILWJTC7145KPTA== - dependencies: - get-stream "^6.0.1" - minimist "^1.2.5" - -"@mapbox/geojson-types@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz#9aecf642cb00eab1080a57c4f949a65b4a5846d6" - integrity sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw== - -"@mapbox/jsonlint-lines-primitives@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234" - integrity sha1-zlblOfg1UrWNENZy6k1vya3HsjQ= - -"@mapbox/mapbox-gl-supported@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz#f60b6a55a5d8e5ee908347d2ce4250b15103dc8e" - integrity sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg== - -"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2" - integrity sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI= - -"@mapbox/tiny-sdf@^1.1.1": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz#424c620a96442b20402552be70a7f62a8407cc59" - integrity sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw== - -"@mapbox/unitbezier@^0.0.0": - version "0.0.0" - resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz#15651bd553a67b8581fb398810c98ad86a34524e" - integrity sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4= - -"@mapbox/vector-tile@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz#d3a74c90402d06e89ec66de49ec817ff53409666" - integrity sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw== - dependencies: - "@mapbox/point-geometry" "~0.1.0" - -"@mapbox/whoots-js@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe" - integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@plotly/d3-sankey-circular@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@plotly/d3-sankey-circular/-/d3-sankey-circular-0.33.1.tgz#15d1e0337e0e4b1135bdf0e2195c88adacace1a7" - integrity sha512-FgBV1HEvCr3DV7RHhDsPXyryknucxtfnLwPtCKKxdolKyTFYoLX/ibEfX39iFYIL7DYbVeRtP43dbFcrHNE+KQ== - dependencies: - d3-array "^1.2.1" - d3-collection "^1.0.4" - d3-shape "^1.2.0" - elementary-circuits-directed-graph "^1.0.4" - -"@plotly/d3-sankey@0.7.2": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@plotly/d3-sankey/-/d3-sankey-0.7.2.tgz#ddd5290d3b02c60037ced018a162644a2ccef33b" - integrity sha512-2jdVos1N3mMp3QW0k2q1ph7Gd6j5PY1YihBrwpkFnKqO+cqtZq3AdEYUeSGXMeLsBDQYiqTVcihYfk8vr5tqhw== - dependencies: - d3-array "1" - d3-collection "1" - d3-shape "^1.2.0" - -"@plotly/point-cluster@^3.1.9": - version "3.1.9" - resolved "https://registry.yarnpkg.com/@plotly/point-cluster/-/point-cluster-3.1.9.tgz#8ffec77fbf5041bf15401079e4fdf298220291c1" - integrity sha512-MwaI6g9scKf68Orpr1pHZ597pYx9uP8UEFXLPbsCmuw3a84obwz6pnMXGc90VhgDNeNiLEdlmuK7CPo+5PIxXw== - dependencies: - array-bounds "^1.0.1" - binary-search-bounds "^2.0.4" - clamp "^1.0.1" - defined "^1.0.0" - dtype "^2.0.0" - flatten-vertex-data "^1.0.2" - is-obj "^1.0.1" - math-log2 "^1.0.1" - parse-rect "^1.2.0" - pick-by-alias "^1.2.0" - -"@polka/url@^1.0.0-next.20": - version "1.0.0-next.21" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" - integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== - -"@turf/area@^6.0.1": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@turf/area/-/area-6.5.0.tgz#1d0d7aee01d8a4a3d4c91663ed35cc615f36ad56" - integrity sha512-xCZdiuojokLbQ+29qR6qoMD89hv+JAgWjLrwSEWL+3JV8IXKeNFl6XkEJz9HGkVpnXvQKJoRz4/liT+8ZZ5Jyg== - dependencies: - "@turf/helpers" "^6.5.0" - "@turf/meta" "^6.5.0" - -"@turf/bbox@^6.0.1": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@turf/bbox/-/bbox-6.5.0.tgz#bec30a744019eae420dac9ea46fb75caa44d8dc5" - integrity sha512-RBbLaao5hXTYyyg577iuMtDB8ehxMlUqHEJiMs8jT1GHkFhr6sYre3lmLsPeYEi/ZKj5TP5tt7fkzNdJ4GIVyw== - dependencies: - "@turf/helpers" "^6.5.0" - "@turf/meta" "^6.5.0" - -"@turf/centroid@^6.0.2": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@turf/centroid/-/centroid-6.5.0.tgz#ecaa365412e5a4d595bb448e7dcdacfb49eb0009" - integrity sha512-MwE1oq5E3isewPprEClbfU5pXljIK/GUOMbn22UM3IFPDJX0KeoyLNwghszkdmFp/qMGL/M13MMWvU+GNLXP/A== - dependencies: - "@turf/helpers" "^6.5.0" - "@turf/meta" "^6.5.0" - -"@turf/helpers@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@turf/helpers/-/helpers-6.5.0.tgz#f79af094bd6b8ce7ed2bd3e089a8493ee6cae82e" - integrity sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw== - -"@turf/meta@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@turf/meta/-/meta-6.5.0.tgz#b725c3653c9f432133eaa04d3421f7e51e0418ca" - integrity sha512-RrArvtsV0vdsCBegoBtOalgdSOfkBrTJ07VkpiCnq/491W67hnMWmDu7e6Ztw0C3WldRYTXkg3SumfdzZxLBHA== - dependencies: - "@turf/helpers" "^6.5.0" - -"@types/component-emitter@^1.2.10": - version "1.2.11" - resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" - integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== - -"@types/cookie@^0.4.0": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" - integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== - -"@types/cors@^2.8.8": - version "2.8.12" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" - integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== - -"@types/eslint-scope@^3.7.0": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e" - integrity sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.2.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.0.tgz#afd0519223c29c347087542cbaee2fedc0873b16" - integrity sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^0.0.50": - version "0.0.50" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== - -"@types/http-proxy@^1.17.5": - version "1.17.7" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.7.tgz#30ea85cc2c868368352a37f0d0d3581e24834c6f" - integrity sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w== - dependencies: - "@types/node" "*" - -"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" - integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== - -"@types/mdast@^3.0.0", "@types/mdast@^3.0.3": - version "3.0.10" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af" - integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA== - dependencies: - "@types/unist" "*" - -"@types/node@*", "@types/node@>=10.0.0": - version "16.11.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.11.tgz#6ea7342dfb379ea1210835bada87b3c512120234" - integrity sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/retry@^0.12.0": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" - integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== - -"@types/tabulator-tables@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/tabulator-tables/-/tabulator-tables-5.0.1.tgz#824fef3bef01c38a3bd934016a25e52e1043bf35" - integrity sha512-ieidxy+/bzMCPZsDeSw56DN9ipQ0K4Ts3ZUxPy4yCVExcAsezL4u2UYHBA+BxQ8l7QmEaERT/ctmBqjkRUhh+w== - -"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" - integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@ungap/url-search-params@^0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@ungap/url-search-params/-/url-search-params-0.2.2.tgz#2de3bdec21476a9b70ef11fd7b794752f9afa04c" - integrity sha512-qQsguKXZVKdCixOHX9jqnX/K/1HekPDpGKyEcXHT+zR6EjGA7S4boSuelL4uuPv6YfhN0n8c4UxW+v/Z3gM2iw== - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== - -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webpack-cli/configtest@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" - integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== - -"@webpack-cli/info@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" - integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== - dependencies: - envinfo "^7.7.3" - -"@webpack-cli/serve@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" - integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -a-big-triangle@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/a-big-triangle/-/a-big-triangle-1.0.3.tgz#eefd30b02a8f525e8b1f72bb6bb1b0c16751c794" - integrity sha1-7v0wsCqPUl6LH3K7a7GwwWdRx5Q= - dependencies: - gl-buffer "^2.1.1" - gl-vao "^1.2.0" - weak-map "^1.0.5" - -abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -abs-svg-path@^0.1.1, abs-svg-path@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/abs-svg-path/-/abs-svg-path-0.1.1.tgz#df601c8e8d2ba10d4a76d625e236a9a39c2723bf" - integrity sha1-32Acjo0roQ1KdtYl4japo5wnI78= - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-dynamic-import@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" - integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== - -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== - -acorn-jsx@^5.0.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.0.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^6.1.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.0.4: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== - -acorn@^8.4.1: - version "8.6.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" - integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== - -add-line-numbers@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/add-line-numbers/-/add-line-numbers-1.0.1.tgz#48dbbdea47dbd234deafeac6c93cea6f70b4b7e3" - integrity sha1-SNu96kfb0jTer+rGyTzqb3C0t+M= - dependencies: - pad-left "^1.0.2" - -affine-hull@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/affine-hull/-/affine-hull-1.0.0.tgz#763ff1d38d063ceb7e272f17ee4d7bbcaf905c5d" - integrity sha1-dj/x040GPOt+Jy8X7k17vK+QXF0= - dependencies: - robust-orientation "^1.1.3" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^6.12.4, ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.0, ajv@^8.8.0: - version "8.8.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" - integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -almost-equal@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/almost-equal/-/almost-equal-1.1.0.tgz#f851c631138757994276aa2efbe8dfa3066cccdd" - integrity sha1-+FHGMROHV5lCdqou++jfowZszN0= - -alpha-complex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/alpha-complex/-/alpha-complex-1.0.0.tgz#90865870d6b0542ae73c0c131d4ef989669b72d2" - integrity sha1-kIZYcNawVCrnPAwTHU75iWabctI= - dependencies: - circumradius "^1.0.0" - delaunay-triangulate "^1.1.6" - -alpha-shape@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/alpha-shape/-/alpha-shape-1.0.0.tgz#c83109923ecfda667d2163fe4f26fe24726f64a9" - integrity sha1-yDEJkj7P2mZ9IWP+Tyb+JHJvZKk= - dependencies: - alpha-complex "^1.0.0" - simplicial-complex-boundary "^1.0.0" - -angular@>=1.0.6: - version "1.8.2" - resolved "https://registry.yarnpkg.com/angular/-/angular-1.8.2.tgz#5983bbb5a9fa63e213cb7749199e0d352de3a2f1" - integrity sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw== - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -array-bounds@^1.0.0, array-bounds@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/array-bounds/-/array-bounds-1.0.1.tgz#da11356b4e18e075a4f0c86e1f179a67b7d7ea31" - integrity sha512-8wdW3ZGk6UjMPJx/glyEt0sLzzwAE1bhToPsO1W2pbpR2gULyxe3BjSiuJFheP50T/GgODVPz2fuMUmIywt8cQ== - -array-find-index@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-flatten@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -array-normalize@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/array-normalize/-/array-normalize-1.1.4.tgz#d75cec57383358af38efdf6a78071aa36ae4174c" - integrity sha512-fCp0wKFLjvSPmCn4F5Tiw4M3lpMZoHlCjfcs7nNzuj3vqQQ1/a8cgB9DXcpDSn18c+coLnaW7rqfcYCvKbyJXg== - dependencies: - array-bounds "^1.0.0" - -array-range@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/array-range/-/array-range-1.0.1.tgz#f56e46591843611c6a56f77ef02eda7c50089bfc" - integrity sha1-9W5GWRhDYRxqVvd+8C7afFAIm/w= - -array-rearrange@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/array-rearrange/-/array-rearrange-2.2.2.tgz#fa1a2acf8d02e88dd0c9602aa0e06a79158b2283" - integrity sha512-UfobP5N12Qm4Qu4fwLDIi2v6+wZsSf6snYSxAMeKhrh37YGnNWZPRmVEKc/2wfms53TLQnzfpG8wCx2Y/6NG1w== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -atob-lite@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-1.0.0.tgz#b88dca6006922b962094f7556826bab31c4a296b" - integrity sha1-uI3KYAaSK5YglPdVaCa6sxxKKWs= - -atob-lite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696" - integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY= - -autoprefixer@^10.4.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.0.tgz#c3577eb32a1079a440ec253e404eaf1eb21388c8" - integrity sha512-7FdJ1ONtwzV1G43GDD0kpVMn/qbiNqyOPMFTX5nRffI+7vgWoFEc6DcXOxHJxrWNDXrZh18eDsZjvZGUljSRGA== - dependencies: - browserslist "^4.17.5" - caniuse-lite "^1.0.30001272" - fraction.js "^4.1.1" - normalize-range "^0.1.2" - picocolors "^1.0.0" - postcss-value-parser "^4.1.0" - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -babel-loader@^8.2.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d" - integrity sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^1.4.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" - -babel-plugin-angularjs-annotate@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/babel-plugin-angularjs-annotate/-/babel-plugin-angularjs-annotate-0.10.0.tgz#4213b3aaae494a087aad0b8237c5d0716d22ca76" - integrity sha512-NPE7FOAxcLPCUR/kNkrhHIjoScR3RyIlRH3yRn79j8EZWtpILVnCOdA9yKfsOmRh6BHnLHKl8ZAThc+YDd/QwQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/types" "^7.2.0" - simple-is "~0.2.0" - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-polyfill-corejs2@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd" - integrity sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA== - dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.3.0" - semver "^6.1.1" - -babel-plugin-polyfill-corejs3@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz#0b571f4cf3d67f911512f5c04842a7b8e8263087" - integrity sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.0" - core-js-compat "^3.18.0" - -babel-plugin-polyfill-regenerator@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz#9ebbcd7186e1a33e21c5e20cae4e7983949533be" - integrity sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.0" - -"babel-plugin-styled-components@>= 1.12.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.2.tgz#0fac11402dc9db73698b55847ab1dc73f5197c54" - integrity sha512-7eG5NE8rChnNTDxa6LQfynwgHTVOYYaHJbUYSlOhk8QBXIQiMBKq4gyfHBBKPrxUcVBXVJL61ihduCpCQbuNbw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-module-imports" "^7.16.0" - babel-plugin-syntax-jsx "^6.18.0" - lodash "^4.17.11" - -babel-plugin-syntax-jsx@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= - -babel-plugin-transform-define@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-define/-/babel-plugin-transform-define-2.0.1.tgz#6a34fd6ea89989feb75721ee4cce817ec779be7f" - integrity sha512-7lDR1nFGSJHmhq/ScQtp9LTDmNE2yKPoLtwfiu+WQZnj84XL/J/5AZWZXwYcOwbDtUPhtg+y0yxTiP/oGDU6Kw== - dependencies: - lodash "^4.17.11" - traverse "0.6.6" - -bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== - -bail@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" - integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -barycentric@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/barycentric/-/barycentric-1.0.1.tgz#f1562bb891b26f4fec463a82eeda3657800ec688" - integrity sha1-8VYruJGyb0/sRjqC7to2V4AOxog= - dependencies: - robust-linear-solve "^1.0.0" - -base64-arraybuffer@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" - integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= - -base64id@2.0.0, base64id@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" - integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== - -batch-processor@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8" - integrity sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg= - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - -big-rat@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/big-rat/-/big-rat-1.0.4.tgz#768d093bb57930dd18ed575c7fca27dc5391adea" - integrity sha1-do0JO7V5MN0Y7Vdcf8on3FORreo= - dependencies: - bit-twiddle "^1.0.2" - bn.js "^4.11.6" - double-bits "^1.1.1" - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -binary-search-bounds@^2.0.0, binary-search-bounds@^2.0.3, binary-search-bounds@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/binary-search-bounds/-/binary-search-bounds-2.0.5.tgz#125e5bd399882f71e6660d4bf1186384e989fba7" - integrity sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA== - -bit-twiddle@^1.0.0, bit-twiddle@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bit-twiddle/-/bit-twiddle-1.0.2.tgz#0c6c1fabe2b23d17173d9a61b7b7093eb9e1769e" - integrity sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4= - -bit-twiddle@~0.0.1: - version "0.0.2" - resolved "https://registry.yarnpkg.com/bit-twiddle/-/bit-twiddle-0.0.2.tgz#c2eaebb952a3b94acc140497e1cdcd2f1a33f58e" - integrity sha1-wurruVKjuUrMFASX4c3NLxoz9Y4= - -bitmap-sdf@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/bitmap-sdf/-/bitmap-sdf-1.0.3.tgz#c99913e5729357a6fd350de34158180c013880b2" - integrity sha512-ojYySSvWTx21cbgntR942zgEgqj38wHctN64vr4vYRFf3GKVmI23YlA94meWGkFslidwLwGCsMy2laJ3g/94Sg== - dependencies: - clamp "^1.0.1" - -bl@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5" - integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - -bn.js@^4.11.6: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -body-parser@1.19.0, body-parser@^1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= - dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" - dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" - -bootstrap@4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7" - integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw== - -boundary-cells@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/boundary-cells/-/boundary-cells-2.0.2.tgz#ed28c5a2eb36500413e5714f8eec862ad8ffec14" - integrity sha512-/S48oUFYEgZMNvdqC87iYRbLBAPHYijPRNrNpm/sS8u7ijIViKm/hrV3YD4sx/W68AsG5zLMyBEditVHApHU5w== - -box-intersect@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/box-intersect/-/box-intersect-1.0.2.tgz#4693ad63e828868d0654b114e09364d6281f3fbd" - integrity sha512-yJeMwlmFPG1gIa7Rs/cGXeI6iOj6Qz5MG5PE61xLKpElUGzmJ4abm+qsLpzxKJFpsSDq742BQEocr8dI2t8Nxw== - dependencies: - bit-twiddle "^1.0.2" - typedarray-pool "^1.1.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1: - version "4.18.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f" - integrity sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ== - dependencies: - caniuse-lite "^1.0.30001280" - electron-to-chromium "^1.3.896" - escalade "^3.1.1" - node-releases "^2.0.1" - picocolors "^1.0.0" - -buble@^0.19.3: - version "0.19.8" - resolved "https://registry.yarnpkg.com/buble/-/buble-0.19.8.tgz#d642f0081afab66dccd897d7b6360d94030b9d3d" - integrity sha512-IoGZzrUTY5fKXVkgGHw3QeXFMUNBFv+9l8a4QJKG1JhG3nCMHTdEX1DCOg8568E2Q9qvAQIiSokv6Jsgx8p2cA== - dependencies: - acorn "^6.1.1" - acorn-dynamic-import "^4.0.0" - acorn-jsx "^5.0.1" - chalk "^2.4.2" - magic-string "^0.25.3" - minimist "^1.2.0" - os-homedir "^2.0.0" - regexpu-core "^4.5.4" - -bubleify@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/bubleify/-/bubleify-1.2.1.tgz#c11fa33fa59d5b9b747d4e486f43889084257f37" - integrity sha512-vp3NHmaQVoKaKWvi15FTMinPNjfp+47+/kFJ9ifezdMF/CBLArCxDVUh+FQE3qRxCRj1qyjJqilTBHHqlM8MaQ== - dependencies: - buble "^0.19.3" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camel-case@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - -camelcase@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" - integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== - -camelize@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" - integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= - -caniuse-lite@^1.0.30000655, caniuse-lite@^1.0.30001272, caniuse-lite@^1.0.30001280: - version "1.0.30001283" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz#8573685bdae4d733ef18f78d44ba0ca5fe9e896b" - integrity sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg== - -canvas-fit@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/canvas-fit/-/canvas-fit-1.5.0.tgz#ae13be66ade42f5be0e487e345fce30a5e5b5e5f" - integrity sha1-rhO+Zq3kL1vg5IfjRfzjCl5bXl8= - dependencies: - element-size "^1.1.1" - -capital-case@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" - integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - upper-case-first "^2.0.2" - -ccount@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" - integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== - -cdt2d@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cdt2d/-/cdt2d-1.0.0.tgz#4f212434bcd67bdb3d68b8fef4acdc2c54415141" - integrity sha1-TyEkNLzWe9s9aLj+9KzcLFRBUUE= - dependencies: - binary-search-bounds "^2.0.3" - robust-in-sphere "^1.1.3" - robust-orientation "^1.1.3" - -cell-orientation@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cell-orientation/-/cell-orientation-1.0.1.tgz#b504ad96a66ad286d9edd985a2253d03b80d2850" - integrity sha1-tQStlqZq0obZ7dmFoiU9A7gNKFA= - -chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -change-case@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" - integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A== - dependencies: - camel-case "^4.1.2" - capital-case "^1.0.4" - constant-case "^3.0.4" - dot-case "^3.0.4" - header-case "^2.0.4" - no-case "^3.0.4" - param-case "^3.0.4" - pascal-case "^3.1.2" - path-case "^3.0.4" - sentence-case "^3.0.4" - snake-case "^3.0.4" - tslib "^2.0.3" - -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== - -chokidar@3.5.2, chokidar@^3.5.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -circumcenter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/circumcenter/-/circumcenter-1.0.0.tgz#20d7aa13b17fbac52f52da4f54c6ac8b906ee529" - integrity sha1-INeqE7F/usUvUtpPVMasi5Bu5Sk= - dependencies: - dup "^1.0.0" - robust-linear-solve "^1.0.0" - -circumradius@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/circumradius/-/circumradius-1.0.0.tgz#706c447e3e55cd1ed3d11bd133e37c252cc305b5" - integrity sha1-cGxEfj5VzR7T0RvRM+N8JSzDBbU= - dependencies: - circumcenter "^1.0.0" - -clamp@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/clamp/-/clamp-1.0.1.tgz#66a0e64011816e37196828fdc8c8c147312c8634" - integrity sha1-ZqDmQBGBbjcZaCj9yMjBRzEshjQ= - -classnames@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== - -clean-css@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.2.tgz#d3a7c6ee2511011e051719838bdcf8314dc4548d" - integrity sha512-/eR8ru5zyxKzpBLv9YZvMXgTSSQn7AdkMItMYynsFgGwTveCRVam9IUPFloE85B4vAIj05IuKmmEoV7/AQjT0w== - dependencies: - source-map "~0.6.0" - -clean-pslg@^1.1.0, clean-pslg@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/clean-pslg/-/clean-pslg-1.1.2.tgz#bd35c7460b7e8ab5a9f761a5ed51796aa3c86c11" - integrity sha1-vTXHRgt+irWp92Gl7VF5aqPIbBE= - dependencies: - big-rat "^1.0.3" - box-intersect "^1.0.1" - nextafter "^1.0.0" - rat-vec "^1.1.1" - robust-segment-intersect "^1.0.1" - union-find "^1.0.2" - uniq "^1.0.1" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clsx@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" - integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== - -color-alpha@^1.0.4: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-alpha/-/color-alpha-1.1.3.tgz#71250189e9f02bba8261a94d5e7d5f5606d1749a" - integrity sha512-krPYBO1RSO5LH4AGb/b6z70O1Ip2o0F0+0cVFN5FN99jfQtZFT08rQyg+9oOBNJYAn3SRwJIFC8jUEOKz7PisA== - dependencies: - color-parse "^1.4.1" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-id@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/color-id/-/color-id-1.1.0.tgz#5e9159b99a73ac98f74820cb98a15fde3d7e034c" - integrity sha512-2iRtAn6dC/6/G7bBIo0uupVrIne1NsQJvJxZOBCzQOfk7jRq97feaDZ3RdzuHakRXXnHGNwglto3pqtRx1sX0g== - dependencies: - clamp "^1.0.1" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-normalize@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/color-normalize/-/color-normalize-1.5.2.tgz#d6c8beb02966849548f91a6ac0274c6f19924509" - integrity sha512-yYMIoyFJmUoKbCK6sBShljBWfkt8DXVfaZJn9/zvRJkF9eQJDbZhcYC6LdOVy40p4tfVwYYb9cXl8oqpu7pzBw== - dependencies: - color-rgba "^2.2.0" - dtype "^2.0.0" - -color-parse@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/color-parse/-/color-parse-1.4.2.tgz#78651f5d34df1a57f997643d86f7f87268ad4eb5" - integrity sha512-RI7s49/8yqDj3fECFZjUI1Yi0z/Gq1py43oNJivAIIDSyJiOZLfYCRQEgn8HEVAj++PcRe8AnL2XF0fRJ3BTnA== - dependencies: - color-name "^1.0.0" - -color-rgba@^2.1.1, color-rgba@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/color-rgba/-/color-rgba-2.3.0.tgz#d5eb481d7933d2542d1f222ea10ad40d159e9d35" - integrity sha512-z/5fMOY8/IzrBHPBk+n3ATNSM/1atXcHCRPTGPLlzYJ4fn7CRD46zzt3lkLtQ44cL8UIUU4JBXDVrhWj1khiwg== - dependencies: - color-parse "^1.4.1" - color-space "^1.14.6" - -color-space@^1.14.6: - version "1.16.0" - resolved "https://registry.yarnpkg.com/color-space/-/color-space-1.16.0.tgz#611781bca41cd8582a1466fd9e28a7d3d89772a2" - integrity sha512-A6WMiFzunQ8KEPFmj02OnnoUnqhmSaHaZ/0LVFcPTdlvm8+3aMJ5x1HRHy3bDHPkovkf4sS0f4wsVvwk71fKkg== - dependencies: - hsluv "^0.0.3" - mumath "^3.3.4" - -colorette@^2.0.10, colorette@^2.0.14: - version "2.0.16" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== - -colormap@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/colormap/-/colormap-2.3.2.tgz#4422c1178ce563806e265b96782737be85815abf" - integrity sha512-jDOjaoEEmA9AgA11B/jCSAvYE95r3wRoAyTf3LEHGiUVlNHJaL1mRkf5AyLSpQBVGfTEPwGEqCIzL+kgr2WgNA== - dependencies: - lerp "^1.0.3" - -colors@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combokeys@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/combokeys/-/combokeys-3.0.1.tgz#fc8ca5c3f5f2d2b03a458544cb88b14ab5f53f86" - integrity sha512-5nAfaLZ3oO3kA+/xdoL7t197UJTz2WWidyH3BBeU6hqHtvyFERICd0y3DQFrQkJFTKBrtUDck/xCLLoFpnjaCw== - -commander@2, commander@^2.15.1, commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^7.0.0, commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -commander@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -compare-angle@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/compare-angle/-/compare-angle-1.0.1.tgz#a4eb63416ea3c747fc6bd6c8b63668b4de4fa129" - integrity sha1-pOtjQW6jx0f8a9bItjZotN5PoSk= - dependencies: - robust-orientation "^1.0.2" - robust-product "^1.0.0" - robust-sum "^1.0.0" - signum "^0.0.0" - two-sum "^1.0.0" - -compare-cell@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/compare-cell/-/compare-cell-1.0.0.tgz#a9eb708f6e0e41aef7aa566b130f1968dc9e1aaa" - integrity sha1-qetwj24OQa73qlZrEw8ZaNyeGqo= - -compare-oriented-cell@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/compare-oriented-cell/-/compare-oriented-cell-1.0.1.tgz#6a149feef9dfc4f8fc62358e51dd42effbbdc39e" - integrity sha1-ahSf7vnfxPj8YjWOUd1C7/u9w54= - dependencies: - cell-orientation "^1.0.1" - compare-cell "^1.0.0" - -compile-code-loader@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/compile-code-loader/-/compile-code-loader-1.0.0.tgz#492002e69e0ce91dff42bec420bbaf575f4c9c4a" - integrity sha512-MFE1K+xC3f28urqFQ/7LGAzl/MZXzrFz5n3Tp83n6DwiucAVPkbB+z18D7Z0BqvmcuFiYy6hgm9sGrF/mbyZUw== - dependencies: - loader-utils "^2.0.0" - -component-emitter@~1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -compute-dims@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/compute-dims/-/compute-dims-1.1.0.tgz#6d5b712929b6c531af3b4d580ed5adacbbd77e0c" - integrity sha512-YHMiIKjH/8Eom8zATk3g8/lH3HxGCZcVQyEfEoVrfWI7od/WRpTgRGShnei3jArYSx77mQqPxZNokjGHCdLfxg== - dependencies: - utils-copy "^1.0.0" - validate.io-array "^1.0.6" - validate.io-matrix-like "^1.0.2" - validate.io-ndarray-like "^1.0.0" - validate.io-positive-integer "^1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -conic-gradient@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/conic-gradient/-/conic-gradient-1.0.0.tgz#0bd7aaddeaa14aa5a7c08b22a6ee90613f610479" - integrity sha512-TEmM3Ondx8nid2AN0Rsw6eQG7PgTUkL6gs90UqX1cNqO/bpt/H/Rw6DwbzoylQ9SSxqLG1SsteAr9/yBsAzdtw== - dependencies: - prefixfree "^1.0.0" - -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== - -connect@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" - integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== - dependencies: - debug "2.6.9" - finalhandler "1.1.2" - parseurl "~1.3.3" - utils-merge "1.0.1" - -"consolidated-events@^1.1.0 || ^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/consolidated-events/-/consolidated-events-2.0.2.tgz#da8d8f8c2b232831413d9e190dc11669c79f4a91" - integrity sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ== - -const-max-uint32@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/const-max-uint32/-/const-max-uint32-1.0.2.tgz#f009bb6230e678ed874dd2d6a9cd9e3cbfabb676" - integrity sha1-8Am7YjDmeO2HTdLWqc2ePL+rtnY= - -const-pinf-float64@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/const-pinf-float64/-/const-pinf-float64-1.0.0.tgz#f6efb0d79f9c0986d3e79f2923abf9b70b63d726" - integrity sha1-9u+w15+cCYbT558pI6v5twtj1yY= - -constant-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.4.tgz#3b84a9aeaf4cf31ec45e6bf5de91bdfb0589faf1" - integrity sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - upper-case "^2.0.2" - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -convex-hull@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/convex-hull/-/convex-hull-1.0.3.tgz#20a3aa6ce87f4adea2ff7d17971c9fc1c67e1fff" - integrity sha1-IKOqbOh/St6i/30XlxyfwcZ+H/8= - dependencies: - affine-hull "^1.0.0" - incremental-convex-hull "^1.0.1" - monotone-convex-hull-2d "^1.0.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -cookie@~0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== - -core-js-compat@^3.18.0, core-js-compat@^3.19.1: - version "3.19.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.19.2.tgz#18066a3404a302433cb0aa8be82dd3d75c76e5c4" - integrity sha512-ObBY1W5vx/LFFMaL1P5Udo4Npib6fu+cMokeziWkA8Tns4FcDemKF5j9JvaI5JhdkW8EQJQGJN1EcrzmEwuAqQ== - dependencies: - browserslist "^4.18.1" - semver "7.0.0" - -core-js@3.12.1: - version "3.12.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112" - integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cors@~2.8.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -cosmiconfig@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -country-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/country-regex/-/country-regex-1.1.0.tgz#51c333dcdf12927b7e5eeb9c10ac8112a6120896" - integrity sha1-UcMz3N8Sknt+XuucEKyBEqYSCJY= - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -css-blank-pseudo@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-2.0.0.tgz#10667f9c5f91e4fbde76c4efac55e8eaa6ed9967" - integrity sha512-n7fxEOyuvAVPLPb9kL4XTIK/gnp2fKQ7KFQ+9lj60W9pDn/jTr5LjS/kHHm+rES/YJ3m0S6+uJgYSuAJg9zOyA== - -css-color-keywords@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" - integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= - -css-font-size-keywords@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz#854875ace9aca6a8d2ee0d345a44aae9bb6db6cb" - integrity sha1-hUh1rOmspqjS7g00WkSq6btttss= - -css-font-stretch-keywords@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/css-font-stretch-keywords/-/css-font-stretch-keywords-1.0.1.tgz#50cee9b9ba031fb5c952d4723139f1e107b54b10" - integrity sha1-UM7puboDH7XJUtRyMTnx4Qe1SxA= - -css-font-style-keywords@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/css-font-style-keywords/-/css-font-style-keywords-1.0.1.tgz#5c3532813f63b4a1de954d13cea86ab4333409e4" - integrity sha1-XDUygT9jtKHelU0TzqhqtDM0CeQ= - -css-font-weight-keywords@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/css-font-weight-keywords/-/css-font-weight-keywords-1.0.0.tgz#9bc04671ac85bc724b574ef5d3ac96b0d604fd97" - integrity sha1-m8BGcayFvHJLV07106yWsNYE/Zc= - -css-font@^1.0.0, css-font@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-font/-/css-font-1.2.0.tgz#e73cbdc11fd87c8e6c928ad7098a9771c8c2b6e3" - integrity sha512-V4U4Wps4dPDACJ4WpgofJ2RT5Yqwe1lEH6wlOOaIxMi0gTjdIijsc5FmxQlZ7ZZyKQkkutqqvULOp07l9c7ssA== - dependencies: - css-font-size-keywords "^1.0.0" - css-font-stretch-keywords "^1.0.1" - css-font-style-keywords "^1.0.1" - css-font-weight-keywords "^1.0.0" - css-global-keywords "^1.0.1" - css-system-font-keywords "^1.0.0" - pick-by-alias "^1.2.0" - string-split-by "^1.0.0" - unquote "^1.1.0" - -css-global-keywords@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/css-global-keywords/-/css-global-keywords-1.0.1.tgz#72a9aea72796d019b1d2a3252de4e5aaa37e4a69" - integrity sha1-cqmupyeW0Bmx0qMlLeTlqqN+Smk= - -css-has-pseudo@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-2.0.0.tgz#43ae03a990cf3d9e7356837c6b500e04037606b5" - integrity sha512-URYSGI0ggED1W1/xOAH0Zn1bf+YL6tYh1PQzAPlWddEAyyO37mPqMbwCzSjTTNmeCR8BMNXSFLaT5xb6MERdAA== - dependencies: - postcss-selector-parser "^6" - -css-in-js-utils@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99" - integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA== - dependencies: - hyphenate-style-name "^1.0.2" - isobject "^3.0.1" - -css-in-js-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz#640ae6a33646d401fc720c54fc61c42cd76ae2bb" - integrity sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A== - dependencies: - hyphenate-style-name "^1.0.3" - -css-loader@6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.3.0.tgz#334d3500ff0a0c14cfbd4b0670088dbb5b5c1530" - integrity sha512-9NGvHOR+L6ps13Ilw/b216++Q8q+5RpJcVufCdW9S/9iCzs4KBDNa8qnA/n3FK/sSfWmH35PAIK/cfPi7LOSUg== - dependencies: - icss-utils "^5.1.0" - postcss "^8.2.15" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - semver "^7.3.5" - -css-loader@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" - integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== - dependencies: - icss-utils "^5.1.0" - postcss "^8.2.15" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - semver "^7.3.5" - -css-prefers-color-scheme@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-5.0.0.tgz#a89bc1abfe946e77a1a1e12dbc25a1439705933f" - integrity sha512-XpzVrdwbppHm+Nnrzcb/hQb8eq1aKv4U8Oh59LsLfTsbIZZ6Fvn9razb66ihH2aTJ0VhO9n9sVm8piyKXJAZMA== - -css-system-font-keywords@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz#85c6f086aba4eb32c571a3086affc434b84823ed" - integrity sha1-hcbwhquk6zLFcaMIav/ENLhII+0= - -css-to-react-native@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756" - integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ== - dependencies: - camelize "^1.0.0" - css-color-keywords "^1.0.0" - postcss-value-parser "^4.0.2" - -csscolorparser@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b" - integrity sha1-s085HupNqPPpgjHizNjfnAQfFxs= - -cssdb@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-5.0.0.tgz#96db23e70dda3d03a32346de611f0e79fee68b7f" - integrity sha512-Q7982SynYCtcLUBCPgUPFy2TZmDiFyimpdln8K2v4w2c07W4rXL7q5F1ksVAqOAQfxKyyUGCKSsioezKT5bU1Q== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -csstype@^3.0.10, csstype@^3.0.2: - version "3.0.10" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.10.tgz#2ad3a7bed70f35b965707c092e5f30b327c290e5" - integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA== - -cubic-hermite@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cubic-hermite/-/cubic-hermite-1.0.0.tgz#84e3b2f272b31454e8393b99bb6aed45168c14e5" - integrity sha1-hOOy8nKzFFToOTuZu2rtRRaMFOU= - -custom-event@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" - integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= - -cwise-compiler@^1.0.0, cwise-compiler@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/cwise-compiler/-/cwise-compiler-1.1.3.tgz#f4d667410e850d3a313a7d2db7b1e505bb034cc5" - integrity sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU= - dependencies: - uniq "^1.0.0" - -d3-array@1, d3-array@^1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" - integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== - -d3-collection@1, d3-collection@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" - integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== - -d3-color@1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" - integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== - -d3-dispatch@1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58" - integrity sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA== - -d3-force@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.2.1.tgz#fd29a5d1ff181c9e7f0669e4bd72bdb0e914ec0b" - integrity sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg== - dependencies: - d3-collection "1" - d3-dispatch "1" - d3-quadtree "1" - d3-timer "1" - -d3-hierarchy@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz#2f6bee24caaea43f8dc37545fa01628559647a83" - integrity sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ== - -d3-interpolate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" - integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== - dependencies: - d3-color "1" - -d3-path@1: - version "1.0.9" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" - integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== - -d3-quadtree@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.7.tgz#ca8b84df7bb53763fe3c2f24bd435137f4e53135" - integrity sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA== - -d3-shape@^1.2.0: - version "1.3.7" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" - integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== - dependencies: - d3-path "1" - -d3-timer@1: - version "1.0.10" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" - integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw== - -d3@^3.5.17: - version "3.5.17" - resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8" - integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g= - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -date-fns@^2.27.0: - version "2.28.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" - integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== - -date-format@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" - integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== - -date-format@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" - integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -debug@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@~4.3.1: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -deep-equal@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.5.tgz#55cd2fe326d83f9cbf7261ef0e060b3f724c5cb9" - integrity sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw== - dependencies: - call-bind "^1.0.0" - es-get-iterator "^1.1.1" - get-intrinsic "^1.0.1" - is-arguments "^1.0.4" - is-date-object "^1.0.2" - is-regex "^1.1.1" - isarray "^2.0.5" - object-is "^1.1.4" - object-keys "^1.1.1" - object.assign "^4.1.2" - regexp.prototype.flags "^1.3.0" - side-channel "^1.0.3" - which-boxed-primitive "^1.0.1" - which-collection "^1.0.1" - which-typed-array "^1.1.2" - -deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -default-gateway@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - -del@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" - integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - -delaunay-triangulate@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/delaunay-triangulate/-/delaunay-triangulate-1.1.6.tgz#5bbca21b078198d4bc3c75796a35cbb98c25954c" - integrity sha1-W7yiGweBmNS8PHV5ajXLuYwllUw= - dependencies: - incremental-convex-hull "^1.0.1" - uniq "^1.0.1" - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-kerning@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/detect-kerning/-/detect-kerning-2.1.2.tgz#4ecd548e4a5a3fc880fe2a50609312d000fa9fc2" - integrity sha512-I3JIbrnKPAntNLl1I6TpSQQdQ4AutYzv/sKMFKbepawV/hlH0GmYKhUoOEMd4xqaUHT+Bm0f4127lh5qs1m1tw== - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -di@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" - integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^1.3.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" - integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" - -dom-helpers@^5.1.3: - version "5.2.1" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" - integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^3.0.2" - -dom-serialize@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" - integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= - dependencies: - custom-event "~1.0.0" - ent "~2.2.0" - extend "^3.0.0" - void-elements "^2.0.0" - -dom-serializer@^1.0.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" - integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - -domelementtype@^2.0.1, domelementtype@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" - integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== - -domhandler@^4.0, domhandler@^4.2.0, domhandler@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" - integrity sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w== - dependencies: - domelementtype "^2.2.0" - -domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -double-bits@^1.1.0, double-bits@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/double-bits/-/double-bits-1.1.1.tgz#58abba45494da4d0fa36b73ad11a286c9184b1c6" - integrity sha1-WKu6RUlNpND6Nrc60RoobJGEscY= - -draw-svg-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/draw-svg-path/-/draw-svg-path-1.0.0.tgz#6f116d962dd314b99ea534d6f58dd66cdbd69379" - integrity sha1-bxFtli3TFLmepTTW9Y3WbNvWk3k= - dependencies: - abs-svg-path "~0.1.1" - normalize-svg-path "~0.1.0" - -dtype@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dtype/-/dtype-2.0.0.tgz#cd052323ce061444ecd2e8f5748f69a29be28434" - integrity sha1-zQUjI84GFETs0uj1dI9popvihDQ= - -dukat@0.5.8-rc.4: - version "0.5.8-rc.4" - resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" - integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== - dependencies: - google-protobuf "3.12.2" - typescript "3.9.5" - -dup@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dup/-/dup-1.0.0.tgz#51fc5ac685f8196469df0b905e934b20af5b4029" - integrity sha1-UfxaxoX4GWRp3wuQXpNLIK9bQCk= - -duplexer@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - -duplexify@^3.4.5: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -earcut@^2.1.5, earcut@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.3.tgz#d44ced2ff5a18859568e327dd9c7d46b16f55cf4" - integrity sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug== - -edges-to-adjacency-list@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/edges-to-adjacency-list/-/edges-to-adjacency-list-1.0.0.tgz#c146d2e084addfba74a51293c6e0199a49f757f1" - integrity sha1-wUbS4ISt37p0pRKTxuAZmkn3V/E= - dependencies: - uniq "^1.0.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.3.896: - version "1.4.5" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz#912e8fd1645edee2f0f212558f40916eb538b1f9" - integrity sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw== - -element-resize-detector@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.2.3.tgz#5078d9b99398fe4c589f8c8df94ff99e5d413ff3" - integrity sha512-+dhNzUgLpq9ol5tyhoG7YLoXL3ssjfFW+0gpszXPwRU6NjGr1fVHMEAF8fVzIiRJq57Nre0RFeIjJwI8Nh2NmQ== - dependencies: - batch-processor "1.0.0" - -element-size@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/element-size/-/element-size-1.1.1.tgz#64e5f159d97121631845bcbaecaf279c39b5e34e" - integrity sha1-ZOXxWdlxIWMYRby67K8nnDm1404= - -elementary-circuits-directed-graph@^1.0.4: - version "1.3.1" - resolved "https://registry.yarnpkg.com/elementary-circuits-directed-graph/-/elementary-circuits-directed-graph-1.3.1.tgz#31c5a1c69517de833127247e5460472168e9e1c1" - integrity sha512-ZEiB5qkn2adYmpXGnJKkxT8uJHlW/mxmBpmeqawEHzPxh9HkLD4/1mFYX5l0On+f6rcPIt8/EWlRU2Vo3fX6dQ== - dependencies: - strongly-connected-components "^1.0.1" - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.0.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -engine.io-parser@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" - integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== - dependencies: - base64-arraybuffer "0.1.4" - -engine.io@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.1.tgz#9a8f8a5ac5a5ea316183c489bf7f5b6cf91ace5b" - integrity sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w== - dependencies: - accepts "~1.3.4" - base64id "2.0.0" - cookie "~0.4.1" - cors "~2.8.5" - debug "~4.3.1" - engine.io-parser "~4.0.0" - ws "~7.4.2" - -enhanced-resolve@^3.1.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" - integrity sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24= - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - object-assign "^4.0.1" - tapable "^0.2.7" - -enhanced-resolve@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" - integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -ent@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" - integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -entities@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" - integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== - -envinfo@^7.7.3: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== - -errno@^0.1.3: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.18.5: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.1" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-get-iterator@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" - integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.0" - has-symbols "^1.0.1" - is-arguments "^1.1.0" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.5" - isarray "^2.0.5" - -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: - version "0.10.53" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" - integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.3" - next-tick "~1.0.0" - -es6-error@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -es6-iterator@^2.0.3, es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-promise@^4.0.3, es6-promise@^4.2.8: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= - dependencies: - es6-promise "^4.0.3" - -es6-symbol@^3.1.1, es6-symbol@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -es6-weak-map@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" - integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== - dependencies: - d "1" - es5-ext "^0.10.46" - es6-iterator "^2.0.3" - es6-symbol "^3.1.1" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escodegen@^1.11.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-plugin-react-hooks@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" - integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1, estraverse@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -ext@^1.1.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" - integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== - dependencies: - type "^2.5.0" - -extend@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extract-frustum-planes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/extract-frustum-planes/-/extract-frustum-planes-1.0.0.tgz#97d5703ff0564c8c3c6838cac45f9e7bc52c9ef5" - integrity sha1-l9VwP/BWTIw8aDjKxF+ee8UsnvU= - -extricate-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/extricate-loader/-/extricate-loader-3.0.0.tgz#7a9998e885046d5d6991d62d4887ee113ca1e0bd" - integrity sha512-Ts6BIh25xhFpeGaG0La345bYQdRXWv3ZvUwmJB6/QsXRywWrZmM1hGz8eZfQaBwy/HsmGOZevzGLesVtsrrmyg== - dependencies: - loader-utils "^1.1.0" - -falafel@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/falafel/-/falafel-2.2.4.tgz#b5d86c060c2412a43166243cb1bce44d1abd2819" - integrity sha512-0HXjo8XASWRmsS0X1EkhwEMZaD3Qvp7FfURwjLKjG1ghfRm/MGZl2r4cWUTv41KdNghTw4OUMmVtdGQp3+H+uQ== - dependencies: - acorn "^7.1.1" - foreach "^2.0.5" - isarray "^2.0.1" - object-keys "^1.0.6" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-isnumeric@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/fast-isnumeric/-/fast-isnumeric-1.1.4.tgz#e165786ff471c439e9ace2b8c8e66cceb47e2ea4" - integrity sha512-1mM8qOr2LYz8zGaUdmiqRDiuue00Dxjgcb1NQR7TnhLVh6sQyngP9xvLo7Sl7LZpP/sk5eb+bcyWXw530NTBZw== - dependencies: - is-string-blank "^1.0.1" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fastdom@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fastdom/-/fastdom-1.0.10.tgz#4f2c7c9b24e7e249fc70c63131842b859b92bf09" - integrity sha512-sbL4h358IlZn8VsTvA5TYnKVLYif46XhPEll+HTSxVtDSpqZEO/17D/QqlxE9V2K7AQ82GXeYeQLU2HWwKgk1A== - dependencies: - strictdom "^1.0.1" - -fastest-levenshtein@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" - integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" - integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -file-saver@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.2.tgz#06d6e728a9ea2df2cce2f8d9e84dfcdc338ec17a" - integrity sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw== - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -filtered-vector@^1.2.1: - version "1.2.5" - resolved "https://registry.yarnpkg.com/filtered-vector/-/filtered-vector-1.2.5.tgz#5a831278c159721dd3be34ef017842836ef3d461" - integrity sha512-5Vu6wdtQJ1O2nRmz39dIr9m3hEDq1skYby5k1cJQdNWK4dMgvYcUEiA/9j7NcKfNZ5LGxn8w2LSLiigyH7pTAw== - dependencies: - binary-search-bounds "^2.0.0" - cubic-hermite "^1.0.0" - -finalhandler@1.1.2, finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -flatten-vertex-data@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/flatten-vertex-data/-/flatten-vertex-data-1.0.2.tgz#889fd60bea506006ca33955ee1105175fb620219" - integrity sha512-BvCBFK2NZqerFTdMDgqfHBwxYWnxeCkwONsw6PvBMcUXqo8U/KDWwmXhqx1x2kLIg7DqIsJfOaJFOmlua3Lxuw== - dependencies: - dtype "^2.0.0" - -flatten@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" - integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== - -flip-pixels@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/flip-pixels/-/flip-pixels-1.0.2.tgz#aad7b7d9fc65932d5f27e2e4dac4b494140845e4" - integrity sha512-oXbJGbjDnfJRWPC7Va38EFhd+A8JWE5/hCiKcK8qjCdbLj9DTpsq6MEudwpRTH+V4qq+Jw7d3pUgQdSr3x3mTA== - -focus-trap@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.7.1.tgz#d474f86dbaf3c7fbf0d53cf0b12295f4f4068d10" - integrity sha512-a6czHbT9twVpy2RpkWQA9vIgwQgB9Nx1PIxNNUxQT4nugG/3QibwxO+tWTh9i+zSY2SFiX4pnYhTaFaQF/6ZAg== - dependencies: - tabbable "^5.2.1" - -focus-visible@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/focus-visible/-/focus-visible-5.2.0.tgz#3a9e41fccf587bd25dcc2ef045508284f0a4d6b3" - integrity sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ== - -follow-redirects@^1.0.0: - version "1.14.5" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381" - integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA== - -font-atlas@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/font-atlas/-/font-atlas-2.1.0.tgz#aa2d6dcf656a6c871d66abbd3dfbea2f77178348" - integrity sha512-kP3AmvX+HJpW4w3d+PiPR2X6E1yvsBXt2yhuCw+yReO9F1WYhvZwx3c95DGZGwg9xYzDGrgJYa885xmVA+28Cg== - dependencies: - css-font "^1.0.0" - -font-measure@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/font-measure/-/font-measure-1.2.2.tgz#41dbdac5d230dbf4db08865f54da28a475e83026" - integrity sha512-mRLEpdrWzKe9hbfaF3Qpr06TAjquuBVP5cHy4b3hyeNdjc9i0PO6HniGsX5vjL5OWv7+Bd++NiooNpT/s8BvIA== - dependencies: - css-font "^1.2.0" - -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - -format-util@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" - integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fraction.js@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.2.tgz#13e420a92422b6cf244dff8690ed89401029fbe8" - integrity sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -from2@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-monkey@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -gamma@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/gamma/-/gamma-0.1.0.tgz#3315643403bf27906ca80ab37c36ece9440ef330" - integrity sha1-MxVkNAO/J5BsqAqzfDbs6UQO8zA= - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -geojson-vt@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-3.2.1.tgz#f8adb614d2c1d3f6ee7c4265cad4bbf3ad60c8b7" - integrity sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-canvas-context@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-canvas-context/-/get-canvas-context-1.0.2.tgz#d6e7b50bc4e4c86357cd39f22647a84b73601e93" - integrity sha1-1ue1C8TkyGNXzTnyJkeoS3NgHpM= - -get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-stream@^6.0.0, get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -gl-axes3d@^1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/gl-axes3d/-/gl-axes3d-1.5.3.tgz#47e3dd6c21356a59349910ec01af58e28ea69fe9" - integrity sha512-KRYbguKQcDQ6PcB9g1pgqB8Ly4TY1DQODpPKiDTasyWJ8PxQk0t2Q7XoQQijNqvsguITCpVVCzNb5GVtIWiVlQ== - dependencies: - bit-twiddle "^1.0.2" - dup "^1.0.0" - extract-frustum-planes "^1.0.0" - gl-buffer "^2.1.2" - gl-mat4 "^1.2.0" - gl-shader "^4.2.1" - gl-state "^1.0.0" - gl-vao "^1.3.0" - gl-vec4 "^1.0.1" - glslify "^7.0.0" - robust-orientation "^1.1.3" - split-polygon "^1.0.0" - vectorize-text "^3.2.1" - -gl-buffer@^2.1.1, gl-buffer@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/gl-buffer/-/gl-buffer-2.1.2.tgz#2db8d9c1a5527fba0cdb91289c206e882b889cdb" - integrity sha1-LbjZwaVSf7oM25EonCBuiCuInNs= - dependencies: - ndarray "^1.0.15" - ndarray-ops "^1.1.0" - typedarray-pool "^1.0.0" - -gl-cone3d@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/gl-cone3d/-/gl-cone3d-1.5.2.tgz#66af5c33b7d5174034dfa3654a88e995998d92bc" - integrity sha512-1JNeHH4sUtUmDA4ZK7Om8/kShwb8IZVAsnxaaB7IPRJsNGciLj1sTpODrJGeMl41RNkex5kXD2SQFrzyEAR2Rw== - dependencies: - colormap "^2.3.1" - gl-buffer "^2.1.2" - gl-mat4 "^1.2.0" - gl-shader "^4.2.1" - gl-texture2d "^2.1.0" - gl-vao "^1.3.0" - gl-vec3 "^1.1.3" - glsl-inverse "^1.0.0" - glsl-out-of-range "^1.0.4" - glsl-specular-cook-torrance "^2.0.1" - glslify "^7.0.0" - ndarray "^1.0.18" - -gl-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gl-constants/-/gl-constants-1.0.0.tgz#597a504e364750ff50253aa35f8dea7af4a5d233" - integrity sha1-WXpQTjZHUP9QJTqjX43qevSl0jM= - -gl-contour2d@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/gl-contour2d/-/gl-contour2d-1.1.7.tgz#ca330cf8449673a9ca0b3f6726c83f8d35c7a50c" - integrity sha512-GdebvJ9DtT3pJDpoE+eU2q+Wo9S3MijPpPz5arZbhK85w2bARmpFpVfPaDlZqWkB644W3BlH8TVyvAo1KE4Bhw== - dependencies: - binary-search-bounds "^2.0.4" - cdt2d "^1.0.0" - clean-pslg "^1.1.2" - gl-buffer "^2.1.2" - gl-shader "^4.2.1" - glslify "^7.0.0" - iota-array "^1.0.0" - ndarray "^1.0.18" - surface-nets "^1.0.2" - -gl-error3d@^1.0.16: - version "1.0.16" - resolved "https://registry.yarnpkg.com/gl-error3d/-/gl-error3d-1.0.16.tgz#88a94952f5303d9cf5cb86806789a360777c5446" - integrity sha512-TGJewnKSp7ZnqGgG3XCF9ldrDbxZrO+OWlx6oIet4OdOM//n8xJ5isArnIV/sdPJnFbhfoLxWrW9f5fxHFRQ1A== - dependencies: - gl-buffer "^2.1.2" - gl-shader "^4.2.1" - gl-vao "^1.3.0" - glsl-out-of-range "^1.0.4" - glslify "^7.0.0" - -gl-fbo@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/gl-fbo/-/gl-fbo-2.0.5.tgz#0fa75a497cf787695530691c8f04abb6fb55fa22" - integrity sha1-D6daSXz3h2lVMGkcjwSrtvtV+iI= - dependencies: - gl-texture2d "^2.0.0" - -gl-format-compiler-error@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/gl-format-compiler-error/-/gl-format-compiler-error-1.0.3.tgz#0c79b1751899ce9732e86240f090aa41e98471a8" - integrity sha1-DHmxdRiZzpcy6GJA8JCqQemEcag= - dependencies: - add-line-numbers "^1.0.1" - gl-constants "^1.0.0" - glsl-shader-name "^1.0.0" - sprintf-js "^1.0.3" - -gl-heatmap2d@^1.0.6: - version "1.1.1" - resolved "https://registry.yarnpkg.com/gl-heatmap2d/-/gl-heatmap2d-1.1.1.tgz#dbbb2c288bfe277002fa50985155b0403d87640f" - integrity sha512-6Vo1fPIB1vQFWBA/MR6JAA16XuQuhwvZRbSjYEq++m4QV33iqjGS2HcVIRfJGX+fomd5eiz6bwkVZcKm69zQPw== - dependencies: - binary-search-bounds "^2.0.4" - gl-buffer "^2.1.2" - gl-shader "^4.2.1" - glslify "^7.0.0" - iota-array "^1.0.0" - typedarray-pool "^1.2.0" - -gl-line3d@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/gl-line3d/-/gl-line3d-1.2.1.tgz#632fc5b931a84a315995322b271aaf497e292609" - integrity sha512-eeb0+RI2ZBRqMYJK85SgsRiJK7c4aiOjcnirxv0830A3jmOc99snY3AbPcV8KvKmW0Yaf3KA4e+qNCbHiTOTnA== - dependencies: - binary-search-bounds "^2.0.4" - gl-buffer "^2.1.2" - gl-shader "^4.2.1" - gl-texture2d "^2.1.0" - gl-vao "^1.3.0" - glsl-out-of-range "^1.0.4" - glslify "^7.0.0" - ndarray "^1.0.18" - -gl-mat3@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gl-mat3/-/gl-mat3-1.0.0.tgz#89633219ca429379a16b9185d95d41713453b912" - integrity sha1-iWMyGcpCk3mha5GF2V1BcTRTuRI= - -gl-mat4@^1.0.1, gl-mat4@^1.0.2, gl-mat4@^1.0.3, gl-mat4@^1.1.2, gl-mat4@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/gl-mat4/-/gl-mat4-1.2.0.tgz#49d8a7636b70aa00819216635f4a3fd3f4669b26" - integrity sha512-sT5C0pwB1/e9G9AvAoLsoaJtbMGjfd/jfxo8jMCKqYYEnjZuFvqV5rehqar0538EmssjdDeiEWnKyBSTw7quoA== - -gl-matrix@^3.2.1: - version "3.4.3" - resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9" - integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA== - -gl-mesh3d@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/gl-mesh3d/-/gl-mesh3d-2.3.1.tgz#087a93c5431df923570ca51cfc691bab0d21a6b8" - integrity sha512-pXECamyGgu4/9HeAQSE5OEUuLBGS1aq9V4BCsTcxsND4fNLaajEkYKUz/WY2QSYElqKdsMBVsldGiKRKwlybqA== - dependencies: - barycentric "^1.0.1" - colormap "^2.3.1" - gl-buffer "^2.1.2" - gl-mat4 "^1.2.0" - gl-shader "^4.2.1" - gl-texture2d "^2.1.0" - gl-vao "^1.3.0" - glsl-out-of-range "^1.0.4" - glsl-specular-cook-torrance "^2.0.1" - glslify "^7.0.0" - ndarray "^1.0.18" - normals "^1.1.0" - polytope-closest-point "^1.0.0" - simplicial-complex-contour "^1.0.2" - typedarray-pool "^1.1.0" - -gl-plot2d@^1.4.5: - version "1.4.5" - resolved "https://registry.yarnpkg.com/gl-plot2d/-/gl-plot2d-1.4.5.tgz#6412b8b3f8df3e7d89c5955daac7059e04d657d4" - integrity sha512-6GmCN10SWtV+qHFQ1gjdnVubeHFVsm6P4zmo0HrPIl9TcdePCUHDlBKWAuE6XtFhiMKMj7R8rApOX8O8uXUYog== - dependencies: - binary-search-bounds "^2.0.4" - gl-buffer "^2.1.2" - gl-select-static "^2.0.7" - gl-shader "^4.2.1" - glsl-inverse "^1.0.0" - glslify "^7.0.0" - text-cache "^4.2.2" - -gl-plot3d@^2.4.6: - version "2.4.7" - resolved "https://registry.yarnpkg.com/gl-plot3d/-/gl-plot3d-2.4.7.tgz#b66e18c5affdd664f42c884acf7b82c60b41ee78" - integrity sha512-mLDVWrl4Dj0O0druWyHUK5l7cBQrRIJRn2oROEgrRuOgbbrLAzsREKefwMO0bA0YqkiZMFMnV5VvPA9j57X5Xg== - dependencies: - "3d-view" "^2.0.0" - a-big-triangle "^1.0.3" - gl-axes3d "^1.5.3" - gl-fbo "^2.0.5" - gl-mat4 "^1.2.0" - gl-select-static "^2.0.7" - gl-shader "^4.2.1" - gl-spikes3d "^1.0.10" - glslify "^7.0.0" - has-passive-events "^1.0.0" - is-mobile "^2.2.1" - mouse-change "^1.4.0" - mouse-event-offset "^3.0.2" - mouse-wheel "^1.2.0" - ndarray "^1.0.19" - right-now "^1.0.0" - -gl-pointcloud2d@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/gl-pointcloud2d/-/gl-pointcloud2d-1.0.3.tgz#f37e215f21ccb2e17f0604664e99fc3d6a4e611d" - integrity sha512-OS2e1irvJXVRpg/GziXj10xrFJm9kkRfFoB6BLUvkjCQV7ZRNNcs2CD+YSK1r0gvMwTg2T3lfLM3UPwNtz+4Xw== - dependencies: - gl-buffer "^2.1.2" - gl-shader "^4.2.1" - glslify "^7.0.0" - typedarray-pool "^1.1.0" - -gl-quat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gl-quat/-/gl-quat-1.0.0.tgz#0945ec923386f45329be5dc357b1c8c2d47586c5" - integrity sha1-CUXskjOG9FMpvl3DV7HIwtR1hsU= - dependencies: - gl-mat3 "^1.0.0" - gl-vec3 "^1.0.3" - gl-vec4 "^1.0.0" - -gl-scatter3d@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/gl-scatter3d/-/gl-scatter3d-1.2.3.tgz#83d63700ec2fe4e95b3d1cd613e86de9a6b5f603" - integrity sha512-nXqPlT1w5Qt51dTksj+DUqrZqwWAEWg0PocsKcoDnVNv0X8sGA+LBZ0Y+zrA+KNXUL0PPCX9WR9cF2uJAZl1Sw== - dependencies: - gl-buffer "^2.1.2" - gl-mat4 "^1.2.0" - gl-shader "^4.2.1" - gl-vao "^1.3.0" - glsl-out-of-range "^1.0.4" - glslify "^7.0.0" - is-string-blank "^1.0.1" - typedarray-pool "^1.1.0" - vectorize-text "^3.2.1" - -gl-select-box@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/gl-select-box/-/gl-select-box-1.0.4.tgz#47c11caa2b84f81e8bbfde08c6e39eeebb53d3d8" - integrity sha512-mKsCnglraSKyBbQiGq0Ila0WF+m6Tr+EWT2yfaMn/Sh9aMHq5Wt0F/l6Cf/Ed3CdERq5jHWAY5yxLviZteYu2w== - dependencies: - gl-buffer "^2.1.2" - gl-shader "^4.2.1" - glslify "^7.0.0" - -gl-select-static@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/gl-select-static/-/gl-select-static-2.0.7.tgz#ce7eb05ae0139009c15e2d2d0d731600b3dae5c0" - integrity sha512-OvpYprd+ngl3liEatBTdXhSyNBjwvjMSvV2rN0KHpTU+BTi4viEETXNZXFgGXY37qARs0L28ybk3UQEW6C5Nnw== - dependencies: - bit-twiddle "^1.0.2" - gl-fbo "^2.0.5" - ndarray "^1.0.18" - typedarray-pool "^1.1.0" - -gl-shader@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/gl-shader/-/gl-shader-4.3.1.tgz#56094cf3c06e802ac6c286b3b2166abce901d882" - integrity sha512-xLoN6XtRLlg97SEqtuzfKc+pVWpVkQ3YjDI1kuCale8tF7+zMhiKlMfmG4IMQPMdKJZQbIc/Ny8ZusEpfh5U+w== - dependencies: - gl-format-compiler-error "^1.0.2" - weakmap-shim "^1.1.0" - -gl-spikes2d@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/gl-spikes2d/-/gl-spikes2d-1.0.2.tgz#ef8dbcff6c7451dec2b751d7a3c593d09ad5457f" - integrity sha512-QVeOZsi9nQuJJl7NB3132CCv5KA10BWxAY2QgJNsKqbLsG53B/TrGJpjIAohnJftdZ4fT6b3ZojWgeaXk8bOOA== - -gl-spikes3d@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/gl-spikes3d/-/gl-spikes3d-1.0.10.tgz#e3b2b677a6f51750f23c064447af4f093da79305" - integrity sha512-lT3xroowOFxMvlhT5Mof76B2TE02l5zt/NIWljhczV2FFHgIVhA4jMrd5dIv1so1RXMBDJIKu0uJI3QKliDVLg== - dependencies: - gl-buffer "^2.1.2" - gl-shader "^4.2.1" - gl-vao "^1.3.0" - glslify "^7.0.0" - -gl-state@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gl-state/-/gl-state-1.0.0.tgz#262faa75835b0b9c532c12f38adc425d1d30cd17" - integrity sha1-Ji+qdYNbC5xTLBLzitxCXR0wzRc= - dependencies: - uniq "^1.0.0" - -gl-streamtube3d@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/gl-streamtube3d/-/gl-streamtube3d-1.4.1.tgz#bd2b725e00aa96989ce34b06ebf66a76f93e35ae" - integrity sha512-rH02v00kgwgdpkXVo7KsSoPp38bIAYR9TE1iONjcQ4cQAlDhrGRauqT/P5sUaOIzs17A2DxWGcXM+EpNQs9pUA== - dependencies: - gl-cone3d "^1.5.2" - gl-vec3 "^1.1.3" - gl-vec4 "^1.0.1" - glsl-inverse "^1.0.0" - glsl-out-of-range "^1.0.4" - glsl-specular-cook-torrance "^2.0.1" - glslify "^7.0.0" - -gl-surface3d@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/gl-surface3d/-/gl-surface3d-1.6.0.tgz#5fc915759a91e9962dcfbf3982296c462a032526" - integrity sha512-x15+u4712ysnB85G55RLJEml6mOB4VaDn0VTlXCc9JcjRl5Es10Tk7lhGGyiPtkCfHwvhnkxzYA1/rHHYN7Y0A== - dependencies: - binary-search-bounds "^2.0.4" - bit-twiddle "^1.0.2" - colormap "^2.3.1" - dup "^1.0.0" - gl-buffer "^2.1.2" - gl-mat4 "^1.2.0" - gl-shader "^4.2.1" - gl-texture2d "^2.1.0" - gl-vao "^1.3.0" - glsl-out-of-range "^1.0.4" - glsl-specular-beckmann "^1.1.2" - glslify "^7.0.0" - ndarray "^1.0.18" - ndarray-gradient "^1.0.0" - ndarray-ops "^1.2.2" - ndarray-pack "^1.2.1" - ndarray-scratch "^1.2.0" - surface-nets "^1.0.2" - typedarray-pool "^1.1.0" - -gl-text@^1.1.8: - version "1.3.1" - resolved "https://registry.yarnpkg.com/gl-text/-/gl-text-1.3.1.tgz#f36594464101b5b053178d6d219c3d08fb9144c8" - integrity sha512-/f5gcEMiZd+UTBJLTl3D+CkCB/0UFGTx3nflH8ZmyWcLkZhsZ1+Xx5YYkw2rgWAzgPeE35xCqBuHSoMKQVsR+w== - dependencies: - bit-twiddle "^1.0.2" - color-normalize "^1.5.0" - css-font "^1.2.0" - detect-kerning "^2.1.2" - es6-weak-map "^2.0.3" - flatten-vertex-data "^1.0.2" - font-atlas "^2.1.0" - font-measure "^1.2.2" - gl-util "^3.1.2" - is-plain-obj "^1.1.0" - object-assign "^4.1.1" - parse-rect "^1.2.0" - parse-unit "^1.0.1" - pick-by-alias "^1.2.0" - regl "^2.0.0" - to-px "^1.0.1" - typedarray-pool "^1.1.0" - -gl-texture2d@^2.0.0, gl-texture2d@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/gl-texture2d/-/gl-texture2d-2.1.0.tgz#ff6824e7e7c31a8ba6fdcdbe9e5c695d7e2187c7" - integrity sha1-/2gk5+fDGoum/c2+nlxpXX4hh8c= - dependencies: - ndarray "^1.0.15" - ndarray-ops "^1.2.2" - typedarray-pool "^1.1.0" - -gl-util@^3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/gl-util/-/gl-util-3.1.3.tgz#1e9a724f844b802597c6e30565d4c1e928546861" - integrity sha512-dvRTggw5MSkJnCbh74jZzSoTOGnVYK+Bt+Ckqm39CVcl6+zSsxqWk4lr5NKhkqXHL6qvZAU9h17ZF8mIskY9mA== - dependencies: - is-browser "^2.0.1" - is-firefox "^1.0.3" - is-plain-obj "^1.1.0" - number-is-integer "^1.0.1" - object-assign "^4.1.0" - pick-by-alias "^1.2.0" - weak-map "^1.0.5" - -gl-vao@^1.2.0, gl-vao@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/gl-vao/-/gl-vao-1.3.0.tgz#e9e92aa95588cab9d5c2f04b693440c3df691923" - integrity sha1-6ekqqVWIyrnVwvBLaTRAw99pGSM= - -gl-vec3@^1.0.2, gl-vec3@^1.0.3, gl-vec3@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/gl-vec3/-/gl-vec3-1.1.3.tgz#a47c62f918774a06cbed1b65bcd0288ecbb03826" - integrity sha512-jduKUqT0SGH02l8Yl+mV1yVsDfYgQAJyXGxkJQGyxPLHRiW25DwVIRPt6uvhrEMHftJfqhqKthRcyZqNEl9Xdw== - -gl-vec4@^1.0.0, gl-vec4@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gl-vec4/-/gl-vec4-1.0.1.tgz#97d96878281b14b532cbce101785dfd1cb340964" - integrity sha1-l9loeCgbFLUyy84QF4Xf0cs0CWQ= - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3, glob@^7.1.7: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globby@^11.0.1: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -glsl-inject-defines@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz#dd1aacc2c17fcb2bd3fc32411c6633d0d7b60fd4" - integrity sha1-3RqswsF/yyvT/DJBHGYz0Ne2D9Q= - dependencies: - glsl-token-inject-block "^1.0.0" - glsl-token-string "^1.0.1" - glsl-tokenizer "^2.0.2" - -glsl-inverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/glsl-inverse/-/glsl-inverse-1.0.0.tgz#12c0b1d065f558444d1e6feaf79b5ddf8a918ae6" - integrity sha1-EsCx0GX1WERNHm/q95td34qRiuY= - -glsl-out-of-range@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/glsl-out-of-range/-/glsl-out-of-range-1.0.4.tgz#3d73d083bc9ecc73efd45dfc7063c29e92c9c873" - integrity sha512-fCcDu2LCQ39VBvfe1FbhuazXEf0CqMZI9OYXrYlL6uUARG48CTAbL04+tZBtVM0zo1Ljx4OLu2AxNquq++lxWQ== - -glsl-resolve@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/glsl-resolve/-/glsl-resolve-0.0.1.tgz#894bef73910d792c81b5143180035d0a78af76d3" - integrity sha1-iUvvc5ENeSyBtRQxgANdCnivdtM= - dependencies: - resolve "^0.6.1" - xtend "^2.1.2" - -glsl-shader-name@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/glsl-shader-name/-/glsl-shader-name-1.0.0.tgz#a2c30b3ba73499befb0cc7184d7c7733dd4b487d" - integrity sha1-osMLO6c0mb77DMcYTXx3M91LSH0= - dependencies: - atob-lite "^1.0.0" - glsl-tokenizer "^2.0.2" - -glsl-specular-beckmann@^1.1.1, glsl-specular-beckmann@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/glsl-specular-beckmann/-/glsl-specular-beckmann-1.1.2.tgz#fce9056933ecdf2456278376a54d082893e775f1" - integrity sha1-/OkFaTPs3yRWJ4N2pU0IKJPndfE= - -glsl-specular-cook-torrance@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/glsl-specular-cook-torrance/-/glsl-specular-cook-torrance-2.0.1.tgz#a891cc06c8c7b4f4728702b4824fdacbb967d78f" - integrity sha1-qJHMBsjHtPRyhwK0gk/ay7ln148= - dependencies: - glsl-specular-beckmann "^1.1.1" - -glsl-token-assignments@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/glsl-token-assignments/-/glsl-token-assignments-2.0.2.tgz#a5d82ab78499c2e8a6b83cb69495e6e665ce019f" - integrity sha1-pdgqt4SZwuimuDy2lJXm5mXOAZ8= - -glsl-token-defines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/glsl-token-defines/-/glsl-token-defines-1.0.0.tgz#cb892aa959936231728470d4f74032489697fa9d" - integrity sha1-y4kqqVmTYjFyhHDU90AySJaX+p0= - dependencies: - glsl-tokenizer "^2.0.0" - -glsl-token-depth@^1.1.0, glsl-token-depth@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/glsl-token-depth/-/glsl-token-depth-1.1.2.tgz#23c5e30ee2bd255884b4a28bc850b8f791e95d84" - integrity sha1-I8XjDuK9JViEtKKLyFC495HpXYQ= - -glsl-token-descope@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/glsl-token-descope/-/glsl-token-descope-1.0.2.tgz#0fc90ab326186b82f597b2e77dc9e21efcd32076" - integrity sha1-D8kKsyYYa4L1l7LnfcniHvzTIHY= - dependencies: - glsl-token-assignments "^2.0.0" - glsl-token-depth "^1.1.0" - glsl-token-properties "^1.0.0" - glsl-token-scope "^1.1.0" - -glsl-token-inject-block@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/glsl-token-inject-block/-/glsl-token-inject-block-1.1.0.tgz#e1015f5980c1091824adaa2625f1dfde8bd00034" - integrity sha1-4QFfWYDBCRgkraomJfHf3ovQADQ= - -glsl-token-properties@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/glsl-token-properties/-/glsl-token-properties-1.0.1.tgz#483dc3d839f0d4b5c6171d1591f249be53c28a9e" - integrity sha1-SD3D2Dnw1LXGFx0VkfJJvlPCip4= - -glsl-token-scope@^1.1.0, glsl-token-scope@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/glsl-token-scope/-/glsl-token-scope-1.1.2.tgz#a1728e78df24444f9cb93fd18ef0f75503a643b1" - integrity sha1-oXKOeN8kRE+cuT/RjvD3VQOmQ7E= - -glsl-token-string@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/glsl-token-string/-/glsl-token-string-1.0.1.tgz#59441d2f857de7c3449c945666021ece358e48ec" - integrity sha1-WUQdL4V958NEnJRWZgIezjWOSOw= - -glsl-token-whitespace-trim@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/glsl-token-whitespace-trim/-/glsl-token-whitespace-trim-1.0.0.tgz#46d1dfe98c75bd7d504c05d7d11b1b3e9cc93b10" - integrity sha1-RtHf6Yx1vX1QTAXX0RsbPpzJOxA= - -glsl-tokenizer@^2.0.0, glsl-tokenizer@^2.0.2: - version "2.1.5" - resolved "https://registry.yarnpkg.com/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz#1c2e78c16589933c274ba278d0a63b370c5fee1a" - integrity sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA== - dependencies: - through2 "^0.6.3" - -glslify-bundle@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glslify-bundle/-/glslify-bundle-5.1.1.tgz#30d2ddf2e6b935bf44d1299321e3b729782c409a" - integrity sha512-plaAOQPv62M1r3OsWf2UbjN0hUYAB7Aph5bfH58VxJZJhloRNbxOL9tl/7H71K7OLJoSJ2ZqWOKk3ttQ6wy24A== - dependencies: - glsl-inject-defines "^1.0.1" - glsl-token-defines "^1.0.0" - glsl-token-depth "^1.1.1" - glsl-token-descope "^1.0.2" - glsl-token-scope "^1.1.1" - glsl-token-string "^1.0.1" - glsl-token-whitespace-trim "^1.0.0" - glsl-tokenizer "^2.0.2" - murmurhash-js "^1.0.0" - shallow-copy "0.0.1" - -glslify-deps@^1.2.5: - version "1.3.2" - resolved "https://registry.yarnpkg.com/glslify-deps/-/glslify-deps-1.3.2.tgz#c09ee945352bfc07ac2d8a1cc9e3de776328c72b" - integrity sha512-7S7IkHWygJRjcawveXQjRXLO2FTjijPDYC7QfZyAQanY+yGLCFHYnPtsGT9bdyHiwPTw/5a1m1M9hamT2aBpag== - dependencies: - "@choojs/findup" "^0.2.0" - events "^3.2.0" - glsl-resolve "0.0.1" - glsl-tokenizer "^2.0.0" - graceful-fs "^4.1.2" - inherits "^2.0.1" - map-limit "0.0.1" - resolve "^1.0.0" - -glslify@^7.0.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glslify/-/glslify-7.1.1.tgz#454d9172b410cb49864029c86d5613947fefd30b" - integrity sha512-bud98CJ6kGZcP9Yxcsi7Iz647wuDz3oN+IZsjCRi5X1PI7t/xPKeL0mOwXJjo+CRZMqvq0CkSJiywCcY7kVYog== - dependencies: - bl "^2.2.1" - concat-stream "^1.5.2" - duplexify "^3.4.5" - falafel "^2.1.0" - from2 "^2.3.0" - glsl-resolve "0.0.1" - glsl-token-whitespace-trim "^1.0.0" - glslify-bundle "^5.0.0" - glslify-deps "^1.2.5" - minimist "^1.2.5" - resolve "^1.1.5" - stack-trace "0.0.9" - static-eval "^2.0.5" - through2 "^2.0.1" - xtend "^4.0.0" - -google-protobuf@3.12.2: - version "3.12.2" - resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" - integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -grid-index@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.1.0.tgz#97f8221edec1026c8377b86446a7c71e79522ea7" - integrity sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -gzip-size@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" - integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== - dependencies: - duplexer "^0.1.2" - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-hover@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-hover/-/has-hover-1.0.1.tgz#3d97437aeb199c62b8ac08acbdc53d3bc52c17f7" - integrity sha1-PZdDeusZnGK4rAisvcU9O8UsF/c= - dependencies: - is-browser "^2.0.1" - -has-passive-events@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-passive-events/-/has-passive-events-1.0.0.tgz#75fc3dc6dada182c58f24ebbdc018276d1ea3515" - integrity sha512-2vSj6IeIsgvsRMyeQ0JaCX5Q3lX4zMn5HpoVc7MEhQ6pv8Iq9rsXjsp+E5ZwaT7T0xhMT0KmU8gtt1EFVdbJiw== - dependencies: - is-browser "^2.0.1" - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -he@1.2.0, he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -header-case@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.4.tgz#5a42e63b55177349cf405beb8d775acabb92c063" - integrity sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q== - dependencies: - capital-case "^1.0.4" - tslib "^2.0.3" - -highlight.js@^10.7.2: - version "10.7.3" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" - integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== - -hoist-non-react-statics@^3.0.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -hsluv@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/hsluv/-/hsluv-0.0.3.tgz#829107dafb4a9f8b52a1809ed02e091eade6754c" - integrity sha1-gpEH2vtKn4tSoYCe0C4JHq3mdUw= - -html-entities@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" - integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== - -html-loader@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-3.0.1.tgz#84d9094d7fc2e3fcd871d1524736953742758585" - integrity sha512-90Sxg9FhTkQEzmmHT2KOAQniTZgC72aifcfR0fZsuo1PJz0K4EXiTwxejTUombF8XShLj5RaZKYsUJhxR6G2dA== - dependencies: - html-minifier-terser "^6.0.2" - parse5 "^6.0.1" - -html-minifier-terser@^6.0.2: - version "6.1.0" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" - integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== - dependencies: - camel-case "^4.1.2" - clean-css "^5.2.2" - commander "^8.3.0" - he "^1.2.0" - param-case "^3.0.4" - relateurl "^0.2.7" - terser "^5.10.0" - -html-to-react@^1.3.4: - version "1.4.7" - resolved "https://registry.yarnpkg.com/html-to-react/-/html-to-react-1.4.7.tgz#a58129c1b77c6d4e047a647372bd194e25420b89" - integrity sha512-adtKiee5AtnuUhdB8bxbASRP2bW/A0OrlwysEuqZxXdURb0/1XR0m/woE1V5cJA1U5nyzAvk/PdFNO9S73DE/g== - dependencies: - domhandler "^4.0" - htmlparser2 "^7.0" - lodash.camelcase "^4.3.0" - ramda "^0.27.1" - -htmlparser2@^7.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5" - integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.2" - domutils "^2.8.0" - entities "^3.0.1" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-parser-js@>=0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" - integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== - -http-proxy-middleware@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz#7ef3417a479fb7666a571e09966c66a39bd2c15f" - integrity sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg== - dependencies: - "@types/http-proxy" "^1.17.5" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -hyphenate-style-name@^1.0.2, hyphenate-style-name@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" - integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== - dependencies: - postcss "^7.0.14" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -ieee754@^1.1.12: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^5.1.4: - version "5.1.9" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" - integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ== - -image-palette@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/image-palette/-/image-palette-2.1.0.tgz#d976525a1df75964ca125d2dba2741e92905547f" - integrity sha512-3ImSEWD26+xuQFdP0RWR4WSXadZwvgrFhjGNpMEapTG1tf2XrBFS2dlKK5hNgH4UIaSQlSUFRn1NeA+zULIWbQ== - dependencies: - color-id "^1.1.0" - pxls "^2.0.0" - quantize "^1.0.2" - -import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0" - integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -incremental-convex-hull@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/incremental-convex-hull/-/incremental-convex-hull-1.0.1.tgz#51428c14cb9d9a6144bfe69b2851fb377334be1e" - integrity sha1-UUKMFMudmmFEv+abKFH7N3M0vh4= - dependencies: - robust-orientation "^1.1.2" - simplicial-complex "^1.0.0" - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -inline-style-prefixer@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-6.0.1.tgz#c5c0e43ba8831707afc5f5bbfd97edf45c1fa7ae" - integrity sha512-AsqazZ8KcRzJ9YPN1wMH2aNM7lkWQ8tSPrW5uDk1ziYwiAPWSZnUsC7lfZq+BDqLqz0B4Pho5wscWcJzVvRzDQ== - dependencies: - css-in-js-utils "^2.0.0" - -internal-ip@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" - integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== - dependencies: - default-gateway "^6.0.0" - ipaddr.js "^1.9.1" - is-ip "^3.1.0" - p-event "^4.2.0" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -interpolate-loader@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/interpolate-loader/-/interpolate-loader-2.0.1.tgz#bdf0092a3d4732842ac29c20bd03f1fb34891705" - integrity sha512-X5/cKHUnAS5gV/oK9Z6pEjg2xVH5EGgnC5QmaOPwK/o7qMOMyyafwFL1mtH3yAK+COCjyaH56MOs9G8uXG12yA== - dependencies: - escape-string-regexp "^2.0.0" - loader-utils "^1.1.0" - -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - -interval-tree-1d@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/interval-tree-1d/-/interval-tree-1d-1.0.4.tgz#b44f657de7ddae69ea3f98e0a9ad4bb046b07d11" - integrity sha512-wY8QJH+6wNI0uh4pDQzMvl+478Qh7Rl4qLmqiluxALlNvl+I+o5x38Pw3/z7mDPTPS1dQalZJXsmbvxx5gclhQ== - dependencies: - binary-search-bounds "^2.0.0" - -invert-permutation@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-permutation/-/invert-permutation-1.0.0.tgz#a0a78042eadb36bc17551e787efd1439add54933" - integrity sha1-oKeAQurbNrwXVR54fv0UOa3VSTM= - -iota-array@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/iota-array/-/iota-array-1.0.0.tgz#81ef57fe5d05814cd58c2483632a99c30a0e8087" - integrity sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc= - -ip-regex@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" - integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== - -ip@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.1, ipaddr.js@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - -is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - -is-arguments@^1.0.4, is-arguments@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-base64@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-base64/-/is-base64-0.1.0.tgz#a6f20610c6ef4863a51cba32bc0222544b932622" - integrity sha512-WRRyllsGXJM7ZN7gPTCCQ/6wNPTRDwiWdPK66l5sJzcU/oOzcIcRRf0Rux8bkpox/1yjt0F6VJRsQOIG2qz5sg== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-blob@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-blob/-/is-blob-2.1.0.tgz#e36cd82c90653f1e1b930f11baf9c64216a05385" - integrity sha512-SZ/fTft5eUhQM6oF/ZaASFDEdbFVe89Imltn9uZr03wdKMcWNVYSMjQPFtg05QuNkt5l5c135ElvXEQG0rk4tw== - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-browser@^2.0.1, is-browser@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-browser/-/is-browser-2.1.0.tgz#fc084d59a5fced307d6708c59356bad7007371a9" - integrity sha512-F5rTJxDQ2sW81fcfOR1GnCXT6sVJC104fCyfj+mjpwNEwaPYSn5fte5jiHmBg3DHsIoL/l8Kvw5VN5SsTRcRFQ== - -is-buffer@^1.0.2: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-buffer@^2.0.0, is-buffer@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-core-module@^2.2.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" - integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1, is-date-object@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-firefox@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-firefox/-/is-firefox-1.0.3.tgz#2a2a1567783a417f6e158323108f3861b0918562" - integrity sha1-KioVZ3g6QX9uFYMjEI84YbCRhWI= - -is-float-array@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-float-array/-/is-float-array-1.0.0.tgz#96d67b1cbadf47ab1e05be208933acd386978a09" - integrity sha512-4ew1Sx6B6kEAl3T3NOM0yB94J3NZnBdNt4paw0e8nY73yHHTeTEhyQ3Lj7EQEnv5LD+GxNTaT4L46jcKjjpLiQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== - -is-iexplorer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-iexplorer/-/is-iexplorer-1.0.0.tgz#1d72bc66d3fe22eaf6170dda8cf10943248cfc76" - integrity sha1-HXK8ZtP+Iur2Fw3ajPEJQySM/HY= - -is-ip@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" - integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== - dependencies: - ip-regex "^4.0.0" - -is-map@^2.0.1, is-map@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== - -is-mobile@^2.2.1, is-mobile@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/is-mobile/-/is-mobile-2.2.2.tgz#f6c9c5d50ee01254ce05e739bdd835f1ed4e9954" - integrity sha512-wW/SXnYJkTjs++tVK5b6kVITZpAZPtUrt9SF80vvxGiF/Oywal+COk1jlRkiVq15RFNEQKQY31TkV24/1T5cVg== - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-inside@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-obj@^2.0.0, is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-obj@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.0.0.tgz#06c0999fd7574edf5a906ba5644ad0feb3a84d22" - integrity sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.0.4, is-regex@^1.1.1, is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-set@^2.0.1, is-set@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== - -is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string-blank@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-string-blank/-/is-string-blank-1.0.1.tgz#866dca066d41d2894ebdfd2d8fe93e586e583a03" - integrity sha512-9H+ZBCVs3L9OYqv8nuUAzpcT9OTgMD1yAWrG7ihlnibdkbtB850heAmYWxHuXc4CHy4lKeK69tN+ny1K7gBIrw== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-svg-path@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-svg-path/-/is-svg-path-1.0.2.tgz#77ab590c12b3d20348e5c7a13d0040c87784dda0" - integrity sha1-d6tZDBKz0gNI5cehPQBAyHeE3aA= - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79" - integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-abstract "^1.18.5" - foreach "^2.0.5" - has-tostringtag "^1.0.0" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-url-superb@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-url-superb/-/is-url-superb-4.0.0.tgz#b54d1d2499bb16792748ac967aa3ecb41a33a8c2" - integrity sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA== - -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakref@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" - integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== - dependencies: - call-bind "^1.0.0" - -is-weakset@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" - integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@^2.0.1, isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isbinaryfile@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" - integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -jest-worker@^27.0.6: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.0.tgz#fa10dddc611cbb47a4153543dd16a0c7e7fd745c" - integrity sha512-4WuKcUxtzxBoKOUFbt1MtTY9fJwPVD4aN/4Cgxee7OLetPZn5as2bjfZz98XSf2Zq1JFfhqPZpS+43BmWXKgCA== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jquery@3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5" - integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -json5@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" - integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== - dependencies: - minimist "^1.2.5" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -just-debounce-it@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/just-debounce-it/-/just-debounce-it-3.0.1.tgz#8c8a4c9327c9523366ec79ac9a959a938153bd2f" - integrity sha512-6EQWOpRV8fm/ame6XvGBSxvsjoMbqj7JS9TV/4Q9aOXt9DQw22GBfTGP6gTAqcBNN/PbzlwtwH7jtM0k9oe9pg== - -karma-chrome-launcher@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" - integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== - dependencies: - which "^1.2.1" - -karma-mocha@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" - integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== - dependencies: - minimist "^1.2.3" - -karma-sourcemap-loader@0.3.8: - version "0.3.8" - resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz#d4bae72fb7a8397328a62b75013d2df937bdcf9c" - integrity sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g== - dependencies: - graceful-fs "^4.1.2" - -karma-webpack@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" - integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== - dependencies: - glob "^7.1.3" - minimatch "^3.0.4" - webpack-merge "^4.1.5" - -karma@6.3.4: - version "6.3.4" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" - integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== - dependencies: - body-parser "^1.19.0" - braces "^3.0.2" - chokidar "^3.5.1" - colors "^1.4.0" - connect "^3.7.0" - di "^0.0.1" - dom-serialize "^2.2.1" - glob "^7.1.7" - graceful-fs "^4.2.6" - http-proxy "^1.18.1" - isbinaryfile "^4.0.8" - lodash "^4.17.21" - log4js "^6.3.0" - mime "^2.5.2" - minimatch "^3.0.4" - qjobs "^1.2.0" - range-parser "^1.2.1" - rimraf "^3.0.2" - socket.io "^3.1.0" - source-map "^0.6.1" - tmp "^0.2.1" - ua-parser-js "^0.7.28" - yargs "^16.1.1" - -kdbush@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-3.0.0.tgz#f8484794d47004cc2d85ed3a79353dbe0abc2bf0" - integrity sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew== - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klona@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" - integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== - -lerp@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/lerp/-/lerp-1.0.3.tgz#a18c8968f917896de15ccfcc28d55a6b731e776e" - integrity sha1-oYyJaPkXiW3hXM/MKNVaa3Med24= - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -loader-runner@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" - integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== - -loader-utils@^1.1.0, loader-utils@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" - integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - -loader-utils@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" - integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log4js@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" - integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== - dependencies: - date-format "^3.0.0" - debug "^4.1.1" - flatted "^2.0.1" - rfdc "^1.1.4" - streamroller "^2.2.4" - -longest-streak@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" - integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg== - -loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -magic-string@^0.25.3: - version "0.25.7" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" - integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== - dependencies: - sourcemap-codec "^1.4.4" - -make-dir@^3.0.2, make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -map-limit@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/map-limit/-/map-limit-0.0.1.tgz#eb7961031c0f0e8d001bf2d56fab685d58822f38" - integrity sha1-63lhAxwPDo0AG/LVb6toXViCLzg= - dependencies: - once "~1.3.0" - -mapbox-gl@1.10.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-1.10.1.tgz#7dbd53bdf2f78e45e125c1115e94dea286ef663c" - integrity sha512-0aHt+lFUpYfvh0kMIqXqNXqoYMuhuAsMlw87TbhWrw78Tx2zfuPI0Lx31/YPUgJ+Ire0tzQ4JnuBL7acDNXmMg== - dependencies: - "@mapbox/geojson-rewind" "^0.5.0" - "@mapbox/geojson-types" "^1.0.2" - "@mapbox/jsonlint-lines-primitives" "^2.0.2" - "@mapbox/mapbox-gl-supported" "^1.5.0" - "@mapbox/point-geometry" "^0.1.0" - "@mapbox/tiny-sdf" "^1.1.1" - "@mapbox/unitbezier" "^0.0.0" - "@mapbox/vector-tile" "^1.3.1" - "@mapbox/whoots-js" "^3.1.0" - csscolorparser "~1.0.3" - earcut "^2.2.2" - geojson-vt "^3.2.1" - gl-matrix "^3.2.1" - grid-index "^1.1.0" - minimist "^1.2.5" - murmurhash-js "^1.0.0" - pbf "^3.2.1" - potpack "^1.0.1" - quickselect "^2.0.0" - rw "^1.3.3" - supercluster "^7.0.0" - tinyqueue "^2.0.3" - vt-pbf "^3.1.1" - -marching-simplex-table@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/marching-simplex-table/-/marching-simplex-table-1.0.0.tgz#bc16256e0f8f9b558aa9b2872f8832d9433f52ea" - integrity sha1-vBYlbg+Pm1WKqbKHL4gy2UM/Uuo= - dependencies: - convex-hull "^1.0.3" - -markdown-table@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-2.0.0.tgz#194a90ced26d31fe753d8b9434430214c011865b" - integrity sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A== - dependencies: - repeat-string "^1.0.0" - -mat4-decompose@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mat4-decompose/-/mat4-decompose-1.0.4.tgz#65eb4fe39d70878f7a444eb4624d52f7e7eb2faf" - integrity sha1-ZetP451wh496RE60Yk1S9+frL68= - dependencies: - gl-mat4 "^1.0.1" - gl-vec3 "^1.0.2" - -mat4-interpolate@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mat4-interpolate/-/mat4-interpolate-1.0.4.tgz#55ffe9eb3c35295e2c0d5a9f7725d9068a89ff74" - integrity sha1-Vf/p6zw1KV4sDVqfdyXZBoqJ/3Q= - dependencies: - gl-mat4 "^1.0.1" - gl-vec3 "^1.0.2" - mat4-decompose "^1.0.3" - mat4-recompose "^1.0.3" - quat-slerp "^1.0.0" - -mat4-recompose@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mat4-recompose/-/mat4-recompose-1.0.4.tgz#3953c230ff2473dc772ee014a52c925cf81b0e4d" - integrity sha1-OVPCMP8kc9x3LuAUpSySXPgbDk0= - dependencies: - gl-mat4 "^1.0.1" - -math-log2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/math-log2/-/math-log2-1.0.1.tgz#fb8941be5f5ebe8979e718e6273b178e58694565" - integrity sha1-+4lBvl9evol55xjmJzsXjlhpRWU= - -matrix-camera-controller@^2.1.1, matrix-camera-controller@^2.1.3: - version "2.1.4" - resolved "https://registry.yarnpkg.com/matrix-camera-controller/-/matrix-camera-controller-2.1.4.tgz#d316ae5e99fe801610c1d7842ab54566d4c62411" - integrity sha512-zsPGPONclrKSImNpqqKDTcqFpWLAIwMXEJtCde4IFPOw1dA9udzFg4HOFytOTosOFanchrx7+Hqq6glLATIxBA== - dependencies: - binary-search-bounds "^2.0.0" - gl-mat4 "^1.1.2" - gl-vec3 "^1.0.3" - mat4-interpolate "^1.0.3" - -mdast-add-list-metadata@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz#95e73640ce2fc1fa2dcb7ec443d09e2bfe7db4cf" - integrity sha512-fB/VP4MJ0LaRsog7hGPxgOrSL3gE/2uEdZyDuSEnKCv/8IkYHiDkIQSbChiJoHyxZZXZ9bzckyRk+vNxFzh8rA== - dependencies: - unist-util-visit-parents "1.1.2" - -mdast-util-find-and-replace@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz#b7db1e873f96f66588c321f1363069abf607d1b5" - integrity sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA== - dependencies: - escape-string-regexp "^4.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" - -mdast-util-from-markdown@^0.8.0: - version "0.8.5" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c" - integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-string "^2.0.0" - micromark "~2.11.0" - parse-entities "^2.0.0" - unist-util-stringify-position "^2.0.0" - -mdast-util-gfm-autolink-literal@^0.1.0: - version "0.1.3" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz#9c4ff399c5ddd2ece40bd3b13e5447d84e385fb7" - integrity sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A== - dependencies: - ccount "^1.0.0" - mdast-util-find-and-replace "^1.1.0" - micromark "^2.11.3" - -mdast-util-gfm-strikethrough@^0.2.0: - version "0.2.3" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz#45eea337b7fff0755a291844fbea79996c322890" - integrity sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA== - dependencies: - mdast-util-to-markdown "^0.6.0" - -mdast-util-gfm-table@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz#af05aeadc8e5ee004eeddfb324b2ad8c029b6ecf" - integrity sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ== - dependencies: - markdown-table "^2.0.0" - mdast-util-to-markdown "~0.6.0" - -mdast-util-gfm-task-list-item@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz#70c885e6b9f543ddd7e6b41f9703ee55b084af10" - integrity sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A== - dependencies: - mdast-util-to-markdown "~0.6.0" - -mdast-util-gfm@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz#8ecddafe57d266540f6881f5c57ff19725bd351c" - integrity sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ== - dependencies: - mdast-util-gfm-autolink-literal "^0.1.0" - mdast-util-gfm-strikethrough "^0.2.0" - mdast-util-gfm-table "^0.1.0" - mdast-util-gfm-task-list-item "^0.1.0" - mdast-util-to-markdown "^0.6.1" - -mdast-util-to-markdown@^0.6.0, mdast-util-to-markdown@^0.6.1, mdast-util-to-markdown@~0.6.0: - version "0.6.5" - resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz#b33f67ca820d69e6cc527a93d4039249b504bebe" - integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ== - dependencies: - "@types/unist" "^2.0.0" - longest-streak "^2.0.0" - mdast-util-to-string "^2.0.0" - parse-entities "^2.0.0" - repeat-string "^1.0.0" - zwitch "^1.0.0" - -mdast-util-to-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" - integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -memfs@^3.2.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.0.tgz#8bc12062b973be6b295d4340595736a656f0a257" - integrity sha512-o/RfP0J1d03YwsAxyHxAYs2kyJp55AFkMazlFAZFR2I2IXkxiUTXRabJ6RmNNCQ83LAD2jy52Khj0m3OffpNdA== - dependencies: - fs-monkey "1.0.3" - -memoize-one@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" - integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== - -memory-fs@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromark-extension-gfm-autolink-literal@~0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz#53866c1f0c7ef940ae7ca1f72c6faef8fed9f204" - integrity sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw== - dependencies: - micromark "~2.11.3" - -micromark-extension-gfm-strikethrough@~0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz#96cb83356ff87bf31670eefb7ad7bba73e6514d1" - integrity sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw== - dependencies: - micromark "~2.11.0" - -micromark-extension-gfm-table@~0.4.0: - version "0.4.3" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz#4d49f1ce0ca84996c853880b9446698947f1802b" - integrity sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA== - dependencies: - micromark "~2.11.0" - -micromark-extension-gfm-tagfilter@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz#d9f26a65adee984c9ccdd7e182220493562841ad" - integrity sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q== - -micromark-extension-gfm-task-list-item@~0.3.0: - version "0.3.3" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz#d90c755f2533ed55a718129cee11257f136283b8" - integrity sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ== - dependencies: - micromark "~2.11.0" - -micromark-extension-gfm@^0.3.0: - version "0.3.3" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz#36d1a4c089ca8bdfd978c9bd2bf1a0cb24e2acfe" - integrity sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A== - dependencies: - micromark "~2.11.0" - micromark-extension-gfm-autolink-literal "~0.5.0" - micromark-extension-gfm-strikethrough "~0.6.5" - micromark-extension-gfm-table "~0.4.0" - micromark-extension-gfm-tagfilter "~0.3.0" - micromark-extension-gfm-task-list-item "~0.3.0" - -micromark@^2.11.3, micromark@~2.11.0, micromark@~2.11.3: - version "2.11.4" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a" - integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== - dependencies: - debug "^4.0.0" - parse-entities "^2.0.0" - -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": - version "1.51.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== - -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24: - version "2.1.34" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" - integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== - dependencies: - mime-db "1.51.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.5.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@^0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mocha@9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" - integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.7" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.25" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.1.5" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -monotone-convex-hull-2d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/monotone-convex-hull-2d/-/monotone-convex-hull-2d-1.0.1.tgz#47f5daeadf3c4afd37764baa1aa8787a40eee08c" - integrity sha1-R/Xa6t88Sv03dkuqGqh4ekDu4Iw= - dependencies: - robust-orientation "^1.1.3" - -mouse-change@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/mouse-change/-/mouse-change-1.4.0.tgz#c2b77e5bfa34a43ce1445c8157a4e4dc9895c14f" - integrity sha1-wrd+W/o0pDzhRFyBV6Tk3JiVwU8= - dependencies: - mouse-event "^1.0.0" - -mouse-event-offset@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/mouse-event-offset/-/mouse-event-offset-3.0.2.tgz#dfd86a6e248c6ba8cad53b905d5037a2063e9984" - integrity sha1-39hqbiSMa6jK1TuQXVA3ogY+mYQ= - -mouse-event@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/mouse-event/-/mouse-event-1.0.5.tgz#b3789edb7109997d5a932d1d01daa1543a501732" - integrity sha1-s3ie23EJmX1aky0dAdqhVDpQFzI= - -mouse-wheel@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mouse-wheel/-/mouse-wheel-1.2.0.tgz#6d2903b1ea8fb48e61f1b53b9036773f042cdb5c" - integrity sha1-bSkDseqPtI5h8bU7kDZ3PwQs21w= - dependencies: - right-now "^1.0.0" - signum "^1.0.0" - to-px "^1.0.1" - -mrmime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.0.tgz#14d387f0585a5233d291baba339b063752a2398b" - integrity sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== - dependencies: - dns-packet "^1.3.1" - thunky "^1.0.2" - -mumath@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/mumath/-/mumath-3.3.4.tgz#48d4a0f0fd8cad4e7b32096ee89b161a63d30bbf" - integrity sha1-SNSg8P2MrU57Mglu6JsWGmPTC78= - dependencies: - almost-equal "^1.1.0" - -murmurhash-js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51" - integrity sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E= - -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== - -nanoid@^3.1.30: - version "3.1.30" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" - integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== - -ndarray-extract-contour@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ndarray-extract-contour/-/ndarray-extract-contour-1.0.1.tgz#0aee113a3a33b226b90c4888cf877bf4751305e4" - integrity sha1-Cu4ROjozsia5DEiIz4d79HUTBeQ= - dependencies: - typedarray-pool "^1.0.0" - -ndarray-gradient@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ndarray-gradient/-/ndarray-gradient-1.0.1.tgz#16126a78ac241162248224aa662b6db6a5885402" - integrity sha512-+xONVi7xxTCGL6KOb11Yyoe0tPNqAUKF39CvFoRjL5pdOmPd2G2pckK9lD5bpLF3q45LLnYNyiUSJSdNmQ2MTg== - dependencies: - cwise-compiler "^1.0.0" - dup "^1.0.0" - -ndarray-linear-interpolate@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ndarray-linear-interpolate/-/ndarray-linear-interpolate-1.0.0.tgz#78bc92b85b9abc15b6e67ee65828f9e2137ae72b" - integrity sha1-eLySuFuavBW25n7mWCj54hN65ys= - -ndarray-ops@^1.1.0, ndarray-ops@^1.2.1, ndarray-ops@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/ndarray-ops/-/ndarray-ops-1.2.2.tgz#59e88d2c32a7eebcb1bc690fae141579557a614e" - integrity sha1-WeiNLDKn7ryxvGkPrhQVeVV6YU4= - dependencies: - cwise-compiler "^1.0.0" - -ndarray-pack@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ndarray-pack/-/ndarray-pack-1.2.1.tgz#8caebeaaa24d5ecf70ff86020637977da8ee585a" - integrity sha1-jK6+qqJNXs9w/4YCBjeXfajuWFo= - dependencies: - cwise-compiler "^1.1.2" - ndarray "^1.0.13" - -ndarray-scratch@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ndarray-scratch/-/ndarray-scratch-1.2.0.tgz#6304636d62eba93db4727ac13c693341dba50e01" - integrity sha1-YwRjbWLrqT20cnrBPGkzQdulDgE= - dependencies: - ndarray "^1.0.14" - ndarray-ops "^1.2.1" - typedarray-pool "^1.0.2" - -ndarray-sort@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ndarray-sort/-/ndarray-sort-1.0.1.tgz#fea05b4cb834c7f4e0216a354f3ca751300dfd6a" - integrity sha1-/qBbTLg0x/TgIWo1TzynUTAN/Wo= - dependencies: - typedarray-pool "^1.0.0" - -ndarray@^1.0.11, ndarray@^1.0.13, ndarray@^1.0.14, ndarray@^1.0.15, ndarray@^1.0.18, ndarray@^1.0.19: - version "1.0.19" - resolved "https://registry.yarnpkg.com/ndarray/-/ndarray-1.0.19.tgz#6785b5f5dfa58b83e31ae5b2a058cfd1ab3f694e" - integrity sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ== - dependencies: - iota-array "^1.0.0" - is-buffer "^1.0.2" - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -next-tick@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= - -nextafter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/nextafter/-/nextafter-1.0.0.tgz#b7d77b535310e3e097e6025abb0a903477ec1a3a" - integrity sha1-t9d7U1MQ4+CX5gJauwqQNHfsGjo= - dependencies: - double-bits "^1.1.0" - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== - -node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= - -normalize-svg-path@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz#0e614eca23c39f0cffe821d6be6cd17e569a766c" - integrity sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg== - dependencies: - svg-arc-to-cubic-bezier "^3.0.0" - -normalize-svg-path@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/normalize-svg-path/-/normalize-svg-path-0.1.0.tgz#456360e60ece75fbef7b5d7e160480e7ffd16fe5" - integrity sha1-RWNg5g7Odfvve11+FgSA5//Rb+U= - -normals@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/normals/-/normals-1.1.0.tgz#325b595ed34afe467a6c55a14fd9085787ff59c0" - integrity sha1-MltZXtNK/kZ6bFWhT9kIV4f/WcA= - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -number-is-integer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-integer/-/number-is-integer-1.0.1.tgz#e59bca172ffed27318e79c7ceb6cb72c095b2152" - integrity sha1-5ZvKFy/+0nMY55x862y3LAlbIVI= - dependencies: - is-finite "^1.0.1" - -numeric@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/numeric/-/numeric-1.2.6.tgz#765b02bef97988fcf880d4eb3f36b80fa31335aa" - integrity sha1-dlsCvvl5iPz4gNTrPza4D6MTNao= - -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== - -object-is@^1.0.1, object-is@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.0.12, object-keys@^1.0.6, object-keys@^1.0.9, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.0, object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -once@~1.3.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" - integrity sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA= - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.9: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -opener@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" - integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -orbit-camera-controller@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/orbit-camera-controller/-/orbit-camera-controller-4.0.0.tgz#6e2b36f0e7878663c330f50da9b7ce686c277005" - integrity sha1-bis28OeHhmPDMPUNqbfOaGwncAU= - dependencies: - filtered-vector "^1.2.1" - gl-mat4 "^1.0.3" - -os-homedir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-2.0.0.tgz#a0c76bb001a8392a503cbd46e7e650b3423a923c" - integrity sha512-saRNz0DSC5C/I++gFIaJTXoFJMRwiP5zHar5vV3xQ2TkgEw6hDCcU5F272JjUylpiVgBrZNQHnfjkLabTfb92Q== - -p-event@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-retry@^4.5.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" - integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== - dependencies: - "@types/retry" "^0.12.0" - retry "^0.13.1" - -p-timeout@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -pad-left@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pad-left/-/pad-left-1.0.2.tgz#19e5735ea98395a26cedc6ab926ead10f3100d4c" - integrity sha1-GeVzXqmDlaJs7carkm6tEPMQDUw= - dependencies: - repeat-string "^1.3.0" - -param-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" - integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parenthesis@^3.1.5: - version "3.1.8" - resolved "https://registry.yarnpkg.com/parenthesis/-/parenthesis-3.1.8.tgz#3457fccb8f05db27572b841dad9d2630b912f125" - integrity sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw== - -parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse-rect@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parse-rect/-/parse-rect-1.2.0.tgz#e0a5b0dbaaaee637a0a1eb9779969e19399d8dec" - integrity sha512-4QZ6KYbnE6RTwg9E0HpLchUM9EZt6DnDxajFZZDSV4p/12ZJEvPO702DZpGvRYEPo00yKDys7jASi+/w7aO8LA== - dependencies: - pick-by-alias "^1.2.0" - -parse-svg-path@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/parse-svg-path/-/parse-svg-path-0.1.2.tgz#7a7ec0d1eb06fa5325c7d3e009b859a09b5d49eb" - integrity sha1-en7A0esG+lMlx9PgCbhZoJtdSes= - -parse-unit@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-unit/-/parse-unit-1.0.1.tgz#7e1bb6d5bef3874c28e392526a2541170291eecf" - integrity sha1-fhu21b7zh0wo45JSaiVBFwKR7s8= - -parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -path-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/path-case/-/path-case-3.0.4.tgz#9168645334eb942658375c56f80b4c0cb5f82c6f" - integrity sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pbf@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.2.1.tgz#b4c1b9e72af966cd82c6531691115cc0409ffe2a" - integrity sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ== - dependencies: - ieee754 "^1.1.12" - resolve-protobuf-schema "^2.1.0" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -permutation-parity@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/permutation-parity/-/permutation-parity-1.0.0.tgz#0174d51fca704b11b9a4b152b23d537fdc6b5ef4" - integrity sha1-AXTVH8pwSxG5pLFSsj1Tf9xrXvQ= - dependencies: - typedarray-pool "^1.0.0" - -permutation-rank@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/permutation-rank/-/permutation-rank-1.0.0.tgz#9fd98bbcecf08fbf5994b5eadc94a62e679483b5" - integrity sha1-n9mLvOzwj79ZlLXq3JSmLmeUg7U= - dependencies: - invert-permutation "^1.0.0" - typedarray-pool "^1.0.0" - -pick-by-alias@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pick-by-alias/-/pick-by-alias-1.2.0.tgz#5f7cb2b1f21a6e1e884a0c87855aa4a37361107b" - integrity sha1-X3yysfIabh6ISgyHhVqko3NhEHs= - -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pkg-dir@^4.1.0, pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -planar-dual@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/planar-dual/-/planar-dual-1.0.2.tgz#b6a4235523b1b0cb79e5f926f8ea335dd982d563" - integrity sha1-tqQjVSOxsMt55fkm+OozXdmC1WM= - dependencies: - compare-angle "^1.0.0" - dup "^1.0.0" - -planar-graph-to-polyline@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/planar-graph-to-polyline/-/planar-graph-to-polyline-1.0.6.tgz#ed300620c33001ee2cca0ac6d1dae8d02d23f009" - integrity sha512-h8a9kdAjo7mRhC0X6HZ42xzFp7vKDZA+Hygyhsq/08Qi4vVAQYJaLLYLvKUUzRbVKvdYqq0reXHyV0EygyEBHA== - dependencies: - edges-to-adjacency-list "^1.0.0" - planar-dual "^1.0.0" - point-in-big-polygon "^2.0.1" - robust-orientation "^1.0.1" - robust-sum "^1.0.0" - two-product "^1.0.0" - uniq "^1.0.0" - -plotly.js@1.54.6: - version "1.54.6" - resolved "https://registry.yarnpkg.com/plotly.js/-/plotly.js-1.54.6.tgz#ed021aa8da85759c69602c97bd3dab2b09eeec22" - integrity sha512-z6FDeo/O4iNN+TfKJvk3Sv+MS7prFfM6oLJK5q9TYpwIQEz8oOtxwKQJospqtKub6mvxOhPoDIxxmpDZeiNopQ== - dependencies: - "@plotly/d3-sankey" "0.7.2" - "@plotly/d3-sankey-circular" "0.33.1" - "@turf/area" "^6.0.1" - "@turf/bbox" "^6.0.1" - "@turf/centroid" "^6.0.2" - alpha-shape "^1.0.0" - canvas-fit "^1.5.0" - color-normalize "^1.5.0" - color-rgba "^2.1.1" - convex-hull "^1.0.3" - country-regex "^1.1.0" - d3 "^3.5.17" - d3-force "^1.2.1" - d3-hierarchy "^1.1.9" - d3-interpolate "^1.4.0" - delaunay-triangulate "^1.1.6" - es6-promise "^4.2.8" - fast-isnumeric "^1.1.4" - gl-cone3d "^1.5.2" - gl-contour2d "^1.1.7" - gl-error3d "^1.0.16" - gl-heatmap2d "^1.0.6" - gl-line3d "1.2.1" - gl-mat4 "^1.2.0" - gl-mesh3d "^2.3.1" - gl-plot2d "^1.4.5" - gl-plot3d "^2.4.6" - gl-pointcloud2d "^1.0.3" - gl-scatter3d "^1.2.3" - gl-select-box "^1.0.4" - gl-spikes2d "^1.0.2" - gl-streamtube3d "^1.4.1" - gl-surface3d "^1.5.2" - gl-text "^1.1.8" - glslify "^7.0.0" - has-hover "^1.0.1" - has-passive-events "^1.0.0" - is-mobile "^2.2.2" - mapbox-gl "1.10.1" - matrix-camera-controller "^2.1.3" - mouse-change "^1.4.0" - mouse-event-offset "^3.0.2" - mouse-wheel "^1.2.0" - ndarray "^1.0.19" - ndarray-linear-interpolate "^1.0.0" - parse-svg-path "^0.1.2" - point-cluster "^3.1.8" - polybooljs "^1.2.0" - regl "^1.6.1" - regl-error2d "^2.0.8" - regl-line2d "^3.0.15" - regl-scatter2d "^3.1.8" - regl-splom "^1.0.8" - right-now "^1.0.0" - robust-orientation "^1.1.3" - sane-topojson "^4.0.0" - strongly-connected-components "^1.0.1" - superscript-text "^1.0.0" - svg-path-sdf "^1.1.3" - tinycolor2 "^1.4.1" - to-px "1.0.1" - topojson-client "^3.1.0" - webgl-context "^2.2.0" - world-calendars "^1.0.3" - -point-cluster@^3.1.8: - version "3.1.8" - resolved "https://registry.yarnpkg.com/point-cluster/-/point-cluster-3.1.8.tgz#a63625fd8964f2a5b446025a1acf8bcac42500c0" - integrity sha512-7klIr45dpMeZuqjIK9+qBg3m2IhyZJNJkdqjJFw0Olq75FM8ojrTMjClVUrMjNYRVqtwztxCHH71Fyjhg+YwyQ== - dependencies: - array-bounds "^1.0.1" - array-normalize "^1.1.4" - binary-search-bounds "^2.0.4" - bubleify "^1.1.0" - clamp "^1.0.1" - defined "^1.0.0" - dtype "^2.0.0" - flatten-vertex-data "^1.0.2" - is-obj "^1.0.1" - math-log2 "^1.0.1" - parse-rect "^1.2.0" - pick-by-alias "^1.2.0" - -point-in-big-polygon@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/point-in-big-polygon/-/point-in-big-polygon-2.0.1.tgz#69d293010cead58af08c3082ad1d23f600ef10af" - integrity sha512-DtrN8pa2VfMlvmWlCcypTFeBE4+OYz1ojDNJLKCWa4doiVAD6PRBbxFYAT71tsp5oKaRXT5sxEiHCAQKb1zr2Q== - dependencies: - binary-search-bounds "^2.0.0" - interval-tree-1d "^1.0.1" - robust-orientation "^1.1.3" - slab-decomposition "^1.0.1" - -polybooljs@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/polybooljs/-/polybooljs-1.2.0.tgz#b4390c2e079d4c262d3b2504c6288d95ba7a4758" - integrity sha1-tDkMLgedTCYtOyUExiiNlbp6R1g= - -polytope-closest-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/polytope-closest-point/-/polytope-closest-point-1.0.0.tgz#e6e57f4081ab5e8c778b811ef06e2c48ae338c3f" - integrity sha1-5uV/QIGrXox3i4Ee8G4sSK4zjD8= - dependencies: - numeric "^1.2.6" - -popper.js@1.16.1: - version "1.16.1" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" - integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== - -portfinder@^1.0.28: - version "1.0.28" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" - integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.5" - -postcss-attribute-case-insensitive@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.0.tgz#39cbf6babf3ded1e4abf37d09d6eda21c644105c" - integrity sha512-b4g9eagFGq9T5SWX4+USfVyjIb3liPnjhHHRMP7FMB2kFVpYyfEscV0wP3eaXhKlcHKUut8lt5BGoeylWA/dBQ== - dependencies: - postcss-selector-parser "^6.0.2" - -postcss-calc@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" - integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== - dependencies: - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.2" - -postcss-color-functional-notation@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.0.1.tgz#2fd769959e7fe658b4c0e7d40b0ab245fc8664f1" - integrity sha512-qxD/7Q2rdmqJLSYxlJFJM9gVdyVLTBVrOUc+B6+KbOe4t2G2KnoI3HdimdK4PerGLqAqKnEVGgal7YKImm0g+w== - dependencies: - postcss-values-parser "6.0.1" - -postcss-color-hex-alpha@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.0.tgz#84bfd985a93b0a18e047ebcb5fd463e2cae5e7a6" - integrity sha512-Z0xiE0j+hbefUj0LWOMkzmTIS7k+dqJKzLwoKww0KJhju/sWXr+84Yk7rmvFoML/4LjGpJgefZvDwExrsWfHZw== - dependencies: - postcss-values-parser "^6.0.0" - -postcss-color-rebeccapurple@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.0.0.tgz#980fbd98eb68ebbb38be02a82c7554e043c8fdf4" - integrity sha512-+Ogw3SA0ESjjO87S8Dn+aAEHK6hFAWAVbTVnyXnmbV6Xh0TKi0vXpzhlKG/yrxujxtlgQcMQNQjg75uWWv28xA== - dependencies: - postcss-values-parser "^6" - -postcss-custom-media@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz#1be6aff8be7dc9bf1fe014bde3b71b92bb4552f1" - integrity sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g== - -postcss-custom-properties@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.0.0.tgz#fd01ec9bd1462336ea8af7ba3c1a2c47c203031e" - integrity sha512-eAyX3rMjZKxdne6tWKjkWbNWfw6bbv4xTsrjNJ7C3uGDODrzbQXR+ueshRkw7Lhlhc3qyTmYH/sFfD0AbhgdSQ== - dependencies: - postcss-values-parser "^6" - -postcss-custom-selectors@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.0.tgz#022839e41fbf71c47ae6e316cb0e6213012df5ef" - integrity sha512-/1iyBhz/W8jUepjGyu7V1OPcGbc636snN1yXEQCinb6Bwt7KxsiU7/bLQlp8GwAXzCh7cobBU5odNn/2zQWR8Q== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-dir-pseudo-class@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.0.tgz#7026a070a4849072a232eaf0cdd960de3013658d" - integrity sha512-TC4eB5ZnLRSV1PLsAPualEjxFysU9IVEBx8h+Md2qzo8iWdNqwWCckx5fTWfe6dJxUpB0TWEpWEFhZ/YHvjSCA== - dependencies: - postcss-selector-parser "6.0.6" - -postcss-double-position-gradients@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.0.1.tgz#3c21ad52b6f13d81caf2563b0010a2c5872272af" - integrity sha512-L18N4Y1gpKQPEnZ6JOxO3H5gswZzTNR+ZqruZG7cOtOF/GR6J1YBRKn5hdTn3Vs4Y9XuDqaBD8vIXFIEft9Jqw== - dependencies: - postcss-values-parser "6.0.1" - -postcss-env-function@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.2.tgz#5509d008ff0f069fa18bd2eace4f3fdb18150c28" - integrity sha512-VXKv0Vskq7olS3Q2zj38G4au4PkW+YWBRgng2Czx0pP9PyqU6uzjS6uVU1VkJN8i0OTPM7g82YFUdiz/7pEvpg== - dependencies: - postcss-values-parser "6.0.1" - -postcss-flexbugs-fixes@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz#2028e145313074fc9abe276cb7ca14e5401eb49d" - integrity sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ== - -postcss-focus-visible@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.1.tgz#b12a859616eca7152976fec24ef337ab29bbc405" - integrity sha512-UddLlBmJ78Nu7OrKME70EKxCPBdxTx7pKIyD3GDNRM8Tnq19zmscT9QzsvR8gygz0i0nNUjMtSz4N3AEWZ5R/Q== - -postcss-focus-within@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.1.tgz#615659122325d86e00bc8ed84ab6129d0b3a0f62" - integrity sha512-50v1AZVlFSVzLTNdBQG521Aa54VABf/X1RkhR8Fm/9dDQby0W0XdwOnuo8Juvf0ZZXbKkxyTkyyQD0QaNVZVGg== - -postcss-font-family-system-ui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-font-family-system-ui/-/postcss-font-family-system-ui-5.0.0.tgz#cceb13dccb11019e9d6246db9a93137a30a53e21" - integrity sha512-3ndzyyMPhSbZekEPTuvKZz17jQXftAGMcVxNV4rTKNXsOsl23ZKlHcccEPB9tpB/SmGtDszdPvajdJrjZeKBfQ== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.30000655" - -postcss-font-variant@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" - integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== - -postcss-gap-properties@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.0.tgz#8941c400df902247603fd915c7dc81e1d7686b15" - integrity sha512-QJOkz1epC/iCuOdhQPm3n9T+F25+P+MYJEEcs5xz/Q+020mc9c6ZRGJkzPJd8FS9hFmT9eEKFEx9PEDl+lH5og== - -postcss-image-set-function@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.2.tgz#95b64db01b8812fcbece3bb36a3f2b8133bf7c91" - integrity sha512-NbTOc3xOq/YjIJS8/UVnhI16NxRuCiEWjem0eYt87sKvjdpk00niQ9oVo3eSR+kmMKWIO979x3j5i1GYJNxe1A== - dependencies: - postcss-values-parser "6.0.1" - -postcss-initial@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" - integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== - -postcss-lab-function@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.0.1.tgz#b6a1fb1032ddd7f4f7198ca78ec84c9b5bc7d80e" - integrity sha512-8F2keZUlUiX/tznbCZ5y3Bmx6pnc19kvL4oq+x+uoK0ZYQjUWmHDdVHBG6iMq2T0Fteu+AgGAo94UcIsL4ay2w== - dependencies: - "@csstools/convert-colors" "2.0.0" - postcss-values-parser "6.0.1" - -postcss-loader@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" - integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.5" - semver "^7.3.5" - -postcss-logical@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.0.tgz#f646ef6a3562890e1123a32e695d14cc271afb21" - integrity sha512-fWEWMn/xf6F9SMzAD7OS0GTm8Qh1BlBmEbVT/YZGYhwipQEwOpO7YOOu+qnzLksDg9JjLRj5tLmeN8OW8+ogIA== - -postcss-media-minmax@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" - integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values-replace@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values-replace/-/postcss-modules-values-replace-3.4.0.tgz#259192a73a291888816edb93934dd7177fb877ac" - integrity sha512-pY8iCSKxdt25uE+N4dO1PUUDOl8FIuvtZfT5964TuFJVhq+CEG8uqDpOCpCnqda/3K9ZFCNo4prn84H9SgP4Rw== - dependencies: - enhanced-resolve "^3.1.0" - es6-promisify "^5.0.0" - icss-utils "^4.0.0" - loader-utils "^2.0.0" - postcss "^7.0.0" - postcss-values-parser "^1.3.1" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-nesting@^10.0.2: - version "10.0.2" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.0.2.tgz#0cf9e81712fe7b6c3005e7d884cce2cb0a06326e" - integrity sha512-FdecapAKIe+kp6uLNW7icw1g1B2HRhAAfsNv/TPzopeM08gpUbnBpqKSVqxrCqLDwzQG854ZJn5I0BiJ35WvmA== - dependencies: - postcss-selector-parser "6.0.6" - -postcss-overflow-shorthand@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.0.tgz#f57631672333b302ffdcfc0735b8b7d0244c2a25" - integrity sha512-4fTapLT68wUoIr4m3Z0sKn1NbXX0lJYvj4aDA2++KpNx8wMSVf55UuLPz0nSjXa7dV1p0xQHlJ0iFJRNrSY2mw== - -postcss-page-break@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" - integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== - -postcss-place@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.1.tgz#9fbd18b3d1d438d313b2a29f5a50424c8ebca28d" - integrity sha512-X+vHHzqZjI4JbSoj3uYpL6rGRUHE1O9F8g+jBFn5U94U0t6GjJuL/xSN7tU6Pnm9tpfXioHfxwt9E8+JrCB9OQ== - dependencies: - postcss-values-parser "6.0.1" - -postcss-preset-env@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.0.1.tgz#7f1fc5ac38e60a8e5ff9a920396d936a830e6120" - integrity sha512-oB7IJGwLBEwnao823mS2b9hqbp5Brm0EZKWRVROayjGwyPQVjY9gZpPZk/ItFakdx7GAPgv3ya+9R3KrUqCwYA== - dependencies: - autoprefixer "^10.4.0" - browserslist "^4.17.5" - caniuse-lite "^1.0.30001272" - css-blank-pseudo "^2.0.0" - css-has-pseudo "^2.0.0" - css-prefers-color-scheme "^5.0.0" - cssdb "^5.0.0" - postcss "^8.3" - postcss-attribute-case-insensitive "^5.0.0" - postcss-color-functional-notation "^4.0.1" - postcss-color-hex-alpha "^8.0.0" - postcss-color-rebeccapurple "^7.0.0" - postcss-custom-media "^8.0.0" - postcss-custom-properties "^12.0.0" - postcss-custom-selectors "^6.0.0" - postcss-dir-pseudo-class "^6.0.0" - postcss-double-position-gradients "^3.0.1" - postcss-env-function "^4.0.2" - postcss-focus-visible "^6.0.1" - postcss-focus-within "^5.0.1" - postcss-font-variant "^5.0.0" - postcss-gap-properties "^3.0.0" - postcss-image-set-function "^4.0.2" - postcss-initial "^4.0.1" - postcss-lab-function "^4.0.1" - postcss-logical "^5.0.0" - postcss-media-minmax "^5.0.0" - postcss-nesting "^10.0.2" - postcss-overflow-shorthand "^3.0.0" - postcss-page-break "^3.0.4" - postcss-place "^7.0.1" - postcss-pseudo-class-any-link "^7.0.0" - postcss-replace-overflow-wrap "^4.0.0" - postcss-selector-not "^5.0.0" - -postcss-pseudo-class-any-link@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.0.0.tgz#b06483c8a241cee1e420f9ebd08680d4f95b2b20" - integrity sha512-Q4KjHlyBo91nvW+wTDZHGYcjtlSSkYwxweMuq1g8+dx1S8qAnedItvHLnbdAAdqJCZP1is5dLqiI8TvfJ+cjVQ== - dependencies: - postcss-selector-parser "^6" - -postcss-replace-overflow-wrap@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" - integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== - -postcss-selector-not@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-5.0.0.tgz#ac5fc506f7565dd872f82f5314c0f81a05630dc7" - integrity sha512-/2K3A4TCP9orP4TNS7u3tGdRFVKqz/E6pX3aGnriPG0jU78of8wsUcqE4QAhWEU0d+WnMSF93Ah3F//vUtK+iQ== - dependencies: - balanced-match "^1.0.0" - -postcss-selector-parser@6.0.6, postcss-selector-parser@^6, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.6" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" - integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss-values-parser@6.0.1, postcss-values-parser@^6, postcss-values-parser@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-6.0.1.tgz#aeb5e4522c4aabeb1ebbb14122194b9c08069675" - integrity sha512-hH3HREaFAEsVOzUgYiwvFggUqUvoIZoXD2OjhzY2CEM7uVDaQTKP5bmqbchCBoVvywsqiGVYhwC8p2wMUzpW+Q== - dependencies: - color-name "^1.1.4" - is-url-superb "^4.0.0" - quote-unquote "^1.0.0" - -postcss-values-parser@^1.3.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-1.5.0.tgz#5d9fa63e2bcb0179ce48f3235303765eb89f3047" - integrity sha512-3M3p+2gMp0AH3da530TlX8kiO1nxdTnc3C6vr8dMxRLIlh8UYkz0/wcwptSXjhtx2Fr0TySI7a+BHDQ8NL7LaQ== - dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss@^6.0.1: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.4.0" - -postcss@^7.0.0, postcss@^7.0.14: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - -postcss@^8.2.15, postcss@^8.3: - version "8.4.4" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.4.tgz#d53d4ec6a75fd62557a66bb41978bf47ff0c2869" - integrity sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q== - dependencies: - nanoid "^3.1.30" - picocolors "^1.0.0" - source-map-js "^1.0.1" - -postcss@^8.4.4: - version "8.4.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" - integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== - dependencies: - nanoid "^3.1.30" - picocolors "^1.0.0" - source-map-js "^1.0.1" - -potpack@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.2.tgz#23b99e64eb74f5741ffe7656b5b5c4ddce8dfc14" - integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ== - -prefixfree@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prefixfree/-/prefixfree-1.0.0.tgz#82b0edbbac107f2a3e2dc569d6c3df4035cd7910" - integrity sha1-grDtu6wQfyo+LcVp1sPfQDXNeRA= - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -prop-types@^15.0.0, prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -protocol-buffers-schema@^3.3.1: - version "3.6.0" - resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03" - integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw== - -proxy-addr@~2.0.5: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -pxls@^2.0.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/pxls/-/pxls-2.3.2.tgz#79100d2cc95089fc6e00053a9d93c1ddddb2c7b4" - integrity sha512-pQkwgbLqWPcuES5iEmGa10OlCf5xG0blkIF3dg7PpRZShbTYcvAdfFfGL03SMrkaSUaa/V0UpN9HWg40O2AIIw== - dependencies: - arr-flatten "^1.1.0" - compute-dims "^1.1.0" - flip-pixels "^1.0.2" - is-browser "^2.1.0" - is-buffer "^2.0.3" - to-uint8 "^1.4.1" - -qjobs@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" - integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -quantize@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/quantize/-/quantize-1.0.2.tgz#d25ac200a77b6d70f40127ca171a10e33c8546de" - integrity sha1-0lrCAKd7bXD0ASfKFxoQ4zyFRt4= - -quat-slerp@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/quat-slerp/-/quat-slerp-1.0.1.tgz#2baa15ce3a6bbdc3241d972eb17283139ed69f29" - integrity sha1-K6oVzjprvcMkHZcusXKDE57Wnyk= - dependencies: - gl-quat "^1.0.0" - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quickselect@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" - integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== - -quote-unquote@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/quote-unquote/-/quote-unquote-1.0.0.tgz#67a9a77148effeaf81a4d428404a710baaac8a0b" - integrity sha1-Z6mncUjv/q+BpNQoQEpxC6qsigs= - -raf@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" - integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== - dependencies: - performance-now "^2.1.0" - -ramda@^0.27.1: - version "0.27.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9" - integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -rat-vec@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/rat-vec/-/rat-vec-1.1.1.tgz#0dde2b66b7b34bb1bcd2a23805eac806d87fd17f" - integrity sha1-Dd4rZrezS7G80qI4BerIBth/0X8= - dependencies: - big-rat "^1.0.3" - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -react-dom@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" - integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler "^0.20.2" - -react-file-drop@3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/react-file-drop/-/react-file-drop-3.0.6.tgz#7fb75bdc0e9a10be4f6c653d2a906cacdd460d3e" - integrity sha512-OXfSpA8YY/OsKNITXPAOr+Rar8izqNZkx/N7B5vkp00AhQOFvj8ctC4bWInq1Mzpm4De5+XfpXAYbj4D4ze1QA== - dependencies: - prop-types "^15.7.2" - -react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - -react-markdown@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-5.0.3.tgz#41040ea7a9324b564b328fb81dd6c04f2a5373ac" - integrity sha512-jDWOc1AvWn0WahpjW6NK64mtx6cwjM4iSsLHJPNBqoAgGOVoIdJMqaKX4++plhOtdd4JksdqzlDibgPx6B/M2w== - dependencies: - "@types/mdast" "^3.0.3" - "@types/unist" "^2.0.3" - html-to-react "^1.3.4" - mdast-add-list-metadata "1.0.1" - prop-types "^15.7.2" - react-is "^16.8.6" - remark-parse "^9.0.0" - unified "^9.0.0" - unist-util-visit "^2.0.0" - xtend "^4.0.1" - -react-movable@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/react-movable/-/react-movable-3.0.2.tgz#45e6bd95db9f8340a114ddc8860dc9994719e94a" - integrity sha512-dDDYm3CRnDy8YLXMyyaR2MbcQiTwhPOP+dfl3fZukiI6mN1flVatcjSozT7HXjVk2yHwBC67ZOWGVAmjY6F/dA== - -react-virtualized@^9.22.3: - version "9.22.3" - resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421" - integrity sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw== - dependencies: - "@babel/runtime" "^7.7.2" - clsx "^1.0.4" - dom-helpers "^5.1.3" - loose-envify "^1.4.0" - prop-types "^15.7.2" - react-lifecycles-compat "^3.0.4" - -react-waypoint@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/react-waypoint/-/react-waypoint-10.1.0.tgz#6ab522a61bd52946260e4a78b3182759a97b40ec" - integrity sha512-wiVF0lTslVm27xHbnvUUADUrcDjrQxAp9lEYGExvcoEBScYbXu3Kt++pLrfj6CqOeeRAL4HcX8aANVLSn6bK0Q== - dependencies: - "@babel/runtime" "^7.12.5" - consolidated-events "^1.1.0 || ^2.0.0" - prop-types "^15.0.0" - react-is "^17.0.1" - -react@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -"readable-stream@>=1.0.33-1 <1.1.0-0": - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== - dependencies: - resolve "^1.9.0" - -reduce-simplicial-complex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/reduce-simplicial-complex/-/reduce-simplicial-complex-1.0.0.tgz#74d696a2f835f7a6dcd92065fd8c5181f2edf8bc" - integrity sha1-dNaWovg196bc2SBl/YxRgfLt+Lw= - dependencies: - cell-orientation "^1.0.1" - compare-cell "^1.0.0" - compare-oriented-cell "^1.0.1" - -regenerate-unicode-properties@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" - integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA== - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regenerator-transform@^0.14.2: - version "0.14.5" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" - integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== - dependencies: - "@babel/runtime" "^7.8.4" - -regex-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regex-regex/-/regex-regex-1.0.0.tgz#9048a1eaeb870f4d480dabc76fc42cdcc0bc3a72" - integrity sha1-kEih6uuHD01IDavHb8Qs3MC8OnI= - -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -regexpu-core@^4.5.4, regexpu-core@^4.7.1: - version "4.8.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" - integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg== - dependencies: - regenerate "^1.4.2" - regenerate-unicode-properties "^9.0.0" - regjsgen "^0.5.2" - regjsparser "^0.7.0" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.0.0" - -regjsgen@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== - -regjsparser@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" - integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ== - dependencies: - jsesc "~0.5.0" - -regl-error2d@^2.0.8: - version "2.0.12" - resolved "https://registry.yarnpkg.com/regl-error2d/-/regl-error2d-2.0.12.tgz#3b976e13fe641d5242a154fcacc80aecfa0a9881" - integrity sha512-r7BUprZoPO9AbyqM5qlJesrSRkl+hZnVKWKsVp7YhOl/3RIpi4UDGASGJY0puQ96u5fBYw/OlqV24IGcgJ0McA== - dependencies: - array-bounds "^1.0.1" - color-normalize "^1.5.0" - flatten-vertex-data "^1.0.2" - object-assign "^4.1.1" - pick-by-alias "^1.2.0" - to-float32 "^1.1.0" - update-diff "^1.1.0" - -regl-line2d@^3.0.15: - version "3.1.2" - resolved "https://registry.yarnpkg.com/regl-line2d/-/regl-line2d-3.1.2.tgz#2bedef7f44c1f7fae75c90f9918258723ca84c1c" - integrity sha512-nmT7WWS/WxmXAQMkgaMKWXaVmwJ65KCrjbqHGOUjjqQi6shfT96YbBOvelXwO9hG7/hjvbzjtQ2UO0L3e7YaXQ== - dependencies: - array-bounds "^1.0.1" - array-find-index "^1.0.2" - array-normalize "^1.1.4" - color-normalize "^1.5.0" - earcut "^2.1.5" - es6-weak-map "^2.0.3" - flatten-vertex-data "^1.0.2" - glslify "^7.0.0" - object-assign "^4.1.1" - parse-rect "^1.2.0" - pick-by-alias "^1.2.0" - to-float32 "^1.1.0" - -regl-scatter2d@^3.1.8, regl-scatter2d@^3.2.3: - version "3.2.8" - resolved "https://registry.yarnpkg.com/regl-scatter2d/-/regl-scatter2d-3.2.8.tgz#a1360e803e3fdf628ca09a72a435a0b7d4cf5675" - integrity sha512-bqrqJyeHkGBa9mEfuBnRd7FUtdtZ1l+gsM2C5Ugr1U3vJG5K3mdWdVWtOAllZ5FHHyWJV/vgjVvftgFUg6CDig== - dependencies: - "@plotly/point-cluster" "^3.1.9" - array-range "^1.0.1" - array-rearrange "^2.2.2" - clamp "^1.0.1" - color-id "^1.1.0" - color-normalize "^1.5.0" - color-rgba "^2.1.1" - flatten-vertex-data "^1.0.2" - glslify "^7.0.0" - image-palette "^2.1.0" - is-iexplorer "^1.0.0" - object-assign "^4.1.1" - parse-rect "^1.2.0" - pick-by-alias "^1.2.0" - to-float32 "^1.1.0" - update-diff "^1.1.0" - -regl-splom@^1.0.8: - version "1.0.14" - resolved "https://registry.yarnpkg.com/regl-splom/-/regl-splom-1.0.14.tgz#58800b7bbd7576aa323499a1966868a6c9ea1456" - integrity sha512-OiLqjmPRYbd7kDlHC6/zDf6L8lxgDC65BhC8JirhP4ykrK4x22ZyS+BnY8EUinXKDeMgmpRwCvUmk7BK4Nweuw== - dependencies: - array-bounds "^1.0.1" - array-range "^1.0.1" - color-alpha "^1.0.4" - flatten-vertex-data "^1.0.2" - parse-rect "^1.2.0" - pick-by-alias "^1.2.0" - raf "^3.4.1" - regl-scatter2d "^3.2.3" - -regl@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/regl/-/regl-1.7.0.tgz#0d185431044a356bf80e9b775b11b935ef2746d3" - integrity sha512-bEAtp/qrtKucxXSJkD4ebopFZYP0q1+3Vb2WECWv/T8yQEgKxDxJ7ztO285tAMaYZVR6mM1GgI6CCn8FROtL1w== - -regl@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/regl/-/regl-2.1.0.tgz#7dae71e9ff20f29c4f42f510c70cd92ebb6b657c" - integrity sha512-oWUce/aVoEvW5l2V0LK7O5KJMzUSKeiOwFuJehzpSFd43dO5spP9r+sSUfhKtsky4u6MCqWJaRL+abzExynfTg== - -relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= - -remark-breaks@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/remark-breaks/-/remark-breaks-3.0.2.tgz#f466b9d3474d7323146c0149fc1496dabadd908e" - integrity sha512-x96YDJ9X+Ry0/JNZFKfr1hpcAKvGYWfUTszxY9RbxKEqq6uzPPoLCuHdZsLPZZUdAv3nCROyc7FPrQLWr2rxyw== - dependencies: - "@types/mdast" "^3.0.0" - unified "^10.0.0" - unist-util-visit "^4.0.0" - -remark-gfm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-1.0.0.tgz#9213643001be3f277da6256464d56fd28c3b3c0d" - integrity sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA== - dependencies: - mdast-util-gfm "^0.1.0" - micromark-extension-gfm "^0.3.0" - -remark-parse@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" - integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== - dependencies: - mdast-util-from-markdown "^0.8.0" - -repeat-string@^1.0.0, repeat-string@^1.3.0: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-protobuf-schema@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758" - integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ== - dependencies: - protocol-buffers-schema "^3.3.1" - -resolve@^0.6.1: - version "0.6.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" - integrity sha1-3ZV5gufnNt699TtYpN2RdUV13UY= - -resolve@^1.0.0, resolve@^1.1.5, resolve@^1.14.2, resolve@^1.9.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rfdc@^1.1.4: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -right-now@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/right-now/-/right-now-1.0.0.tgz#6e89609deebd7dcdaf8daecc9aea39cf585a0918" - integrity sha1-bolgne69fc2vja7Mmuo5z1haCRg= - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -robust-compress@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/robust-compress/-/robust-compress-1.0.0.tgz#4cf62c4b318d8308516012bb8c11752f39329b1b" - integrity sha1-TPYsSzGNgwhRYBK7jBF1Lzkymxs= - -robust-determinant@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/robust-determinant/-/robust-determinant-1.1.0.tgz#8ecae79b79caab3e74f6debe2237e5391a27e9c7" - integrity sha1-jsrnm3nKqz509t6+IjflORon6cc= - dependencies: - robust-compress "^1.0.0" - robust-scale "^1.0.0" - robust-sum "^1.0.0" - two-product "^1.0.0" - -robust-dot-product@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/robust-dot-product/-/robust-dot-product-1.0.0.tgz#c9ba0178bd2c304bfd725f58e889f1d946004553" - integrity sha1-yboBeL0sMEv9cl9Y6Inx2UYARVM= - dependencies: - robust-sum "^1.0.0" - two-product "^1.0.0" - -robust-in-sphere@^1.1.3: - version "1.2.1" - resolved "https://registry.yarnpkg.com/robust-in-sphere/-/robust-in-sphere-1.2.1.tgz#ece3c2ae0fdf36b351680566adea7e93c6ba46da" - integrity sha512-3zJdcMIOP1gdwux93MKTS0RiMYEGwQBoE5R1IW/9ZQmGeZzP7f7i4+xdcK8ujJvF/dEOS1WPuI9IB1WNFbj3Cg== - dependencies: - robust-scale "^1.0.0" - robust-subtract "^1.0.0" - robust-sum "^1.0.0" - two-product "^1.0.0" - -robust-linear-solve@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/robust-linear-solve/-/robust-linear-solve-1.0.0.tgz#0cd6ac5040691a6f2aa3cd6311d728905ca3a1f1" - integrity sha1-DNasUEBpGm8qo81jEdcokFyjofE= - dependencies: - robust-determinant "^1.1.0" - -robust-orientation@^1.0.1, robust-orientation@^1.0.2, robust-orientation@^1.1.2, robust-orientation@^1.1.3: - version "1.2.1" - resolved "https://registry.yarnpkg.com/robust-orientation/-/robust-orientation-1.2.1.tgz#f6c2b00a5df5f1cb9597be63a45190f273899361" - integrity sha512-FuTptgKwY6iNuU15nrIJDLjXzCChWB+T4AvksRtwPS/WZ3HuP1CElCm1t+OBfgQKfWbtZIawip+61k7+buRKAg== - dependencies: - robust-scale "^1.0.2" - robust-subtract "^1.0.0" - robust-sum "^1.0.0" - two-product "^1.0.2" - -robust-product@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/robust-product/-/robust-product-1.0.0.tgz#685250007cdbba7cf1de75bff6d2927011098abe" - integrity sha1-aFJQAHzbunzx3nW/9tKScBEJir4= - dependencies: - robust-scale "^1.0.0" - robust-sum "^1.0.0" - -robust-scale@^1.0.0, robust-scale@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/robust-scale/-/robust-scale-1.0.2.tgz#775132ed09542d028e58b2cc79c06290bcf78c32" - integrity sha1-d1Ey7QlULQKOWLLMecBikLz3jDI= - dependencies: - two-product "^1.0.2" - two-sum "^1.0.0" - -robust-segment-intersect@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/robust-segment-intersect/-/robust-segment-intersect-1.0.1.tgz#3252b6a0fc1ba14ade6915ccbe09cbce9aab1c1c" - integrity sha1-MlK2oPwboUreaRXMvgnLzpqrHBw= - dependencies: - robust-orientation "^1.1.3" - -robust-subtract@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/robust-subtract/-/robust-subtract-1.0.0.tgz#e0b164e1ed8ba4e3a5dda45a12038348dbed3e9a" - integrity sha1-4LFk4e2LpOOl3aRaEgODSNvtPpo= - -robust-sum@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/robust-sum/-/robust-sum-1.0.0.tgz#16646e525292b4d25d82757a286955e0bbfa53d9" - integrity sha1-FmRuUlKStNJdgnV6KGlV4Lv6U9k= - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rw@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" - integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sane-topojson@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/sane-topojson/-/sane-topojson-4.0.0.tgz#624cdb26fc6d9392c806897bfd1a393f29bb5308" - integrity sha512-bJILrpBboQfabG3BNnHI2hZl52pbt80BE09u4WhnrmzuF2JbMKZdl62G5glXskJ46p+gxE2IzOwGj/awR4g8AA== - -scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -schema-utils@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" - -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.8.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" - -scrollbar-width@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/scrollbar-width/-/scrollbar-width-3.1.1.tgz#c62e63efa5934dac37b43da34f7550caca8444a2" - integrity sha1-xi5j76WTTaw3tD2jT3VQysqERKI= - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -selfsigned@^1.10.11: - version "1.10.11" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" - integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== - dependencies: - node-forge "^0.10.0" - -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -sentence-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f" - integrity sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - upper-case-first "^2.0.2" - -serialize-javascript@6.0.0, serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shallow-copy@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" - integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA= - -shallowequal@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" - integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.3, side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.3: - version "3.0.6" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" - integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== - -signum@^0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/signum/-/signum-0.0.0.tgz#ab551b1003351070a704783f1a09c5e7691f9cf6" - integrity sha1-q1UbEAM1EHCnBHg/GgnF52kfnPY= - -signum@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/signum/-/signum-1.0.0.tgz#74a7d2bf2a20b40eba16a92b152124f1d559fa77" - integrity sha1-dKfSvyogtA66FqkrFSEk8dVZ+nc= - -simple-is@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/simple-is/-/simple-is-0.2.0.tgz#2abb75aade39deb5cc815ce10e6191164850baf0" - integrity sha1-Krt1qt453rXMgVzhDmGRFkhQuvA= - -simplicial-complex-boundary@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simplicial-complex-boundary/-/simplicial-complex-boundary-1.0.1.tgz#72c9ff1e24deaa374c9bb2fa0cbf0c081ebef815" - integrity sha1-csn/HiTeqjdMm7L6DL8MCB6++BU= - dependencies: - boundary-cells "^2.0.0" - reduce-simplicial-complex "^1.0.0" - -simplicial-complex-contour@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/simplicial-complex-contour/-/simplicial-complex-contour-1.0.2.tgz#890aacac284365340110545cf2629a26e04bf9d1" - integrity sha1-iQqsrChDZTQBEFRc8mKaJuBL+dE= - dependencies: - marching-simplex-table "^1.0.0" - ndarray "^1.0.15" - ndarray-sort "^1.0.0" - typedarray-pool "^1.1.0" - -simplicial-complex@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/simplicial-complex/-/simplicial-complex-0.3.3.tgz#4c30cad57f9e45729dd8f306c8753579f46be99e" - integrity sha1-TDDK1X+eRXKd2PMGyHU1efRr6Z4= - dependencies: - bit-twiddle "~0.0.1" - union-find "~0.0.3" - -simplicial-complex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simplicial-complex/-/simplicial-complex-1.0.0.tgz#6c33a4ed69fcd4d91b7bcadd3b30b63683eae241" - integrity sha1-bDOk7Wn81Nkbe8rdOzC2NoPq4kE= - dependencies: - bit-twiddle "^1.0.0" - union-find "^1.0.0" - -simplify-planar-graph@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/simplify-planar-graph/-/simplify-planar-graph-2.0.1.tgz#bc85893725f32e8fa8ae25681398446d2cbcf766" - integrity sha1-vIWJNyXzLo+oriVoE5hEbSy892Y= - dependencies: - robust-orientation "^1.0.1" - simplicial-complex "^0.3.3" - -simply-uuid@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simply-uuid/-/simply-uuid-1.0.1.tgz#539241d81528969cef23892faf4588005fa99ab8" - integrity sha1-U5JB2BUolpzvI4kvr0WIAF+pmrg= - -sirv@^1.0.7: - version "1.0.19" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" - integrity sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ== - dependencies: - "@polka/url" "^1.0.0-next.20" - mrmime "^1.0.0" - totalist "^1.0.0" - -slab-decomposition@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/slab-decomposition/-/slab-decomposition-1.0.3.tgz#0345b3d364d78dad3f400cd5c8e0424547d23e7c" - integrity sha512-1EfR304JHvX9vYQkUi4AKqN62mLsjk6W45xTk/TxwN8zd3HGwS7PVj9zj0I6fgCZqfGlimDEY+RzzASHn97ZmQ== - dependencies: - binary-search-bounds "^2.0.0" - functional-red-black-tree "^1.0.0" - robust-orientation "^1.1.3" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -snake-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" - integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -sniffr@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/sniffr/-/sniffr-1.2.0.tgz#d4e31073ef4f7c00d87dba89289736fba25cadb4" - integrity sha512-k7C0ZcHBU330LcSkKyc2cOOB0uHosME8b2t9qFJqdqB1cKwGmZWd7BVwBz5mWOMJ5dggK1dy2qv+DSwteKLBzQ== - -socket.io-adapter@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" - integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== - -socket.io-parser@~4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" - integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== - dependencies: - "@types/component-emitter" "^1.2.10" - component-emitter "~1.3.0" - debug "~4.3.1" - -socket.io@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" - integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== - dependencies: - "@types/cookie" "^0.4.0" - "@types/cors" "^2.8.8" - "@types/node" ">=10.0.0" - accepts "~1.3.4" - base64id "~2.0.0" - debug "~4.3.1" - engine.io "~4.1.0" - socket.io-adapter "~2.1.0" - socket.io-parser "~4.0.3" - -sockjs@^0.3.21: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== - -source-map-js@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" - integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== - -source-map-loader@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" - integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== - dependencies: - abab "^2.0.5" - iconv-lite "^0.6.2" - source-map-js "^0.6.2" - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -sourcemap-codec@^1.4.4: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-polygon@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/split-polygon/-/split-polygon-1.0.0.tgz#0eacc8a136a76b12a3d95256ea7da45db0c2d247" - integrity sha1-DqzIoTanaxKj2VJW6n2kXbDC0kc= - dependencies: - robust-dot-product "^1.0.0" - robust-sum "^1.0.0" - -sprintf-js@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== - -stack-trace@0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" - integrity sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU= - -static-eval@^2.0.5: - version "2.1.0" - resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.1.0.tgz#a16dbe54522d7fa5ef1389129d813fd47b148014" - integrity sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw== - dependencies: - escodegen "^1.11.1" - -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== - -streamroller@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" - integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== - dependencies: - date-format "^2.1.0" - debug "^4.1.1" - fs-extra "^8.1.0" - -strictdom@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strictdom/-/strictdom-1.0.1.tgz#189de91649f73d44d59b8432efa68ef9d2659460" - integrity sha1-GJ3pFkn3PUTVm4Qy76aO+dJllGA= - -string-split-by@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string-split-by/-/string-split-by-1.0.0.tgz#53895fb3397ebc60adab1f1e3a131f5372586812" - integrity sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A== - dependencies: - parenthesis "^3.1.5" - -string-to-arraybuffer@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-to-arraybuffer/-/string-to-arraybuffer-1.0.2.tgz#161147fbadea02e28b0935002cec4c40f1ca7f0a" - integrity sha512-DaGZidzi93dwjQen5I2osxR9ERS/R7B1PFyufNMnzhj+fmlDQAc1DSDIJVJhgI8Oq221efIMbABUBdPHDRt43Q== - dependencies: - atob-lite "^2.0.0" - is-base64 "^0.1.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strongly-connected-components@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strongly-connected-components/-/strongly-connected-components-1.0.1.tgz#0920e2b4df67c8eaee96c6b6234fe29e873dba99" - integrity sha1-CSDitN9nyOrulsa2I0/inoc9upk= - -style-inject@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/style-inject/-/style-inject-0.3.0.tgz#d21c477affec91811cc82355832a700d22bf8dd3" - integrity sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw== - -style-loader@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.0.tgz#d66ea95fc50b22f8b79b69a9e414760fcf58d8d8" - integrity sha512-szANub7ksJtQioJYtpbWwh1hUl99uK15n5HDlikeCRil/zYMZgSxucHddyF/4A3qJMUiAjPhFowrrQuNMA7jwQ== - -style-loader@~3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== - -styled-components@^5.3.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.3.tgz#312a3d9a549f4708f0fb0edc829eb34bde032743" - integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/traverse" "^7.4.5" - "@emotion/is-prop-valid" "^0.8.8" - "@emotion/stylis" "^0.8.4" - "@emotion/unitless" "^0.7.4" - babel-plugin-styled-components ">= 1.12.0" - css-to-react-native "^3.0.0" - hoist-non-react-statics "^3.0.0" - shallowequal "^1.1.0" - supports-color "^5.5.0" - -supercluster@^7.0.0: - version "7.1.4" - resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-7.1.4.tgz#6762aabfd985d3390b49f13b815567d5116a828a" - integrity sha512-GhKkRM1jMR6WUwGPw05fs66pOFWhf59lXq+Q3J3SxPvhNcmgOtLRV6aVQPMRsmXdpaeFJGivt+t7QXUPL3ff4g== - dependencies: - kdbush "^3.0.0" - -superscript-text@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/superscript-text/-/superscript-text-1.0.0.tgz#e7cb2752567360df50beb0610ce8df3d71d8dfd8" - integrity sha1-58snUlZzYN9QvrBhDOjfPXHY39g= - -supports-color@8.1.1, supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -surface-nets@^1.0.0, surface-nets@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/surface-nets/-/surface-nets-1.0.2.tgz#e433c8cbba94a7274c6f4c99552b461bf1fc7a4b" - integrity sha1-5DPIy7qUpydMb0yZVStGG/H8eks= - dependencies: - ndarray-extract-contour "^1.0.0" - triangulate-hypercube "^1.0.0" - zero-crossings "^1.0.0" - -svg-arc-to-cubic-bezier@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz#390c450035ae1c4a0104d90650304c3bc814abe6" - integrity sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g== - -svg-path-bounds@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/svg-path-bounds/-/svg-path-bounds-1.0.2.tgz#00312f672b08afc432a66ddfbd06db40cec8d0d0" - integrity sha512-H4/uAgLWrppIC0kHsb2/dWUYSmb4GE5UqH06uqWBcg6LBjX2fu0A8+JrO2/FJPZiSsNOKZAhyFFgsLTdYUvSqQ== - dependencies: - abs-svg-path "^0.1.1" - is-svg-path "^1.0.1" - normalize-svg-path "^1.0.0" - parse-svg-path "^0.1.2" - -svg-path-sdf@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/svg-path-sdf/-/svg-path-sdf-1.1.3.tgz#92957a31784c0eaf68945472c8dc6bf9e6d126fc" - integrity sha512-vJJjVq/R5lSr2KLfVXVAStktfcfa1pNFjFOgyJnzZFXlO/fDZ5DmM8FpnSKKzLPfEYTVeXuVBTHF296TpxuJVg== - dependencies: - bitmap-sdf "^1.0.0" - draw-svg-path "^1.0.0" - is-svg-path "^1.0.1" - parse-svg-path "^0.1.2" - svg-path-bounds "^1.0.1" - -tabbable@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.1.tgz#e3fda7367ddbb172dcda9f871c0fdb36d1c4cd9c" - integrity sha512-40pEZ2mhjaZzK0BnI+QGNjJO8UYx9pP5v7BGe17SORTO0OEuuaAwQTkAp8whcZvqon44wKFOikD+Al11K3JICQ== - -tabulator-tables@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/tabulator-tables/-/tabulator-tables-5.0.1.tgz#c077de5da11ddca654a3132e908e80ff5f5382e2" - integrity sha512-zSPYzkLIBGwmAFEPOgUpXXNKzO95bVj6EKRikS0Em32gnfhSR9n73mN5TpQV1jU4nPv/pUUTbMZVVHrjzIaaJQ== - -tapable@^0.2.7: - version "0.2.9" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.9.tgz#af2d8bbc9b04f74ee17af2b4d9048f807acd18a8" - integrity sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A== - -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -terser-webpack-plugin@^5.1.3: - version "5.2.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.2.5.tgz#ce65b9880a0c36872555c4874f45bbdb02ee32c9" - integrity sha512-3luOVHku5l0QBeYS8r4CdHYWEGMmIj3H1U64jgkdZzECcSOJAyJ9TjuqcQZvw1Y+4AOBN9SeYJPJmFn2cM4/2g== - dependencies: - jest-worker "^27.0.6" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - terser "^5.7.2" - -terser@^5.10.0, terser@^5.7.2: - version "5.10.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" - integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.20" - -text-cache@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/text-cache/-/text-cache-4.2.2.tgz#d0d30ba89b7312ea1c1a31cd9a4db56c1cef7fe7" - integrity sha512-zky+UDYiX0a/aPw/YTBD+EzKMlCTu1chFuCMZeAkgoRiceySdROu1V2kJXhCbtEdBhiOviYnAdGiSYl58HW0ZQ== - dependencies: - vectorize-text "^3.2.1" - -three-csg-ts@3.1.9: - version "3.1.9" - resolved "https://registry.yarnpkg.com/three-csg-ts/-/three-csg-ts-3.1.9.tgz#1438de3b6747b9b55deb88d9e0acdc6e47681979" - integrity sha512-Qke0+07AKDfeiRjh46sOF2iiilSMcKnfgHjuArdMB4poZs3X0FQLHGFIEBbGrv3ejrkHASW9o5pLRfFFQhk9hg== - -three@0.137.4: - version "0.137.4" - resolved "https://registry.yarnpkg.com/three/-/three-0.137.4.tgz#ec73b6a6c40b733d56544b13d0c3cdb0bce5d0a7" - integrity sha512-kUyOZNX+dMbvaS0mGYM1BaXHkHVNQdpryWH8dBg3mn725dJcTo9/5rjyH+OJ8V0r+XbZPz7sncV+c3Gjpc9UBA== - -through2@^0.6.3: - version "0.6.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" - integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= - dependencies: - readable-stream ">=1.0.33-1 <1.1.0-0" - xtend ">=4.0.0 <4.1.0-0" - -through2@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -tinycolor2@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" - integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== - -tinyqueue@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08" - integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA== - -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - -to-array-buffer@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/to-array-buffer/-/to-array-buffer-3.2.0.tgz#cb684dd691a7368c3b249c2348d75227f7d4dbb4" - integrity sha512-zN33mwi0gpL+7xW1ITLfJ48CEj6ZQW0ZAP0MU+2W3kEY0PAIncyuxmD4OqkUVhPAbTP7amq9j/iwvZKYS+lzSQ== - dependencies: - flatten-vertex-data "^1.0.2" - is-blob "^2.0.1" - string-to-arraybuffer "^1.0.0" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-float32@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/to-float32/-/to-float32-1.1.0.tgz#39bd3b11eadccd490c08f5f9171da5127b6f3946" - integrity sha512-keDnAusn/vc+R3iEiSDw8TOF7gPiTLdK1ArvWtYbJQiVfmRg6i/CAvbKq3uIS0vWroAC7ZecN3DjQKw3aSklUg== - -to-px@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-px/-/to-px-1.0.1.tgz#5bbaed5e5d4f76445bcc903c293a2307dd324646" - integrity sha1-W7rtXl1PdkRbzJA8KTojB90yRkY= - dependencies: - parse-unit "^1.0.1" - -to-px@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/to-px/-/to-px-1.1.0.tgz#b6b269ed5db0cc9aefc15272a4c8bcb2ca1e99ca" - integrity sha512-bfg3GLYrGoEzrGoE05TAL/Uw+H/qrf2ptr9V3W7U0lkjjyYnIfgxmVLUfhQ1hZpIQwin81uxhDjvUkDYsC0xWw== - dependencies: - parse-unit "^1.0.1" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -to-uint8@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/to-uint8/-/to-uint8-1.4.1.tgz#9f45694905b827f247d37bc8ec83b2818d81fac9" - integrity sha512-o+ochsMlTZyucbww8It401FC2Rx+OP2RpDeYbA6h+y9HgedDl1UjdsJ9CmzKEG7AFP9es5PmJ4eDWeeeXihESg== - dependencies: - arr-flatten "^1.1.0" - clamp "^1.0.1" - is-base64 "^0.1.0" - is-float-array "^1.0.0" - to-array-buffer "^3.0.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -topojson-client@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.1.0.tgz#22e8b1ed08a2b922feeb4af6f53b6ef09a467b99" - integrity sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw== - dependencies: - commander "2" - -totalist@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" - integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== - -traverse@0.6.6: - version "0.6.6" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" - integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= - -triangulate-hypercube@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/triangulate-hypercube/-/triangulate-hypercube-1.0.1.tgz#d8071db2ebfcfd51f308d0bcf2a5c48a5b36d137" - integrity sha1-2Acdsuv8/VHzCNC88qXEils20Tc= - dependencies: - gamma "^0.1.0" - permutation-parity "^1.0.0" - permutation-rank "^1.0.0" - -triangulate-polyline@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/triangulate-polyline/-/triangulate-polyline-1.0.3.tgz#bf8ba877a85054103feb9fa5a61b4e8d7017814d" - integrity sha1-v4uod6hQVBA/65+lphtOjXAXgU0= - dependencies: - cdt2d "^1.0.0" - -trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== - -trough@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/trough/-/trough-2.0.2.tgz#94a3aa9d5ce379fc561f6244905b3f36b7458d96" - integrity sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w== - -tslib@^2.0.3: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== - -turntable-camera-controller@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/turntable-camera-controller/-/turntable-camera-controller-3.0.1.tgz#8dbd3fe00550191c65164cb888971049578afd99" - integrity sha1-jb0/4AVQGRxlFky4iJcQSVeK/Zk= - dependencies: - filtered-vector "^1.2.1" - gl-mat4 "^1.0.2" - gl-vec3 "^1.0.2" - -two-product@^1.0.0, two-product@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/two-product/-/two-product-1.0.2.tgz#67d95d4b257a921e2cb4bd7af9511f9088522eaa" - integrity sha1-Z9ldSyV6kh4stL16+VEfkIhSLqo= - -two-sum@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/two-sum/-/two-sum-1.0.0.tgz#31d3f32239e4f731eca9df9155e2b297f008ab64" - integrity sha1-MdPzIjnk9zHsqd+RVeKyl/AIq2Q= - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type-name@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/type-name/-/type-name-2.0.2.tgz#efe7d4123d8ac52afff7f40c7e4dec5266008fb4" - integrity sha1-7+fUEj2KxSr/9/QMfk3sUmYAj7Q= - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" - integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== - -typedarray-pool@^1.0.0, typedarray-pool@^1.0.2, typedarray-pool@^1.1.0, typedarray-pool@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/typedarray-pool/-/typedarray-pool-1.2.0.tgz#e7e90720144ba02b9ed660438af6f3aacfe33ac3" - integrity sha512-YTSQbzX43yvtpfRtIDAYygoYtgT+Rpjuxy9iOpczrjpXLgGoyG7aS5USJXV2d3nn8uHTeb9rXDvzS27zUg5KYQ== - dependencies: - bit-twiddle "^1.0.0" - dup "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typescript@3.9.5: - version "3.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" - integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== - -ua-parser-js@^0.7.28: - version "0.7.31" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" - integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" - integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== - -unified@^10.0.0: - version "10.1.1" - resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.1.tgz#345e349e3ab353ab612878338eb9d57b4dea1d46" - integrity sha512-v4ky1+6BN9X3pQrOdkFIPWAaeDsHPE1svRDxq7YpTc2plkIqFMwukfqM+l0ewpP9EfwARlt9pPFAeWYhHm8X9w== - dependencies: - "@types/unist" "^2.0.0" - bail "^2.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^5.0.0" - -unified@^9.0.0: - version "9.2.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" - integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - -union-find@^1.0.0, union-find@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/union-find/-/union-find-1.0.2.tgz#292bac415e6ad3a89535d237010db4a536284e58" - integrity sha1-KSusQV5q06iVNdI3AQ20pTYoTlg= - -union-find@~0.0.3: - version "0.0.4" - resolved "https://registry.yarnpkg.com/union-find/-/union-find-0.0.4.tgz#b854b3301619bdad144b0014c78f96eac0d2f0f6" - integrity sha1-uFSzMBYZva0USwAUx4+W6sDS8PY= - -uniq@^1.0.0, uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - -unist-util-is@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" - integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== - -unist-util-is@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.1.1.tgz#e8aece0b102fa9bc097b0fef8f870c496d4a6236" - integrity sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ== - -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" - -unist-util-stringify-position@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz#d517d2883d74d0daa0b565adc3d10a02b4a8cde9" - integrity sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-visit-parents@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-1.1.2.tgz#f6e3afee8bdbf961c0e6f028ea3c0480028c3d06" - integrity sha512-yvo+MMLjEwdc3RhhPYSximset7rwjMrdt9E41Smmvg25UQIenzrN83cRnF1JMzoMi9zZOQeYXHSDf7p+IQkW3Q== - -unist-util-visit-parents@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" - integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - -unist-util-visit-parents@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz#44bbc5d25f2411e7dfc5cecff12de43296aa8521" - integrity sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - -unist-util-visit@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" - integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" - -unist-util-visit@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.0.tgz#f41e407a9e94da31594e6b1c9811c51ab0b3d8f5" - integrity sha512-n7lyhFKJfVZ9MnKtqbsqkQEk5P1KShj0+//V7mAcoI6bpbUjh3C/OG8HVD+pBihfh6Ovl01m8dkcv9HNqYajmQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - unist-util-visit-parents "^5.0.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unquote@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - -update-diff@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/update-diff/-/update-diff-1.1.0.tgz#f510182d81ee819fb82c3a6b22b62bbdeda7808f" - integrity sha1-9RAYLYHugZ+4LDprIrYrve2ngI8= - -upper-case-first@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" - integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg== - dependencies: - tslib "^2.0.3" - -upper-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.2.tgz#d89810823faab1df1549b7d97a76f8662bae6f7a" - integrity sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg== - dependencies: - tslib "^2.0.3" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -utils-copy-error@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-copy-error/-/utils-copy-error-1.0.1.tgz#791de393c0f09890afd59f3cbea635f079a94fa5" - integrity sha1-eR3jk8DwmJCv1Z88vqY18HmpT6U= - dependencies: - object-keys "^1.0.9" - utils-copy "^1.1.0" - -utils-copy@^1.0.0, utils-copy@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/utils-copy/-/utils-copy-1.1.1.tgz#6e2b97982aa8cd73e1182a3e6f8bec3c0f4058a7" - integrity sha1-biuXmCqozXPhGCo+b4vsPA9AWKc= - dependencies: - const-pinf-float64 "^1.0.0" - object-keys "^1.0.9" - type-name "^2.0.0" - utils-copy-error "^1.0.0" - utils-indexof "^1.0.0" - utils-regex-from-string "^1.0.0" - validate.io-array "^1.0.3" - validate.io-buffer "^1.0.1" - validate.io-nonnegative-integer "^1.0.0" - -utils-indexof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/utils-indexof/-/utils-indexof-1.0.0.tgz#20feabf09ef1018b523643e8380e7bc83ec61b5c" - integrity sha1-IP6r8J7xAYtSNkPoOA57yD7GG1w= - dependencies: - validate.io-array-like "^1.0.1" - validate.io-integer-primitive "^1.0.0" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -utils-regex-from-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/utils-regex-from-string/-/utils-regex-from-string-1.0.0.tgz#fe1a2909f8de0ff0d5182c80fbc654d6a687d189" - integrity sha1-/hopCfjeD/DVGCyA+8ZU1qaH0Yk= - dependencies: - regex-regex "^1.0.0" - validate.io-string-primitive "^1.0.0" - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate.io-array-like@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/validate.io-array-like/-/validate.io-array-like-1.0.2.tgz#7af9f7eb7b51715beb2215668ec5cce54faddb5a" - integrity sha1-evn363tRcVvrIhVmjsXM5U+t21o= - dependencies: - const-max-uint32 "^1.0.2" - validate.io-integer-primitive "^1.0.0" - -validate.io-array@^1.0.3, validate.io-array@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/validate.io-array/-/validate.io-array-1.0.6.tgz#5b5a2cafd8f8b85abb2f886ba153f2d93a27774d" - integrity sha1-W1osr9j4uFq7L4hroVPy2Tond00= - -validate.io-buffer@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/validate.io-buffer/-/validate.io-buffer-1.0.2.tgz#852d6734021914d5d13afc32531761e3720ed44e" - integrity sha1-hS1nNAIZFNXROvwyUxdh43IO1E4= - -validate.io-integer-primitive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/validate.io-integer-primitive/-/validate.io-integer-primitive-1.0.0.tgz#a9aa010355fe8681c0fea6c1a74ad2419cadddc6" - integrity sha1-qaoBA1X+hoHA/qbBp0rSQZyt3cY= - dependencies: - validate.io-number-primitive "^1.0.0" - -validate.io-integer@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/validate.io-integer/-/validate.io-integer-1.0.5.tgz#168496480b95be2247ec443f2233de4f89878068" - integrity sha1-FoSWSAuVviJH7EQ/IjPeT4mHgGg= - dependencies: - validate.io-number "^1.0.3" - -validate.io-matrix-like@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/validate.io-matrix-like/-/validate.io-matrix-like-1.0.2.tgz#5ec32a75d0889dac736dea68bdd6145b155edfc3" - integrity sha1-XsMqddCInaxzbepovdYUWxVe38M= - -validate.io-ndarray-like@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/validate.io-ndarray-like/-/validate.io-ndarray-like-1.0.0.tgz#d8a3b0ed165bbf1d2fc0d0073270cfa552295919" - integrity sha1-2KOw7RZbvx0vwNAHMnDPpVIpWRk= - -validate.io-nonnegative-integer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/validate.io-nonnegative-integer/-/validate.io-nonnegative-integer-1.0.0.tgz#8069243a08c5f98e95413c929dfd7b18f3f6f29f" - integrity sha1-gGkkOgjF+Y6VQTySnf17GPP28p8= - dependencies: - validate.io-integer "^1.0.5" - -validate.io-number-primitive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/validate.io-number-primitive/-/validate.io-number-primitive-1.0.0.tgz#d2e01f202989369dcf1155449564203afe584e55" - integrity sha1-0uAfICmJNp3PEVVElWQgOv5YTlU= - -validate.io-number@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/validate.io-number/-/validate.io-number-1.0.3.tgz#f63ffeda248bf28a67a8d48e0e3b461a1665baf8" - integrity sha1-9j/+2iSL8opnqNSODjtGGhZluvg= - -validate.io-positive-integer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/validate.io-positive-integer/-/validate.io-positive-integer-1.0.0.tgz#7ed2d03b4c27558cc66a00aab0f0e921814a6582" - integrity sha1-ftLQO0wnVYzGagCqsPDpIYFKZYI= - dependencies: - validate.io-integer "^1.0.5" - -validate.io-string-primitive@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/validate.io-string-primitive/-/validate.io-string-primitive-1.0.1.tgz#b8135b9fb1372bde02fdd53ad1d0ccd6de798fee" - integrity sha1-uBNbn7E3K94C/dU60dDM1t55j+4= - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -vectorize-text@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/vectorize-text/-/vectorize-text-3.2.2.tgz#3e978889df4ae333975d38669529c942a63e1f65" - integrity sha512-34NVOCpMMQVXujU4vb/c6u98h6djI0jGdtC202H4Huvzn48B6ARsR7cmGh1xsAc0pHNQiUKGK/aHF05VtGv+eA== - dependencies: - cdt2d "^1.0.0" - clean-pslg "^1.1.0" - ndarray "^1.0.11" - planar-graph-to-polyline "^1.0.6" - simplify-planar-graph "^2.0.1" - surface-nets "^1.0.0" - triangulate-polyline "^1.0.0" - -vfile-message@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" - integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" - -vfile-message@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.0.2.tgz#db7eaebe7fecb853010f2ef1664427f52baf8f74" - integrity sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^3.0.0" - -vfile@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" - integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" - -vfile@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.2.0.tgz#a32a646ff9251c274dbe8675644a39031025b369" - integrity sha512-ftCpb6pU8Jrzcqku8zE6N3Gi4/RkDhRwEXSWudzZzA2eEOn/cBpsfk9aulCUR+j1raRSAykYQap9u6j6rhUaCA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - -void-elements@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= - -vt-pbf@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac" - integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA== - dependencies: - "@mapbox/point-geometry" "0.1.0" - "@mapbox/vector-tile" "^1.3.1" - pbf "^3.2.1" - -watchpack@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.0.tgz#a41bca3da6afaff31e92a433f4c856a0c25ea0c4" - integrity sha512-MnN0Q1OsvB/GGHETrFeZPQaOelWh/7O+EiFlj8sM9GPjtQkis7k01aAxrg/18kTfoIVcLL+haEVFlXDaSRwKRw== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -weak-map@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/weak-map/-/weak-map-1.0.5.tgz#79691584d98607f5070bd3b70a40e6bb22e401eb" - integrity sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes= - -weakmap-shim@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/weakmap-shim/-/weakmap-shim-1.1.1.tgz#d65afd784109b2166e00ff571c33150ec2a40b49" - integrity sha1-1lr9eEEJshZuAP9XHDMVDsKkC0k= - -webgl-context@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/webgl-context/-/webgl-context-2.2.0.tgz#8f37d7257cf6df1cd0a49e6a7b1b721b94cc86a0" - integrity sha1-jzfXJXz23xzQpJ5qextyG5TMhqA= - dependencies: - get-canvas-context "^1.0.1" - -webpack-bundle-analyzer@4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz#1b0eea2947e73528754a6f9af3e91b2b6e0f79d5" - integrity sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ== - dependencies: - acorn "^8.0.4" - acorn-walk "^8.0.0" - chalk "^4.1.0" - commander "^7.2.0" - gzip-size "^6.0.0" - lodash "^4.17.20" - opener "^1.5.2" - sirv "^1.0.7" - ws "^7.3.1" - -webpack-cli@4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" - integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" - colorette "^2.0.14" - commander "^7.0.0" - execa "^5.0.0" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - v8-compile-cache "^2.2.0" - webpack-merge "^5.7.3" - -webpack-dev-middleware@^5.2.1: - version "5.2.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.2.2.tgz#eb5193faa5479ca1086b9f7bed68b89c731bff62" - integrity sha512-DjZyYrsHhkikAFNvSNKrpnziXukU1EChFAh9j4LAm6ndPLPW8cN0KhM7T+RAiOqsQ6ABfQ8hoKIs9IWMTjov+w== - dependencies: - colorette "^2.0.10" - memfs "^3.2.2" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" - integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== - dependencies: - ansi-html-community "^0.0.8" - bonjour "^3.5.0" - chokidar "^3.5.1" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - del "^6.0.0" - express "^4.17.1" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" - internal-ip "^6.2.0" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - portfinder "^1.0.28" - schema-utils "^3.1.0" - selfsigned "^1.10.11" - serve-index "^1.9.1" - sockjs "^0.3.21" - spdy "^4.0.2" - strip-ansi "^7.0.0" - url "^0.11.0" - webpack-dev-middleware "^5.2.1" - ws "^8.1.0" - -webpack-merge@^4.1.5: - version "4.2.2" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== - dependencies: - lodash "^4.17.15" - -webpack-merge@^5.7.3: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - -webpack-sources@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" - integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== - -webpack@5.57.1: - version "5.57.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" - integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" - webpack-sources "^3.2.0" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - -which-typed-array@^1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793" - integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-abstract "^1.18.5" - foreach "^2.0.5" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.7" - -which@2.0.2, which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== - -world-calendars@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/world-calendars/-/world-calendars-1.0.3.tgz#b25c5032ba24128ffc41d09faf4a5ec1b9c14335" - integrity sha1-slxQMrokEo/8QdCfr0pewbnBQzU= - dependencies: - object-assign "^4.1.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -ws@^7.3.1: - version "7.5.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" - integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== - -ws@^8.1.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.3.0.tgz#7185e252c8973a60d57170175ff55fdbd116070d" - integrity sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw== - -ws@~7.4.2: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -xtend@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.2.0.tgz#eef6b1f198c1c8deafad8b1765a04dad4a01c5a9" - integrity sha1-7vax8ZjByN6vrYsXZaBNrUoBxak= - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0, yargs@^16.1.1: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zero-crossings@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/zero-crossings/-/zero-crossings-1.0.1.tgz#c562bd3113643f3443a245d12406b88b69b9a9ff" - integrity sha1-xWK9MRNkPzRDokXRJAa4i2m5qf8= - dependencies: - cwise-compiler "^1.0.0" - -zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts index 53dee008..7d7564b5 100644 --- a/ui/ring/build.gradle.kts +++ b/ui/ring/build.gradle.kts @@ -5,7 +5,7 @@ plugins { val dataforgeVersion: String by rootProject.extra kotlin{ - js{ + js(IR){ useCommonJs() browser { commonWebpackConfig { diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index bfe711c8..1e9b59b9 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } kotlin { - js{ + js(IR){ binaries.library() } sourceSets { diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index ec77fa22..86234c10 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -4,7 +4,7 @@ plugins { dependencies { api(project(":visionforge-core")) - api(npmlibs.ktor.server.cio) - api(npmlibs.ktor.html.builder) - api(npmlibs.ktor.websockets) + api("io.ktor-server-cio:${npmlibs.versions.ktor}") + api("io.ktor:ktor-server-html-builder:${npmlibs.versions.ktor}") + api("io.ktor:ktor-server-websockets:${npmlibs.versions.ktor}") } \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts index 696b30cf..67e12b10 100644 --- a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts +++ b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts @@ -5,7 +5,7 @@ plugins { val ktorVersion: String by rootProject.extra kotlin { - js{ + js(IR){ browser { webpackTask { this.outputFileName = "js/visionforge-three.js" From 3198bad094db205efca5bbfe6eecf89f149c4048 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 13 Apr 2022 17:08:25 +0300 Subject: [PATCH 004/112] Update build. --- .gitignore | 2 + CHANGELOG.md | 3 +- build.gradle.kts | 2 +- demo/muon-monitor/build.gradle.kts | 5 +- .../ru/mipt/npm/muon/monitor/MMServer.kt | 28 +++++----- demo/playground/build.gradle.kts | 2 +- gradle.properties | 1 + gradle/wrapper/gradle-wrapper.properties | 2 +- .../visionforge/bootstrap/tabComponent.kt | 2 +- visionforge-server/build.gradle.kts | 9 ++-- .../visionforge/server/VisionServer.kt | 52 +++++++++---------- .../visionforge/tables/TableVisionJsPlugin.kt | 2 +- .../solid/three/ThreeLabelFactory.kt | 1 - 13 files changed, 55 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index 7fab40d3..6d07da58 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ build/ data/ !gradle-wrapper.jar + +/kotlin-js-store/yarn.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index d2cf0882..a59c31d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,11 @@ ## [Unreleased] ### Added +- Context receivers flag ### Changed - Naming of Canvas3D options -- Lights are added to the scene instead of 3D options +- Lights are added to the scene instead of 3D options ### Deprecated diff --git a/build.gradle.kts b/build.gradle.kts index c3148a64..3d983923 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ val fxVersion by extra("11") allprojects{ group = "space.kscience" - version = "0.2.1-dev-1" + version = "0.3.0-dev-1" } subprojects { diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index 59d3495a..f3b1710c 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -45,8 +45,9 @@ kotlin { jvmMain { dependencies { implementation("org.apache.commons:commons-math3:3.6.1") - implementation("io.ktor-server-cio:${npmlibs.versions.ktor}") - implementation("io.ktor:ktor-serialization-kotlinx-json:${npmlibs.versions.ktor}") + implementation("io.ktor:ktor-server-cio:${ktorVersion}") + implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}") + implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}") } } jsMain { diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt index 29abd7ca..aa533431 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt @@ -1,24 +1,22 @@ package ru.mipt.npm.muon.monitor.server -import io.ktor.application.Application -import io.ktor.application.call -import io.ktor.application.install -import io.ktor.application.log -import io.ktor.features.CallLogging -import io.ktor.features.ContentNegotiation -import io.ktor.features.DefaultHeaders import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode -import io.ktor.http.content.resources -import io.ktor.http.content.static -import io.ktor.response.respond -import io.ktor.response.respondText -import io.ktor.routing.Routing -import io.ktor.routing.get -import io.ktor.serialization.json +import io.ktor.serialization.kotlinx.json.json +import io.ktor.server.application.Application +import io.ktor.server.application.call +import io.ktor.server.application.install +import io.ktor.server.application.log import io.ktor.server.cio.CIO import io.ktor.server.engine.embeddedServer +import io.ktor.server.http.content.resources +import io.ktor.server.http.content.static +import io.ktor.server.plugins.contentnegotiation.ContentNegotiation +import io.ktor.server.response.respond +import io.ktor.server.response.respondText +import io.ktor.server.routing.Routing +import io.ktor.server.routing.get import org.apache.commons.math3.random.JDKRandomGenerator import ru.mipt.npm.muon.monitor.Model import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator @@ -40,8 +38,6 @@ fun Application.module(context: Context = Global) { environment.log.info("Current directory: $currentDir") val solidManager = context.fetch(Solids) - install(DefaultHeaders) - install(CallLogging) install(ContentNegotiation) { json() } diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index 61f4e033..076f9d37 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -32,7 +32,7 @@ kotlin { kotlinOptions { jvmTarget = "11" freeCompilerArgs = - freeCompilerArgs + "-Xjvm-default=all" + "-Xopt-in=kotlin.RequiresOptIn" + "-Xlambdas=indy" + freeCompilerArgs + "-Xjvm-default=all" + "-Xopt-in=kotlin.RequiresOptIn" + "-Xlambdas=indy" + "-Xcontext-receivers" } } testRuns["test"].executionTask.configure { diff --git a/gradle.properties b/gradle.properties index 1d420172..f6fbbfc2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,5 +3,6 @@ kotlin.mpp.stability.nowarn=true kotlin.jupyter.add.scanner=false org.gradle.parallel=true +org.gradle.jvmargs=-Xmx4G toolsVersion=0.11.4-kotlin-1.6.20 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6e5897..aa991fce 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt index 07bd9b55..23b5071b 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt @@ -30,7 +30,7 @@ public external interface TabPaneProps : PropsWithChildren { public val TabPane: FC = fc("TabPane") { props -> var activeTab: String? by useState(props.activeTab) - val children: Array = Children.map(props.children) { + val children: Array?> = Children.map(props.children) { it.asElementOrNull() } ?: emptyArray() diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index 86234c10..a89f2d07 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -2,9 +2,12 @@ plugins { id("ru.mipt.npm.gradle.jvm") } +val ktorVersion = npmlibs.versions.ktor.get() + dependencies { api(project(":visionforge-core")) - api("io.ktor-server-cio:${npmlibs.versions.ktor}") - api("io.ktor:ktor-server-html-builder:${npmlibs.versions.ktor}") - api("io.ktor:ktor-server-websockets:${npmlibs.versions.ktor}") + api("io.ktor:ktor-server-cio:${ktorVersion}") + api("io.ktor:ktor-server-html-builder:${ktorVersion}") + api("io.ktor:ktor-server-websockets:${ktorVersion}") + implementation("io.ktor:ktor-server-cors:${ktorVersion}") } \ No newline at end of file diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 2abb6efb..7d55771c 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -1,24 +1,25 @@ package space.kscience.visionforge.server -import io.ktor.application.* -import io.ktor.features.CORS -import io.ktor.features.CallLogging -import io.ktor.html.respondHtml import io.ktor.http.* -import io.ktor.http.cio.websocket.Frame -import io.ktor.http.content.resources -import io.ktor.http.content.static -import io.ktor.response.respond -import io.ktor.response.respondText -import io.ktor.routing.* +import io.ktor.server.application.* import io.ktor.server.cio.CIO import io.ktor.server.engine.ApplicationEngine import io.ktor.server.engine.embeddedServer -import io.ktor.util.getOrFail -import io.ktor.websocket.WebSockets -import io.ktor.websocket.webSocket +import io.ktor.server.html.respondHtml +import io.ktor.server.http.content.resources +import io.ktor.server.http.content.static +import io.ktor.server.plugins.cors.CORS +import io.ktor.server.response.respond +import io.ktor.server.response.respondText +import io.ktor.server.routing.* +import io.ktor.server.util.getOrFail +import io.ktor.server.websocket.WebSockets +import io.ktor.server.websocket.webSocket +import io.ktor.websocket.Frame import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.html.* @@ -130,13 +131,13 @@ public class VisionServer internal constructor( try { withContext(visionManager.context.coroutineContext) { - vision.flowChanges(updateInterval.milliseconds).collect { update -> + vision.flowChanges(updateInterval.milliseconds).onEach { update -> val json = visionManager.jsonFormat.encodeToString( VisionChange.serializer(), update ) outgoing.send(Frame.Text(json)) - } + }.collect() } } catch (t: Throwable) { application.log.info("WebSocket update channel for $name is closed with exception: $t") @@ -241,21 +242,16 @@ public fun Application.visionServer( webServerUrl: Url, path: String = DEFAULT_PAGE, ): VisionServer { - if (featureOrNull(WebSockets) == null) { - install(WebSockets) + install(WebSockets) + install(CORS) { + anyHost() } - if (featureOrNull(CORS) == null) { - install(CORS) { - anyHost() - } - } - - if (featureOrNull(CallLogging) == null) { - install(CallLogging) - } +// if (pluginOrNull(CallLogging) == null) { +// install(CallLogging) +// } - val serverRoute = (featureOrNull(Routing) ?: install(Routing)).createRouteFromPath(path) + val serverRoute = install(Routing).createRouteFromPath(path) serverRoute { static { @@ -263,7 +259,7 @@ public fun Application.visionServer( } } - return VisionServer(visionManager, webServerUrl.copy(encodedPath = path), serverRoute) + return VisionServer(visionManager, URLBuilder(webServerUrl).apply { encodedPath = path }.build(), serverRoute) } /** diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index 42525847..bc1fb271 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -1,6 +1,6 @@ package space.kscience.visionforge.tables -import kotlinext.js.jso +import kotlinx.js.jso import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.AbstractPlugin diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index 02586120..38e3e6a6 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -4,7 +4,6 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.core.Object3D import info.laht.threekt.geometries.TextBufferGeometry import info.laht.threekt.objects.Mesh -import kotlinext.js.jsObject import kotlinext.js.jso import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.warn From 212d729afbb3cd86fc9a3960cf7ad7bc46416b57 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 15 Apr 2022 12:46:05 +0300 Subject: [PATCH 005/112] A prototype for context receivers --- .../visionforge/html/HtmlVisionRenderer.kt | 2 +- .../visionforge/html/HtmlVisionContext.kt | 96 +++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt index f5abdf42..5a4395af 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt @@ -22,7 +22,7 @@ internal const val RENDER_FUNCTION_NAME = "renderAllVisionsById" /** * Render a fragment in the given consumer and return a map of extracted visions - * @param manager a VisionManager used for serialization + * @param context a context used to create a vision fragment * @param embedData embed Vision initial state in the HTML * @param fetchDataUrl fetch data after first render from given url * @param fetchUpdatesUrl receive push updates from the server at given url diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt new file mode 100644 index 00000000..513676d4 --- /dev/null +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt @@ -0,0 +1,96 @@ +package space.kscience.visionforge.html + +import kotlinx.html.* +import space.kscience.dataforge.context.ContextAware +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MetaSerializer +import space.kscience.dataforge.meta.isEmpty +import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.parseAsName +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.setAsRoot +import space.kscience.visionforge.visionManager + +/** + * Rendering context for visions in HTML + */ +public interface HtmlVisionContext : ContextAware { + + /** + * Generate div id for vision div tag + */ + public fun generateId(name: Name): String = "vision[$name]" + + /** + * Render vision at given [DIV] + */ + public fun DIV.renderVision(name: Name, vision: Vision, outputMeta: Meta) +} + + +public typealias HtmlVisionContextFragment = context(HtmlVisionContext) TagConsumer<*>.() -> Unit + +context(HtmlVisionContext) + public fun HtmlVisionContextFragment(content: TagConsumer<*>.() -> Unit): HtmlVisionFragment = content + +context(HtmlVisionContext) + private fun TagConsumer.vision( + visionManager: VisionManager, + name: Name, + vision: Vision, + outputMeta: Meta = Meta.EMPTY, +): T = div { + id = generateId(name) + classes = setOf(VisionTagConsumer.OUTPUT_CLASS) + vision.setAsRoot(visionManager) + attributes[VisionTagConsumer.OUTPUT_NAME_ATTRIBUTE] = name.toString() + if (!outputMeta.isEmpty()) { + //Hard-code output configuration + script { + attributes["class"] = VisionTagConsumer.OUTPUT_META_CLASS + unsafe { + +visionManager.jsonFormat.encodeToString(MetaSerializer, outputMeta) + } + } + } + renderVision(name, vision, outputMeta) +} + +context(HtmlVisionContext) + private fun TagConsumer.vision( + name: Name, + vision: Vision, + outputMeta: Meta = Meta.EMPTY, +): T = vision(context.visionManager, name, vision, outputMeta) + +/** + * Insert a vision in this HTML. + */ +context(HtmlVisionContext) + @DFExperimental + @VisionDSL + public fun TagConsumer.vision( + name: Name? = null, + visionProvider: VisionOutput.() -> Vision, +): T { + val output = VisionOutput(context, name) + val vision = output.visionProvider() + val actualName = + name ?: NameToken(VisionTagConsumer.DEFAULT_VISION_NAME, vision.hashCode().toUInt().toString()).asName() + return vision(output.buildVisionManager(), actualName, vision, output.meta) +} + +/** + * Insert a vision in this HTML. + */ +context(HtmlVisionContext) + @DFExperimental + @VisionDSL + public fun TagConsumer.vision( + name: String?, + visionProvider: VisionOutput.() -> Vision, +): T = vision(name?.parseAsName(), visionProvider) \ No newline at end of file From ce02a18c09a8afadf2456f65deeef3e6773ade6a Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 24 May 2022 23:00:10 +0300 Subject: [PATCH 006/112] Fix mesh conversion and lightning for examples --- demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt | 13 +++++++++++-- demo/playground/src/jvmMain/kotlin/randomSpheres.kt | 4 ++++ gradle.properties | 1 + visionforge-threejs/build.gradle.kts | 2 +- .../solid/three/ThreeCompositeFactory.kt | 4 ++-- .../visionforge/solid/three/ThreeMaterials.kt | 6 +----- .../space/kscience/visionforge/solid/three/three.kt | 12 +++++++++++- 7 files changed, 31 insertions(+), 11 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt b/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt index 6ee718a2..24c56304 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt @@ -1,12 +1,21 @@ package space.kscience.visionforge.examples import space.kscience.gdml.GdmlShowCase -import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.Colors +import space.kscience.visionforge.gdml.gdml import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.invoke +import space.kscience.visionforge.solid.solid fun main() = makeVisionFile { vision("canvas") { requirePlugin(Solids) - GdmlShowCase.babyIaxo().toVision() + solid { + ambientLight { + color(Colors.white) + } + gdml(GdmlShowCase.babyIaxo(), "D0") + } } } \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/randomSpheres.kt b/demo/playground/src/jvmMain/kotlin/randomSpheres.kt index 2d9a5f05..fd1b9865 100644 --- a/demo/playground/src/jvmMain/kotlin/randomSpheres.kt +++ b/demo/playground/src/jvmMain/kotlin/randomSpheres.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.examples import kotlinx.html.div import kotlinx.html.h1 +import space.kscience.visionforge.Colors import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.* import java.nio.file.Paths @@ -17,6 +18,9 @@ fun main() = makeVisionFile( div { vision { solid { + ambientLight { + color(Colors.white) + } repeat(100) { sphere(5, name = "sphere[$it]") { x = random.nextDouble(-300.0, 300.0) diff --git a/gradle.properties b/gradle.properties index f6fbbfc2..5a1cefb4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.jupyter.add.scanner=false +#kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index 3aa1ef5e..f0462837 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -11,5 +11,5 @@ kotlin{ dependencies { api(project(":visionforge-solid")) implementation(npm("three", "0.137.4")) - implementation(npm("three-csg-ts", "3.1.9")) + implementation(npm("three-csg-ts", "3.1.10")) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index f57530b3..74528c50 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -38,8 +38,8 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory override val type: KClass get() = Composite::class override fun invoke(three: ThreePlugin, obj: Composite): Mesh { - val first = three.buildObject3D(obj.first) as? Mesh ?: error("First part of composite is not a mesh") - val second = three.buildObject3D(obj.second) as? Mesh ?: error("Second part of composite is not a mesh") + val first = three.buildObject3D(obj.first).takeIfMesh() ?: error("First part of composite is not a mesh") + val second = three.buildObject3D(obj.second).takeIfMesh() ?: error("Second part of composite is not a mesh") return when (obj.compositeType) { CompositeType.GROUP, CompositeType.UNION -> CSG.union(first, second) CompositeType.INTERSECT -> CSG.intersect(first, second) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 5b4fa220..82b088e5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -161,17 +161,14 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { SolidMaterial.MATERIAL_COLOR_KEY -> { material.asDynamic().color = vision.computePropertyNode(SolidMaterial.MATERIAL_COLOR_KEY)?.threeColor() ?: ThreeMaterials.DEFAULT_COLOR - material.needsUpdate = true } SolidMaterial.SPECULAR_COLOR_KEY -> { material.asDynamic().specular = vision.computePropertyNode(SolidMaterial.SPECULAR_COLOR_KEY)?.threeColor() ?: ThreeMaterials.DEFAULT_COLOR - material.needsUpdate = true } SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { material.asDynamic().emissive = vision.computePropertyNode(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY)?.threeColor() ?: ThreeMaterials.BLACK_COLOR - material.needsUpdate = true } SolidMaterial.MATERIAL_OPACITY_KEY -> { val opacity = vision.getPropertyValue( @@ -180,16 +177,15 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { )?.double ?: 1.0 material.opacity = opacity material.transparent = opacity < 1.0 - material.needsUpdate = true } SolidMaterial.MATERIAL_WIREFRAME_KEY -> { material.asDynamic().wireframe = vision.getPropertyValue( SolidMaterial.MATERIAL_WIREFRAME_KEY, inherit = true, )?.boolean ?: false - material.needsUpdate = true } else -> console.warn("Unrecognized material property: $propertyName") } + material.needsUpdate = true } } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt index 447cf4b6..d21ff544 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Layers +import info.laht.threekt.core.Object3D import info.laht.threekt.external.controls.OrbitControls import info.laht.threekt.materials.Material import info.laht.threekt.math.Vector3 @@ -31,4 +32,13 @@ internal fun Any.dispose() { } } -public fun Layers.check(layer: Int): Boolean = (mask shr(layer) and 0x00000001) > 0 \ No newline at end of file +public fun Layers.check(layer: Int): Boolean = (mask shr (layer) and 0x00000001) > 0 + +internal fun Object3D.takeIfMesh(): Mesh? { + val d = asDynamic() + return if(d.isMesh as Boolean){ + d.unsafeCast() + } else { + null + } +} \ No newline at end of file From 86935ce52af027c72bcf75c2b8a6e20c5f153156 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 24 May 2022 23:09:40 +0300 Subject: [PATCH 007/112] Fix light in GDML demo --- .../kscience/visionforge/gdml/demo/GDMLAppComponent.kt | 6 ++++++ .../kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt index 823297ec..c82fa60b 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt @@ -17,6 +17,7 @@ import space.kscience.dataforge.context.fetch import space.kscience.dataforge.names.Name import space.kscience.gdml.Gdml import space.kscience.gdml.decodeFromString +import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.markLayers import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.ring.ThreeCanvasWithControls @@ -24,6 +25,8 @@ import space.kscience.visionforge.ring.tab import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.invoke import styled.css import styled.styledDiv @@ -53,6 +56,9 @@ val GDMLApp = fc("GDMLApp") { props -> setAsRoot(visionManager) console.info("Marking layers for file $name") markLayers() + ambientLight { + color(Colors.white) + } } } name.endsWith(".json") -> visionManager.decodeFromString(data) diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index 74246432..284e09f6 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -6,7 +6,10 @@ import react.dom.render import space.kscience.dataforge.context.Context import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Application +import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication import styled.injectGlobal @@ -41,7 +44,11 @@ private class GDMLDemoApp : Application { render(element) { child(GDMLApp) { - val vision = GdmlShowCase.cubes().toVision() + val vision = GdmlShowCase.cubes().toVision().apply { + ambientLight { + color(Colors.white) + } + } //println(context.plugins.fetch(VisionManager).encodeToString(vision)) attrs { this.context = context From 4b1149b99ba35efc2672d89a8879824bb92c4d3a Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 6 Jul 2022 11:11:48 +0300 Subject: [PATCH 008/112] Migrate to new build tools and DF 0.6 --- build.gradle.kts | 10 ++++++++-- .../kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt | 5 +++-- .../js-playground/src/main/kotlin/JsPlaygroundApp.kt | 5 +++-- .../kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt | 5 +++-- gradle.properties | 2 +- ui/react/build.gradle.kts | 4 ++++ .../kscience/visionforge/react/PropertyEditor.kt | 4 ++-- .../kotlin/space/kscience/visionforge/react/ext.kt | 10 ++++++++++ .../ThreeWithControlsPlugin.kt | 8 +++++--- .../ringPropertyEditor.kt | 5 +++-- .../space/kscience/visionforge/VisionManager.kt | 2 +- .../space/kscience/visionforge/VisionClient.kt | 3 +-- .../kotlin/space/kscience/visionforge/FXPlugin.kt | 5 +++-- .../space/kscience/visionforge/solid/FX3DPlugin.kt | 3 ++- .../kscience/visionforge/markup/MarkupPlugin.kt | 4 +++- .../space/kscience/visionforge/plotly/plotlyJs.kt | 4 +++- .../space/kscience/visionforge/plotly/plotlyJvm.kt | 5 +++-- .../space/kscience/visionforge/solid/Solids.kt | 3 ++- visionforge-tables/build.gradle.kts | 2 +- .../kscience/visionforge/tables/TableVisionPlugin.kt | 4 ++-- .../kscience/visionforge/tables/VisionOfTable.kt | 6 +++--- .../kscience/visionforge/tables/VisionOfTableTest.kt | 4 ++-- .../visionforge/tables/TableVisionJsPlugin.kt | 12 ++++++------ .../visionforge/solid/three/ThreeLabelFactory.kt | 2 +- .../kscience/visionforge/solid/three/ThreePlugin.kt | 3 ++- 25 files changed, 77 insertions(+), 43 deletions(-) create mode 100644 ui/react/src/main/kotlin/space/kscience/visionforge/react/ext.kt diff --git a/build.gradle.kts b/build.gradle.kts index 3d983923..5e8bc323 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,12 +3,12 @@ plugins { // id("org.jetbrains.kotlinx.kover") version "0.5.0" } -val dataforgeVersion by extra("0.5.2") +val dataforgeVersion by extra("0.6.0-dev-10") val fxVersion by extra("11") allprojects{ group = "space.kscience" - version = "0.3.0-dev-1" + version = "0.3.0-dev-2" } subprojects { @@ -19,6 +19,12 @@ subprojects { mavenCentral() maven("https://maven.jzy3d.org/releases") } + + tasks.withType{ + kotlinOptions{ + freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers" + } + } } ksciencePublish { diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index 284e09f6..edcbe6f0 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -2,12 +2,13 @@ package space.kscience.visionforge.gdml.demo import kotlinx.browser.document import kotlinx.css.* -import react.dom.render +import react.dom.client.createRoot import space.kscience.dataforge.context.Context import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Application import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.ambientLight import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.three.ThreePlugin @@ -42,7 +43,7 @@ private class GDMLDemoApp : Application { val element = document.getElementById("application") ?: error("Element with id 'application' not found on page") - render(element) { + createRoot(element).render { child(GDMLApp) { val vision = GdmlShowCase.cubes().toVision().apply { ambientLight { diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index 5e09911b..1cd2611b 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -1,6 +1,6 @@ import kotlinx.browser.document import kotlinx.css.* -import react.dom.render +import react.dom.client.createRoot import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.context.Context @@ -10,6 +10,7 @@ import space.kscience.visionforge.Application import space.kscience.visionforge.Colors import space.kscience.visionforge.VisionClient import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.react.render import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.ThreeWithControlsPlugin import space.kscience.visionforge.ring.solid @@ -38,7 +39,7 @@ private class JsPlaygroundApp : Application { val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page") - render(element) { + createRoot(element).render { styledDiv { css { padding(0.pt) diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 6b611146..17c3f149 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -1,11 +1,12 @@ package ru.mipt.npm.muon.monitor import kotlinx.browser.document -import react.dom.render +import react.dom.client.createRoot import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch import space.kscience.visionforge.Application import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication @@ -21,7 +22,7 @@ private class MMDemoApp : Application { val model = Model(visionManager) val element = document.getElementById("app") ?: error("Element with id 'app' not found on page") - render(element) { + createRoot(element).render { child(MMApp) { attrs { this.model = model diff --git a/gradle.properties b/gradle.properties index 5a1cefb4..95d6d923 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,4 @@ kotlin.jupyter.add.scanner=false org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.11.4-kotlin-1.6.20 \ No newline at end of file +toolsVersion=0.11.7-kotlin-1.7.0 \ No newline at end of file diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index 40853ca9..d71dc6ac 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -8,4 +8,8 @@ dependencies{ api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") // implementation(npm("react-select","4.3.0")) implementation(project(":visionforge-threejs")) +} + +rootProject.extensions.configure { + versions.webpackCli.version = "4.10.0" } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index 6c677e2e..29c9b49e 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -7,7 +7,7 @@ import org.w3c.dom.Element import org.w3c.dom.events.Event import react.* import react.dom.attrs -import react.dom.render +import react.dom.client.createRoot import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.ValueRequirement @@ -235,6 +235,6 @@ public fun Element.configEditor( default: Meta = config, descriptor: MetaDescriptor? = null, key: Any? = null, -): Unit = render(this) { +): Unit = createRoot(this).render { configEditor(config, default, descriptor, key = key) } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ext.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ext.kt new file mode 100644 index 00000000..ae47fa65 --- /dev/null +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ext.kt @@ -0,0 +1,10 @@ +package space.kscience.visionforge.react + +import react.Props +import react.RBuilder +import react.createElement +import react.dom.client.Root + +public fun Root.render(block: RBuilder.() -> Unit) { + render(createElement(block)) +} \ No newline at end of file diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt index c01b5ae1..bf1a2160 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt @@ -2,7 +2,7 @@ package space.kscience.visionforge.ring import kotlinx.coroutines.async import org.w3c.dom.Element -import react.child +import react.dom.client.createRoot import space.kscience.dataforge.context.AbstractPlugin import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory @@ -12,6 +12,7 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision +import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.three.ThreePlugin import kotlin.reflect.KClass @@ -25,7 +26,7 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING override fun render(element: Element, vision: Vision, meta: Meta) { - react.dom.render(element) { + createRoot(element).render { child(ThreeCanvasWithControls) { attrs { this.context = this@ThreeWithControlsPlugin.context @@ -45,6 +46,7 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.threejs.withControls", PluginTag.DATAFORGE_GROUP) override val type: KClass = ThreeWithControlsPlugin::class - override fun invoke(meta: Meta, context: Context): ThreeWithControlsPlugin = ThreeWithControlsPlugin() + + override fun build(context: Context, meta: Meta): ThreeWithControlsPlugin = ThreeWithControlsPlugin() } } \ No newline at end of file diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt index 06f2a1c0..5c959184 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt @@ -2,8 +2,8 @@ package space.kscience.visionforge.ring import org.w3c.dom.Element import react.RBuilder +import react.dom.client.createRoot import react.dom.p -import react.dom.render import ringui.Island import ringui.SmartTabs import ringui.Tab @@ -14,6 +14,7 @@ import space.kscience.visionforge.getStyle import space.kscience.visionforge.react.flexColumn import space.kscience.visionforge.react.metaViewer import space.kscience.visionforge.react.propertyEditor +import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.styles @@ -72,6 +73,6 @@ public fun RBuilder.ringPropertyEditor( public fun Element.ringPropertyEditor( item: Vision, descriptor: MetaDescriptor? = item.descriptor, -): Unit = render(this) { +): Unit = createRoot(this).render { ringPropertyEditor(item, descriptor = descriptor) } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 118fd47c..cd017cad 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -63,7 +63,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) { public const val VISION_SERIALIZER_MODULE_TARGET: String = "visionSerializerModule" - override fun invoke(meta: Meta, context: Context): VisionManager = VisionManager(meta) + override fun build(context: Context, meta: Meta): VisionManager = VisionManager(meta) private val defaultSerialModule: SerializersModule = SerializersModule { polymorphic(Vision::class) { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index c437a5d6..e9425afb 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -203,8 +203,7 @@ public class VisionClient : AbstractPlugin() { ) else super.content(target) public companion object : PluginFactory { - - override fun invoke(meta: Meta, context: Context): VisionClient = VisionClient() + override fun build(context: Context, meta: Meta): VisionClient = VisionClient() override val tag: PluginTag = PluginTag(name = "vision.client", group = PluginTag.DATAFORGE_GROUP) diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/FXPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/FXPlugin.kt index c571059c..4edc4f13 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/FXPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/FXPlugin.kt @@ -95,8 +95,9 @@ public class FXPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(meta) { public companion object : PluginFactory { override val type: KClass = FXPlugin::class override val tag: PluginTag = PluginTag("vis.fx", group = PluginTag.DATAFORGE_GROUP) - override fun invoke(meta: Meta, context: Context): FXPlugin = - FXPlugin(meta) + + override fun build(context: Context, meta: Meta): FXPlugin = FXPlugin(meta) + } } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt index 48f99ac1..e16b2126 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt @@ -138,7 +138,8 @@ public class FX3DPlugin : AbstractPlugin() { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.fx3D", PluginTag.DATAFORGE_GROUP) override val type: KClass = FX3DPlugin::class - override fun invoke(meta: Meta, context: Context): FX3DPlugin = FX3DPlugin() + + override fun build(context: Context, meta: Meta): FX3DPlugin = FX3DPlugin() } } diff --git a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index 4d7a1060..939669a0 100644 --- a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -47,6 +47,8 @@ public class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP) override val type: KClass = MarkupPlugin::class - override fun invoke(meta: Meta, context: Context): MarkupPlugin = MarkupPlugin() + + override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() + } } \ No newline at end of file diff --git a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt index 7406986b..d3b8473e 100644 --- a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt +++ b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt @@ -42,6 +42,8 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { public actual companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.plotly.js", PluginTag.DATAFORGE_GROUP) override val type: KClass = PlotlyPlugin::class - override fun invoke(meta: Meta, context: Context): PlotlyPlugin = PlotlyPlugin() + + override fun build(context: Context, meta: Meta): PlotlyPlugin = PlotlyPlugin() + } } \ No newline at end of file diff --git a/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt b/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt index ad7be4f3..8fda1d98 100644 --- a/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt +++ b/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.plotly import kotlinx.serialization.modules.SerializersModule import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.Plugin import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta @@ -18,6 +17,8 @@ public actual class PlotlyPlugin : VisionPlugin() { public actual companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP) override val type: KClass = PlotlyPlugin::class - override fun invoke(meta: Meta, context: Context): PlotlyPlugin = PlotlyPlugin() + + override fun build(context: Context, meta: Meta): PlotlyPlugin = PlotlyPlugin() + } } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 7e52d709..b43d6475 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -24,7 +24,8 @@ public class Solids(meta: Meta) : VisionPlugin(meta) { public companion object : PluginFactory { override val tag: PluginTag = PluginTag(name = "vision.solid", group = PluginTag.DATAFORGE_GROUP) override val type: KClass = Solids::class - override fun invoke(meta: Meta, context: Context): Solids = Solids(meta) + + override fun build(context: Context, meta: Meta): Solids = Solids(meta) private fun PolymorphicModuleBuilder.solids() { subclass(SolidGroup.serializer()) diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index 55c367c5..4326da36 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("ru.mipt.npm.gradle.mpp") } -val tablesVersion = "0.1.4" +val tablesVersion = "0.2.0-dev-1" kscience { useSerialization() diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt index 6e632147..fd03b550 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt @@ -8,7 +8,6 @@ import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionManager import space.kscience.visionforge.VisionPlugin import kotlin.reflect.KClass @@ -25,6 +24,7 @@ public class TableVisionPlugin : VisionPlugin() { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.table", PluginTag.DATAFORGE_GROUP) override val type: KClass = TableVisionPlugin::class - override fun invoke(meta: Meta, context: Context): TableVisionPlugin = TableVisionPlugin() + + override fun build(context: Context, meta: Meta): TableVisionPlugin = TableVisionPlugin() } } \ No newline at end of file diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt index 95888f67..6370b699 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt @@ -86,7 +86,7 @@ public fun Table.toVision(): VisionOfTable = toVision { (it ?: Double.Na @DFExperimental public inline fun VisionOutput.table( vararg headers: ColumnHeader, - block: MutableRowTable.() -> Unit, + block: RowTableBuilder.() -> Unit, ): VisionOfTable { requirePlugin(TableVisionPlugin) return RowTable(*headers, block = block).toVision() @@ -94,8 +94,8 @@ public inline fun VisionOutput.table( @DFExperimental public inline fun VisionOutput.columnTable( - columnSize: UInt, - block: MutableColumnTable.() -> Unit, + columnSize: Int, + block: ColumnTableBuilder.() -> Unit, ): VisionOfTable = ColumnTable(columnSize, block).toVision() @DFExperimental diff --git a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt index 5796d8e2..8c9f755c 100644 --- a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt +++ b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt @@ -17,7 +17,7 @@ internal class VisionOfTableTest { val x by ColumnHeader.typed() val y by ColumnHeader.typed() - val table = ColumnTable(100U) { + val table = ColumnTable(100) { x.fill { it.asValue() } y.values = x.values.map { it?.double?.pow(2)?.asValue() } } @@ -27,6 +27,6 @@ internal class VisionOfTableTest { val rows = vision.rowSequence().toList() - assertEquals(50, rows[50][x]?.int) + assertEquals(50, rows[50][x].int) } } \ No newline at end of file diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index bc1fb271..28ad7327 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -7,7 +7,6 @@ import space.kscience.dataforge.context.AbstractPlugin import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag -import space.kscience.dataforge.meta.DynamicMeta import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.toDynamic import space.kscience.dataforge.names.Name @@ -49,15 +48,15 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { } }.toTypedArray() - columns = Array(table.headers.size + 1){ - if(it==0){ + columns = Array(table.headers.size + 1) { + if (it == 0) { jso { field = "@index" title = "#" resizable = false } } else { - val header = table.headers[it-1] + val header = table.headers[it - 1] jso { field = header.name title = header.properties.title ?: header.name @@ -67,7 +66,7 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { } - data = table.rows.mapIndexed { index, row-> + data = table.rows.mapIndexed { index, row -> val d = row.meta.toDynamic() d["@index"] = index d @@ -91,6 +90,7 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.table.js", PluginTag.DATAFORGE_GROUP) override val type: KClass = TableVisionJsPlugin::class - override fun invoke(meta: Meta, context: Context): TableVisionJsPlugin = TableVisionJsPlugin() + + override fun build(context: Context, meta: Meta): TableVisionJsPlugin = TableVisionJsPlugin() } } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index 38e3e6a6..d07f542e 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -4,7 +4,7 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.core.Object3D import info.laht.threekt.geometries.TextBufferGeometry import info.laht.threekt.objects.Mesh -import kotlinext.js.jso +import kotlinx.js.jso import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.warn import space.kscience.visionforge.onPropertyChange diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 8c32551a..182ec009 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -151,7 +151,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.threejs", PluginTag.DATAFORGE_GROUP) override val type: KClass = ThreePlugin::class - override fun invoke(meta: Meta, context: Context): ThreePlugin = ThreePlugin() + + override fun build(context: Context, meta: Meta): ThreePlugin = ThreePlugin() } } From 791d6d7a815376b7af2550a7101a6e38c7191ed0 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 4 Aug 2022 21:36:00 +0300 Subject: [PATCH 009/112] [WIP] great refactoring in progress --- build.gradle.kts | 2 +- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 37 ++- .../npm/root/serialization/rootToSolid.kt | 2 +- .../visionforge/gdml/GDMLVisionTest.kt | 14 +- .../visionforge/gdml/demo/GDMLAppComponent.kt | 1 - .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 1 - .../src/main/kotlin/JsPlaygroundApp.kt | 4 +- .../src/main/kotlin/gravityDemo.kt | 4 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 20 +- .../mipt/npm/muon/monitor/MMAppComponent.kt | 1 - .../src/jvmMain/kotlin/gdmlCurve.kt | 4 +- .../playground/src/jvmMain/kotlin/gdmlIaxo.kt | 4 +- .../src/jvmMain/kotlin/randomSpheres.kt | 4 +- .../src/jvmMain/kotlin/simpleCube.kt | 4 +- .../main/kotlin/ru/mipt/npm/sat/geometry.kt | 2 +- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 2 +- .../kscience/visionforge/solid/demo/demo.kt | 30 +- .../visionforge/solid/demo/VariableBox.kt | 3 +- docs/hierarchy.md | 2 +- docs/inheritance.md | 2 +- docs/uml/Vision.puml | 6 +- gradle.properties | 2 +- .../visionforge/bootstrap/threeControls.kt | 4 +- .../bootstrap/visionPropertyEditor.kt | 5 +- .../kscience/visionforge/react/VisionTree.kt | 10 +- .../ThreeViewWithControls.kt | 4 +- visionforge-core/api/visionforge-core.api | 16 +- .../kscience/visionforge/AbstractVision.kt | 107 ++++++ .../visionforge/ComputedVisionProperties.kt | 84 ----- .../kscience/visionforge/StyleReference.kt | 6 +- .../space/kscience/visionforge/StyleSheet.kt | 36 ++- .../space/kscience/visionforge/Vision.kt | 201 ++++++++---- .../space/kscience/visionforge/VisionBase.kt | 176 ---------- .../kscience/visionforge/VisionChange.kt | 36 +-- .../kscience/visionforge/VisionContainer.kt | 196 +++++++++++ .../space/kscience/visionforge/VisionGroup.kt | 158 +++++---- .../kscience/visionforge/VisionGroupBase.kt | 168 ---------- .../kscience/visionforge/VisionManager.kt | 26 +- .../kscience/visionforge/VisionProperties.kt | 81 +++++ .../visionforge/VisionPropertyContainer.kt | 27 +- .../visionforge/html/VisionOfHtmlForm.kt | 3 +- .../visionforge/html/VisionOfHtmlInput.kt | 15 +- .../kscience/visionforge/visionDelegates.kt | 4 +- .../kscience/visionforge/visionDescriptor.kt | 1 + .../visionforge/visitor/StatisticsVisitor.kt | 2 - .../visionforge/visitor/VisionVisitor.kt | 18 +- .../kscience/visionforge/html/HtmlTagTest.kt | 16 +- .../visionforge/meta/VisionPropertyTest.kt | 36 ++- .../editor/VisionEditorFragment.kt | 9 +- .../visionforge/editor/VisionTreeFragment.kt | 8 +- .../kscience/visionforge/solid/FX3DPlugin.kt | 8 +- .../visionforge/solid/FXReferenceFactory.kt | 11 +- .../solid/VisualObjectFXBinding.kt | 4 +- .../visionforge/gdml/GdmlLoaderOptions.kt | 4 +- .../kscience/visionforge/gdml/gdmlLoader.kt | 16 +- .../kscience/visionforge/gdml/markLayers.kt | 17 +- .../src/commonTest/kotlin/TestCubes.kt | 6 +- .../visionforge/markup/VisionOfMarkup.kt | 7 +- .../visionforge/plotly/VisionOfPlotly.kt | 11 +- .../visionforge/server/VisionServer.kt | 3 +- visionforge-solid/api/visionforge-solid.api | 4 +- .../visionforge/solid/ColorAccessor.kt | 13 +- .../kscience/visionforge/solid/Composite.kt | 31 +- .../kscience/visionforge/solid/Extruded.kt | 12 +- .../kscience/visionforge/solid/Quaternion.kt | 11 - .../space/kscience/visionforge/solid/Solid.kt | 34 +- .../kscience/visionforge/solid/SolidBase.kt | 17 +- .../kscience/visionforge/solid/SolidGroup.kt | 43 ++- .../visionforge/solid/SolidMaterial.kt | 11 +- .../visionforge/solid/SolidReference.kt | 304 +++++++++++------- .../kscience/visionforge/solid/Solids.kt | 5 +- .../kscience/visionforge/solid/Sphere.kt | 10 +- .../kscience/visionforge/solid/SphereLayer.kt | 18 +- .../kscience/visionforge/solid/geometry.kt | 6 +- .../solid/specifications/Canvas3DOptions.kt | 1 + .../solid/transform/RemoveSingleChild.kt | 45 ++- .../visionforge/solid/transform/UnRef.kt | 36 ++- .../visionforge/solid/CompositeTest.kt | 2 +- .../kscience/visionforge/solid/ConvexTest.kt | 5 +- .../kscience/visionforge/solid/GroupTest.kt | 14 +- .../visionforge/solid/PropertyTest.kt | 20 +- .../visionforge/solid/SerializationTest.kt | 17 +- .../visionforge/solid/SolidPluginTest.kt | 5 +- .../visionforge/solid/SolidReferenceTest.kt | 6 +- .../visionforge/solid/VisionUpdateTest.kt | 12 +- .../visionforge/tables/VisionOfTable.kt | 8 +- .../solid/three/MeshThreeFactory.kt | 17 +- .../solid/three/ThreeAmbientLightFactory.kt | 2 +- .../solid/three/ThreeCanvasLabelFactory.kt | 5 +- .../solid/three/ThreeCompositeFactory.kt | 2 +- .../visionforge/solid/three/ThreeFactory.kt | 2 +- .../solid/three/ThreeLabelFactory.kt | 2 +- .../solid/three/ThreeLineFactory.kt | 6 +- .../visionforge/solid/three/ThreeMaterials.kt | 4 +- .../visionforge/solid/three/ThreePlugin.kt | 11 +- .../solid/three/ThreePointLightFactory.kt | 9 +- .../solid/three/ThreeReferenceFactory.kt | 4 +- 97 files changed, 1290 insertions(+), 1155 deletions(-) create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt delete mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ComputedVisionProperties.kt delete mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt delete mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt delete mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Quaternion.kt diff --git a/build.gradle.kts b/build.gradle.kts index 5e8bc323..f0c9d504 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ plugins { // id("org.jetbrains.kotlinx.kover") version "0.5.0" } -val dataforgeVersion by extra("0.6.0-dev-10") +val dataforgeVersion by extra("0.6.0-dev-12") val fxVersion by extra("11") allprojects{ diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 7c345dd4..fbeb84dd 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -1,10 +1,14 @@ package ru.mipt.npm.root -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.double +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.isEmpty import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.doubleArray import space.kscience.visionforge.isEmpty +import space.kscience.visionforge.setPropertyValue import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY import kotlin.math.* @@ -20,7 +24,7 @@ private fun degToRad(d: Double) = d * PI / 180.0 private data class RootToSolidContext( val prototypeHolder: PrototypeHolder, val currentLayer: Int = 0, - val maxLayer: Int = 5 + val maxLayer: Int = 5, ) // converting to XYZ to Tait–Bryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix @@ -42,14 +46,17 @@ private fun Solid.useMatrix(matrix: DGeoMatrix?) { "TGeoIdentity" -> { //do nothing } + "TGeoTranslation" -> { val fTranslation by matrix.meta.doubleArray() translate(fTranslation) } + "TGeoRotation" -> { val fRotationMatrix by matrix.meta.doubleArray() rotate(fRotationMatrix) } + "TGeoCombiTrans" -> { val fTranslation by matrix.meta.doubleArray() @@ -58,6 +65,7 @@ private fun Solid.useMatrix(matrix: DGeoMatrix?) { rotate(it.doubleArray) } } + "TGeoHMatrix" -> { val fTranslation by matrix.meta.doubleArray() val fRotationMatrix by matrix.meta.doubleArray() @@ -73,7 +81,7 @@ private fun SolidGroup.addShape( shape: DGeoShape, context: RootToSolidContext, name: String? = shape.fName.ifEmpty { null }, - block: Solid.() -> Unit = {} + block: Solid.() -> Unit = {}, ) { when (shape.typename) { "TGeoCompositeShape" -> { @@ -94,6 +102,7 @@ private fun SolidGroup.addShape( } }.apply(block) } + "TGeoXtru" -> { val fNvert by shape.meta.int(0) val fX by shape.meta.doubleArray() @@ -121,6 +130,7 @@ private fun SolidGroup.addShape( } }.apply(block) } + "TGeoTube" -> { val fRmax by shape.meta.double(0.0) val fDz by shape.meta.double(0.0) @@ -134,6 +144,7 @@ private fun SolidGroup.addShape( block = block ) } + "TGeoTubeSeg" -> { val fRmax by shape.meta.double(0.0) val fDz by shape.meta.double(0.0) @@ -151,6 +162,7 @@ private fun SolidGroup.addShape( block = block ) } + "TGeoPcon" -> { val fDphi by shape.meta.double(0.0) val fNz by shape.meta.int(2) @@ -176,6 +188,7 @@ private fun SolidGroup.addShape( TODO() } } + "TGeoPgon" -> { //TODO add a inner polygone layer val fDphi by shape.meta.double(0.0) @@ -206,15 +219,18 @@ private fun SolidGroup.addShape( } }.apply(block) } + "TGeoShapeAssembly" -> { val fVolume by shape.dObject(::DGeoVolume) fVolume?.let { volume -> addRootVolume(volume, context, block = block) } } + "TGeoBBox" -> { box(shape.fDX * 2, shape.fDY * 2, shape.fDZ * 2, name = name, block = block) } + "TGeoTrap" -> { val fTheta by shape.meta.double(0.0) val fPhi by shape.meta.double(0.0) @@ -242,6 +258,7 @@ private fun SolidGroup.addShape( val node8 = Point3D(-fTl2, fH2, fDz) hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name) } + "TGeoScaledShape" -> { val fShape by shape.dObject(::DGeoShape) val fScale by shape.dObject(::DGeoScale) @@ -253,6 +270,7 @@ private fun SolidGroup.addShape( } } } + else -> { TODO("A shape with type ${shape.typename} not implemented") } @@ -267,6 +285,7 @@ private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) { val fMatrix by obj.dObject(::DGeoMatrix) this.useMatrix(fMatrix) } + "TGeoNodeOffset" -> { val fOffset by obj.meta.double(0.0) x = fOffset @@ -301,10 +320,10 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? } } } - return if (group.isEmpty()) { + return if (group.children.isEmpty()) { null - } else if (group.children.size == 1 && group.meta.isEmpty()) { - (group.children.values.first() as Solid).apply { parent = null } + } else if (group.items.size == 1 && group.meta.isEmpty()) { + group.items.values.first().apply { parent = null } } else { group } @@ -317,7 +336,7 @@ private fun SolidGroup.addRootVolume( context: RootToSolidContext, name: String? = null, cache: Boolean = true, - block: Solid.() -> Unit = {} + block: Solid.() -> Unit = {}, ) { val combinedName = if (volume.fName.isEmpty()) { name @@ -330,7 +349,7 @@ private fun SolidGroup.addRootVolume( if (!cache) { val group = buildVolume(volume, context)?.apply { volume.fFillColor?.let { - meta[MATERIAL_COLOR_KEY] = RootColors[it] + setPropertyValue(MATERIAL_COLOR_KEY, RootColors[it]) } block() } @@ -347,7 +366,7 @@ private fun SolidGroup.addRootVolume( ref(templateName, name).apply { volume.fFillColor?.let { - meta[MATERIAL_COLOR_KEY] = RootColors[it] + setPropertyValue(MATERIAL_COLOR_KEY, RootColors[it]) } block() } diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt index 117e51b3..4483afcb 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt @@ -160,7 +160,7 @@ private fun SolidGroup.volume(volume: TGeoVolume, name: String? = null, cache: B name = combinedName, obj = group, prototypeHolder = rootPrototypes, - templateName = volumesName + Name.parse(combinedName ?: "volume[${group.hashCode()}]") + prototypeName = volumesName + Name.parse(combinedName ?: "volume[${group.hashCode()}]") ) } diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index 12918532..afb23f16 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -1,13 +1,13 @@ package space.kscience.visionforge.gdml +import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.string import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties import space.kscience.visionforge.get -import space.kscience.visionforge.setProperty +import space.kscience.visionforge.getProperty +import space.kscience.visionforge.getPropertyValue import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.material @@ -20,8 +20,8 @@ class GDMLVisionTest { @Test fun testCubesStyles(){ - val segment = cubes["composite-000.segment-0"] as Solid - println(segment.computeProperties().getValue(Vision.STYLE_KEY)) + val segment = cubes.children["composite-000.segment-0"] as Solid + println(segment.getPropertyValue(Vision.STYLE_KEY)) // println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY)) // println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY)) @@ -35,7 +35,7 @@ class GDMLVisionTest { fun testPrototypeProperty() { val child = cubes[Name.of("composite-000","segment-0")] assertNotNull(child) - child.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) - assertEquals("red", child.getPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY)?.string) + child.setPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) + assertEquals("red", child.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string) } } \ No newline at end of file diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt index c82fa60b..b28dec12 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt @@ -26,7 +26,6 @@ import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.invoke import styled.css import styled.styledDiv diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index edcbe6f0..1cd1b0ff 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -10,7 +10,6 @@ import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication import styled.injectGlobal diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index 1cd2611b..c31b48e0 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -75,7 +75,7 @@ private class JsPlaygroundApp : Application { context = playgroundContext solid { ambientLight { - color(Colors.white) + color.set(Colors.white) } repeat(100) { sphere(5, name = "sphere[$it]") { @@ -83,7 +83,7 @@ private class JsPlaygroundApp : Application { y = random.nextDouble(-300.0, 300.0) z = random.nextDouble(-300.0, 300.0) material { - color(random.nextInt()) + color.set(random.nextInt()) } detail = 16 } diff --git a/demo/js-playground/src/main/kotlin/gravityDemo.kt b/demo/js-playground/src/main/kotlin/gravityDemo.kt index 4d420cc7..3bdd574c 100644 --- a/demo/js-playground/src/main/kotlin/gravityDemo.kt +++ b/demo/js-playground/src/main/kotlin/gravityDemo.kt @@ -43,13 +43,13 @@ val GravityDemo = fc { props -> context = props.context solid { pointLight(200, 200, 200, name = "light"){ - color(Colors.white) + color.set(Colors.white) } ambientLight() sphere(5.0, "ball") { detail = 16 - color("red") + color.set("red") val h = 100.0 y = h context.launch { diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 06501374..596b11dd 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -3,24 +3,18 @@ package ru.mipt.npm.muon.monitor import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.LOWER_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.UPPER_LAYER_Z +import space.kscience.visionforge.VisionContainerBuilder import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.removeAll import space.kscience.visionforge.setAsRoot -import space.kscience.visionforge.setProperty import space.kscience.visionforge.solid.* -import kotlin.collections.HashMap -import kotlin.collections.HashSet -import kotlin.collections.filter -import kotlin.collections.forEach import kotlin.collections.set -import kotlin.collections.toTypedArray import kotlin.math.PI class Model(val manager: VisionManager) { private val map = HashMap() private val events = HashSet() - private fun SolidGroup.pixel(pixel: SC1) { + private fun VisionContainerBuilder.pixel(pixel: SC1) { val group = group(pixel.name) { position = Point3D(pixel.center.x, pixel.center.y, pixel.center.z) box(pixel.xSize, pixel.ySize, pixel.zSize) @@ -45,7 +39,7 @@ class Model(val manager: VisionManager) { val root: SolidGroup = SolidGroup().apply { setAsRoot(this@Model.manager) material { - color("darkgreen") + color.set("darkgreen") } rotationX = PI / 2 group("bottom") { @@ -70,14 +64,14 @@ class Model(val manager: VisionManager) { private fun highlight(pixel: String) { println("highlight $pixel") - map[pixel]?.color?.invoke("blue") + map[pixel]?.color.set("blue") } fun reset() { map.values.forEach { - it.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, null) + it.setPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY, null) } - tracks.removeAll() + tracks.children.clear() } fun displayEvent(event: Event) { @@ -89,7 +83,7 @@ class Model(val manager: VisionManager) { event.track?.let { tracks.polyline(*it.toTypedArray(), name = "track[${event.id}]") { thickness = 4 - color("red") + color.set("red") } } } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index f9c03756..77ad5845 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -25,7 +25,6 @@ import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.tab import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.edges import styled.css diff --git a/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt b/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt index 70827a2d..f98a0b81 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt @@ -7,7 +7,7 @@ import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.color -import space.kscience.visionforge.solid.invoke +import space.kscience.visionforge.solid.set import space.kscience.visionforge.visible import java.nio.file.Path @@ -229,7 +229,7 @@ fun main() = makeVisionFile(Path.of("curves.html"), resourceLocation = ResourceL visible = false } if(solid.name.startsWith("gas")){ - color("green") + color.set("green") } else { //make all solids semi-transparent transparent() diff --git a/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt b/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt index 24c56304..ee47c461 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt @@ -5,7 +5,7 @@ import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.gdml import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.invoke +import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.solid fun main() = makeVisionFile { @@ -13,7 +13,7 @@ fun main() = makeVisionFile { requirePlugin(Solids) solid { ambientLight { - color(Colors.white) + color.set(Colors.white) } gdml(GdmlShowCase.babyIaxo(), "D0") } diff --git a/demo/playground/src/jvmMain/kotlin/randomSpheres.kt b/demo/playground/src/jvmMain/kotlin/randomSpheres.kt index fd1b9865..47201ff8 100644 --- a/demo/playground/src/jvmMain/kotlin/randomSpheres.kt +++ b/demo/playground/src/jvmMain/kotlin/randomSpheres.kt @@ -19,7 +19,7 @@ fun main() = makeVisionFile( vision { solid { ambientLight { - color(Colors.white) + color.set(Colors.white) } repeat(100) { sphere(5, name = "sphere[$it]") { @@ -27,7 +27,7 @@ fun main() = makeVisionFile( y = random.nextDouble(-300.0, 300.0) z = random.nextDouble(-300.0, 300.0) material { - color(random.nextInt()) + color.set(random.nextInt()) } detail = 16 } diff --git a/demo/playground/src/jvmMain/kotlin/simpleCube.kt b/demo/playground/src/jvmMain/kotlin/simpleCube.kt index e1fc91eb..5dae515c 100644 --- a/demo/playground/src/jvmMain/kotlin/simpleCube.kt +++ b/demo/playground/src/jvmMain/kotlin/simpleCube.kt @@ -2,8 +2,8 @@ package space.kscience.visionforge.examples import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.box -import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.material +import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.solid fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { @@ -11,7 +11,7 @@ fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { solid { box(100, 100, 100) material { - emissiveColor("red") + emissiveColor.set("red") } } } diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt index 93650fb2..631d70f8 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt @@ -15,7 +15,7 @@ internal fun visionOfSatellite( ySegmentSize: Number = xSegmentSize, fiberDiameter: Number = 1.0, ): SolidGroup = SolidGroup { - color("darkgreen") + color.set("darkgreen") val transparent by style { this[SolidMaterial.MATERIAL_OPACITY_KEY] = 0.3 } diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index fbacc5b1..d601a74b 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -44,7 +44,7 @@ fun main() { val randomJ = Random.nextInt(1, 4) val target = Name.parse("layer[$randomLayer].segment[$randomI,$randomJ]") val targetVision = sat[target] as Solid - targetVision.color("red") + targetVision.color.set("red") delay(1000) targetVision.color.clear() delay(500) diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index 5631de56..228f63f7 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -20,7 +20,7 @@ fun VisionLayout.demo(name: String, title: String = name, block: SolidGro } val vision = SolidGroup(block).apply { ambientLight{ - color(Colors.white) + color.set(Colors.white) } } render(Name.parse(name), vision, meta) @@ -46,23 +46,23 @@ fun VisionLayout.showcase() { ambientLight() box(100.0, 100.0, 100.0) { z = -110.0 - color("teal") + color.set("teal") } sphere(50.0) { x = 110 detail = 16 - color("red") + color.set("red") } tube(50, height = 10, innerRadius = 25, angle = PI) { y = 110 detail = 16 rotationX = PI / 4 - color("blue") + color.set("blue") } sphereLayer(50, 40, theta = PI / 2) { rotationX = -PI * 3 / 4 z = 110 - color(Colors.pink) + color.set(Colors.pink) } } @@ -77,7 +77,7 @@ fun VisionLayout.showcase() { visible = false x = 110.0 //override color for this cube - color(1530) + color.set(1530) GlobalScope.launch(Dispatchers.Main) { while (isActive) { @@ -92,7 +92,7 @@ fun VisionLayout.showcase() { val random = Random(111) while (isActive) { delay(1000) - group.color(random.nextInt(0, Int.MAX_VALUE)) + group.color.set(random.nextInt(0, Int.MAX_VALUE)) } } } @@ -104,7 +104,7 @@ fun VisionLayout.showcase() { rotationY = PI / 4 box(100, 100, 100) { rotationZ = PI / 4 - color(Colors.red) + color.set(Colors.red) } } } @@ -117,7 +117,7 @@ fun VisionLayout.showcase() { for (i in 0..100) { layer(i * 5, 20 * sin(2 * PI / 100 * i), 20 * cos(2 * PI / 100 * i)) } - color(Colors.teal) + color.set(Colors.teal) rotationX = -PI / 2 } } @@ -126,13 +126,13 @@ fun VisionLayout.showcase() { sphere(100) { detail = 32 opacity = 0.4 - color(Colors.blue) + color.set(Colors.blue) } repeat(20) { polyline(Point3D(100, 100, 100), Point3D(-100, -100, -100)) { thickness = 3.0 rotationX = it * PI2 / 20 - color(Colors.green) + color.set(Colors.green) //rotationY = it * PI2 / 20 } } @@ -159,7 +159,7 @@ fun VisionLayout.showcaseCSG() { detail = 32 } material { - color(Colors.pink) + color.set(Colors.pink) } } composite(CompositeType.UNION) { @@ -169,7 +169,7 @@ fun VisionLayout.showcaseCSG() { sphere(50) { detail = 32 } - color("lightgreen") + color.set("lightgreen") opacity = 0.7 } composite(CompositeType.SUBTRACT) { @@ -180,7 +180,7 @@ fun VisionLayout.showcaseCSG() { sphere(50) { detail = 32 } - color("teal") + color.set("teal") opacity = 0.7 } } @@ -191,7 +191,7 @@ fun VisionLayout.showcaseCSG() { detail = 32 } box(100, 100, 100) - color("red") + color.set("red") opacity = 0.5 } } diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index af828f46..84a164c8 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -11,7 +11,6 @@ import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.values.asValue import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.set -import space.kscience.visionforge.setProperty import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.three.* @@ -72,7 +71,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision var value: Int get() = meta[VALUE].int ?: 0 set(value) { - setProperty(VALUE, value.asValue()) + setPropertyValue(VALUE, value.asValue()) } companion object { diff --git a/docs/hierarchy.md b/docs/hierarchy.md index 720af5d2..15f3306e 100644 --- a/docs/hierarchy.md +++ b/docs/hierarchy.md @@ -3,7 +3,7 @@ ![](../docs/images/hierarchy.png) ### Vision -* function `getPropertyValue(name: Name, inherit: Boolean = false, includeStyles: Boolean = true, includeDefaults: Boolean = true)` - get property value with given layer flags. +* function `getProperty(name: Name, inherit: Boolean = false, includeStyles: Boolean = true, includeDefaults: Boolean = true)` - get property value with given layer flags. * function `setProperty(name: Name, item: Any?)` - a convenient method to set property node or value. If `item` is null, then node is removed, not a value Sets the `item` property to the element with the `name` identification. diff --git a/docs/inheritance.md b/docs/inheritance.md index d99451f3..1fad27d2 100644 --- a/docs/inheritance.md +++ b/docs/inheritance.md @@ -7,7 +7,7 @@ Properties, which can be inherited by objects, are `styles`, `prototypes` (if th All values of `styles` property are contained in class `StyleSheet`, where they all are defined at `Group`s level. The `prototypes` property tree is defined in `SolidGroup` class via `PrototypeHolder` interface, and `SolidReference` class helps to reuse a template object. -The order of inheritance of properties is set in function `getPropertyValue` in `VisionBase` class. +The order of inheritance of properties is set in function `getProperty` in `VisionBase` class. The order is this: * own styles * prototypes diff --git a/docs/uml/Vision.puml b/docs/uml/Vision.puml index 04e873b9..f590a13e 100644 --- a/docs/uml/Vision.puml +++ b/docs/uml/Vision.puml @@ -3,7 +3,7 @@ interface Vision{ val parent: VisionGroup? - fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value? + fun getProperty(name,inherit,includeStyles,includeDefaults): Value? } interface Solid{ @@ -81,7 +81,7 @@ Solid <--- Composite interface SolidReference{ val prototype: Solid - fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value? + fun getProperty(name,inherit,includeStyles,includeDefaults): Value? } VisionGroup <---- SolidReference SolidReferenceGroup -- SolidReference @@ -91,7 +91,7 @@ class SolidReferenceGroup{ var properties: MutableMeta? val prototype: Solid val children: Map - fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value? + fun getProperty(name,inherit,includeStyles,includeDefaults): Value? } VisionBase <-- SolidReferenceGroup VisionGroup <-- SolidReferenceGroup diff --git a/gradle.properties b/gradle.properties index 95d6d923..92f33679 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,4 @@ kotlin.jupyter.add.scanner=false org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.11.7-kotlin-1.7.0 \ No newline at end of file +toolsVersion=0.11.8-kotlin-1.7.10 \ No newline at end of file diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt index e7602b0e..9ab0403c 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt @@ -10,8 +10,8 @@ import react.fc import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.isEmpty import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.react.visionTree +import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions import styled.css import styled.styledDiv @@ -51,7 +51,7 @@ public val ThreeControls: FC = fc { props -> val selectedObject: Vision? = when { selected == null -> null selected.isEmpty() -> props.vision - else -> (props.vision as? VisionGroup)?.get(selected) + else -> (props.vision as? SolidGroup)?.get(selected) } if (selectedObject != null) { visionPropertyEditor(selectedObject, key = selected) diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index a65c1f42..4393565a 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -2,13 +2,14 @@ package space.kscience.visionforge.bootstrap import org.w3c.dom.Element import react.RBuilder -import react.dom.render +import react.dom.client.createRoot import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.visionforge.Vision import space.kscience.visionforge.computeProperties import space.kscience.visionforge.getStyle import space.kscience.visionforge.react.metaViewer import space.kscience.visionforge.react.propertyEditor +import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.styles @@ -50,6 +51,6 @@ public fun RBuilder.visionPropertyEditor( public fun Element.visionPropertyEditor( item: Vision, descriptor: MetaDescriptor? = item.descriptor, -): Unit = render(this) { +): Unit = createRoot(this).render { visionPropertyEditor(item, descriptor = descriptor) } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt index 54fc8ec4..84f9347f 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt @@ -59,9 +59,9 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { val obj = props.obj //display as node if any child is visible - if (obj is VisionGroup) { + if (obj is VisionGroup<*>) { flexRow { - if (obj.children.any { !it.key.body.startsWith("@") }) { + if (obj.items.any { !it.key.body.startsWith("@") }) { styledSpan { css { +TreeStyles.treeCaret @@ -81,9 +81,9 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { css { +TreeStyles.tree } - obj.children.entries + obj.items.entries .filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children - .sortedBy { (it.value as? VisionGroup)?.isEmpty() ?: true } // ignore empty groups + .sortedBy { (it.value as? VisionGroup<*>)?.isEmpty() ?: true } // ignore empty groups .forEach { (childToken, child) -> styledDiv { css { @@ -92,7 +92,7 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { child(ObjectTree) { attrs { this.name = props.name + childToken - this.obj = child + this.obj = child.vision this.selected = props.selected this.clickCallback = props.clickCallback } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index fa3fab99..085ff608 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -108,7 +108,7 @@ public val ThreeCanvasWithControls: FC = fc("Three selected?.let { when { it.isEmpty() -> solid - else -> (solid as? VisionGroup)?.get(it) + else -> (solid as? SolidGroup)?.get(it) } } } @@ -165,7 +165,7 @@ public val ThreeCanvasWithControls: FC = fc("Three } IslandContent { propertyEditor( - ownProperties = vision.meta, + ownProperties = vision.properties(), allProperties = vision.computeProperties(), descriptor = vision.descriptor, key = selected diff --git a/visionforge-core/api/visionforge-core.api b/visionforge-core/api/visionforge-core.api index 0937e26d..f9099a99 100644 --- a/visionforge-core/api/visionforge-core.api +++ b/visionforge-core/api/visionforge-core.api @@ -183,7 +183,7 @@ public class space/kscience/visionforge/SimpleVisionPropertyContainer : space/ks public fun (Lspace/kscience/dataforge/meta/ObservableMutableMeta;)V public synthetic fun getMeta ()Lspace/kscience/dataforge/meta/MutableMeta; public fun getMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta; - public fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; } public final class space/kscience/visionforge/StyleReference { @@ -241,8 +241,8 @@ public abstract interface class space/kscience/visionforge/Vision : space/kscien public fun getManager ()Lspace/kscience/visionforge/VisionManager; public abstract fun getMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta; public abstract fun getParent ()Lspace/kscience/visionforge/VisionGroup; - public abstract fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; - public static synthetic fun getPropertyValue$default (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/names/Name;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; + public abstract fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public static synthetic fun getProperty$default (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/names/Name;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; public abstract fun invalidateProperty (Lspace/kscience/dataforge/names/Name;)V public abstract fun setParent (Lspace/kscience/visionforge/VisionGroup;)V public abstract fun update (Lspace/kscience/visionforge/VisionChange;)V @@ -266,7 +266,7 @@ public class space/kscience/visionforge/VisionBase : space/kscience/visionforge/ protected final fun getOrCreateProperties ()Lspace/kscience/dataforge/meta/MutableMeta; public fun getParent ()Lspace/kscience/visionforge/VisionGroup; protected final fun getProperties ()Lspace/kscience/dataforge/meta/MutableMeta; - public fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; public fun invalidateProperty (Lspace/kscience/dataforge/names/Name;)V public fun setParent (Lspace/kscience/visionforge/VisionGroup;)V protected final fun setProperties (Lspace/kscience/dataforge/meta/MutableMeta;)V @@ -446,8 +446,8 @@ public final class space/kscience/visionforge/VisionGroupKt { public final class space/kscience/visionforge/VisionKt { public static final fun getPropertyChanges (Lspace/kscience/visionforge/Vision;)Lkotlinx/coroutines/flow/Flow; - public static final fun getPropertyValue (Lspace/kscience/visionforge/Vision;Ljava/lang/String;ZZZ)Lspace/kscience/dataforge/values/Value; - public static synthetic fun getPropertyValue$default (Lspace/kscience/visionforge/Vision;Ljava/lang/String;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; + public static final fun getProperty (Lspace/kscience/visionforge/Vision;Ljava/lang/String;ZZZ)Lspace/kscience/dataforge/values/Value; + public static synthetic fun getProperty$default (Lspace/kscience/visionforge/Vision;Ljava/lang/String;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; public static final fun getVisible (Lspace/kscience/visionforge/Vision;)Ljava/lang/Boolean; public static final fun onPropertyChange (Lspace/kscience/visionforge/Vision;Lkotlin/jvm/functions/Function2;)V public static final fun setProperty (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/names/Name;Ljava/lang/Object;)V @@ -499,8 +499,8 @@ public abstract class space/kscience/visionforge/VisionPlugin : space/kscience/d public abstract interface class space/kscience/visionforge/VisionPropertyContainer { public abstract fun getMeta ()Lspace/kscience/dataforge/meta/MutableMeta; - public abstract fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; - public static synthetic fun getPropertyValue$default (Lspace/kscience/visionforge/VisionPropertyContainer;Lspace/kscience/dataforge/names/Name;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; + public abstract fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public static synthetic fun getProperty$default (Lspace/kscience/visionforge/VisionPropertyContainer;Lspace/kscience/dataforge/names/Name;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; } public final class space/kscience/visionforge/html/HeadersKt { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt new file mode 100644 index 00000000..c6cba1ba --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt @@ -0,0 +1,107 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.launch +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.asMutableMeta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.isEmpty +import space.kscience.dataforge.values.Value +import space.kscience.visionforge.VisionGroup.Companion.updateProperties +import kotlin.jvm.Synchronized + +@Serializable +public abstract class AbstractVision : Vision { + + @Transient + override var parent: Vision? = null + + protected var properties: MutableMeta? = null + + override val meta: Meta get() = properties ?: Meta.EMPTY + + @Synchronized + private fun getOrCreateProperties(): MutableMeta { + if (properties == null) { + //TODO check performance issues + val newProperties = MutableMeta() + properties = newProperties + } + return properties!! + } + + @Transient + private val _propertyChanges = MutableSharedFlow() + override val propertyChanges: SharedFlow get() = _propertyChanges + + override fun getPropertyValue( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + includeDefaults: Boolean, + ): Value? { + properties?.get(name)?.value?.let { return it } + if (includeStyles) { + getStyleProperty(name)?.value?.let { return it } + } + if (inherit) { + parent?.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } + } + if (includeDefaults) { + descriptor?.defaultNode?.get(name)?.value?.let { return it } + } + return null + } + + override fun setProperty(name: Name, node: Meta?) { + //TODO check old value? + if (name.isEmpty()) { + properties = node?.asMutableMeta() + } else if (node == null) { + properties?.setMeta(name, node) + } else { + getOrCreateProperties().setMeta(name, node) + } + invalidateProperty(name) + } + + override fun setPropertyValue(name: Name, value: Value?) { + //TODO check old value? + if (value == null) { + properties?.getMeta(name)?.value = null + } else { + getOrCreateProperties().setValue(name, value) + } + invalidateProperty(name) + } + + override val descriptor: MetaDescriptor? get() = null + + override fun invalidateProperty(propertyName: Name) { + if (propertyName == Vision.STYLE_KEY) { + styles.asSequence() + .mapNotNull { getStyle(it) } + .flatMap { it.items.asSequence() } + .distinctBy { it.key } + .forEach { + invalidateProperty(it.key.asName()) + } + } + manager.context.launch { + _propertyChanges.emit(propertyName) + } + } + + override fun update(change: VisionChange) { + change.properties?.let { + updateProperties(it, Name.EMPTY) + } + } +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ComputedVisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ComputedVisionProperties.kt deleted file mode 100644 index 925eecfe..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ComputedVisionProperties.kt +++ /dev/null @@ -1,84 +0,0 @@ -package space.kscience.visionforge - -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.NameToken -import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.MutableValueProvider -import space.kscience.dataforge.values.Value - -private class ComputedVisionProperties( - val vision: Vision, - val pathName: Name, - val visionDescriptor: MetaDescriptor, - val parentInheritFlag: Boolean?, - val parentStylesFlag: Boolean? -) : Meta { - - val descriptor: MetaDescriptor? by lazy { visionDescriptor[pathName] } - - override val items: Map - get() { - val metaKeys = vision.meta.getMeta(pathName)?.items?.keys ?: emptySet() - val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet() - val inheritFlag = descriptor?.inherited ?: parentInheritFlag - val stylesFlag = descriptor?.usesStyles ?: parentStylesFlag - return (metaKeys + descriptorKeys).associateWith { - ComputedVisionProperties( - vision, - pathName + it, - visionDescriptor, - inheritFlag, - stylesFlag - ) - } - } - - override val value: Value? - get() { - val inheritFlag = descriptor?.inherited ?: parentInheritFlag ?: false - val stylesFlag = descriptor?.usesStyles ?: parentStylesFlag ?: true - return vision.getPropertyValue(pathName, inheritFlag, stylesFlag, true) - } - - override fun toString(): String = Meta.toString(this) - override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) - override fun hashCode(): Int = Meta.hashCode(this) -} - -/** - * Compute property node based on inheritance and style information from the descriptor - */ -public fun Vision.computeProperties(descriptor: MetaDescriptor? = this.descriptor): Meta = - if (descriptor == null) meta else ComputedVisionProperties(this, Name.EMPTY, descriptor, null, null) - -public fun Vision.computePropertyNode( - name: Name, - descriptor: MetaDescriptor? = this.descriptor -): Meta? = computeProperties(descriptor)[name] - -/** - * Compute the property based on the provided value descriptor. By default, use Vision own descriptor - */ -public fun Vision.computeProperty(name: Name, valueDescriptor: MetaDescriptor? = descriptor?.get(name)): Value? { - val inheritFlag = valueDescriptor?.inherited ?: false - val stylesFlag = valueDescriptor?.usesStyles ?: true - return getPropertyValue(name, inheritFlag, stylesFlag) -} - -/** - * Accessor to all vision properties - */ -public fun Vision.computePropertyValues( - descriptor: MetaDescriptor? = this.descriptor -): MutableValueProvider = object : MutableValueProvider { - override fun getValue(name: Name): Value? = computeProperty(name, descriptor?.get(name)) - - override fun setValue(name: Name, value: Value?) { - setProperty(name, value) - } -} - diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt index d5dfac6e..0e2b6132 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt @@ -9,7 +9,7 @@ import kotlin.properties.ReadOnlyProperty /** * A reference to a style defined in a specific container */ -public class StyleReference(public val owner: VisionGroup, public val name: String) +public class StyleReference(public val owner: Vision, public val name: String) private tailrec fun styleIsDefined(vision: Vision, reference: StyleReference): Boolean = when { reference.owner === vision -> true @@ -25,7 +25,7 @@ public fun Vision.useStyle(reference: StyleReference) { } @VisionBuilder -public fun VisionGroup.style( +public fun Vision.style( styleKey: String? = null, builder: MutableMeta.() -> Unit, ): ReadOnlyProperty = ReadOnlyProperty { _, property -> @@ -35,7 +35,7 @@ public fun VisionGroup.style( } @VisionBuilder -public fun VisionGroup.style( +public fun Vision.style( spec: Specification, styleKey: String? = null, builder: T.() -> Unit, diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 52deee3c..cc465d87 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -5,7 +5,6 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.asValue import space.kscience.dataforge.values.stringList import kotlin.jvm.JvmInline @@ -14,11 +13,11 @@ import kotlin.jvm.JvmInline * A container for styles */ @JvmInline -public value class StyleSheet(private val owner: VisionGroup) { +public value class StyleSheet(private val owner: Vision) { - private val styleNode: Meta? get() = owner.meta[STYLESHEET_KEY] + private val styleNode: Meta get() = owner.getProperty(STYLESHEET_KEY) - public val items: Map? get() = styleNode?.items + public val items: Map get() = styleNode.items public operator fun get(key: String): Meta? = owner.getStyle(key) @@ -26,7 +25,7 @@ public value class StyleSheet(private val owner: VisionGroup) { * Define a style without notifying owner */ public fun define(key: String, style: Meta?) { - owner.meta.setMeta(STYLESHEET_KEY + key, style) + owner.setProperty(STYLESHEET_KEY + key, style) } /** @@ -43,7 +42,7 @@ public value class StyleSheet(private val owner: VisionGroup) { /** * Create and set a style */ - public operator fun set(key: String, builder: MutableMeta.() -> Unit) { + public fun update(key: String, builder: MutableMeta.() -> Unit) { val newStyle = get(key)?.toMutableMeta()?.apply(builder) ?: Meta(builder) set(key, newStyle.seal()) } @@ -61,10 +60,8 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) .map { it.asName() } tokens.forEach { parent?.invalidateProperty(it) } } - if (this is VisionGroup) { - for (obj in this) { - obj.styleChanged(key, oldStyle, newStyle) - } + children.values.forEach { vision -> + vision.styleChanged(key, oldStyle, newStyle) } } @@ -73,35 +70,40 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) * List of names of styles applied to this object. Order matters. Not inherited. */ public var Vision.styles: List - get() = meta.getValue(Vision.STYLE_KEY)?.stringList ?: emptyList() + get() = getPropertyValue( + Vision.STYLE_KEY, + inherit = true, + includeStyles = false, + includeDefaults = false + )?.stringList ?: emptyList() set(value) { - meta.setValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue()) + setPropertyValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue()) } /** * A stylesheet for this group and its descendants. Stylesheet is not applied directly, * but instead is just a repository for named configurations. */ -public val VisionGroup.styleSheet: StyleSheet get() = StyleSheet(this) +public val Vision.styleSheet: StyleSheet get() = StyleSheet(this) /** * Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment. */ public fun Vision.useStyle(name: String) { - styles = (meta.getMeta(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name + styles = (getPropertyValue(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name } /** - * Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision]. + * Resolve a style with given name for given [Vision]. The style is not necessarily applied to this [Vision]. */ -public tailrec fun Vision.getStyle(name: String): Meta? = +public fun Vision.getStyle(name: String): Meta? = meta.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) /** * Resolve a property from all styles */ -public fun Vision.getStyleProperty(name: Name): Value? = styles.firstNotNullOfOrNull { getStyle(it)?.get(name)?.value } +public fun Vision.getStyleProperty(name: Name): Meta? = styles.firstNotNullOfOrNull { getStyle(it)?.get(name) } /** * Resolve an item in all style layers diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 1c8e3a28..b25f200c 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -1,17 +1,20 @@ package space.kscience.visionforge -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.launch -import space.kscience.dataforge.meta.* +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import space.kscience.dataforge.context.Global +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.MutableMetaProvider import space.kscience.dataforge.meta.descriptors.Described import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.asValue @@ -23,38 +26,59 @@ import kotlin.reflect.KProperty1 * A root type for display hierarchy */ @Type(TYPE) -public interface Vision : Described, Configurable { +public interface Vision : Described { /** * The parent object of this one. If null, this one is a root. */ - public var parent: VisionGroup? + public var parent: Vision? /** * Owner [VisionManager]. Used to define coroutine scope a serialization */ - public val manager: VisionManager? get() = parent?.manager + public val manager: VisionManager get() = parent?.manager ?: Global.visionManager - /** - * This Vision own properties (ignoring inheritance, styles and defaults) - */ - override val meta: ObservableMutableMeta + public val children: VisionChildren /** - * Get property value with given layer flags. - * @param inherit toggles parent node property lookup. Null means inference from descriptor. Default is false. - * @param includeStyles toggles inclusion of properties from styles. default is true + * Own properties without inheritance or styles. */ + public val meta: Meta + public fun getPropertyValue( name: Name, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, + inherit: Boolean, + includeStyles: Boolean, + includeDefaults: Boolean, ): Value? + /** + * Get property with given layer flags. + * @param inherit toggles parent node property lookup. Null means inference from descriptor. + * @param includeStyles toggles inclusion of properties from styles. + */ + public fun getProperty( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + includeDefaults: Boolean, + ): MutableMeta = VisionProperties(this, name, descriptor?.get(name), inherit, includeStyles) + + public fun setProperty( + name: Name, + node: Meta?, + ) + + public fun setPropertyValue( + name: Name, + value: Value?, + ) + + public val propertyChanges: SharedFlow /** - * Notify all listeners that a property has been changed and should be invalidated + * Notify all listeners that a property has been changed and should be invalidated. + * This method does not check that the property has actually changed. */ public fun invalidateProperty(propertyName: Name) @@ -68,80 +92,135 @@ public interface Vision : Described, Configurable { public companion object { public const val TYPE: String = "vision" public val STYLE_KEY: Name = "@style".asName() + public const val STYLE_TARGET: String = "style" public val VISIBLE_KEY: Name = "visible".asName() } } -/** - * Flow of property invalidation events. It does not contain property values after invalidation since it is not clear - * if it should include inherited properties etc. - */ -@OptIn(ExperimentalCoroutinesApi::class) -@DFExperimental -public val Vision.propertyChanges: Flow - get() = callbackFlow { - meta.onChange(this) { name -> - launch { - send(name) - } - } - awaitClose { - meta.removeListener(this) - } - } +public fun Vision.getPropertyValue( + name: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, + includeDefaults: Boolean = true, + metaDescriptor: MetaDescriptor? = descriptor?.get(name), +): Value? { + val inheritFlag = inherit ?: metaDescriptor?.inherited ?: false + val stylesFlag = includeStyles ?: metaDescriptor?.usesStyles ?: true + return getPropertyValue(name, inheritFlag, stylesFlag, includeDefaults) +} + +public fun Vision.getPropertyValue( + name: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, + includeDefaults: Boolean = true, + metaDescriptor: MetaDescriptor? = descriptor?.get(name), +): Value? = getPropertyValue(name.parseAsName(), inherit, includeStyles, includeDefaults, metaDescriptor) /** - * Subscribe on property updates. The subscription is bound to the given scope and canceled when the scope is canceled + * Compute the property based on the provided value descriptor. By default, use Vision own descriptor */ -public fun Vision.onPropertyChange(callback: Meta.(Name) -> Unit) { - meta.onChange(null, callback) +public fun Vision.getProperty( + name: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, + includeDefaults: Boolean = true, + metaDescriptor: MetaDescriptor? = descriptor?.get(name), +): MutableMeta { + val inheritFlag = inherit ?: metaDescriptor?.inherited ?: false + val stylesFlag = includeStyles ?: metaDescriptor?.usesStyles ?: true + return getProperty(name, inheritFlag, stylesFlag, includeDefaults) } + /** * Get [Vision] property using key as a String */ -public fun Vision.getPropertyValue( - key: String, - inherit: Boolean = false, - includeStyles: Boolean = true, +public fun Vision.getProperty( + name: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, includeDefaults: Boolean = true, -): Value? = getPropertyValue(Name.parse(key), inherit, includeStyles, includeDefaults) + metaDescriptor: MetaDescriptor? = descriptor?.get(name), +): MutableMeta = getProperty(name.parseAsName(), inherit, includeStyles, includeDefaults, metaDescriptor) + /** - * A convenience method to set property node or value. If Item is null, then node is removed, not a value + * Vision's own non-inheritable, non-styleable properties */ -public fun Vision.setProperty(name: Name, item: Any?) { - when (item) { - null -> meta.remove(name) - is Meta -> meta.setMeta(name, item) - is Value -> meta.setValue(name, item) - else -> meta.setValue(name, Value.of(item)) +public fun Vision.properties( + inherit: Boolean? = null, + useStyles: Boolean? = null, +): MutableMetaProvider = VisionProperties(this, Name.EMPTY, inherit = inherit, useStyles = useStyles) + +public fun Vision.setPropertyValue(name: Name, value: Number?) { + if (value == null) { + setPropertyValue(name, null) + } else { + setPropertyValue(name, value.asValue()) + } +} + +public fun Vision.setPropertyValue(name: String, value: Number?): Unit = + setPropertyValue(name.parseAsName(), value) + +public fun Vision.setPropertyValue(name: Name, value: Boolean?) { + if (value == null) { + setPropertyValue(name, null) + } else { + setPropertyValue(name, value.asValue()) } } -public fun Vision.setPropertyNode(key: String, item: Any?) { - setProperty(Name.parse(key), item) +public fun Vision.setPropertyValue(name: String, value: Boolean?): Unit = + setPropertyValue(name.parseAsName(), value) + +public fun Vision.setPropertyValue(name: Name, value: String?) { + if (value == null) { + setPropertyValue(name, null) + } else { + setPropertyValue(name, value.asValue()) + } } +public fun Vision.setPropertyValue(name: String, value: String?): Unit = + setPropertyValue(name.parseAsName(), value) + /** * Control visibility of the element */ public var Vision.visible: Boolean? get() = getPropertyValue(Vision.VISIBLE_KEY)?.boolean - set(value) = meta.setValue(Vision.VISIBLE_KEY, value?.asValue()) + set(value) { + setPropertyValue(Vision.VISIBLE_KEY, value) + } + +/** + * Subscribe on property updates. The subscription is bound to the given scope and canceled when the scope is canceled + */ +public fun Vision.onPropertyChange(callback: (Name) -> Unit): Job = propertyChanges.onEach { + callback(it) +}.launchIn(manager.context) public fun V.useProperty( property: KProperty1, - owner: Any? = null, callBack: V.(T) -> Unit, -) { +): Job { //Pass initial value. callBack(property.get(this)) - meta.onChange(owner) { name -> + return propertyChanges.onEach { name -> if (name.startsWith(property.name.asName())) { callBack(property.get(this@useProperty)) } - } -} \ No newline at end of file + }.launchIn(manager.context) +} + + +public interface MutableVisionGroup : Vision { + + override val children: MutableVisionChildren + + public fun createGroup(): MutableVisionGroup +} diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt deleted file mode 100644 index 003fec79..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt +++ /dev/null @@ -1,176 +0,0 @@ -package space.kscience.visionforge - -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.ObservableMutableMeta -import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.value -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.ValueType -import space.kscience.visionforge.Vision.Companion.STYLE_KEY -import kotlin.jvm.Synchronized - -internal data class MetaListener( - val owner: Any? = null, - val callback: Meta.(name: Name) -> Unit, -) - -/** - * A full base implementation for a [Vision] - * @param parent the parent object for this vision. Could've set later. Not serialized. - */ -@Serializable -@SerialName("vision") -public open class VisionBase( - @Transient override var parent: VisionGroup? = null, - @EncodeDefault protected var properties: MutableMeta? = null, -) : Vision { - - @Synchronized - protected fun getOrCreateProperties(): MutableMeta { - if (properties == null) { - val newProperties = MutableMeta() - properties = newProperties - } - return properties!! - } - - @Transient - private val listeners: MutableList = mutableListOf() - - private inner class VisionProperties(val pathName: Name) : ObservableMutableMeta { - - override val items: Map - get() = properties?.get(pathName)?.items?.mapValues { entry -> - VisionProperties(pathName + entry.key) - } ?: emptyMap() - - override var value: Value? - get() = properties?.get(pathName)?.value - set(value) { - val oldValue = properties?.get(pathName)?.value - getOrCreateProperties().setValue(pathName, value) - if (oldValue != value) { - invalidate(Name.EMPTY) - } - } - - override fun getOrCreate(name: Name): ObservableMutableMeta = VisionProperties(pathName + name) - - override fun setMeta(name: Name, node: Meta?) { - getOrCreateProperties().setMeta(pathName + name, node) - invalidate(name) - } - - @DFExperimental - override fun attach(name: Name, node: ObservableMutableMeta) { - val ownProperties = getOrCreateProperties() - if (ownProperties is ObservableMutableMeta) { - ownProperties.attach(pathName + name, node) - } else { - ownProperties.setMeta(pathName + name, node) - node.onChange(this) { childName -> - ownProperties.setMeta(pathName + name + childName, this[childName]) - } - } - } - - override fun invalidate(name: Name) { - invalidateProperty(pathName + name) - } - - @Synchronized - override fun onChange(owner: Any?, callback: Meta.(name: Name) -> Unit) { - if (pathName.isEmpty()) { - listeners.add((MetaListener(owner, callback))) - } else { - listeners.add(MetaListener(owner) { name -> - if (name.startsWith(pathName)) { - (this@MetaListener[pathName] ?: Meta.EMPTY).callback(name.removeHeadOrNull(pathName)!!) - } - }) - } - } - - @Synchronized - override fun removeListener(owner: Any?) { - listeners.removeAll { it.owner === owner } - } - - override fun toString(): String = Meta.toString(this) - override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) - override fun hashCode(): Int = Meta.hashCode(this) - } - - final override val meta: ObservableMutableMeta get() = VisionProperties(Name.EMPTY) - - override fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): Value? { - properties?.get(name)?.value?.let { return it } - if (includeStyles) { - getStyleProperty(name)?.let { return it } - } - if (inherit) { - parent?.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } - } - if (includeDefaults) { - descriptor?.defaultNode?.get(name)?.value.let { return it } - } - return null - } - - override val descriptor: MetaDescriptor? get() = null - - override fun invalidateProperty(propertyName: Name) { - if (propertyName == STYLE_KEY) { - styles.mapNotNull { getStyle(it) }.asSequence() - .flatMap { it.items.asSequence() } - .distinctBy { it.key } - .forEach { - invalidateProperty(it.key.asName()) - } - } - listeners.forEach { it.callback(properties ?: Meta.EMPTY, propertyName) } - } - - override fun update(change: VisionChange) { - change.properties?.let { - updateProperties(Name.EMPTY, it) - } - } - - public companion object { - public val descriptor: MetaDescriptor = MetaDescriptor { - value(STYLE_KEY, ValueType.STRING) { - multiple = true - } - } - - public fun Vision.updateProperties(at: Name, item: Meta) { - meta.setValue(at, item.value) - item.items.forEach { (token, item) -> - updateProperties(at + token, item) - } - } - - } -} - -//fun VisualObject.findStyle(styleName: Name): Meta? { -// if (this is VisualGroup) { -// val style = resolveStyle(styleName) -// if (style != null) return style -// } -// return parent?.findStyle(styleName) -//} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index ad0d0d70..abea638a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -7,7 +7,6 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.Null @@ -19,14 +18,13 @@ import kotlin.time.Duration */ private fun Vision.deepCopy(): Vision { //Assuming that unrooted visions are already isolated - val manager = this.manager ?: return this //TODO replace by efficient deep copy val json = manager.encodeToJsonElement(this) return manager.decodeFromJson(json) } /** - * An update for a [Vision] or a [VisionGroup] + * An update for a [Vision] */ public class VisionChangeBuilder : VisionContainerBuilder { @@ -87,7 +85,6 @@ public inline fun VisionChange(block: VisionChangeBuilder.() -> Unit): VisionCha VisionChangeBuilder().apply(block).deepCopy() -@OptIn(DFExperimental::class) private fun CoroutineScope.collectChange( name: Name, source: Vision, @@ -96,28 +93,25 @@ private fun CoroutineScope.collectChange( //Collect properties change source.onPropertyChange { propertyName -> - val newItem = source.meta[propertyName] + val newItem = source.getProperty(propertyName, false, false, false) collector().propertyChanged(name, propertyName, newItem) } - if (source is VisionGroup) { - //Subscribe for children changes - source.children.forEach { (token, child) -> - collectChange(name + token, child, collector) - } + val children = source.children + //Subscribe for children changes + for ((token, child) in children) { + collectChange(name + token, child, collector) + } - //Subscribe for structure change - if (source is MutableVisionGroup) { - source.structureChanges.onEach { changedName -> - val after = source[changedName] - val fullName = name + changedName - if (after != null) { - collectChange(fullName, after, collector) - } - collector()[fullName] = after - }.launchIn(this) + //Subscribe for structure change + children.changes.onEach { changedName -> + val after = children[changedName] + val fullName = name + changedName + if (after != null) { + collectChange(fullName, after, collector) } - } + collector()[fullName] = after + }.launchIn(this) } /** diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt new file mode 100644 index 00000000..f7056d59 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -0,0 +1,196 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.serializer +import space.kscience.dataforge.names.* + +@DslMarker +public annotation class VisionBuilder + +public interface VisionContainer { + public operator fun get(name: Name): V? +} + +public interface VisionContainerBuilder { + //TODO add documentation + public operator fun set(name: Name?, child: V?) +} + +/** + * A serializable representation of [Vision] children container + */ +public interface VisionChildren : VisionContainer { + public val parent: Vision? + + public val keys: Set + + public val values: Iterable get() = keys.map { get(it)!! } + + public val changes: Flow + + public operator fun get(token: NameToken): Vision? + + override fun get(name: Name): Vision? = when (name.length) { + 0 -> parent + 1 -> get(name.first()) + else -> get(name.first())?.children?.get(name.cutFirst()) + } + + public companion object { + public fun empty(owner: Vision): VisionChildren = object : VisionChildren { + override val parent: Vision get() = owner + override val keys: Set get() = emptySet() + override val changes: Flow get() = emptyFlow() + override fun get(token: NameToken): Vision? = null + } + } +} + +public fun VisionChildren.isEmpty(): Boolean = keys.isEmpty() + +@Serializable(VisionChildrenContainerSerializer::class) +public interface MutableVisionChildren : VisionChildren, VisionContainerBuilder { + public override val parent: MutableVisionGroup? + + public operator fun set(token: NameToken, value: Vision?) + + override fun set(name: Name?, child: Vision?) { + when { + name == null -> { + if (child != null) { + static(child) + } + } + + name.isEmpty() -> error("Empty names are not allowed in VisionGroup::set") + name.length == 1 -> { + val token = name.tokens.first() + set(token, child) + } + + else -> { + val currentParent = get(name.first()) + if (currentParent != null && currentParent !is MutableVisionGroup) error("Can't assign a child to $currentParent") + val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: parent?.createGroup().also { + set(name.first(), it) + } ?: error("Container owner not set") + parent.children[name.cutFirst()] = child + } + } + } + + public fun clear() +} + +/** + * Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events. + */ +public fun MutableVisionChildren.static(child: Vision): Unit { + set(NameToken("@static", index = child.hashCode().toString()), child) +} + +public fun VisionChildren.asSequence(): Sequence> = sequence { + keys.forEach { yield(it to get(it)!!) } +} + +public operator fun VisionChildren.iterator(): Iterator> = asSequence().iterator() + +public operator fun VisionContainer.get(str: String): V? = get(Name.parse(str)) + +public operator fun VisionContainerBuilder.set( + str: String?, vision: V?, +): Unit = set(str?.parseAsName(), vision) + +internal class VisionChildrenImpl( + items: Map, +) : MutableVisionChildren { + + override var parent: MutableVisionGroup? = null + internal set + + private val items = LinkedHashMap(items) + private val updateJobs = HashMap() + + private val scope: CoroutineScope? get() = parent?.manager?.context + + override val keys: Set get() = items.keys + + override fun get(token: NameToken): Vision? = items[token] + + private val _changes = MutableSharedFlow() + override val changes: SharedFlow get() = _changes + + private fun onChange(name: Name) { + scope?.launch { + _changes.emit(name) + } + } + + override operator fun set(token: NameToken, value: Vision?) { + //fast return if value equals existing + if (value == get(token)) return + + val currentUpdateJob = updateJobs[token] + if (currentUpdateJob != null) { + currentUpdateJob.cancel() + updateJobs.remove(token) + } + + if (value == null) { + items.remove(token) + } else { + items[token] = value + //check if parent already exists and is different from the current one + if (value.parent != null && value.parent != parent) error("Can't reassign parent Vision for $value") + //set parent + value.parent = parent + //start update jobs (only if the vision is rooted) + scope?.let { scope -> + val job = (value.children as? VisionChildrenImpl)?.changes?.onEach { + onChange(token + it) + }?.launchIn(scope) + if (job != null) { + updateJobs[token] = job + } + } + } + + onChange(token.asName()) + } + + override fun clear() { + if (items.isNotEmpty()) { + updateJobs.values.forEach { + it.cancel() + } + updateJobs.clear() + items.clear() + onChange(Name.EMPTY) + } + } +} + +internal object VisionChildrenContainerSerializer : KSerializer { + private val mapSerializer = serializer>() + + override val descriptor: SerialDescriptor = mapSerializer.descriptor + + override fun deserialize(decoder: Decoder): MutableVisionChildren { + val map = decoder.decodeSerializableValue(mapSerializer) + return VisionChildrenImpl(map) + } + + override fun serialize(encoder: Encoder, value: MutableVisionChildren) { + val map = value.keys.associateWith { value[it]!! } + encoder.encodeSerializableValue(mapSerializer, map) + } + +} diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index a8ad1dcd..3c843b85 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -1,109 +1,99 @@ package space.kscience.visionforge -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.launch -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.dataforge.names.* -import space.kscience.dataforge.provider.Provider - -@DslMarker -public annotation class VisionBuilder - -public interface VisionContainer { - public operator fun get(name: Name): V? -} +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.plus +import space.kscience.dataforge.values.ValueType +import space.kscience.visionforge.Vision.Companion.STYLE_KEY +import kotlin.jvm.Synchronized /** - * Represents a group of [Vision] instances + * A full base implementation for a [Vision] */ -public interface VisionGroup : Provider, Vision, VisionContainer { - /** - * A map of top level named children - */ - public val children: Map - - override val defaultTarget: String get() = Vision.TYPE - - /** - * A map of direct children for specific target - * (currently "visual" or "style") - */ - override fun content(target: String): Map = - when (target) { - Vision.TYPE -> children.flatMap { (key, value) -> - val res: Map = if (value is VisionGroup) { - value.content(target).mapKeys { key + it.key } - } else { - mapOf(key.asName() to value) - } - res.entries - }.associate { it.toPair() } - STYLE_TARGET -> styleSheet.items?.mapKeys { it.key.asName() } ?: emptyMap() - else -> emptyMap() +@Serializable +@SerialName("vision.group") +public open class VisionGroup : AbstractVision(), MutableVisionGroup { + + override fun update(change: VisionChange) { + change.children?.forEach { (name, change) -> + when { + change.delete -> children.set(name, null) + change.vision != null -> children.set(name, change.vision) + else -> children[name]?.update(change) + } } - - public override operator fun get(name: Name): Vision? { - return when { - name.isEmpty() -> this - name.length == 1 -> children[name.tokens.first()] - else -> (children[name.tokens.first()] as? VisionGroup)?.get(name.cutFirst()) + change.properties?.let { + updateProperties(it, Name.EMPTY) } } - public companion object { - public const val STYLE_TARGET: String = "style" - } -} + @SerialName("children") + protected var _children: MutableVisionChildren? = null -/** - * Iterate over children of this group - */ -public operator fun VisionGroup.iterator(): Iterator = children.values.iterator() + @Transient + override val children: MutableVisionChildren = object : MutableVisionChildren { -public fun VisionGroup.isEmpty(): Boolean = this.children.isEmpty() + @Synchronized + fun getOrCreateChildren(): MutableVisionChildren { + if (_children == null) { + _children = VisionChildrenImpl(emptyMap()).apply { + parent = this@VisionGroup + } + } + return _children!! + } -public interface VisionContainerBuilder { - //TODO add documentation - public operator fun set(name: Name?, child: V?) -} + override val parent: MutableVisionGroup get() = this@VisionGroup -/** - * Mutable version of [VisionGroup] - */ -public interface MutableVisionGroup : VisionGroup, VisionContainerBuilder { - public fun onStructureChanged(owner: Any?, block: VisionGroup.(Name) -> Unit) + override val keys: Set get() = _children?.keys ?: emptySet() + override val changes: Flow get() = _children?.changes ?: emptyFlow() - public fun removeStructureListener(owner: Any?) -} + override fun get(token: NameToken): Vision? = _children?.get(token) + override fun set(token: NameToken, value: Vision?) { + getOrCreateChildren()[token] = value + } -/** - * Flow structure changes of this group. Unconsumed changes are discarded - */ -@OptIn(ExperimentalCoroutinesApi::class) -@DFExperimental -public val MutableVisionGroup.structureChanges: Flow - get() = callbackFlow { - meta.onChange(this) { name -> - launch { - send(name) - } + override fun set(name: Name?, child: Vision?) { + getOrCreateChildren()[name] = child } - awaitClose { - removeStructureListener(this) + + override fun clear() { + _children?.clear() } } + override fun createGroup(): VisionGroup = VisionGroup() -public operator fun VisionContainer.get(str: String): V? = get(Name.parse(str)) + public companion object { + public val descriptor: MetaDescriptor = MetaDescriptor { + value(STYLE_KEY, ValueType.STRING) { + multiple = true + } + } -public operator fun VisionContainerBuilder.set(token: NameToken, child: V?): Unit = - set(token.asName(), child) + public fun Vision.updateProperties(item: Meta, at: Name = Name.EMPTY) { + setPropertyValue(at, item.value) + item.items.forEach { (token, item) -> + updateProperties(item, at + token) + } + } -public operator fun VisionContainerBuilder.set(key: String?, child: V?): Unit = - set(key?.let(Name::parse), child) + } +} -public fun MutableVisionGroup.removeAll(): Unit = children.keys.map { it.asName() }.forEach { this[it] = null } \ No newline at end of file +//fun VisualObject.findStyle(styleName: Name): Meta? { +// if (this is VisualGroup) { +// val style = resolveStyle(styleName) +// if (style != null) return style +// } +// return parent?.findStyle(styleName) +//} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt deleted file mode 100644 index 7c2af29e..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt +++ /dev/null @@ -1,168 +0,0 @@ -package space.kscience.visionforge - -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import space.kscience.dataforge.names.* -import kotlin.jvm.Synchronized - -private class StructureChangeListener(val owner: Any?, val callback: VisionGroup.(Name) -> Unit) - -/** - * Abstract implementation of mutable group of [Vision] - * - * @param childrenInternal Internal mutable container for group children - */ -@Serializable -@SerialName("vision.group") -public open class VisionGroupBase( - @EncodeDefault @SerialName("children") protected val childrenInternal: MutableMap = LinkedHashMap(), -) : VisionBase(), MutableVisionGroup { - - /** - * A map of top level named children - */ - override val children: Map get() = childrenInternal - - init { - childrenInternal.forEach { (token, child) -> - if (child.parent != null && child.parent != this) error("Can't reassign existing parent for child $token") - child.parent = this - } - } - - override fun invalidateProperty(propertyName: Name) { - super.invalidateProperty(propertyName) - for (obj in this) { - obj.invalidateProperty(propertyName) - } - } - - @Transient - private val structureListeners = HashSet() - - @Synchronized - override fun onStructureChanged(owner: Any?, block: VisionGroup.(Name) -> Unit) { - structureListeners.add(StructureChangeListener(owner, block)) - } - - @Synchronized - override fun removeStructureListener(owner: Any?) { - structureListeners.removeAll { it.owner == owner } - } - - /** - * Propagate children change event upwards - */ - protected fun childrenChanged(name: Name) { - structureListeners.forEach { - it.callback(this, name) - } - } - - /** - * Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events. - */ - protected open fun addStatic(child: Vision): Unit { - attachChild(NameToken("@static", index = child.hashCode().toString()), child) - } - - /** - * Create a vision group of the same type as this vision group. Do not attach it. - */ - protected open fun createGroup(): VisionGroupBase = VisionGroupBase() - - /** - * Set parent for given child and attach it - */ - private fun attachChild(token: NameToken, child: Vision?) { - val before = childrenInternal[token] - when { - child == null -> { - childrenInternal.remove(token) - } - child.parent == null -> { - child.parent = this - childrenInternal[token] = child - } - child.parent !== this -> { - error("Can't reassign existing parent for child $token") - } - } - if (before != child) { - childrenChanged(token.asName()) - if (child is MutableVisionGroup) { - child.onStructureChanged(this) { changedName -> - this@VisionGroupBase.childrenChanged(token + changedName) - } - } - } - } - - /** - * Recursively create a child group - */ - private fun createGroups(name: Name): VisionGroupBase = when { - name.isEmpty() -> error("Should be unreachable") - name.length == 1 -> { - val token = name.tokens.first() - when (val current = children[token]) { - null -> createGroup().also { child -> - attachChild(token, child) - } - is VisionGroupBase -> current - else -> error("Can't create group with name $name because it exists and not a group") - } - } - else -> createGroups(name.tokens.first().asName()).createGroups(name.cutFirst()) - } - - /** - * Add named or unnamed child to the group. If key is null the child is considered unnamed. Both key and value are not - * allowed to be null in the same time. If name is present and [child] is null, the appropriate element is removed. - */ - override fun set(name: Name?, child: Vision?): Unit { - when { - name == null -> { - if (child != null) { - addStatic(child) - } - } - name.isEmpty() -> error("Empty names are not allowed in VisionGroup::set") - name.length == 1 -> { - val token = name.tokens.first() - attachChild(token, child) - } - else -> { - //TODO add safety check - val parent = (get(name.cutLast()) as? MutableVisionGroup) ?: createGroups(name.cutLast()) - parent[name.tokens.last().asName()] = child - } - } - } - - override fun update(change: VisionChange) { - change.children?.forEach { (name, change) -> - when { - change.delete -> set(name, null) - change.vision != null -> set(name, change.vision) - else -> get(name)?.update(change) - } - } - super.update(change) - } -} - -/** - * Non-serializable root group used to propagate manager to its children - */ -internal class RootVisionGroup(override val manager: VisionManager) : VisionGroupBase() - -/** - * Designate this [VisionGroup] as a root and assign a [VisionManager] as its parent - */ -public fun Vision.setAsRoot(manager: VisionManager) { - if (parent != null) error("Vision $this already has a parent. It could not be set as root") - parent = RootVisionGroup(manager) -} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index cd017cad..a11ad358 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -25,13 +25,14 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) { /** * Combined [SerializersModule] for all registered visions */ - public val serializersModule: SerializersModule - get() = SerializersModule { + public val serializersModule: SerializersModule by lazy { + SerializersModule { include(defaultSerialModule) context.gather(VISION_SERIALIZER_MODULE_TARGET).values.forEach { include(it) } } + } public val jsonFormat: Json get() = Json(defaultJson) { @@ -67,9 +68,8 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) { private val defaultSerialModule: SerializersModule = SerializersModule { polymorphic(Vision::class) { - default { VisionBase.serializer() } - subclass(VisionBase.serializer()) - subclass(VisionGroupBase.serializer()) + default { VisionGroup.serializer() } + subclass(VisionGroup.serializer()) subclass(VisionOfNumberField.serializer()) subclass(VisionOfTextField.serializer()) subclass(VisionOfCheckbox.serializer()) @@ -107,5 +107,17 @@ public abstract class VisionPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(met */ public val Context.visionManager: VisionManager get() = fetch(VisionManager) -public fun Vision.encodeToString(): String = - manager?.encodeToString(this) ?: error("VisionManager not defined in Vision") \ No newline at end of file +public fun Vision.encodeToString(): String = manager.encodeToString(this) + +/** + * A root vision attached to [VisionManager] + */ +public class RootVision(override val manager: VisionManager) : VisionGroup() + +/** + * Designate this [Vision] as a root and assign a [VisionManager] as its parent + */ +public fun Vision.setAsRoot(manager: VisionManager) { + if (parent != null) error("Vision $this already has a parent. It could not be set as root") + parent = RootVision(manager) +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt new file mode 100644 index 00000000..140170d3 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -0,0 +1,81 @@ +package space.kscience.visionforge + +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.plus +import space.kscience.dataforge.values.Value + +/** + * A wrapper that emulates delegates reading and writing properties to Vision method + */ +internal class VisionProperties( + val vision: Vision, + val nodeName: Name, + val visionDescriptor: MetaDescriptor? = vision.descriptor, + val inherit: Boolean? = null, + val useStyles: Boolean? = null, +) : MutableMeta { + + val descriptor: MetaDescriptor? by lazy { visionDescriptor?.get(nodeName) } + + override val items: Map + get() { + val metaKeys = vision.meta.getMeta(nodeName)?.items?.keys ?: emptySet() + val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet() + val inheritFlag = descriptor?.inherited ?: inherit + val stylesFlag = descriptor?.usesStyles ?: useStyles + return (metaKeys + descriptorKeys).associateWith { + VisionProperties( + vision, + nodeName + it, + visionDescriptor, + inheritFlag, + stylesFlag + ) + } + } + + override var value: Value? + get() { + val inheritFlag = descriptor?.inherited ?: inherit ?: false + val stylesFlag = descriptor?.usesStyles ?: useStyles ?: true + return vision.getPropertyValue(nodeName, inheritFlag, stylesFlag, true) + } + set(value) { + vision.setPropertyValue(nodeName, value) + } + + override fun getOrCreate(name: Name): MutableMeta = VisionProperties( + vision, + nodeName + name, + visionDescriptor, + inherit, + useStyles + ) + + override fun setMeta(name: Name, node: Meta?) { + vision.setProperty(nodeName + name, node) + } + + override fun toString(): String = Meta.toString(this) + override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) + override fun hashCode(): Int = Meta.hashCode(this) +} + +///** +// * Accessor to all vision properties +// */ +//public fun Vision.computePropertyValues( +// descriptor: MetaDescriptor? = this.descriptor, +//): MutableValueProvider = object : MutableValueProvider { +// override fun getValue(name: Name): Value? = computeProperty(name, descriptor?.get(name))?.value +// +// override fun setValue(name: Name, value: Value?) { +// setProperty(name, value) +// } +//} + diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt index fed474fc..83b6c93c 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt @@ -1,34 +1,29 @@ package space.kscience.visionforge -import space.kscience.dataforge.meta.Configurable +import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.ObservableMutableMeta -import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.Value /** * Property containers are used to create a symmetric behaviors for vision properties and style builders */ public interface VisionPropertyContainer { - public val meta: MutableMeta - - public fun getPropertyValue( + public fun getProperty( name: Name, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, - ): Value? + inherit: Boolean, + includeStyles: Boolean, + includeDefaults: Boolean, + ): Meta? } public open class SimpleVisionPropertyContainer( - override val meta: ObservableMutableMeta, -) : VisionPropertyContainer, Configurable { - override fun getPropertyValue( + public val meta: MutableMeta, +) : VisionPropertyContainer { + override fun getProperty( name: Name, inherit: Boolean, includeStyles: Boolean, - includeDefaults: Boolean - ): Value? = meta[name]?.value + includeDefaults: Boolean, + ): Meta? = meta.getMeta(name) } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt index 0ef6f54e..82e59c2c 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt @@ -9,13 +9,14 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.node +import space.kscience.visionforge.properties @Serializable @SerialName("html.form") public class VisionOfHtmlForm( public val formId: String, ) : VisionOfHtmlInput() { - public var values: Meta? by meta.node() + public var values: Meta? by properties().node() } public class HtmlFormFragment internal constructor( diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt index 084c5b6b..34f49027 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt @@ -5,11 +5,12 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.number import space.kscience.dataforge.meta.string -import space.kscience.visionforge.VisionBase +import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.properties @Serializable -public abstract class VisionOfHtmlInput : VisionBase() { - public var disabled: Boolean by meta.boolean(false) +public abstract class VisionOfHtmlInput : VisionGroup() { + public var disabled: Boolean by properties().boolean(false) } @Serializable @@ -18,7 +19,7 @@ public class VisionOfTextField( public val label: String? = null, public val name: String? = null, ) : VisionOfHtmlInput() { - public var text: String? by meta.string() + public var text: String? by properties().string() } @Serializable @@ -27,7 +28,7 @@ public class VisionOfCheckbox( public val label: String? = null, public val name: String? = null, ) : VisionOfHtmlInput() { - public var checked: Boolean? by meta.boolean() + public var checked: Boolean? by properties().boolean() } @Serializable @@ -36,7 +37,7 @@ public class VisionOfNumberField( public val label: String? = null, public val name: String? = null, ) : VisionOfHtmlInput() { - public var value: Number? by meta.number() + public var value: Number? by properties().number() } @Serializable @@ -48,6 +49,6 @@ public class VisionOfRangeField( public val label: String? = null, public val name: String? = null, ) : VisionOfHtmlInput() { - public var value: Number? by meta.number() + public var value: Number? by properties().number() } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt index 999bbb45..185c98a9 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt @@ -49,7 +49,7 @@ public fun Vision.propertyValue( getPropertyValue(name ?: Name.parse(property.name), inherit, includeStyles, includeDefaults) override fun setValue(thisRef: Any?, property: KProperty<*>, value: Value?) { - meta.setValue(name ?: Name.parse(property.name), value) + setPropertyValue(name ?: Name.parse(property.name), value) } } @@ -69,7 +69,7 @@ public fun Vision.propertyValue( ).let(getter) override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { - meta.setValue(name ?: Name.parse(property.name), value?.let(setter)) + setPropertyValue(name ?: Name.parse(property.name), value?.let(setter)) } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt index 15ef9229..3fa6703f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt @@ -3,6 +3,7 @@ package space.kscience.visionforge import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.* import space.kscience.dataforge.values.asValue +import space.kscience.dataforge.values.set private const val INHERITED_DESCRIPTOR_ATTRIBUTE = "inherited" private const val STYLE_DESCRIPTOR_ATTRIBUTE = "useStyles" diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/StatisticsVisitor.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/StatisticsVisitor.kt index 0a60c3c0..5b989274 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/StatisticsVisitor.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/StatisticsVisitor.kt @@ -1,6 +1,5 @@ package space.kscience.visionforge.visitor -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow @@ -11,7 +10,6 @@ import space.kscience.visionforge.Vision import kotlin.reflect.KClass -@OptIn(ExperimentalCoroutinesApi::class) public suspend fun Vision.flowStatistics(statistics: (Name, Vision) -> T): Flow = callbackFlow { val visitor = object : VisionVisitor { override suspend fun visit(name: Name, vision: Vision){ diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt index 0533dc4e..3ba313a9 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt @@ -6,7 +6,7 @@ import kotlinx.coroutines.launch import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.iterator public interface VisionVisitor { /** @@ -19,30 +19,30 @@ public interface VisionVisitor { /** * Rearrange children of given group */ - public suspend fun visitChildren(name: Name, group: VisionGroup) { + public suspend fun visitChildren(name: Name, group: Vision) { //Do nothing by default } public fun skip(name: Name, vision: Vision): Boolean = false - public companion object{ + public companion object { private fun CoroutineScope.visitTreeAsync( visionVisitor: VisionVisitor, name: Name, - vision: Vision + vision: Vision, ): Job = launch { if (visionVisitor.skip(name, vision)) return@launch visionVisitor.visit(name, vision) - if (vision is VisionGroup) { - visionVisitor.visitChildren(name, vision) - for ((token, child) in vision.children) { - visitTreeAsync(visionVisitor, name + token, child) - } + visionVisitor.visitChildren(name, vision) + + for ((token, child) in vision.children) { + visitTreeAsync(visionVisitor, name + token, child) } } + /** * Recursively visit this [Vision] and all children */ diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index 42a9ba1f..b7b8208d 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -4,13 +4,9 @@ import kotlinx.html.* import kotlinx.html.stream.createHTML import space.kscience.dataforge.context.Global import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.configure -import space.kscience.dataforge.meta.set import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name -import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionBase -import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.* import kotlin.collections.set import kotlin.test.Test @@ -36,7 +32,7 @@ fun FlowContent.renderVisionFragment( @DFExperimental class HtmlTagTest { - fun VisionOutput.base(block: VisionBase.() -> Unit) = VisionBase().apply(block) + fun VisionOutput.base(block: VisionGroup.() -> Unit) = VisionGroup().apply(block) val fragment: HtmlVisionFragment = { div { @@ -46,10 +42,8 @@ class HtmlTagTest { "metaProperty" put 87 } base { - configure { - set("myProp", 82) - set("otherProp", false) - } + setPropertyValue("myProp", 82) + setPropertyValue("otherProp", false) } } } @@ -59,7 +53,7 @@ class HtmlTagTest { div { h2 { +"Properties" } ul { - (vision as? VisionBase)?.meta?.items?.forEach { + vision.getProperty(Name.EMPTY).items.forEach { li { a { +it.key.toString() } p { +it.value.toString() } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 40b4c96e..234d0043 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -1,8 +1,16 @@ package space.kscience.visionforge.meta -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.Scheme +import space.kscience.dataforge.meta.SchemeSpec +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.updateWith import space.kscience.dataforge.values.asValue -import space.kscience.visionforge.VisionBase +import space.kscience.dataforge.values.boolean +import space.kscience.dataforge.values.int +import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.getProperty +import space.kscience.visionforge.getPropertyValue +import space.kscience.visionforge.setPropertyValue import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals @@ -10,22 +18,22 @@ import kotlin.test.assertNotEquals class VisionPropertyTest { @Test fun testPropertyWrite(){ - val vision = VisionBase() - vision.meta["fff"] = 2 - vision.meta["fff.ddd"] = false + val vision = VisionGroup() + vision.setPropertyValue("fff", 2) + vision.setPropertyValue("fff.ddd", false) - assertEquals(2, vision.meta["fff"]?.int) - assertEquals(false, vision.meta["fff.ddd"]?.boolean) + assertEquals(2, vision.getPropertyValue("fff")?.int) + assertEquals(false, vision.getPropertyValue("fff.ddd")?.boolean) } @Test fun testPropertyEdit(){ - val vision = VisionBase() - vision.meta.getOrCreate("fff.ddd").apply { + val vision = VisionGroup() + vision.getProperty("fff.ddd").apply { value = 2.asValue() } - assertEquals(2, vision.meta["fff.ddd"]?.int) - assertNotEquals(true, vision.meta["fff.ddd"]?.boolean) + assertEquals(2, vision.getPropertyValue("fff.ddd")?.int) + assertNotEquals(true, vision.getPropertyValue("fff.ddd")?.boolean) } internal class TestScheme: Scheme(){ @@ -35,10 +43,10 @@ class VisionPropertyTest { @Test fun testPropertyUpdate(){ - val vision = VisionBase() - vision.meta.getOrCreate("fff").updateWith(TestScheme){ + val vision = VisionGroup() + vision.getProperty("fff").updateWith(TestScheme){ ddd = 2 } - assertEquals(2, vision.meta["fff.ddd"]?.int) + assertEquals(2, vision.getPropertyValue("fff.ddd")?.int) } } \ No newline at end of file diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt index bf1033ba..7b1299f4 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt @@ -6,11 +6,10 @@ import javafx.scene.Node import javafx.scene.Parent import javafx.scene.layout.VBox import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.ObservableMutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties +import space.kscience.visionforge.getProperty import space.kscience.visionforge.getStyle import space.kscience.visionforge.styles import tornadofx.* @@ -21,8 +20,8 @@ public class VisionEditorFragment : Fragment() { public var vision: Vision? by visionProperty public val descriptorProperty: SimpleObjectProperty = SimpleObjectProperty() - private val configProperty: Binding = visionProperty.objectBinding { vision -> - vision?.meta + private val configProperty: Binding = visionProperty.objectBinding { vision -> + vision?.getProperty(Name.EMPTY) } private val configEditorProperty: Binding = configProperty.objectBinding(descriptorProperty) { @@ -30,7 +29,7 @@ public class VisionEditorFragment : Fragment() { val node:FXMetaModel = FXMetaModel( meta, vision?.descriptor, - vision?.computeProperties(), + vision?.meta, Name.EMPTY, "Vision properties" ) diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionTreeFragment.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionTreeFragment.kt index 335b5a69..c0c1dfa4 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionTreeFragment.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionTreeFragment.kt @@ -5,17 +5,17 @@ import javafx.scene.control.SelectionMode import javafx.scene.control.TreeItem import javafx.scene.layout.VBox import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.solid.SolidGroup import tornadofx.* private fun toTreeItem(vision: Vision, title: String): TreeItem> { return object : TreeItem>(title to vision) { init { - if (vision is VisionGroup) { + if (vision is SolidGroup) { //lazy populate the tree expandedProperty().onChange { expanded -> if (expanded && children.isEmpty()) { - children.setAll(vision.children.map { + children.setAll(vision.items.map { toTreeItem(it.value, it.key.toString()) }) } @@ -24,7 +24,7 @@ private fun toTreeItem(vision: Vision, title: String): TreeItem referenceFactory(obj, binding) + is SolidReference -> referenceFactory(obj, binding) is SolidGroup -> { - Group(obj.children.mapNotNull { (token, obj) -> + Group(obj.items.mapNotNull { (token, obj) -> (obj as? Solid)?.let { logger.info { token.toString() } buildNode(it).apply { @@ -77,7 +77,7 @@ public class FX3DPlugin : AbstractPlugin() { is PolyLine -> PolyLine3D( obj.points.map { Point3D(it.x, it.y, it.z) }, obj.thickness.toFloat(), - obj.computePropertyNode(SolidMaterial.MATERIAL_COLOR_KEY)?.color() + obj.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).color() ).apply { this.meshView.cullFace = CullFace.FRONT } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt index af00f7c5..60b95f9f 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt @@ -8,20 +8,21 @@ import space.kscience.dataforge.names.firstOrNull import space.kscience.dataforge.names.isEmpty import space.kscience.visionforge.Vision import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX import kotlin.reflect.KClass -public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory { - override val type: KClass get() = SolidReferenceGroup::class +public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory { + override val type: KClass get() = SolidReference::class - override fun invoke(obj: SolidReferenceGroup, binding: VisualObjectFXBinding): Node { + override fun invoke(obj: SolidReference, binding: VisualObjectFXBinding): Node { val prototype = obj.prototype val node = plugin.buildNode(prototype) obj.onPropertyChange { name-> - if (name.firstOrNull()?.body == SolidReferenceGroup.REFERENCE_CHILD_PROPERTY_PREFIX) { + if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'") val propertyName = name.cutFirst() - val referenceChild = obj[childName] ?: error("Reference child with name '$childName' not found") + val referenceChild = obj.children[childName] ?: error("Reference child with name '$childName' not found") val child = node.findChild(childName) ?: error("Object child with name '$childName' not found") child.updateProperty(referenceChild, propertyName) } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt index 607913d7..680033d4 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt @@ -7,7 +7,7 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.values.Value import space.kscience.visionforge.Vision -import space.kscience.visionforge.computePropertyNode +import space.kscience.visionforge.getProperty import space.kscience.visionforge.onPropertyChange import tornadofx.* @@ -36,7 +36,7 @@ public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vi public operator fun get(key: Name): ObjectBinding { return bindings.getOrPut(key) { object : ObjectBinding() { - override fun computeValue(): Meta? = obj.computePropertyNode(key) + override fun computeValue(): Meta = obj.getProperty(key) } } } diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt index 442cde3c..976db192 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt @@ -6,7 +6,7 @@ import space.kscience.dataforge.names.Name import space.kscience.gdml.* import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial -import space.kscience.visionforge.solid.invoke +import space.kscience.visionforge.solid.set import space.kscience.visionforge.useStyle import kotlin.random.Random @@ -44,7 +44,7 @@ public class GdmlLoaderOptions { * Configure paint for given solid with given [GdmlMaterial] */ public var configurePaint: SolidMaterial.(material: GdmlMaterial, solid: GdmlSolid) -> Unit = - { material, _ -> color(randomColor(material)) } + { material, _ -> color.set(randomColor(material)) } private set public fun paint(block: SolidMaterial.(material: GdmlMaterial, solid: GdmlSolid) -> Unit) { diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index f80a5511..34a9afa2 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -30,10 +30,10 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { private val proto = SolidGroup() private val solids = proto.group(solidsName) { - setPropertyNode("edges.enabled", false) + setPropertyValue("edges.enabled", false) } - private val referenceStore = HashMap>() + private val referenceStore = HashMap>() fun Solid.configureSolid(root: Gdml, parent: GdmlVolume, solid: GdmlSolid) { val material = parent.materialref.resolve(root) ?: GdmlElement(parent.materialref.ref) @@ -44,7 +44,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { } } - private fun proxySolid(root: Gdml, group: SolidGroup, solid: GdmlSolid, name: String): SolidReferenceGroup { + private fun proxySolid(root: Gdml, group: SolidGroup, solid: GdmlSolid, name: String): SolidReference { val templateName = solidsName + name if (proto[templateName] == null) { solids.addSolid(root, solid, name) @@ -59,7 +59,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { group: SolidGroup, physVolume: GdmlPhysVolume, volume: GdmlGroup, - ): SolidReferenceGroup { + ): SolidReference { val templateName = volumesName + volume.name.asName() if (proto[templateName] == null) { proto[templateName] = volume(root, volume) @@ -321,7 +321,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { ?: error("Volume with ref ${divisionVolume.volumeref.ref} could not be resolved") //TODO add divisions - set(null, volume(root, volume)) + children.static(volume(root, volume)) } private fun volume( @@ -355,7 +355,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { final.useStyle(rootStyle) final.prototypes { - proto.children.forEach { (token, item) -> + proto.items.forEach { (token, item) -> item.parent = null set(token.asName(), item as? Solid) } @@ -383,9 +383,9 @@ public fun Gdml.toVision(block: GdmlLoaderOptions.() -> Unit = {}): SolidGroup { * Append Gdml node to the group */ public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlLoaderOptions.() -> Unit = {}) { - val visual = gdml.toVision(transformer) + val vision = gdml.toVision(transformer) //println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual)) - set(key, visual) + children[key] = vision } @VisionBuilder diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt index befc69bb..afc6c99a 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt @@ -6,10 +6,9 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.length import space.kscience.dataforge.names.plus -import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidGroup -import space.kscience.visionforge.solid.SolidReferenceGroup +import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.solid.layer @@ -23,15 +22,15 @@ private class VisionCounterTree( var selfCount = 1 val children: Map by lazy { - (vision as? VisionGroup)?.children?.mapValues { (key, vision) -> - if (vision is SolidReferenceGroup) { - prototypes.getOrPut(vision.refName) { - VisionCounterTree(vision.refName, vision.prototype, prototypes) + (vision as? SolidGroup)?.items?.mapValues { (key, vision) -> + if (vision is SolidReference) { + prototypes.getOrPut(vision.prototypeName) { + VisionCounterTree(vision.prototypeName, vision.prototype, prototypes) }.apply { selfCount += 1 } } else { - VisionCounterTree(name + key, vision as Solid, prototypes) + VisionCounterTree(name + key, vision, prototypes) } } ?: emptyMap() } @@ -51,10 +50,10 @@ private fun VisionCounterTree.topToBottom(): Sequence = seque } public fun SolidGroup.markLayers(thresholds: List = listOf(500, 1000, 20000, 50000)) { - val logger = manager?.context?.logger + val logger = manager.context.logger val counterTree = VisionCounterTree(Name.EMPTY, this, hashMapOf()) val totalCount = counterTree.childrenCount - if (totalCount > thresholds.firstOrNull() ?: 0) { + if (totalCount > (thresholds.firstOrNull() ?: 0)) { val allNodes = counterTree.topToBottom().distinct().toMutableList() //println("tree construction finished") allNodes.sortWith( diff --git a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt index 0ca76fd1..948ad214 100644 --- a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt +++ b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt @@ -21,12 +21,12 @@ class TestCubes { @Test fun testCubesDirect() { - val vision = cubes.toVision() + val vision: SolidGroup = cubes.toVision() // println(Solids.encodeToString(vision)) val smallBoxPrototype = vision.getPrototype(Name.parse("solids.smallBox")) as? Box assertNotNull(smallBoxPrototype) assertEquals(30.0, smallBoxPrototype.xSize.toDouble()) - val smallBoxVision = vision["composite-111.smallBox"]?.unref as? Box + val smallBoxVision = vision.children["composite-111.smallBox"]?.unref as? Box assertNotNull(smallBoxVision) assertEquals(30.0, smallBoxVision.xSize.toDouble()) } @@ -55,7 +55,7 @@ class TestCubes { assertNotNull(this.prototype) } if (this is SolidGroup) { - children.forEach { + items.forEach { it.value.checkPrototypes() } } diff --git a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt index 87682978..93e7359e 100644 --- a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt +++ b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt @@ -9,17 +9,18 @@ import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionBase +import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.properties @Serializable @SerialName("vision.markup") public class VisionOfMarkup( public val format: String = COMMONMARK_FORMAT -) : VisionBase() { +) : VisionGroup() { //TODO add templates - public var content: String? by meta.string(CONTENT_PROPERTY_KEY) + public var content: String? by properties().string(CONTENT_PROPERTY_KEY) public companion object { public val CONTENT_PROPERTY_KEY: Name = "content".asName() diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index ebb4773c..880a1961 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -2,21 +2,24 @@ package space.kscience.visionforge.plotly import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.asObservable import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.Name import space.kscience.plotly.Plot import space.kscience.plotly.Plotly -import space.kscience.visionforge.VisionBase +import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.getProperty import space.kscience.visionforge.html.VisionOutput @Serializable @SerialName("vision.plotly") -public class VisionOfPlotly private constructor() : VisionBase() { +public class VisionOfPlotly private constructor() : VisionGroup() { public constructor(plot: Plot) : this() { - properties = plot.meta + setProperty(Name.EMPTY, plot.meta) } - public val plot: Plot get() = Plot(meta) + public val plot: Plot get() = Plot(getProperty(Name.EMPTY).asObservable()) } public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this) diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 7d55771c..bb88fa22 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -8,7 +8,7 @@ import io.ktor.server.engine.embeddedServer import io.ktor.server.html.respondHtml import io.ktor.server.http.content.resources import io.ktor.server.http.content.static -import io.ktor.server.plugins.cors.CORS +import io.ktor.server.plugins.cors.routing.CORS import io.ktor.server.response.respond import io.ktor.server.response.respondText import io.ktor.server.routing.* @@ -18,7 +18,6 @@ import io.ktor.server.websocket.webSocket import io.ktor.websocket.Frame import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext diff --git a/visionforge-solid/api/visionforge-solid.api b/visionforge-solid/api/visionforge-solid.api index 34c11260..c763e3c8 100644 --- a/visionforge-solid/api/visionforge-solid.api +++ b/visionforge-solid/api/visionforge-solid.api @@ -717,7 +717,7 @@ public final class space/kscience/visionforge/solid/SolidMaterialKt { } public abstract interface class space/kscience/visionforge/solid/SolidReference : space/kscience/visionforge/VisionGroup { - public fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; public abstract fun getPrototype ()Lspace/kscience/visionforge/solid/Solid; } @@ -728,7 +728,7 @@ public final class space/kscience/visionforge/solid/SolidReferenceGroup : space/ public fun (Lspace/kscience/dataforge/names/Name;)V public fun getChildren ()Ljava/util/Map; public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; - public fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; public fun getPrototype ()Lspace/kscience/visionforge/solid/Solid; public final fun getRefName ()Lspace/kscience/dataforge/names/Name; public static final fun write$Self (Lspace/kscience/visionforge/solid/SolidReferenceGroup;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index 0f9abc4d..39b7e7b0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -1,12 +1,13 @@ package space.kscience.visionforge.solid -import space.kscience.dataforge.meta.Configurable import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.* import space.kscience.visionforge.Colors +import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.getProperty import kotlin.properties.ReadOnlyProperty @VisionBuilder @@ -27,8 +28,8 @@ public class ColorAccessor( } } -public fun Configurable.color(): ReadOnlyProperty = ReadOnlyProperty { _, property -> - ColorAccessor(meta, property.name.asName()) +public fun Vision.color(): ReadOnlyProperty = ReadOnlyProperty { _, property -> + ColorAccessor(getProperty(Name.EMPTY), property.name.asName()) } public var ColorAccessor?.string: String? @@ -40,21 +41,21 @@ public var ColorAccessor?.string: String? /** * Set [webcolor](https://en.wikipedia.org/wiki/Web_colors) as string */ -public operator fun ColorAccessor?.invoke(webColor: String) { +public fun ColorAccessor?.set(webColor: String) { this?.value = webColor.asValue() } /** * Set color as RGB integer */ -public operator fun ColorAccessor?.invoke(rgb: Int) { +public fun ColorAccessor?.set(rgb: Int) { this?.value = Colors.rgbToString(rgb).asValue() } /** * Set color as RGB */ -public operator fun ColorAccessor?.invoke(r: UByte, g: UByte, b: UByte) { +public fun ColorAccessor?.set(r: UByte, g: UByte, b: UByte) { this?.value = Colors.rgbToString(r, g, b).asValue() } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index d63e08b6..d300b06b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -3,11 +3,8 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.isEmpty -import space.kscience.dataforge.meta.update -import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer -import space.kscience.visionforge.set +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.* public enum class CompositeType { GROUP, // Dumb sum of meshes @@ -28,16 +25,16 @@ public class Composite( public inline fun VisionContainerBuilder.composite( type: CompositeType, name: String? = null, - builder: SolidGroup.() -> Unit, + @VisionBuilder builder: SolidGroup.() -> Unit, ): Composite { - val group = SolidGroup().apply(builder) - val children = group.children.values.filterIsInstance() - if (children.size != 2){ + val group = SolidGroup(builder) + val children = group.items.values.toList() + if (children.size != 2) { error("Composite requires exactly two children, but found ${children.size}") } val res = Composite(type, children[0], children[1]) - res.meta.update(group.meta) + res.setProperty(Name.EMPTY, group.getProperty(Name.EMPTY)) set(name, res) return res @@ -50,34 +47,34 @@ public inline fun VisionContainerBuilder.composite( public fun SolidGroup.smartComposite( type: CompositeType, name: String? = null, - builder: SolidGroup.() -> Unit, + @VisionBuilder builder: SolidGroup.() -> Unit, ): Solid = if (type == CompositeType.GROUP) { val group = SolidGroup(builder) if (name == null && group.meta.isEmpty()) { //append directly to group if no properties are defined - group.children.forEach { (_, value) -> + group.items.forEach { (_, value) -> value.parent = null - set(null, value) + children.static(value) } this } else { - set(name, group) + children[name] = group group } } else { - composite(type, name, builder) + children.composite(type, name, builder) } @VisionBuilder public inline fun VisionContainerBuilder.union( name: String? = null, - builder: SolidGroup.() -> Unit + builder: SolidGroup.() -> Unit, ): Composite = composite(CompositeType.UNION, name, builder = builder) @VisionBuilder public inline fun VisionContainerBuilder.subtract( name: String? = null, - builder: SolidGroup.() -> Unit + builder: SolidGroup.() -> Unit, ): Composite = composite(CompositeType.SUBTRACT, name, builder = builder) @VisionBuilder diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 30ecb575..6e5a8bb7 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.ObservableMutableMeta -import space.kscience.dataforge.meta.configure +import space.kscience.dataforge.names.Name import space.kscience.visionforge.* import kotlin.math.PI import kotlin.math.cos @@ -40,7 +40,7 @@ public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Flo @SerialName("solid.extrude") public class Extruded( public val shape: List, - public val layers: List + public val layers: List, ) : SolidBase(), GeometrySolid, VisionPropertyContainer { override fun toGeometry(geometryBuilder: GeometryBuilder) { @@ -67,7 +67,7 @@ public class Extruded( for (i in (1 until layers.size)) { upperLayer = layers[i] for (j in (0 until shape.size - 1)) { - //counter clockwise + //counterclockwise geometryBuilder.face4( lowerLayer[j], lowerLayer[j + 1], @@ -99,7 +99,7 @@ public class ExtrudeBuilder( public var layers: MutableList = ArrayList(), - config: ObservableMutableMeta = MutableMeta() + config: ObservableMutableMeta = MutableMeta(), ) : SimpleVisionPropertyContainer(config) { public fun shape(block: Shape2DBuilder.() -> Unit) { this.shape = Shape2DBuilder().apply(block).build() @@ -110,12 +110,12 @@ public class ExtrudeBuilder( } internal fun build(): Extruded = Extruded(shape, layers).apply { - configure(this@ExtrudeBuilder.meta) + setProperty(Name.EMPTY, getProperty(Name.EMPTY)) } } @VisionBuilder public fun VisionContainerBuilder.extruded( name: String? = null, - action: ExtrudeBuilder.() -> Unit = {} + action: ExtrudeBuilder.() -> Unit = {}, ): Extruded = ExtrudeBuilder().apply(action).build().also { set(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Quaternion.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Quaternion.kt deleted file mode 100644 index 617c7a38..00000000 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Quaternion.kt +++ /dev/null @@ -1,11 +0,0 @@ -package space.kscience.visionforge.solid - -import kotlin.jvm.JvmInline - -@JvmInline -public value class Quaternion(public val values: DoubleArray) - -public operator fun Quaternion.component1(): Double = values[0] -public operator fun Quaternion.component2(): Double = values[1] -public operator fun Quaternion.component3(): Double = values[2] -public operator fun Quaternion.component4(): Double = values[3] \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 2b9c883b..c3111d4e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -6,16 +6,12 @@ import space.kscience.dataforge.meta.descriptors.node import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.meta.float import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.number import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.* -import space.kscience.visionforge.Vision +import space.kscience.visionforge.* import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY -import space.kscience.visionforge.hide -import space.kscience.visionforge.inherited -import space.kscience.visionforge.setProperty import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY import space.kscience.visionforge.solid.Solid.Companion.IGNORE_KEY import space.kscience.visionforge.solid.Solid.Companion.LAYER_KEY @@ -38,7 +34,7 @@ import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty /** - * Interface for 3-dimensional [Vision] + * Interface for a [Vision] representing a 3D object */ public interface Solid : Vision { @@ -121,7 +117,7 @@ public interface Solid : Vision { public var Solid.layer: Int get() = getPropertyValue(LAYER_KEY, inherit = true)?.int ?: 0 set(value) { - setProperty(LAYER_KEY, value) + setPropertyValue(LAYER_KEY, value) } // Common properties @@ -140,23 +136,23 @@ public enum class RotationOrder { */ public var Solid.rotationOrder: RotationOrder get() = getPropertyValue(Solid.ROTATION_ORDER_KEY)?.enum() ?: RotationOrder.XYZ - set(value) = meta.setValue(Solid.ROTATION_ORDER_KEY, value.name.asValue()) + set(value) = setPropertyValue(Solid.ROTATION_ORDER_KEY, value.name.asValue()) /** * Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default. Not inherited */ public var Solid.detail: Int? - get() = getPropertyValue(DETAIL_KEY, false)?.int - set(value) = meta.setValue(DETAIL_KEY, value?.asValue()) + get() = getPropertyValue(DETAIL_KEY, inherit = false)?.int + set(value) = setPropertyValue(DETAIL_KEY, value?.asValue()) /** * If this property is true, the object will be ignored on render. * Property is not inherited. */ public var Vision.ignore: Boolean? - get() = getPropertyValue(IGNORE_KEY, false)?.boolean - set(value) = meta.setValue(IGNORE_KEY, value?.asValue()) + get() = getPropertyValue(IGNORE_KEY, inherit = false)?.boolean + set(value) = setPropertyValue(IGNORE_KEY, value?.asValue()) //var VisualObject.selected: Boolean? // get() = getProperty(SELECTED_KEY).boolean @@ -165,18 +161,18 @@ public var Vision.ignore: Boolean? internal fun float(name: Name, default: Number): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Number { - return thisRef.meta.getMeta(name)?.number ?: default + return thisRef.getPropertyValue(name)?.number ?: default } override fun setValue(thisRef: Solid, property: KProperty<*>, value: Number) { - thisRef.setProperty(name, value) + thisRef.setPropertyValue(name, value) } } internal fun point(name: Name, default: Float): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Point3D? { - val item = thisRef.meta.getMeta(name) ?: return null + val item = thisRef.meta[name] ?: return null return object : Point3D { override val x: Float get() = item[X_KEY]?.float ?: default override val y: Float get() = item[Y_KEY]?.float ?: default @@ -186,11 +182,11 @@ internal fun point(name: Name, default: Float): ReadWriteProperty, value: Point3D?) { if (value == null) { - thisRef.meta.setMeta(name, null) + thisRef.setProperty(name, null) } else { - thisRef.setProperty(name + X_KEY, value.x) - thisRef.setProperty(name + Y_KEY, value.y) - thisRef.setProperty(name + Z_KEY, value.z) + thisRef.setPropertyValue(name + X_KEY, value.x) + thisRef.setPropertyValue(name + Y_KEY, value.y) + thisRef.setPropertyValue(name + Z_KEY, value.z) } } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt index 70e2501e..6d4b2faf 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt @@ -2,11 +2,24 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.visionforge.VisionBase +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.AbstractVision +import space.kscience.visionforge.VisionChildren @Serializable @SerialName("solid") -public open class SolidBase : VisionBase(), Solid { +public open class SolidBase : AbstractVision(), Solid { override val descriptor: MetaDescriptor get() = Solid.descriptor + override val children: VisionChildren get() = VisionChildren.empty(this) + + override fun getProperty( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + includeDefaults: Boolean, + ): MutableMeta { + return super.getProperty(name, inherit, includeStyles, includeDefaults) + } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index 76d0708b..20528056 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -7,6 +7,7 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.visionforge.* + /** * A container with prototype support */ @@ -23,20 +24,26 @@ public interface PrototypeHolder { public fun getPrototype(name: Name): Solid? } + /** - * Represents 3-dimensional Visual Group - * @param prototypes A container for templates visible inside this group + * A [Solid] group with additional accessor methods */ @Serializable @SerialName("group.solid") -public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder { +public class SolidGroup : VisionGroup(), Solid, PrototypeHolder, MutableVisionGroup, VisionContainerBuilder { + + public val items: Map + get() = children.keys.mapNotNull { + val value = children[it] as? Solid ?: return@mapNotNull null + it to value + }.toMap() - override val children: Map get() = super.childrenInternal.filter { it.key != PROTOTYPES_TOKEN } + public operator fun get(name: Name): Solid? = children[name] as? Solid - private var prototypes: MutableVisionGroup? - get() = childrenInternal[PROTOTYPES_TOKEN] as? MutableVisionGroup + private var prototypes: SolidGroup? + get() = items[PROTOTYPES_TOKEN] as? SolidGroup set(value) { - set(PROTOTYPES_TOKEN, value) + children[PROTOTYPES_TOKEN] = value } @@ -53,36 +60,38 @@ public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder { * Create or edit prototype node as a group */ override fun prototypes(builder: VisionContainerBuilder.() -> Unit): Unit { - (prototypes ?: SolidGroup().also { - prototypes = it - }).run(builder) + (prototypes ?: SolidGroup().also { prototypes = it }).children.run(builder) } override fun createGroup(): SolidGroup = SolidGroup() - // // override fun update(change: VisionChange) { // updatePosition(change.properties) // super.update(change) // } + override fun set(name: Name?, child: Solid?) { + children[name] = child + } + public companion object { public val PROTOTYPES_TOKEN: NameToken = NameToken("@prototypes") } } -@Suppress("FunctionName") -public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block) +public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block) @VisionBuilder -public fun VisionContainerBuilder.group( +public fun VisionContainerBuilder.group( name: Name? = null, builder: SolidGroup.() -> Unit = {}, -): SolidGroup = SolidGroup().apply(builder).also { set(name, it) } +): SolidGroup = SolidGroup(builder).also { set(name, it) } /** * Define a group with given [name], attach it to this parent and return it. */ @VisionBuilder -public fun VisionContainerBuilder.group(name: String, action: SolidGroup.() -> Unit = {}): SolidGroup = - SolidGroup().apply(action).also { set(name, it) } +public fun VisionContainerBuilder.group( + name: String, + action: SolidGroup.() -> Unit = {}, +): SolidGroup = SolidGroup(action).also { set(name, it) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index 75d1f5a3..c68af09c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -9,6 +9,7 @@ import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.ValueType import space.kscience.dataforge.values.asValue import space.kscience.dataforge.values.number +import space.kscience.dataforge.values.set import space.kscience.visionforge.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY @@ -101,19 +102,19 @@ public class SolidMaterial : Scheme() { } public val Solid.color: ColorAccessor - get() = ColorAccessor(computePropertyValues(), MATERIAL_COLOR_KEY) + get() = ColorAccessor(getProperty(Name.EMPTY), MATERIAL_COLOR_KEY) public var Solid.material: SolidMaterial? - get() = computePropertyNode(MATERIAL_KEY)?.let { SolidMaterial.read(it) } - set(value) = meta.setMeta(MATERIAL_KEY, value?.meta) + get() = SolidMaterial.read(getProperty(MATERIAL_KEY)) + set(value) = setProperty(MATERIAL_KEY, value?.meta) @VisionBuilder public fun Solid.material(builder: SolidMaterial.() -> Unit) { - meta.getOrCreate(MATERIAL_KEY).updateWith(SolidMaterial, builder) + getProperty(MATERIAL_KEY).updateWith(SolidMaterial, builder) } public var Solid.opacity: Number? get() = getPropertyValue(MATERIAL_OPACITY_KEY, inherit = true)?.number set(value) { - meta.setValue(MATERIAL_OPACITY_KEY, value?.asValue()) + setPropertyValue(MATERIAL_OPACITY_KEY, value?.asValue()) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 04c54907..8e6e6f59 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -1,30 +1,54 @@ package space.kscience.visionforge.solid +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.emptyFlow import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.ObservableMutableMeta -import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.* import space.kscience.dataforge.values.Value import space.kscience.visionforge.* +import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX -public interface SolidReference : VisionGroup { - /** - * The prototype for this reference. - */ - public val prototype: Solid +/** + * Get a vision prototype if it is a [SolidReference] or vision itself if it is not. + * Unref is recursive, so it always returns a non-reference. + */ +public val Vision.unref: Solid + get() = when (this) { + is SolidReference -> prototype.unref + is Solid -> this + else -> error("This Vision is neither Solid nor SolidReference") + } + +/** + * @param name A name of reference child relative to prototype root + */ +internal class SolidReferenceChild( + val owner: SolidReference, + override var parent: Vision?, + val childName: Name, +) : Solid { + + val prototype: Solid + get() = owner.prototype.children[childName] as? Solid + ?: error("Prototype with name $childName not found") + + override val meta: Meta get() = owner.getProperty(childToken(childName).asName()) override fun getPropertyValue( name: Name, inherit: Boolean, includeStyles: Boolean, - includeDefaults: Boolean + includeDefaults: Boolean, ): Value? { - meta[name]?.value?.let { return it } + owner.getPropertyValue( + childPropertyName(childName, name), inherit, includeStyles, includeDefaults + )?.let { return it } if (includeStyles) { - getStyleProperty(name)?.let { return it } + getStyleProperty(name)?.value?.let { return it } } prototype.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } if (inherit) { @@ -32,117 +56,83 @@ public interface SolidReference : VisionGroup { } return null } -} + override fun setProperty(name: Name, node: Meta?) { + owner.setProperty(childPropertyName(childName, name), node) + } -/** - * Get a vision prototype if it is a [SolidReference] or vision itself if it is not. - * Unref is recursive, so it always returns a non-reference. - */ -public val Vision.unref: Solid - get() = when (this) { - is SolidReference -> prototype.unref - is Solid -> this - else -> error("This Vision is neither Solid nor SolidReference") + override fun setPropertyValue(name: Name, value: Value?) { + owner.setPropertyValue(childPropertyName(childName, name), value) } -private fun childToken(childName: Name): NameToken = - NameToken(SolidReferenceGroup.REFERENCE_CHILD_PROPERTY_PREFIX, childName.toString()) + override val propertyChanges: SharedFlow + get() = TODO("Not yet implemented") -private fun childPropertyName(childName: Name, propertyName: Name): Name = - childToken(childName) + propertyName + override fun invalidateProperty(propertyName: Name) { + owner.invalidateProperty(childPropertyName(childName, propertyName)) + } -/** - * A reference [Solid] to reuse a template object - */ -@Serializable -@SerialName("solid.ref") -public class SolidReferenceGroup( - public val refName: Name, -) : VisionBase(), SolidReference, VisionGroup, Solid { + override fun update(change: VisionChange) { + TODO("Not yet implemented") + } - /** - * Recursively search for defined template in the parent - */ - override val prototype: Solid by lazy { - if (parent == null) error("No parent is present for SolidReferenceGroup") - if (parent !is PrototypeHolder) error("Parent does not hold prototypes") - (parent as? PrototypeHolder)?.getPrototype(refName) ?: error("Prototype with name $refName not found") + + override val children: VisionChildren = object : VisionChildren { + override val parent: Vision get() = this@SolidReferenceChild + + override val keys: Set get() = prototype.children.keys + + override val changes: Flow get() = emptyFlow() + + override fun get(token: NameToken): SolidReferenceChild? { + if (token !in prototype.children.keys) return null + return SolidReferenceChild(this@SolidReferenceChild.owner, this@SolidReferenceChild, childName + token) + } } - override val children: Map - get() = (prototype as? VisionGroup)?.children - ?.filter { it.key != SolidGroup.PROTOTYPES_TOKEN } - ?.mapValues { - ReferenceChild(this, it.key.asName()) - } ?: emptyMap() + companion object { - override fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean - ): Value? = super.getPropertyValue(name, inherit, includeStyles, includeDefaults) + private fun childToken(childName: Name): NameToken = + NameToken(REFERENCE_CHILD_PROPERTY_PREFIX, childName.toString()) - override val descriptor: MetaDescriptor get() = prototype.descriptor + private fun childPropertyName(childName: Name, propertyName: Name): Name = + childToken(childName) + propertyName + } +} + +@Serializable +@SerialName("solid.ref") +public class SolidReference( + @SerialName("prototype") public val prototypeName: Name, +) : SolidBase() { /** - * A ProxyChild is created temporarily only to interact with properties, it does not store any values - * (properties are stored in external cache) and created and destroyed on-demand). + * The prototype for this reference. */ - private class ReferenceChild( - val owner: SolidReferenceGroup, - private val refName: Name - ) : SolidReference, VisionGroup, Solid { - - override val prototype: Solid by lazy { - if (refName.isEmpty()) { - owner.prototype - } else { - val proto = (owner.prototype as? VisionGroup)?.get(refName) - ?: error("Prototype with name $refName not found in SolidReferenceGroup ${owner.refName}") - proto as? Solid ?: error("Prototype with name $refName is ${proto::class} but expected Solid") -// proto.unref as? Solid -// ?: error("Prototype with name $refName is ${proto::class} but expected Solid") - } - } + public val prototype: Solid by lazy { + //Recursively search for defined template in the parent + if (parent == null) error("No parent is present for SolidReference") + if (parent !is PrototypeHolder) error("Parent does not hold prototypes") + (parent as? PrototypeHolder)?.getPrototype(prototypeName) + ?: error("Prototype with name $prototypeName not found") + } - override val meta: ObservableMutableMeta by lazy { - owner.meta.getOrCreate(childToken(refName).asName()) - } + override val children: VisionChildren + get() = object : VisionChildren { + override val parent: Vision get() = this@SolidReference - override val children: Map - get() = (prototype as? VisionGroup)?.children - ?.filter { it.key != SolidGroup.PROTOTYPES_TOKEN } - ?.mapValues { (key, _) -> - ReferenceChild(owner, refName + key.asName()) - } ?: emptyMap() - - override var parent: VisionGroup? - get() { - val parentName = refName.cutLast() - return if (parentName.isEmpty()) owner else ReferenceChild(owner, parentName) - } - set(_) { - error("Setting a parent for a reference child is not possible") - } + override val keys: Set get() = prototype.children.keys - override fun invalidateProperty(propertyName: Name) { - owner.invalidateProperty(childPropertyName(refName, propertyName)) - } + override val changes: Flow get() = emptyFlow() - override fun update(change: VisionChange) { - change.properties?.let { - updateProperties(Name.EMPTY, it) + override fun get(token: NameToken): SolidReferenceChild? { + if (token !in prototype.children.keys) return null + return SolidReferenceChild(this@SolidReference, this@SolidReference, token.asName()) } } - override val descriptor: MetaDescriptor get() = prototype.descriptor - - } - - public companion object { + public companion object{ public const val REFERENCE_CHILD_PROPERTY_PREFIX: String = "@child" } } @@ -150,33 +140,123 @@ public class SolidReferenceGroup( /** * Create ref for existing prototype */ -public fun SolidGroup.ref( +public fun VisionContainerBuilder.ref( templateName: Name, name: String? = null, -): SolidReferenceGroup = SolidReferenceGroup(templateName).also { set(name, it) } +): SolidReference = SolidReference(templateName).also { set(name, it) } -public fun SolidGroup.ref( +public fun VisionContainerBuilder.ref( templateName: String, name: String? = null, -): SolidReferenceGroup = ref(Name.parse(templateName), name) +): SolidReference = ref(Name.parse(templateName), name) /** - * Add new [SolidReferenceGroup] wrapping given object and automatically adding it to the prototypes. - * One must ensure that [prototypeHolder] is a parent of this group. + * Add new [SolidReference] wrapping given object and automatically adding it to the prototypes. */ public fun SolidGroup.newRef( name: String?, obj: Solid, - prototypeHolder: PrototypeHolder = this, - templateName: Name = Name.parse(name ?: obj.toString()), -): SolidReferenceGroup { - val existing = getPrototype(templateName) + prototypeHolder: SolidGroup = this, + prototypeName: Name = Name.parse(name ?: obj.toString()), +): SolidReference { + val existing = prototypeHolder.getPrototype(prototypeName) if (existing == null) { prototypeHolder.prototypes { - set(templateName, obj) + set(prototypeName, obj) } } else if (existing != obj) { error("Can't add different prototype on top of existing one") } - return ref(templateName, name) + return children.ref(prototypeName, name) } + + +// +// +///** +// * A reference [Solid] to reuse a template object +// */ +//@Serializable +//@SerialName("solid.ref") +//public class SolidReferenceGroup( +// public val refName: Name, +//) : VisionGroup(), SolidReference, VisionGroup, Solid { +// +// /** +// * Recursively search for defined template in the parent +// */ +// override val prototype: Solid by lazy { +// if (parent == null) error("No parent is present for SolidReferenceGroup") +// if (parent !is PrototypeHolder) error("Parent does not hold prototypes") +// (parent as? PrototypeHolder)?.getPrototype(refName) ?: error("Prototype with name $refName not found") +// } +// +// override val items: Map> +// get() = (prototype as? VisionGroup<*>)?.items +// ?.filter { it.key != SolidGroup.PROTOTYPES_TOKEN } +// ?.mapValues { +// VisionGroupItem.Node(ReferenceChild(this, it.key.asName())) +// } ?: emptyMap() +// +// override val descriptor: MetaDescriptor get() = prototype.descriptor +// +// +// /** +// * A ProxyChild is created temporarily only to interact with properties, it does not store any values +// * (properties are stored in external cache) and created and destroyed on-demand). +// */ +// private class ReferenceChild( +// val owner: SolidReferenceGroup, +// private val refName: Name, +// ) : SolidReference, VisionGroup, Solid { +// +// override val prototype: Solid by lazy { +// if (refName.isEmpty()) { +// owner.prototype +// } else { +// val proto = (owner.prototype).children.get(refName) +// ?: error("Prototype with name $refName not found in SolidReferenceGroup ${owner.refName}") +// proto as? Solid ?: error("Prototype with name $refName is ${proto::class} but expected Solid") +//// proto.unref as? Solid +//// ?: error("Prototype with name $refName is ${proto::class} but expected Solid") +// } +// } +// +// override val meta: ObservableMutableMeta by lazy { +// owner.meta.getOrCreate(childToken(refName).asName()) +// } +// +// override val items: Map> +// get() = (prototype as? VisionGroup<*>)?.items +// ?.filter { it.key != SolidGroup.PROTOTYPES_TOKEN } +// ?.mapValues { (key, _) -> +// VisionGroupItem.Node(ReferenceChild(owner, refName + key.asName())) +// } ?: emptyMap() +// +// override var parent: VisionGroup<*>? +// get() { +// val parentName = refName.cutLast() +// return if (parentName.isEmpty()) owner else ReferenceChild(owner, parentName) +// } +// set(_) { +// error("Setting a parent for a reference child is not possible") +// } +// +// override fun invalidateProperty(propertyName: Name) { +// owner.invalidateProperty(childPropertyName(refName, propertyName)) +// } +// +// override fun update(change: VisionChange) { +// change.properties?.let { +// updateProperties(it, Name.EMPTY) +// } +// } +// +// override val descriptor: MetaDescriptor get() = prototype.descriptor +// +// } +// +// public companion object { +// public const val REFERENCE_CHILD_PROPERTY_PREFIX: String = "@child" +// } +//} diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index b43d6475..6e9d00d9 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -29,7 +29,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta) { private fun PolymorphicModuleBuilder.solids() { subclass(SolidGroup.serializer()) - subclass(SolidReferenceGroup.serializer()) + subclass(SolidReference.serializer()) subclass(Composite.serializer()) subclass(Box.serializer()) subclass(GenericHexagon.serializer()) @@ -47,8 +47,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta) { public val serializersModuleForSolids: SerializersModule = SerializersModule { polymorphic(Vision::class) { - subclass(VisionBase.serializer()) - subclass(VisionGroupBase.serializer()) + subclass(VisionGroup.serializer()) solids() } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt index bae8d83d..45305e4a 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt @@ -21,7 +21,7 @@ public class Sphere( ) : SolidBase(), GeometrySolid, VisionPropertyContainer { override fun toGeometry(geometryBuilder: GeometryBuilder) { - fun point3DfromSphCoord(r: Float, theta: Float, phi: Float): Point3D { + fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Point3D { // This transformation matches three.js sphere implementation val y = r * cos(theta) val z = r * sin(theta) * sin(phi) @@ -39,10 +39,10 @@ public class Sphere( for (j in 0 until segments) { // phi iteration val phi1 = phiStart + j * phiStep val phi2 = phi1 + phiStep - val point1 = point3DfromSphCoord(radius, theta1, phi1) - val point2 = point3DfromSphCoord(radius, theta1, phi2) - val point3 = point3DfromSphCoord(radius, theta2, phi2) - val point4 = point3DfromSphCoord(radius, theta2, phi1) + val point1 = point3dFromSphCoord(radius, theta1, phi1) + val point2 = point3dFromSphCoord(radius, theta1, phi2) + val point3 = point3dFromSphCoord(radius, theta2, phi2) + val point4 = point3dFromSphCoord(radius, theta2, phi1) geometryBuilder.apply { // 1-2-3-4 gives the same face but with opposite orientation face4(point1, point4, point3, point2) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt index 05149e2e..b5ae5500 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt @@ -27,7 +27,7 @@ public class SphereLayer( require(outerRadius > 0) { "Outer radius must be positive" } require(innerRadius >= 0) { "inner radius must be non-negative" } - fun point3DfromSphCoord(r: Float, theta: Float, phi: Float): Point3D { + fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Point3D { // This transformation matches three.js sphere implementation val y = r * cos(theta) val z = r * sin(theta) * sin(phi) @@ -46,17 +46,17 @@ public class SphereLayer( val phi1 = phiStart + j * phiStep val phi2 = phi1 + phiStep //outer points - val outerPoint1 = point3DfromSphCoord(outerRadius, theta1, phi1) - val outerPoint2 = point3DfromSphCoord(outerRadius, theta1, phi2) - val outerPoint3 = point3DfromSphCoord(outerRadius, theta2, phi2) - val outerPoint4 = point3DfromSphCoord(outerRadius, theta2, phi1) + val outerPoint1 = point3dFromSphCoord(outerRadius, theta1, phi1) + val outerPoint2 = point3dFromSphCoord(outerRadius, theta1, phi2) + val outerPoint3 = point3dFromSphCoord(outerRadius, theta2, phi2) + val outerPoint4 = point3dFromSphCoord(outerRadius, theta2, phi1) // 1-2-3-4 gives the same face but with opposite orientation face4(outerPoint1, outerPoint4, outerPoint3, outerPoint2) if (innerRadius > 0) { - val innerPoint1 = point3DfromSphCoord(innerRadius, theta1, phi1) - val innerPoint2 = point3DfromSphCoord(innerRadius, theta1, phi2) - val innerPoint3 = point3DfromSphCoord(innerRadius, theta2, phi2) - val innerPoint4 = point3DfromSphCoord(innerRadius, theta2, phi1) + val innerPoint1 = point3dFromSphCoord(innerRadius, theta1, phi1) + val innerPoint2 = point3dFromSphCoord(innerRadius, theta1, phi2) + val innerPoint3 = point3dFromSphCoord(innerRadius, theta2, phi2) + val innerPoint4 = point3dFromSphCoord(innerRadius, theta2, phi1) face4(innerPoint1, innerPoint2, innerPoint3, innerPoint4) //the cup if (i == segments - 1 && theta != PI.toFloat() && innerRadius != outerRadius) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt index a0ad09a0..e9c9c146 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt @@ -112,9 +112,9 @@ public fun Point3D.toMeta(): Meta = Meta { internal fun Meta.toVector(default: Float = 0f) = Point3D( - this[Solid.X_KEY].float ?: default, - this[Solid.Y_KEY].float ?: default, - this[Solid.Z_KEY].float ?: default + this[X_KEY].float ?: default, + this[Y_KEY].float ?: default, + this[Z_KEY].float ?: default ) //internal fun Solid.updatePosition(meta: Meta?) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt index e74b47f0..aa53d424 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt @@ -5,6 +5,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.scheme import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.names.Name +import space.kscience.dataforge.values.set import space.kscience.visionforge.hide import space.kscience.visionforge.widgetType diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index 39aadbf1..bab2e518 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -1,31 +1,26 @@ package space.kscience.visionforge.solid.transform -import space.kscience.dataforge.meta.configure -import space.kscience.dataforge.meta.update import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.visionforge.* +import space.kscience.visionforge.getProperty import space.kscience.visionforge.solid.* private operator fun Number.plus(other: Number) = toFloat() + other.toFloat() private operator fun Number.times(other: Number) = toFloat() * other.toFloat() @DFExperimental -internal fun Vision.updateFrom(other: Vision): Vision { - if (this is Solid && other is Solid) { - x += other.x - y += other.y - z += other.y - rotationX += other.rotationX - rotationY += other.rotationY - rotationZ += other.rotationZ - scaleX *= other.scaleX - scaleY *= other.scaleY - scaleZ *= other.scaleZ - configure{ - update(other.meta) - } - } +internal fun Solid.updateFrom(other: Solid): Solid { + x += other.x + y += other.y + z += other.y + rotationX += other.rotationX + rotationY += other.rotationY + rotationZ += other.rotationZ + scaleX *= other.scaleX + scaleY *= other.scaleY + scaleZ *= other.scaleZ + setProperty(Name.EMPTY, other.getProperty(Name.EMPTY)) return this } @@ -34,17 +29,17 @@ internal fun Vision.updateFrom(other: Vision): Vision { internal object RemoveSingleChild : VisualTreeTransform() { override fun SolidGroup.transformInPlace() { - fun MutableVisionGroup.replaceChildren() { - children.forEach { (childName, parent) -> - if (parent is SolidReferenceGroup) return@forEach //ignore refs - if (parent is MutableVisionGroup) { + fun SolidGroup.replaceChildren() { + items.forEach { (childName, parent) -> + if (parent is SolidReference) return@forEach //ignore refs + if (parent is SolidGroup) { parent.replaceChildren() } - if (parent is VisionGroup && parent.children.size == 1) { - val child = parent.children.values.first() + if (parent is SolidGroup && parent.items.size == 1) { + val child: Solid = parent.items.values.first() val newParent = child.updateFrom(parent) newParent.parent = null - set(childName.asName(), newParent) + children[childName.asName()] = newParent } } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt index 890c8291..b78863d2 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt @@ -2,41 +2,47 @@ package space.kscience.visionforge.solid.transform import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.visionforge.MutableVisionGroup -import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.solid.SolidGroup -import space.kscience.visionforge.solid.SolidReferenceGroup +import space.kscience.visionforge.solid.SolidReference +import kotlin.collections.HashMap +import kotlin.collections.Map +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.collections.filter +import kotlin.collections.filterIsInstance +import kotlin.collections.fold +import kotlin.collections.forEach +import kotlin.collections.set @DFExperimental internal object UnRef : VisualTreeTransform() { - private fun VisionGroup.countRefs(): Map { - return children.values.fold(HashMap()) { reducer, obj -> - if (obj is VisionGroup) { - val counter = obj.countRefs() + private fun SolidGroup.countRefs(): Map { + return items.values.fold(HashMap()) { reducer, vision -> + if (vision is SolidGroup) { + val counter = vision.countRefs() counter.forEach { (key, value) -> reducer[key] = (reducer[key] ?: 0) + value } - } else if (obj is SolidReferenceGroup) { - reducer[obj.refName] = (reducer[obj.refName] ?: 0) + 1 + } else if (vision is SolidReference) { + reducer[vision.prototypeName] = (reducer[vision.prototypeName] ?: 0) + 1 } return reducer } } - private fun MutableVisionGroup.unref(name: Name) { + private fun SolidGroup.unref(name: Name) { (this as? SolidGroup)?.prototypes{ set(name, null) } - children.filter { (it.value as? SolidReferenceGroup)?.refName == name }.forEach { (key, value) -> - val reference = value as SolidReferenceGroup + items.filter { (it.value as? SolidReference)?.prototypeName == name }.forEach { (key, value) -> + val reference = value as SolidReference val newChild = reference.prototype.updateFrom(reference) newChild.parent = null - set(key.asName(), newChild) // replace proxy with merged object + children[key] = newChild // replace proxy with merged object } - children.values.filterIsInstance().forEach { it.unref(name) } + items.values.filterIsInstance().forEach { it.unref(name) } } override fun SolidGroup.transformInPlace() { diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt index 411aa75b..17dfb925 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt @@ -18,7 +18,7 @@ class CompositeTest { detail = 32 } material { - color("pink") + color.set("pink") } } } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt index a7133006..500bddb2 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt @@ -1,7 +1,6 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.meta.getIndexed -import space.kscience.dataforge.meta.node import space.kscience.dataforge.meta.toMeta import space.kscience.dataforge.misc.DFExperimental import kotlin.test.Test @@ -12,7 +11,7 @@ class ConvexTest { @Suppress("UNUSED_VARIABLE") @Test fun testConvexBuilder() { - val group = SolidGroup().apply { + val group = SolidGroup{ convex { point(50, 50, -50) point(50, -50, -50) @@ -25,7 +24,7 @@ class ConvexTest { } } - val convex = group.children.values.first() as Convex + val convex = group.items.values.first() as Convex val json = Solids.jsonForSolids.encodeToJsonElement(Convex.serializer(), convex) val meta = json.toMeta() diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt index 4e78e340..87de5c77 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt @@ -9,7 +9,7 @@ import kotlin.test.assertEquals class GroupTest { @Test fun testGroupWithComposite() { - val group = SolidGroup().apply { + val group = SolidGroup{ union("union") { box(100, 100, 100) { z = 100 @@ -18,7 +18,7 @@ class GroupTest { } box(100, 100, 100) material { - color(Colors.lightgreen) + color.set(Colors.lightgreen) opacity = 0.3f } } @@ -30,7 +30,7 @@ class GroupTest { } box(100, 100, 100) y = 300 - color(Colors.red) + color.set(Colors.red) } subtract("subtract") { box(100, 100, 100) { @@ -40,12 +40,12 @@ class GroupTest { } box(100, 100, 100) y = -300 - color(Colors.blue) + color.set(Colors.blue) } } - assertEquals(3, group.children.count()) - assertEquals(300.0, (group["intersect"] as Solid).y.toDouble()) - assertEquals(-300.0, (group["subtract"] as Solid).y.toDouble()) + assertEquals(3, group.items.count()) + assertEquals(300.0, (group.children["intersect"] as Solid).y.toDouble()) + assertEquals(-300.0, (group.children["subtract"] as Solid).y.toDouble()) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt index ec58e4d2..8e6f0b89 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt @@ -15,7 +15,7 @@ class PropertyTest { val box = Box(10.0f, 10.0f,10.0f) box.material { //meta["color"] = "pink" - color("pink") + color.set("pink") } assertEquals("pink", box.meta["material.color"]?.string) assertEquals("pink", box.color.string) @@ -33,7 +33,7 @@ class PropertyTest { } box.material { - color("pink") + color.set("pink") } assertEquals("pink", c) @@ -43,7 +43,7 @@ class PropertyTest { fun testInheritedProperty() { var box: Box? = null val group = SolidGroup().apply { - setPropertyNode("test", 22) + setPropertyValue("test", 22) group { box = box(100, 100, 100) } @@ -54,14 +54,14 @@ class PropertyTest { @Test fun testStyleProperty() { var box: Box? = null - val group = SolidGroup().apply { + val group = SolidGroup{ styleSheet { - set("testStyle") { + update("testStyle") { "test" put 22 } } group { - box = box(100, 100, 100).apply { + box = box(100, 100, 100) { useStyle("testStyle") } } @@ -74,7 +74,7 @@ class PropertyTest { var box: Box? = null val group = SolidGroup().apply { styleSheet { - set("testStyle") { + update("testStyle") { SolidMaterial.MATERIAL_COLOR_KEY put "#555555" } } @@ -89,10 +89,10 @@ class PropertyTest { @Test fun testReferenceStyleProperty() { - var box: SolidReferenceGroup? = null + var box: SolidReference? = null val group = SolidGroup{ styleSheet { - set("testStyle") { + update("testStyle") { SolidMaterial.MATERIAL_COLOR_KEY put "#555555" } } @@ -105,6 +105,6 @@ class PropertyTest { box = ref("box".asName()) } } - assertEquals("#555555", box?.color.string) + assertEquals("#555555", box!!.color.string) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index 558d005c..70cb9c4e 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors -import space.kscience.visionforge.MutableVisionGroup import space.kscience.visionforge.get import kotlin.test.Test import kotlin.test.assertEquals @@ -14,10 +13,10 @@ import kotlin.test.assertEquals fun SolidGroup.refGroup( name: String, templateName: Name = Name.parse(name), - block: MutableVisionGroup.() -> Unit -): SolidReferenceGroup { + block: SolidGroup.() -> Unit +): SolidReference { val group = SolidGroup().apply(block) - return newRef(name, group, templateName = templateName) + return newRef(name, group, prototypeName = templateName) } @@ -25,7 +24,7 @@ class SerializationTest { @Test fun testCubeSerialization() { val cube = Box(100f, 100f, 100f).apply { - color(222) + color.set(222) x = 100 z = -100 } @@ -38,7 +37,7 @@ class SerializationTest { @Test fun testProxySerialization() { val cube = Box(100f, 100f, 100f).apply { - color(222) + color.set(222) x = 100 z = -100 } @@ -53,21 +52,21 @@ class SerializationTest { val string = Solids.encodeToString(group) println(string) val reconstructed = Solids.decodeFromString(string) as SolidGroup - assertEquals(group["cube"]?.meta, reconstructed["cube"]?.meta) + assertEquals(group.children["cube"]?.meta, reconstructed.children["cube"]?.meta) } @Test fun lightSerialization(){ val group = SolidGroup { ambientLight { - color(Colors.white) + color.set(Colors.white) intensity = 100.0 } } val serialized = Solids.encodeToString(group) val reconstructed = Solids.decodeFromString(serialized) as SolidGroup - assertEquals(100.0, (reconstructed["@ambientLight"] as AmbientLightSource).intensity.toDouble()) + assertEquals(100.0, (reconstructed.children["@ambientLight"] as AmbientLightSource).intensity.toDouble()) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt index 23a48a63..4ac22e1f 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt @@ -24,6 +24,9 @@ class SolidPluginTest { val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup - assertEquals(visionManager.encodeToJsonElement(vision["aBox"]!!), visionManager.encodeToJsonElement(reconstructed["aBox"]!!)) + assertEquals( + visionManager.encodeToJsonElement(vision.children["aBox"]!!), + visionManager.encodeToJsonElement(reconstructed.children["aBox"]!!) + ) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt index cfdd73f0..4726f246 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt @@ -15,7 +15,7 @@ class SolidReferenceTest { SolidMaterial.MATERIAL_COLOR_KEY put "red" } newRef("test", Box(100f,100f,100f).apply { - color("blue") + color.set("blue") useStyle(theStyle) }) } @@ -23,13 +23,13 @@ class SolidReferenceTest { @Test fun testReferenceProperty(){ - assertEquals("blue", (groupWithReference["test"] as Solid).color.string) + assertEquals("blue", (groupWithReference.children["test"] as Solid).color.string) } @Test fun testReferenceSerialization(){ val serialized = Solids.jsonForSolids.encodeToJsonElement(groupWithReference) val deserialized = Solids.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized) - assertEquals("blue", (deserialized["test"] as Solid).color.string) + assertEquals("blue", (deserialized.children["test"] as Solid).color.string) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 26b4b40d..3fbf3ad4 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -21,24 +21,24 @@ class VisionUpdateTest { box(200,200,200, name = "origin") } val dif = VisionChange{ - group("top") { - color(123) + group ("top") { + color.set(123) box(100,100,100) } propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) } targetVision.update(dif) - assertTrue { targetVision["top"] is SolidGroup } - assertEquals("red", (targetVision["origin"] as Solid).color.string) // Should work - assertEquals("#00007b", (targetVision["top"] as Solid).color.string) // new item always takes precedence + assertTrue { targetVision.children["top"] is SolidGroup } + assertEquals("red", (targetVision.children["origin"] as Solid).color.string) // Should work + assertEquals("#00007b", (targetVision.children["top"] as Solid).color.string) // new item always takes precedence } @Test fun testVisionChangeSerialization(){ val change = VisionChange{ group("top") { - color(123) + color.set(123) box(100,100,100) } propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt index 6370b699..d76398fc 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt @@ -12,8 +12,9 @@ import space.kscience.dataforge.values.Null import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.asValue import space.kscience.tables.* -import space.kscience.visionforge.VisionBase +import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.html.VisionOutput +import space.kscience.visionforge.properties import kotlin.jvm.JvmName import kotlin.reflect.typeOf @@ -41,12 +42,13 @@ public val ColumnHeader.properties: ValueColumnScheme get() = ValueColumn @SerialName("vision.table") public class VisionOfTable( override val headers: List<@Serializable(ColumnHeaderSerializer::class) ColumnHeader>, -) : VisionBase(), Rows { +) : VisionGroup(), Rows { public var data: List get() = meta.getIndexed("rows").entries.sortedBy { it.key?.toInt() }.map { it.value } set(value) { - meta["rows"] = value + //TODO Make it better + properties()["rows"] = value } public val rows: List get() = data.map(::MetaRow) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt index 7ac4f13e..68b44fc5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt @@ -4,16 +4,15 @@ import info.laht.threekt.core.BufferGeometry import info.laht.threekt.geometries.EdgesGeometry import info.laht.threekt.objects.LineSegments import info.laht.threekt.objects.Mesh -import space.kscience.dataforge.meta.updateWith +import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.boolean import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.computePropertyNode +import space.kscience.visionforge.getProperty import space.kscience.visionforge.onPropertyChange -import space.kscience.visionforge.setProperty +import space.kscience.visionforge.setPropertyValue import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.layer @@ -32,7 +31,7 @@ public abstract class MeshThreeFactory( */ public abstract fun buildGeometry(obj: T): BufferGeometry - override fun invoke(three: ThreePlugin, obj: T): Mesh { + override fun build(three: ThreePlugin, obj: T): Mesh { val geometry = buildGeometry(obj) //val meshMeta: Meta = obj.properties[Material3D.MATERIAL_KEY]?.node ?: Meta.empty @@ -78,8 +77,8 @@ public abstract class MeshThreeFactory( @VisionBuilder public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { - setProperty(EDGES_ENABLED_KEY, enabled) - meta.getOrCreate(EDGES_MATERIAL_KEY).updateWith(SolidMaterial, block) + setPropertyValue(EDGES_ENABLED_KEY, enabled) + SolidMaterial.write(getProperty(EDGES_MATERIAL_KEY)).apply(block) } internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { @@ -95,9 +94,9 @@ internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { public fun Mesh.applyEdges(obj: Solid) { val edges = children.find { it.name == "@edges" } as? LineSegments //inherited edges definition, enabled by default - if (obj.getPropertyValue(EDGES_ENABLED_KEY, inherit = true)?.boolean != false) { + if (obj.getProperty(EDGES_ENABLED_KEY, inherit = true).boolean != false) { val bufferGeometry = geometry as? BufferGeometry ?: return - val material = ThreeMaterials.getLineMaterial(obj.computePropertyNode(EDGES_MATERIAL_KEY), true) + val material = ThreeMaterials.getLineMaterial(obj.getProperty(EDGES_MATERIAL_KEY), true) if (edges == null) { add( LineSegments( diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt index c3d6bfa0..9e105bde 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt @@ -8,7 +8,7 @@ import kotlin.reflect.KClass public object ThreeAmbientLightFactory : ThreeFactory { override val type: KClass get() = AmbientLightSource::class - override fun invoke(three: ThreePlugin, obj: AmbientLightSource): AmbientLight { + override fun build(three: ThreePlugin, obj: AmbientLightSource): AmbientLight { val res = AmbientLight().apply { color = obj.color.threeColor() ?: Color(0x404040) intensity = obj.intensity.toDouble() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index 7dd30a34..3fb87c7b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -11,6 +11,7 @@ import org.w3c.dom.CanvasRenderingContext2D import org.w3c.dom.CanvasTextBaseline import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.MIDDLE +import space.kscience.visionforge.getProperty import space.kscience.visionforge.solid.SolidLabel import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG @@ -22,11 +23,11 @@ import kotlin.reflect.KClass public object ThreeCanvasLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun invoke(three: ThreePlugin, obj: SolidLabel): Object3D { + override fun build(three: ThreePlugin, obj: SolidLabel): Object3D { val canvas = document.createElement("canvas") as HTMLCanvasElement val context = canvas.getContext("2d") as CanvasRenderingContext2D context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.getPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY)?.value ?: "black" + context.fillStyle = obj.getProperty(SolidMaterial.MATERIAL_COLOR_KEY)?.value ?: "black" context.textBaseline = CanvasTextBaseline.MIDDLE val metrics = context.measureText(obj.text) //canvas.width = metrics.width.toInt() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index 74528c50..4bd9826c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -37,7 +37,7 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory override val type: KClass get() = Composite::class - override fun invoke(three: ThreePlugin, obj: Composite): Mesh { + override fun build(three: ThreePlugin, obj: Composite): Mesh { val first = three.buildObject3D(obj.first).takeIfMesh() ?: error("First part of composite is not a mesh") val second = three.buildObject3D(obj.second).takeIfMesh() ?: error("Second part of composite is not a mesh") return when (obj.compositeType) { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 6e540f71..3397ea96 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -22,7 +22,7 @@ public interface ThreeFactory { public val type: KClass - public operator fun invoke(three: ThreePlugin, obj: T): Object3D + public fun build(three: ThreePlugin, obj: T): Object3D public companion object { public const val TYPE: String = "threeFactory" diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index d07f542e..46df4405 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -17,7 +17,7 @@ import kotlin.reflect.KClass public object ThreeLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun invoke(three: ThreePlugin, obj: SolidLabel): Object3D { + override fun build(three: ThreePlugin, obj: SolidLabel): Object3D { val textGeo = TextBufferGeometry(obj.text, jso { font = obj.fontFamily size = 20 diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index ee36d74b..da1984f3 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -4,7 +4,7 @@ import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.math.Color import info.laht.threekt.objects.LineSegments -import space.kscience.visionforge.computePropertyNode +import space.kscience.visionforge.getProperty import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial @@ -17,7 +17,7 @@ import kotlin.reflect.KClass public object ThreeLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun invoke(three: ThreePlugin, obj: PolyLine): Object3D { + override fun build(three: ThreePlugin, obj: PolyLine): Object3D { val geometry = BufferGeometry().apply { setFromPoints(Array((obj.points.size - 1) * 2) { obj.points[ceil(it / 2.0).toInt()].toVector() @@ -25,7 +25,7 @@ public object ThreeLineFactory : ThreeFactory { } val material = ThreeMaterials.getLineMaterial( - obj.computePropertyNode(SolidMaterial.MATERIAL_KEY), + obj.getProperty(SolidMaterial.MATERIAL_KEY), false ) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 82b088e5..e0f3a4a6 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -171,7 +171,7 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { ?: ThreeMaterials.BLACK_COLOR } SolidMaterial.MATERIAL_OPACITY_KEY -> { - val opacity = vision.getPropertyValue( + val opacity = vision.getProperty( SolidMaterial.MATERIAL_OPACITY_KEY, inherit = true, )?.double ?: 1.0 @@ -179,7 +179,7 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { material.transparent = opacity < 1.0 } SolidMaterial.MATERIAL_WIREFRAME_KEY -> { - material.asDynamic().wireframe = vision.getPropertyValue( + material.asDynamic().wireframe = vision.getProperty( SolidMaterial.MATERIAL_WIREFRAME_KEY, inherit = true, )?.boolean ?: false diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 182ec009..03ed5ee4 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -12,7 +12,6 @@ import space.kscience.visionforge.Vision import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.set import space.kscience.visionforge.visible import kotlin.collections.set import kotlin.reflect.KClass @@ -49,10 +48,10 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public fun buildObject3D(obj: Solid): Object3D = when (obj) { is ThreeJsVision -> obj.render(this) - is SolidReferenceGroup -> ThreeReferenceFactory(this, obj) + is SolidReferenceGroup -> ThreeReferenceFactory.build(this, obj) is SolidGroup -> { val group = ThreeGroup() - obj.children.forEach { (token, child) -> + obj.items.forEach { (token, child) -> if (child is Solid && token != SolidGroup.PROTOTYPES_TOKEN && child.ignore != true) { try { val object3D = buildObject3D(child) @@ -101,13 +100,13 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { } } } - is Composite -> compositeFactory(this, obj) + is Composite -> compositeFactory.build(this, obj) else -> { //find specialized factory for this type if it is present val factory: ThreeFactory? = findObjectFactory(obj::class) when { - factory != null -> factory(this, obj) - obj is GeometrySolid -> ThreeShapeFactory(this, obj) + factory != null -> factory.build(this, obj) + obj is GeometrySolid -> ThreeShapeFactory.build(this, obj) else -> error("Renderer for ${obj::class} not found") } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt index 727aa098..e6c84c94 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt @@ -11,17 +11,19 @@ import kotlin.reflect.KClass public object ThreePointLightFactory : ThreeFactory { override val type: KClass get() = PointLightSource::class - override fun invoke(three: ThreePlugin, obj: PointLightSource): PointLight { + private val DEFAULT_COLOR = Color(0x404040) + + override fun build(three: ThreePlugin, obj: PointLightSource): PointLight { val res = PointLight().apply { matrixAutoUpdate = false - color = obj.color.threeColor() ?: Color(0x404040) + color = obj.color.threeColor() ?: DEFAULT_COLOR intensity = obj.intensity.toDouble() updatePosition(obj) } obj.onPropertyChange { name -> when (name) { - LightSource::color.name.asName() -> res.color = obj.color.threeColor() ?: Color(0x404040) + LightSource::color.name.asName() -> res.color = obj.color.threeColor() ?: DEFAULT_COLOR LightSource::intensity.name.asName() -> res.intensity = obj.intensity.toDouble() else -> res.updateProperty(obj, name) } @@ -29,4 +31,5 @@ public object ThreePointLightFactory : ThreeFactory { return res } + } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index aa779e46..8e667dcb 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -30,7 +30,7 @@ public object ThreeReferenceFactory : ThreeFactory { } } - override fun invoke(three: ThreePlugin, obj: SolidReferenceGroup): Object3D { + override fun build(three: ThreePlugin, obj: SolidReferenceGroup): Object3D { val template = obj.prototype val cachedObject = cache.getOrPut(template) { three.buildObject3D(template) @@ -50,7 +50,7 @@ public object ThreeReferenceFactory : ThreeFactory { if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'") val propertyName = name.cutFirst() - val referenceChild = obj[childName] ?: error("Reference child with name '$childName' not found") + val referenceChild = obj.children[childName] ?: error("Reference child with name '$childName' not found") val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") child.updateProperty(referenceChild, propertyName) } else { From 9b1ca8332b4825b35d66752ac3cdac708bca6958 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 7 Aug 2022 20:33:05 +0300 Subject: [PATCH 010/112] [WIP] great refactoring in progress --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 3 +- .../visionforge/gdml/GDMLVisionTest.kt | 1 - .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 4 +- .../visionforge/solid/demo/VariableBox.kt | 2 +- .../kscience/visionforge/AbstractVision.kt | 140 ++++++------ .../space/kscience/visionforge/StyleSheet.kt | 18 +- .../space/kscience/visionforge/Vision.kt | 157 +------------ .../kscience/visionforge/VisionChange.kt | 12 +- .../kscience/visionforge/VisionContainer.kt | 30 +-- .../space/kscience/visionforge/VisionGroup.kt | 47 +++- .../kscience/visionforge/VisionManager.kt | 8 +- .../kscience/visionforge/VisionProperties.kt | 208 +++++++++++++++--- .../visionforge/VisionPropertyContainer.kt | 29 --- .../visionforge/html/VisionOfHtmlForm.kt | 3 +- .../visionforge/html/VisionOfHtmlInput.kt | 19 +- .../kscience/visionforge/visionDelegates.kt | 91 -------- .../visionforge/visitor/VisionVisitor.kt | 5 +- .../kscience/visionforge/html/HtmlTagTest.kt | 11 +- .../visionforge/meta/VisionPropertyTest.kt | 44 ++-- .../editor/VisionEditorFragment.kt | 1 - .../kscience/visionforge/solid/FX3DPlugin.kt | 3 +- .../solid/VisualObjectFXBinding.kt | 1 - .../kscience/visionforge/gdml/markLayers.kt | 2 +- .../visionforge/plotly/VisionOfPlotly.kt | 5 +- .../visionforge/solid/ColorAccessor.kt | 4 +- .../kscience/visionforge/solid/Composite.kt | 15 +- .../kscience/visionforge/solid/ConeSegment.kt | 8 +- .../kscience/visionforge/solid/ConeSurface.kt | 9 +- .../kscience/visionforge/solid/Convex.kt | 11 +- .../kscience/visionforge/solid/Extruded.kt | 13 +- .../kscience/visionforge/solid/Hexagon.kt | 10 +- .../kscience/visionforge/solid/LightSource.kt | 9 +- .../kscience/visionforge/solid/PolyLine.kt | 16 +- .../space/kscience/visionforge/solid/Solid.kt | 30 +-- .../kscience/visionforge/solid/SolidBase.kt | 15 +- .../kscience/visionforge/solid/SolidGroup.kt | 10 +- .../kscience/visionforge/solid/SolidLabel.kt | 7 +- .../visionforge/solid/SolidMaterial.kt | 12 +- .../visionforge/solid/SolidReference.kt | 198 ++++++++++------- .../kscience/visionforge/solid/Solids.kt | 5 +- .../kscience/visionforge/solid/Sphere.kt | 9 +- .../kscience/visionforge/solid/SphereLayer.kt | 6 +- .../solid/transform/RemoveSingleChild.kt | 4 +- .../visionforge/solid/PropertyTest.kt | 11 +- .../visionforge/solid/SerializationTest.kt | 4 +- .../visionforge/tables/VisionOfTable.kt | 10 +- .../solid/three/MeshThreeFactory.kt | 1 - .../solid/three/ThreeCanvasLabelFactory.kt | 3 +- .../solid/three/ThreeLineFactory.kt | 3 +- 49 files changed, 598 insertions(+), 669 deletions(-) delete mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt delete mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index fbeb84dd..8cc4c258 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -3,7 +3,6 @@ package ru.mipt.npm.root import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int -import space.kscience.dataforge.meta.isEmpty import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.doubleArray @@ -322,7 +321,7 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? } return if (group.children.isEmpty()) { null - } else if (group.items.size == 1 && group.meta.isEmpty()) { + } else if (group.items.size == 1 && group.meta== null) { group.items.values.first().apply { parent = null } } else { group diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index afb23f16..c46f49ff 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -6,7 +6,6 @@ import space.kscience.dataforge.values.asValue import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Vision import space.kscience.visionforge.get -import space.kscience.visionforge.getProperty import space.kscience.visionforge.getPropertyValue import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 596b11dd..dff6da3f 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -3,7 +3,7 @@ package ru.mipt.npm.muon.monitor import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.LOWER_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.UPPER_LAYER_Z -import space.kscience.visionforge.VisionContainerBuilder +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionManager import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.* @@ -14,7 +14,7 @@ class Model(val manager: VisionManager) { private val map = HashMap() private val events = HashSet() - private fun VisionContainerBuilder.pixel(pixel: SC1) { + private fun MutableVisionContainer.pixel(pixel: SC1) { val group = group(pixel.name) { position = Point3D(pixel.center.x, pixel.center.y, pixel.center.z) box(pixel.xSize, pixel.ySize, pixel.zSize) diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index 84a164c8..d429cafb 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -49,7 +49,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision onPropertyChange { name -> when { name == VALUE -> { - val value = meta.get(VALUE).int ?: 0 + val value = meta[VALUE].int ?: 0 val size = value.toFloat() / 255f * 20f mesh.scale.z = size.toDouble() mesh.position.z = size.toDouble() / 2 diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt index c6cba1ba..f6b38880 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt @@ -3,101 +3,105 @@ package space.kscience.visionforge import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch -import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName import kotlinx.serialization.Transient -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.asMutableMeta +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.values.Value -import space.kscience.visionforge.VisionGroup.Companion.updateProperties +import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import kotlin.jvm.Synchronized -@Serializable + public abstract class AbstractVision : Vision { @Transient override var parent: Vision? = null - protected var properties: MutableMeta? = null - - override val meta: Meta get() = properties ?: Meta.EMPTY + @SerialName("properties") + internal var _properties: MutableMeta? = null - @Synchronized - private fun getOrCreateProperties(): MutableMeta { - if (properties == null) { - //TODO check performance issues - val newProperties = MutableMeta() - properties = newProperties - } - return properties!! - } + protected open val defaultProperties: Meta? get() = descriptor?.defaultNode @Transient - private val _propertyChanges = MutableSharedFlow() - override val propertyChanges: SharedFlow get() = _propertyChanges - - override fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): Value? { - properties?.get(name)?.value?.let { return it } - if (includeStyles) { - getStyleProperty(name)?.value?.let { return it } + final override val properties: MutableVisionProperties = object : MutableVisionProperties { + override val descriptor: MetaDescriptor? get() = this@AbstractVision.descriptor + override val default: Meta? get() = defaultProperties + + @Synchronized + private fun getOrCreateProperties(): MutableMeta { + if (_properties == null) { + //TODO check performance issues + val newProperties = MutableMeta() + _properties = newProperties + } + return _properties!! } - if (inherit) { - parent?.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } + + override val raw: Meta? get() = _properties + + override fun getValue( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + ): Value? { + raw?.get(name)?.value?.let { return it } + if (includeStyles) { + getStyleProperty(name)?.value?.let { return it } + } + if (inherit) { + parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } + } + return default?.get(name)?.value } - if (includeDefaults) { - descriptor?.defaultNode?.get(name)?.value?.let { return it } + + override fun set(name: Name, node: Meta?) { + //TODO check old value? + if (name.isEmpty()) { + _properties = node?.asMutableMeta() + } else if (node == null) { + _properties?.setMeta(name, node) + } else { + getOrCreateProperties().setMeta(name, node) + } + invalidate(name) } - return null - } - override fun setProperty(name: Name, node: Meta?) { - //TODO check old value? - if (name.isEmpty()) { - properties = node?.asMutableMeta() - } else if (node == null) { - properties?.setMeta(name, node) - } else { - getOrCreateProperties().setMeta(name, node) + override fun setValue(name: Name, value: Value?) { + //TODO check old value? + if (value == null) { + _properties?.getMeta(name)?.value = null + } else { + getOrCreateProperties().setValue(name, value) + } + invalidate(name) } - invalidateProperty(name) - } - override fun setPropertyValue(name: Name, value: Value?) { - //TODO check old value? - if (value == null) { - properties?.getMeta(name)?.value = null - } else { - getOrCreateProperties().setValue(name, value) + @Transient + private val _changes = MutableSharedFlow() + override val changes: SharedFlow get() = _changes + + override fun invalidate(propertyName: Name) { + if (propertyName == Vision.STYLE_KEY) { + styles.asSequence() + .mapNotNull { getStyle(it) } + .flatMap { it.items.asSequence() } + .distinctBy { it.key } + .forEach { + invalidate(it.key.asName()) + } + } + manager.context.launch { + _changes.emit(propertyName) + } } - invalidateProperty(name) + } override val descriptor: MetaDescriptor? get() = null - override fun invalidateProperty(propertyName: Name) { - if (propertyName == Vision.STYLE_KEY) { - styles.asSequence() - .mapNotNull { getStyle(it) } - .flatMap { it.items.asSequence() } - .distinctBy { it.key } - .forEach { - invalidateProperty(it.key.asName()) - } - } - manager.context.launch { - _propertyChanges.emit(propertyName) - } - } override fun update(change: VisionChange) { change.properties?.let { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index cc465d87..aed19706 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -15,7 +15,7 @@ import kotlin.jvm.JvmInline @JvmInline public value class StyleSheet(private val owner: Vision) { - private val styleNode: Meta get() = owner.getProperty(STYLESHEET_KEY) + private val styleNode: Meta get() = owner.properties[STYLESHEET_KEY] public val items: Map get() = styleNode.items @@ -25,7 +25,7 @@ public value class StyleSheet(private val owner: Vision) { * Define a style without notifying owner */ public fun define(key: String, style: Meta?) { - owner.setProperty(STYLESHEET_KEY + key, style) + owner.properties[STYLESHEET_KEY + key] = style } /** @@ -58,26 +58,24 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) val tokens: Collection = ((oldStyle?.items?.keys ?: emptySet()) + (newStyle?.items?.keys ?: emptySet())) .map { it.asName() } - tokens.forEach { parent?.invalidateProperty(it) } + tokens.forEach { parent?.properties?.invalidate(it) } } - children.values.forEach { vision -> + children?.forEach { _, vision -> vision.styleChanged(key, oldStyle, newStyle) } } - /** * List of names of styles applied to this object. Order matters. Not inherited. */ public var Vision.styles: List - get() = getPropertyValue( + get() = properties.getValue( Vision.STYLE_KEY, inherit = true, includeStyles = false, - includeDefaults = false )?.stringList ?: emptyList() set(value) { - setPropertyValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue()) + properties.setValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue()) } /** @@ -90,7 +88,7 @@ public val Vision.styleSheet: StyleSheet get() = StyleSheet(this) * Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment. */ public fun Vision.useStyle(name: String) { - styles = (getPropertyValue(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name + styles = (properties.getValue(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name } @@ -98,7 +96,7 @@ public fun Vision.useStyle(name: String) { * Resolve a style with given name for given [Vision]. The style is not necessarily applied to this [Vision]. */ public fun Vision.getStyle(name: String): Meta? = - meta.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) + properties.raw?.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) /** * Resolve a property from all styles diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index b25f200c..e538b226 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -1,22 +1,15 @@ package space.kscience.visionforge import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import space.kscience.dataforge.context.Global -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.MutableMetaProvider import space.kscience.dataforge.meta.descriptors.Described import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.asValue import space.kscience.dataforge.values.boolean import space.kscience.visionforge.Vision.Companion.TYPE @@ -38,49 +31,8 @@ public interface Vision : Described { */ public val manager: VisionManager get() = parent?.manager ?: Global.visionManager - public val children: VisionChildren - /** - * Own properties without inheritance or styles. - */ - public val meta: Meta - - public fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): Value? - - /** - * Get property with given layer flags. - * @param inherit toggles parent node property lookup. Null means inference from descriptor. - * @param includeStyles toggles inclusion of properties from styles. - */ - public fun getProperty( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): MutableMeta = VisionProperties(this, name, descriptor?.get(name), inherit, includeStyles) - - public fun setProperty( - name: Name, - node: Meta?, - ) - - public fun setPropertyValue( - name: Name, - value: Value?, - ) - - public val propertyChanges: SharedFlow - - /** - * Notify all listeners that a property has been changed and should be invalidated. - * This method does not check that the property has actually changed. - */ - public fun invalidateProperty(propertyName: Name) + public val properties: MutableVisionProperties /** * Update this vision using a dif represented by [VisionChange]. @@ -98,108 +50,19 @@ public interface Vision : Described { } } -public fun Vision.getPropertyValue( - name: Name, - inherit: Boolean? = null, - includeStyles: Boolean? = null, - includeDefaults: Boolean = true, - metaDescriptor: MetaDescriptor? = descriptor?.get(name), -): Value? { - val inheritFlag = inherit ?: metaDescriptor?.inherited ?: false - val stylesFlag = includeStyles ?: metaDescriptor?.usesStyles ?: true - return getPropertyValue(name, inheritFlag, stylesFlag, includeDefaults) -} - -public fun Vision.getPropertyValue( - name: String, - inherit: Boolean? = null, - includeStyles: Boolean? = null, - includeDefaults: Boolean = true, - metaDescriptor: MetaDescriptor? = descriptor?.get(name), -): Value? = getPropertyValue(name.parseAsName(), inherit, includeStyles, includeDefaults, metaDescriptor) - -/** - * Compute the property based on the provided value descriptor. By default, use Vision own descriptor - */ -public fun Vision.getProperty( - name: Name, - inherit: Boolean? = null, - includeStyles: Boolean? = null, - includeDefaults: Boolean = true, - metaDescriptor: MetaDescriptor? = descriptor?.get(name), -): MutableMeta { - val inheritFlag = inherit ?: metaDescriptor?.inherited ?: false - val stylesFlag = includeStyles ?: metaDescriptor?.usesStyles ?: true - return getProperty(name, inheritFlag, stylesFlag, includeDefaults) -} - - -/** - * Get [Vision] property using key as a String - */ -public fun Vision.getProperty( - name: String, - inherit: Boolean? = null, - includeStyles: Boolean? = null, - includeDefaults: Boolean = true, - metaDescriptor: MetaDescriptor? = descriptor?.get(name), -): MutableMeta = getProperty(name.parseAsName(), inherit, includeStyles, includeDefaults, metaDescriptor) - - -/** - * Vision's own non-inheritable, non-styleable properties - */ -public fun Vision.properties( - inherit: Boolean? = null, - useStyles: Boolean? = null, -): MutableMetaProvider = VisionProperties(this, Name.EMPTY, inherit = inherit, useStyles = useStyles) - -public fun Vision.setPropertyValue(name: Name, value: Number?) { - if (value == null) { - setPropertyValue(name, null) - } else { - setPropertyValue(name, value.asValue()) - } -} - -public fun Vision.setPropertyValue(name: String, value: Number?): Unit = - setPropertyValue(name.parseAsName(), value) - -public fun Vision.setPropertyValue(name: Name, value: Boolean?) { - if (value == null) { - setPropertyValue(name, null) - } else { - setPropertyValue(name, value.asValue()) - } -} - -public fun Vision.setPropertyValue(name: String, value: Boolean?): Unit = - setPropertyValue(name.parseAsName(), value) - -public fun Vision.setPropertyValue(name: Name, value: String?) { - if (value == null) { - setPropertyValue(name, null) - } else { - setPropertyValue(name, value.asValue()) - } -} - -public fun Vision.setPropertyValue(name: String, value: String?): Unit = - setPropertyValue(name.parseAsName(), value) - /** * Control visibility of the element */ public var Vision.visible: Boolean? - get() = getPropertyValue(Vision.VISIBLE_KEY)?.boolean + get() = properties.getValue(Vision.VISIBLE_KEY)?.boolean set(value) { - setPropertyValue(Vision.VISIBLE_KEY, value) + properties.setValue(Vision.VISIBLE_KEY, value?.asValue()) } /** * Subscribe on property updates. The subscription is bound to the given scope and canceled when the scope is canceled */ -public fun Vision.onPropertyChange(callback: (Name) -> Unit): Job = propertyChanges.onEach { +public fun Vision.onPropertyChange(callback: (Name) -> Unit): Job = properties.changes.onEach { callback(it) }.launchIn(manager.context) @@ -210,17 +73,9 @@ public fun V.useProperty( ): Job { //Pass initial value. callBack(property.get(this)) - return propertyChanges.onEach { name -> + return properties.changes.onEach { name -> if (name.startsWith(property.name.asName())) { callBack(property.get(this@useProperty)) } }.launchIn(manager.context) -} - - -public interface MutableVisionGroup : Vision { - - override val children: MutableVisionChildren - - public fun createGroup(): MutableVisionGroup -} +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index abea638a..a4667b2f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -26,7 +26,7 @@ private fun Vision.deepCopy(): Vision { /** * An update for a [Vision] */ -public class VisionChangeBuilder : VisionContainerBuilder { +public class VisionChangeBuilder : MutableVisionContainer { private var reset: Boolean = false private var vision: Vision? = null @@ -77,7 +77,7 @@ public class VisionChangeBuilder : VisionContainerBuilder { public data class VisionChange( public val delete: Boolean = false, public val vision: Vision? = null, - @Serializable(MetaSerializer::class) public val properties: Meta? = null, + public val properties: Meta? = null, public val children: Map? = null, ) @@ -93,25 +93,25 @@ private fun CoroutineScope.collectChange( //Collect properties change source.onPropertyChange { propertyName -> - val newItem = source.getProperty(propertyName, false, false, false) + val newItem = source.properties.raw?.get(propertyName) collector().propertyChanged(name, propertyName, newItem) } val children = source.children //Subscribe for children changes - for ((token, child) in children) { + children?.forEach { token, child -> collectChange(name + token, child, collector) } //Subscribe for structure change - children.changes.onEach { changedName -> + children?.changes?.onEach { changedName -> val after = children[changedName] val fullName = name + changedName if (after != null) { collectChange(fullName, after, collector) } collector()[fullName] = after - }.launchIn(this) + }?.launchIn(this) } /** diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index f7056d59..81f7d9da 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -19,7 +19,7 @@ public interface VisionContainer { public operator fun get(name: Name): V? } -public interface VisionContainerBuilder { +public interface MutableVisionContainer { //TODO add documentation public operator fun set(name: Name?, child: V?) } @@ -28,7 +28,7 @@ public interface VisionContainerBuilder { * A serializable representation of [Vision] children container */ public interface VisionChildren : VisionContainer { - public val parent: Vision? + public val group: Vision? public val keys: Set @@ -39,14 +39,14 @@ public interface VisionChildren : VisionContainer { public operator fun get(token: NameToken): Vision? override fun get(name: Name): Vision? = when (name.length) { - 0 -> parent + 0 -> group 1 -> get(name.first()) else -> get(name.first())?.children?.get(name.cutFirst()) } public companion object { public fun empty(owner: Vision): VisionChildren = object : VisionChildren { - override val parent: Vision get() = owner + override val group: Vision get() = owner override val keys: Set get() = emptySet() override val changes: Flow get() = emptyFlow() override fun get(token: NameToken): Vision? = null @@ -56,9 +56,13 @@ public interface VisionChildren : VisionContainer { public fun VisionChildren.isEmpty(): Boolean = keys.isEmpty() +public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) { + keys.forEach { block(it, get(it)!!) } +} + @Serializable(VisionChildrenContainerSerializer::class) -public interface MutableVisionChildren : VisionChildren, VisionContainerBuilder { - public override val parent: MutableVisionGroup? +public interface MutableVisionChildren : VisionChildren, MutableVisionContainer { + public override val group: MutableVisionGroup? public operator fun set(token: NameToken, value: Vision?) @@ -79,7 +83,7 @@ public interface MutableVisionChildren : VisionChildren, VisionContainerBuilder< else -> { val currentParent = get(name.first()) if (currentParent != null && currentParent !is MutableVisionGroup) error("Can't assign a child to $currentParent") - val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: parent?.createGroup().also { + val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group?.createGroup().also { set(name.first(), it) } ?: error("Container owner not set") parent.children[name.cutFirst()] = child @@ -105,7 +109,7 @@ public operator fun VisionChildren.iterator(): Iterator> public operator fun VisionContainer.get(str: String): V? = get(Name.parse(str)) -public operator fun VisionContainerBuilder.set( +public operator fun MutableVisionContainer.set( str: String?, vision: V?, ): Unit = set(str?.parseAsName(), vision) @@ -113,13 +117,13 @@ internal class VisionChildrenImpl( items: Map, ) : MutableVisionChildren { - override var parent: MutableVisionGroup? = null + override var group: MutableVisionGroup? = null internal set private val items = LinkedHashMap(items) private val updateJobs = HashMap() - private val scope: CoroutineScope? get() = parent?.manager?.context + private val scope: CoroutineScope? get() = group?.manager?.context override val keys: Set get() = items.keys @@ -149,9 +153,9 @@ internal class VisionChildrenImpl( } else { items[token] = value //check if parent already exists and is different from the current one - if (value.parent != null && value.parent != parent) error("Can't reassign parent Vision for $value") + if (value.parent != null && value.parent != group) error("Can't reassign parent Vision for $value") //set parent - value.parent = parent + value.parent = group //start update jobs (only if the vision is rooted) scope?.let { scope -> val job = (value.children as? VisionChildrenImpl)?.changes?.onEach { @@ -179,7 +183,7 @@ internal class VisionChildrenImpl( } internal object VisionChildrenContainerSerializer : KSerializer { - private val mapSerializer = serializer>() + private val mapSerializer = serializer>() override val descriptor: SerialDescriptor = mapSerializer.descriptor diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index 3c843b85..f87650a7 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -13,20 +13,33 @@ import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.Vision.Companion.STYLE_KEY +import kotlin.js.JsName import kotlin.jvm.Synchronized + +public interface VisionGroup : Vision { + public val children: VisionChildren +} + +public interface MutableVisionGroup : VisionGroup { + + override val children: MutableVisionChildren + + public fun createGroup(): MutableVisionGroup +} + +public val Vision.children: VisionChildren? get() = (this as? VisionGroup)?.children + /** * A full base implementation for a [Vision] */ -@Serializable -@SerialName("vision.group") -public open class VisionGroup : AbstractVision(), MutableVisionGroup { +public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { override fun update(change: VisionChange) { change.children?.forEach { (name, change) -> when { - change.delete -> children.set(name, null) - change.vision != null -> children.set(name, change.vision) + change.delete -> children[name] = null + change.vision != null -> children[name] = change.vision else -> children[name]?.update(change) } } @@ -45,13 +58,13 @@ public open class VisionGroup : AbstractVision(), MutableVisionGroup { fun getOrCreateChildren(): MutableVisionChildren { if (_children == null) { _children = VisionChildrenImpl(emptyMap()).apply { - parent = this@VisionGroup + group = this@AbstractVisionGroup } } return _children!! } - override val parent: MutableVisionGroup get() = this@VisionGroup + override val group: MutableVisionGroup get() = this@AbstractVisionGroup override val keys: Set get() = _children?.keys ?: emptySet() override val changes: Flow get() = _children?.changes ?: emptyFlow() @@ -71,7 +84,7 @@ public open class VisionGroup : AbstractVision(), MutableVisionGroup { } } - override fun createGroup(): VisionGroup = VisionGroup() + abstract override fun createGroup(): AbstractVisionGroup public companion object { public val descriptor: MetaDescriptor = MetaDescriptor { @@ -80,16 +93,28 @@ public open class VisionGroup : AbstractVision(), MutableVisionGroup { } } - public fun Vision.updateProperties(item: Meta, at: Name = Name.EMPTY) { - setPropertyValue(at, item.value) + public fun Vision.updateProperties(item: Meta, name: Name = Name.EMPTY) { + properties.setValue(name, item.value) item.items.forEach { (token, item) -> - updateProperties(item, at + token) + updateProperties(item, name + token) } } } } +/** + * A simple vision group that just holds children. Nothing else. + */ +@Serializable +@SerialName("vision.group") +public class SimpleVisionGroup : AbstractVisionGroup() { + override fun createGroup(): SimpleVisionGroup = SimpleVisionGroup() +} + +@JsName("createVisionGroup") +public fun VisionGroup(): VisionGroup = SimpleVisionGroup() + //fun VisualObject.findStyle(styleName: Name): Meta? { // if (this is VisualGroup) { // val style = resolveStyle(styleName) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index a11ad358..3428dd33 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -68,8 +68,8 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) { private val defaultSerialModule: SerializersModule = SerializersModule { polymorphic(Vision::class) { - default { VisionGroup.serializer() } - subclass(VisionGroup.serializer()) + default { SimpleVisionGroup.serializer() } + subclass(SimpleVisionGroup.serializer()) subclass(VisionOfNumberField.serializer()) subclass(VisionOfTextField.serializer()) subclass(VisionOfCheckbox.serializer()) @@ -112,7 +112,9 @@ public fun Vision.encodeToString(): String = manager.encodeToString(this) /** * A root vision attached to [VisionManager] */ -public class RootVision(override val manager: VisionManager) : VisionGroup() +public class RootVision(override val manager: VisionManager) : AbstractVisionGroup() { + override fun createGroup(): SimpleVisionGroup = SimpleVisionGroup() +} /** * Designate this [Vision] as a root and assign a [VisionManager] as its parent diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 140170d3..b4ca16ec 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -1,40 +1,104 @@ package space.kscience.visionforge +import kotlinx.coroutines.flow.Flow import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.Value +import space.kscience.dataforge.values.asValue -/** - * A wrapper that emulates delegates reading and writing properties to Vision method - */ -internal class VisionProperties( - val vision: Vision, +public interface VisionProperties { + + /** + * Raw Visions own properties without styles, defaults, etc. + */ + public val raw: Meta? + + public val descriptor: MetaDescriptor? + public val default: Meta? + + public fun getValue( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + ): Value? + + /** + * Get property with given layer flags. + * @param inherit toggles parent node property lookup. Null means inference from descriptor. + * @param includeStyles toggles inclusion of properties from styles. + */ + public operator fun get( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + ): Meta + + public val changes: Flow + + /** + * Notify all listeners that a property has been changed and should be invalidated. + * This method does not check that the property has actually changed. + */ + public fun invalidate(propertyName: Name) +} + +public interface MutableVisionProperties : VisionProperties { + + override operator fun get( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + ): MutableMeta = VisionPropertiesItem( + this, + name, + inherit, + includeStyles, + ) + + + public operator fun set( + name: Name, + node: Meta?, + ) + + public fun setValue( + name: Name, + value: Value?, + ) +} + +private class VisionPropertiesItem( + val properties: MutableVisionProperties, val nodeName: Name, - val visionDescriptor: MetaDescriptor? = vision.descriptor, val inherit: Boolean? = null, val useStyles: Boolean? = null, + val default: Meta? = null, ) : MutableMeta { - val descriptor: MetaDescriptor? by lazy { visionDescriptor?.get(nodeName) } + val descriptor: MetaDescriptor? by lazy { properties.descriptor?.get(nodeName) } + override val items: Map get() { - val metaKeys = vision.meta.getMeta(nodeName)?.items?.keys ?: emptySet() + val metaKeys = properties.raw?.getMeta(nodeName)?.items?.keys ?: emptySet() val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet() + val defaultKeys = default?.get(nodeName)?.items?.keys ?: emptySet() val inheritFlag = descriptor?.inherited ?: inherit val stylesFlag = descriptor?.usesStyles ?: useStyles - return (metaKeys + descriptorKeys).associateWith { - VisionProperties( - vision, + return (metaKeys + descriptorKeys + defaultKeys).associateWith { + VisionPropertiesItem( + properties, nodeName + it, - visionDescriptor, inheritFlag, - stylesFlag + stylesFlag, + default ) } } @@ -43,22 +107,22 @@ internal class VisionProperties( get() { val inheritFlag = descriptor?.inherited ?: inherit ?: false val stylesFlag = descriptor?.usesStyles ?: useStyles ?: true - return vision.getPropertyValue(nodeName, inheritFlag, stylesFlag, true) + return properties.getValue(nodeName, inheritFlag, stylesFlag) ?: default?.getValue(nodeName) } set(value) { - vision.setPropertyValue(nodeName, value) + properties.setValue(nodeName, value) } - override fun getOrCreate(name: Name): MutableMeta = VisionProperties( - vision, + override fun getOrCreate(name: Name): MutableMeta = VisionPropertiesItem( + properties, nodeName + name, - visionDescriptor, inherit, - useStyles + useStyles, + default ) override fun setMeta(name: Name, node: Meta?) { - vision.setProperty(nodeName + name, node) + properties[nodeName + name] = node } override fun toString(): String = Meta.toString(this) @@ -66,16 +130,96 @@ internal class VisionProperties( override fun hashCode(): Int = Meta.hashCode(this) } -///** -// * Accessor to all vision properties -// */ -//public fun Vision.computePropertyValues( -// descriptor: MetaDescriptor? = this.descriptor, -//): MutableValueProvider = object : MutableValueProvider { -// override fun getValue(name: Name): Value? = computeProperty(name, descriptor?.get(name))?.value -// -// override fun setValue(name: Name, value: Value?) { -// setProperty(name, value) -// } -//} +public fun VisionProperties.getValue( + name: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Value? { + val descriptor = descriptor?.get(name) + val inheritFlag = inherit ?: descriptor?.inherited ?: false + val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true + return getValue(name, inheritFlag, stylesFlag) +} + +public fun VisionProperties.getValue( + name: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Value? = getValue(name.parseAsName(), inherit, includeStyles) + +/** + * Compute the property based on the provided value descriptor. By default, use Vision own descriptor + */ +public operator fun VisionProperties.get( + name: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Meta { + val descriptor: MetaDescriptor? = descriptor?.get(name) + val inheritFlag = inherit ?: descriptor?.inherited ?: false + val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true + return get(name, inheritFlag, stylesFlag) +} + + +/** + * Get [Vision] property using key as a String + */ +public operator fun VisionProperties.get( + name: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Meta = get(name.parseAsName(), inherit, includeStyles) + + +/** + * Compute the property based on the provided value descriptor. By default, use Vision own descriptor + */ +public operator fun MutableVisionProperties.get( + name: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): MutableMeta { + val descriptor: MetaDescriptor? = descriptor?.get(name) + val inheritFlag = inherit ?: descriptor?.inherited ?: false + val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true + return get(name, inheritFlag, stylesFlag) +} + +/** + * The root property node with given inheritance and style flags + */ +public fun MutableVisionProperties.root( + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): MutableMeta = get(Name.EMPTY, inherit, includeStyles) + + +/** + * Get [Vision] property using key as a String + */ +public operator fun MutableVisionProperties.get( + name: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): MutableMeta = get(name.parseAsName(), inherit, includeStyles) + + +public operator fun MutableVisionProperties.set(name: Name, value: Number): Unit = + setValue(name, value.asValue()) + +public operator fun MutableVisionProperties.set(name: String, value: Number): Unit = + set(name.parseAsName(), value) + +public operator fun MutableVisionProperties.set(name: Name, value: Boolean): Unit = + setValue(name, value.asValue()) + +public operator fun MutableVisionProperties.set(name: String, value: Boolean): Unit = + set(name.parseAsName(), value) + +public operator fun MutableVisionProperties.set(name: Name, value: String): Unit = + setValue(name, value.asValue()) + +public operator fun MutableVisionProperties.set(name: String, value: String): Unit = + set(name.parseAsName(), value) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt deleted file mode 100644 index 83b6c93c..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt +++ /dev/null @@ -1,29 +0,0 @@ -package space.kscience.visionforge - -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.names.Name - -/** - * Property containers are used to create a symmetric behaviors for vision properties and style builders - */ -public interface VisionPropertyContainer { - - public fun getProperty( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): Meta? -} - -public open class SimpleVisionPropertyContainer( - public val meta: MutableMeta, -) : VisionPropertyContainer { - override fun getProperty( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): Meta? = meta.getMeta(name) -} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt index 82e59c2c..4315066a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt @@ -9,14 +9,13 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.node -import space.kscience.visionforge.properties @Serializable @SerialName("html.form") public class VisionOfHtmlForm( public val formId: String, ) : VisionOfHtmlInput() { - public var values: Meta? by properties().node() + public var values: Meta? by mutableProperties.node() } public class HtmlFormFragment internal constructor( diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt index 34f49027..19106240 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt @@ -5,12 +5,15 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.number import space.kscience.dataforge.meta.string -import space.kscience.visionforge.VisionGroup -import space.kscience.visionforge.properties +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.* + +//TODO replace by something +internal val Vision.mutableProperties get() = properties[Name.EMPTY, false, false] @Serializable -public abstract class VisionOfHtmlInput : VisionGroup() { - public var disabled: Boolean by properties().boolean(false) +public abstract class VisionOfHtmlInput : AbstractVision() { + public var disabled: Boolean by mutableProperties.boolean { false } } @Serializable @@ -19,7 +22,7 @@ public class VisionOfTextField( public val label: String? = null, public val name: String? = null, ) : VisionOfHtmlInput() { - public var text: String? by properties().string() + public var text: String? by mutableProperties.string() } @Serializable @@ -28,7 +31,7 @@ public class VisionOfCheckbox( public val label: String? = null, public val name: String? = null, ) : VisionOfHtmlInput() { - public var checked: Boolean? by properties().boolean() + public var checked: Boolean? by mutableProperties.boolean() } @Serializable @@ -37,7 +40,7 @@ public class VisionOfNumberField( public val label: String? = null, public val name: String? = null, ) : VisionOfHtmlInput() { - public var value: Number? by properties().number() + public var value: Number? by mutableProperties.number() } @Serializable @@ -49,6 +52,6 @@ public class VisionOfRangeField( public val label: String? = null, public val name: String? = null, ) : VisionOfHtmlInput() { - public var value: Number? by properties().number() + public var value: Number? by mutableProperties.number() } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt deleted file mode 100644 index 185c98a9..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt +++ /dev/null @@ -1,91 +0,0 @@ -package space.kscience.visionforge - -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.number -import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KProperty - -//public fun Vision.propertyNode( -// name: Name? = null, -// inherit: Boolean = false, -// includeStyles: Boolean = true, -// includeDefaults: Boolean = true, -//): ReadWriteProperty = object : ReadWriteProperty { -// override fun getValue(thisRef: Any?, property: KProperty<*>): Meta? = -// getProperty(name ?: Name.parse(property.name), inherit, includeStyles, includeDefaults) -// -// override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta?) { -// meta.setMeta(name ?: Name.parse(property.name), value) -// } -//} -// -//public fun Vision.propertyNode( -// converter: MetaConverter, -// name: Name? = null, -// inherit: Boolean = false, -// includeStyles: Boolean = true, -// includeDefaults: Boolean = true, -//): ReadWriteProperty = object : ReadWriteProperty { -// override fun getValue(thisRef: Any?, property: KProperty<*>): T? = getProperty( -// name ?: Name.parse(property.name), -// inherit, -// includeStyles, -// includeDefaults -// )?.let(converter::metaToObject) -// -// override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { -// meta.setMeta(name ?: Name.parse(property.name), value?.let(converter::objectToMeta)) -// } -//} - -public fun Vision.propertyValue( - name: Name? = null, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, -): ReadWriteProperty = object : ReadWriteProperty { - override fun getValue(thisRef: Any?, property: KProperty<*>): Value? = - getPropertyValue(name ?: Name.parse(property.name), inherit, includeStyles, includeDefaults) - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: Value?) { - setPropertyValue(name ?: Name.parse(property.name), value) - } -} - -public fun Vision.propertyValue( - name: Name? = null, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, - setter: (T) -> Value? = { it?.let(Value::of) }, - getter: (Value?) -> T, -): ReadWriteProperty = object : ReadWriteProperty { - override fun getValue(thisRef: Any?, property: KProperty<*>): T = getPropertyValue( - name ?: Name.parse(property.name), - inherit, - includeStyles, - includeDefaults - ).let(getter) - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { - setPropertyValue(name ?: Name.parse(property.name), value?.let(setter)) - } -} - -public fun Vision.numberProperty( - name: Name? = null, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true -): ReadWriteProperty = propertyValue(name, inherit, includeStyles, includeDefaults) { it?.number } - -public fun Vision.numberProperty( - name: Name? = null, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, - default: () -> Number -): ReadWriteProperty = propertyValue(name, inherit, includeStyles, includeDefaults) { - it?.number ?: default() -} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt index 3ba313a9..4ceab3d9 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt @@ -6,7 +6,8 @@ import kotlinx.coroutines.launch import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus import space.kscience.visionforge.Vision -import space.kscience.visionforge.iterator +import space.kscience.visionforge.children +import space.kscience.visionforge.forEach public interface VisionVisitor { /** @@ -37,7 +38,7 @@ public interface VisionVisitor { visionVisitor.visitChildren(name, vision) - for ((token, child) in vision.children) { + vision.children?.forEach { token, child -> visitTreeAsync(visionVisitor, name + token, child) } } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index b7b8208d..d6128963 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -30,9 +30,10 @@ fun FlowContent.renderVisionFragment( @DFExperimental -class HtmlTagTest { +private fun VisionOutput.base(block: VisionGroup.() -> Unit) = VisionGroup().apply(block) - fun VisionOutput.base(block: VisionGroup.() -> Unit) = VisionGroup().apply(block) +@DFExperimental +class HtmlTagTest { val fragment: HtmlVisionFragment = { div { @@ -42,8 +43,8 @@ class HtmlTagTest { "metaProperty" put 87 } base { - setPropertyValue("myProp", 82) - setPropertyValue("otherProp", false) + properties["myProp"] = 82 + properties["otherProp"] = false } } } @@ -53,7 +54,7 @@ class HtmlTagTest { div { h2 { +"Properties" } ul { - vision.getProperty(Name.EMPTY).items.forEach { + vision.properties.raw?.items?.forEach { li { a { +it.key.toString() } p { +it.value.toString() } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 234d0043..f488bcf7 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -8,45 +8,47 @@ import space.kscience.dataforge.values.asValue import space.kscience.dataforge.values.boolean import space.kscience.dataforge.values.int import space.kscience.visionforge.VisionGroup -import space.kscience.visionforge.getProperty -import space.kscience.visionforge.getPropertyValue -import space.kscience.visionforge.setPropertyValue +import space.kscience.visionforge.get +import space.kscience.visionforge.getValue +import space.kscience.visionforge.set import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals -class VisionPropertyTest { + +private class TestScheme : Scheme() { + var ddd by int() + + companion object : SchemeSpec(::TestScheme) +} + +internal class VisionPropertyTest { @Test - fun testPropertyWrite(){ + fun testPropertyWrite() { val vision = VisionGroup() - vision.setPropertyValue("fff", 2) - vision.setPropertyValue("fff.ddd", false) + vision.properties["fff"] = 2 + vision.properties["fff.ddd"] = false - assertEquals(2, vision.getPropertyValue("fff")?.int) - assertEquals(false, vision.getPropertyValue("fff.ddd")?.boolean) + assertEquals(2, vision.properties.getValue("fff")?.int) + assertEquals(false, vision.properties.getValue("fff.ddd")?.boolean) } @Test - fun testPropertyEdit(){ + fun testPropertyEdit() { val vision = VisionGroup() - vision.getProperty("fff.ddd").apply { + vision.properties["fff.ddd"].apply { value = 2.asValue() } - assertEquals(2, vision.getPropertyValue("fff.ddd")?.int) - assertNotEquals(true, vision.getPropertyValue("fff.ddd")?.boolean) - } - - internal class TestScheme: Scheme(){ - var ddd by int() - companion object: SchemeSpec(::TestScheme) + assertEquals(2, vision.properties.getValue("fff.ddd")?.int) + assertNotEquals(true, vision.properties.getValue("fff.ddd")?.boolean) } @Test - fun testPropertyUpdate(){ + fun testPropertyUpdate() { val vision = VisionGroup() - vision.getProperty("fff").updateWith(TestScheme){ + vision.properties["fff"].updateWith(TestScheme) { ddd = 2 } - assertEquals(2, vision.getPropertyValue("fff.ddd")?.int) + assertEquals(2, vision.properties.getValue("fff.ddd")?.int) } } \ No newline at end of file diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt index 7b1299f4..0185dc43 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt @@ -9,7 +9,6 @@ import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision -import space.kscience.visionforge.getProperty import space.kscience.visionforge.getStyle import space.kscience.visionforge.styles import tornadofx.* diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt index cd45c6e1..90c94b35 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt @@ -16,7 +16,6 @@ import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.misc.Type -import space.kscience.visionforge.getProperty import space.kscience.visionforge.solid.FX3DFactory.Companion.TYPE import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_WIREFRAME_KEY @@ -77,7 +76,7 @@ public class FX3DPlugin : AbstractPlugin() { is PolyLine -> PolyLine3D( obj.points.map { Point3D(it.x, it.y, it.z) }, obj.thickness.toFloat(), - obj.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).color() + obj.get(SolidMaterial.MATERIAL_COLOR_KEY).color() ).apply { this.meshView.cullFace = CullFace.FRONT } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt index 680033d4..78d02164 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt @@ -7,7 +7,6 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.values.Value import space.kscience.visionforge.Vision -import space.kscience.visionforge.getProperty import space.kscience.visionforge.onPropertyChange import tornadofx.* diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt index afc6c99a..b2dbce57 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt @@ -76,7 +76,7 @@ public fun SolidGroup.markLayers(thresholds: List = listOf(500, 1000, 20000 node.vision.layer = layerIndex remaining -= node.selfCount * (node.children.size + 1) - logger?.apply { + logger.run { if (node.selfCount > 1) { info { "Prototype with name ${node.name} moved to layer $layerIndex. $remaining nodes remains" } } else { diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index 880a1961..732358bf 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -7,13 +7,12 @@ import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.plotly.Plot import space.kscience.plotly.Plotly -import space.kscience.visionforge.VisionGroup -import space.kscience.visionforge.getProperty +import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.html.VisionOutput @Serializable @SerialName("vision.plotly") -public class VisionOfPlotly private constructor() : VisionGroup() { +public class VisionOfPlotly private constructor() : AbstractVision() { public constructor(plot: Plot) : this() { setProperty(Name.EMPTY, plot.meta) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index 39b7e7b0..62a3b2a0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -7,7 +7,7 @@ import space.kscience.dataforge.values.* import space.kscience.visionforge.Colors import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.getProperty +import space.kscience.visionforge.root import kotlin.properties.ReadOnlyProperty @VisionBuilder @@ -29,7 +29,7 @@ public class ColorAccessor( } public fun Vision.color(): ReadOnlyProperty = ReadOnlyProperty { _, property -> - ColorAccessor(getProperty(Name.EMPTY), property.name.asName()) + ColorAccessor(properties.root(), property.name.asName()) } public var ColorAccessor?.string: String? diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index d300b06b..f30c641b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.isEmpty import space.kscience.dataforge.names.Name import space.kscience.visionforge.* @@ -19,10 +18,10 @@ public class Composite( public val compositeType: CompositeType, public val first: Solid, public val second: Solid, -) : SolidBase(), VisionPropertyContainer +) : SolidBase() @VisionBuilder -public inline fun VisionContainerBuilder.composite( +public inline fun MutableVisionContainer.composite( type: CompositeType, name: String? = null, @VisionBuilder builder: SolidGroup.() -> Unit, @@ -34,7 +33,7 @@ public inline fun VisionContainerBuilder.composite( } val res = Composite(type, children[0], children[1]) - res.setProperty(Name.EMPTY, group.getProperty(Name.EMPTY)) + res.properties[Name.EMPTY] = group.properties.raw set(name, res) return res @@ -50,7 +49,7 @@ public fun SolidGroup.smartComposite( @VisionBuilder builder: SolidGroup.() -> Unit, ): Solid = if (type == CompositeType.GROUP) { val group = SolidGroup(builder) - if (name == null && group.meta.isEmpty()) { + if (name == null && group.properties.raw == null) { //append directly to group if no properties are defined group.items.forEach { (_, value) -> value.parent = null @@ -66,19 +65,19 @@ public fun SolidGroup.smartComposite( } @VisionBuilder -public inline fun VisionContainerBuilder.union( +public inline fun MutableVisionContainer.union( name: String? = null, builder: SolidGroup.() -> Unit, ): Composite = composite(CompositeType.UNION, name, builder = builder) @VisionBuilder -public inline fun VisionContainerBuilder.subtract( +public inline fun MutableVisionContainer.subtract( name: String? = null, builder: SolidGroup.() -> Unit, ): Composite = composite(CompositeType.SUBTRACT, name, builder = builder) @VisionBuilder -public inline fun VisionContainerBuilder.intersect( +public inline fun MutableVisionContainer.intersect( name: String? = null, builder: SolidGroup.() -> Unit, ): Composite = composite(CompositeType.INTERSECT, name, builder = builder) \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt index 560ec496..1a8e4a9d 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt @@ -2,8 +2,8 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder import space.kscience.visionforge.set import kotlin.math.cos import kotlin.math.sin @@ -20,7 +20,7 @@ public class ConeSegment( public val topRadius: Float, public val startAngle: Float = 0f, public val angle: Float = PI2 -) : SolidBase(), GeometrySolid { +) : SolidBase(), GeometrySolid { override fun toGeometry(geometryBuilder: GeometryBuilder) { val segments = detail ?: 32 @@ -67,7 +67,7 @@ public class ConeSegment( } @VisionBuilder -public inline fun VisionContainerBuilder.cylinder( +public inline fun MutableVisionContainer.cylinder( r: Number, height: Number, name: String? = null, @@ -79,7 +79,7 @@ public inline fun VisionContainerBuilder.cylinder( ).apply(block).also { set(name, it) } @VisionBuilder -public inline fun VisionContainerBuilder.cone( +public inline fun MutableVisionContainer.cone( bottomRadius: Number, height: Number, upperRadius: Number = 0.0, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt index 25f79ee8..b5a4d5cf 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt @@ -2,9 +2,8 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer import space.kscience.visionforge.set import kotlin.math.PI import kotlin.math.cos @@ -24,7 +23,7 @@ public class ConeSurface( public val topInnerRadius: Float, public val startAngle: Float = 0f, public val angle: Float = PI2, -) : SolidBase(), GeometrySolid, VisionPropertyContainer { +) : SolidBase(), GeometrySolid { init { require(bottomRadius > 0) { "Cone surface bottom radius must be positive" } @@ -124,7 +123,7 @@ public class ConeSurface( @VisionBuilder -public inline fun VisionContainerBuilder.tube( +public inline fun MutableVisionContainer.tube( radius: Number, height: Number, innerRadius: Number, @@ -143,7 +142,7 @@ public inline fun VisionContainerBuilder.tube( ).apply(block).also { set(name, it) } @VisionBuilder -public inline fun VisionContainerBuilder.coneSurface( +public inline fun MutableVisionContainer.coneSurface( bottomOuterRadius: Number, bottomInnerRadius: Number, height: Number, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt index 24d1ff16..ad0a456e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt @@ -2,16 +2,17 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.set @Serializable @SerialName("solid.convex") -public class Convex(public val points: List) : SolidBase(), VisionPropertyContainer +public class Convex(public val points: List) : SolidBase() -public inline fun VisionContainerBuilder.convex(name: String? = null, action: ConvexBuilder.() -> Unit = {}): Convex = - ConvexBuilder().apply(action).build().also { set(name, it) } +public inline fun MutableVisionContainer.convex( + name: String? = null, + action: ConvexBuilder.() -> Unit = {}, +): Convex = ConvexBuilder().apply(action).build().also { set(name, it) } public class ConvexBuilder { private val points = ArrayList() diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 6e5a8bb7..0b1c2e20 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -3,7 +3,6 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.ObservableMutableMeta import space.kscience.dataforge.names.Name import space.kscience.visionforge.* import kotlin.math.PI @@ -41,7 +40,7 @@ public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Flo public class Extruded( public val shape: List, public val layers: List, -) : SolidBase(), GeometrySolid, VisionPropertyContainer { +) : SolidBase(), GeometrySolid { override fun toGeometry(geometryBuilder: GeometryBuilder) { val shape: Shape2D = shape @@ -96,11 +95,9 @@ public class Extruded( public class ExtrudeBuilder( public var shape: List = emptyList(), - public var layers: MutableList = ArrayList(), - - config: ObservableMutableMeta = MutableMeta(), -) : SimpleVisionPropertyContainer(config) { + public val properties: MutableMeta = MutableMeta(), +) { public fun shape(block: Shape2DBuilder.() -> Unit) { this.shape = Shape2DBuilder().apply(block).build() } @@ -110,12 +107,12 @@ public class ExtrudeBuilder( } internal fun build(): Extruded = Extruded(shape, layers).apply { - setProperty(Name.EMPTY, getProperty(Name.EMPTY)) + this.properties[Name.EMPTY] = this@ExtrudeBuilder.properties } } @VisionBuilder -public fun VisionContainerBuilder.extruded( +public fun MutableVisionContainer.extruded( name: String? = null, action: ExtrudeBuilder.() -> Unit = {}, ): Extruded = ExtrudeBuilder().apply(action).build().also { set(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt index 7f42a3eb..b327f9bf 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt @@ -2,8 +2,8 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder import space.kscience.visionforge.set public interface Hexagon : GeometrySolid { @@ -35,7 +35,7 @@ public class Box( public val xSize: Float, public val ySize: Float, public val zSize: Float, -) : SolidBase(), Hexagon { +) : SolidBase(), Hexagon { private inline val dx get() = xSize / 2 private inline val dy get() = ySize / 2 @@ -52,7 +52,7 @@ public class Box( } @VisionBuilder -public inline fun VisionContainerBuilder.box( +public inline fun MutableVisionContainer.box( xSize: Number, ySize: Number, zSize: Number, @@ -71,10 +71,10 @@ public class GenericHexagon( override val node6: Point3D, override val node7: Point3D, override val node8: Point3D, -) : SolidBase(), Hexagon +) : SolidBase(), Hexagon @VisionBuilder -public inline fun VisionContainerBuilder.hexagon( +public inline fun MutableVisionContainer.hexagon( node1: Point3D, node2: Point3D, node3: Point3D, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt index 6bab2cf3..3f90d903 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -5,15 +5,16 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.node import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.meta.number import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.* @Serializable -public abstract class LightSource : SolidBase() { +public abstract class LightSource : SolidBase() { override val descriptor: MetaDescriptor get() = LightSource.descriptor public val color: ColorAccessor by color() - public var intensity: Number by numberProperty(includeStyles = false) { 1.0 } + public var intensity: Number by properties.root(includeStyles = false).number { 1.0 } public companion object{ public val descriptor: MetaDescriptor by lazy { @@ -51,7 +52,7 @@ public abstract class LightSource : SolidBase() { public class AmbientLightSource : LightSource() @VisionBuilder -public fun VisionContainerBuilder.ambientLight( +public fun MutableVisionContainer.ambientLight( name: String? = "@ambientLight", block: AmbientLightSource.() -> Unit = {}, ): AmbientLightSource = AmbientLightSource().apply(block).also { set(name, it) } @@ -62,7 +63,7 @@ public class PointLightSource : LightSource() @VisionBuilder -public fun VisionContainerBuilder.pointLight( +public fun MutableVisionContainer.pointLight( x: Number, y: Number, z: Number, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt index 05d58744..df28b344 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt @@ -2,27 +2,19 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.plus +import space.kscience.dataforge.meta.number import space.kscience.visionforge.* @Serializable @SerialName("solid.line") -public class PolyLine(public val points: List) : SolidBase(), VisionPropertyContainer { +public class PolyLine(public val points: List) : SolidBase() { //var lineType by string() - public var thickness: Number by numberProperty(name = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY) { 1.0 } - - - public companion object { - public val THICKNESS_KEY: Name = "thickness".asName() - } - + public var thickness: Number by properties[SolidMaterial.MATERIAL_KEY].number { 1.0 } } @VisionBuilder -public fun VisionContainerBuilder.polyline( +public fun MutableVisionContainer.polyline( vararg points: Point3D, name: String? = null, action: PolyLine.() -> Unit = {}, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index c3111d4e..1cfc1d3b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -115,9 +115,9 @@ public interface Solid : Vision { * Get the layer number this solid belongs to. Return 0 if layer is not defined. */ public var Solid.layer: Int - get() = getPropertyValue(LAYER_KEY, inherit = true)?.int ?: 0 + get() = properties.getValue(LAYER_KEY, inherit = true)?.int ?: 0 set(value) { - setPropertyValue(LAYER_KEY, value) + properties.set(LAYER_KEY, value) } // Common properties @@ -135,24 +135,24 @@ public enum class RotationOrder { * Rotation order */ public var Solid.rotationOrder: RotationOrder - get() = getPropertyValue(Solid.ROTATION_ORDER_KEY)?.enum() ?: RotationOrder.XYZ - set(value) = setPropertyValue(Solid.ROTATION_ORDER_KEY, value.name.asValue()) + get() = properties.getValue(Solid.ROTATION_ORDER_KEY)?.enum() ?: RotationOrder.XYZ + set(value) = properties.setValue(Solid.ROTATION_ORDER_KEY, value.name.asValue()) /** * Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default. Not inherited */ public var Solid.detail: Int? - get() = getPropertyValue(DETAIL_KEY, inherit = false)?.int - set(value) = setPropertyValue(DETAIL_KEY, value?.asValue()) + get() = properties.getValue(DETAIL_KEY, inherit = false)?.int + set(value) = properties.setValue(DETAIL_KEY, value?.asValue()) /** * If this property is true, the object will be ignored on render. * Property is not inherited. */ public var Vision.ignore: Boolean? - get() = getPropertyValue(IGNORE_KEY, inherit = false)?.boolean - set(value) = setPropertyValue(IGNORE_KEY, value?.asValue()) + get() = properties.getValue(IGNORE_KEY, inherit = false, includeStyles = false)?.boolean + set(value) = properties.setValue(IGNORE_KEY, value?.asValue()) //var VisualObject.selected: Boolean? // get() = getProperty(SELECTED_KEY).boolean @@ -161,18 +161,18 @@ public var Vision.ignore: Boolean? internal fun float(name: Name, default: Number): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Number { - return thisRef.getPropertyValue(name)?.number ?: default + return thisRef.properties.getValue(name)?.number ?: default } override fun setValue(thisRef: Solid, property: KProperty<*>, value: Number) { - thisRef.setPropertyValue(name, value) + thisRef.properties.setValue(name, value.asValue()) } } internal fun point(name: Name, default: Float): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Point3D? { - val item = thisRef.meta[name] ?: return null + val item = thisRef.properties.raw?.get(name) ?: return null return object : Point3D { override val x: Float get() = item[X_KEY]?.float ?: default override val y: Float get() = item[Y_KEY]?.float ?: default @@ -182,11 +182,11 @@ internal fun point(name: Name, default: Float): ReadWriteProperty, value: Point3D?) { if (value == null) { - thisRef.setProperty(name, null) + thisRef.properties[name] = null } else { - thisRef.setPropertyValue(name + X_KEY, value.x) - thisRef.setPropertyValue(name + Y_KEY, value.y) - thisRef.setPropertyValue(name + Z_KEY, value.z) + thisRef.properties[name + X_KEY] = value.x + thisRef.properties[name + Y_KEY] = value.y + thisRef.properties[name + Z_KEY] = value.z } } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt index 6d4b2faf..7aef3f82 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt @@ -2,24 +2,11 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.names.Name import space.kscience.visionforge.AbstractVision -import space.kscience.visionforge.VisionChildren @Serializable @SerialName("solid") -public open class SolidBase : AbstractVision(), Solid { +public open class SolidBase : AbstractVision(), Solid { override val descriptor: MetaDescriptor get() = Solid.descriptor - override val children: VisionChildren get() = VisionChildren.empty(this) - - override fun getProperty( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): MutableMeta { - return super.getProperty(name, inherit, includeStyles, includeDefaults) - } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index 20528056..e514dee4 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -16,7 +16,7 @@ public interface PrototypeHolder { * Build or update prototype tree */ @VisionBuilder - public fun prototypes(builder: VisionContainerBuilder.() -> Unit) + public fun prototypes(builder: MutableVisionContainer.() -> Unit) /** * Resolve a prototype from this container. Should never return a ref. @@ -30,7 +30,7 @@ public interface PrototypeHolder { */ @Serializable @SerialName("group.solid") -public class SolidGroup : VisionGroup(), Solid, PrototypeHolder, MutableVisionGroup, VisionContainerBuilder { +public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, MutableVisionGroup, MutableVisionContainer { public val items: Map get() = children.keys.mapNotNull { @@ -59,7 +59,7 @@ public class SolidGroup : VisionGroup(), Solid, PrototypeHolder, MutableVisionGr /** * Create or edit prototype node as a group */ - override fun prototypes(builder: VisionContainerBuilder.() -> Unit): Unit { + override fun prototypes(builder: MutableVisionContainer.() -> Unit): Unit { (prototypes ?: SolidGroup().also { prototypes = it }).children.run(builder) } @@ -82,7 +82,7 @@ public class SolidGroup : VisionGroup(), Solid, PrototypeHolder, MutableVisionGr public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block) @VisionBuilder -public fun VisionContainerBuilder.group( +public fun MutableVisionContainer.group( name: Name? = null, builder: SolidGroup.() -> Unit = {}, ): SolidGroup = SolidGroup(builder).also { set(name, it) } @@ -91,7 +91,7 @@ public fun VisionContainerBuilder.group( * Define a group with given [name], attach it to this parent and return it. */ @VisionBuilder -public fun VisionContainerBuilder.group( +public fun MutableVisionContainer.group( name: String, action: SolidGroup.() -> Unit = {}, ): SolidGroup = SolidGroup(action).also { set(name, it) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt index 8cf27881..649e7f7c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt @@ -2,9 +2,8 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer import space.kscience.visionforge.set @Serializable @@ -13,10 +12,10 @@ public class SolidLabel( public val text: String, public val fontSize: Double, public val fontFamily: String, -) : SolidBase(), VisionPropertyContainer +) : SolidBase() @VisionBuilder -public fun VisionContainerBuilder.label( +public fun MutableVisionContainer.label( text: String, fontSize: Number = 20, fontFamily: String = "Arial", diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index c68af09c..87a39ac4 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -102,19 +102,19 @@ public class SolidMaterial : Scheme() { } public val Solid.color: ColorAccessor - get() = ColorAccessor(getProperty(Name.EMPTY), MATERIAL_COLOR_KEY) + get() = ColorAccessor(properties.root(), MATERIAL_COLOR_KEY) public var Solid.material: SolidMaterial? - get() = SolidMaterial.read(getProperty(MATERIAL_KEY)) - set(value) = setProperty(MATERIAL_KEY, value?.meta) + get() = SolidMaterial.read(properties[MATERIAL_KEY]) + set(value) = properties.set(MATERIAL_KEY, value?.meta) @VisionBuilder public fun Solid.material(builder: SolidMaterial.() -> Unit) { - getProperty(MATERIAL_KEY).updateWith(SolidMaterial, builder) + properties[MATERIAL_KEY].updateWith(SolidMaterial, builder) } public var Solid.opacity: Number? - get() = getPropertyValue(MATERIAL_OPACITY_KEY, inherit = true)?.number + get() = properties.getValue(MATERIAL_OPACITY_KEY, inherit = true)?.number set(value) { - setPropertyValue(MATERIAL_OPACITY_KEY, value?.asValue()) + properties.setValue(MATERIAL_OPACITY_KEY, value?.asValue()) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 8e6e6f59..3e34212a 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -1,14 +1,15 @@ package space.kscience.visionforge.solid -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.Meta +import kotlinx.serialization.Transient +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.* import space.kscience.dataforge.values.Value import space.kscience.visionforge.* +import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX @@ -23,6 +24,71 @@ public val Vision.unref: Solid else -> error("This Vision is neither Solid nor SolidReference") } +@Serializable +@SerialName("solid.ref") +public class SolidReference( + @SerialName("prototype") public val prototypeName: Name, +) : SolidBase(), VisionGroup { + + /** + * The prototype for this reference. + */ + public val prototype: Solid by lazy { + //Recursively search for defined template in the parent + if (parent == null) error("No parent is present for SolidReference") + if (parent !is PrototypeHolder) error("Parent does not hold prototypes") + (parent as? PrototypeHolder)?.getPrototype(prototypeName) + ?: error("Prototype with name $prototypeName not found") + } + + override val descriptor: MetaDescriptor get() = prototype.descriptor + + override val defaultProperties: Meta + get() = prototype.properties.raw?.withDefault(descriptor.defaultNode) ?: descriptor.defaultNode + + override val children: VisionChildren + get() = object : VisionChildren { + override val group: Vision get() = this@SolidReference + + override val keys: Set get() = prototype.children?.keys ?: emptySet() + + override val changes: Flow get() = emptyFlow() + + override fun get(token: NameToken): SolidReferenceChild? { + if (token !in (prototype.children?.keys ?: emptySet())) return null + return SolidReferenceChild(this@SolidReference, this@SolidReference, token.asName()) + } + } + +// override fun getPropertyValue( +// name: Name, +// inherit: Boolean, +// includeStyles: Boolean, +// includeDefaults: Boolean, +// ): Value? { +// meta?.getValue(name)?.let { return it } +// if (includeStyles) { +// getStyleProperty(name)?.value?.let { return it } +// } +// prototype.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } +// if (inherit) { +// parent?.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } +// } +// return null +// } +// +// override fun getProperty( +// name: Name, +// inherit: Boolean, +// includeStyles: Boolean, +// includeDefaults: Boolean, +// ): MutableMeta = VisionProperties(this, name, descriptor[name], inherit, includeStyles, prototype.meta) + + public companion object { + public const val REFERENCE_CHILD_PROPERTY_PREFIX: String = "@child" + } +} + /** * @param name A name of reference child relative to prototype root */ @@ -30,62 +96,74 @@ internal class SolidReferenceChild( val owner: SolidReference, override var parent: Vision?, val childName: Name, -) : Solid { +) : Solid, VisionGroup { val prototype: Solid - get() = owner.prototype.children[childName] as? Solid + get() = owner.prototype.children?.get(childName) as? Solid ?: error("Prototype with name $childName not found") - override val meta: Meta get() = owner.getProperty(childToken(childName).asName()) - - override fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): Value? { - owner.getPropertyValue( - childPropertyName(childName, name), inherit, includeStyles, includeDefaults - )?.let { return it } - if (includeStyles) { - getStyleProperty(name)?.value?.let { return it } - } - prototype.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } - if (inherit) { - parent?.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } - } - return null - } + override val descriptor: MetaDescriptor get() = prototype.descriptor - override fun setProperty(name: Name, node: Meta?) { - owner.setProperty(childPropertyName(childName, name), node) - } + @Transient + override val properties: MutableVisionProperties = object : MutableVisionProperties { + override val descriptor: MetaDescriptor get() = this@SolidReferenceChild.descriptor + override val default: Meta + get() = prototype.properties.raw?.withDefault(descriptor.defaultNode) ?: descriptor.defaultNode - override fun setPropertyValue(name: Name, value: Value?) { - owner.setPropertyValue(childPropertyName(childName, name), value) - } + override val raw: MutableMeta by lazy { owner.properties[childToken(childName).asName()] } - override val propertyChanges: SharedFlow - get() = TODO("Not yet implemented") + override fun getValue( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + ): Value? { + raw[name]?.value?.let { return it } + if (includeStyles) { + getStyleProperty(name)?.value?.let { return it } + } + if (inherit) { + parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } + } + return default[name]?.value + } - override fun invalidateProperty(propertyName: Name) { - owner.invalidateProperty(childPropertyName(childName, propertyName)) + override fun set(name: Name, node: Meta?) { + raw.setMeta(name, node) + } + + override fun setValue(name: Name, value: Value?) { + raw.setValue(name, value) + } + override val changes: Flow get() = owner.properties.changes.filter { it.startsWith(childToken(childName)) } + + override fun invalidate(propertyName: Name) { + owner.properties.invalidate(childPropertyName(childName, propertyName)) + } } override fun update(change: VisionChange) { - TODO("Not yet implemented") + change.children?.forEach { (name, change) -> + when { + change.delete -> error("Deleting children inside ref is not allowed.") + change.vision != null -> error("Updating content of the ref is not allowed") + else -> children[name]?.update(change) + } + } + change.properties?.let { + updateProperties(it, Name.EMPTY) + } } override val children: VisionChildren = object : VisionChildren { - override val parent: Vision get() = this@SolidReferenceChild + override val group: Vision get() = this@SolidReferenceChild - override val keys: Set get() = prototype.children.keys + override val keys: Set get() = prototype.children?.keys ?: emptySet() override val changes: Flow get() = emptyFlow() override fun get(token: NameToken): SolidReferenceChild? { - if (token !in prototype.children.keys) return null + if (token !in (prototype.children?.keys ?: emptySet())) return null return SolidReferenceChild(this@SolidReferenceChild.owner, this@SolidReferenceChild, childName + token) } } @@ -101,51 +179,15 @@ internal class SolidReferenceChild( } } -@Serializable -@SerialName("solid.ref") -public class SolidReference( - @SerialName("prototype") public val prototypeName: Name, -) : SolidBase() { - - /** - * The prototype for this reference. - */ - public val prototype: Solid by lazy { - //Recursively search for defined template in the parent - if (parent == null) error("No parent is present for SolidReference") - if (parent !is PrototypeHolder) error("Parent does not hold prototypes") - (parent as? PrototypeHolder)?.getPrototype(prototypeName) - ?: error("Prototype with name $prototypeName not found") - } - - override val children: VisionChildren - get() = object : VisionChildren { - override val parent: Vision get() = this@SolidReference - - override val keys: Set get() = prototype.children.keys - - override val changes: Flow get() = emptyFlow() - - override fun get(token: NameToken): SolidReferenceChild? { - if (token !in prototype.children.keys) return null - return SolidReferenceChild(this@SolidReference, this@SolidReference, token.asName()) - } - } - - public companion object{ - public const val REFERENCE_CHILD_PROPERTY_PREFIX: String = "@child" - } -} - /** * Create ref for existing prototype */ -public fun VisionContainerBuilder.ref( +public fun MutableVisionContainer.ref( templateName: Name, name: String? = null, ): SolidReference = SolidReference(templateName).also { set(name, it) } -public fun VisionContainerBuilder.ref( +public fun MutableVisionContainer.ref( templateName: String, name: String? = null, ): SolidReference = ref(Name.parse(templateName), name) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 6e9d00d9..722c97f8 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.modules.PolymorphicModuleBuilder import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.subclass +import kotlinx.serialization.serializer import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag @@ -47,12 +48,12 @@ public class Solids(meta: Meta) : VisionPlugin(meta) { public val serializersModuleForSolids: SerializersModule = SerializersModule { polymorphic(Vision::class) { - subclass(VisionGroup.serializer()) + subclass(SimpleVisionGroup.serializer()) solids() } polymorphic(Solid::class) { - default { SolidBase.serializer() } + default { SolidBase.serializer(serializer()) } solids() } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt index 45305e4a..0ce0d893 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt @@ -2,9 +2,8 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer import space.kscience.visionforge.set import kotlin.math.PI import kotlin.math.cos @@ -17,8 +16,8 @@ public class Sphere( public val phiStart: Float = 0f, public val phi: Float = PI2, public val thetaStart: Float = 0f, - public val theta: Float = PI .toFloat(), -) : SolidBase(), GeometrySolid, VisionPropertyContainer { + public val theta: Float = PI.toFloat(), +) : SolidBase(), GeometrySolid { override fun toGeometry(geometryBuilder: GeometryBuilder) { fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Point3D { @@ -53,7 +52,7 @@ public class Sphere( } @VisionBuilder -public inline fun VisionContainerBuilder.sphere( +public inline fun MutableVisionContainer.sphere( radius: Number, name: String? = null, action: Sphere.() -> Unit = {}, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt index b5ae5500..709968af 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt @@ -2,8 +2,8 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder import space.kscience.visionforge.set import kotlin.math.PI import kotlin.math.cos @@ -21,7 +21,7 @@ public class SphereLayer( public val phi: Float = PI2, public val thetaStart: Float = 0f, public val theta: Float = PI.toFloat(), -) : SolidBase(), GeometrySolid { +) : SolidBase(), GeometrySolid { override fun toGeometry(geometryBuilder: GeometryBuilder): Unit = geometryBuilder.run { require(outerRadius > 0) { "Outer radius must be positive" } @@ -69,7 +69,7 @@ public class SphereLayer( } @VisionBuilder -public inline fun VisionContainerBuilder.sphereLayer( +public inline fun MutableVisionContainer.sphereLayer( outerRadius: Number, innerRadius: Number, phiStart: Number = 0f, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index bab2e518..dbdc58ec 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge.solid.transform import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.visionforge.getProperty +import space.kscience.visionforge.root import space.kscience.visionforge.solid.* private operator fun Number.plus(other: Number) = toFloat() + other.toFloat() @@ -20,7 +20,7 @@ internal fun Solid.updateFrom(other: Solid): Solid { scaleX *= other.scaleX scaleY *= other.scaleY scaleZ *= other.scaleZ - setProperty(Name.EMPTY, other.getProperty(Name.EMPTY)) + properties[Name.EMPTY] = other.properties.root() return this } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt index 8e6f0b89..688712e6 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt @@ -1,9 +1,8 @@ package space.kscience.visionforge.solid -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.asName import space.kscience.dataforge.values.int +import space.kscience.dataforge.values.string import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals @@ -17,7 +16,7 @@ class PropertyTest { //meta["color"] = "pink" color.set("pink") } - assertEquals("pink", box.meta["material.color"]?.string) + assertEquals("pink", box.properties.getValue("material.color")?.string) assertEquals("pink", box.color.string) } @@ -43,12 +42,12 @@ class PropertyTest { fun testInheritedProperty() { var box: Box? = null val group = SolidGroup().apply { - setPropertyValue("test", 22) + properties["test"] = 22 group { box = box(100, 100, 100) } } - assertEquals(22, box?.getPropertyValue("test", inherit = true)?.int) + assertEquals(22, box?.properties?.getValue("test", inherit = true)?.int) } @Test @@ -66,7 +65,7 @@ class PropertyTest { } } } - assertEquals(22, box?.getPropertyValue("test")?.int) + assertEquals(22, box?.properties?.getValue("test")?.int) } @Test diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index 70cb9c4e..baad6110 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -31,7 +31,7 @@ class SerializationTest { val string = Solids.encodeToString(cube) println(string) val newCube = Solids.decodeFromString(string) - assertEquals(cube.meta, newCube.meta) + assertEquals(cube.properties.raw, newCube.properties.raw) } @Test @@ -52,7 +52,7 @@ class SerializationTest { val string = Solids.encodeToString(group) println(string) val reconstructed = Solids.decodeFromString(string) as SolidGroup - assertEquals(group.children["cube"]?.meta, reconstructed.children["cube"]?.meta) + assertEquals(group.children["cube"]?.properties?.raw, reconstructed.children["cube"]?.properties?.raw) } @Test diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt index d76398fc..cb870da8 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt @@ -12,7 +12,7 @@ import space.kscience.dataforge.values.Null import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.asValue import space.kscience.tables.* -import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.html.VisionOutput import space.kscience.visionforge.properties import kotlin.jvm.JvmName @@ -42,10 +42,14 @@ public val ColumnHeader.properties: ValueColumnScheme get() = ValueColumn @SerialName("vision.table") public class VisionOfTable( override val headers: List<@Serializable(ColumnHeaderSerializer::class) ColumnHeader>, -) : VisionGroup(), Rows { +) : AbstractVision(), Rows { public var data: List - get() = meta.getIndexed("rows").entries.sortedBy { it.key?.toInt() }.map { it.value } + get() = meta?.getIndexed("rows")?.entries?.sortedBy { + it.key?.toInt() + }?.map { + it.value + } ?: emptyList() set(value) { //TODO Make it better properties()["rows"] = value diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt index 68b44fc5..b7d8244d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt @@ -10,7 +10,6 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.getProperty import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.setPropertyValue import space.kscience.visionforge.solid.Solid diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index 3fb87c7b..42a8b6e6 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -11,7 +11,6 @@ import org.w3c.dom.CanvasRenderingContext2D import org.w3c.dom.CanvasTextBaseline import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.MIDDLE -import space.kscience.visionforge.getProperty import space.kscience.visionforge.solid.SolidLabel import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG @@ -27,7 +26,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory { val canvas = document.createElement("canvas") as HTMLCanvasElement val context = canvas.getContext("2d") as CanvasRenderingContext2D context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.getProperty(SolidMaterial.MATERIAL_COLOR_KEY)?.value ?: "black" + context.fillStyle = obj.get(SolidMaterial.MATERIAL_COLOR_KEY)?.value ?: "black" context.textBaseline = CanvasTextBaseline.MIDDLE val metrics = context.measureText(obj.text) //canvas.width = metrics.width.toInt() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index da1984f3..6e9c7472 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -4,7 +4,6 @@ import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.math.Color import info.laht.threekt.objects.LineSegments -import space.kscience.visionforge.getProperty import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial @@ -25,7 +24,7 @@ public object ThreeLineFactory : ThreeFactory { } val material = ThreeMaterials.getLineMaterial( - obj.getProperty(SolidMaterial.MATERIAL_KEY), + obj.get(SolidMaterial.MATERIAL_KEY), false ) From c71042ae06346fbe362426145a243febba2bee83 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 8 Aug 2022 22:17:06 +0300 Subject: [PATCH 011/112] [WIP] great refactoring in progress --- .../kscience/visionforge/AbstractVision.kt | 6 +- .../kscience/visionforge/VisionChange.kt | 19 ++--- .../kscience/visionforge/VisionContainer.kt | 79 +++++++++---------- .../space/kscience/visionforge/VisionGroup.kt | 46 ++++------- visionforge-plotly/build.gradle.kts | 2 +- visionforge-solid/build.gradle.kts | 5 ++ .../visionforge/solid/SolidReference.kt | 24 ------ .../visionforge/solid/PropertyTest.kt | 28 ++++--- .../visionforge/solid/SolidReferenceTest.kt | 2 + .../visionforge/solid/VisionUpdateTest.kt | 6 +- visionforge-tables/build.gradle.kts | 2 +- 11 files changed, 96 insertions(+), 123 deletions(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt index f6b38880..0e0e043d 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor @@ -15,13 +16,14 @@ import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import kotlin.jvm.Synchronized +@Serializable public abstract class AbstractVision : Vision { @Transient override var parent: Vision? = null @SerialName("properties") - internal var _properties: MutableMeta? = null + protected var _properties: MutableMeta? = null protected open val defaultProperties: Meta? get() = descriptor?.defaultNode @@ -80,7 +82,7 @@ public abstract class AbstractVision : Vision { } @Transient - private val _changes = MutableSharedFlow() + private val _changes = MutableSharedFlow(10) override val changes: SharedFlow get() = _changes override fun invalidate(propertyName: Name) { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index a4667b2f..33bbd5ca 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -16,7 +16,7 @@ import kotlin.time.Duration /** * Create a deep copy of given Vision without external connections. */ -private fun Vision.deepCopy(): Vision { +private fun Vision.deepCopy(manager: VisionManager): Vision { //Assuming that unrooted visions are already isolated //TODO replace by efficient deep copy val json = manager.encodeToJsonElement(this) @@ -26,7 +26,7 @@ private fun Vision.deepCopy(): Vision { /** * An update for a [Vision] */ -public class VisionChangeBuilder : MutableVisionContainer { +public class VisionChangeBuilder(private val manager: VisionManager) : MutableVisionContainer { private var reset: Boolean = false private var vision: Vision? = null @@ -37,7 +37,7 @@ public class VisionChangeBuilder : MutableVisionContainer { @Synchronized private fun getOrPutChild(visionName: Name): VisionChangeBuilder = - children.getOrPut(visionName) { VisionChangeBuilder() } + children.getOrPut(visionName) { VisionChangeBuilder(manager) } public fun propertyChanged(visionName: Name, propertyName: Name, item: Meta?) { if (visionName == Name.EMPTY) { @@ -61,7 +61,7 @@ public class VisionChangeBuilder : MutableVisionContainer { */ public fun deepCopy(): VisionChange = VisionChange( reset, - vision?.deepCopy(), + vision?.deepCopy(manager), if (propertyChange.isEmpty()) null else propertyChange.seal(), if (children.isEmpty()) null else children.mapValues { it.value.deepCopy() } ) @@ -81,8 +81,8 @@ public data class VisionChange( public val children: Map? = null, ) -public inline fun VisionChange(block: VisionChangeBuilder.() -> Unit): VisionChange = - VisionChangeBuilder().apply(block).deepCopy() +public inline fun VisionManager.VisionChange(block: VisionChangeBuilder.() -> Unit): VisionChange = + VisionChangeBuilder(this).apply(block).deepCopy() private fun CoroutineScope.collectChange( @@ -119,14 +119,15 @@ private fun CoroutineScope.collectChange( */ public fun Vision.flowChanges( collectionDuration: Duration, + manager: VisionManager = this.manager, ): Flow = flow { - var collector = VisionChangeBuilder() + var collector = VisionChangeBuilder(manager) coroutineScope { collectChange(Name.EMPTY, this@flowChanges) { collector } //Send initial vision state - val initialChange = VisionChange(vision = deepCopy()) + val initialChange = VisionChange(vision = deepCopy(manager)) emit(initialChange) while (currentCoroutineContext().isActive) { @@ -137,7 +138,7 @@ public fun Vision.flowChanges( //emit changes emit(collector.deepCopy()) //Reset the collector - collector = VisionChangeBuilder() + collector = VisionChangeBuilder(manager) } } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index 81f7d9da..4ce69047 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -4,12 +4,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch -import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import kotlinx.serialization.serializer import space.kscience.dataforge.names.* @DslMarker @@ -60,9 +54,9 @@ public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) { keys.forEach { block(it, get(it)!!) } } -@Serializable(VisionChildrenContainerSerializer::class) public interface MutableVisionChildren : VisionChildren, MutableVisionContainer { - public override val group: MutableVisionGroup? + + public override val group: MutableVisionGroup public operator fun set(token: NameToken, value: Vision?) @@ -83,9 +77,9 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer< else -> { val currentParent = get(name.first()) if (currentParent != null && currentParent !is MutableVisionGroup) error("Can't assign a child to $currentParent") - val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group?.createGroup().also { + val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group.createGroup().also { set(name.first(), it) - } ?: error("Container owner not set") + } parent.children[name.cutFirst()] = child } } @@ -113,27 +107,26 @@ public operator fun MutableVisionContainer.set( str: String?, vision: V?, ): Unit = set(str?.parseAsName(), vision) -internal class VisionChildrenImpl( - items: Map, +internal abstract class VisionChildrenImpl( + override val group: MutableVisionGroup, ) : MutableVisionChildren { - override var group: MutableVisionGroup? = null - internal set - - private val items = LinkedHashMap(items) private val updateJobs = HashMap() - private val scope: CoroutineScope? get() = group?.manager?.context + abstract val items: MutableMap? + abstract fun buildItems(): MutableMap - override val keys: Set get() = items.keys + private val scope: CoroutineScope get() = group.manager.context - override fun get(token: NameToken): Vision? = items[token] + override val keys: Set get() = items?.keys ?: emptySet() + + override fun get(token: NameToken): Vision? = items?.get(token) private val _changes = MutableSharedFlow() override val changes: SharedFlow get() = _changes private fun onChange(name: Name) { - scope?.launch { + scope.launch { _changes.emit(name) } } @@ -149,16 +142,16 @@ internal class VisionChildrenImpl( } if (value == null) { - items.remove(token) + items?.remove(token) } else { - items[token] = value + (items ?: buildItems())[token] = value //check if parent already exists and is different from the current one if (value.parent != null && value.parent != group) error("Can't reassign parent Vision for $value") //set parent value.parent = group //start update jobs (only if the vision is rooted) - scope?.let { scope -> - val job = (value.children as? VisionChildrenImpl)?.changes?.onEach { + scope.let { scope -> + val job = value.children?.changes?.onEach { onChange(token + it) }?.launchIn(scope) if (job != null) { @@ -171,30 +164,30 @@ internal class VisionChildrenImpl( } override fun clear() { - if (items.isNotEmpty()) { + if (!items.isNullOrEmpty()) { updateJobs.values.forEach { it.cancel() } updateJobs.clear() - items.clear() + items?.clear() onChange(Name.EMPTY) } } } - -internal object VisionChildrenContainerSerializer : KSerializer { - private val mapSerializer = serializer>() - - override val descriptor: SerialDescriptor = mapSerializer.descriptor - - override fun deserialize(decoder: Decoder): MutableVisionChildren { - val map = decoder.decodeSerializableValue(mapSerializer) - return VisionChildrenImpl(map) - } - - override fun serialize(encoder: Encoder, value: MutableVisionChildren) { - val map = value.keys.associateWith { value[it]!! } - encoder.encodeSerializableValue(mapSerializer, map) - } - -} +// +//internal object VisionChildrenContainerSerializer : KSerializer { +// private val mapSerializer = serializer>() +// +// override val descriptor: SerialDescriptor = mapSerializer.descriptor +// +// override fun deserialize(decoder: Decoder): MutableVisionChildren { +// val map = decoder.decodeSerializableValue(mapSerializer) +// return VisionChildrenImpl(map) +// } +// +// override fun serialize(encoder: Encoder, value: MutableVisionChildren) { +// val map = value.keys.associateWith { value[it]!! } +// encoder.encodeSerializableValue(mapSerializer, map) +// } +// +//} diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index f87650a7..9535fbd9 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -1,10 +1,7 @@ package space.kscience.visionforge -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.emptyFlow import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value @@ -33,6 +30,7 @@ public val Vision.children: VisionChildren? get() = (this as? VisionGroup)?.chil /** * A full base implementation for a [Vision] */ +@Serializable public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { override fun update(change: VisionChange) { @@ -49,38 +47,26 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup } @SerialName("children") - protected var _children: MutableVisionChildren? = null - - @Transient - override val children: MutableVisionChildren = object : MutableVisionChildren { - - @Synchronized - fun getOrCreateChildren(): MutableVisionChildren { - if (_children == null) { - _children = VisionChildrenImpl(emptyMap()).apply { - group = this@AbstractVisionGroup - } - } - return _children!! - } + protected var _children: MutableMap? = null - override val group: MutableVisionGroup get() = this@AbstractVisionGroup - override val keys: Set get() = _children?.keys ?: emptySet() - override val changes: Flow get() = _children?.changes ?: emptyFlow() - - override fun get(token: NameToken): Vision? = _children?.get(token) + init { + _children?.forEach { it.value.parent = this } + } - override fun set(token: NameToken, value: Vision?) { - getOrCreateChildren()[token] = value - } + override val children: MutableVisionChildren by lazy { + object : VisionChildrenImpl(this){ + override val items: MutableMap? + get() = this@AbstractVisionGroup._children - override fun set(name: Name?, child: Vision?) { - getOrCreateChildren()[name] = child - } + @Synchronized + override fun buildItems(): MutableMap { + if (_children == null) { + _children = LinkedHashMap() + } + return _children!! + } - override fun clear() { - _children?.clear() } } diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index caeb4e52..1c1ed308 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("ru.mipt.npm.gradle.mpp") } -val plotlyVersion = "0.5.0" +val plotlyVersion = "0.5.3-dev-1" kscience { useSerialization() diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index e00830d5..ce669659 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -15,6 +15,11 @@ kotlin { api(project(":visionforge-core")) } } + commonTest{ + dependencies{ + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4") + } + } } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 3e34212a..aa79734f 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -60,30 +60,6 @@ public class SolidReference( } } -// override fun getPropertyValue( -// name: Name, -// inherit: Boolean, -// includeStyles: Boolean, -// includeDefaults: Boolean, -// ): Value? { -// meta?.getValue(name)?.let { return it } -// if (includeStyles) { -// getStyleProperty(name)?.value?.let { return it } -// } -// prototype.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } -// if (inherit) { -// parent?.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } -// } -// return null -// } -// -// override fun getProperty( -// name: Name, -// inherit: Boolean, -// includeStyles: Boolean, -// includeDefaults: Boolean, -// ): MutableMeta = VisionProperties(this, name, descriptor[name], inherit, includeStyles, prototype.meta) - public companion object { public const val REFERENCE_CHILD_PROPERTY_PREFIX: String = "@child" } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt index 688712e6..bb6f5de1 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt @@ -1,5 +1,9 @@ package space.kscience.visionforge.solid +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.withTimeout import space.kscience.dataforge.names.asName import space.kscience.dataforge.values.int import space.kscience.dataforge.values.string @@ -10,8 +14,8 @@ import kotlin.test.assertEquals @Suppress("UNUSED_VARIABLE") class PropertyTest { @Test - fun testColor(){ - val box = Box(10.0f, 10.0f,10.0f) + fun testColor() { + val box = Box(10.0f, 10.0f, 10.0f) box.material { //meta["color"] = "pink" color.set("pink") @@ -20,14 +24,17 @@ class PropertyTest { assertEquals("pink", box.color.string) } + @OptIn(ExperimentalCoroutinesApi::class) @Test - fun testColorUpdate(){ - val box = Box(10.0f, 10.0f,10.0f) + fun testColorUpdate() = runTest { + val box = Box(10.0f, 10.0f, 10.0f) + + val c = CompletableDeferred() + - var c: String? = null box.onPropertyChange { - if(it == SolidMaterial.MATERIAL_COLOR_KEY){ - c = box.color.string + if (it == SolidMaterial.MATERIAL_COLOR_KEY) { + c.complete(box.color.string) } } @@ -35,7 +42,8 @@ class PropertyTest { color.set("pink") } - assertEquals("pink", c) + assertEquals("pink", withTimeout(50) { c.await() }) + } @Test @@ -53,7 +61,7 @@ class PropertyTest { @Test fun testStyleProperty() { var box: Box? = null - val group = SolidGroup{ + val group = SolidGroup { styleSheet { update("testStyle") { "test" put 22 @@ -89,7 +97,7 @@ class PropertyTest { @Test fun testReferenceStyleProperty() { var box: SolidReference? = null - val group = SolidGroup{ + val group = SolidGroup { styleSheet { update("testStyle") { SolidMaterial.MATERIAL_COLOR_KEY put "#555555" diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt index 4726f246..f74426ba 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.solid import kotlinx.serialization.json.encodeToJsonElement import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.get import space.kscience.visionforge.get import space.kscience.visionforge.style import space.kscience.visionforge.useStyle @@ -30,6 +31,7 @@ class SolidReferenceTest { fun testReferenceSerialization(){ val serialized = Solids.jsonForSolids.encodeToJsonElement(groupWithReference) val deserialized = Solids.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized) + assertEquals(groupWithReference.items["test"]?.color.string, deserialized.items["test"]?.color.string) assertEquals("blue", (deserialized.children["test"] as Solid).color.string) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 3fbf3ad4..026499f4 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -11,7 +11,7 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue -class VisionUpdateTest { +internal class VisionUpdateTest { val solidManager = Global.fetch(Solids) val visionManager = solidManager.visionManager @@ -20,7 +20,7 @@ class VisionUpdateTest { val targetVision = SolidGroup { box(200,200,200, name = "origin") } - val dif = VisionChange{ + val dif = visionManager.VisionChange{ group ("top") { color.set(123) box(100,100,100) @@ -36,7 +36,7 @@ class VisionUpdateTest { @Test fun testVisionChangeSerialization(){ - val change = VisionChange{ + val change = visionManager.VisionChange{ group("top") { color.set(123) box(100,100,100) diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index 4326da36..d4e86bf1 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("ru.mipt.npm.gradle.mpp") } -val tablesVersion = "0.2.0-dev-1" +val tablesVersion = "0.2.0-dev-3" kscience { useSerialization() From 47bde02488084521897d75fda7af113b5aedc7fc Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 9 Aug 2022 12:49:01 +0300 Subject: [PATCH 012/112] [WIP] Completed solid refactoring --- .../kscience/visionforge/AbstractVision.kt | 101 ++---------------- .../space/kscience/visionforge/Vision.kt | 7 +- .../kscience/visionforge/VisionContainer.kt | 12 ++- .../space/kscience/visionforge/VisionGroup.kt | 21 ++-- .../kscience/visionforge/VisionProperties.kt | 89 ++++++++++++++- .../visionforge/solid/SolidReference.kt | 49 ++++++--- 6 files changed, 148 insertions(+), 131 deletions(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt index 0e0e043d..e7df2198 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt @@ -1,19 +1,10 @@ package space.kscience.visionforge -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.launch import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.isEmpty -import space.kscience.dataforge.values.Value -import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties -import kotlin.jvm.Synchronized @Serializable @@ -23,91 +14,17 @@ public abstract class AbstractVision : Vision { override var parent: Vision? = null @SerialName("properties") - protected var _properties: MutableMeta? = null - - protected open val defaultProperties: Meta? get() = descriptor?.defaultNode - - @Transient - final override val properties: MutableVisionProperties = object : MutableVisionProperties { - override val descriptor: MetaDescriptor? get() = this@AbstractVision.descriptor - override val default: Meta? get() = defaultProperties - - @Synchronized - private fun getOrCreateProperties(): MutableMeta { - if (_properties == null) { - //TODO check performance issues - val newProperties = MutableMeta() - _properties = newProperties - } - return _properties!! - } - - override val raw: Meta? get() = _properties - - override fun getValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - ): Value? { - raw?.get(name)?.value?.let { return it } - if (includeStyles) { - getStyleProperty(name)?.value?.let { return it } - } - if (inherit) { - parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } - } - return default?.get(name)?.value + protected var propertiesInternal: MutableMeta? = null + + final override val properties: MutableVisionProperties by lazy { + object : AbstractVisionProperties(this) { + override var properties: MutableMeta? + get() = propertiesInternal + set(value) { + propertiesInternal = value + } } - - override fun set(name: Name, node: Meta?) { - //TODO check old value? - if (name.isEmpty()) { - _properties = node?.asMutableMeta() - } else if (node == null) { - _properties?.setMeta(name, node) - } else { - getOrCreateProperties().setMeta(name, node) - } - invalidate(name) - } - - override fun setValue(name: Name, value: Value?) { - //TODO check old value? - if (value == null) { - _properties?.getMeta(name)?.value = null - } else { - getOrCreateProperties().setValue(name, value) - } - invalidate(name) - } - - @Transient - private val _changes = MutableSharedFlow(10) - override val changes: SharedFlow get() = _changes - - override fun invalidate(propertyName: Name) { - if (propertyName == Vision.STYLE_KEY) { - styles.asSequence() - .mapNotNull { getStyle(it) } - .flatMap { it.items.asSequence() } - .distinctBy { it.key } - .forEach { - invalidate(it.key.asName()) - } - } - manager.context.launch { - _changes.emit(propertyName) - } - } - } override val descriptor: MetaDescriptor? get() = null - - - override fun update(change: VisionChange) { - change.properties?.let { - updateProperties(it, Name.EMPTY) - } - } } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index e538b226..7bdcbe54 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -12,6 +12,7 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.values.asValue import space.kscience.dataforge.values.boolean +import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.TYPE import kotlin.reflect.KProperty1 @@ -37,7 +38,11 @@ public interface Vision : Described { /** * Update this vision using a dif represented by [VisionChange]. */ - public fun update(change: VisionChange) + public fun update(change: VisionChange) { + change.properties?.let { + updateProperties(it, Name.EMPTY) + } + } override val descriptor: MetaDescriptor? diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index 4ce69047..529c01a1 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import space.kscience.dataforge.names.* +import kotlin.jvm.Synchronized @DslMarker public annotation class VisionBuilder @@ -113,8 +114,15 @@ internal abstract class VisionChildrenImpl( private val updateJobs = HashMap() - abstract val items: MutableMap? - abstract fun buildItems(): MutableMap + abstract var items: MutableMap? + + @Synchronized + private fun buildItems(): MutableMap { + if (items == null) { + items = LinkedHashMap() + } + return items!! + } private val scope: CoroutineScope get() = group.manager.context diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index 9535fbd9..f666fcd8 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -11,7 +11,6 @@ import space.kscience.dataforge.names.plus import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.Vision.Companion.STYLE_KEY import kotlin.js.JsName -import kotlin.jvm.Synchronized public interface VisionGroup : Vision { @@ -47,26 +46,20 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup } @SerialName("children") - protected var _children: MutableMap? = null + protected var childrenInternal: MutableMap? = null init { - _children?.forEach { it.value.parent = this } + childrenInternal?.forEach { it.value.parent = this } } override val children: MutableVisionChildren by lazy { - object : VisionChildrenImpl(this){ - override val items: MutableMap? - get() = this@AbstractVisionGroup._children - - @Synchronized - override fun buildItems(): MutableMap { - if (_children == null) { - _children = LinkedHashMap() + object : VisionChildrenImpl(this) { + override var items: MutableMap? + get() = this@AbstractVisionGroup.childrenInternal + set(value) { + this@AbstractVisionGroup.childrenInternal = value } - return _children!! - } - } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index b4ca16ec..a750df5b 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -1,17 +1,20 @@ package space.kscience.visionforge import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.launch +import kotlinx.serialization.Transient import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.asMutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.meta.get -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.NameToken -import space.kscience.dataforge.names.parseAsName -import space.kscience.dataforge.names.plus +import space.kscience.dataforge.names.* import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.asValue +import kotlin.jvm.Synchronized public interface VisionProperties { @@ -21,7 +24,6 @@ public interface VisionProperties { public val raw: Meta? public val descriptor: MetaDescriptor? - public val default: Meta? public fun getValue( name: Name, @@ -130,6 +132,83 @@ private class VisionPropertiesItem( override fun hashCode(): Int = Meta.hashCode(this) } +public abstract class AbstractVisionProperties( + private val vision: Vision, +) : MutableVisionProperties { + override val descriptor: MetaDescriptor? get() = vision.descriptor + protected val default: Meta? get() = descriptor?.defaultNode + + protected abstract var properties: MutableMeta? + + override val raw: Meta? get() = properties + + @Synchronized + protected fun getOrCreateProperties(): MutableMeta { + if (properties == null) { + //TODO check performance issues + val newProperties = MutableMeta() + properties = newProperties + } + return properties!! + } + + override fun getValue( + name: Name, + inherit: Boolean, + includeStyles: Boolean, + ): Value? { + raw?.get(name)?.value?.let { return it } + if (includeStyles) { + vision.getStyleProperty(name)?.value?.let { return it } + } + if (inherit) { + vision.parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } + } + return default?.get(name)?.value + } + + override fun set(name: Name, node: Meta?) { + //TODO check old value? + if (name.isEmpty()) { + properties = node?.asMutableMeta() + } else if (node == null) { + properties?.setMeta(name, node) + } else { + getOrCreateProperties().setMeta(name, node) + } + invalidate(name) + } + + override fun setValue(name: Name, value: Value?) { + //TODO check old value? + if (value == null) { + properties?.getMeta(name)?.value = null + } else { + getOrCreateProperties().setValue(name, value) + } + invalidate(name) + } + + @Transient + private val _changes = MutableSharedFlow(10) + override val changes: SharedFlow get() = _changes + + override fun invalidate(propertyName: Name) { + if (propertyName == Vision.STYLE_KEY) { + vision.styles.asSequence() + .mapNotNull { vision.getStyle(it) } + .flatMap { it.items.asSequence() } + .distinctBy { it.key } + .forEach { + invalidate(it.key.asName()) + } + } + vision.manager.context.launch { + _changes.emit(propertyName) + } + } +} + public fun VisionProperties.getValue( name: Name, inherit: Boolean? = null, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index aa79734f..5428a7dd 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -28,7 +28,10 @@ public val Vision.unref: Solid @SerialName("solid.ref") public class SolidReference( @SerialName("prototype") public val prototypeName: Name, -) : SolidBase(), VisionGroup { +) : VisionGroup, Solid { + + @Transient + override var parent: Vision? = null /** * The prototype for this reference. @@ -40,11 +43,30 @@ public class SolidReference( (parent as? PrototypeHolder)?.getPrototype(prototypeName) ?: error("Prototype with name $prototypeName not found") } - override val descriptor: MetaDescriptor get() = prototype.descriptor - override val defaultProperties: Meta - get() = prototype.properties.raw?.withDefault(descriptor.defaultNode) ?: descriptor.defaultNode + @SerialName("properties") + private var propertiesInternal: MutableMeta? = null + + override val properties: MutableVisionProperties by lazy { + object : AbstractVisionProperties(this) { + override var properties: MutableMeta? + get() = propertiesInternal + set(value) { + propertiesInternal = value + } + + override val raw: Meta? get() = properties + + override fun get(name: Name, inherit: Boolean, includeStyles: Boolean): MutableMeta { + return properties?.getMeta(name) ?: prototype.properties.get(name, inherit, includeStyles) + } + + override fun getValue(name: Name, inherit: Boolean, includeStyles: Boolean): Value? { + return properties?.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) + } + } + } override val children: VisionChildren get() = object : VisionChildren { @@ -66,7 +88,7 @@ public class SolidReference( } /** - * @param name A name of reference child relative to prototype root + * @param childName A name of reference child relative to prototype root */ internal class SolidReferenceChild( val owner: SolidReference, @@ -83,25 +105,17 @@ internal class SolidReferenceChild( @Transient override val properties: MutableVisionProperties = object : MutableVisionProperties { override val descriptor: MetaDescriptor get() = this@SolidReferenceChild.descriptor - override val default: Meta - get() = prototype.properties.raw?.withDefault(descriptor.defaultNode) ?: descriptor.defaultNode override val raw: MutableMeta by lazy { owner.properties[childToken(childName).asName()] } + override fun get(name: Name, inherit: Boolean, includeStyles: Boolean): MutableMeta = + raw.getMeta(name) ?: prototype.properties.get(name, inherit, includeStyles) + override fun getValue( name: Name, inherit: Boolean, includeStyles: Boolean, - ): Value? { - raw[name]?.value?.let { return it } - if (includeStyles) { - getStyleProperty(name)?.value?.let { return it } - } - if (inherit) { - parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } - } - return default[name]?.value - } + ): Value? = raw.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) override fun set(name: Name, node: Meta?) { raw.setMeta(name, node) @@ -110,6 +124,7 @@ internal class SolidReferenceChild( override fun setValue(name: Name, value: Value?) { raw.setValue(name, value) } + override val changes: Flow get() = owner.properties.changes.filter { it.startsWith(childToken(childName)) } override fun invalidate(propertyName: Name) { From 9221df785d2553b7890957fa1d7078e132db37a6 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 9 Aug 2022 14:53:46 +0300 Subject: [PATCH 013/112] [WIP] Completed solid refactoring --- build.gradle.kts | 2 +- .../kotlin/ru/mipt/npm/root/DObject.kt | 1 - .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 10 +++---- .../mipt/npm/root/serialization/jsonToRoot.kt | 7 +++-- .../visionforge/gdml/GDMLVisionTest.kt | 2 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 2 +- .../src/jvmMain/kotlin/allThingsDemo.kt | 2 +- .../src/jvmMain/kotlin/rootParser.kt | 2 +- demo/playground/src/jvmMain/kotlin/tables.kt | 2 +- .../visionforge/solid/demo/VariableBox.kt | 2 +- .../visionforge/solid/demo/MetaEditorDemo.kt | 2 +- .../visionforge/react/MultiSelectChooser.kt | 4 +-- .../visionforge/react/RangeValueChooser.kt | 2 +- .../visionforge/react/valueChooser.kt | 4 --- .../space/kscience/visionforge/Colors.kt | 7 +---- .../space/kscience/visionforge/StyleSheet.kt | 2 -- .../space/kscience/visionforge/Vision.kt | 4 +-- .../kscience/visionforge/VisionChange.kt | 1 - .../space/kscience/visionforge/VisionGroup.kt | 2 +- .../kscience/visionforge/VisionProperties.kt | 7 +---- .../kscience/visionforge/visionDescriptor.kt | 3 +- .../visionforge/meta/VisionPropertyTest.kt | 8 +---- .../visionforge/editor/ColorValueChooser.kt | 6 +--- .../editor/ComboBoxValueChooser.kt | 6 +--- .../visionforge/editor/FXMetaModel.kt | 6 +--- .../kscience/visionforge/editor/MetaViewer.kt | 2 +- .../visionforge/editor/TextValueChooser.kt | 3 +- .../visionforge/editor/ValueCallback.kt | 2 +- .../visionforge/editor/ValueChooser.kt | 4 +-- .../visionforge/editor/ValueChooserBase.kt | 4 +-- .../editor/VisionEditorFragment.kt | 5 ++-- .../kscience/visionforge/solid/FX3DPlugin.kt | 3 +- .../kscience/visionforge/solid/FXMaterials.kt | 8 +---- .../solid/VisualObjectFXBinding.kt | 7 +++-- .../kscience/visionforge/gdml/gdmlLoader.kt | 2 +- .../visionforge/markup/VisionOfMarkup.kt | 10 +++---- .../visionforge/plotly/VisionOfPlotly.kt | 5 ++-- .../visionforge/solid/ColorAccessor.kt | 2 +- .../kscience/visionforge/solid/LightSource.kt | 2 +- .../space/kscience/visionforge/solid/Solid.kt | 4 +-- .../visionforge/solid/SolidMaterial.kt | 5 +--- .../visionforge/solid/SolidReference.kt | 1 - .../solid/specifications/Canvas3DOptions.kt | 2 +- .../visionforge/solid/DescriptorTest.kt | 2 +- .../visionforge/solid/PropertyTest.kt | 4 +-- .../visionforge/solid/VisionUpdateTest.kt | 2 +- .../visionforge/tables/VisionOfTable.kt | 13 ++++----- .../visionforge/tables/VisionOfTableTest.kt | 8 ++--- .../solid/three/MeshThreeFactory.kt | 11 +++---- .../solid/three/ThreeCanvasLabelFactory.kt | 3 +- .../visionforge/solid/three/ThreeJsVision.kt | 2 +- .../solid/three/ThreeLineFactory.kt | 3 +- .../visionforge/solid/three/ThreeMaterials.kt | 29 +++++++------------ 53 files changed, 97 insertions(+), 147 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f0c9d504..d02cd7c5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ plugins { // id("org.jetbrains.kotlinx.kover") version "0.5.0" } -val dataforgeVersion by extra("0.6.0-dev-12") +val dataforgeVersion by extra("0.6.0-dev-13") val fxVersion by extra("11") allprojects{ diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt index 5af50c3f..8b67c108 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt @@ -5,7 +5,6 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.misc.Named import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.doubleArray import kotlin.properties.ReadOnlyProperty public fun MetaProvider.doubleArray( diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 8cc4c258..48a21ff1 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -1,13 +1,13 @@ package ru.mipt.npm.root import space.kscience.dataforge.meta.double +import space.kscience.dataforge.meta.doubleArray import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.doubleArray import space.kscience.visionforge.isEmpty -import space.kscience.visionforge.setPropertyValue +import space.kscience.visionforge.set import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY import kotlin.math.* @@ -321,7 +321,7 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? } return if (group.children.isEmpty()) { null - } else if (group.items.size == 1 && group.meta== null) { + } else if (group.items.size == 1 && group.properties.raw == null) { group.items.values.first().apply { parent = null } } else { group @@ -348,7 +348,7 @@ private fun SolidGroup.addRootVolume( if (!cache) { val group = buildVolume(volume, context)?.apply { volume.fFillColor?.let { - setPropertyValue(MATERIAL_COLOR_KEY, RootColors[it]) + properties[MATERIAL_COLOR_KEY] = RootColors[it] } block() } @@ -365,7 +365,7 @@ private fun SolidGroup.addRootVolume( ref(templateName, name).apply { volume.fFillColor?.let { - setPropertyValue(MATERIAL_COLOR_KEY, RootColors[it]) + properties[MATERIAL_COLOR_KEY] = RootColors[it] } block() } diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt index 5d338394..b4a63748 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt @@ -14,7 +14,7 @@ import kotlinx.serialization.modules.subclass private fun jsonRootDeserializer( tSerializer: KSerializer, - builder: (JsonElement) -> T + builder: (JsonElement) -> T, ): DeserializationStrategy = object : DeserializationStrategy { private val jsonElementSerializer = JsonElement.serializer() @@ -46,6 +46,7 @@ private object RootDecoder { private val refCache: List, ) : KSerializer by tSerializer { + @OptIn(ExperimentalSerializationApi::class) @Suppress("UNCHECKED_CAST") override fun deserialize(decoder: Decoder): T { val input = decoder as JsonDecoder @@ -92,7 +93,7 @@ private object RootDecoder { @OptIn(ExperimentalSerializationApi::class) fun unrefSerializersModule( - refCache: List + refCache: List, ): SerializersModule = SerializersModule { contextual(TObjArray::class) { @@ -197,11 +198,13 @@ private object RootDecoder { fillCache(it) } } + is JsonArray -> { element.forEach { fillCache(it) } } + else -> { //ignore primitives } diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index c46f49ff..0f74e9a8 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -1,8 +1,8 @@ package space.kscience.visionforge.gdml +import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.asValue import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Vision import space.kscience.visionforge.get diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index dff6da3f..4bf18124 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -69,7 +69,7 @@ class Model(val manager: VisionManager) { fun reset() { map.values.forEach { - it.setPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY, null) + it.properties[SolidMaterial.MATERIAL_COLOR_KEY] = null } tracks.children.clear() } diff --git a/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt b/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt index 23b73af4..328387c1 100644 --- a/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt +++ b/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.examples import kotlinx.html.h2 -import space.kscience.dataforge.values.ValueType +import space.kscience.dataforge.meta.ValueType import space.kscience.plotly.layout import space.kscience.plotly.models.ScatterMode import space.kscience.plotly.models.TextPosition diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/rootParser.kt index 184557da..f88793ee 100644 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ b/demo/playground/src/jvmMain/kotlin/rootParser.kt @@ -6,7 +6,7 @@ import ru.mipt.npm.root.toSolid import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.isLeaf -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.string import space.kscience.visionforge.solid.Solids import java.nio.file.Paths import java.util.zip.ZipInputStream diff --git a/demo/playground/src/jvmMain/kotlin/tables.kt b/demo/playground/src/jvmMain/kotlin/tables.kt index 46cad89d..ab27ebdf 100644 --- a/demo/playground/src/jvmMain/kotlin/tables.kt +++ b/demo/playground/src/jvmMain/kotlin/tables.kt @@ -1,6 +1,6 @@ package space.kscience.visionforge.examples -import space.kscience.dataforge.values.ValueType +import space.kscience.dataforge.meta.ValueType import space.kscience.tables.ColumnHeader import space.kscience.tables.valueRow import space.kscience.visionforge.html.ResourceLocation diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index d429cafb..4ddc185a 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -3,12 +3,12 @@ package space.kscience.visionforge.solid.demo import info.laht.threekt.core.Object3D import info.laht.threekt.geometries.BoxGeometry import info.laht.threekt.objects.Mesh +import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.number import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.asValue import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.set import space.kscience.visionforge.solid.SolidGroup diff --git a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt b/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt index 3cdf058e..a4217555 100644 --- a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt +++ b/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt @@ -2,10 +2,10 @@ package space.kscience.visionforge.demo import javafx.geometry.Orientation import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.ValueType import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.node import space.kscience.dataforge.meta.descriptors.value -import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.editor.FXMetaModel import space.kscience.visionforge.editor.MetaViewer import space.kscience.visionforge.editor.MutableMetaEditor diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt index f3c81a57..612fdfe6 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt @@ -10,9 +10,9 @@ import react.dom.attrs import react.dom.option import react.dom.select import react.fc +import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.descriptors.allowedValues -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.string @JsExport public val MultiSelectChooser: FC = fc("MultiSelectChooser") { props -> diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index 8ccedc01..382209c2 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -10,11 +10,11 @@ import react.FC import react.dom.attrs import react.fc import react.useState +import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.descriptors.ValueRequirement import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.string -import space.kscience.dataforge.values.asValue import styled.css import styled.styledInput diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index 03996c04..cd769414 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -19,10 +19,6 @@ import react.useState import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.allowedValues -import space.kscience.dataforge.values.ValueType -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.int -import space.kscience.dataforge.values.string import space.kscience.visionforge.Colors import space.kscience.visionforge.widgetType import styled.css diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Colors.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Colors.kt index 58be399e..ad4a4c0e 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Colors.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Colors.kt @@ -1,11 +1,6 @@ package space.kscience.visionforge -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.number -import space.kscience.dataforge.values.ValueType -import space.kscience.dataforge.values.int -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.* import kotlin.math.max /** diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index aed19706..9fc148b3 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -5,8 +5,6 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.stringList import kotlin.jvm.JvmInline /** diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 7bdcbe54..9b8304de 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -4,14 +4,14 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import space.kscience.dataforge.context.Global +import space.kscience.dataforge.meta.asValue +import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.descriptors.Described import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.boolean import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.TYPE import kotlin.reflect.KProperty1 diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 33bbd5ca..d0a7ec70 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -9,7 +9,6 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.Null import kotlin.jvm.Synchronized import kotlin.time.Duration diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index f666fcd8..8faa21b4 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -3,12 +3,12 @@ package space.kscience.visionforge import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.ValueType import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.Vision.Companion.STYLE_KEY import kotlin.js.JsName diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index a750df5b..7b6c6e7b 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -5,15 +5,10 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch import kotlinx.serialization.Transient -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.asMutableMeta +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue import kotlin.jvm.Synchronized public interface VisionProperties { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt index 3fa6703f..66ee43e0 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt @@ -2,8 +2,7 @@ package space.kscience.visionforge import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.* -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.set +import space.kscience.dataforge.meta.set private const val INHERITED_DESCRIPTOR_ATTRIBUTE = "inherited" private const val STYLE_DESCRIPTOR_ATTRIBUTE = "useStyles" diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index f488bcf7..23517112 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -1,12 +1,6 @@ package space.kscience.visionforge.meta -import space.kscience.dataforge.meta.Scheme -import space.kscience.dataforge.meta.SchemeSpec -import space.kscience.dataforge.meta.int -import space.kscience.dataforge.meta.updateWith -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.boolean -import space.kscience.dataforge.values.int +import space.kscience.dataforge.meta.* import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.get import space.kscience.visionforge.getValue diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ColorValueChooser.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ColorValueChooser.kt index 442c299f..1161d5bf 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ColorValueChooser.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ColorValueChooser.kt @@ -3,13 +3,9 @@ package space.kscience.visionforge.editor import javafx.scene.control.ColorPicker import javafx.scene.paint.Color import org.slf4j.LoggerFactory -import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.Null -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.string import tornadofx.* /** diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ComboBoxValueChooser.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ComboBoxValueChooser.kt index a99599ee..a4c4e583 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ComboBoxValueChooser.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ComboBoxValueChooser.kt @@ -8,14 +8,10 @@ package space.kscience.visionforge.editor import javafx.collections.FXCollections import javafx.scene.control.ComboBox import javafx.util.StringConverter -import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.allowedValues -import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.parseValue -import space.kscience.dataforge.values.string import java.util.* public class ComboBoxValueChooser(public val values: Collection? = null) : ValueChooserBase>() { diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/FXMetaModel.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/FXMetaModel.kt index 7d8e71b2..8c3d2584 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/FXMetaModel.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/FXMetaModel.kt @@ -5,14 +5,10 @@ import javafx.beans.binding.BooleanBinding import javafx.beans.binding.ListBinding import javafx.beans.binding.ObjectBinding import javafx.collections.ObservableList -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.ObservableMeta -import space.kscience.dataforge.meta.boolean +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.Value import tornadofx.* /** diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/MetaViewer.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/MetaViewer.kt index 4563ade5..144b018e 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/MetaViewer.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/MetaViewer.kt @@ -21,7 +21,7 @@ import javafx.scene.control.TreeSortMode import javafx.scene.control.TreeTableView import javafx.scene.layout.BorderPane import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.string import space.kscience.visionforge.dfIconView import tornadofx.* diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/TextValueChooser.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/TextValueChooser.kt index 9a1840ce..fd86ec72 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/TextValueChooser.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/TextValueChooser.kt @@ -9,11 +9,10 @@ import javafx.beans.value.ObservableValue import javafx.scene.control.TextField import javafx.scene.input.KeyCode import javafx.scene.input.KeyEvent -import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.validate import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.* import tornadofx.* public class TextValueChooser : ValueChooserBase() { diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueCallback.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueCallback.kt index a4e72871..c6d654f5 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueCallback.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueCallback.kt @@ -5,7 +5,7 @@ */ package space.kscience.visionforge.editor -import space.kscience.dataforge.values.Value +import space.kscience.dataforge.meta.Value /** diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooser.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooser.kt index f62513b0..ea43547c 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooser.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooser.kt @@ -10,14 +10,14 @@ import javafx.beans.value.ObservableValue import javafx.scene.Node import space.kscience.dataforge.context.Context import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.Null +import space.kscience.dataforge.meta.Value import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.allowedValues import space.kscience.dataforge.meta.descriptors.validate import space.kscience.dataforge.misc.Named import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.Null -import space.kscience.dataforge.values.Value import space.kscience.visionforge.widget import space.kscience.visionforge.widgetType import tornadofx.* diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooserBase.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooserBase.kt index e9b61886..a9adae8f 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooserBase.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooserBase.kt @@ -8,9 +8,9 @@ package space.kscience.visionforge.editor import javafx.beans.property.SimpleObjectProperty import javafx.scene.Node import org.slf4j.LoggerFactory +import space.kscience.dataforge.meta.Null +import space.kscience.dataforge.meta.Value import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.values.Null -import space.kscience.dataforge.values.Value import tornadofx.* /** diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt index 0185dc43..0fcc45f3 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt @@ -10,6 +10,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.getStyle +import space.kscience.visionforge.root import space.kscience.visionforge.styles import tornadofx.* @@ -20,7 +21,7 @@ public class VisionEditorFragment : Fragment() { public val descriptorProperty: SimpleObjectProperty = SimpleObjectProperty() private val configProperty: Binding = visionProperty.objectBinding { vision -> - vision?.getProperty(Name.EMPTY) + vision?.properties?.root() } private val configEditorProperty: Binding = configProperty.objectBinding(descriptorProperty) { @@ -28,7 +29,7 @@ public class VisionEditorFragment : Fragment() { val node:FXMetaModel = FXMetaModel( meta, vision?.descriptor, - vision?.meta, + vision?.properties?.root(), Name.EMPTY, "Vision properties" ) diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt index 90c94b35..bac388ee 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt @@ -16,6 +16,7 @@ import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.misc.Type +import space.kscience.visionforge.get import space.kscience.visionforge.solid.FX3DFactory.Companion.TYPE import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_WIREFRAME_KEY @@ -76,7 +77,7 @@ public class FX3DPlugin : AbstractPlugin() { is PolyLine -> PolyLine3D( obj.points.map { Point3D(it.x, it.y, it.z) }, obj.thickness.toFloat(), - obj.get(SolidMaterial.MATERIAL_COLOR_KEY).color() + obj.properties.get(SolidMaterial.MATERIAL_COLOR_KEY).color() ).apply { this.meshView.cullFace = CullFace.FRONT } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXMaterials.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXMaterials.kt index ca5e6583..81bbad5b 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXMaterials.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXMaterials.kt @@ -3,13 +3,7 @@ package space.kscience.visionforge.solid import javafx.scene.paint.Color import javafx.scene.paint.Material import javafx.scene.paint.PhongMaterial -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.double -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.int -import space.kscience.dataforge.values.ValueType -import space.kscience.dataforge.values.int -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.* import space.kscience.visionforge.Colors import space.kscience.visionforge.solid.FXMaterials.GREY diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt index 78d02164..8d3e2836 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt @@ -5,8 +5,8 @@ import javafx.beans.binding.* import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.Value import space.kscience.visionforge.Vision +import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange import tornadofx.* @@ -35,7 +35,7 @@ public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vi public operator fun get(key: Name): ObjectBinding { return bindings.getOrPut(key) { object : ObjectBinding() { - override fun computeValue(): Meta = obj.getProperty(key) + override fun computeValue(): Meta = obj.properties[key] } } } @@ -57,4 +57,5 @@ public fun ObjectBinding.float(default: Float): FloatBinding = floatBindi public fun ObjectBinding.int(default: Int): IntegerBinding = integerBinding { it.int ?: default } public fun ObjectBinding.long(default: Long): LongBinding = longBinding { it.long ?: default } -public fun ObjectBinding.transform(transform: (Meta) -> T): Binding = objectBinding { it?.let(transform) } +public fun ObjectBinding.transform(transform: (Meta) -> T): Binding = + objectBinding { it?.let(transform) } diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index 34a9afa2..a102b2b3 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -30,7 +30,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { private val proto = SolidGroup() private val solids = proto.group(solidsName) { - setPropertyValue("edges.enabled", false) + properties["edges.enabled"] = false } private val referenceStore = HashMap>() diff --git a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt index 93e7359e..ace39d2b 100644 --- a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt +++ b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt @@ -8,19 +8,19 @@ import kotlinx.serialization.modules.subclass import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName +import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionGroup -import space.kscience.visionforge.properties +import space.kscience.visionforge.root @Serializable @SerialName("vision.markup") public class VisionOfMarkup( - public val format: String = COMMONMARK_FORMAT -) : VisionGroup() { + public val format: String = COMMONMARK_FORMAT, +) : AbstractVision() { //TODO add templates - public var content: String? by properties().string(CONTENT_PROPERTY_KEY) + public var content: String? by properties.root().string(CONTENT_PROPERTY_KEY) public companion object { public val CONTENT_PROPERTY_KEY: Name = "content".asName() diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index 732358bf..c23de631 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -9,16 +9,17 @@ import space.kscience.plotly.Plot import space.kscience.plotly.Plotly import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.html.VisionOutput +import space.kscience.visionforge.root @Serializable @SerialName("vision.plotly") public class VisionOfPlotly private constructor() : AbstractVision() { public constructor(plot: Plot) : this() { - setProperty(Name.EMPTY, plot.meta) + properties[Name.EMPTY] = plot.meta } - public val plot: Plot get() = Plot(getProperty(Name.EMPTY).asObservable()) + public val plot: Plot get() = Plot(properties.root().asObservable()) } public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index 62a3b2a0..dde24ef0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.solid +import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.* import space.kscience.visionforge.Colors import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionBuilder diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt index 3f90d903..13736fcd 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -2,11 +2,11 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.ValueType import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.node import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.meta.number -import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.* @Serializable diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 1cfc1d3b..d932a4b3 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -1,15 +1,13 @@ package space.kscience.visionforge.solid +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.enum import space.kscience.dataforge.meta.descriptors.node import space.kscience.dataforge.meta.descriptors.value -import space.kscience.dataforge.meta.float -import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.* import space.kscience.visionforge.* import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index 87a39ac4..e8da3499 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -3,13 +3,10 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.ValueType -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.number -import space.kscience.dataforge.values.set import space.kscience.visionforge.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 5428a7dd..e071d07b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -7,7 +7,6 @@ import kotlinx.serialization.Transient import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.Value import space.kscience.visionforge.* import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt index aa53d424..78e35dfa 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt @@ -4,8 +4,8 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.scheme import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.set import space.kscience.visionforge.hide import space.kscience.visionforge.widgetType diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/DescriptorTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/DescriptorTest.kt index 6f004f5c..87527802 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/DescriptorTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/DescriptorTest.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid +import space.kscience.dataforge.meta.ValueType import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.solid.specifications.Canvas3DOptions import kotlin.test.Test import kotlin.test.assertNotNull diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt index bb6f5de1..2eb4c65d 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt @@ -4,9 +4,9 @@ import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import kotlinx.coroutines.withTimeout +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.int -import space.kscience.dataforge.values.string import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 026499f4..e5a13594 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -3,8 +3,8 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.fetch import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.asValue import space.kscience.visionforge.VisionChange import space.kscience.visionforge.get import kotlin.test.Test diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt index cb870da8..20332974 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt @@ -8,13 +8,10 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import space.kscience.dataforge.meta.* import space.kscience.dataforge.misc.DFExperimental -import space.kscience.dataforge.values.Null -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue import space.kscience.tables.* import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.html.VisionOutput -import space.kscience.visionforge.properties +import space.kscience.visionforge.root import kotlin.jvm.JvmName import kotlin.reflect.typeOf @@ -45,14 +42,14 @@ public class VisionOfTable( ) : AbstractVision(), Rows { public var data: List - get() = meta?.getIndexed("rows")?.entries?.sortedBy { + get() = properties.root().getIndexed("rows").entries.sortedBy { it.key?.toInt() - }?.map { + }.map { it.value - } ?: emptyList() + } set(value) { //TODO Make it better - properties()["rows"] = value + properties.root()["rows"] = value } public val rows: List get() = data.map(::MetaRow) diff --git a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt index 8c9f755c..e3b199d1 100644 --- a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt +++ b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.tables -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.double -import space.kscience.dataforge.values.int +import space.kscience.dataforge.meta.Value +import space.kscience.dataforge.meta.asValue +import space.kscience.dataforge.meta.double +import space.kscience.dataforge.meta.int import space.kscience.tables.ColumnHeader import space.kscience.tables.ColumnTable import space.kscience.tables.get diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt index b7d8244d..04f192fd 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt @@ -10,8 +10,9 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange -import space.kscience.visionforge.setPropertyValue +import space.kscience.visionforge.set import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.layer @@ -76,8 +77,8 @@ public abstract class MeshThreeFactory( @VisionBuilder public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { - setPropertyValue(EDGES_ENABLED_KEY, enabled) - SolidMaterial.write(getProperty(EDGES_MATERIAL_KEY)).apply(block) + properties.set(EDGES_ENABLED_KEY, enabled) + SolidMaterial.write(properties[EDGES_MATERIAL_KEY]).apply(block) } internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { @@ -93,9 +94,9 @@ internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { public fun Mesh.applyEdges(obj: Solid) { val edges = children.find { it.name == "@edges" } as? LineSegments //inherited edges definition, enabled by default - if (obj.getProperty(EDGES_ENABLED_KEY, inherit = true).boolean != false) { + if (obj.properties.get(EDGES_ENABLED_KEY, inherit = true).boolean != false) { val bufferGeometry = geometry as? BufferGeometry ?: return - val material = ThreeMaterials.getLineMaterial(obj.getProperty(EDGES_MATERIAL_KEY), true) + val material = ThreeMaterials.getLineMaterial(obj.properties[EDGES_MATERIAL_KEY], true) if (edges == null) { add( LineSegments( diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index 42a8b6e6..8108389e 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -11,6 +11,7 @@ import org.w3c.dom.CanvasRenderingContext2D import org.w3c.dom.CanvasTextBaseline import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.MIDDLE +import space.kscience.visionforge.get import space.kscience.visionforge.solid.SolidLabel import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG @@ -26,7 +27,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory { val canvas = document.createElement("canvas") as HTMLCanvasElement val context = canvas.getContext("2d") as CanvasRenderingContext2D context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.get(SolidMaterial.MATERIAL_COLOR_KEY)?.value ?: "black" + context.fillStyle = obj.properties[SolidMaterial.MATERIAL_COLOR_KEY].value ?: "black" context.textBaseline = CanvasTextBaseline.MIDDLE val metrics = context.measureText(obj.text) //canvas.width = metrics.width.toInt() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt index 27a5da44..7c709a5c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt @@ -6,6 +6,6 @@ import space.kscience.visionforge.solid.SolidBase /** * A custom visual object that has its own Three.js renderer */ -public abstract class ThreeJsVision : SolidBase() { +public abstract class ThreeJsVision : SolidBase() { public abstract fun render(three: ThreePlugin): Object3D } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index 6e9c7472..70938e99 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -4,6 +4,7 @@ import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.math.Color import info.laht.threekt.objects.LineSegments +import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial @@ -24,7 +25,7 @@ public object ThreeLineFactory : ThreeFactory { } val material = ThreeMaterials.getLineMaterial( - obj.get(SolidMaterial.MATERIAL_KEY), + obj.properties[SolidMaterial.MATERIAL_KEY], false ) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index e0f3a4a6..a9f68f69 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -10,11 +10,7 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.* -import space.kscience.visionforge.Colors -import space.kscience.visionforge.Vision -import space.kscience.visionforge.computePropertyNode -import space.kscience.visionforge.getStyleNodes +import space.kscience.visionforge.* import space.kscience.visionforge.solid.ColorAccessor import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.SolidReference @@ -98,7 +94,8 @@ public object ThreeMaterials { * Compute color */ public fun Meta.threeColor(): Color? { - val value = getValue(Name.EMPTY) + if(isEmpty()) return null + val value = value return if (isLeaf) { when { value == null -> null @@ -132,19 +129,15 @@ private var Material.cached: Boolean } public fun Mesh.updateMaterial(vision: Vision) { - val ownMaterialMeta = vision.meta.getMeta(SolidMaterial.MATERIAL_KEY) + val ownMaterialMeta = vision.properties.raw?.get(SolidMaterial.MATERIAL_KEY) if (ownMaterialMeta == null) { if (vision is SolidReference && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty()) { updateMaterial(vision.prototype) } else { - material = vision.computePropertyNode(SolidMaterial.MATERIAL_KEY)?.let { - ThreeMaterials.cacheMaterial(it) - } ?: ThreeMaterials.DEFAULT + material = ThreeMaterials.cacheMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]) } } else { - material = vision.computePropertyNode(SolidMaterial.MATERIAL_KEY)?.let { - ThreeMaterials.buildMaterial(it) - } ?: ThreeMaterials.DEFAULT + material = ThreeMaterials.buildMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]) } } @@ -159,19 +152,19 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { } else { when (propertyName) { SolidMaterial.MATERIAL_COLOR_KEY -> { - material.asDynamic().color = vision.computePropertyNode(SolidMaterial.MATERIAL_COLOR_KEY)?.threeColor() + material.asDynamic().color = vision.properties[SolidMaterial.MATERIAL_COLOR_KEY].threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.SPECULAR_COLOR_KEY -> { - material.asDynamic().specular = vision.computePropertyNode(SolidMaterial.SPECULAR_COLOR_KEY)?.threeColor() + material.asDynamic().specular = vision.properties[SolidMaterial.SPECULAR_COLOR_KEY].threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { - material.asDynamic().emissive = vision.computePropertyNode(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY)?.threeColor() + material.asDynamic().emissive = vision.properties[SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY].threeColor() ?: ThreeMaterials.BLACK_COLOR } SolidMaterial.MATERIAL_OPACITY_KEY -> { - val opacity = vision.getProperty( + val opacity = vision.properties.getValue( SolidMaterial.MATERIAL_OPACITY_KEY, inherit = true, )?.double ?: 1.0 @@ -179,7 +172,7 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { material.transparent = opacity < 1.0 } SolidMaterial.MATERIAL_WIREFRAME_KEY -> { - material.asDynamic().wireframe = vision.getProperty( + material.asDynamic().wireframe = vision.properties.getValue( SolidMaterial.MATERIAL_WIREFRAME_KEY, inherit = true, )?.boolean ?: false From 0ea1ee056a48c32538da677f57abbb56a59ea9b3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 12 Aug 2022 22:16:06 +0300 Subject: [PATCH 014/112] All tests pass --- build.gradle.kts | 2 +- cern-root-loader/build.gradle.kts | 2 +- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 2 +- demo/gdml/build.gradle.kts | 8 +- .../visionforge/gdml/GDMLVisionTest.kt | 7 +- .../visionforge/gdml/demo/GDMLAppComponent.kt | 3 +- .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 3 +- demo/js-playground/build.gradle.kts | 2 +- demo/muon-monitor/build.gradle.kts | 2 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 2 +- .../mipt/npm/muon/monitor/MMAppComponent.kt | 3 +- .../ru/mipt/npm/muon/monitor/MMDemoApp.kt | 1 + .../src/jsMain/resources/index.html | 1 - demo/sat-demo/build.gradle.kts | 2 +- demo/solid-showcase/build.gradle.kts | 6 +- .../visionforge/solid/demo/VariableBox.kt | 9 +- gradle.properties | 2 +- jupyter/build.gradle.kts | 4 +- .../visionforge-jupyter-gdml/build.gradle.kts | 4 +- settings.gradle.kts | 10 +- ui/bootstrap/build.gradle.kts | 2 +- .../visionforge/bootstrap/outputConfig.kt | 6 +- .../bootstrap/visionPropertyEditor.kt | 32 ++++-- ui/react/build.gradle.kts | 2 +- .../visionforge/react/MultiSelectChooser.kt | 2 +- .../visionforge/react/PropertyEditor.kt | 104 +++++++++++------- .../visionforge/react/RangeValueChooser.kt | 2 +- .../kscience/visionforge/react/VisionTree.kt | 13 ++- .../visionforge/react/valueChooser.kt | 16 +-- ui/ring/build.gradle.kts | 2 +- .../ThreeViewWithControls.kt | 42 ++++--- .../ringPropertyEditor.kt | 34 ++++-- .../ringThreeControls.kt | 6 +- visionforge-core/build.gradle.kts | 4 +- .../space/kscience/visionforge/StyleSheet.kt | 8 +- .../space/kscience/visionforge/Vision.kt | 14 ++- .../kscience/visionforge/VisionChange.kt | 6 +- .../kscience/visionforge/VisionContainer.kt | 6 +- .../kscience/visionforge/VisionManager.kt | 3 +- .../kscience/visionforge/VisionProperties.kt | 103 ++++++----------- .../visionforge/html/VisionOfHtmlInput.kt | 2 +- .../kscience/visionforge/html/HtmlTagTest.kt | 2 +- .../visionforge/meta/VisionPropertyTest.kt | 6 +- .../kscience/visionforge/VisionClient.kt | 2 +- visionforge-fx/build.gradle.kts | 8 +- .../kscience/visionforge/solid/FX3DPlugin.kt | 3 +- .../solid/VisualObjectFXBinding.kt | 3 +- visionforge-gdml/build.gradle.kts | 7 +- .../kscience/visionforge/gdml/markLayers.kt | 3 +- .../src/commonTest/kotlin/TestCubes.kt | 2 +- visionforge-markdown/build.gradle.kts | 2 +- visionforge-plotly/build.gradle.kts | 2 +- .../visionforge/plotly/VisionOfPlotly.kt | 2 +- visionforge-server/build.gradle.kts | 2 +- .../visionforge/server/VisionServer.kt | 1 + visionforge-solid/build.gradle.kts | 9 +- .../visionforge/solid/ColorAccessor.kt | 2 +- .../kscience/visionforge/solid/Composite.kt | 4 +- .../kscience/visionforge/solid/Extruded.kt | 2 +- .../kscience/visionforge/solid/PolyLine.kt | 2 +- .../space/kscience/visionforge/solid/Solid.kt | 4 +- .../kscience/visionforge/solid/SolidGroup.kt | 2 +- .../visionforge/solid/SolidMaterial.kt | 8 +- .../visionforge/solid/SolidReference.kt | 31 +++--- .../solid/transform/RemoveSingleChild.kt | 2 +- .../visionforge/solid/PropertyTest.kt | 9 +- .../visionforge/solid/SerializationTest.kt | 4 +- visionforge-tables/build.gradle.kts | 4 +- .../visionforge/tables/VisionOfTableTest.kt | 2 +- visionforge-threejs/build.gradle.kts | 2 +- .../solid/three/MeshThreeFactory.kt | 7 +- .../solid/three/ThreeCanvasLabelFactory.kt | 3 +- .../solid/three/ThreeLineFactory.kt | 3 +- .../visionforge/solid/three/ThreeMaterials.kt | 17 +-- .../visionforge/solid/three/ThreePlugin.kt | 17 +-- .../solid/three/ThreeReferenceFactory.kt | 21 ++-- .../build.gradle.kts | 2 +- 77 files changed, 372 insertions(+), 314 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index d02cd7c5..f2c4e6d5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.project") + id("space.kscience.gradle.project") // id("org.jetbrains.kotlinx.kover") version "0.5.0" } diff --git a/cern-root-loader/build.gradle.kts b/cern-root-loader/build.gradle.kts index fa26fab5..0ea3de8f 100644 --- a/cern-root-loader/build.gradle.kts +++ b/cern-root-loader/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } kscience{ diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 48a21ff1..a867f054 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -321,7 +321,7 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? } return if (group.children.isEmpty()) { null - } else if (group.items.size == 1 && group.properties.raw == null) { + } else if (group.items.size == 1 && group.properties.own == null) { group.items.values.first().apply { parent = null } } else { group diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index a6c3fb0a..39c82290 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -1,8 +1,8 @@ -import ru.mipt.npm.gradle.DependencyConfiguration -import ru.mipt.npm.gradle.FXModule +import space.kscience.gradle.DependencyConfiguration +import space.kscience.gradle.FXModule plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") application } @@ -36,7 +36,7 @@ kotlin { jvmMain { dependencies { implementation(project(":visionforge-fx")) - implementation("ch.qos.logback:logback-classic:1.2.5") + implementation("ch.qos.logback:logback-classic:1.2.11") } } jsMain { diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index 0f74e9a8..723edb3b 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -6,7 +6,6 @@ import space.kscience.dataforge.names.Name import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Vision import space.kscience.visionforge.get -import space.kscience.visionforge.getPropertyValue import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.material @@ -20,7 +19,7 @@ class GDMLVisionTest { @Test fun testCubesStyles(){ val segment = cubes.children["composite-000.segment-0"] as Solid - println(segment.getPropertyValue(Vision.STYLE_KEY)) + println(segment.properties.getValue(Vision.STYLE_KEY)) // println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY)) // println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY)) @@ -34,7 +33,7 @@ class GDMLVisionTest { fun testPrototypeProperty() { val child = cubes[Name.of("composite-000","segment-0")] assertNotNull(child) - child.setPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) - assertEquals("red", child.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string) + child.properties.setValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) + assertEquals("red", child.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string) } } \ No newline at end of file diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt index b28dec12..8f605ccd 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt @@ -26,6 +26,7 @@ import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.set import styled.css import styled.styledDiv @@ -56,7 +57,7 @@ val GDMLApp = fc("GDMLApp") { props -> console.info("Marking layers for file $name") markLayers() ambientLight { - color(Colors.white) + color.set(Colors.white) } } } diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index 1cd1b0ff..d4a80876 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -10,6 +10,7 @@ import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication import styled.injectGlobal @@ -46,7 +47,7 @@ private class GDMLDemoApp : Application { child(GDMLApp) { val vision = GdmlShowCase.cubes().toVision().apply { ambientLight { - color(Colors.white) + color.set(Colors.white) } } //println(context.plugins.fetch(VisionManager).encodeToString(vision)) diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index ccec7015..ada5841a 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } kscience{ diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index f3b1710c..ad37a7c2 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") application } diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 4bf18124..aeb0abd3 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -69,7 +69,7 @@ class Model(val manager: VisionManager) { fun reset() { map.values.forEach { - it.properties[SolidMaterial.MATERIAL_COLOR_KEY] = null + it.properties.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, null) } tracks.children.clear() } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index 77ad5845..20a33fe2 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -25,6 +25,7 @@ import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.tab import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.edges import styled.css @@ -57,7 +58,7 @@ val MMApp = fc("Muon monitor") { props -> props.model.root.apply { edges() ambientLight{ - color(Colors.white) + color.set(Colors.white) } } } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 17c3f149..9c96ad07 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -17,6 +17,7 @@ private class MMDemoApp : Application { val context = Context("MM-demo") { plugin(ThreePlugin) } + val visionManager = context.fetch(VisionManager) val model = Model(visionManager) diff --git a/demo/muon-monitor/src/jsMain/resources/index.html b/demo/muon-monitor/src/jsMain/resources/index.html index dbca2406..f9dee8bd 100644 --- a/demo/muon-monitor/src/jsMain/resources/index.html +++ b/demo/muon-monitor/src/jsMain/resources/index.html @@ -5,7 +5,6 @@ Three js demo for particle physics -
diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 267e4a82..e12b730f 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") application } diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index bc391b9d..d3e03135 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -1,8 +1,8 @@ -import ru.mipt.npm.gradle.DependencyConfiguration -import ru.mipt.npm.gradle.FXModule +import space.kscience.gradle.DependencyConfiguration +import space.kscience.gradle.FXModule plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") application } diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index 4ddc185a..56221efb 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -4,7 +4,6 @@ import info.laht.threekt.core.Object3D import info.laht.threekt.geometries.BoxGeometry import info.laht.threekt.objects.Mesh import space.kscience.dataforge.meta.asValue -import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.number import space.kscience.dataforge.names.asName @@ -43,13 +42,13 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision it.layers.enable(this@VariableBox.layer) } } - mesh.scale.z = meta[VALUE].number?.toDouble() ?: 1.0 + mesh.scale.z = properties.getValue(VALUE)?.number?.toDouble() ?: 1.0 //add listener to object properties onPropertyChange { name -> when { name == VALUE -> { - val value = meta[VALUE].int ?: 0 + val value = properties.getValue(VALUE)?.int ?: 0 val size = value.toFloat() / 255f * 20f mesh.scale.z = size.toDouble() mesh.position.z = size.toDouble() / 2 @@ -69,9 +68,9 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision } var value: Int - get() = meta[VALUE].int ?: 0 + get() = properties.getValue(VALUE)?.int ?: 0 set(value) { - setPropertyValue(VALUE, value.asValue()) + properties.setValue(VALUE, value.asValue()) } companion object { diff --git a/gradle.properties b/gradle.properties index 92f33679..aeb2ca21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,4 @@ kotlin.jupyter.add.scanner=false org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.11.8-kotlin-1.7.10 \ No newline at end of file +toolsVersion=0.12.0-kotlin-1.7.20-Beta \ No newline at end of file diff --git a/jupyter/build.gradle.kts b/jupyter/build.gradle.kts index 0b406250..45aaeaa3 100644 --- a/jupyter/build.gradle.kts +++ b/jupyter/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") id("org.jetbrains.kotlin.jupyter.api") } @@ -21,5 +21,5 @@ kotlin { } readme { - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL + maturity = space.kscience.gradle.Maturity.EXPERIMENTAL } \ No newline at end of file diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/jupyter/visionforge-jupyter-gdml/build.gradle.kts index 4a575602..3129de1e 100644 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ b/jupyter/visionforge-jupyter-gdml/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } description = "Jupyter api artifact for GDML rendering" @@ -56,5 +56,5 @@ kscience { } readme { - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL + maturity = space.kscience.gradle.Maturity.EXPERIMENTAL } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 3ae9f6f9..4215d150 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,10 +15,10 @@ pluginManagement { } plugins { - id("ru.mipt.npm.gradle.project") version toolsVersion - id("ru.mipt.npm.gradle.mpp") version toolsVersion - id("ru.mipt.npm.gradle.jvm") version toolsVersion - id("ru.mipt.npm.gradle.js") version toolsVersion + id("space.kscience.gradle.project") version toolsVersion + id("space.kscience.gradle.mpp") version toolsVersion + id("space.kscience.gradle.jvm") version toolsVersion + id("space.kscience.gradle.js") version toolsVersion } } @@ -34,7 +34,7 @@ dependencyResolutionManagement { versionCatalogs { create("npmlibs") { - from("ru.mipt.npm:version-catalog:$toolsVersion") + from("space.kscience:version-catalog:$toolsVersion") } } } diff --git a/ui/bootstrap/build.gradle.kts b/ui/bootstrap/build.gradle.kts index b1b0588e..c0b980d9 100644 --- a/ui/bootstrap/build.gradle.kts +++ b/ui/bootstrap/build.gradle.kts @@ -1,6 +1,6 @@ plugins { kotlin("js") - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } val dataforgeVersion: String by rootProject.extra diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt index 0d4e2dc7..deb63381 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.bootstrap +import kotlinx.coroutines.GlobalScope import kotlinx.css.BorderStyle import kotlinx.css.Color import kotlinx.css.padding @@ -15,7 +16,6 @@ import react.RBuilder import react.dom.attrs import react.dom.button import react.fc -import space.kscience.dataforge.meta.withDefault import space.kscience.visionforge.Vision import space.kscience.visionforge.encodeToString import space.kscience.visionforge.react.flexColumn @@ -69,8 +69,8 @@ public val CanvasControls: FC = fc("CanvasControls") { prop } } propertyEditor( - ownProperties = props.canvasOptions.meta, - allProperties = props.canvasOptions.meta.withDefault(Canvas3DOptions.descriptor.defaultNode), + scope = props.vision?.manager?.context ?: GlobalScope, + properties = props.canvasOptions.meta, descriptor = Canvas3DOptions.descriptor, expanded = false ) diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index 4393565a..b82d48fe 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -3,13 +3,16 @@ package space.kscience.visionforge.bootstrap import org.w3c.dom.Element import react.RBuilder import react.dom.client.createRoot +import react.key import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.get import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties import space.kscience.visionforge.getStyle +import space.kscience.visionforge.react.EditorPropertyState +import space.kscience.visionforge.react.PropertyEditor import space.kscience.visionforge.react.metaViewer -import space.kscience.visionforge.react.propertyEditor import space.kscience.visionforge.react.render +import space.kscience.visionforge.root import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.styles @@ -20,12 +23,25 @@ public fun RBuilder.visionPropertyEditor( ) { card("Properties") { - propertyEditor( - ownProperties = vision.meta, - allProperties = vision.computeProperties(), - descriptor = descriptor, - key = key - ) + child(PropertyEditor){ + attrs{ + this.key = key?.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = descriptor + this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") + this.getPropertyState = {name-> + if(vision.properties.own?.get(name)!= null){ + EditorPropertyState.Defined + } else if(vision.properties.root()[name] != null){ + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } } val styles = if (vision is SolidReference) { (vision.styles + vision.prototype.styles).distinct() diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index d71dc6ac..1a58d333 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } dependencies{ diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt index 612fdfe6..fb339429 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt @@ -25,7 +25,7 @@ public val MultiSelectChooser: FC = fc("MultiSelectChooser") select { attrs { multiple = true - values = (props.actual.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } + values = (props.meta.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } onChangeFunction = onChange } props.descriptor?.allowedValues?.forEach { optionValue -> diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index 29c9b49e..4e94ef06 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -1,13 +1,18 @@ package space.kscience.visionforge.react +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import kotlinx.css.* import kotlinx.css.properties.TextDecoration import kotlinx.html.js.onClickFunction -import org.w3c.dom.Element import org.w3c.dom.events.Event import react.* import react.dom.attrs -import react.dom.client.createRoot import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.ValueRequirement @@ -19,17 +24,30 @@ import styled.styledButton import styled.styledDiv import styled.styledSpan +/** + * The display state of a property + */ +public sealed class EditorPropertyState { + public object Defined : EditorPropertyState() + public class Default(public val source: String = "unknown") : EditorPropertyState() + + public object Undefined : EditorPropertyState() + +} + + public external interface PropertyEditorProps : Props { /** * Root config object - always non-null */ - public var meta: ObservableMutableMeta + public var meta: MutableMeta - /** - * Provide default item (greyed out if used) - */ - public var withDefault: MetaProvider + public var getPropertyState: (Name) -> EditorPropertyState + + public var scope: CoroutineScope + + public var updates: Flow /** * Full path to the displayed node in [meta]. Could be empty @@ -54,7 +72,7 @@ private val PropertyEditorItem: FC = fc("PropertyEditorItem private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { var expanded: Boolean by useState { props.expanded ?: true } val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) } - var ownProperty: ObservableMutableMeta by useState { props.meta.getOrCreate(props.name) } + var property: MutableMeta by useState { props.meta.getOrCreate(props.name) } val keys = useMemo(descriptor) { buildSet { @@ -70,17 +88,18 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { val token = props.name.lastOrNull()?.toString() ?: "Properties" fun update() { - ownProperty = props.meta.getOrCreate(props.name) + property = props.meta.getOrCreate(props.name) } useEffect(props.meta) { - props.meta.onChange(props) { updatedName -> + val job = props.updates.onEach { updatedName -> if (updatedName == props.name) { update() } - } + }.launchIn(props.scope) + cleanup { - props.meta.removeListener(props) + job.cancel() } } @@ -115,7 +134,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { styledSpan { css { +TreeStyles.treeLabel - if (ownProperty.isEmpty()) { + if (property.isEmpty()) { +TreeStyles.treeLabelInactive } } @@ -131,8 +150,8 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { ValueChooser { attrs { this.descriptor = descriptor - this.meta = ownProperty - this.actual = props.withDefault.getMeta(props.name) ?: ownProperty + this.meta = property + this.state = props.getPropertyState(props.name) } } } @@ -156,7 +175,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } +"\u00D7" attrs { - if (ownProperty.isEmpty()) { + if (property.isEmpty()) { disabled = true } else { onClickFunction = removeClick @@ -179,9 +198,11 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { attrs { this.key = props.name.toString() this.meta = props.meta - this.withDefault = props.withDefault this.name = props.name + token this.descriptor = props.descriptor + this.scope = props.scope + this.getPropertyState = { props.getPropertyState(props.name + token) } + this.updates = props.updates } } //configEditor(props.root, props.name + token, props.descriptor, props.default) @@ -197,44 +218,51 @@ public val PropertyEditor: FC = fc("PropertyEditor") { prop attrs { this.key = "" this.meta = props.meta - this.withDefault = props.withDefault this.name = Name.EMPTY this.descriptor = props.descriptor this.expanded = props.expanded + this.scope = props.scope + this.getPropertyState = props.getPropertyState + this.updates = props.updates } } } +@OptIn(ExperimentalCoroutinesApi::class) public fun RBuilder.propertyEditor( - ownProperties: ObservableMutableMeta, - allProperties: MetaProvider = ownProperties, + scope: CoroutineScope, + properties: ObservableMutableMeta, descriptor: MetaDescriptor? = null, key: Any? = null, expanded: Boolean? = null, ) { child(PropertyEditor) { attrs { - this.meta = ownProperties - this.withDefault = allProperties + this.meta = properties this.descriptor = descriptor this.key = key?.toString() ?: "" this.expanded = expanded + this.scope = scope + this.getPropertyState = { name -> + if (properties[name] != null) { + EditorPropertyState.Defined + } else if (descriptor?.get(name)?.defaultValue != null) { + EditorPropertyState.Default("descriptor") + } else { + EditorPropertyState.Undefined + } + } + this.updates = callbackFlow { + properties.onChange(scope) { name -> + scope.launch { + send(name) + } + } + + invokeOnClose { + properties.removeListener(scope) + } + } } } -} - -public fun RBuilder.configEditor( - config: ObservableMutableMeta, - default: MetaProvider = config, - descriptor: MetaDescriptor? = null, - key: Any? = null, -): Unit = propertyEditor(config, default, descriptor, key = key) - -public fun Element.configEditor( - config: ObservableMutableMeta, - default: Meta = config, - descriptor: MetaDescriptor? = null, - key: Any? = null, -): Unit = createRoot(this).render { - configEditor(config, default, descriptor, key = key) } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index 382209c2..ae6386d9 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -20,7 +20,7 @@ import styled.styledInput @JsExport public val RangeValueChooser: FC = fc("RangeValueChooser") { props -> - var innerValue by useState(props.actual.double) + var innerValue by useState(props.meta.double) var rangeDisabled: Boolean by useState(props.meta.value == null) val handleDisable: (Event) -> Unit = { diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt index 84f9347f..9866c30e 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt @@ -16,6 +16,7 @@ import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.asSequence import space.kscience.visionforge.isEmpty import styled.css import styled.styledDiv @@ -59,9 +60,9 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { val obj = props.obj //display as node if any child is visible - if (obj is VisionGroup<*>) { + if (obj is VisionGroup) { flexRow { - if (obj.items.any { !it.key.body.startsWith("@") }) { + if (obj.children.keys.any { !it.body.startsWith("@") }) { styledSpan { css { +TreeStyles.treeCaret @@ -81,9 +82,9 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { css { +TreeStyles.tree } - obj.items.entries - .filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children - .sortedBy { (it.value as? VisionGroup<*>)?.isEmpty() ?: true } // ignore empty groups + obj.children.asSequence() + .filter { !it.first.toString().startsWith("@") } // ignore statics and other hidden children + .sortedBy { (it.second as? VisionGroup)?.children?.isEmpty() ?: true } // ignore empty groups .forEach { (childToken, child) -> styledDiv { css { @@ -92,7 +93,7 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { child(ObjectTree) { attrs { this.name = props.name + childToken - this.obj = child.vision + this.obj = child this.selected = props.selected this.clickCallback = props.clickCallback } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index cd769414..75cd3a0c 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -27,13 +27,13 @@ import styled.styledSelect public external interface ValueChooserProps : Props { public var descriptor: MetaDescriptor? - public var meta: ObservableMutableMeta - public var actual: Meta + public var meta: MutableMeta + public var state: EditorPropertyState } @JsExport public val StringValueChooser: FC = fc("StringValueChooser") { props -> - var value by useState(props.actual.string ?: "") + var value by useState(props.meta.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { value = (event.target as HTMLInputElement).value @@ -67,7 +67,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" } attrs { //this.attributes["indeterminate"] = (props.item == null).toString() - checked = props.actual.boolean ?: false + checked = props.meta.boolean ?: false onChangeFunction = handleChange } } @@ -75,7 +75,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" @JsExport public val NumberValueChooser: FC = fc("NumberValueChooser") { props -> - var innerValue by useState(props.actual.string ?: "") + var innerValue by useState(props.meta.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { innerValue = (event.target as HTMLInputElement).value @@ -113,7 +113,7 @@ public val NumberValueChooser: FC = fc("NumberValueChooser") @JsExport public val ComboValueChooser: FC = fc("ComboValueChooser") { props -> - var selected by useState(props.actual.string ?: "") + var selected by useState(props.meta.string ?: "") val handleChange: (Event) -> Unit = { selected = (it.target as HTMLSelectElement).value props.meta.value = selected.asValue() @@ -128,7 +128,7 @@ public val ComboValueChooser: FC = fc("ComboValueChooser") { } } attrs { - this.value = props.actual.string ?: "" + this.value = props.meta.string ?: "" multiple = false onChangeFunction = handleChange } @@ -146,7 +146,7 @@ public val ColorValueChooser: FC = fc("ColorValueChooser") { margin(0.px) } attrs { - this.value = props.actual.value?.let { value -> + this.value = props.meta.value?.let { value -> if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) else value.string } ?: "#000000" diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts index 7d7564b5..aa168c11 100644 --- a/ui/ring/build.gradle.kts +++ b/ui/ring/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } val dataforgeVersion: String by rootProject.extra diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index 085ff608..babafb2e 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -9,18 +9,19 @@ import react.dom.div import react.dom.span import ringui.* import space.kscience.dataforge.context.Context +import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.length -import space.kscience.visionforge.* -import space.kscience.visionforge.react.ThreeCanvasComponent -import space.kscience.visionforge.react.flexColumn -import space.kscience.visionforge.react.flexRow -import space.kscience.visionforge.react.propertyEditor +import space.kscience.visionforge.Vision +import space.kscience.visionforge.react.* +import space.kscience.visionforge.root +import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions +import space.kscience.visionforge.visionManager import styled.css import styled.styledDiv @@ -38,7 +39,7 @@ public fun ThreeCanvasWithControlsProps.solid(block: SolidGroup.() -> Unit) { } } -public fun ThreeCanvasWithControlsProps.options(block: Canvas3DOptions.() -> Unit){ +public fun ThreeCanvasWithControlsProps.options(block: Canvas3DOptions.() -> Unit) { options = Canvas3DOptions(block) } @@ -81,14 +82,14 @@ public fun RBuilder.nameCrumbs(name: Name?, link: (Name) -> Unit): Unit = styled @JsExport public val ThreeCanvasWithControls: FC = fc("ThreeViewWithControls") { props -> - var selected by useState { props.selected } + var selected: Name? by useState { props.selected } var solid: Solid? by useState(null) useEffect { props.context.launch { solid = props.builderOfSolid.await() //ensure that the solid is properly rooted - if(solid?.parent == null){ + if (solid?.parent == null) { solid?.setAsRoot(props.context.visionManager) } } @@ -164,12 +165,25 @@ public val ThreeCanvasWithControls: FC = fc("Three nameCrumbs(selected) { selected = it } } IslandContent { - propertyEditor( - ownProperties = vision.properties(), - allProperties = vision.computeProperties(), - descriptor = vision.descriptor, - key = selected - ) + child(PropertyEditor) { + attrs { + this.key = selected.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = vision.descriptor + this.scope = props.context + this.getPropertyState = { name -> + if (vision.properties.own?.get(name) != null) { + EditorPropertyState.Defined + } else if (vision.properties.root()[name] != null) { + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } } } } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt index 5c959184..b4ce3284 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt @@ -4,17 +4,16 @@ import org.w3c.dom.Element import react.RBuilder import react.dom.client.createRoot import react.dom.p +import react.key import ringui.Island import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.get import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties import space.kscience.visionforge.getStyle -import space.kscience.visionforge.react.flexColumn -import space.kscience.visionforge.react.metaViewer -import space.kscience.visionforge.react.propertyEditor -import space.kscience.visionforge.react.render +import space.kscience.visionforge.react.* +import space.kscience.visionforge.root import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.styles @@ -31,12 +30,25 @@ public fun RBuilder.ringPropertyEditor( flexColumn { Island("Properties") { - propertyEditor( - ownProperties = vision.meta, - allProperties = vision.computeProperties(), - descriptor = descriptor, - key = key - ) + child(PropertyEditor) { + attrs { + this.key = key?.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = descriptor + this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") + this.getPropertyState = {name-> + if(vision.properties.own?.get(name)!= null){ + EditorPropertyState.Defined + } else if(vision.properties.root()[name] != null){ + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } } if (styles.isNotEmpty()) { diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt index 68cc13b2..1b62bd1f 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.ring +import kotlinx.coroutines.GlobalScope import kotlinx.css.BorderStyle import kotlinx.css.Color import kotlinx.css.padding @@ -18,7 +19,6 @@ import react.fc import ringui.Island import ringui.SmartTabs import ringui.Tab -import space.kscience.dataforge.meta.withDefault import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.encodeToString @@ -75,8 +75,8 @@ internal val CanvasControls: FC = fc("CanvasControls") { pr } } propertyEditor( - ownProperties = props.options.meta, - allProperties = props.options.meta.withDefault(Canvas3DOptions.descriptor.defaultNode), + scope = props.vision?.manager?.context ?: GlobalScope, + properties = props.options.meta, descriptor = Canvas3DOptions.descriptor, expanded = false ) diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index 227c80dc..d9bf251c 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val dataforgeVersion: String by rootProject.extra @@ -28,5 +28,5 @@ kscience{ } readme{ - maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT + maturity = space.kscience.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 9fc148b3..1c05d6d6 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline @JvmInline public value class StyleSheet(private val owner: Vision) { - private val styleNode: Meta get() = owner.properties[STYLESHEET_KEY] + private val styleNode: Meta get() = owner.properties.getProperty(STYLESHEET_KEY) public val items: Map get() = styleNode.items @@ -23,7 +23,7 @@ public value class StyleSheet(private val owner: Vision) { * Define a style without notifying owner */ public fun define(key: String, style: Meta?) { - owner.properties[STYLESHEET_KEY + key] = style + owner.properties.setProperty(STYLESHEET_KEY + key, style) } /** @@ -86,7 +86,7 @@ public val Vision.styleSheet: StyleSheet get() = StyleSheet(this) * Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment. */ public fun Vision.useStyle(name: String) { - styles = (properties.getValue(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name + styles = (properties.own?.get(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name } @@ -94,7 +94,7 @@ public fun Vision.useStyle(name: String) { * Resolve a style with given name for given [Vision]. The style is not necessarily applied to this [Vision]. */ public fun Vision.getStyle(name: String): Meta? = - properties.raw?.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) + properties.own?.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) /** * Resolve a property from all styles diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 9b8304de..a8b590e7 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import space.kscience.dataforge.context.Global import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.descriptors.Described @@ -30,7 +30,7 @@ public interface Vision : Described { /** * Owner [VisionManager]. Used to define coroutine scope a serialization */ - public val manager: VisionManager get() = parent?.manager ?: Global.visionManager + public val manager: VisionManager? get() = parent?.manager public val properties: MutableVisionProperties @@ -67,13 +67,17 @@ public var Vision.visible: Boolean? /** * Subscribe on property updates. The subscription is bound to the given scope and canceled when the scope is canceled */ -public fun Vision.onPropertyChange(callback: (Name) -> Unit): Job = properties.changes.onEach { +public fun Vision.onPropertyChange( + scope: CoroutineScope? = manager?.context, + callback: (Name) -> Unit +): Job = properties.changes.onEach { callback(it) -}.launchIn(manager.context) +}.launchIn(scope ?: error("Orphan Vision can't observe properties")) public fun V.useProperty( property: KProperty1, + scope: CoroutineScope? = manager?.context, callBack: V.(T) -> Unit, ): Job { //Pass initial value. @@ -82,5 +86,5 @@ public fun V.useProperty( if (name.startsWith(property.name.asName())) { callBack(property.get(this@useProperty)) } - }.launchIn(manager.context) + }.launchIn(scope ?: error("Orphan Vision can't observe properties")) } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index d0a7ec70..0e3a8dc1 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -91,8 +91,8 @@ private fun CoroutineScope.collectChange( ) { //Collect properties change - source.onPropertyChange { propertyName -> - val newItem = source.properties.raw?.get(propertyName) + source.onPropertyChange(this) { propertyName -> + val newItem = source.properties.own?.get(propertyName) collector().propertyChanged(name, propertyName, newItem) } @@ -118,8 +118,8 @@ private fun CoroutineScope.collectChange( */ public fun Vision.flowChanges( collectionDuration: Duration, - manager: VisionManager = this.manager, ): Flow = flow { + val manager = manager?: error("Orphan vision could not collect changes") var collector = VisionChangeBuilder(manager) coroutineScope { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index 529c01a1..481a53ce 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -124,7 +124,7 @@ internal abstract class VisionChildrenImpl( return items!! } - private val scope: CoroutineScope get() = group.manager.context + private val scope: CoroutineScope? get() = group.manager?.context override val keys: Set get() = items?.keys ?: emptySet() @@ -134,7 +134,7 @@ internal abstract class VisionChildrenImpl( override val changes: SharedFlow get() = _changes private fun onChange(name: Name) { - scope.launch { + scope?.launch { _changes.emit(name) } } @@ -158,7 +158,7 @@ internal abstract class VisionChildrenImpl( //set parent value.parent = group //start update jobs (only if the vision is rooted) - scope.let { scope -> + scope?.let { scope -> val job = value.children?.changes?.onEach { onChange(token + it) }?.launchIn(scope) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 3428dd33..a6f1a7c6 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -107,7 +107,8 @@ public abstract class VisionPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(met */ public val Context.visionManager: VisionManager get() = fetch(VisionManager) -public fun Vision.encodeToString(): String = manager.encodeToString(this) +public fun Vision.encodeToString(): String = + manager?.encodeToString(this) ?: error("Orphan vision could not be encoded") /** * A root vision attached to [VisionManager] diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 7b6c6e7b..693e85bf 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -1,5 +1,7 @@ package space.kscience.visionforge +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow @@ -16,14 +18,14 @@ public interface VisionProperties { /** * Raw Visions own properties without styles, defaults, etc. */ - public val raw: Meta? + public val own: Meta? public val descriptor: MetaDescriptor? public fun getValue( name: Name, - inherit: Boolean, - includeStyles: Boolean, + inherit: Boolean? = null, + includeStyles: Boolean? = null, ): Value? /** @@ -31,10 +33,10 @@ public interface VisionProperties { * @param inherit toggles parent node property lookup. Null means inference from descriptor. * @param includeStyles toggles inclusion of properties from styles. */ - public operator fun get( + public fun getProperty( name: Name, - inherit: Boolean, - includeStyles: Boolean, + inherit: Boolean? = null, + includeStyles: Boolean? = null, ): Meta public val changes: Flow @@ -48,10 +50,10 @@ public interface VisionProperties { public interface MutableVisionProperties : VisionProperties { - override operator fun get( + override fun getProperty( name: Name, - inherit: Boolean, - includeStyles: Boolean, + inherit: Boolean?, + includeStyles: Boolean?, ): MutableMeta = VisionPropertiesItem( this, name, @@ -60,7 +62,7 @@ public interface MutableVisionProperties : VisionProperties { ) - public operator fun set( + public fun setProperty( name: Name, node: Meta?, ) @@ -84,7 +86,7 @@ private class VisionPropertiesItem( override val items: Map get() { - val metaKeys = properties.raw?.getMeta(nodeName)?.items?.keys ?: emptySet() + val metaKeys = properties.own?.getMeta(nodeName)?.items?.keys ?: emptySet() val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet() val defaultKeys = default?.get(nodeName)?.items?.keys ?: emptySet() val inheritFlag = descriptor?.inherited ?: inherit @@ -119,7 +121,7 @@ private class VisionPropertiesItem( ) override fun setMeta(name: Name, node: Meta?) { - properties[nodeName + name] = node + properties.setProperty(nodeName + name, node) } override fun toString(): String = Meta.toString(this) @@ -131,11 +133,10 @@ public abstract class AbstractVisionProperties( private val vision: Vision, ) : MutableVisionProperties { override val descriptor: MetaDescriptor? get() = vision.descriptor - protected val default: Meta? get() = descriptor?.defaultNode protected abstract var properties: MutableMeta? - override val raw: Meta? get() = properties + override val own: Meta? get() = properties @Synchronized protected fun getOrCreateProperties(): MutableMeta { @@ -149,20 +150,24 @@ public abstract class AbstractVisionProperties( override fun getValue( name: Name, - inherit: Boolean, - includeStyles: Boolean, + inherit: Boolean?, + includeStyles: Boolean?, ): Value? { - raw?.get(name)?.value?.let { return it } - if (includeStyles) { + val descriptor = descriptor?.get(name) + val inheritFlag = inherit ?: descriptor?.inherited ?: false + val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true + + own?.get(name)?.value?.let { return it } + if (stylesFlag) { vision.getStyleProperty(name)?.value?.let { return it } } - if (inherit) { + if (inheritFlag) { vision.parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } } - return default?.get(name)?.value + return descriptor?.defaultValue } - override fun set(name: Name, node: Meta?) { + override fun setProperty(name: Name, node: Meta?) { //TODO check old value? if (name.isEmpty()) { properties = node?.asMutableMeta() @@ -188,6 +193,7 @@ public abstract class AbstractVisionProperties( private val _changes = MutableSharedFlow(10) override val changes: SharedFlow get() = _changes + @OptIn(DelicateCoroutinesApi::class) override fun invalidate(propertyName: Name) { if (propertyName == Vision.STYLE_KEY) { vision.styles.asSequence() @@ -198,85 +204,46 @@ public abstract class AbstractVisionProperties( invalidate(it.key.asName()) } } - vision.manager.context.launch { + (vision.manager?.context ?: GlobalScope).launch { _changes.emit(propertyName) } } } -public fun VisionProperties.getValue( - name: Name, - inherit: Boolean? = null, - includeStyles: Boolean? = null, -): Value? { - val descriptor = descriptor?.get(name) - val inheritFlag = inherit ?: descriptor?.inherited ?: false - val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - return getValue(name, inheritFlag, stylesFlag) -} - public fun VisionProperties.getValue( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, ): Value? = getValue(name.parseAsName(), inherit, includeStyles) -/** - * Compute the property based on the provided value descriptor. By default, use Vision own descriptor - */ -public operator fun VisionProperties.get( - name: Name, - inherit: Boolean? = null, - includeStyles: Boolean? = null, -): Meta { - val descriptor: MetaDescriptor? = descriptor?.get(name) - val inheritFlag = inherit ?: descriptor?.inherited ?: false - val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - return get(name, inheritFlag, stylesFlag) -} - - /** * Get [Vision] property using key as a String */ -public operator fun VisionProperties.get( +public fun VisionProperties.getProperty( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, -): Meta = get(name.parseAsName(), inherit, includeStyles) - - -/** - * Compute the property based on the provided value descriptor. By default, use Vision own descriptor - */ -public operator fun MutableVisionProperties.get( - name: Name, - inherit: Boolean? = null, - includeStyles: Boolean? = null, -): MutableMeta { - val descriptor: MetaDescriptor? = descriptor?.get(name) - val inheritFlag = inherit ?: descriptor?.inherited ?: false - val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - return get(name, inheritFlag, stylesFlag) -} +): Meta = getProperty(name.parseAsName(), inherit, includeStyles) /** * The root property node with given inheritance and style flags + * @param inherit - inherit properties from the [Vision] parent. If null, infer from descriptor + * @param includeStyles - include style information. If null, infer from descriptor */ public fun MutableVisionProperties.root( inherit: Boolean? = null, includeStyles: Boolean? = null, -): MutableMeta = get(Name.EMPTY, inherit, includeStyles) +): MutableMeta = getProperty(Name.EMPTY, inherit, includeStyles) /** * Get [Vision] property using key as a String */ -public operator fun MutableVisionProperties.get( +public fun MutableVisionProperties.getProperty( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, -): MutableMeta = get(name.parseAsName(), inherit, includeStyles) +): MutableMeta = getProperty(name.parseAsName(), inherit, includeStyles) public operator fun MutableVisionProperties.set(name: Name, value: Number): Unit = diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt index 19106240..3a818b08 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt @@ -9,7 +9,7 @@ import space.kscience.dataforge.names.Name import space.kscience.visionforge.* //TODO replace by something -internal val Vision.mutableProperties get() = properties[Name.EMPTY, false, false] +internal val Vision.mutableProperties get() = properties.getProperty(Name.EMPTY, false, false) @Serializable public abstract class VisionOfHtmlInput : AbstractVision() { diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index d6128963..f72fe2bf 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -54,7 +54,7 @@ class HtmlTagTest { div { h2 { +"Properties" } ul { - vision.properties.raw?.items?.forEach { + vision.properties.own?.items?.forEach { li { a { +it.key.toString() } p { +it.value.toString() } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 23517112..e7a35faa 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -2,7 +2,7 @@ package space.kscience.visionforge.meta import space.kscience.dataforge.meta.* import space.kscience.visionforge.VisionGroup -import space.kscience.visionforge.get +import space.kscience.visionforge.getProperty import space.kscience.visionforge.getValue import space.kscience.visionforge.set import kotlin.test.Test @@ -30,7 +30,7 @@ internal class VisionPropertyTest { @Test fun testPropertyEdit() { val vision = VisionGroup() - vision.properties["fff.ddd"].apply { + vision.properties.getProperty("fff.ddd").apply { value = 2.asValue() } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) @@ -40,7 +40,7 @@ internal class VisionPropertyTest { @Test fun testPropertyUpdate() { val vision = VisionGroup() - vision.properties["fff"].updateWith(TestScheme) { + vision.properties.getProperty("fff").updateWith(TestScheme) { ddd = 2 } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index e9425afb..41018759 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -115,7 +115,7 @@ public class VisionClient : AbstractPlugin() { onopen = { feedbackJob = vision.flowChanges( - feedbackAggregationTime.milliseconds + feedbackAggregationTime.milliseconds, ).onEach { change -> send(visionManager.encodeToString(change)) }.launchIn(visionManager.context) diff --git a/visionforge-fx/build.gradle.kts b/visionforge-fx/build.gradle.kts index 26fa13c8..464c7af3 100644 --- a/visionforge-fx/build.gradle.kts +++ b/visionforge-fx/build.gradle.kts @@ -1,12 +1,12 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") } val dataforgeVersion: String by rootProject.extra val fxVersion: String by rootProject.extra kscience{ - useFx(ru.mipt.npm.gradle.FXModule.CONTROLS, version = fxVersion) + useFx(space.kscience.gradle.FXModule.CONTROLS, version = fxVersion) } dependencies { @@ -15,12 +15,12 @@ dependencies { api("org.fxyz3d:fxyz3d:0.5.4") { exclude(module = "slf4j-simple") } - api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}") + api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${space.kscience.gradle.KScienceVersions.coroutinesVersion}") implementation("eu.mihosoft.vrl.jcsg:jcsg:0.5.7") { exclude(module = "slf4j-simple") } } readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE + maturity = space.kscience.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt index bac388ee..d39f284c 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt @@ -16,7 +16,6 @@ import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.misc.Type -import space.kscience.visionforge.get import space.kscience.visionforge.solid.FX3DFactory.Companion.TYPE import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_WIREFRAME_KEY @@ -77,7 +76,7 @@ public class FX3DPlugin : AbstractPlugin() { is PolyLine -> PolyLine3D( obj.points.map { Point3D(it.x, it.y, it.z) }, obj.thickness.toFloat(), - obj.properties.get(SolidMaterial.MATERIAL_COLOR_KEY).color() + obj.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).color() ).apply { this.meshView.cullFace = CullFace.FRONT } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt index 8d3e2836..2eb2255c 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt @@ -6,7 +6,6 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.Vision -import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange import tornadofx.* @@ -35,7 +34,7 @@ public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vi public operator fun get(key: Name): ObjectBinding { return bindings.getOrPut(key) { object : ObjectBinding() { - override fun computeValue(): Meta = obj.properties[key] + override fun computeValue(): Meta = obj.properties.getProperty(key) } } } diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index 1e9b59b9..345445da 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } kotlin { @@ -13,5 +13,10 @@ kotlin { api("space.kscience:gdml:0.4.0") } } + jvmTest{ + dependencies{ + implementation("ch.qos.logback:logback-classic:1.2.11") + } + } } } \ No newline at end of file diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt index b2dbce57..7af53964 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.gdml +import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.info import space.kscience.dataforge.context.logger import space.kscience.dataforge.names.Name @@ -50,7 +51,7 @@ private fun VisionCounterTree.topToBottom(): Sequence = seque } public fun SolidGroup.markLayers(thresholds: List = listOf(500, 1000, 20000, 50000)) { - val logger = manager.context.logger + val logger = manager?.context?.logger ?: Global.logger val counterTree = VisionCounterTree(Name.EMPTY, this, hashMapOf()) val totalCount = counterTree.childrenCount if (totalCount > (thresholds.firstOrNull() ?: 0)) { diff --git a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt index 948ad214..a30cf863 100644 --- a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt +++ b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt @@ -26,7 +26,7 @@ class TestCubes { val smallBoxPrototype = vision.getPrototype(Name.parse("solids.smallBox")) as? Box assertNotNull(smallBoxPrototype) assertEquals(30.0, smallBoxPrototype.xSize.toDouble()) - val smallBoxVision = vision.children["composite-111.smallBox"]?.unref as? Box + val smallBoxVision = vision.children["composite-111.smallBox"]?.prototype as? Box assertNotNull(smallBoxVision) assertEquals(30.0, smallBoxVision.xSize.toDouble()) } diff --git a/visionforge-markdown/build.gradle.kts b/visionforge-markdown/build.gradle.kts index 1a8e4efd..2909ab6d 100644 --- a/visionforge-markdown/build.gradle.kts +++ b/visionforge-markdown/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val markdownVersion = "0.2.4" diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index 1c1ed308..919dde07 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val plotlyVersion = "0.5.3-dev-1" diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index c23de631..2e89dbf5 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -16,7 +16,7 @@ import space.kscience.visionforge.root public class VisionOfPlotly private constructor() : AbstractVision() { public constructor(plot: Plot) : this() { - properties[Name.EMPTY] = plot.meta + properties.setProperty(Name.EMPTY, plot.meta) } public val plot: Plot get() = Plot(properties.root().asObservable()) diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index a89f2d07..236dda78 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") } val ktorVersion = npmlibs.versions.ktor.get() diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index bb88fa22..d4bf939f 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -92,6 +92,7 @@ public class VisionServer internal constructor( header() } title(title) + consumer.header() } body { //Load the fragment and remember all loaded visions diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index ce669659..f794afe4 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } kscience{ @@ -20,9 +20,14 @@ kotlin { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4") } } + jvmTest{ + dependencies{ + implementation("ch.qos.logback:logback-classic:1.2.11") + } + } } } readme{ - maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT + maturity = space.kscience.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index dde24ef0..29de1575 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -29,7 +29,7 @@ public class ColorAccessor( } public fun Vision.color(): ReadOnlyProperty = ReadOnlyProperty { _, property -> - ColorAccessor(properties.root(), property.name.asName()) + ColorAccessor(properties.root(true), property.name.asName()) } public var ColorAccessor?.string: String? diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index f30c641b..fb1b4774 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -33,7 +33,7 @@ public inline fun MutableVisionContainer.composite( } val res = Composite(type, children[0], children[1]) - res.properties[Name.EMPTY] = group.properties.raw + res.properties.setProperty(Name.EMPTY, group.properties.own) set(name, res) return res @@ -49,7 +49,7 @@ public fun SolidGroup.smartComposite( @VisionBuilder builder: SolidGroup.() -> Unit, ): Solid = if (type == CompositeType.GROUP) { val group = SolidGroup(builder) - if (name == null && group.properties.raw == null) { + if (name == null && group.properties.own == null) { //append directly to group if no properties are defined group.items.forEach { (_, value) -> value.parent = null diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 0b1c2e20..68eded95 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -107,7 +107,7 @@ public class ExtrudeBuilder( } internal fun build(): Extruded = Extruded(shape, layers).apply { - this.properties[Name.EMPTY] = this@ExtrudeBuilder.properties + this.properties.setProperty(Name.EMPTY, this@ExtrudeBuilder.properties) } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt index df28b344..587e803c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt @@ -10,7 +10,7 @@ import space.kscience.visionforge.* public class PolyLine(public val points: List) : SolidBase() { //var lineType by string() - public var thickness: Number by properties[SolidMaterial.MATERIAL_KEY].number { 1.0 } + public var thickness: Number by properties.getProperty(SolidMaterial.MATERIAL_KEY).number { 1.0 } } @VisionBuilder diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index d932a4b3..2283f187 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -170,7 +170,7 @@ internal fun float(name: Name, default: Number): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Point3D? { - val item = thisRef.properties.raw?.get(name) ?: return null + val item = thisRef.properties.own?.get(name) ?: return null return object : Point3D { override val x: Float get() = item[X_KEY]?.float ?: default override val y: Float get() = item[Y_KEY]?.float ?: default @@ -180,7 +180,7 @@ internal fun point(name: Name, default: Float): ReadWriteProperty, value: Point3D?) { if (value == null) { - thisRef.properties[name] = null + thisRef.properties.setProperty(name, null) } else { thisRef.properties[name + X_KEY] = value.x thisRef.properties[name + Y_KEY] = value.y diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index e514dee4..80a1129d 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -54,7 +54,7 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable * If prototype is a ref, then it is unfolded automatically. */ override fun getPrototype(name: Name): Solid? = - prototypes?.get(name)?.unref ?: (parent as? PrototypeHolder)?.getPrototype(name) + prototypes?.get(name)?.prototype ?: (parent as? PrototypeHolder)?.getPrototype(name) /** * Create or edit prototype node as a group diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index e8da3499..7d5c4d00 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -99,15 +99,15 @@ public class SolidMaterial : Scheme() { } public val Solid.color: ColorAccessor - get() = ColorAccessor(properties.root(), MATERIAL_COLOR_KEY) + get() = ColorAccessor(properties.root(true), MATERIAL_COLOR_KEY) public var Solid.material: SolidMaterial? - get() = SolidMaterial.read(properties[MATERIAL_KEY]) - set(value) = properties.set(MATERIAL_KEY, value?.meta) + get() = SolidMaterial.read(properties.getProperty(MATERIAL_KEY)) + set(value) = properties.setProperty(MATERIAL_KEY, value?.meta) @VisionBuilder public fun Solid.material(builder: SolidMaterial.() -> Unit) { - properties[MATERIAL_KEY].updateWith(SolidMaterial, builder) + properties.getProperty(MATERIAL_KEY).updateWith(SolidMaterial, builder) } public var Solid.opacity: Number? diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index e071d07b..51e0bc6b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -16,9 +16,10 @@ import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD * Get a vision prototype if it is a [SolidReference] or vision itself if it is not. * Unref is recursive, so it always returns a non-reference. */ -public val Vision.unref: Solid +public val Vision.prototype: Solid get() = when (this) { - is SolidReference -> prototype.unref + is SolidReference -> prototype.prototype + is SolidReferenceChild -> prototype.prototype is Solid -> this else -> error("This Vision is neither Solid nor SolidReference") } @@ -55,13 +56,13 @@ public class SolidReference( propertiesInternal = value } - override val raw: Meta? get() = properties + override val own: Meta? get() = properties - override fun get(name: Name, inherit: Boolean, includeStyles: Boolean): MutableMeta { - return properties?.getMeta(name) ?: prototype.properties.get(name, inherit, includeStyles) + override fun getProperty(name: Name, inherit: Boolean?, includeStyles: Boolean?): MutableMeta { + return properties?.getMeta(name) ?: prototype.properties.getProperty(name, inherit, includeStyles) } - override fun getValue(name: Name, inherit: Boolean, includeStyles: Boolean): Value? { + override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? { return properties?.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) } } @@ -105,23 +106,23 @@ internal class SolidReferenceChild( override val properties: MutableVisionProperties = object : MutableVisionProperties { override val descriptor: MetaDescriptor get() = this@SolidReferenceChild.descriptor - override val raw: MutableMeta by lazy { owner.properties[childToken(childName).asName()] } + override val own: MutableMeta by lazy { owner.properties.getProperty(childToken(childName).asName()) } - override fun get(name: Name, inherit: Boolean, includeStyles: Boolean): MutableMeta = - raw.getMeta(name) ?: prototype.properties.get(name, inherit, includeStyles) + override fun getProperty(name: Name, inherit: Boolean?, includeStyles: Boolean?): MutableMeta = + own.getMeta(name) ?: prototype.properties.getProperty(name, inherit, includeStyles) override fun getValue( name: Name, - inherit: Boolean, - includeStyles: Boolean, - ): Value? = raw.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) + inherit: Boolean?, + includeStyles: Boolean?, + ): Value? = own.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) - override fun set(name: Name, node: Meta?) { - raw.setMeta(name, node) + override fun setProperty(name: Name, node: Meta?) { + own.setMeta(name, node) } override fun setValue(name: Name, value: Value?) { - raw.setValue(name, value) + own.setValue(name, value) } override val changes: Flow get() = owner.properties.changes.filter { it.startsWith(childToken(childName)) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index dbdc58ec..dc01e749 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -20,7 +20,7 @@ internal fun Solid.updateFrom(other: Solid): Solid { scaleX *= other.scaleX scaleY *= other.scaleY scaleZ *= other.scaleZ - properties[Name.EMPTY] = other.properties.root() + properties.setProperty(Name.EMPTY, other.properties.root()) return this } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt index 2eb4c65d..5e26284e 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt @@ -3,7 +3,6 @@ package space.kscience.visionforge.solid import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.withTimeout import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.asName @@ -26,13 +25,13 @@ class PropertyTest { @OptIn(ExperimentalCoroutinesApi::class) @Test - fun testColorUpdate() = runTest { + fun testColorUpdate() = runTest(dispatchTimeoutMs = 200) { val box = Box(10.0f, 10.0f, 10.0f) val c = CompletableDeferred() - box.onPropertyChange { + val subscription = box.onPropertyChange(this) { if (it == SolidMaterial.MATERIAL_COLOR_KEY) { c.complete(box.color.string) } @@ -42,8 +41,8 @@ class PropertyTest { color.set("pink") } - assertEquals("pink", withTimeout(50) { c.await() }) - + assertEquals("pink", c.await()) + subscription.cancel() } @Test diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index baad6110..c2dee067 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -31,7 +31,7 @@ class SerializationTest { val string = Solids.encodeToString(cube) println(string) val newCube = Solids.decodeFromString(string) - assertEquals(cube.properties.raw, newCube.properties.raw) + assertEquals(cube.properties.own, newCube.properties.own) } @Test @@ -52,7 +52,7 @@ class SerializationTest { val string = Solids.encodeToString(group) println(string) val reconstructed = Solids.decodeFromString(string) as SolidGroup - assertEquals(group.children["cube"]?.properties?.raw, reconstructed.children["cube"]?.properties?.raw) + assertEquals(group.children["cube"]?.properties?.own, reconstructed.children["cube"]?.properties?.own) } @Test diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index d4e86bf1..55cc27e5 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val tablesVersion = "0.2.0-dev-3" @@ -36,5 +36,5 @@ kotlin { } readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE + maturity = space.kscience.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt index e3b199d1..e1210ffa 100644 --- a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt +++ b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt @@ -17,7 +17,7 @@ internal class VisionOfTableTest { val x by ColumnHeader.typed() val y by ColumnHeader.typed() - val table = ColumnTable(100) { + val table = ColumnTable(100) { x.fill { it.asValue() } y.values = x.values.map { it?.double?.pow(2)?.asValue() } } diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index f0462837..d9d0f96d 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } kotlin{ diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt index 04f192fd..9309848f 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt @@ -10,7 +10,6 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.set import space.kscience.visionforge.solid.Solid @@ -78,7 +77,7 @@ public abstract class MeshThreeFactory( @VisionBuilder public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { properties.set(EDGES_ENABLED_KEY, enabled) - SolidMaterial.write(properties[EDGES_MATERIAL_KEY]).apply(block) + SolidMaterial.write(properties.getProperty(EDGES_MATERIAL_KEY)).apply(block) } internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { @@ -94,9 +93,9 @@ internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { public fun Mesh.applyEdges(obj: Solid) { val edges = children.find { it.name == "@edges" } as? LineSegments //inherited edges definition, enabled by default - if (obj.properties.get(EDGES_ENABLED_KEY, inherit = true).boolean != false) { + if (obj.properties.getProperty(EDGES_ENABLED_KEY, inherit = true).boolean != false) { val bufferGeometry = geometry as? BufferGeometry ?: return - val material = ThreeMaterials.getLineMaterial(obj.properties[EDGES_MATERIAL_KEY], true) + val material = ThreeMaterials.getLineMaterial(obj.properties.getProperty(EDGES_MATERIAL_KEY), true) if (edges == null) { add( LineSegments( diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index 8108389e..d33c7e79 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -11,7 +11,6 @@ import org.w3c.dom.CanvasRenderingContext2D import org.w3c.dom.CanvasTextBaseline import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.MIDDLE -import space.kscience.visionforge.get import space.kscience.visionforge.solid.SolidLabel import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG @@ -27,7 +26,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory { val canvas = document.createElement("canvas") as HTMLCanvasElement val context = canvas.getContext("2d") as CanvasRenderingContext2D context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.properties[SolidMaterial.MATERIAL_COLOR_KEY].value ?: "black" + context.fillStyle = obj.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).value ?: "black" context.textBaseline = CanvasTextBaseline.MIDDLE val metrics = context.measureText(obj.text) //canvas.width = metrics.width.toInt() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index 70938e99..fcd92b7c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -4,7 +4,6 @@ import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.math.Color import info.laht.threekt.objects.LineSegments -import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial @@ -25,7 +24,7 @@ public object ThreeLineFactory : ThreeFactory { } val material = ThreeMaterials.getLineMaterial( - obj.properties[SolidMaterial.MATERIAL_KEY], + obj.properties.getProperty(SolidMaterial.MATERIAL_KEY), false ) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index a9f68f69..20bd7f3a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -10,7 +10,9 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.visionforge.* +import space.kscience.visionforge.Colors +import space.kscience.visionforge.Vision +import space.kscience.visionforge.getStyleNodes import space.kscience.visionforge.solid.ColorAccessor import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.SolidReference @@ -129,15 +131,15 @@ private var Material.cached: Boolean } public fun Mesh.updateMaterial(vision: Vision) { - val ownMaterialMeta = vision.properties.raw?.get(SolidMaterial.MATERIAL_KEY) + val ownMaterialMeta = vision.properties.own?.get(SolidMaterial.MATERIAL_KEY) if (ownMaterialMeta == null) { if (vision is SolidReference && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty()) { updateMaterial(vision.prototype) } else { - material = ThreeMaterials.cacheMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]) + material = ThreeMaterials.cacheMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)) } } else { - material = ThreeMaterials.buildMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]) + material = ThreeMaterials.buildMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)) } } @@ -152,15 +154,16 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { } else { when (propertyName) { SolidMaterial.MATERIAL_COLOR_KEY -> { - material.asDynamic().color = vision.properties[SolidMaterial.MATERIAL_COLOR_KEY].threeColor() + material.asDynamic().color = vision.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.SPECULAR_COLOR_KEY -> { - material.asDynamic().specular = vision.properties[SolidMaterial.SPECULAR_COLOR_KEY].threeColor() + material.asDynamic().specular = vision.properties.getProperty(SolidMaterial.SPECULAR_COLOR_KEY).threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { - material.asDynamic().emissive = vision.properties[SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY].threeColor() + material.asDynamic().emissive = vision.properties.getProperty(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY) + .threeColor() ?: ThreeMaterials.BLACK_COLOR } SolidMaterial.MATERIAL_OPACITY_KEY -> { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 03ed5ee4..2fe9585c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -1,6 +1,8 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.core.Object3D +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* @@ -9,7 +11,6 @@ import space.kscience.dataforge.meta.update import space.kscience.dataforge.names.* import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision -import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.visible @@ -48,11 +49,11 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public fun buildObject3D(obj: Solid): Object3D = when (obj) { is ThreeJsVision -> obj.render(this) - is SolidReferenceGroup -> ThreeReferenceFactory.build(this, obj) + is SolidReference -> ThreeReferenceFactory.build(this, obj) is SolidGroup -> { val group = ThreeGroup() obj.items.forEach { (token, child) -> - if (child is Solid && token != SolidGroup.PROTOTYPES_TOKEN && child.ignore != true) { + if (token != SolidGroup.PROTOTYPES_TOKEN && child.ignore != true) { try { val object3D = buildObject3D(child) group[token] = object3D @@ -67,7 +68,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { updatePosition(obj) //obj.onChildrenChange() - obj.onPropertyChange { name -> + obj.properties.changes.onEach { name -> if ( name.startsWith(Solid.POSITION_KEY) || name.startsWith(Solid.ROTATION_KEY) || @@ -78,10 +79,10 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { } else if (name == Vision.VISIBLE_KEY) { visible = obj.visible ?: true } - } + }.launchIn(context) - obj.onStructureChanged(this){ childName -> - val child = get(childName) + obj.children.changes.onEach { childName -> + val child = obj.children[childName] //removing old object findChild(childName)?.let { oldChild -> @@ -97,7 +98,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { logger.error(ex) { "Failed to render $child" } } } - } + }.launchIn(context) } } is Composite -> compositeFactory.build(this, obj) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index 8e667dcb..27657931 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -7,20 +7,21 @@ import space.kscience.dataforge.names.cutFirst import space.kscience.dataforge.names.firstOrNull import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidReferenceGroup -import space.kscience.visionforge.solid.SolidReferenceGroup.Companion.REFERENCE_CHILD_PROPERTY_PREFIX +import space.kscience.visionforge.solid.SolidReference +import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX import kotlin.reflect.KClass -public object ThreeReferenceFactory : ThreeFactory { +public object ThreeReferenceFactory : ThreeFactory { private val cache = HashMap() - override val type: KClass = SolidReferenceGroup::class + override val type: KClass = SolidReference::class private fun Object3D.replicate(): Object3D { return when (this) { is Mesh -> Mesh(geometry, material).also { it.applyMatrix4(matrix) } + else -> clone(false) }.also { obj: Object3D -> obj.name = this.name @@ -30,7 +31,7 @@ public object ThreeReferenceFactory : ThreeFactory { } } - override fun build(three: ThreePlugin, obj: SolidReferenceGroup): Object3D { + override fun build(three: ThreePlugin, obj: SolidReference): Object3D { val template = obj.prototype val cachedObject = cache.getOrPut(template) { three.buildObject3D(template) @@ -39,18 +40,20 @@ public object ThreeReferenceFactory : ThreeFactory { val object3D: Object3D = cachedObject.replicate() object3D.updatePosition(obj) - if(object3D is Mesh){ + if (object3D is Mesh) { //object3D.material = ThreeMaterials.buildMaterial(obj.getProperty(SolidMaterial.MATERIAL_KEY).node!!) object3D.applyProperties(obj) } //TODO apply child properties - obj.onPropertyChange { name-> + obj.onPropertyChange { name -> if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { - val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'") + val childName = name.firstOrNull()?.index?.let(Name::parse) + ?: error("Wrong syntax for reference child property: '$name'") val propertyName = name.cutFirst() - val referenceChild = obj.children[childName] ?: error("Reference child with name '$childName' not found") + val referenceChild = + obj.children[childName] ?: error("Reference child with name '$childName' not found") val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") child.updateProperty(referenceChild, propertyName) } else { diff --git a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts index 67e12b10..399eb5b0 100644 --- a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts +++ b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val ktorVersion: String by rootProject.extra From ecf4a6a198133c620f9654b3703754a25fc70b82 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 13 Aug 2022 12:45:10 +0300 Subject: [PATCH 015/112] Add property flows --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 4 +- .../visionforge/gdml/GDMLVisionTest.kt | 4 +- demo/muon-monitor/build.gradle.kts | 1 + .../visionforge/solid/demo/VisionLayout.kt | 3 + .../kscience/visionforge/solid/demo/demo.kt | 2 + .../visionforge/solid/demo/ThreeDemoGrid.kt | 3 + .../visionforge/solid/demo/VariableBox.kt | 6 +- .../visionforge/solid/demo/FXDemoGrid.kt | 5 ++ visionforge-core/build.gradle.kts | 5 ++ .../space/kscience/visionforge/Vision.kt | 19 +--- .../kscience/visionforge/VisionChange.kt | 4 +- .../kscience/visionforge/VisionContainer.kt | 31 +++++-- .../space/kscience/visionforge/VisionGroup.kt | 29 ++++-- .../kscience/visionforge/VisionManager.kt | 6 +- .../kscience/visionforge/VisionProperties.kt | 15 +++- .../kscience/visionforge/flowProperty.kt | 55 ++++++++++++ .../space/kscience/visionforge/useProperty.kt | 54 +++++++++++ .../kscience/visionforge/html/HtmlTagTest.kt | 2 +- .../visionforge/meta/VisionPropertyTest.kt | 89 +++++++++++++++++-- .../visionforge/solid/FXReferenceFactory.kt | 2 +- .../kscience/visionforge/gdml/gdmlLoader.kt | 8 +- .../src/commonTest/kotlin/TestCubes.kt | 4 +- visionforge-solid/build.gradle.kts | 4 +- .../kscience/visionforge/solid/Composite.kt | 4 +- .../kscience/visionforge/solid/ConeSegment.kt | 6 +- .../kscience/visionforge/solid/ConeSurface.kt | 6 +- .../kscience/visionforge/solid/Convex.kt | 4 +- .../kscience/visionforge/solid/Extruded.kt | 2 +- .../kscience/visionforge/solid/Hexagon.kt | 6 +- .../kscience/visionforge/solid/LightSource.kt | 4 +- .../kscience/visionforge/solid/PolyLine.kt | 2 +- .../kscience/visionforge/solid/SolidGroup.kt | 10 +-- .../kscience/visionforge/solid/SolidLabel.kt | 4 +- .../visionforge/solid/SolidReference.kt | 8 +- .../kscience/visionforge/solid/Sphere.kt | 4 +- .../kscience/visionforge/solid/SphereLayer.kt | 4 +- .../solid/transform/RemoveSingleChild.kt | 2 +- .../visionforge/solid/transform/UnRef.kt | 8 +- .../kscience/visionforge/solid/GroupTest.kt | 6 +- .../visionforge/solid/SerializationTest.kt | 6 +- .../visionforge/solid/SolidPluginTest.kt | 6 +- .../visionforge/solid/SolidReferenceTest.kt | 6 +- .../visionforge/solid/VisionUpdateTest.kt | 8 +- visionforge-threejs/build.gradle.kts | 2 +- .../solid/three/ThreeBoxFactory.kt | 2 +- .../solid/three/ThreeCompositeFactory.kt | 2 +- .../solid/three/ThreeConeFactory.kt | 2 +- .../solid/three/ThreeConvexFactory.kt | 2 +- .../visionforge/solid/three/ThreeFactory.kt | 2 +- ...eshThreeFactory.kt => ThreeMeshFactory.kt} | 6 +- .../visionforge/solid/three/ThreePlugin.kt | 2 +- .../solid/three/ThreeReferenceFactory.kt | 2 +- .../solid/three/ThreeSphereFactory.kt | 2 +- 53 files changed, 356 insertions(+), 129 deletions(-) create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt rename visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/{MeshThreeFactory.kt => ThreeMeshFactory.kt} (96%) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index a867f054..b7b79b51 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -352,14 +352,14 @@ private fun SolidGroup.addRootVolume( } block() } - set(combinedName?.let { Name.parse(it) }, group) + setChild(combinedName?.let { Name.parse(it) }, group) } else { val templateName = volumesName + volume.name val existing = getPrototype(templateName) if (existing == null) { context.prototypeHolder.prototypes { val group = buildVolume(volume, context) - set(templateName, group) + setChild(templateName, group) } } diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index 723edb3b..294af3ee 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -5,7 +5,7 @@ import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Vision -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.material @@ -18,7 +18,7 @@ class GDMLVisionTest { @Test fun testCubesStyles(){ - val segment = cubes.children["composite-000.segment-0"] as Solid + val segment = cubes.children.getChild("composite-000.segment-0") as Solid println(segment.properties.getValue(Vision.STYLE_KEY)) // println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY)) // println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY)) diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index ad37a7c2..b2c69a7d 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -48,6 +48,7 @@ kotlin { implementation("io.ktor:ktor-server-cio:${ktorVersion}") implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}") implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}") + implementation("ch.qos.logback:logback-classic:1.2.11") } } jsMain { diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt index 016f2ecf..9b8c6b98 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt @@ -3,7 +3,10 @@ package space.kscience.visionforge.solid.demo import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision +import space.kscience.visionforge.solid.Solids public interface VisionLayout { + val solids: Solids + public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY) } \ No newline at end of file diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index 228f63f7..88c6d154 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -5,6 +5,7 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.invoke import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors +import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.visible @@ -22,6 +23,7 @@ fun VisionLayout.demo(name: String, title: String = name, block: SolidGro ambientLight{ color.set(Colors.white) } + setAsRoot(solids.visionManager) } render(Name.parse(name), vision, meta) } diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt index 6dcfa36f..d448349c 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt @@ -16,6 +16,7 @@ import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.three.ThreeCanvas import space.kscience.visionforge.solid.three.ThreePlugin @@ -27,6 +28,8 @@ class ThreeDemoGrid(element: Element) : VisionLayout { private val three = Global.fetch(ThreePlugin) + override val solids: Solids get() = three.solids + init { element.clear() element.append { diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index 56221efb..e55b1c8d 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -9,7 +9,7 @@ import space.kscience.dataforge.meta.number import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.onPropertyChange -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.three.* @@ -20,7 +20,7 @@ internal fun SolidGroup.varBox( ySize: Number, name: String = "", action: VariableBox.() -> Unit = {}, -): VariableBox = VariableBox(xSize, ySize).apply(action).also { set(name, it) } +): VariableBox = VariableBox(xSize, ySize).apply(action).also { setChild(name, it) } internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision() { @@ -59,7 +59,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision material.color.setRGB(r.toFloat() / 256, g.toFloat() / 256, b.toFloat() / 256) mesh.updateMatrix() } - name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox) + name.startsWith(ThreeMeshFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox) else -> mesh.updateProperty(this@VariableBox, name) } } diff --git a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt b/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt index ef03092a..81501016 100644 --- a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt +++ b/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt @@ -10,9 +10,11 @@ import space.kscience.dataforge.names.Name import space.kscience.visionforge.solid.FX3DPlugin import space.kscience.visionforge.solid.FXCanvas3D import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.Solids import tornadofx.* class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout { + private val outputs = FXCollections.observableHashMap() override val root: Parent = borderpane { @@ -24,6 +26,9 @@ class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout { } private val fx3d = Global.fetch(FX3DPlugin) + override val solids: Solids get() = fx3d.solids + + override fun render(name: Name, vision: Solid, meta: Meta) { outputs.getOrPut(name) { FXCanvas3D(fx3d, canvasOptions) }.render(vision) diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index d9bf251c..a8886521 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -13,6 +13,11 @@ kotlin { api("org.jetbrains.kotlin-wrappers:kotlin-css") } } + commonTest{ + dependencies{ + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${space.kscience.gradle.KScienceVersions.coroutinesVersion}") + } + } jsMain { dependencies { api("org.jetbrains.kotlin-wrappers:kotlin-extensions") diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index a8b590e7..aa698409 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -11,10 +11,8 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.TYPE -import kotlin.reflect.KProperty1 /** * A root type for display hierarchy @@ -72,19 +70,4 @@ public fun Vision.onPropertyChange( callback: (Name) -> Unit ): Job = properties.changes.onEach { callback(it) -}.launchIn(scope ?: error("Orphan Vision can't observe properties")) - - -public fun V.useProperty( - property: KProperty1, - scope: CoroutineScope? = manager?.context, - callBack: V.(T) -> Unit, -): Job { - //Pass initial value. - callBack(property.get(this)) - return properties.changes.onEach { name -> - if (name.startsWith(property.name.asName())) { - callBack(property.get(this@useProperty)) - } - }.launchIn(scope ?: error("Orphan Vision can't observe properties")) -} \ No newline at end of file +}.launchIn(scope ?: error("Orphan Vision can't observe properties")) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 0e3a8dc1..29c38ebd 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -47,7 +47,7 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi } } - override fun set(name: Name?, child: Vision?) { + override fun setChild(name: Name?, child: Vision?) { if (name == null) error("Static children are not allowed in VisionChange") getOrPutChild(name).apply { vision = child @@ -109,7 +109,7 @@ private fun CoroutineScope.collectChange( if (after != null) { collectChange(fullName, after, collector) } - collector()[fullName] = after + collector().setChild(fullName, after) }?.launchIn(this) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index 481a53ce..bda9ab42 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -11,12 +11,12 @@ import kotlin.jvm.Synchronized public annotation class VisionBuilder public interface VisionContainer { - public operator fun get(name: Name): V? + public fun getChild(name: Name): V? } public interface MutableVisionContainer { //TODO add documentation - public operator fun set(name: Name?, child: V?) + public fun setChild(name: Name?, child: V?) } /** @@ -33,10 +33,10 @@ public interface VisionChildren : VisionContainer { public operator fun get(token: NameToken): Vision? - override fun get(name: Name): Vision? = when (name.length) { + override fun getChild(name: Name): Vision? = when (name.length) { 0 -> group 1 -> get(name.first()) - else -> get(name.first())?.children?.get(name.cutFirst()) + else -> get(name.first())?.children?.getChild(name.cutFirst()) } public companion object { @@ -49,6 +49,10 @@ public interface VisionChildren : VisionContainer { } } +public operator fun VisionChildren.get(name: Name): Vision? = getChild(name) +public operator fun VisionChildren.get(name: String): Vision? = getChild(name) + + public fun VisionChildren.isEmpty(): Boolean = keys.isEmpty() public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) { @@ -61,7 +65,7 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer< public operator fun set(token: NameToken, value: Vision?) - override fun set(name: Name?, child: Vision?) { + override fun setChild(name: Name?, child: Vision?) { when { name == null -> { if (child != null) { @@ -81,7 +85,7 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer< val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group.createGroup().also { set(name.first(), it) } - parent.children[name.cutFirst()] = child + parent.children.setChild(name.cutFirst(), child) } } } @@ -89,6 +93,15 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer< public fun clear() } +public operator fun MutableVisionChildren.set(name: Name?, vision: Vision?) { + setChild(name, vision) +} + +public operator fun MutableVisionChildren.set(name: String?, vision: Vision?) { + setChild(name, vision) +} + + /** * Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events. */ @@ -102,11 +115,11 @@ public fun VisionChildren.asSequence(): Sequence> = sequ public operator fun VisionChildren.iterator(): Iterator> = asSequence().iterator() -public operator fun VisionContainer.get(str: String): V? = get(Name.parse(str)) +public fun VisionContainer.getChild(str: String): V? = getChild(Name.parse(str)) -public operator fun MutableVisionContainer.set( +public fun MutableVisionContainer.setChild( str: String?, vision: V?, -): Unit = set(str?.parseAsName(), vision) +): Unit = setChild(str?.parseAsName(), vision) internal abstract class VisionChildrenImpl( override val group: MutableVisionGroup, diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index 8faa21b4..613a5dfe 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -10,7 +10,6 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.plus import space.kscience.visionforge.Vision.Companion.STYLE_KEY -import kotlin.js.JsName public interface VisionGroup : Vision { @@ -35,9 +34,9 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup override fun update(change: VisionChange) { change.children?.forEach { (name, change) -> when { - change.delete -> children[name] = null - change.vision != null -> children[name] = change.vision - else -> children[name]?.update(change) + change.delete -> children.setChild(name, null) + change.vision != null -> children.setChild(name, change.vision) + else -> children.getChild(name)?.update(change) } } change.properties?.let { @@ -87,12 +86,28 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup */ @Serializable @SerialName("vision.group") -public class SimpleVisionGroup : AbstractVisionGroup() { +public class SimpleVisionGroup : AbstractVisionGroup(), MutableVisionContainer { override fun createGroup(): SimpleVisionGroup = SimpleVisionGroup() + + override fun setChild(name: Name?, child: Vision?) { + children.setChild(name, child) + } } -@JsName("createVisionGroup") -public fun VisionGroup(): VisionGroup = SimpleVisionGroup() +@VisionBuilder +public fun MutableVisionContainer.group( + name: Name? = null, + builder: SimpleVisionGroup.() -> Unit = {}, +): SimpleVisionGroup = SimpleVisionGroup().apply(builder).also { setChild(name, it) } + +/** + * Define a group with given [name], attach it to this parent and return it. + */ +@VisionBuilder +public fun MutableVisionContainer.group( + name: String, + builder: SimpleVisionGroup.() -> Unit = {}, +): SimpleVisionGroup = SimpleVisionGroup().apply(builder).also { setChild(name, it) } //fun VisualObject.findStyle(styleName: Name): Meta? { // if (this is VisualGroup) { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index a6f1a7c6..314b15d5 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -19,7 +19,7 @@ import space.kscience.visionforge.html.VisionOfNumberField import space.kscience.visionforge.html.VisionOfTextField import kotlin.reflect.KClass -public class VisionManager(meta: Meta) : AbstractPlugin(meta) { +public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionContainer { override val tag: PluginTag get() = Companion.tag /** @@ -58,6 +58,10 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) { public fun encodeToMeta(vision: Vision, descriptor: MetaDescriptor? = null): Meta = encodeToJsonElement(vision).toMeta(descriptor) + override fun setChild(name: Name?, child: Vision?) { + child?.setAsRoot(this) + } + public companion object : PluginFactory { override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP) override val type: KClass = VisionManager::class diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 693e85bf..1f751d55 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -73,6 +73,19 @@ public interface MutableVisionProperties : VisionProperties { ) } +public fun MutableVisionProperties.remove(name: Name){ + setProperty(name, null) +} + +public fun MutableVisionProperties.remove(name: String){ + remove(name.parseAsName()) +} + +@VisionBuilder +public operator fun MutableVisionProperties.invoke(block: MutableMeta.() -> Unit) { + root(inherit = false, includeStyles = false).apply(block) +} + private class VisionPropertiesItem( val properties: MutableVisionProperties, val nodeName: Name, @@ -190,7 +203,7 @@ public abstract class AbstractVisionProperties( } @Transient - private val _changes = MutableSharedFlow(10) + private val _changes = MutableSharedFlow() override val changes: SharedFlow get() = _changes @OptIn(DelicateCoroutinesApi::class) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt new file mode 100644 index 00000000..c8f14ae3 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt @@ -0,0 +1,55 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.Value +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.parseAsName +import space.kscience.dataforge.names.startsWith + +/** + * Create a flow of a specific property + */ +public fun Vision.flowProperty( + propertyName: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Flow = flow { + //Pass initial value. + emit(properties.getProperty(propertyName, inherit, includeStyles)) + properties.changes.collect { name -> + if (name.startsWith(propertyName)) { + emit(properties.getProperty(propertyName, inherit, includeStyles)) + } + } +} + +public fun Vision.flowProperty( + propertyName: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Flow = flowProperty(propertyName.parseAsName(), inherit, includeStyles) + +/** + * Flow the value of specific property + */ +public fun Vision.flowPropertyValue( + propertyName: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Flow = flow { + //Pass initial value. + emit(properties.getValue(propertyName, inherit, includeStyles)) + properties.changes.collect { name -> + if (name.startsWith(propertyName)) { + emit(properties.getValue(propertyName, inherit, includeStyles)) + } + } +} + +public fun Vision.flowPropertyValue( + propertyName: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Flow = flowPropertyValue(propertyName.parseAsName(), inherit, includeStyles) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt new file mode 100644 index 00000000..b7cec960 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt @@ -0,0 +1,54 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.parseAsName +import space.kscience.dataforge.names.startsWith +import kotlin.reflect.KProperty1 + + +/** + * Call [callBack] on initial value of the property and then on all subsequent values after change + */ +public fun Vision.useProperty( + propertyName: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, + scope: CoroutineScope? = manager?.context, + callBack: (Meta) -> Unit, +): Job { + //Pass initial value. + callBack(properties.getProperty(propertyName, inherit, includeStyles)) + return properties.changes.onEach { name -> + if (name.startsWith(propertyName)) { + callBack(properties.getProperty(propertyName, inherit, includeStyles)) + } + }.launchIn(scope ?: error("Orphan Vision can't observe properties")) +} + +public fun Vision.useProperty( + propertyName: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, + scope: CoroutineScope? = manager?.context, + callBack: (Meta) -> Unit, +): Job = useProperty(propertyName.parseAsName(),inherit, includeStyles, scope, callBack) + +public fun V.useProperty( + property: KProperty1, + scope: CoroutineScope? = manager?.context, + callBack: V.(T) -> Unit, +): Job { + //Pass initial value. + callBack(property.get(this)) + return properties.changes.onEach { name -> + if (name.startsWith(property.name.asName())) { + callBack(property.get(this@useProperty)) + } + }.launchIn(scope ?: error("Orphan Vision can't observe properties")) +} \ No newline at end of file diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index f72fe2bf..670f2018 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -30,7 +30,7 @@ fun FlowContent.renderVisionFragment( @DFExperimental -private fun VisionOutput.base(block: VisionGroup.() -> Unit) = VisionGroup().apply(block) +private fun VisionOutput.base(block: VisionGroup.() -> Unit) = context.visionManager.group().apply(block) @DFExperimental class HtmlTagTest { diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index e7a35faa..64f0d0b2 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -1,10 +1,14 @@ package space.kscience.visionforge.meta +import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.collectIndexed +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import space.kscience.dataforge.context.Global +import space.kscience.dataforge.context.fetch import space.kscience.dataforge.meta.* -import space.kscience.visionforge.VisionGroup -import space.kscience.visionforge.getProperty -import space.kscience.visionforge.getValue -import space.kscience.visionforge.set +import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals @@ -17,9 +21,12 @@ private class TestScheme : Scheme() { } internal class VisionPropertyTest { + + private val manager = Global.fetch(VisionManager) + @Test fun testPropertyWrite() { - val vision = VisionGroup() + val vision = manager.group() vision.properties["fff"] = 2 vision.properties["fff.ddd"] = false @@ -29,7 +36,7 @@ internal class VisionPropertyTest { @Test fun testPropertyEdit() { - val vision = VisionGroup() + val vision = manager.group() vision.properties.getProperty("fff.ddd").apply { value = 2.asValue() } @@ -39,10 +46,78 @@ internal class VisionPropertyTest { @Test fun testPropertyUpdate() { - val vision = VisionGroup() + val vision = manager.group() vision.properties.getProperty("fff").updateWith(TestScheme) { ddd = 2 } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) } + + @Test + fun testChildrenPropertyPropagation() = runTest(dispatchTimeoutMs = 200) { + val group = Global.fetch(VisionManager).group { + properties { + "test" put 11 + } + group("child") { + properties { + "test" put 22 + } + } + } + + val child = group.children["child"]!! + + var value: Value? = null + + var callCounter = 0 + + child.useProperty("test", inherit = true) { + callCounter++ + value = it.value + } + + assertEquals(22, value?.int) + assertEquals(1, callCounter) + + child.properties.remove("test") + + //Need this to avoid the race + delay(20) + + assertEquals(11, child.properties.getProperty("test", inherit = true).int) + assertEquals(11, value?.int) + assertEquals(2, callCounter) + } + + @Test + fun testChildrenPropertyFlow() = runTest(dispatchTimeoutMs = 200) { + val group = Global.fetch(VisionManager).group { + properties { + "test" put 11 + } + group("child") { + properties { + "test" put 22 + } + } + } + + val child = group.children["child"]!! + + launch { + child.flowPropertyValue("test", inherit = true).collectIndexed { index, value -> + if (index == 0) { + assertEquals(22, value?.int) + } else if (index == 1) { + assertEquals(11, value?.int) + cancel() + } + } + } + //wait for subscription to be created + delay(10) + + child.properties.remove("test") + } } \ No newline at end of file diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt index 60b95f9f..1c3ecb60 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt @@ -22,7 +22,7 @@ public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory { val group: SolidGroup = volume(root, volume) - this[physVolume.name] = group.withPosition(root, physVolume) + this.setChild(physVolume.name, group.withPosition(root, physVolume)) } GdmlLoaderOptions.Action.PROTOTYPE -> { proxyVolume(root, this, physVolume, volume) @@ -357,7 +357,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { final.prototypes { proto.items.forEach { (token, item) -> item.parent = null - set(token.asName(), item as? Solid) + setChild(token.asName(), item as? Solid) } } settings.styleCache.forEach { @@ -385,7 +385,7 @@ public fun Gdml.toVision(block: GdmlLoaderOptions.() -> Unit = {}): SolidGroup { public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlLoaderOptions.() -> Unit = {}) { val vision = gdml.toVision(transformer) //println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual)) - children[key] = vision + children.setChild(key, vision) } @VisionBuilder diff --git a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt index a30cf863..aa262c45 100644 --- a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt +++ b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt @@ -4,7 +4,7 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.names.Name import space.kscience.gdml.* import space.kscience.visionforge.Vision -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import space.kscience.visionforge.solid.* import space.kscience.visionforge.visionManager import kotlin.test.Test @@ -26,7 +26,7 @@ class TestCubes { val smallBoxPrototype = vision.getPrototype(Name.parse("solids.smallBox")) as? Box assertNotNull(smallBoxPrototype) assertEquals(30.0, smallBoxPrototype.xSize.toDouble()) - val smallBoxVision = vision.children["composite-111.smallBox"]?.prototype as? Box + val smallBoxVision = vision.children.getChild("composite-111.smallBox")?.prototype as? Box assertNotNull(smallBoxVision) assertEquals(30.0, smallBoxVision.xSize.toDouble()) } diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index f794afe4..7a0f145c 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -1,3 +1,5 @@ +import space.kscience.gradle.KScienceVersions + plugins { id("space.kscience.gradle.mpp") } @@ -17,7 +19,7 @@ kotlin { } commonTest{ dependencies{ - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${KScienceVersions.coroutinesVersion}") } } jvmTest{ diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index fb1b4774..1c28025c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -35,7 +35,7 @@ public inline fun MutableVisionContainer.composite( res.properties.setProperty(Name.EMPTY, group.properties.own) - set(name, res) + setChild(name, res) return res } @@ -57,7 +57,7 @@ public fun SolidGroup.smartComposite( } this } else { - children[name] = group + children.setChild(name, group) group } } else { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt index 1a8e4a9d..873ae44e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import kotlin.math.cos import kotlin.math.sin @@ -76,7 +76,7 @@ public inline fun MutableVisionContainer.cylinder( r.toFloat(), height.toFloat(), r.toFloat() -).apply(block).also { set(name, it) } +).apply(block).also { setChild(name, it) } @VisionBuilder public inline fun MutableVisionContainer.cone( @@ -93,4 +93,4 @@ public inline fun MutableVisionContainer.cone( topRadius = upperRadius.toFloat(), startAngle = startAngle.toFloat(), angle = angle.toFloat() -).apply(block).also { set(name, it) } \ No newline at end of file +).apply(block).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt index b5a4d5cf..0bc023e6 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin @@ -139,7 +139,7 @@ public inline fun MutableVisionContainer.tube( topInnerRadius = innerRadius.toFloat(), startAngle = startAngle.toFloat(), angle = angle.toFloat() -).apply(block).also { set(name, it) } +).apply(block).also { setChild(name, it) } @VisionBuilder public inline fun MutableVisionContainer.coneSurface( @@ -160,4 +160,4 @@ public inline fun MutableVisionContainer.coneSurface( topInnerRadius = topInnerRadius.toFloat(), startAngle = startAngle.toFloat(), angle = angle.toFloat() -).apply(block).also { set(name, it) } \ No newline at end of file +).apply(block).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt index ad0a456e..4d50c2c4 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.visionforge.MutableVisionContainer -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild @Serializable @SerialName("solid.convex") @@ -12,7 +12,7 @@ public class Convex(public val points: List) : SolidBase() public inline fun MutableVisionContainer.convex( name: String? = null, action: ConvexBuilder.() -> Unit = {}, -): Convex = ConvexBuilder().apply(action).build().also { set(name, it) } +): Convex = ConvexBuilder().apply(action).build().also { setChild(name, it) } public class ConvexBuilder { private val points = ArrayList() diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 68eded95..faec109b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -115,4 +115,4 @@ public class ExtrudeBuilder( public fun MutableVisionContainer.extruded( name: String? = null, action: ExtrudeBuilder.() -> Unit = {}, -): Extruded = ExtrudeBuilder().apply(action).build().also { set(name, it) } \ No newline at end of file +): Extruded = ExtrudeBuilder().apply(action).build().also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt index b327f9bf..92f11e1b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild public interface Hexagon : GeometrySolid { public val node1: Point3D @@ -58,7 +58,7 @@ public inline fun MutableVisionContainer.box( zSize: Number, name: String? = null, block: Box.() -> Unit = {}, -): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { set(name, it) } +): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { setChild(name, it) } @Serializable @SerialName("solid.hexagon") @@ -85,4 +85,4 @@ public inline fun MutableVisionContainer.hexagon( node8: Point3D, name: String? = null, action: Hexagon.() -> Unit = {}, -): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { set(name, it) } \ No newline at end of file +): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt index 13736fcd..3db461ef 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -55,7 +55,7 @@ public class AmbientLightSource : LightSource() public fun MutableVisionContainer.ambientLight( name: String? = "@ambientLight", block: AmbientLightSource.() -> Unit = {}, -): AmbientLightSource = AmbientLightSource().apply(block).also { set(name, it) } +): AmbientLightSource = AmbientLightSource().apply(block).also { setChild(name, it) } @Serializable @SerialName("solid.light.point") @@ -71,5 +71,5 @@ public fun MutableVisionContainer.pointLight( block: PointLightSource.() -> Unit = {}, ): PointLightSource = PointLightSource().apply(block).also { it.position = Point3D(x, y, z) - set(name, it) + setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt index 587e803c..4d5373b8 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt @@ -18,4 +18,4 @@ public fun MutableVisionContainer.polyline( vararg points: Point3D, name: String? = null, action: PolyLine.() -> Unit = {}, -): PolyLine = PolyLine(points.toList()).apply(action).also { set(name, it) } \ No newline at end of file +): PolyLine = PolyLine(points.toList()).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index 80a1129d..f3ca4cf8 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -38,7 +38,7 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable it to value }.toMap() - public operator fun get(name: Name): Solid? = children[name] as? Solid + public operator fun get(name: Name): Solid? = children.getChild(name) as? Solid private var prototypes: SolidGroup? get() = items[PROTOTYPES_TOKEN] as? SolidGroup @@ -70,8 +70,8 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable // super.update(change) // } - override fun set(name: Name?, child: Solid?) { - children[name] = child + override fun setChild(name: Name?, child: Solid?) { + children.setChild(name, child) } public companion object { @@ -85,7 +85,7 @@ public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGr public fun MutableVisionContainer.group( name: Name? = null, builder: SolidGroup.() -> Unit = {}, -): SolidGroup = SolidGroup(builder).also { set(name, it) } +): SolidGroup = SolidGroup(builder).also { setChild(name, it) } /** * Define a group with given [name], attach it to this parent and return it. @@ -94,4 +94,4 @@ public fun MutableVisionContainer.group( public fun MutableVisionContainer.group( name: String, action: SolidGroup.() -> Unit = {}, -): SolidGroup = SolidGroup(action).also { set(name, it) } +): SolidGroup = SolidGroup(action).also { setChild(name, it) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt index 649e7f7c..2e59c1f8 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild @Serializable @SerialName("solid.label") @@ -21,4 +21,4 @@ public fun MutableVisionContainer.label( fontFamily: String = "Arial", name: String? = null, action: SolidLabel.() -> Unit = {}, -): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) } \ No newline at end of file +): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 51e0bc6b..76eb56aa 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -97,7 +97,7 @@ internal class SolidReferenceChild( ) : Solid, VisionGroup { val prototype: Solid - get() = owner.prototype.children?.get(childName) as? Solid + get() = owner.prototype.children?.getChild(childName) as? Solid ?: error("Prototype with name $childName not found") override val descriptor: MetaDescriptor get() = prototype.descriptor @@ -137,7 +137,7 @@ internal class SolidReferenceChild( when { change.delete -> error("Deleting children inside ref is not allowed.") change.vision != null -> error("Updating content of the ref is not allowed") - else -> children[name]?.update(change) + else -> children.getChild(name)?.update(change) } } change.properties?.let { @@ -176,7 +176,7 @@ internal class SolidReferenceChild( public fun MutableVisionContainer.ref( templateName: Name, name: String? = null, -): SolidReference = SolidReference(templateName).also { set(name, it) } +): SolidReference = SolidReference(templateName).also { setChild(name, it) } public fun MutableVisionContainer.ref( templateName: String, @@ -195,7 +195,7 @@ public fun SolidGroup.newRef( val existing = prototypeHolder.getPrototype(prototypeName) if (existing == null) { prototypeHolder.prototypes { - set(prototypeName, obj) + setChild(prototypeName, obj) } } else if (existing != obj) { error("Can't add different prototype on top of existing one") diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt index 0ce0d893..ed43f663 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin @@ -58,4 +58,4 @@ public inline fun MutableVisionContainer.sphere( action: Sphere.() -> Unit = {}, ): Sphere = Sphere( radius.toFloat(), -).apply(action).also { set(name, it) } \ No newline at end of file +).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt index 709968af..bb630772 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin @@ -85,4 +85,4 @@ public inline fun MutableVisionContainer.sphereLayer( phi.toFloat(), thetaStart.toFloat(), theta.toFloat() -).apply(action).also { set(name, it) } \ No newline at end of file +).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index dc01e749..d1e6fe5a 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -39,7 +39,7 @@ internal object RemoveSingleChild : VisualTreeTransform() { val child: Solid = parent.items.values.first() val newParent = child.updateFrom(parent) newParent.parent = null - children[childName.asName()] = newParent + children.setChild(childName.asName(), newParent) } } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt index b78863d2..72fa1a76 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt @@ -4,14 +4,8 @@ import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.SolidReference -import kotlin.collections.HashMap -import kotlin.collections.Map import kotlin.collections.component1 import kotlin.collections.component2 -import kotlin.collections.filter -import kotlin.collections.filterIsInstance -import kotlin.collections.fold -import kotlin.collections.forEach import kotlin.collections.set @DFExperimental @@ -33,7 +27,7 @@ internal object UnRef : VisualTreeTransform() { private fun SolidGroup.unref(name: Name) { (this as? SolidGroup)?.prototypes{ - set(name, null) + setChild(name, null) } items.filter { (it.value as? SolidReference)?.prototypeName == name }.forEach { (key, value) -> val reference = value as SolidReference diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt index 87de5c77..013a8d4c 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid import space.kscience.visionforge.Colors -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import kotlin.math.PI import kotlin.test.Test import kotlin.test.assertEquals @@ -45,7 +45,7 @@ class GroupTest { } assertEquals(3, group.items.count()) - assertEquals(300.0, (group.children["intersect"] as Solid).y.toDouble()) - assertEquals(-300.0, (group.children["subtract"] as Solid).y.toDouble()) + assertEquals(300.0, (group.children.getChild("intersect") as Solid).y.toDouble()) + assertEquals(-300.0, (group.children.getChild("subtract") as Solid).y.toDouble()) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index c2dee067..49c90dab 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -2,7 +2,7 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import kotlin.test.Test import kotlin.test.assertEquals @@ -52,7 +52,7 @@ class SerializationTest { val string = Solids.encodeToString(group) println(string) val reconstructed = Solids.decodeFromString(string) as SolidGroup - assertEquals(group.children["cube"]?.properties?.own, reconstructed.children["cube"]?.properties?.own) + assertEquals(group.children.getChild("cube")?.properties?.own, reconstructed.children.getChild("cube")?.properties?.own) } @Test @@ -66,7 +66,7 @@ class SerializationTest { val serialized = Solids.encodeToString(group) val reconstructed = Solids.decodeFromString(serialized) as SolidGroup - assertEquals(100.0, (reconstructed.children["@ambientLight"] as AmbientLightSource).intensity.toDouble()) + assertEquals(100.0, (reconstructed.children.getChild("@ambientLight") as AmbientLightSource).intensity.toDouble()) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt index 4ac22e1f..d60b9042 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.fetch import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import kotlin.test.Test import kotlin.test.assertEquals @@ -25,8 +25,8 @@ class SolidPluginTest { val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup assertEquals( - visionManager.encodeToJsonElement(vision.children["aBox"]!!), - visionManager.encodeToJsonElement(reconstructed.children["aBox"]!!) + visionManager.encodeToJsonElement(vision.children.getChild("aBox")!!), + visionManager.encodeToJsonElement(reconstructed.children.getChild("aBox")!!) ) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt index f74426ba..027f8b03 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge.solid import kotlinx.serialization.json.encodeToJsonElement import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.get -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import space.kscience.visionforge.style import space.kscience.visionforge.useStyle import kotlin.test.Test @@ -24,7 +24,7 @@ class SolidReferenceTest { @Test fun testReferenceProperty(){ - assertEquals("blue", (groupWithReference.children["test"] as Solid).color.string) + assertEquals("blue", (groupWithReference.children.getChild("test") as Solid).color.string) } @Test @@ -32,6 +32,6 @@ class SolidReferenceTest { val serialized = Solids.jsonForSolids.encodeToJsonElement(groupWithReference) val deserialized = Solids.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized) assertEquals(groupWithReference.items["test"]?.color.string, deserialized.items["test"]?.color.string) - assertEquals("blue", (deserialized.children["test"] as Solid).color.string) + assertEquals("blue", (deserialized.children.getChild("test") as Solid).color.string) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index e5a13594..2cf5c861 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -6,7 +6,7 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.names.asName import space.kscience.visionforge.VisionChange -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -29,9 +29,9 @@ internal class VisionUpdateTest { propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) } targetVision.update(dif) - assertTrue { targetVision.children["top"] is SolidGroup } - assertEquals("red", (targetVision.children["origin"] as Solid).color.string) // Should work - assertEquals("#00007b", (targetVision.children["top"] as Solid).color.string) // new item always takes precedence + assertTrue { targetVision.children.getChild("top") is SolidGroup } + assertEquals("red", (targetVision.children.getChild("origin") as Solid).color.string) // Should work + assertEquals("#00007b", (targetVision.children.getChild("top") as Solid).color.string) // new item always takes precedence } @Test diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index d9d0f96d..86b8702c 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -10,6 +10,6 @@ kotlin{ dependencies { api(project(":visionforge-solid")) - implementation(npm("three", "0.137.4")) + implementation(npm("three", "0.137.5")) implementation(npm("three-csg-ts", "3.1.10")) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt index a5b50688..f66492ed 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt @@ -4,7 +4,7 @@ import info.laht.threekt.geometries.BoxGeometry import space.kscience.visionforge.solid.Box import space.kscience.visionforge.solid.detail -public object ThreeBoxFactory : MeshThreeFactory(Box::class) { +public object ThreeBoxFactory : ThreeMeshFactory(Box::class) { override fun buildGeometry(obj: Box): BoxGeometry = obj.detail?.let { detail -> BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index 4bd9826c..de318f95 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -50,7 +50,7 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory obj.onPropertyChange { name -> when { //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) - name.startsWith(MeshThreeFactory.EDGES_KEY) -> applyEdges(obj) + name.startsWith(ThreeMeshFactory.EDGES_KEY) -> applyEdges(obj) else -> updateProperty(obj, name) } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt index 5789c30e..8eed04ae 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt @@ -7,7 +7,7 @@ import space.kscience.visionforge.solid.detail import kotlin.math.PI import kotlin.math.pow -public object ThreeConeFactory : MeshThreeFactory(ConeSegment::class) { +public object ThreeConeFactory : ThreeMeshFactory(ConeSegment::class) { override fun buildGeometry(obj: ConeSegment): BufferGeometry { val cylinder = obj.detail?.let { val segments = it.toDouble().pow(0.5).toInt() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt index fe08b1cf..2ab67219 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.external.geometries.ConvexBufferGeometry import space.kscience.visionforge.solid.Convex -public object ThreeConvexFactory : MeshThreeFactory(Convex::class) { +public object ThreeConvexFactory : ThreeMeshFactory(Convex::class) { override fun buildGeometry(obj: Convex): ConvexBufferGeometry { val vectors = obj.points.map { it.toVector() }.toTypedArray() return ConvexBufferGeometry(vectors) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 3397ea96..8c39aeb3 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -75,7 +75,7 @@ public fun Object3D.updateProperty(source: Vision, propertyName: Name) { /** * Generic factory for elements which provide inside geometry builder */ -public object ThreeShapeFactory : MeshThreeFactory(GeometrySolid::class) { +public object ThreeShapeFactory : ThreeMeshFactory(GeometrySolid::class) { override fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply { obj.toGeometry(this) }.build() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt similarity index 96% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt rename to visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index 9309848f..ea39bbea 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -15,14 +15,14 @@ import space.kscience.visionforge.set import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.layer -import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_ENABLED_KEY -import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_MATERIAL_KEY +import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_ENABLED_KEY +import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_MATERIAL_KEY import kotlin.reflect.KClass /** * Basic geometry-based factory */ -public abstract class MeshThreeFactory( +public abstract class ThreeMeshFactory( override val type: KClass, ) : ThreeFactory { /** diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 2fe9585c..7c1358d7 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -82,7 +82,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { }.launchIn(context) obj.children.changes.onEach { childName -> - val child = obj.children[childName] + val child = obj.children.getChild(childName) //removing old object findChild(childName)?.let { oldChild -> diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index 27657931..ade11074 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -53,7 +53,7 @@ public object ThreeReferenceFactory : ThreeFactory { ?: error("Wrong syntax for reference child property: '$name'") val propertyName = name.cutFirst() val referenceChild = - obj.children[childName] ?: error("Reference child with name '$childName' not found") + obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found") val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") child.updateProperty(referenceChild, propertyName) } else { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt index 8932a6c8..9d4926c5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt @@ -5,7 +5,7 @@ import info.laht.threekt.geometries.SphereGeometry import space.kscience.visionforge.solid.Sphere import space.kscience.visionforge.solid.detail -public object ThreeSphereFactory : MeshThreeFactory(Sphere::class) { +public object ThreeSphereFactory : ThreeMeshFactory(Sphere::class) { override fun buildGeometry(obj: Sphere): BufferGeometry { return obj.detail?.let {detail -> SphereGeometry( From c586a2ea14f2b3be330914abe8b93d2efd0fdf16 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 13 Aug 2022 18:17:22 +0300 Subject: [PATCH 016/112] Fix (almost) property resolution --- .../src/jvmMain/kotlin/formServer.kt | 2 +- .../visionforge/solid/demo/VariableBox.kt | 1 + .../visionforge/react/PropertyEditor.kt | 6 ++- .../ringThreeControls.kt | 2 + .../kscience/visionforge/StyleReference.kt | 4 +- .../space/kscience/visionforge/StyleSheet.kt | 8 ++-- .../kscience/visionforge/VisionChange.kt | 2 +- .../kscience/visionforge/VisionProperties.kt | 41 ++++++++++++------ .../visionforge/html/VisionTagConsumer.kt | 4 +- .../space/kscience/visionforge/useProperty.kt | 2 +- .../visionforge/meta/VisionPropertyTest.kt | 42 +++++++++++-------- .../kscience/visionforge/solid/FX3DPlugin.kt | 4 +- .../visionforge/solid/FXCompositeFactory.kt | 2 +- .../visionforge/solid/FXConvexFactory.kt | 2 +- .../visionforge/solid/FXReferenceFactory.kt | 10 +++-- .../visionforge/solid/FXShapeFactory.kt | 2 +- ...lObjectFXBinding.kt => VisionFXBinding.kt} | 2 +- .../visionforge/gdml/GdmlLoaderOptions.kt | 2 +- .../kscience/visionforge/gdml/gdmlLoader.kt | 2 +- .../visionforge/solid/SolidReference.kt | 26 +++++++++++- .../{PropertyTest.kt => SolidPropertyTest.kt} | 10 +++-- .../solid/three/ThreeLabelFactory.kt | 2 +- .../solid/three/ThreeMeshFactory.kt | 2 +- .../visionforge/solid/three/ThreePlugin.kt | 7 +++- 24 files changed, 123 insertions(+), 64 deletions(-) rename visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/{VisualObjectFXBinding.kt => VisionFXBinding.kt} (96%) rename visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/{PropertyTest.kt => SolidPropertyTest.kt} (92%) diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index 7397b6b6..accd1a16 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -49,7 +49,7 @@ fun main() { } vision("form") { form } - form.onPropertyChange { + form.onPropertyChange { _, _ -> println(this) } } diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index e55b1c8d..28b0c968 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -59,6 +59,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision material.color.setRGB(r.toFloat() / 256, g.toFloat() / 256, b.toFloat() / 256) mesh.updateMatrix() } + name.startsWith(ThreeMeshFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox) else -> mesh.updateProperty(this@VariableBox, name) } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index 4e94ef06..ca64fd07 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -74,6 +74,8 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) } var property: MutableMeta by useState { props.meta.getOrCreate(props.name) } + val defined = props.getPropertyState(props.name) == EditorPropertyState.Defined + val keys = useMemo(descriptor) { buildSet { descriptor?.children?.filterNot { @@ -134,7 +136,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { styledSpan { css { +TreeStyles.treeLabel - if (property.isEmpty()) { + if (!defined) { +TreeStyles.treeLabelInactive } } @@ -175,7 +177,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } +"\u00D7" attrs { - if (property.isEmpty()) { + if (!defined) { disabled = true } else { onClickFunction = removeClick diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt index 1b62bd1f..6a440e71 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.ring +import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope import kotlinx.css.BorderStyle import kotlinx.css.Color @@ -52,6 +53,7 @@ internal external interface CanvasControlsProps : Props { public var vision: Vision? } +@OptIn(DelicateCoroutinesApi::class) internal val CanvasControls: FC = fc("CanvasControls") { props -> flexColumn { flexRow { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt index 0e2b6132..62d898b8 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt @@ -18,10 +18,10 @@ private tailrec fun styleIsDefined(vision: Vision, reference: StyleReference): B } @VisionBuilder -public fun Vision.useStyle(reference: StyleReference) { +public fun Vision.useStyle(reference: StyleReference, notify: Boolean = true) { //check that style is defined in a parent //check(styleIsDefined(this, reference)) { "Style reference does not belong to a Vision parent" } - useStyle(reference.name) + useStyle(reference.name, notify) } @VisionBuilder diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 1c05d6d6..11e76d0c 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -83,10 +83,12 @@ public var Vision.styles: List public val Vision.styleSheet: StyleSheet get() = StyleSheet(this) /** - * Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment. + * Add style name to the list of styles to be resolved later. + * The style with given name does not necessary exist at the moment. */ -public fun Vision.useStyle(name: String) { - styles = (properties.own?.get(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name +public fun Vision.useStyle(name: String, notify: Boolean = true) { + val newStyle = properties.own?.get(Vision.STYLE_KEY)?.value?.list?.plus(name.asValue()) ?: listOf(name.asValue()) + properties.setValue(Vision.STYLE_KEY, newStyle.asValue(), notify) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 29c38ebd..cfd522b3 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -119,7 +119,7 @@ private fun CoroutineScope.collectChange( public fun Vision.flowChanges( collectionDuration: Duration, ): Flow = flow { - val manager = manager?: error("Orphan vision could not collect changes") + val manager = manager ?: error("Orphan vision could not collect changes") var collector = VisionChangeBuilder(manager) coroutineScope { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 1f751d55..c15c6c55 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -61,23 +61,24 @@ public interface MutableVisionProperties : VisionProperties { includeStyles, ) - public fun setProperty( name: Name, node: Meta?, + notify: Boolean = true, ) public fun setValue( name: Name, value: Value?, + notify: Boolean = true, ) } -public fun MutableVisionProperties.remove(name: Name){ +public fun MutableVisionProperties.remove(name: Name) { setProperty(name, null) } -public fun MutableVisionProperties.remove(name: String){ +public fun MutableVisionProperties.remove(name: String) { remove(name.parseAsName()) } @@ -180,7 +181,7 @@ public abstract class AbstractVisionProperties( return descriptor?.defaultValue } - override fun setProperty(name: Name, node: Meta?) { + override fun setProperty(name: Name, node: Meta?, notify: Boolean) { //TODO check old value? if (name.isEmpty()) { properties = node?.asMutableMeta() @@ -189,25 +190,42 @@ public abstract class AbstractVisionProperties( } else { getOrCreateProperties().setMeta(name, node) } - invalidate(name) + if (notify) { + invalidate(name) + } } - override fun setValue(name: Name, value: Value?) { + override fun setValue(name: Name, value: Value?, notify: Boolean) { //TODO check old value? if (value == null) { properties?.getMeta(name)?.value = null } else { getOrCreateProperties().setValue(name, value) } - invalidate(name) + if (notify) { + invalidate(name) + } } @Transient - private val _changes = MutableSharedFlow() - override val changes: SharedFlow get() = _changes + protected val changesInternal = MutableSharedFlow() + override val changes: SharedFlow get() = changesInternal - @OptIn(DelicateCoroutinesApi::class) override fun invalidate(propertyName: Name) { + //send update signal + @OptIn(DelicateCoroutinesApi::class) + (vision.manager?.context ?: GlobalScope).launch { + changesInternal.emit(propertyName) + } + + //notify children if there are any + if (vision is VisionGroup) { + vision.children.values.forEach { + it.properties.invalidate(propertyName) + } + } + + // update styles if (propertyName == Vision.STYLE_KEY) { vision.styles.asSequence() .mapNotNull { vision.getStyle(it) } @@ -217,9 +235,6 @@ public abstract class AbstractVisionProperties( invalidate(it.key.asName()) } } - (vision.manager?.context ?: GlobalScope).launch { - _changes.emit(propertyName) - } } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt index afdd686f..df0b9391 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt @@ -86,7 +86,9 @@ public abstract class VisionTagConsumer( ): T = div { id = resolveId(name) classes = setOf(OUTPUT_CLASS) - vision.setAsRoot(manager) + if (vision.parent == null) { + vision.setAsRoot(manager) + } attributes[OUTPUT_NAME_ATTRIBUTE] = name.toString() if (!outputMeta.isEmpty()) { //Hard-code output configuration diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt index b7cec960..4d00f15b 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt @@ -37,7 +37,7 @@ public fun Vision.useProperty( includeStyles: Boolean? = null, scope: CoroutineScope? = manager?.context, callBack: (Meta) -> Unit, -): Job = useProperty(propertyName.parseAsName(),inherit, includeStyles, scope, callBack) +): Job = useProperty(propertyName.parseAsName(), inherit, includeStyles, scope, callBack) public fun V.useProperty( property: KProperty1, diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 64f0d0b2..90c72b9b 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -1,9 +1,7 @@ package space.kscience.visionforge.meta -import kotlinx.coroutines.cancel -import kotlinx.coroutines.delay +import kotlinx.coroutines.* import kotlinx.coroutines.flow.collectIndexed -import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.fetch @@ -20,6 +18,7 @@ private class TestScheme : Scheme() { companion object : SchemeSpec(::TestScheme) } +@OptIn(ExperimentalCoroutinesApi::class) internal class VisionPropertyTest { private val manager = Global.fetch(VisionManager) @@ -68,56 +67,63 @@ internal class VisionPropertyTest { val child = group.children["child"]!! - var value: Value? = null + val deferred: CompletableDeferred = CompletableDeferred() var callCounter = 0 - child.useProperty("test", inherit = true) { + val subscription = child.useProperty("test", inherit = true) { + deferred.complete(it.value) callCounter++ - value = it.value } - assertEquals(22, value?.int) + assertEquals(22, deferred.await()?.int) assertEquals(1, callCounter) child.properties.remove("test") - //Need this to avoid the race - delay(20) - assertEquals(11, child.properties.getProperty("test", inherit = true).int) - assertEquals(11, value?.int) - assertEquals(2, callCounter) +// assertEquals(11, deferred.await()?.int) +// assertEquals(2, callCounter) + subscription.cancel() } @Test fun testChildrenPropertyFlow() = runTest(dispatchTimeoutMs = 200) { val group = Global.fetch(VisionManager).group { + properties { "test" put 11 } + group("child") { properties { "test" put 22 } } + } val child = group.children["child"]!! launch { child.flowPropertyValue("test", inherit = true).collectIndexed { index, value -> - if (index == 0) { - assertEquals(22, value?.int) - } else if (index == 1) { - assertEquals(11, value?.int) - cancel() + when (index) { + 0 -> assertEquals(22, value?.int) + 1 -> assertEquals(11, value?.int) + 2 -> { + assertEquals(33, value?.int) + cancel() + } } } } + //wait for subscription to be created - delay(10) + delay(5) child.properties.remove("test") + + delay(50) + group.properties["test"] = 33 } } \ No newline at end of file diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt index d39f284c..8a0abcdb 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt @@ -45,7 +45,7 @@ public class FX3DPlugin : AbstractPlugin() { } public fun buildNode(obj: Solid): Node { - val binding = VisualObjectFXBinding(this, obj) + val binding = VisionFXBinding(this, obj) return when (obj) { is SolidReference -> referenceFactory(obj, binding) is SolidGroup -> { @@ -150,7 +150,7 @@ public interface FX3DFactory { public val type: KClass - public operator fun invoke(obj: T, binding: VisualObjectFXBinding): Node + public operator fun invoke(obj: T, binding: VisionFXBinding): Node public companion object { public const val TYPE: String = "fx3DFactory" diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXCompositeFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXCompositeFactory.kt index 588f15cf..2e07527a 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXCompositeFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXCompositeFactory.kt @@ -42,7 +42,7 @@ public class FXCompositeFactory(public val plugin: FX3DPlugin) : FX3DFactory get() = Composite::class - override fun invoke(obj: Composite, binding: VisualObjectFXBinding): Node { + override fun invoke(obj: Composite, binding: VisionFXBinding): Node { val first = plugin.buildNode(obj.first) as? MeshView ?: error("Can't build node") val second = plugin.buildNode(obj.second) as? MeshView ?: error("Can't build node") val firstCSG = first.toCSG() diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXConvexFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXConvexFactory.kt index 7bc44207..ddb342b0 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXConvexFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXConvexFactory.kt @@ -10,7 +10,7 @@ import kotlin.reflect.KClass public object FXConvexFactory : FX3DFactory { override val type: KClass get() = Convex::class - override fun invoke(obj: Convex, binding: VisualObjectFXBinding): Node { + override fun invoke(obj: Convex, binding: VisionFXBinding): Node { val hull = HullUtil.hull( obj.points.map { Vector3d.xyz(it.x.toDouble(), it.y.toDouble(), it.z.toDouble()) }, PropertyStorage() diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt index 1c3ecb60..a75771cb 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt @@ -14,15 +14,17 @@ import kotlin.reflect.KClass public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory { override val type: KClass get() = SolidReference::class - override fun invoke(obj: SolidReference, binding: VisualObjectFXBinding): Node { + override fun invoke(obj: SolidReference, binding: VisionFXBinding): Node { val prototype = obj.prototype val node = plugin.buildNode(prototype) - obj.onPropertyChange { name-> + obj.onPropertyChange { name -> if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { - val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'") + val childName = name.firstOrNull()?.index?.let(Name::parse) + ?: error("Wrong syntax for reference child property: '$name'") val propertyName = name.cutFirst() - val referenceChild = obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found") + val referenceChild = + obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found") val child = node.findChild(childName) ?: error("Object child with name '$childName' not found") child.updateProperty(referenceChild, propertyName) } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXShapeFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXShapeFactory.kt index 116075ce..d4d58db1 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXShapeFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXShapeFactory.kt @@ -11,7 +11,7 @@ import kotlin.reflect.KClass public object FXShapeFactory : FX3DFactory { override val type: KClass get() = GeometrySolid::class - override fun invoke(obj: GeometrySolid, binding: VisualObjectFXBinding): MeshView { + override fun invoke(obj: GeometrySolid, binding: VisionFXBinding): MeshView { val mesh = FXGeometryBuilder().apply { obj.toGeometry(this) }.build() return MeshView(mesh) } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisionFXBinding.kt similarity index 96% rename from visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt rename to visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisionFXBinding.kt index 2eb2255c..cc4f3637 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisionFXBinding.kt @@ -12,7 +12,7 @@ import tornadofx.* /** * A caching binding collection for [Vision] properties */ -public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vision) { +public class VisionFXBinding(public val fx: FX3DPlugin, public val obj: Vision) { private val bindings = HashMap>() init { diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt index 976db192..34ab7d68 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt @@ -30,7 +30,7 @@ public class GdmlLoaderOptions { styleCache.getOrPut(Name.parse(name)) { Meta(builder) } - useStyle(name) + useStyle(name, false) } public fun Solid.transparent() { diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index f3527148..2e209c5c 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -352,7 +352,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { val rootStyle by final.style("gdml") { Solid.ROTATION_ORDER_KEY put RotationOrder.ZXY } - final.useStyle(rootStyle) + final.useStyle(rootStyle, false) final.prototypes { proto.items.forEach { (token, item) -> diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 76eb56aa..1c123632 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -1,6 +1,9 @@ package space.kscience.visionforge.solid +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient @@ -65,6 +68,25 @@ public class SolidReference( override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? { return properties?.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) } + + override fun invalidate(propertyName: Name) { + //send update signal + @OptIn(DelicateCoroutinesApi::class) + (manager?.context ?: GlobalScope).launch { + changesInternal.emit(propertyName) + } + + // update styles + if (propertyName == Vision.STYLE_KEY) { + styles.asSequence() + .mapNotNull { getStyle(it) } + .flatMap { it.items.asSequence() } + .distinctBy { it.key } + .forEach { + invalidate(it.key.asName()) + } + } + } } } @@ -117,11 +139,11 @@ internal class SolidReferenceChild( includeStyles: Boolean?, ): Value? = own.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) - override fun setProperty(name: Name, node: Meta?) { + override fun setProperty(name: Name, node: Meta?, notify: Boolean) { own.setMeta(name, node) } - override fun setValue(name: Name, value: Value?) { + override fun setValue(name: Name, value: Value?, notify: Boolean) { own.setValue(name, value) } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt similarity index 92% rename from visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt rename to visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index 5e26284e..6c9fc288 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.solid import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.string @@ -10,8 +11,9 @@ import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals +@OptIn(ExperimentalCoroutinesApi::class) @Suppress("UNUSED_VARIABLE") -class PropertyTest { +class SolidPropertyTest { @Test fun testColor() { val box = Box(10.0f, 10.0f, 10.0f) @@ -23,7 +25,6 @@ class PropertyTest { assertEquals("pink", box.color.string) } - @OptIn(ExperimentalCoroutinesApi::class) @Test fun testColorUpdate() = runTest(dispatchTimeoutMs = 200) { val box = Box(10.0f, 10.0f, 10.0f) @@ -31,11 +32,12 @@ class PropertyTest { val c = CompletableDeferred() - val subscription = box.onPropertyChange(this) { - if (it == SolidMaterial.MATERIAL_COLOR_KEY) { + val subscription = box.onPropertyChange(this) { key -> + if (key == SolidMaterial.MATERIAL_COLOR_KEY) { c.complete(box.color.string) } } + delay(5) box.material { color.set("pink") diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index 46df4405..b122f9c3 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -27,7 +27,7 @@ public object ThreeLabelFactory : ThreeFactory { return Mesh(textGeo, ThreeMaterials.DEFAULT).apply { updateMaterial(obj) updatePosition(obj) - obj.onPropertyChange { _ -> + obj.onPropertyChange { //TODO three.logger.warn { "Label parameter change not implemented" } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index ea39bbea..a35ca12d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -43,7 +43,7 @@ public abstract class ThreeMeshFactory( } //add listener to object properties - obj.onPropertyChange { name -> + obj.onPropertyChange { name-> when { name.startsWith(Solid.GEOMETRY_KEY) -> { val oldGeometry = mesh.geometry diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 7c1358d7..c715efdb 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -11,6 +11,7 @@ import space.kscience.dataforge.meta.update import space.kscience.dataforge.names.* import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision +import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.visible @@ -68,7 +69,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { updatePosition(obj) //obj.onChildrenChange() - obj.properties.changes.onEach { name -> + obj.onPropertyChange(context) { name -> if ( name.startsWith(Solid.POSITION_KEY) || name.startsWith(Solid.ROTATION_KEY) || @@ -79,7 +80,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { } else if (name == Vision.VISIBLE_KEY) { visible = obj.visible ?: true } - }.launchIn(context) + } obj.children.changes.onEach { childName -> val child = obj.children.getChild(childName) @@ -101,6 +102,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { }.launchIn(context) } } + is Composite -> compositeFactory.build(this, obj) else -> { //find specialized factory for this type if it is present @@ -179,6 +181,7 @@ internal fun Object3D.getOrCreateGroup(name: Name): Object3D { this.add(group) } } + else -> getOrCreateGroup(name.tokens.first().asName()).getOrCreateGroup(name.cutFirst()) } } From 43362f51f5642941c16550043da99f9f0b525458 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 13 Aug 2022 20:47:03 +0300 Subject: [PATCH 017/112] Fix styling for Prototypes --- .../ThreeViewWithControls.kt | 11 +++-- .../space/kscience/visionforge/StyleSheet.kt | 6 +-- .../kscience/visionforge/VisionProperties.kt | 10 +++-- .../visionforge/solid/SolidReference.kt | 41 +++++++++++++++---- 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index babafb2e..883b621d 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -5,7 +5,9 @@ import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.css.* import react.* +import react.dom.b import react.dom.div +import react.dom.p import react.dom.span import ringui.* import space.kscience.dataforge.context.Context @@ -14,14 +16,11 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.length -import space.kscience.visionforge.Vision +import space.kscience.visionforge.* import space.kscience.visionforge.react.* -import space.kscience.visionforge.root -import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.visionManager import styled.css import styled.styledDiv @@ -184,6 +183,10 @@ public val ThreeCanvasWithControls: FC = fc("Three } } } + p { + b { +"Styles: " } + +vision.styles.joinToString(separator = ", ") + } } } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 11e76d0c..9db79e19 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -67,11 +67,7 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) * List of names of styles applied to this object. Order matters. Not inherited. */ public var Vision.styles: List - get() = properties.getValue( - Vision.STYLE_KEY, - inherit = true, - includeStyles = false, - )?.stringList ?: emptyList() + get() = properties.getValue(Vision.STYLE_KEY, inherit = false, includeStyles = false)?.stringList ?: emptyList() set(value) { properties.setValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue()) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index c15c6c55..fd7befdf 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -167,16 +167,18 @@ public abstract class AbstractVisionProperties( inherit: Boolean?, includeStyles: Boolean?, ): Value? { + own?.get(name)?.value?.let { return it } + val descriptor = descriptor?.get(name) - val inheritFlag = inherit ?: descriptor?.inherited ?: false val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - own?.get(name)?.value?.let { return it } if (stylesFlag) { vision.getStyleProperty(name)?.value?.let { return it } } + + val inheritFlag = inherit ?: descriptor?.inherited ?: false if (inheritFlag) { - vision.parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } + vision.parent?.properties?.getValue(name, inheritFlag, stylesFlag)?.let { return it } } return descriptor?.defaultValue } @@ -208,7 +210,7 @@ public abstract class AbstractVisionProperties( } @Transient - protected val changesInternal = MutableSharedFlow() + protected val changesInternal: MutableSharedFlow = MutableSharedFlow() override val changes: SharedFlow get() = changesInternal override fun invalidate(propertyName: Name) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 1c123632..2cf90987 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -9,6 +9,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.names.* import space.kscience.visionforge.* import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties @@ -59,16 +60,41 @@ public class SolidReference( propertiesInternal = value } - override val own: Meta? get() = properties + override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? { + if(name == Vision.STYLE_KEY){ + return buildList { + properties?.getValue(Vision.STYLE_KEY)?.list?.forEach { + add(it) + } + prototype.styles.forEach { + add(it.asValue()) + } + }.distinct().asValue() + } + properties?.getValue(name)?.let { return it } - override fun getProperty(name: Name, inherit: Boolean?, includeStyles: Boolean?): MutableMeta { - return properties?.getMeta(name) ?: prototype.properties.getProperty(name, inherit, includeStyles) - } + val descriptor = descriptor?.get(name) + val inheritFlag = inherit ?: descriptor?.inherited ?: false + val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? { - return properties?.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) + if (stylesFlag) { + getStyleProperty(name)?.value?.let { return it } + } + + if (inheritFlag) { + parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } + } + + prototype.properties.getValue(name, inheritFlag, stylesFlag)?.let { return it } + + if(inheritFlag){ + parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it } + } + + return null } + override fun invalidate(propertyName: Name) { //send update signal @OptIn(DelicateCoroutinesApi::class) @@ -130,9 +156,6 @@ internal class SolidReferenceChild( override val own: MutableMeta by lazy { owner.properties.getProperty(childToken(childName).asName()) } - override fun getProperty(name: Name, inherit: Boolean?, includeStyles: Boolean?): MutableMeta = - own.getMeta(name) ?: prototype.properties.getProperty(name, inherit, includeStyles) - override fun getValue( name: Name, inherit: Boolean?, From eeec89f0e678b9fffb42c3f208484745da8dd5e4 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 Aug 2022 10:47:36 +0300 Subject: [PATCH 018/112] Fix property editor --- build.gradle.kts | 7 +++++- settings.gradle.kts | 1 + .../bootstrap/visionPropertyEditor.kt | 13 +++++----- ui/react/build.gradle.kts | 4 --- .../visionforge/react/MultiSelectChooser.kt | 4 +-- .../visionforge/react/PropertyEditor.kt | 15 +++++++---- .../visionforge/react/RangeValueChooser.kt | 18 +++++++------ .../visionforge/react/valueChooser.kt | 25 ++++++++++--------- .../ThreeViewWithControls.kt | 8 +++--- .../solid/three/ThreeCanvasLabelFactory.kt | 2 +- 10 files changed, 55 insertions(+), 42 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f2c4e6d5..4c76b98f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,4 +37,9 @@ apiValidation { ignoredPackages.add("info.laht.threekt") } -readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md") \ No newline at end of file +readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md") + + +//rootProject.extensions.configure { +// versions.webpackCli.version = "4.10.0" +//} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 4215d150..9bdf544a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -12,6 +12,7 @@ pluginManagement { maven("https://repo.kotlin.link") mavenCentral() gradlePluginPortal() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") } plugins { diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index b82d48fe..5e30f838 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -5,7 +5,7 @@ import react.RBuilder import react.dom.client.createRoot import react.key import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.isEmpty import space.kscience.visionforge.Vision import space.kscience.visionforge.getStyle import space.kscience.visionforge.react.EditorPropertyState @@ -23,17 +23,18 @@ public fun RBuilder.visionPropertyEditor( ) { card("Properties") { - child(PropertyEditor){ - attrs{ + child(PropertyEditor) { + attrs { this.key = key?.toString() this.meta = vision.properties.root() this.updates = vision.properties.changes this.descriptor = descriptor this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") - this.getPropertyState = {name-> - if(vision.properties.own?.get(name)!= null){ + this.getPropertyState = { name -> + val ownMeta = vision.properties.own?.getMeta(name) + if (ownMeta != null && !ownMeta.isEmpty()) { EditorPropertyState.Defined - } else if(vision.properties.root()[name] != null){ + } else if (vision.properties.root().getValue(name) != null) { // TODO differentiate EditorPropertyState.Default() } else { diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index 1a58d333..acbe40cb 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -8,8 +8,4 @@ dependencies{ api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") // implementation(npm("react-select","4.3.0")) implementation(project(":visionforge-threejs")) -} - -rootProject.extensions.configure { - versions.webpackCli.version = "4.10.0" } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt index fb339429..fc635d21 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt @@ -19,13 +19,13 @@ public val MultiSelectChooser: FC = fc("MultiSelectChooser") val onChange: (Event) -> Unit = { event: Event -> val newSelected = (event.target as HTMLSelectElement).selectedOptions.asList() .map { (it as HTMLOptionElement).value.asValue() } - props.meta.value = newSelected.asValue() + props.onValueChange(newSelected.asValue()) } select { attrs { multiple = true - values = (props.meta.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } + values = (props.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } onChangeFunction = onChange } props.descriptor?.allowedValues?.forEach { optionValue -> diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index ca64fd07..f5d28f19 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -73,8 +73,8 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { var expanded: Boolean by useState { props.expanded ?: true } val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) } var property: MutableMeta by useState { props.meta.getOrCreate(props.name) } + var editorPropertyState: EditorPropertyState by useState { props.getPropertyState(props.name) } - val defined = props.getPropertyState(props.name) == EditorPropertyState.Defined val keys = useMemo(descriptor) { buildSet { @@ -91,6 +91,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { fun update() { property = props.meta.getOrCreate(props.name) + editorPropertyState = props.getPropertyState(props.name) } useEffect(props.meta) { @@ -136,7 +137,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { styledSpan { css { +TreeStyles.treeLabel - if (!defined) { + if (editorPropertyState != EditorPropertyState.Defined) { +TreeStyles.treeLabelInactive } } @@ -152,8 +153,12 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { ValueChooser { attrs { this.descriptor = descriptor - this.meta = property - this.state = props.getPropertyState(props.name) + this.state = editorPropertyState + this.value = property.value + this.onValueChange = { + property.value = it + editorPropertyState = props.getPropertyState(props.name) + } } } } @@ -177,7 +182,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } +"\u00D7" attrs { - if (!defined) { + if (editorPropertyState!= EditorPropertyState.Defined) { disabled = true } else { onClickFunction = removeClick diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index ae6386d9..309e4b7f 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -20,22 +20,24 @@ import styled.styledInput @JsExport public val RangeValueChooser: FC = fc("RangeValueChooser") { props -> - var innerValue by useState(props.meta.double) - var rangeDisabled: Boolean by useState(props.meta.value == null) + var innerValue by useState(props.value?.double) + var rangeDisabled: Boolean by useState(props.state != EditorPropertyState.Defined) val handleDisable: (Event) -> Unit = { val checkBoxValue = (it.target as HTMLInputElement).checked rangeDisabled = !checkBoxValue - props.meta.value = if (!checkBoxValue) { - null - } else { - innerValue?.asValue() - } + props.onValueChange( + if (!checkBoxValue) { + null + } else { + innerValue?.asValue() + } + ) } val handleChange: (Event) -> Unit = { val newValue = (it.target as HTMLInputElement).value - props.meta.value = newValue.toDoubleOrNull()?.asValue() + props.onValueChange(newValue.toDoubleOrNull()?.asValue()) innerValue = newValue.toDoubleOrNull() } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index 75cd3a0c..7ba72e1c 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -27,17 +27,18 @@ import styled.styledSelect public external interface ValueChooserProps : Props { public var descriptor: MetaDescriptor? - public var meta: MutableMeta public var state: EditorPropertyState + public var value: Value? + public var onValueChange: (Value?) -> Unit } @JsExport public val StringValueChooser: FC = fc("StringValueChooser") { props -> - var value by useState(props.meta.string ?: "") + var value by useState(props.value?.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { value = (event.target as HTMLInputElement).value - props.meta.value = value.asValue() + props.onValueChange(value.asValue()) } } val handleChange: (Event) -> Unit = { @@ -59,7 +60,7 @@ public val StringValueChooser: FC = fc("StringValueChooser") public val BooleanValueChooser: FC = fc("BooleanValueChooser") { props -> val handleChange: (Event) -> Unit = { val newValue = (it.target as HTMLInputElement).checked - props.meta.value = newValue.asValue() + props.onValueChange(newValue.asValue()) } styledInput(type = InputType.checkBox) { css { @@ -67,7 +68,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" } attrs { //this.attributes["indeterminate"] = (props.item == null).toString() - checked = props.meta.boolean ?: false + checked = props.value?.boolean ?: false onChangeFunction = handleChange } } @@ -75,7 +76,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" @JsExport public val NumberValueChooser: FC = fc("NumberValueChooser") { props -> - var innerValue by useState(props.meta.string ?: "") + var innerValue by useState(props.value?.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { innerValue = (event.target as HTMLInputElement).value @@ -83,7 +84,7 @@ public val NumberValueChooser: FC = fc("NumberValueChooser") if (number == null) { console.error("The input value $innerValue is not a number") } else { - props.meta.value = number.asValue() + props.onValueChange(number.asValue()) } } } @@ -113,10 +114,10 @@ public val NumberValueChooser: FC = fc("NumberValueChooser") @JsExport public val ComboValueChooser: FC = fc("ComboValueChooser") { props -> - var selected by useState(props.meta.string ?: "") + var selected by useState(props.value?.string ?: "") val handleChange: (Event) -> Unit = { selected = (it.target as HTMLSelectElement).value - props.meta.value = selected.asValue() + props.onValueChange(selected.asValue()) } styledSelect { css { @@ -128,7 +129,7 @@ public val ComboValueChooser: FC = fc("ComboValueChooser") { } } attrs { - this.value = props.meta.string ?: "" + this.value = props.value?.string ?: "" multiple = false onChangeFunction = handleChange } @@ -138,7 +139,7 @@ public val ComboValueChooser: FC = fc("ComboValueChooser") { @JsExport public val ColorValueChooser: FC = fc("ColorValueChooser") { props -> val handleChange: (Event) -> Unit = { - props.meta.value = (it.target as HTMLInputElement).value.asValue() + props.onValueChange((it.target as HTMLInputElement).value.asValue()) } styledInput(type = InputType.color) { css { @@ -146,7 +147,7 @@ public val ColorValueChooser: FC = fc("ColorValueChooser") { margin(0.px) } attrs { - this.value = props.meta.value?.let { value -> + this.value = props.value?.let { value -> if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) else value.string } ?: "#000000" diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index 883b621d..c1344569 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -183,9 +183,11 @@ public val ThreeCanvasWithControls: FC = fc("Three } } } - p { - b { +"Styles: " } - +vision.styles.joinToString(separator = ", ") + vision.styles.takeIf { it.isNotEmpty() }?.let { styles -> + p { + b { +"Styles: " } + +styles.joinToString(separator = ", ") + } } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index d33c7e79..8b4e823b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -26,7 +26,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory { val canvas = document.createElement("canvas") as HTMLCanvasElement val context = canvas.getContext("2d") as CanvasRenderingContext2D context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).value ?: "black" + context.fillStyle = obj.properties.getValue(SolidMaterial.MATERIAL_COLOR_KEY, false, true)?.value ?: "black" context.textBaseline = CanvasTextBaseline.MIDDLE val metrics = context.measureText(obj.text) //canvas.width = metrics.width.toInt() From 34fbb23c60bd82c70ae2070b1f9c6506703f6b11 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 Aug 2022 12:52:18 +0300 Subject: [PATCH 019/112] Cleanup vision root rules --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 9 +++++---- .../npm/root/serialization/rootToSolid.kt | 7 ++++--- .../visionforge/gdml/demo/GDMLAppComponent.kt | 12 ++++------- .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 4 +++- .../src/main/kotlin/JsPlaygroundApp.kt | 5 +++-- .../src/main/kotlin/gravityDemo.kt | 7 +++---- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 12 +++++------ .../src/jvmMain/kotlin/formServer.kt | 2 +- .../src/jvmMain/kotlin/rootParser.kt | 4 ++-- demo/sat-demo/build.gradle.kts | 2 +- .../main/kotlin/ru/mipt/npm/sat/geometry.kt | 8 ++++---- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 7 ++++++- .../kscience/visionforge/solid/demo/demo.kt | 9 ++++----- gradle.properties | 2 +- .../ThreeViewWithControls.kt | 9 ++++++--- .../ThreeWithControlsPlugin.kt | 2 +- .../space/kscience/visionforge/VisionGroup.kt | 9 +++++---- .../kscience/visionforge/VisionClient.kt | 1 + .../kscience/visionforge/gdml/gdmlLoader.kt | 2 +- .../kscience/visionforge/solid/Composite.kt | 4 ++-- .../kscience/visionforge/solid/SolidGroup.kt | 15 +++++++------- .../visionforge/solid/SolidReference.kt | 20 ++++++++++++------- .../kscience/visionforge/solid/Solids.kt | 20 +++++++++++++++++-- .../visionforge/solid/CompositeTest.kt | 2 +- .../kscience/visionforge/solid/ConvexTest.kt | 2 +- .../kscience/visionforge/solid/GroupTest.kt | 2 +- .../visionforge/solid/SerializationTest.kt | 4 ++-- .../visionforge/solid/SolidPluginTest.kt | 2 +- .../visionforge/solid/SolidPropertyTest.kt | 12 +++++------ .../visionforge/solid/SolidReferenceTest.kt | 2 +- .../visionforge/solid/VisionUpdateTest.kt | 6 +++--- 31 files changed, 118 insertions(+), 86 deletions(-) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index b7b79b51..af185db3 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -6,6 +6,7 @@ import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.isEmpty import space.kscience.visionforge.set import space.kscience.visionforge.solid.* @@ -262,7 +263,7 @@ private fun SolidGroup.addShape( val fShape by shape.dObject(::DGeoShape) val fScale by shape.dObject(::DGeoScale) fShape?.let { scaledShape -> - group(name?.let { Name.parse(it) }) { + solidGroup(name?.let { Name.parse(it) }) { scale = Point3D(fScale?.x ?: 1.0, fScale?.y ?: 1.0, fScale?.z ?: 1.0) addShape(scaledShape, context) apply(block) @@ -294,7 +295,7 @@ private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) { } private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? { - val group = SolidGroup { + val group = SolidGroup().apply { //set current layer layer = context.currentLayer val nodes = volume.fNodes @@ -372,9 +373,9 @@ private fun SolidGroup.addRootVolume( } } -public fun DGeoManager.toSolid(): SolidGroup = SolidGroup { +public fun MutableVisionContainer.rootGeo(dGeoManager: DGeoManager): SolidGroup = solidGroup { val context = RootToSolidContext(this) - fNodes.forEach { node -> + dGeoManager.fNodes.forEach { node -> addRootNode(node, context) } } \ No newline at end of file diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt index 4483afcb..50a4002a 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt @@ -3,6 +3,7 @@ package ru.mipt.npm.root.serialization import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.solid.* import kotlin.math.PI import kotlin.math.atan2 @@ -132,7 +133,7 @@ private fun buildGroup(volume: TGeoVolume): SolidGroup { return if (volume is TGeoVolumeAssemblyRef) { buildGroup(volume.value) } else { - SolidGroup { + SolidGroup().apply { volume.fShape?.let { addShape(it) } volume.fNodes?.let { it.arr.forEach { obj -> @@ -180,8 +181,8 @@ private fun SolidGroup.volume(volume: TGeoVolume, name: String? = null, cache: B // } -public fun TGeoManager.toSolid(): SolidGroup = SolidGroup { - fNodes.arr.forEach { +public fun MutableVisionContainer.rootGeo(tGeoManager: TGeoManager): SolidGroup = solidGroup { + tGeoManager.fNodes.arr.forEach { node(it) } } \ No newline at end of file diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt index 8f605ccd..4301966a 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt @@ -10,10 +10,7 @@ import org.w3c.files.get import react.Props import react.dom.h2 import react.fc -import react.useMemo import react.useState -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch import space.kscience.dataforge.names.Name import space.kscience.gdml.Gdml import space.kscience.gdml.decodeFromString @@ -31,14 +28,13 @@ import styled.css import styled.styledDiv external interface GDMLAppProps : Props { - var context: Context + var solids: Solids var vision: Solid? var selected: Name? } @JsExport val GDMLApp = fc("GDMLApp") { props -> - val visionManager = useMemo(props.context) { props.context.fetch(Solids).visionManager } var deferredVision: Deferred by useState { CompletableDeferred(props.vision) } @@ -53,7 +49,7 @@ val GDMLApp = fc("GDMLApp") { props -> name.endsWith(".gdml") || name.endsWith(".xml") -> { val gdml = Gdml.decodeFromString(data) gdml.toVision().apply { - setAsRoot(visionManager) + setAsRoot(props.solids.visionManager) console.info("Marking layers for file $name") markLayers() ambientLight { @@ -61,7 +57,7 @@ val GDMLApp = fc("GDMLApp") { props -> } } } - name.endsWith(".json") -> visionManager.decodeFromString(data) + name.endsWith(".json") -> props.solids.visionManager.decodeFromString(data) else -> { window.alert("File extension is not recognized: $name") error("File extension is not recognized: $name") @@ -82,7 +78,7 @@ val GDMLApp = fc("GDMLApp") { props -> } child(ThreeCanvasWithControls) { attrs { - this.context = props.context + this.solids = props.solids this.builderOfSolid = deferredVision this.selected = props.selected tab("Load") { diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index d4a80876..ab2b35e0 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -4,11 +4,13 @@ import kotlinx.browser.document import kotlinx.css.* import react.dom.client.createRoot import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.fetch import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Application import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.react.render +import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.three.ThreePlugin @@ -52,7 +54,7 @@ private class GDMLDemoApp : Application { } //println(context.plugins.fetch(VisionManager).encodeToString(vision)) attrs { - this.context = context + this.solids = context.fetch(Solids) this.vision = vision } } diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index c31b48e0..1ee7e013 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -4,6 +4,7 @@ import react.dom.client.createRoot import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.fetch import space.kscience.plotly.models.Trace import space.kscience.plotly.scatter import space.kscience.visionforge.Application @@ -51,7 +52,7 @@ private class JsPlaygroundApp : Application { Tab("gravity") { GravityDemo { attrs { - this.context = playgroundContext + this.solids = playgroundContext.fetch(Solids) } } } @@ -72,7 +73,7 @@ private class JsPlaygroundApp : Application { child(ThreeCanvasWithControls) { val random = Random(112233) attrs { - context = playgroundContext + solids = playgroundContext.fetch(Solids) solid { ambientLight { color.set(Colors.white) diff --git a/demo/js-playground/src/main/kotlin/gravityDemo.kt b/demo/js-playground/src/main/kotlin/gravityDemo.kt index 3bdd574c..c04baf98 100644 --- a/demo/js-playground/src/main/kotlin/gravityDemo.kt +++ b/demo/js-playground/src/main/kotlin/gravityDemo.kt @@ -4,7 +4,6 @@ import kotlinx.coroutines.launch import kotlinx.css.* import react.Props import react.fc -import space.kscience.dataforge.context.Context import space.kscience.plotly.layout import space.kscience.plotly.models.Trace import space.kscience.visionforge.Colors @@ -18,7 +17,7 @@ import styled.styledDiv import kotlin.math.sqrt external interface DemoProps : Props { - var context: Context + var solids: Solids } val GravityDemo = fc { props -> @@ -40,7 +39,7 @@ val GravityDemo = fc { props -> } child(ThreeCanvasWithControls) { attrs { - context = props.context + solids = props.solids solid { pointLight(200, 200, 200, name = "light"){ color.set(Colors.white) @@ -52,7 +51,7 @@ val GravityDemo = fc { props -> color.set("red") val h = 100.0 y = h - context.launch { + solids.context.launch { val g = 10.0 val dt = 0.1 var time = 0.0 diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index aeb0abd3..cf8caf80 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -15,7 +15,7 @@ class Model(val manager: VisionManager) { private val events = HashSet() private fun MutableVisionContainer.pixel(pixel: SC1) { - val group = group(pixel.name) { + val group = solidGroup(pixel.name) { position = Point3D(pixel.center.x, pixel.center.y, pixel.center.z) box(pixel.xSize, pixel.ySize, pixel.zSize) label(pixel.name) { @@ -27,7 +27,7 @@ class Model(val manager: VisionManager) { } private fun SolidGroup.detector(detector: SC16) { - group(detector.name) { + solidGroup(detector.name) { detector.pixels.forEach { pixel(it) } @@ -42,24 +42,24 @@ class Model(val manager: VisionManager) { color.set("darkgreen") } rotationX = PI / 2 - group("bottom") { + solidGroup("bottom") { Monitor.detectors.filter { it.center.z == LOWER_LAYER_Z }.forEach { detector(it) } } - group("middle") { + solidGroup("middle") { Monitor.detectors.filter { it.center.z == CENTRAL_LAYER_Z }.forEach { detector(it) } } - group("top") { + solidGroup("top") { Monitor.detectors.filter { it.center.z == UPPER_LAYER_Z }.forEach { detector(it) } } - tracks = group("tracks") + tracks = solidGroup("tracks") } private fun highlight(pixel: String) { diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index accd1a16..7397b6b6 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -49,7 +49,7 @@ fun main() { } vision("form") { form } - form.onPropertyChange { _, _ -> + form.onPropertyChange { println(this) } } diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/rootParser.kt index f88793ee..1a4330f4 100644 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ b/demo/playground/src/jvmMain/kotlin/rootParser.kt @@ -1,8 +1,8 @@ package space.kscience.visionforge.examples import ru.mipt.npm.root.DGeoManager +import ru.mipt.npm.root.rootGeo import ru.mipt.npm.root.serialization.TGeoManager -import ru.mipt.npm.root.toSolid import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.isLeaf @@ -34,7 +34,7 @@ fun main() { println(it) } - val solid = geo.toSolid() + val solid = Solids.rootGeo(geo) Paths.get("BM@N.vf.json").writeText(Solids.encodeToString(solid)) //println(Solids.encodeToString(solid)) diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index e12b730f..870f3388 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -15,7 +15,7 @@ group = "ru.mipt.npm" dependencies{ implementation(project(":visionforge-threejs:visionforge-threejs-server")) - implementation("ch.qos.logback:logback-classic:1.2.3") + implementation("ch.qos.logback:logback-classic:1.2.11") } application { diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt index 631d70f8..052fb6e0 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt @@ -6,7 +6,7 @@ import space.kscience.visionforge.style import space.kscience.visionforge.useStyle import kotlin.math.PI -internal fun visionOfSatellite( +internal fun Solids.visionOfSatellite( layers: Int = 10, layerHeight: Number = 10, xSegments: Int = 3, @@ -14,7 +14,7 @@ internal fun visionOfSatellite( xSegmentSize: Number = 30, ySegmentSize: Number = xSegmentSize, fiberDiameter: Number = 1.0, -): SolidGroup = SolidGroup { +): SolidGroup = solidGroup { color.set("darkgreen") val transparent by style { this[SolidMaterial.MATERIAL_OPACITY_KEY] = 0.3 @@ -31,7 +31,7 @@ internal fun visionOfSatellite( val totalXSize = xSegments * xSegmentSize.toDouble() val totalYSize = ySegments * ySegmentSize.toDouble() for (layer in 1..layers) { - group("layer[$layer]") { + solidGroup("layer[$layer]") { for (i in 1..xSegments) { for (j in 1..ySegments) { box(xSegmentSize, ySegmentSize, layerHeight, name = "segment[$i,$j]") { @@ -42,7 +42,7 @@ internal fun visionOfSatellite( } } } - group("fibers") { + solidGroup("fibers") { for (i in 1..xSegments) { cylinder(fiberDiameter, totalYSize) { useStyle(red) diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index d601a74b..41ac4d2f 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -5,6 +5,8 @@ import kotlinx.coroutines.* import kotlinx.html.div import kotlinx.html.h1 import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.html.Page import space.kscience.visionforge.html.plus @@ -17,13 +19,16 @@ import space.kscience.visionforge.visionManager import kotlin.random.Random +@OptIn(DFExperimental::class) fun main() { val satContext = Context("sat") { plugin(Solids) } + val solids = satContext.fetch(Solids) + //Create a geometry - val sat = visionOfSatellite(ySegments = 3) + val sat = solids.visionOfSatellite(ySegments = 3) val server = satContext.visionManager.serve { page(header = Page.threeJsHeader + Page.styleSheetHeader("css/styles.css")) { diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index 88c6d154..0398c6bf 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -5,7 +5,6 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.invoke import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors -import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.visible @@ -19,11 +18,11 @@ fun VisionLayout.demo(name: String, title: String = name, block: SolidGro val meta = Meta { "title" put title } - val vision = SolidGroup(block).apply { + val vision = solids.solidGroup { + block() ambientLight{ color.set(Colors.white) } - setAsRoot(solids.visionManager) } render(Name.parse(name), vision, meta) } @@ -69,7 +68,7 @@ fun VisionLayout.showcase() { } demo("dynamic", "Dynamic properties") { - val group = group { + val group = solidGroup { box(100, 100, 100) { z = 110.0 opacity = 0.5 @@ -101,7 +100,7 @@ fun VisionLayout.showcase() { demo("rotation", "Rotations") { box(100, 100, 100) - group { + solidGroup { x = 200 rotationY = PI / 4 box(100, 100, 100) { diff --git a/gradle.properties b/gradle.properties index aeb2ca21..668f0f5d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.jupyter.add.scanner=false -#kotlin.incremental.js.ir=true +kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index c1344569..3b7133e9 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -10,7 +10,6 @@ import react.dom.div import react.dom.p import react.dom.span import ringui.* -import space.kscience.dataforge.context.Context import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken @@ -20,21 +19,25 @@ import space.kscience.visionforge.* import space.kscience.visionforge.react.* import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidGroup +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.solidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions import styled.css import styled.styledDiv public external interface ThreeCanvasWithControlsProps : Props { - public var context: Context + public var solids: Solids public var builderOfSolid: Deferred public var selected: Name? public var options: Canvas3DOptions? public var additionalTabs: Map Unit>? } +private val ThreeCanvasWithControlsProps.context get() = solids.context + public fun ThreeCanvasWithControlsProps.solid(block: SolidGroup.() -> Unit) { builderOfSolid = context.async { - SolidGroup(block) + solids.solidGroup(null, block) } } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt index bf1a2160..191742ca 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt @@ -29,7 +29,7 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { createRoot(element).render { child(ThreeCanvasWithControls) { attrs { - this.context = this@ThreeWithControlsPlugin.context + this.solids = three.solids this.builderOfSolid = context.async { vision as Solid} } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index 613a5dfe..01786453 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -8,6 +8,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus import space.kscience.visionforge.Vision.Companion.STYLE_KEY @@ -95,19 +96,19 @@ public class SimpleVisionGroup : AbstractVisionGroup(), MutableVisionContainer.group( +public inline fun MutableVisionContainer.group( name: Name? = null, builder: SimpleVisionGroup.() -> Unit = {}, -): SimpleVisionGroup = SimpleVisionGroup().apply(builder).also { setChild(name, it) } +): SimpleVisionGroup = SimpleVisionGroup().also { setChild(name, it) }.apply(builder) /** * Define a group with given [name], attach it to this parent and return it. */ @VisionBuilder -public fun MutableVisionContainer.group( +public inline fun MutableVisionContainer.group( name: String, builder: SimpleVisionGroup.() -> Unit = {}, -): SimpleVisionGroup = SimpleVisionGroup().apply(builder).also { setChild(name, it) } +): SimpleVisionGroup = group(name.parseAsName(), builder) //fun VisualObject.findStyle(styleName: Name): Meta? { // if (this is VisualGroup) { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index 41018759..41e3b8e6 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -65,6 +65,7 @@ public class VisionClient : AbstractPlugin() { private fun renderVision(name: String, element: Element, vision: Vision?, outputMeta: Meta) { if (vision != null) { + vision.setAsRoot(visionManager) val renderer = findRendererFor(vision) ?: error("Could not find renderer for ${visionManager.encodeToString(vision)}") renderer.render(element, vision, outputMeta) diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index 2e209c5c..18e2640e 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -29,7 +29,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { */ private val proto = SolidGroup() - private val solids = proto.group(solidsName) { + private val solids = proto.solidGroup(solidsName) { properties["edges.enabled"] = false } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index 1c28025c..7c6ab3ec 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -26,7 +26,7 @@ public inline fun MutableVisionContainer.composite( name: String? = null, @VisionBuilder builder: SolidGroup.() -> Unit, ): Composite { - val group = SolidGroup(builder) + val group = SolidGroup().apply(builder) val children = group.items.values.toList() if (children.size != 2) { error("Composite requires exactly two children, but found ${children.size}") @@ -48,7 +48,7 @@ public fun SolidGroup.smartComposite( name: String? = null, @VisionBuilder builder: SolidGroup.() -> Unit, ): Solid = if (type == CompositeType.GROUP) { - val group = SolidGroup(builder) + val group = SolidGroup().apply(builder) if (name == null && group.properties.own == null) { //append directly to group if no properties are defined group.items.forEach { (_, value) -> diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index f3ca4cf8..a089bf4d 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -5,6 +5,7 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.parseAsName import space.kscience.visionforge.* @@ -30,7 +31,8 @@ public interface PrototypeHolder { */ @Serializable @SerialName("group.solid") -public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, MutableVisionGroup, MutableVisionContainer { +public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, MutableVisionGroup, + MutableVisionContainer { public val items: Map get() = children.keys.mapNotNull { @@ -79,19 +81,18 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable } } -public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block) - @VisionBuilder -public fun MutableVisionContainer.group( +public inline fun MutableVisionContainer.solidGroup( name: Name? = null, builder: SolidGroup.() -> Unit = {}, -): SolidGroup = SolidGroup(builder).also { setChild(name, it) } +): SolidGroup = SolidGroup().also { setChild(name, it) }.apply(builder) +//root first, update later /** * Define a group with given [name], attach it to this parent and return it. */ @VisionBuilder -public fun MutableVisionContainer.group( +public inline fun MutableVisionContainer.solidGroup( name: String, action: SolidGroup.() -> Unit = {}, -): SolidGroup = SolidGroup(action).also { setChild(name, it) } +): SolidGroup = solidGroup(name.parseAsName(), action) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 2cf90987..07398a42 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -71,24 +71,30 @@ public class SolidReference( } }.distinct().asValue() } + //1. resolve own properties properties?.getValue(name)?.let { return it } val descriptor = descriptor?.get(name) val inheritFlag = inherit ?: descriptor?.inherited ?: false val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - if (stylesFlag) { - getStyleProperty(name)?.value?.let { return it } - } + //2. Resolve prototype onw properties + prototype.properties.getValue(name, inheritFlag, stylesFlag)?.let { return it } - if (inheritFlag) { - parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } + if (stylesFlag) { + //3. own styles + own?.getValue(Vision.STYLE_KEY)?.list?.forEach { styleName -> + getStyle(styleName.string)?.getValue(name)?.let { return it } + } + //4. prototype styles + prototype.getStyleProperty(name)?.value?.let { return it } } - prototype.properties.getValue(name, inheritFlag, stylesFlag)?.let { return it } - if(inheritFlag){ + //5. own inheritance parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it } + //6. prototype inheritance + prototype.parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it } } return null diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 722c97f8..43640182 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -10,22 +10,34 @@ import kotlinx.serialization.serializer import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag +import space.kscience.dataforge.context.fetch import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.Name import space.kscience.visionforge.* import space.kscience.visionforge.html.VisionOutput import kotlin.reflect.KClass -public class Solids(meta: Meta) : VisionPlugin(meta) { +public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer { override val tag: PluginTag get() = Companion.tag override val visionSerializersModule: SerializersModule get() = serializersModuleForSolids - public companion object : PluginFactory { + override fun setChild(name: Name?, child: Solid?) { + child?.setAsRoot(visionManager) + } + + public companion object : PluginFactory, MutableVisionContainer { override val tag: PluginTag = PluginTag(name = "vision.solid", group = PluginTag.DATAFORGE_GROUP) override val type: KClass = Solids::class + public val default: Solids by lazy { + Context("@Solids"){ + plugin(Solids) + }.fetch(Solids) + } + override fun build(context: Context, meta: Meta): Solids = Solids(meta) private fun PolymorphicModuleBuilder.solids() { @@ -68,6 +80,10 @@ public class Solids(meta: Meta) : VisionPlugin(meta) { public fun decodeFromString(str: String): Solid = jsonForSolids.decodeFromString(PolymorphicSerializer(Solid::class), str) + + override fun setChild(name: Name?, child: Solid?) { + default.setChild(name, child) + } } } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt index 17dfb925..779a1b27 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt @@ -8,7 +8,7 @@ class CompositeTest { @Test fun testCompositeBuilder(){ lateinit var composite: Composite - SolidGroup { + Solids.solidGroup { composite = composite(CompositeType.INTERSECT) { y = 300 box(100, 100, 100) { diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt index 500bddb2..e78dc12c 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt @@ -11,7 +11,7 @@ class ConvexTest { @Suppress("UNUSED_VARIABLE") @Test fun testConvexBuilder() { - val group = SolidGroup{ + val group = Solids.solidGroup { convex { point(50, 50, -50) point(50, -50, -50) diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt index 013a8d4c..b486f723 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt @@ -9,7 +9,7 @@ import kotlin.test.assertEquals class GroupTest { @Test fun testGroupWithComposite() { - val group = SolidGroup{ + val group = Solids.solidGroup{ union("union") { box(100, 100, 100) { z = 100 diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index 49c90dab..45d1a737 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -41,7 +41,7 @@ class SerializationTest { x = 100 z = -100 } - val group = SolidGroup { + val group = Solids.solidGroup { newRef("cube", cube) refGroup("pg", Name.parse("pg.content")) { sphere(50) { @@ -57,7 +57,7 @@ class SerializationTest { @Test fun lightSerialization(){ - val group = SolidGroup { + val group = Solids.solidGroup { ambientLight { color.set(Colors.white) intensity = 100.0 diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt index d60b9042..ad9a06e9 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt @@ -8,7 +8,7 @@ import kotlin.test.Test import kotlin.test.assertEquals class SolidPluginTest { - val vision = SolidGroup { + val vision = Solids.solidGroup { box(100, 100, 100, name = "aBox") sphere(100, name = "aSphere") { diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index 6c9fc288..2859019b 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -52,7 +52,7 @@ class SolidPropertyTest { var box: Box? = null val group = SolidGroup().apply { properties["test"] = 22 - group { + solidGroup { box = box(100, 100, 100) } } @@ -62,13 +62,13 @@ class SolidPropertyTest { @Test fun testStyleProperty() { var box: Box? = null - val group = SolidGroup { + val group = Solids.solidGroup { styleSheet { update("testStyle") { "test" put 22 } } - group { + solidGroup { box = box(100, 100, 100) { useStyle("testStyle") } @@ -86,7 +86,7 @@ class SolidPropertyTest { SolidMaterial.MATERIAL_COLOR_KEY put "#555555" } } - group { + solidGroup { box = box(100, 100, 100) { useStyle("testStyle") } @@ -98,7 +98,7 @@ class SolidPropertyTest { @Test fun testReferenceStyleProperty() { var box: SolidReference? = null - val group = SolidGroup { + val group = Solids.solidGroup { styleSheet { update("testStyle") { SolidMaterial.MATERIAL_COLOR_KEY put "#555555" @@ -109,7 +109,7 @@ class SolidPropertyTest { styles = listOf("testStyle") } } - group { + solidGroup { box = ref("box".asName()) } } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt index 027f8b03..021a4b73 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt @@ -11,7 +11,7 @@ import kotlin.test.assertEquals @DFExperimental class SolidReferenceTest { - val groupWithReference = SolidGroup { + val groupWithReference = Solids.solidGroup { val theStyle by style { SolidMaterial.MATERIAL_COLOR_KEY put "red" } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 2cf5c861..65fdf373 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -17,11 +17,11 @@ internal class VisionUpdateTest { @Test fun testVisionUpdate(){ - val targetVision = SolidGroup { + val targetVision = Solids.solidGroup { box(200,200,200, name = "origin") } val dif = visionManager.VisionChange{ - group ("top") { + solidGroup ("top") { color.set(123) box(100,100,100) } @@ -37,7 +37,7 @@ internal class VisionUpdateTest { @Test fun testVisionChangeSerialization(){ val change = visionManager.VisionChange{ - group("top") { + solidGroup("top") { color.set(123) box(100,100,100) } From 846e87a44b57d2991ca3ae814082aa6c01c1f414 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 Aug 2022 14:25:44 +0300 Subject: [PATCH 020/112] Fix flaky properties test --- .../mipt/npm/muon/monitor/MMAppComponent.kt | 8 ++++---- .../ru/mipt/npm/muon/monitor/MMDemoApp.kt | 3 ++- .../visionforge/meta/VisionPropertyTest.kt | 20 +++++++------------ 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index 20a33fe2..3ecb7f9f 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -16,7 +16,6 @@ import react.dom.p import react.fc import react.useMemo import react.useState -import space.kscience.dataforge.context.Context import space.kscience.dataforge.meta.invoke import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors @@ -24,6 +23,7 @@ import space.kscience.visionforge.react.flexColumn import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.tab +import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.specifications.Canvas3DOptions @@ -35,7 +35,7 @@ import kotlin.math.PI external interface MMAppProps : Props { var model: Model - var context: Context + var solids: Solids var selected: Name? } @@ -71,7 +71,7 @@ val MMApp = fc("Muon monitor") { props -> } child(ThreeCanvasWithControls) { attrs { - this.context = props.context + this.solids = props.solids this.builderOfSolid = CompletableDeferred(root) this.selected = props.selected this.options = mmOptions @@ -82,7 +82,7 @@ val MMApp = fc("Muon monitor") { props -> +"Next" attrs { onClickFunction = { - context.launch { + solids.context.launch { val event = window.fetch( "http://localhost:8080/event", RequestInit("GET") diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 9c96ad07..4b18291b 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -7,6 +7,7 @@ import space.kscience.dataforge.context.fetch import space.kscience.visionforge.Application import space.kscience.visionforge.VisionManager import space.kscience.visionforge.react.render +import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication @@ -27,7 +28,7 @@ private class MMDemoApp : Application { child(MMApp) { attrs { this.model = model - this.context = context + this.solids = context.fetch(Solids) } } } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 90c72b9b..08497a57 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -1,7 +1,9 @@ package space.kscience.visionforge.meta import kotlinx.coroutines.* -import kotlinx.coroutines.flow.collectIndexed +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.take +import kotlinx.coroutines.flow.toList import kotlinx.coroutines.test.runTest import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.fetch @@ -106,24 +108,16 @@ internal class VisionPropertyTest { val child = group.children["child"]!! launch { - child.flowPropertyValue("test", inherit = true).collectIndexed { index, value -> - when (index) { - 0 -> assertEquals(22, value?.int) - 1 -> assertEquals(11, value?.int) - 2 -> { - assertEquals(33, value?.int) - cancel() - } - } - } + val list = child.flowPropertyValue("test", inherit = true).take(3).map { it?.int }.toList() + assertEquals(22, list.first()) + //assertEquals(11, list[1]) //a race + assertEquals(33, list.last()) } //wait for subscription to be created delay(5) child.properties.remove("test") - - delay(50) group.properties["test"] = 33 } } \ No newline at end of file From ac651c4d502a6d831839a64f694ff02f9adca047 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 Aug 2022 14:41:22 +0300 Subject: [PATCH 021/112] Fix reference property resolution --- .../kotlin/space/kscience/visionforge/solid/SolidReference.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 07398a42..0b1bc43e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -79,7 +79,7 @@ public class SolidReference( val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true //2. Resolve prototype onw properties - prototype.properties.getValue(name, inheritFlag, stylesFlag)?.let { return it } + prototype.properties.own?.getValue(name)?.let { return it } if (stylesFlag) { //3. own styles @@ -97,7 +97,7 @@ public class SolidReference( prototype.parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it } } - return null + return descriptor?.defaultValue } From e2f281debec9d7bafa46438fc02d38767f1c9e65 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 Aug 2022 17:22:10 +0300 Subject: [PATCH 022/112] Optimizations... optimizations --- .../mipt/npm/root/serialization/jsonToRoot.kt | 1 - demo/muon-monitor/build.gradle.kts | 31 ++++--- demo/solid-showcase/build.gradle.kts | 2 +- .../kscience/visionforge/solid/demo/demo.kt | 2 +- gradle.properties | 2 +- .../visionforge/bootstrap/outputConfig.kt | 3 + .../visionforge/react/valueChooser.kt | 3 +- .../kscience/visionforge/VisionChange.kt | 30 +++++-- .../kscience/visionforge/VisionContainer.kt | 23 ++--- .../space/kscience/visionforge/VisionGroup.kt | 2 +- .../kscience/visionforge/VisionManager.kt | 1 + .../space/kscience/visionforge/solid/Solid.kt | 2 +- .../visionforge/solid/SolidReference.kt | 2 +- .../solid/three/ThreeAmbientLightFactory.kt | 6 +- .../solid/three/ThreeCanvasLabelFactory.kt | 12 +-- .../solid/three/ThreeCompositeFactory.kt | 26 +++--- .../visionforge/solid/three/ThreeFactory.kt | 18 ++-- .../solid/three/ThreeLabelFactory.kt | 18 ++-- .../solid/three/ThreeLineFactory.kt | 20 +++-- .../visionforge/solid/three/ThreeMaterials.kt | 16 ++-- .../solid/three/ThreeMeshFactory.kt | 54 ++++++------ .../visionforge/solid/three/ThreePlugin.kt | 86 ++++++++++--------- .../solid/three/ThreePointLightFactory.kt | 20 +++-- .../solid/three/ThreeReferenceFactory.kt | 32 +++---- .../build.gradle.kts | 35 +++++--- 25 files changed, 255 insertions(+), 192 deletions(-) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt index b4a63748..96c6098c 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt @@ -91,7 +91,6 @@ private object RootDecoder { private fun KSerializer.unref(refCache: List): KSerializer = RootUnrefSerializer(this, refCache) - @OptIn(ExperimentalSerializationApi::class) fun unrefSerializersModule( refCache: List, ): SerializersModule = SerializersModule { diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index b2c69a7d..fe3f89cb 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -21,21 +21,13 @@ kotlin { useCommonJs() browser { commonWebpackConfig { - cssSupport.enabled = false + cssSupport { + enabled = false + } } } } - afterEvaluate { - val jsBrowserDistribution by tasks.getting - - tasks.getByName("jvmProcessResources") { - dependsOn(jsBrowserDistribution) - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - from(jsBrowserDistribution) - } - } - sourceSets { commonMain { dependencies { @@ -65,6 +57,23 @@ application { mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt") } +val jsBrowserDistribution by tasks.getting +val jsBrowserDevelopmentExecutableDistribution by tasks.getting + +val devMode = rootProject.findProperty("visionforge.development") as? Boolean + ?: rootProject.version.toString().contains("dev") + +tasks.getByName("jvmProcessResources") { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + if (devMode) { + dependsOn(jsBrowserDevelopmentExecutableDistribution) + from(jsBrowserDevelopmentExecutableDistribution) + } else { + dependsOn(jsBrowserDistribution) + from(jsBrowserDistribution) + } +} + //distributions { // main { // contents { diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index d3e03135..2da1299f 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -40,5 +40,5 @@ kotlin { } application { - mainClassName = "space.kscience.visionforge.solid.demo.FXDemoAppKt" + mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt") } \ No newline at end of file diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index 0398c6bf..ef009b82 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -20,7 +20,7 @@ fun VisionLayout.demo(name: String, title: String = name, block: SolidGro } val vision = solids.solidGroup { block() - ambientLight{ + ambientLight { color.set(Colors.white) } } diff --git a/gradle.properties b/gradle.properties index 668f0f5d..aeb2ca21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.jupyter.add.scanner=false -kotlin.incremental.js.ir=true +#kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt index deb63381..3dfba202 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.bootstrap +import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope import kotlinx.css.BorderStyle import kotlinx.css.Color @@ -47,6 +48,7 @@ public external interface CanvasControlsProps : Props { public var vision: Vision? } + public val CanvasControls: FC = fc("CanvasControls") { props -> flexColumn { flexRow { @@ -68,6 +70,7 @@ public val CanvasControls: FC = fc("CanvasControls") { prop } } } + @OptIn(DelicateCoroutinesApi::class) propertyEditor( scope = props.vision?.manager?.context ?: GlobalScope, properties = props.canvasOptions.meta, diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index 7ba72e1c..04c7d946 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.react +import info.laht.threekt.math.Color import kotlinx.css.margin import kotlinx.css.pct import kotlinx.css.px @@ -149,7 +150,7 @@ public val ColorValueChooser: FC = fc("ColorValueChooser") { attrs { this.value = props.value?.let { value -> if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) - else value.string + else "#" + Color(value.string).getHexString() } ?: "#000000" onChangeFunction = handleChange } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index cfd522b3..1edcdf70 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus import kotlin.jvm.Synchronized @@ -16,18 +17,37 @@ import kotlin.time.Duration * Create a deep copy of given Vision without external connections. */ private fun Vision.deepCopy(manager: VisionManager): Vision { + if(this is NullVision) return NullVision + //Assuming that unrooted visions are already isolated //TODO replace by efficient deep copy val json = manager.encodeToJsonElement(this) return manager.decodeFromJson(json) } +/** + * A vision used only in change propagation and showing that the target should be removed + */ +@Serializable +public object NullVision : Vision { + override var parent: Vision? + get() = null + set(_) { + error("Can't set parent for null vision") + } + + override val properties: MutableVisionProperties get() = error("Can't get properties of `NullVision`") + + override val descriptor: MetaDescriptor? = null + +} + + /** * An update for a [Vision] */ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVisionContainer { - private var reset: Boolean = false private var vision: Vision? = null private val propertyChange = MutableMeta() private val children: HashMap = HashMap() @@ -50,8 +70,7 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi override fun setChild(name: Name?, child: Vision?) { if (name == null) error("Static children are not allowed in VisionChange") getOrPutChild(name).apply { - vision = child - reset = vision == null + vision = child ?: NullVision } } @@ -59,7 +78,6 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi * Isolate collected changes by creating detached copies of given visions */ public fun deepCopy(): VisionChange = VisionChange( - reset, vision?.deepCopy(manager), if (propertyChange.isEmpty()) null else propertyChange.seal(), if (children.isEmpty()) null else children.mapValues { it.value.deepCopy() } @@ -67,14 +85,12 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi } /** - * @param delete flag showing that this vision child should be removed - * @param vision a new value for vision content + * @param vision a new value for vision content. If the Vision is to be removed should be [NullVision] * @param properties updated properties * @param children a map of children changed in ths [VisionChange]. If a child to be removed, set [delete] flag to true. */ @Serializable public data class VisionChange( - public val delete: Boolean = false, public val vision: Vision? = null, public val properties: Meta? = null, public val children: Map? = null, diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index bda9ab42..975e170a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import space.kscience.dataforge.names.* +import space.kscience.visionforge.VisionChildren.Companion.STATIC_TOKEN_BODY import kotlin.jvm.Synchronized @DslMarker @@ -40,6 +41,8 @@ public interface VisionChildren : VisionContainer { } public companion object { + public const val STATIC_TOKEN_BODY: String = "@static" + public fun empty(owner: Vision): VisionChildren = object : VisionChildren { override val group: Vision get() = owner override val keys: Set get() = emptySet() @@ -105,8 +108,8 @@ public operator fun MutableVisionChildren.set(name: String?, vision: Vision?) { /** * Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events. */ -public fun MutableVisionChildren.static(child: Vision): Unit { - set(NameToken("@static", index = child.hashCode().toString()), child) +public fun MutableVisionChildren.static(child: Vision) { + set(NameToken(STATIC_TOKEN_BODY, index = child.hashCode().toString()), child) } public fun VisionChildren.asSequence(): Sequence> = sequence { @@ -185,14 +188,14 @@ internal abstract class VisionChildrenImpl( } override fun clear() { - if (!items.isNullOrEmpty()) { - updateJobs.values.forEach { - it.cancel() - } - updateJobs.clear() - items?.clear() - onChange(Name.EMPTY) - } + items?.forEach { set(it.key, null) } +// if (!items.isNullOrEmpty()) { +// updateJobs.values.forEach { +// it.cancel() +// } +// updateJobs.clear() +// items?.clear() +// } } } // diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index 01786453..8a651ffc 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -35,7 +35,7 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup override fun update(change: VisionChange) { change.children?.forEach { (name, change) -> when { - change.delete -> children.setChild(name, null) + change.vision == NullVision -> children.setChild(name, null) change.vision != null -> children.setChild(name, change.vision) else -> children.getChild(name)?.update(change) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 314b15d5..4e64f63a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -73,6 +73,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont private val defaultSerialModule: SerializersModule = SerializersModule { polymorphic(Vision::class) { default { SimpleVisionGroup.serializer() } + subclass(NullVision.serializer()) subclass(SimpleVisionGroup.serializer()) subclass(VisionOfNumberField.serializer()) subclass(VisionOfTextField.serializer()) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 2283f187..7d0d0b94 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -115,7 +115,7 @@ public interface Solid : Vision { public var Solid.layer: Int get() = properties.getValue(LAYER_KEY, inherit = true)?.int ?: 0 set(value) { - properties.set(LAYER_KEY, value) + properties[LAYER_KEY] = value } // Common properties diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 0b1bc43e..b54e3ab6 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -186,7 +186,7 @@ internal class SolidReferenceChild( override fun update(change: VisionChange) { change.children?.forEach { (name, change) -> when { - change.delete -> error("Deleting children inside ref is not allowed.") + change.vision == NullVision -> error("Deleting children inside ref is not allowed.") change.vision != null -> error("Updating content of the ref is not allowed") else -> children.getChild(name)?.update(change) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt index 9e105bde..5df6cc7a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt @@ -8,10 +8,10 @@ import kotlin.reflect.KClass public object ThreeAmbientLightFactory : ThreeFactory { override val type: KClass get() = AmbientLightSource::class - override fun build(three: ThreePlugin, obj: AmbientLightSource): AmbientLight { + override fun build(three: ThreePlugin, vision: AmbientLightSource, observe: Boolean): AmbientLight { val res = AmbientLight().apply { - color = obj.color.threeColor() ?: Color(0x404040) - intensity = obj.intensity.toDouble() + color = vision.color.threeColor() ?: Color(0x404040) + intensity = vision.intensity.toDouble() } return res diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index 8b4e823b..cc798297 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -22,17 +22,17 @@ import kotlin.reflect.KClass public object ThreeCanvasLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun build(three: ThreePlugin, obj: SolidLabel): Object3D { + override fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { val canvas = document.createElement("canvas") as HTMLCanvasElement val context = canvas.getContext("2d") as CanvasRenderingContext2D - context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.properties.getValue(SolidMaterial.MATERIAL_COLOR_KEY, false, true)?.value ?: "black" + context.font = "Bold ${vision.fontSize}pt ${vision.fontFamily}" + context.fillStyle = vision.properties.getValue(SolidMaterial.MATERIAL_COLOR_KEY, false, true)?.value ?: "black" context.textBaseline = CanvasTextBaseline.MIDDLE - val metrics = context.measureText(obj.text) + val metrics = context.measureText(vision.text) //canvas.width = metrics.width.toInt() - context.fillText(obj.text, (canvas.width - metrics.width) / 2, 0.5 * canvas.height) + context.fillText(vision.text, (canvas.width - metrics.width) / 2, 0.5 * canvas.height) // canvas contents will be used for a texture @@ -50,7 +50,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory { material ) - mesh.updatePosition(obj) + mesh.updatePosition(vision) mesh.userData[DO_NOT_HIGHLIGHT_TAG] = true return mesh diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index de318f95..e4cb84d5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -37,21 +37,25 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory override val type: KClass get() = Composite::class - override fun build(three: ThreePlugin, obj: Composite): Mesh { - val first = three.buildObject3D(obj.first).takeIfMesh() ?: error("First part of composite is not a mesh") - val second = three.buildObject3D(obj.second).takeIfMesh() ?: error("Second part of composite is not a mesh") - return when (obj.compositeType) { + override fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh { + val first = + three.buildObject3D(vision.first, observe).takeIfMesh() ?: error("First part of composite is not a mesh") + val second = + three.buildObject3D(vision.second, observe).takeIfMesh() ?: error("Second part of composite is not a mesh") + return when (vision.compositeType) { CompositeType.GROUP, CompositeType.UNION -> CSG.union(first, second) CompositeType.INTERSECT -> CSG.intersect(first, second) CompositeType.SUBTRACT -> CSG.subtract(first, second) }.apply { - updatePosition(obj) - applyProperties(obj) - obj.onPropertyChange { name -> - when { - //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) - name.startsWith(ThreeMeshFactory.EDGES_KEY) -> applyEdges(obj) - else -> updateProperty(obj, name) + updatePosition(vision) + applyProperties(vision) + if (observe) { + vision.onPropertyChange { name -> + when { + //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) + name.startsWith(ThreeMeshFactory.EDGES_KEY) -> applyEdges(vision) + else -> updateProperty(vision, name) + } } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 8c39aeb3..5c4c6cd5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -22,7 +22,11 @@ public interface ThreeFactory { public val type: KClass - public fun build(three: ThreePlugin, obj: T): Object3D + /** + * Build an [Object3D] from [vision]. + * @param observe if false, does not observe the changes in [vision] after render (useful for statics). + */ + public fun build(three: ThreePlugin, vision: T, observe: Boolean = true): Object3D public companion object { public const val TYPE: String = "threeFactory" @@ -32,10 +36,10 @@ public interface ThreeFactory { /** * Update position, rotation and visibility */ -public fun Object3D.updatePosition(obj: Vision) { - visible = obj.visible ?: true - if (obj is Solid) { - position.set(obj.x, obj.y, obj.z) +public fun Object3D.updatePosition(vision: Vision) { + visible = vision.visible ?: true + if (vision is Solid) { + position.set(vision.x, vision.y, vision.z) // val quaternion = obj.quaternion // @@ -46,9 +50,9 @@ public fun Object3D.updatePosition(obj: Vision) { // setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) // } - setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) + setRotationFromEuler( Euler(vision.rotationX, vision.rotationY, vision.rotationZ, vision.rotationOrder.name)) - scale.set(obj.scaleX, obj.scaleY, obj.scaleZ) + scale.set(vision.scaleX, vision.scaleY, vision.scaleZ) updateMatrix() } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index b122f9c3..c9244ea5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -17,19 +17,21 @@ import kotlin.reflect.KClass public object ThreeLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun build(three: ThreePlugin, obj: SolidLabel): Object3D { - val textGeo = TextBufferGeometry(obj.text, jso { - font = obj.fontFamily + override fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { + val textGeo = TextBufferGeometry(vision.text, jso { + font = vision.fontFamily size = 20 height = 1 curveSegments = 1 }) return Mesh(textGeo, ThreeMaterials.DEFAULT).apply { - updateMaterial(obj) - updatePosition(obj) - obj.onPropertyChange { - //TODO - three.logger.warn { "Label parameter change not implemented" } + createMaterial(vision) + updatePosition(vision) + if(observe) { + vision.onPropertyChange(three.context) { + //TODO + three.logger.warn { "Label parameter change not implemented" } + } } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index fcd92b7c..557a375f 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -16,27 +16,29 @@ import kotlin.reflect.KClass public object ThreeLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun build(three: ThreePlugin, obj: PolyLine): Object3D { + override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { val geometry = BufferGeometry().apply { - setFromPoints(Array((obj.points.size - 1) * 2) { - obj.points[ceil(it / 2.0).toInt()].toVector() + setFromPoints(Array((vision.points.size - 1) * 2) { + vision.points[ceil(it / 2.0).toInt()].toVector() }) } val material = ThreeMaterials.getLineMaterial( - obj.properties.getProperty(SolidMaterial.MATERIAL_KEY), + vision.properties.getProperty(SolidMaterial.MATERIAL_KEY), false ) - material.linewidth = obj.thickness.toDouble() - material.color = obj.color.string?.let { Color(it) } ?: DEFAULT_LINE_COLOR + material.linewidth = vision.thickness.toDouble() + material.color = vision.color.string?.let { Color(it) } ?: DEFAULT_LINE_COLOR return LineSegments(geometry, material).apply { - updatePosition(obj) + updatePosition(vision) //layers.enable(obj.layer) //add listener to object properties - obj.onPropertyChange { propertyName -> - updateProperty(obj, propertyName) + if(observe) { + vision.onPropertyChange(three.context) { propertyName -> + updateProperty(vision, propertyName) + } } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 20bd7f3a..57e90750 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -49,7 +49,7 @@ public object ThreeMaterials { cached = true } - private val lineMaterialCache = HashMap() + private val lineMaterialCache = HashMap() private fun buildLineMaterial(meta: Meta): LineBasicMaterial = LineBasicMaterial().apply { color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_LINE_COLOR @@ -61,14 +61,12 @@ public object ThreeMaterials { public fun getLineMaterial(meta: Meta?, cache: Boolean): LineBasicMaterial { if (meta == null) return DEFAULT_LINE return if (cache) { - lineMaterialCache.getOrPut(meta) { buildLineMaterial(meta) } + lineMaterialCache.getOrPut(meta.hashCode()) { buildLineMaterial(meta) } } else { buildLineMaterial(meta) } } - private val materialCache = HashMap() - internal fun buildMaterial(meta: Meta): Material = when (meta[SolidMaterial.TYPE_KEY]?.string) { "simple" -> MeshBasicMaterial().apply { color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR @@ -85,7 +83,9 @@ public object ThreeMaterials { needsUpdate = true } - internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta) { + private val materialCache = HashMap() + + internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta.hashCode()) { buildMaterial(meta).apply { cached = true } @@ -130,11 +130,11 @@ private var Material.cached: Boolean userData["cached"] = value } -public fun Mesh.updateMaterial(vision: Vision) { +public fun Mesh.createMaterial(vision: Vision) { val ownMaterialMeta = vision.properties.own?.get(SolidMaterial.MATERIAL_KEY) if (ownMaterialMeta == null) { if (vision is SolidReference && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty()) { - updateMaterial(vision.prototype) + createMaterial(vision.prototype) } else { material = ThreeMaterials.cacheMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)) } @@ -150,7 +150,7 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { || propertyName == SolidMaterial.MATERIAL_KEY + SolidMaterial.TYPE_KEY ) { //generate a new material since cached material should not be changed - updateMaterial(vision) + createMaterial(vision) } else { when (propertyName) { SolidMaterial.MATERIAL_COLOR_KEY -> { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index a35ca12d..96fa2621 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -30,32 +30,34 @@ public abstract class ThreeMeshFactory( */ public abstract fun buildGeometry(obj: T): BufferGeometry - override fun build(three: ThreePlugin, obj: T): Mesh { - val geometry = buildGeometry(obj) + override fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh { + val geometry = buildGeometry(vision) //val meshMeta: Meta = obj.properties[Material3D.MATERIAL_KEY]?.node ?: Meta.empty val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply { matrixAutoUpdate = false //set position for mesh - updatePosition(obj) - applyProperties(obj) + updatePosition(vision) + applyProperties(vision) } - //add listener to object properties - obj.onPropertyChange { name-> - when { - name.startsWith(Solid.GEOMETRY_KEY) -> { - val oldGeometry = mesh.geometry - val newGeometry = buildGeometry(obj) - oldGeometry.attributes = newGeometry.attributes - //mesh.applyWireFrame(obj) - mesh.applyEdges(obj) - newGeometry.dispose() + if(observe) { + //add listener to object properties + vision.onPropertyChange(three.context) { name -> + when { + name.startsWith(Solid.GEOMETRY_KEY) -> { + val oldGeometry = mesh.geometry + val newGeometry = buildGeometry(vision) + oldGeometry.attributes = newGeometry.attributes + //mesh.applyWireFrame(obj) + mesh.applyEdges(vision) + newGeometry.dispose() + } + //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) + name.startsWith(EDGES_KEY) -> mesh.applyEdges(vision) + else -> mesh.updateProperty(vision, name) } - //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) - name.startsWith(EDGES_KEY) -> mesh.applyEdges(obj) - else -> mesh.updateProperty(obj, name) } } @@ -76,26 +78,26 @@ public abstract class ThreeMeshFactory( @VisionBuilder public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { - properties.set(EDGES_ENABLED_KEY, enabled) + properties[EDGES_ENABLED_KEY] = enabled SolidMaterial.write(properties.getProperty(EDGES_MATERIAL_KEY)).apply(block) } -internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { - updateMaterial(obj) - applyEdges(obj) +internal fun Mesh.applyProperties(vision: Solid): Mesh = apply { + createMaterial(vision) + applyEdges(vision) //applyWireFrame(obj) - layers.set(obj.layer) + layers.set(vision.layer) children.forEach { - it.layers.set(obj.layer) + it.layers.set(vision.layer) } } -public fun Mesh.applyEdges(obj: Solid) { +public fun Mesh.applyEdges(vision: Solid) { val edges = children.find { it.name == "@edges" } as? LineSegments //inherited edges definition, enabled by default - if (obj.properties.getProperty(EDGES_ENABLED_KEY, inherit = true).boolean != false) { + if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = true)?.boolean != false) { val bufferGeometry = geometry as? BufferGeometry ?: return - val material = ThreeMaterials.getLineMaterial(obj.properties.getProperty(EDGES_MATERIAL_KEY), true) + val material = ThreeMaterials.getLineMaterial(vision.properties.getProperty(EDGES_MATERIAL_KEY), true) if (edges == null) { add( LineSegments( diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index c715efdb..ba30e88b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -11,7 +11,7 @@ import space.kscience.dataforge.meta.update import space.kscience.dataforge.names.* import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision -import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.VisionChildren import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.visible @@ -48,69 +48,75 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { as ThreeFactory? } - public fun buildObject3D(obj: Solid): Object3D = when (obj) { - is ThreeJsVision -> obj.render(this) - is SolidReference -> ThreeReferenceFactory.build(this, obj) + public fun buildObject3D(vision: Solid, observe: Boolean = true): Object3D = when (vision) { + is ThreeJsVision -> vision.render(this) + is SolidReference -> ThreeReferenceFactory.build(this, vision, observe) is SolidGroup -> { val group = ThreeGroup() - obj.items.forEach { (token, child) -> + vision.items.forEach { (token, child) -> if (token != SolidGroup.PROTOTYPES_TOKEN && child.ignore != true) { try { - val object3D = buildObject3D(child) + val object3D = buildObject3D( + child, + if (token.body == VisionChildren.STATIC_TOKEN_BODY) false else observe + ) + // disable tracking changes for statics group[token] = object3D } catch (ex: Throwable) { logger.error(ex) { "Failed to render $child" } - ex.printStackTrace() } } } group.apply { - updatePosition(obj) + updatePosition(vision) //obj.onChildrenChange() + if (observe) { + vision.properties.changes.onEach { name -> + if ( + name.startsWith(Solid.POSITION_KEY) || + name.startsWith(Solid.ROTATION_KEY) || + name.startsWith(Solid.SCALE_KEY) + ) { + //update position of mesh using this object + updatePosition(vision) + } else if (name == Vision.VISIBLE_KEY) { + visible = vision.visible ?: true + } + }.launchIn(context) - obj.onPropertyChange(context) { name -> - if ( - name.startsWith(Solid.POSITION_KEY) || - name.startsWith(Solid.ROTATION_KEY) || - name.startsWith(Solid.SCALE_KEY) - ) { - //update position of mesh using this object - updatePosition(obj) - } else if (name == Vision.VISIBLE_KEY) { - visible = obj.visible ?: true - } - } + vision.children.changes.onEach { childName -> + if(childName.isEmpty()) return@onEach - obj.children.changes.onEach { childName -> - val child = obj.children.getChild(childName) + val child = vision.children.getChild(childName) - //removing old object - findChild(childName)?.let { oldChild -> - oldChild.parent?.remove(oldChild) - } + //removing old object + findChild(childName)?.let { oldChild -> + oldChild.parent?.remove(oldChild) + } - //adding new object - if (child != null && child is Solid) { - try { - val object3D = buildObject3D(child) - set(childName, object3D) - } catch (ex: Throwable) { - logger.error(ex) { "Failed to render $child" } + //adding new object + if (child != null && child is Solid) { + try { + val object3D = buildObject3D(child) + set(childName, object3D) + } catch (ex: Throwable) { + logger.error(ex) { "Failed to render $child" } + } } - } - }.launchIn(context) + }.launchIn(context) + } } } - is Composite -> compositeFactory.build(this, obj) + is Composite -> compositeFactory.build(this, vision, observe) else -> { //find specialized factory for this type if it is present - val factory: ThreeFactory? = findObjectFactory(obj::class) + val factory: ThreeFactory? = findObjectFactory(vision::class) when { - factory != null -> factory.build(this, obj) - obj is GeometrySolid -> ThreeShapeFactory.build(this, obj) - else -> error("Renderer for ${obj::class} not found") + factory != null -> factory.build(this, vision, observe) + vision is GeometrySolid -> ThreeShapeFactory.build(this, vision, observe) + else -> error("Renderer for ${vision::class} not found") } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt index e6c84c94..56df4b8b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt @@ -13,19 +13,21 @@ public object ThreePointLightFactory : ThreeFactory { private val DEFAULT_COLOR = Color(0x404040) - override fun build(three: ThreePlugin, obj: PointLightSource): PointLight { + override fun build(three: ThreePlugin, vision: PointLightSource, observe: Boolean): PointLight { val res = PointLight().apply { matrixAutoUpdate = false - color = obj.color.threeColor() ?: DEFAULT_COLOR - intensity = obj.intensity.toDouble() - updatePosition(obj) + color = vision.color.threeColor() ?: DEFAULT_COLOR + intensity = vision.intensity.toDouble() + updatePosition(vision) } - obj.onPropertyChange { name -> - when (name) { - LightSource::color.name.asName() -> res.color = obj.color.threeColor() ?: DEFAULT_COLOR - LightSource::intensity.name.asName() -> res.intensity = obj.intensity.toDouble() - else -> res.updateProperty(obj, name) + if(observe) { + vision.onPropertyChange(three.context) { name -> + when (name) { + LightSource::color.name.asName() -> res.color = vision.color.threeColor() ?: DEFAULT_COLOR + LightSource::intensity.name.asName() -> res.intensity = vision.intensity.toDouble() + else -> res.updateProperty(vision, name) + } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index ade11074..ec60ddb3 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -31,33 +31,35 @@ public object ThreeReferenceFactory : ThreeFactory { } } - override fun build(three: ThreePlugin, obj: SolidReference): Object3D { - val template = obj.prototype + override fun build(three: ThreePlugin, vision: SolidReference, observe: Boolean): Object3D { + val template = vision.prototype val cachedObject = cache.getOrPut(template) { three.buildObject3D(template) } val object3D: Object3D = cachedObject.replicate() - object3D.updatePosition(obj) + object3D.updatePosition(vision) if (object3D is Mesh) { //object3D.material = ThreeMaterials.buildMaterial(obj.getProperty(SolidMaterial.MATERIAL_KEY).node!!) - object3D.applyProperties(obj) + object3D.applyProperties(vision) } //TODO apply child properties - obj.onPropertyChange { name -> - if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { - val childName = name.firstOrNull()?.index?.let(Name::parse) - ?: error("Wrong syntax for reference child property: '$name'") - val propertyName = name.cutFirst() - val referenceChild = - obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found") - val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") - child.updateProperty(referenceChild, propertyName) - } else { - object3D.updateProperty(obj, name) + if (observe) { + vision.onPropertyChange(three.context) { name -> + if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { + val childName = name.firstOrNull()?.index?.let(Name::parse) + ?: error("Wrong syntax for reference child property: '$name'") + val propertyName = name.cutFirst() + val referenceChild = + vision.children.getChild(childName) ?: error("Reference child with name '$childName' not found") + val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") + child.updateProperty(referenceChild, propertyName) + } else { + object3D.updateProperty(vision, name) + } } } diff --git a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts index 399eb5b0..7623086d 100644 --- a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts +++ b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts @@ -1,11 +1,11 @@ plugins { id("space.kscience.gradle.mpp") - } +} val ktorVersion: String by rootProject.extra kotlin { - js(IR){ + js(IR) { browser { webpackTask { this.outputFileName = "js/visionforge-three.js" @@ -14,17 +14,6 @@ kotlin { binaries.executable() } - afterEvaluate { - val jsBrowserDistribution by tasks.getting - - tasks.getByName("jvmProcessResources") { - dependsOn(jsBrowserDistribution) - afterEvaluate { - from(jsBrowserDistribution) - } - } - } - sourceSets { commonMain { dependencies { @@ -42,4 +31,22 @@ kotlin { } } } -} \ No newline at end of file +} + + +val jsBrowserDistribution by tasks.getting +val jsBrowserDevelopmentExecutableDistribution by tasks.getting + +val devMode = rootProject.findProperty("visionforge.development") as? Boolean + ?: rootProject.version.toString().contains("dev") + +tasks.getByName("jvmProcessResources") { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + if (devMode) { + dependsOn(jsBrowserDevelopmentExecutableDistribution) + from(jsBrowserDevelopmentExecutableDistribution) + } else { + dependsOn(jsBrowserDistribution) + from(jsBrowserDistribution) + } +} From 98bb935de5f7ebf5e2a4cc4d9986f38293275994 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 Aug 2022 20:28:47 +0300 Subject: [PATCH 023/112] Optimizations... optimizations --- visionforge-threejs/build.gradle.kts | 2 +- .../visionforge/solid/three/ThreeCanvas.kt | 16 +++++++++------- .../visionforge/solid/three/ThreeFactory.kt | 5 ++--- .../visionforge/solid/three/ThreeMaterials.kt | 4 ++-- .../visionforge/solid/three/ThreeMeshFactory.kt | 6 ++++-- .../solid/three/ThreeReferenceFactory.kt | 7 +++---- .../kscience/visionforge/solid/three/three.kt | 9 +++++++++ 7 files changed, 30 insertions(+), 19 deletions(-) diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index 86b8702c..8be1b7a1 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -10,6 +10,6 @@ kotlin{ dependencies { api(project(":visionforge-solid")) - implementation(npm("three", "0.137.5")) + implementation(npm("three", "0.143.0")) implementation(npm("three-csg-ts", "3.1.10")) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index 586abe32..747b722a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -212,7 +212,7 @@ public class ThreeCanvas( } //find first non-static parent in this object ancestry - private fun Object3D?.upTrace(): Object3D? = if (this?.name?.startsWith("@") == true) parent else this + private tailrec fun Object3D.upTrace(): Object3D? = if (!name.startsWith("@")) this else parent?.upTrace() private fun pick(): Object3D? { // update the picking ray with the camera and mouse position @@ -222,8 +222,8 @@ public class ThreeCanvas( return root?.let { root -> val intersects = raycaster.intersectObject(root, true) //skip invisible objects - val obj = intersects.map { it.`object` }.firstOrNull { it.visible } - obj.upTrace() + val obj: Object3D? = intersects.map { it.`object` }.firstOrNull { it.visible } + obj?.upTrace() } } @@ -280,20 +280,22 @@ public class ThreeCanvas( edgesName: String, material: LineBasicMaterial = SELECTED_MATERIAL, ) { + if (userData[DO_NOT_HIGHLIGHT_TAG] == true) { return } - if (this is Mesh) { - val edges = getObjectByName(edgesName) ?: LineSegments( + + if (isMesh(this)) { + val highlightMesh = getObjectByName(edgesName) ?: LineSegments( EdgesGeometry(geometry), material ).also { it.name = edgesName add(it) } - edges.visible = highlight + highlightMesh.visible = highlight } else { - children.filter { it.name != edgesName }.forEach { + children.filter { !it.name.startsWith("@") && it.name != edgesName }.forEach { it.toggleHighlight(highlight, edgesName, material) } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 5c4c6cd5..0f38640c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -3,7 +3,6 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.math.Euler -import info.laht.threekt.objects.Mesh import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith @@ -50,7 +49,7 @@ public fun Object3D.updatePosition(vision: Vision) { // setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) // } - setRotationFromEuler( Euler(vision.rotationX, vision.rotationY, vision.rotationZ, vision.rotationOrder.name)) + setRotationFromEuler(Euler(vision.rotationX, vision.rotationY, vision.rotationZ, vision.rotationOrder.name)) scale.set(vision.scaleX, vision.scaleY, vision.scaleZ) updateMatrix() @@ -62,7 +61,7 @@ public fun Object3D.updatePosition(vision: Vision) { */ public fun Object3D.updateProperty(source: Vision, propertyName: Name) { // console.log("$source updated $propertyName with ${source.computeProperty(propertyName)}") - if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) { + if (isMesh(this) && propertyName.startsWith(MATERIAL_KEY)) { updateMaterialProperty(source, propertyName) } else if ( propertyName.startsWith(Solid.POSITION_KEY) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 57e90750..3826f11d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -39,13 +39,13 @@ public object ThreeMaterials { public val SELECTED_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { color.set(Colors.ivory) - linewidth = 8.0 + linewidth = 2.0 cached = true } public val HIGHLIGHT_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { color.set(Colors.blue) - linewidth = 8.0 + linewidth = 2.0 cached = true } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index 96fa2621..1a68985f 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -17,6 +17,7 @@ import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_ENABLED_KEY import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_MATERIAL_KEY +import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_OBJECT_NAME import kotlin.reflect.KClass /** @@ -66,6 +67,7 @@ public abstract class ThreeMeshFactory( public companion object { public val EDGES_KEY: Name = "edges".asName() + internal const val EDGES_OBJECT_NAME: String = "@edges" //public val WIREFRAME_KEY: Name = "wireframe".asName() public val ENABLED_KEY: Name = "enabled".asName() @@ -93,7 +95,7 @@ internal fun Mesh.applyProperties(vision: Solid): Mesh = apply { } public fun Mesh.applyEdges(vision: Solid) { - val edges = children.find { it.name == "@edges" } as? LineSegments + val edges = children.find { it.name == EDGES_OBJECT_NAME } as? LineSegments //inherited edges definition, enabled by default if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = true)?.boolean != false) { val bufferGeometry = geometry as? BufferGeometry ?: return @@ -104,7 +106,7 @@ public fun Mesh.applyEdges(vision: Solid) { EdgesGeometry(bufferGeometry), material ).apply { - name = "@edges" + name = EDGES_OBJECT_NAME } ) } else { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index ec60ddb3..b0e1d69c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -17,11 +17,10 @@ public object ThreeReferenceFactory : ThreeFactory { override val type: KClass = SolidReference::class private fun Object3D.replicate(): Object3D { - return when (this) { - is Mesh -> Mesh(geometry, material).also { + return when { + isMesh(this) -> Mesh(geometry, material).also { it.applyMatrix4(matrix) } - else -> clone(false) }.also { obj: Object3D -> obj.name = this.name @@ -40,7 +39,7 @@ public object ThreeReferenceFactory : ThreeFactory { val object3D: Object3D = cachedObject.replicate() object3D.updatePosition(vision) - if (object3D is Mesh) { + if (isMesh(object3D)) { //object3D.material = ThreeMaterials.buildMaterial(obj.getProperty(SolidMaterial.MATERIAL_KEY).node!!) object3D.applyProperties(vision) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt index d21ff544..94262052 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt @@ -11,6 +11,7 @@ import info.laht.threekt.textures.Texture import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.float import space.kscience.dataforge.meta.get +import kotlin.contracts.contract import kotlin.math.PI public val Meta.vector: Vector3 get() = Vector3(this["x"].float ?: 0f, this["y"].float ?: 0f, this["z"].float ?: 0f) @@ -34,6 +35,14 @@ internal fun Any.dispose() { public fun Layers.check(layer: Int): Boolean = (mask shr (layer) and 0x00000001) > 0 + +internal fun isMesh(object3D: Object3D): Boolean{ + contract { + returns(true) implies (object3D is Mesh) + } + return object3D.asDynamic().isMesh as? Boolean ?: false +} + internal fun Object3D.takeIfMesh(): Mesh? { val d = asDynamic() return if(d.isMesh as Boolean){ From cb25dca34c42cac5afbdada60be6f046d33d978f Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 Aug 2022 22:03:46 +0300 Subject: [PATCH 024/112] Refactor three package. Add MeshLine --- CHANGELOG.md | 9 +++- .../visionforge/solid/demo/VariableBox.kt | 6 +-- .../visionforge/react/valueChooser.kt | 2 +- .../kscience/visionforge/solid/PolyLine.kt | 6 ++- visionforge-threejs/build.gradle.kts | 1 + .../solid/three/ThreeAmbientLightFactory.kt | 4 +- .../solid/three/ThreeBoxFactory.kt | 2 +- .../visionforge/solid/three/ThreeCanvas.kt | 47 ++++++++++++------- .../solid/three/ThreeCanvasLabelFactory.kt | 12 ++--- .../solid/three/ThreeCompositeFactory.kt | 2 +- .../solid/three/ThreeConeFactory.kt | 4 +- .../solid/three/ThreeConvexFactory.kt | 2 +- .../visionforge/solid/three/ThreeFactory.kt | 6 +-- .../solid/three/ThreeGeometryBuilder.kt | 6 +-- .../visionforge/solid/three/ThreeJsVision.kt | 2 +- .../solid/three/ThreeLabelFactory.kt | 6 +-- .../solid/three/ThreeLineFactory.kt | 8 ++-- .../visionforge/solid/three/ThreeMaterials.kt | 26 +++------- .../solid/three/ThreeMeshFactory.kt | 8 ++-- .../solid/three/ThreeMeshLineFactory.kt | 41 ++++++++++++++++ .../visionforge/solid/three/ThreePlugin.kt | 8 ++-- .../solid/three/ThreePointLightFactory.kt | 4 +- .../solid/three/ThreeReferenceFactory.kt | 4 +- .../solid/three/ThreeSmartLineFactory.kt | 17 +++++++ .../solid/three/ThreeSphereFactory.kt | 4 +- .../kscience/visionforge/solid/three/csg.kt | 8 ++-- .../kscience/visionforge/solid/three/three.kt | 16 +++---- .../{info/laht/threekt => three}/THREE.kt | 2 +- .../animation/AnimationAction.kt | 4 +- .../animation/AnimationClip.kt | 2 +- .../animation/AnimationMixer.kt | 4 +- .../animation/AnimationUtils.kt | 2 +- .../animation/KeyFrameTrack.kt | 2 +- .../laht/threekt => three}/audio/Audio.kt | 2 +- .../threekt => three}/audio/AudioContext.kt | 2 +- .../threekt => three}/audio/AudioListener.kt | 4 +- .../audio/PositionalAudio.kt | 2 +- .../laht/threekt => three}/cameras/Camera.kt | 8 ++-- .../cameras/OrthographicCamera.kt | 2 +- .../cameras/PerspectiveCamera.kt | 2 +- .../threekt => three}/core/BufferAttribute.kt | 10 ++-- .../threekt => three}/core/BufferGeometry.kt | 10 ++-- .../laht/threekt => three}/core/Clock.kt | 2 +- .../threekt => three}/core/EventDispatcher.kt | 2 +- .../laht/threekt => three}/core/Face3.kt | 6 +-- .../core/InstancedBufferGeometry.kt | 2 +- .../laht/threekt => three}/core/Layers.kt | 2 +- .../laht/threekt => three}/core/Object3D.kt | 4 +- .../laht/threekt => three}/core/Raycaster.kt | 10 ++-- .../laht/threekt => three}/core/Uniform.kt | 2 +- .../threekt => three}/external/Detector.kt | 2 +- .../external/ImprovedNoise.kt | 2 +- .../external/SimplexNoise.kt | 2 +- .../external/controls/FlyControls.kt | 4 +- .../external/controls/OrbitControls.kt | 6 +-- .../external/controls/TrackballControls.kt | 8 ++-- .../external/controls/TransformControls.kt | 4 +- .../external/exporters/OBJExporter.kt | 4 +- .../external/exporters/STLExporter.kt | 4 +- .../external/geometries/ConvexGeometry.kt | 6 +-- .../external/libs/GUIParams.kt | 2 +- .../threekt => three}/external/libs/Stats.kt | 2 +- .../threekt => three}/external/libs/datgui.kt | 2 +- .../external/loaders/BabylonLoader.kt | 6 +-- .../external/loaders/GLTFLoader.kt | 10 ++-- .../external/loaders/LoaderSupport.kt | 2 +- .../external/loaders/MTLLoader.kt | 6 +-- .../external/loaders/OBJLoader.kt | 8 ++-- .../external/loaders/OBJLoader2.kt | 6 +-- .../external/loaders/STLLoader.kt | 6 +-- .../threekt => three}/external/objects/Sky.kt | 4 +- .../external/objects/Water.kt | 4 +- .../external/objects/WaterOptions.kt | 6 +-- .../threekt => three}/extras/SceneUtils.kt | 12 ++--- .../threekt => three}/extras/core/Curve.kt | 2 +- .../extras/core/CurvePath.kt | 2 +- .../threekt => three}/extras/core/Path.kt | 4 +- .../threekt => three}/extras/core/Shape.kt | 4 +- .../extras/core/ShapePath.kt | 2 +- .../extras/curves/ArcCurve.kt | 2 +- .../extras/curves/CatmullRomCurve3.kt | 6 +-- .../extras/curves/EllipseCurve.kt | 6 +-- .../extras/curves/LineCurve.kt | 6 +-- .../extras/curves/LineCurve3.kt | 6 +-- .../extras/curves/QuadricBezierCurve.kt | 6 +-- .../extras/curves/QuadricBezierCurve3.kt | 6 +-- .../extras/curves/SplineCurve.kt | 6 +-- .../geometries/BoxGeometry.kt | 4 +- .../geometries/ConeGeometry.kt | 4 +- .../geometries/CylinderGeometry.kt | 4 +- .../geometries/EdgesGeometry.kt | 4 +- .../geometries/ExtrudeGeometry.kt | 8 ++-- .../geometries/PlaneGeometry.kt | 4 +- .../geometries/SphereGeometry.kt | 4 +- .../geometries/TextGeometry.kt | 2 +- .../geometries/TorusGeometry.kt | 4 +- .../geometries/TubeGeometry.kt | 8 ++-- .../geometries/WireframeGeometry.kt | 4 +- .../threekt => three}/helpers/ArrowHelper.kt | 12 ++--- .../threekt => three}/helpers/AxesHelper.kt | 4 +- .../threekt => three}/helpers/Box3Helper.kt | 6 +-- .../threekt => three}/helpers/CameraHelper.kt | 6 +-- .../threekt => three}/helpers/GridHelper.kt | 4 +- .../helpers/HemisphereLightHelper.kt | 8 ++-- .../threekt => three}/helpers/PlaneHelper.kt | 8 ++-- .../{info/laht/threekt => three}/ktutils.kt | 6 +-- .../threekt => three}/lights/AmbientLight.kt | 2 +- .../lights/DirectionalLight.kt | 4 +- .../lights/DirectionalLightShadow.kt | 2 +- .../lights/HemisphereLight.kt | 4 +- .../laht/threekt => three}/lights/Light.kt | 6 +-- .../threekt => three}/lights/LightShadow.kt | 8 ++-- .../threekt => three}/lights/PointLight.kt | 2 +- .../threekt => three}/lights/SpotLight.kt | 4 +- .../lights/SpotLightShadow.kt | 2 +- .../laht/threekt => three}/loaders/Cache.kt | 2 +- .../loaders/CompressedTextureLoader.kt | 4 +- .../threekt => three}/loaders/ImageLoader.kt | 2 +- .../threekt => three}/loaders/JSONLoader.kt | 8 ++-- .../laht/threekt => three}/loaders/Loader.kt | 2 +- .../loaders/LoadingManager.kt | 2 +- .../loaders/MaterialLoader.kt | 6 +-- .../loaders/TextureLoader.kt | 4 +- .../materials/LineBasicMaterial.kt | 4 +- .../materials/LineDashedMaterial.kt | 2 +- .../threekt => three}/materials/Material.kt | 2 +- .../materials/MeshBasicMaterial.kt | 6 +-- .../materials/MeshDepthMaterial.kt | 4 +- .../materials/MeshLambertMaterial.kt | 6 +-- .../materials/MeshNormalMaterial.kt | 6 +-- .../materials/MeshPhongMaterial.kt | 8 ++-- .../materials/MeshPhysicalMaterial.kt | 2 +- .../materials/MeshStandardMaterial.kt | 8 ++-- .../materials/PointsMaterial.kt | 6 +-- .../materials/RawShaderMaterial.kt | 2 +- .../materials/ShaderMaterial.kt | 2 +- .../materials/SpriteMaterial.kt | 6 +-- .../{info/laht/threekt => three}/math/Box2.kt | 2 +- .../{info/laht/threekt => three}/math/Box3.kt | 4 +- .../laht/threekt => three}/math/Color.kt | 2 +- .../threekt => three}/math/ColorConstants.kt | 2 +- .../threekt => three}/math/Cylindrical.kt | 2 +- .../laht/threekt => three}/math/Euler.kt | 2 +- .../laht/threekt => three}/math/Frustrum.kt | 2 +- .../laht/threekt => three}/math/Line3.kt | 2 +- .../{info/laht/threekt => three}/math/Math.kt | 2 +- .../laht/threekt => three}/math/Matrix3.kt | 4 +- .../laht/threekt => three}/math/Matrix4.kt | 4 +- .../laht/threekt => three}/math/Plane.kt | 2 +- .../laht/threekt => three}/math/Quaternion.kt | 2 +- .../{info/laht/threekt => three}/math/Ray.kt | 2 +- .../laht/threekt => three}/math/Sphere.kt | 2 +- .../laht/threekt => three}/math/Spherical.kt | 2 +- .../laht/threekt => three}/math/Triangle.kt | 2 +- .../laht/threekt => three}/math/Vector2.kt | 2 +- .../laht/threekt => three}/math/Vector3.kt | 4 +- .../laht/threekt => three}/math/Vector4.kt | 2 +- .../laht/threekt => three}/math/operators.kt | 2 +- .../main/kotlin/three/meshline/MeshLine.kt | 37 +++++++++++++++ .../main/kotlin/three/meshline/meshLineExt.kt | 8 ++++ .../laht/threekt => three}/objects/Group.kt | 4 +- .../laht/threekt => three}/objects/LOD.kt | 10 ++-- .../laht/threekt => three}/objects/Line.kt | 12 ++--- .../threekt => three}/objects/LineLoop.kt | 6 +-- .../threekt => three}/objects/LineSegments.kt | 8 ++-- .../laht/threekt => three}/objects/Mesh.kt | 12 ++--- .../laht/threekt => three}/objects/Points.kt | 10 ++-- .../laht/threekt => three}/objects/Sprite.kt | 10 ++-- .../renderers/WebGL2Renderer.kt | 6 +-- .../renderers/WebGL2RendererParams.kt | 2 +- .../renderers/WebGLRenderTarget.kt | 6 +-- .../renderers/WebGLRenderTargetOptions.kt | 2 +- .../renderers/WebGLRenderer.kt | 8 ++-- .../renderers/WebGLRendererParams.kt | 2 +- .../renderers/shaders/ShaderChunk.kt | 2 +- .../renderers/shaders/ShaderLib.kt | 2 +- .../renderers/shaders/UniformsUtil.kt | 4 +- .../laht/threekt => three}/scenes/Fog.kt | 4 +- .../laht/threekt => three}/scenes/FogExp2.kt | 4 +- .../laht/threekt => three}/scenes/Scene.kt | 6 +-- .../textures/CompressedTexture.kt | 2 +- .../threekt => three}/textures/CubeTexture.kt | 2 +- .../textures/DepthTexture.kt | 2 +- .../threekt => three}/textures/Texture.kt | 6 +-- .../utils/BufferGeometryUtils.kt | 4 +- 185 files changed, 550 insertions(+), 438 deletions(-) create mode 100644 visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt create mode 100644 visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/THREE.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/animation/AnimationAction.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/animation/AnimationClip.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/animation/AnimationMixer.kt (92%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/animation/AnimationUtils.kt (71%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/animation/KeyFrameTrack.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/audio/Audio.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/audio/AudioContext.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/audio/AudioListener.kt (89%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/audio/PositionalAudio.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/cameras/Camera.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/cameras/OrthographicCamera.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/cameras/PerspectiveCamera.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/BufferAttribute.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/BufferGeometry.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/Clock.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/EventDispatcher.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/Face3.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/InstancedBufferGeometry.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/Layers.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/Object3D.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/Raycaster.kt (91%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/core/Uniform.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/Detector.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/ImprovedNoise.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/SimplexNoise.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/controls/FlyControls.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/controls/OrbitControls.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/controls/TrackballControls.kt (90%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/controls/TransformControls.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/exporters/OBJExporter.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/exporters/STLExporter.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/geometries/ConvexGeometry.kt (64%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/libs/GUIParams.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/libs/Stats.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/libs/datgui.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/loaders/BabylonLoader.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/loaders/GLTFLoader.kt (89%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/loaders/LoaderSupport.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/loaders/MTLLoader.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/loaders/OBJLoader.kt (91%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/loaders/OBJLoader2.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/loaders/STLLoader.kt (92%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/objects/Sky.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/objects/Water.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/external/objects/WaterOptions.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/SceneUtils.kt (87%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/core/Curve.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/core/CurvePath.kt (89%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/core/Path.kt (62%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/core/Shape.kt (55%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/core/ShapePath.kt (64%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/curves/ArcCurve.kt (91%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/curves/CatmullRomCurve3.kt (79%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/curves/EllipseCurve.kt (85%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/curves/LineCurve.kt (67%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/curves/LineCurve3.kt (67%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/curves/QuadricBezierCurve.kt (74%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/curves/QuadricBezierCurve3.kt (74%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/extras/curves/SplineCurve.kt (68%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/BoxGeometry.kt (77%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/ConeGeometry.kt (82%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/CylinderGeometry.kt (82%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/EdgesGeometry.kt (66%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/ExtrudeGeometry.kt (92%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/PlaneGeometry.kt (73%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/SphereGeometry.kt (82%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/TextGeometry.kt (96%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/TorusGeometry.kt (78%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/TubeGeometry.kt (73%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/geometries/WireframeGeometry.kt (71%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/helpers/ArrowHelper.kt (87%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/helpers/AxesHelper.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/helpers/Box3Helper.kt (92%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/helpers/CameraHelper.kt (91%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/helpers/GridHelper.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/helpers/HemisphereLightHelper.kt (91%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/helpers/PlaneHelper.kt (59%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/ktutils.kt (55%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/AmbientLight.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/DirectionalLight.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/DirectionalLightShadow.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/HemisphereLight.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/Light.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/LightShadow.kt (90%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/PointLight.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/SpotLight.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/lights/SpotLightShadow.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/loaders/Cache.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/loaders/CompressedTextureLoader.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/loaders/ImageLoader.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/loaders/JSONLoader.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/loaders/Loader.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/loaders/LoadingManager.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/loaders/MaterialLoader.kt (92%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/loaders/TextureLoader.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/LineBasicMaterial.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/LineDashedMaterial.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/Material.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/MeshBasicMaterial.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/MeshDepthMaterial.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/MeshLambertMaterial.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/MeshNormalMaterial.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/MeshPhongMaterial.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/MeshPhysicalMaterial.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/MeshStandardMaterial.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/PointsMaterial.kt (92%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/RawShaderMaterial.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/ShaderMaterial.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/materials/SpriteMaterial.kt (92%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Box2.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Box3.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Color.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/ColorConstants.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Cylindrical.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Euler.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Frustrum.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Line3.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Math.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Matrix3.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Matrix4.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Plane.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Quaternion.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Ray.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Sphere.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Spherical.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Triangle.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Vector2.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Vector3.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/Vector4.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/math/operators.kt (98%) create mode 100644 visionforge-threejs/src/main/kotlin/three/meshline/MeshLine.kt create mode 100644 visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/objects/Group.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/objects/LOD.kt (88%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/objects/Line.kt (85%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/objects/LineLoop.kt (91%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/objects/LineSegments.kt (89%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/objects/Mesh.kt (86%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/objects/Points.kt (87%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/objects/Sprite.kt (87%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/WebGL2Renderer.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/WebGL2RendererParams.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/WebGLRenderTarget.kt (93%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/WebGLRenderTargetOptions.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/WebGLRenderer.kt (96%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/WebGLRendererParams.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/shaders/ShaderChunk.kt (99%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/shaders/ShaderLib.kt (96%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/renderers/shaders/UniformsUtil.kt (94%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/scenes/Fog.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/scenes/FogExp2.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/scenes/Scene.kt (95%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/textures/CompressedTexture.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/textures/CubeTexture.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/textures/DepthTexture.kt (97%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/textures/Texture.kt (98%) rename visionforge-threejs/src/main/kotlin/{info/laht/threekt => three}/utils/BufferGeometryUtils.kt (88%) diff --git a/CHANGELOG.md b/CHANGELOG.md index a59c31d9..f60db403 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,15 @@ ## [Unreleased] ### Added - Context receivers flag +- MeshLine for thick lines ### Changed -- Naming of Canvas3D options -- Lights are added to the scene instead of 3D options +- Visions **must** be rooted in order to subscribe to updates. +- Visions use flows instead of direct subscriptions. +- Radical change of inner workings of vision children and properties. +- Three package changed to `three`. +- Naming of Canvas3D options. +- Lights are added to the scene instead of 3D options. ### Deprecated diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index 28b0c968..1e626155 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -1,8 +1,5 @@ package space.kscience.visionforge.solid.demo -import info.laht.threekt.core.Object3D -import info.laht.threekt.geometries.BoxGeometry -import info.laht.threekt.objects.Mesh import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.number @@ -13,6 +10,9 @@ import space.kscience.visionforge.setChild import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.three.* +import three.core.Object3D +import three.geometries.BoxGeometry +import three.objects.Mesh import kotlin.math.max internal fun SolidGroup.varBox( diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index 04c7d946..96c1e6fe 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -1,6 +1,5 @@ package space.kscience.visionforge.react -import info.laht.threekt.math.Color import kotlinx.css.margin import kotlinx.css.pct import kotlinx.css.px @@ -25,6 +24,7 @@ import space.kscience.visionforge.widgetType import styled.css import styled.styledInput import styled.styledSelect +import three.math.Color public external interface ValueChooserProps : Props { public var descriptor: MetaDescriptor? diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt index 4d5373b8..0f366dbe 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt @@ -10,7 +10,11 @@ import space.kscience.visionforge.* public class PolyLine(public val points: List) : SolidBase() { //var lineType by string() - public var thickness: Number by properties.getProperty(SolidMaterial.MATERIAL_KEY).number { 1.0 } + public var thickness: Number by properties.root(inherit = false, includeStyles = true).number { DEFAULT_THICKNESS } + + public companion object { + public const val DEFAULT_THICKNESS: Double = 1.0 + } } @VisionBuilder diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index 8be1b7a1..7ba2c555 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -12,4 +12,5 @@ dependencies { api(project(":visionforge-solid")) implementation(npm("three", "0.143.0")) implementation(npm("three-csg-ts", "3.1.10")) + implementation(npm("three.meshline","1.4.0")) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt index 5df6cc7a..3d420570 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt @@ -1,8 +1,8 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.lights.AmbientLight -import info.laht.threekt.math.Color import space.kscience.visionforge.solid.AmbientLightSource +import three.lights.AmbientLight +import three.math.Color import kotlin.reflect.KClass public object ThreeAmbientLightFactory : ThreeFactory { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt index f66492ed..21c52198 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt @@ -1,8 +1,8 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.geometries.BoxGeometry import space.kscience.visionforge.solid.Box import space.kscience.visionforge.solid.detail +import three.geometries.BoxGeometry public object ThreeBoxFactory : ThreeMeshFactory(Box::class) { override fun buildGeometry(obj: Box): BoxGeometry = diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index 747b722a..04b04699 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -1,18 +1,5 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.WebGLRenderer -import info.laht.threekt.cameras.PerspectiveCamera -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.external.controls.OrbitControls -import info.laht.threekt.external.controls.TrackballControls -import info.laht.threekt.geometries.EdgesGeometry -import info.laht.threekt.helpers.AxesHelper -import info.laht.threekt.materials.LineBasicMaterial -import info.laht.threekt.math.* -import info.laht.threekt.objects.LineSegments -import info.laht.threekt.objects.Mesh -import info.laht.threekt.scenes.Scene import kotlinx.browser.window import org.w3c.dom.Element import org.w3c.dom.HTMLCanvasElement @@ -25,8 +12,19 @@ import space.kscience.dataforge.names.* import space.kscience.visionforge.Colors import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.specifications.* -import space.kscience.visionforge.solid.three.ThreeMaterials.HIGHLIGHT_MATERIAL -import space.kscience.visionforge.solid.three.ThreeMaterials.SELECTED_MATERIAL +import three.WebGLRenderer +import three.cameras.PerspectiveCamera +import three.core.Object3D +import three.core.Raycaster +import three.external.controls.OrbitControls +import three.external.controls.TrackballControls +import three.geometries.EdgesGeometry +import three.helpers.AxesHelper +import three.math.* +import three.meshline.MeshLine +import three.meshline.MeshLineMaterial +import three.objects.Mesh +import three.scenes.Scene import kotlin.math.cos import kotlin.math.sin @@ -278,7 +276,7 @@ public class ThreeCanvas( private fun Object3D.toggleHighlight( highlight: Boolean, edgesName: String, - material: LineBasicMaterial = SELECTED_MATERIAL, + material: MeshLineMaterial, ) { if (userData[DO_NOT_HIGHLIGHT_TAG] == true) { @@ -286,8 +284,8 @@ public class ThreeCanvas( } if (isMesh(this)) { - val highlightMesh = getObjectByName(edgesName) ?: LineSegments( - EdgesGeometry(geometry), + val highlightMesh = getObjectByName(edgesName) ?: Mesh( + MeshLine(EdgesGeometry(geometry)), material ).also { it.name = edgesName @@ -319,6 +317,19 @@ public class ThreeCanvas( } public companion object { + public val SELECTED_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply { + color.set(Colors.ivory) + linewidth = 2.0 + cached = true + } + + public val HIGHLIGHT_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply { + color.set(Colors.blue) + linewidth = 2.0 + cached = true + } + + public const val DO_NOT_HIGHLIGHT_TAG: String = "doNotHighlight" private const val HIGHLIGHT_NAME = "@highlight" private const val SELECT_NAME = "@select" diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index cc798297..0b0019df 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -1,11 +1,5 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.DoubleSide -import info.laht.threekt.core.Object3D -import info.laht.threekt.geometries.PlaneGeometry -import info.laht.threekt.materials.MeshBasicMaterial -import info.laht.threekt.objects.Mesh -import info.laht.threekt.textures.Texture import kotlinx.browser.document import org.w3c.dom.CanvasRenderingContext2D import org.w3c.dom.CanvasTextBaseline @@ -14,6 +8,12 @@ import org.w3c.dom.MIDDLE import space.kscience.visionforge.solid.SolidLabel import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG +import three.DoubleSide +import three.core.Object3D +import three.geometries.PlaneGeometry +import three.materials.MeshBasicMaterial +import three.objects.Mesh +import three.textures.Texture import kotlin.reflect.KClass /** diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index e4cb84d5..44bcb797 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -1,11 +1,11 @@ package space.kscience.visionforge.solid.three import CSG -import info.laht.threekt.objects.Mesh import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.Composite import space.kscience.visionforge.solid.CompositeType +import three.objects.Mesh import kotlin.reflect.KClass /** diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt index 8eed04ae..acb81e1f 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.geometries.CylinderGeometry import space.kscience.visionforge.solid.ConeSegment import space.kscience.visionforge.solid.detail +import three.core.BufferGeometry +import three.geometries.CylinderGeometry import kotlin.math.PI import kotlin.math.pow diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt index 2ab67219..83115b13 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.external.geometries.ConvexBufferGeometry import space.kscience.visionforge.solid.Convex +import three.external.geometries.ConvexBufferGeometry public object ThreeConvexFactory : ThreeMeshFactory(Convex::class) { override fun buildGeometry(obj: Convex): ConvexBufferGeometry { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 0f38640c..cf42c139 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -1,8 +1,5 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Euler import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith @@ -11,6 +8,9 @@ import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY import space.kscience.visionforge.solid.three.ThreeFactory.Companion.TYPE import space.kscience.visionforge.visible +import three.core.BufferGeometry +import three.core.Object3D +import three.math.Euler import kotlin.reflect.KClass /** diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt index fc226de6..e75e4847 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt @@ -1,8 +1,8 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Float32BufferAttribute -import info.laht.threekt.math.Vector3 +import three.core.BufferGeometry +import three.core.Float32BufferAttribute +import three.math.Vector3 import space.kscience.dataforge.meta.Meta import space.kscience.visionforge.solid.GeometryBuilder import space.kscience.visionforge.solid.Point3D diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt index 7c709a5c..3829698e 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt @@ -1,6 +1,6 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.Object3D +import three.core.Object3D import space.kscience.visionforge.solid.SolidBase /** diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index c9244ea5..49796fb0 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.Object3D -import info.laht.threekt.geometries.TextBufferGeometry -import info.laht.threekt.objects.Mesh +import three.core.Object3D +import three.geometries.TextBufferGeometry +import three.objects.Mesh import kotlinx.js.jso import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.warn diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index 557a375f..adf4ce0d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Color -import info.laht.threekt.objects.LineSegments +import three.core.BufferGeometry +import three.core.Object3D +import three.math.Color +import three.objects.LineSegments import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 3826f11d..abcd5df5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -1,11 +1,5 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.materials.LineBasicMaterial -import info.laht.threekt.materials.Material -import info.laht.threekt.materials.MeshBasicMaterial -import info.laht.threekt.materials.MeshStandardMaterial -import info.laht.threekt.math.Color -import info.laht.threekt.objects.Mesh import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName @@ -16,6 +10,12 @@ import space.kscience.visionforge.getStyleNodes import space.kscience.visionforge.solid.ColorAccessor import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.SolidReference +import three.materials.LineBasicMaterial +import three.materials.Material +import three.materials.MeshBasicMaterial +import three.materials.MeshStandardMaterial +import three.math.Color +import three.objects.Mesh public object ThreeMaterials { @@ -37,18 +37,6 @@ public object ThreeMaterials { cached = true } - public val SELECTED_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { - color.set(Colors.ivory) - linewidth = 2.0 - cached = true - } - - public val HIGHLIGHT_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { - color.set(Colors.blue) - linewidth = 2.0 - cached = true - } - private val lineMaterialCache = HashMap() private fun buildLineMaterial(meta: Meta): LineBasicMaterial = LineBasicMaterial().apply { @@ -124,7 +112,7 @@ public fun ColorAccessor.threeColor(): Color? { } } -private var Material.cached: Boolean +internal var Material.cached: Boolean get() = userData["cached"] == true set(value) { userData["cached"] = value diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index 1a68985f..ef7f5120 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -1,9 +1,5 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.geometries.EdgesGeometry -import info.laht.threekt.objects.LineSegments -import info.laht.threekt.objects.Mesh import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName @@ -18,6 +14,10 @@ import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_ENABLED_KEY import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_MATERIAL_KEY import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_OBJECT_NAME +import three.core.BufferGeometry +import three.geometries.EdgesGeometry +import three.objects.LineSegments +import three.objects.Mesh import kotlin.reflect.KClass /** diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt new file mode 100644 index 00000000..3d9b4c3b --- /dev/null +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt @@ -0,0 +1,41 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.PolyLine +import space.kscience.visionforge.solid.color +import space.kscience.visionforge.solid.string +import three.core.Object3D +import three.math.Color +import three.meshline.MeshLine +import three.meshline.MeshLineMaterial +import three.objects.Mesh +import kotlin.math.ceil +import kotlin.reflect.KClass + +public object ThreeMeshLineFactory : ThreeFactory { + override val type: KClass get() = PolyLine::class + + override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + val geometry = MeshLine( + Array((vision.points.size - 1) * 2) { + vision.points[ceil(it / 2.0).toInt()].toVector() + } + ) + + val material = MeshLineMaterial().apply { + thickness = vision.thickness.toFloat() + color = vision.color.string?.let { Color(it) } ?: ThreeMaterials.DEFAULT_LINE_COLOR + } + + return Mesh(geometry, material).apply { + updatePosition(vision) + //layers.enable(obj.layer) + //add listener to object properties + if (observe) { + vision.onPropertyChange(three.context) { propertyName -> + updateProperty(vision, propertyName) + } + } + } + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index ba30e88b..bae26853 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -1,6 +1,5 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.Object3D import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.w3c.dom.Element @@ -15,9 +14,10 @@ import space.kscience.visionforge.VisionChildren import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.visible +import three.core.Object3D import kotlin.collections.set import kotlin.reflect.KClass -import info.laht.threekt.objects.Group as ThreeGroup +import three.objects.Group as ThreeGroup public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { override val tag: PluginTag get() = Companion.tag @@ -35,7 +35,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { objectFactories[Convex::class] = ThreeConvexFactory objectFactories[Sphere::class] = ThreeSphereFactory objectFactories[ConeSegment::class] = ThreeConeFactory - objectFactories[PolyLine::class] = ThreeLineFactory + objectFactories[PolyLine::class] = ThreeSmartLineFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory objectFactories[PointLightSource::class] = ThreePointLightFactory @@ -182,7 +182,7 @@ internal fun Object3D.getOrCreateGroup(name: Name): Object3D { name.isEmpty() -> this name.length == 1 -> { val token = name.tokens.first() - children.find { it.name == token.toString() } ?: info.laht.threekt.objects.Group().also { group -> + children.find { it.name == token.toString() } ?: ThreeGroup().also { group -> group.name = token.toString() this.add(group) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt index 56df4b8b..fdd2e019 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt @@ -1,11 +1,11 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.lights.PointLight -import info.laht.threekt.math.Color import space.kscience.dataforge.names.asName import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.LightSource import space.kscience.visionforge.solid.PointLightSource +import three.lights.PointLight +import three.math.Color import kotlin.reflect.KClass public object ThreePointLightFactory : ThreeFactory { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index b0e1d69c..bde8c456 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -1,7 +1,5 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.Object3D -import info.laht.threekt.objects.Mesh import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.cutFirst import space.kscience.dataforge.names.firstOrNull @@ -9,6 +7,8 @@ import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX +import three.core.Object3D +import three.objects.Mesh import kotlin.reflect.KClass public object ThreeReferenceFactory : ThreeFactory { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt new file mode 100644 index 00000000..2e7329da --- /dev/null +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt @@ -0,0 +1,17 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.visionforge.solid.PolyLine +import three.core.Object3D +import kotlin.reflect.KClass + +public object ThreeSmartLineFactory : ThreeFactory { + override val type: KClass get() = PolyLine::class + + override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + return if (vision.thickness == 1.0) { + ThreeLineFactory.build(three, vision, observe) + } else { + ThreeMeshLineFactory.build(three, vision, observe) + } + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt index 9d4926c5..8022a09c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.geometries.SphereGeometry import space.kscience.visionforge.solid.Sphere import space.kscience.visionforge.solid.detail +import three.core.BufferGeometry +import three.geometries.SphereGeometry public object ThreeSphereFactory : ThreeMeshFactory(Sphere::class) { override fun buildGeometry(obj: Sphere): BufferGeometry { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt index ac2fefc0..940d72c3 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt @@ -10,10 +10,10 @@ @file:JsModule("three-csg-ts") @file:JsNonModule -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.math.Matrix4 -import info.laht.threekt.math.Vector3 -import info.laht.threekt.objects.Mesh +import three.core.BufferGeometry +import three.math.Matrix4 +import three.math.Vector3 +import three.objects.Mesh public external class CSG { public fun clone(): CSG diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt index 94262052..9c9d5b2b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt @@ -1,16 +1,16 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Layers -import info.laht.threekt.core.Object3D -import info.laht.threekt.external.controls.OrbitControls -import info.laht.threekt.materials.Material -import info.laht.threekt.math.Vector3 -import info.laht.threekt.objects.Mesh -import info.laht.threekt.textures.Texture import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.float import space.kscience.dataforge.meta.get +import three.core.BufferGeometry +import three.core.Layers +import three.core.Object3D +import three.external.controls.OrbitControls +import three.materials.Material +import three.math.Vector3 +import three.objects.Mesh +import three.textures.Texture import kotlin.contracts.contract import kotlin.math.PI diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/THREE.kt b/visionforge-threejs/src/main/kotlin/three/THREE.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/THREE.kt rename to visionforge-threejs/src/main/kotlin/three/THREE.kt index 3f8028cb..4dca1f62 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/THREE.kt +++ b/visionforge-threejs/src/main/kotlin/three/THREE.kt @@ -26,7 +26,7 @@ @file:JsNonModule @file:Suppress("NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "unused") -package info.laht.threekt +package three external val REVISION: String diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationAction.kt b/visionforge-threejs/src/main/kotlin/three/animation/AnimationAction.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationAction.kt rename to visionforge-threejs/src/main/kotlin/three/animation/AnimationAction.kt index d0e9b073..185793ff 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationAction.kt +++ b/visionforge-threejs/src/main/kotlin/three/animation/AnimationAction.kt @@ -2,9 +2,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation -import info.laht.threekt.core.Object3D +import three.core.Object3D external class AnimationAction( mixer: AnimationMixer, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationClip.kt b/visionforge-threejs/src/main/kotlin/three/animation/AnimationClip.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationClip.kt rename to visionforge-threejs/src/main/kotlin/three/animation/AnimationClip.kt index 262f02dc..dfb1df5a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationClip.kt +++ b/visionforge-threejs/src/main/kotlin/three/animation/AnimationClip.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation /** * An AnimationClip is a reusable set of keyframe tracks which represent an animation. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationMixer.kt b/visionforge-threejs/src/main/kotlin/three/animation/AnimationMixer.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationMixer.kt rename to visionforge-threejs/src/main/kotlin/three/animation/AnimationMixer.kt index 383f88f7..45932e59 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationMixer.kt +++ b/visionforge-threejs/src/main/kotlin/three/animation/AnimationMixer.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation -import info.laht.threekt.core.Object3D +import three.core.Object3D /** * The AnimationMixer is a player for animations on a particular object in the scene. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationUtils.kt b/visionforge-threejs/src/main/kotlin/three/animation/AnimationUtils.kt similarity index 71% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationUtils.kt rename to visionforge-threejs/src/main/kotlin/three/animation/AnimationUtils.kt index 34a9633b..c0e05b3a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationUtils.kt +++ b/visionforge-threejs/src/main/kotlin/three/animation/AnimationUtils.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation external object AnimationUtils { //TODO diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/KeyFrameTrack.kt b/visionforge-threejs/src/main/kotlin/three/animation/KeyFrameTrack.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/KeyFrameTrack.kt rename to visionforge-threejs/src/main/kotlin/three/animation/KeyFrameTrack.kt index 478fd1f6..2f3f3436 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/KeyFrameTrack.kt +++ b/visionforge-threejs/src/main/kotlin/three/animation/KeyFrameTrack.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation import org.khronos.webgl.Float32Array diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/Audio.kt b/visionforge-threejs/src/main/kotlin/three/audio/Audio.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/Audio.kt rename to visionforge-threejs/src/main/kotlin/three/audio/Audio.kt index f6266c41..95918ede 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/Audio.kt +++ b/visionforge-threejs/src/main/kotlin/three/audio/Audio.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.audio +package three.audio /** * Create a non-positional ( global ) audio object. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioContext.kt b/visionforge-threejs/src/main/kotlin/three/audio/AudioContext.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioContext.kt rename to visionforge-threejs/src/main/kotlin/three/audio/AudioContext.kt index 3bccd0ac..3908a548 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioContext.kt +++ b/visionforge-threejs/src/main/kotlin/three/audio/AudioContext.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.audio +package three.audio /** * This contains methods for setting up an AudioContext. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioListener.kt b/visionforge-threejs/src/main/kotlin/three/audio/AudioListener.kt similarity index 89% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioListener.kt rename to visionforge-threejs/src/main/kotlin/three/audio/AudioListener.kt index e99b9b13..cbdb06f1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioListener.kt +++ b/visionforge-threejs/src/main/kotlin/three/audio/AudioListener.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.audio +package three.audio -import info.laht.threekt.core.Object3D +import three.core.Object3D /** * Create a non-positional ( global ) audio object. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/PositionalAudio.kt b/visionforge-threejs/src/main/kotlin/three/audio/PositionalAudio.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/PositionalAudio.kt rename to visionforge-threejs/src/main/kotlin/three/audio/PositionalAudio.kt index 19c17bea..7c1006f4 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/PositionalAudio.kt +++ b/visionforge-threejs/src/main/kotlin/three/audio/PositionalAudio.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.audio +package three.audio /** * Create a positional audio object. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/Camera.kt b/visionforge-threejs/src/main/kotlin/three/cameras/Camera.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/Camera.kt rename to visionforge-threejs/src/main/kotlin/three/cameras/Camera.kt index 6ab80298..5f1ba54f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/Camera.kt +++ b/visionforge-threejs/src/main/kotlin/three/cameras/Camera.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.cameras +package three.cameras -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Matrix4 -import info.laht.threekt.math.Vector3 +import three.core.Object3D +import three.math.Matrix4 +import three.math.Vector3 external interface View { var enabled: Boolean diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/OrthographicCamera.kt b/visionforge-threejs/src/main/kotlin/three/cameras/OrthographicCamera.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/OrthographicCamera.kt rename to visionforge-threejs/src/main/kotlin/three/cameras/OrthographicCamera.kt index 320d71b5..706c8746 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/OrthographicCamera.kt +++ b/visionforge-threejs/src/main/kotlin/three/cameras/OrthographicCamera.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.cameras +package three.cameras external class OrthographicCamera( varleft: Int, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/PerspectiveCamera.kt b/visionforge-threejs/src/main/kotlin/three/cameras/PerspectiveCamera.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/PerspectiveCamera.kt rename to visionforge-threejs/src/main/kotlin/three/cameras/PerspectiveCamera.kt index 4deee300..a5b12de8 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/PerspectiveCamera.kt +++ b/visionforge-threejs/src/main/kotlin/three/cameras/PerspectiveCamera.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.cameras +package three.cameras external class PerspectiveCamera(fov: Int, aspect: Double, near: Number, far: Number) : Camera { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferAttribute.kt b/visionforge-threejs/src/main/kotlin/three/core/BufferAttribute.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferAttribute.kt rename to visionforge-threejs/src/main/kotlin/three/core/BufferAttribute.kt index 6a773330..e045b2d6 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferAttribute.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/BufferAttribute.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector2 -import info.laht.threekt.math.Vector3 -import info.laht.threekt.math.Vector4 +import three.math.Color +import three.math.Vector2 +import three.math.Vector3 +import three.math.Vector4 abstract external class BufferAttribute protected constructor( array: dynamic, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferGeometry.kt b/visionforge-threejs/src/main/kotlin/three/core/BufferGeometry.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/core/BufferGeometry.kt index 251627a7..5038aee7 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/BufferGeometry.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.math.Box3 -import info.laht.threekt.math.Matrix4 -import info.laht.threekt.math.Sphere -import info.laht.threekt.math.Vector3 +import three.math.Box3 +import three.math.Matrix4 +import three.math.Sphere +import three.math.Vector3 /** * This class is an efficient alternative to Geometry, because it stores all data, including vertex positions, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Clock.kt b/visionforge-threejs/src/main/kotlin/three/core/Clock.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Clock.kt rename to visionforge-threejs/src/main/kotlin/three/core/Clock.kt index 8cce902c..e5925f56 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Clock.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/Clock.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core /** * Object for keeping track of time. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/EventDispatcher.kt b/visionforge-threejs/src/main/kotlin/three/core/EventDispatcher.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/EventDispatcher.kt rename to visionforge-threejs/src/main/kotlin/three/core/EventDispatcher.kt index 459da88b..1646775e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/EventDispatcher.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/EventDispatcher.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core external open class EventDispatcher { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Face3.kt b/visionforge-threejs/src/main/kotlin/three/core/Face3.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Face3.kt rename to visionforge-threejs/src/main/kotlin/three/core/Face3.kt index ff48d022..a7ec7f0b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Face3.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/Face3.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector3 +import three.math.Color +import three.math.Vector3 external class Face3 { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/InstancedBufferGeometry.kt b/visionforge-threejs/src/main/kotlin/three/core/InstancedBufferGeometry.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/InstancedBufferGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/core/InstancedBufferGeometry.kt index 92137432..99c4df70 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/InstancedBufferGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/InstancedBufferGeometry.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core external class InstancedBufferGeometry : BufferGeometry { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Layers.kt b/visionforge-threejs/src/main/kotlin/three/core/Layers.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Layers.kt rename to visionforge-threejs/src/main/kotlin/three/core/Layers.kt index 503878d1..6d29399c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Layers.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/Layers.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core /** * A Layers object assigns an Object3D to 1 or more of 32 layers numbered 0 to 31 - internally the diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Object3D.kt b/visionforge-threejs/src/main/kotlin/three/core/Object3D.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Object3D.kt rename to visionforge-threejs/src/main/kotlin/three/core/Object3D.kt index e49add5e..86739f76 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Object3D.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/Object3D.kt @@ -26,9 +26,9 @@ @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.math.* +import three.math.* /** * This is the base class for most objects in three.js and provides a set of properties and methods for manipulating objects in 3D space. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Raycaster.kt b/visionforge-threejs/src/main/kotlin/three/core/Raycaster.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Raycaster.kt rename to visionforge-threejs/src/main/kotlin/three/core/Raycaster.kt index 2e2944af..e03844f6 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Raycaster.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/Raycaster.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.cameras.Camera -import info.laht.threekt.math.Ray -import info.laht.threekt.math.Vector2 -import info.laht.threekt.math.Vector3 +import three.cameras.Camera +import three.math.Ray +import three.math.Vector2 +import three.math.Vector3 external interface Params { var Mesh: dynamic diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Uniform.kt b/visionforge-threejs/src/main/kotlin/three/core/Uniform.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Uniform.kt rename to visionforge-threejs/src/main/kotlin/three/core/Uniform.kt index a92cdf2a..a2bef114 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Uniform.kt +++ b/visionforge-threejs/src/main/kotlin/three/core/Uniform.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core external class Uniform { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/Detector.kt b/visionforge-threejs/src/main/kotlin/three/external/Detector.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/Detector.kt rename to visionforge-threejs/src/main/kotlin/three/external/Detector.kt index 716e5d74..3dc1ed28 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/Detector.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/Detector.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external +package three.external import org.w3c.dom.Element diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/ImprovedNoise.kt b/visionforge-threejs/src/main/kotlin/three/external/ImprovedNoise.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/ImprovedNoise.kt rename to visionforge-threejs/src/main/kotlin/three/external/ImprovedNoise.kt index bc380022..4ee3942d 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/ImprovedNoise.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/ImprovedNoise.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external +package three.external external object ImprovedNoise { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/SimplexNoise.kt b/visionforge-threejs/src/main/kotlin/three/external/SimplexNoise.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/SimplexNoise.kt rename to visionforge-threejs/src/main/kotlin/three/external/SimplexNoise.kt index f8ab5a82..6856c354 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/SimplexNoise.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/SimplexNoise.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external +package three.external external object SimplexNoise { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/FlyControls.kt b/visionforge-threejs/src/main/kotlin/three/external/controls/FlyControls.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/FlyControls.kt rename to visionforge-threejs/src/main/kotlin/three/external/controls/FlyControls.kt index 11e25207..77de67e0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/FlyControls.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/controls/FlyControls.kt @@ -25,10 +25,10 @@ @file:JsModule("three/examples/jsm/controls/FlyControls.js") @file:JsNonModule -package info.laht.threekt.external.controls +package three.external.controls -import info.laht.threekt.core.Object3D import org.w3c.dom.Node +import three.core.Object3D external class FlyControls(`object`: Object3D, domElement: Node = definedExternally) { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/OrbitControls.kt b/visionforge-threejs/src/main/kotlin/three/external/controls/OrbitControls.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/OrbitControls.kt rename to visionforge-threejs/src/main/kotlin/three/external/controls/OrbitControls.kt index db7f2ac9..94223fc4 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/OrbitControls.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/controls/OrbitControls.kt @@ -25,11 +25,11 @@ @file:JsModule("three/examples/jsm/controls/OrbitControls.js") @file:JsNonModule -package info.laht.threekt.external.controls +package three.external.controls -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Vector3 import org.w3c.dom.Node +import three.core.Object3D +import three.math.Vector3 /** * This set of controls performs orbiting, dollying (zooming), and panning. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TrackballControls.kt b/visionforge-threejs/src/main/kotlin/three/external/controls/TrackballControls.kt similarity index 90% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TrackballControls.kt rename to visionforge-threejs/src/main/kotlin/three/external/controls/TrackballControls.kt index b128553e..64998dc2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TrackballControls.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/controls/TrackballControls.kt @@ -9,13 +9,13 @@ @file:JsModule("three/examples/jsm/controls/TrackballControls.js") @file:JsNonModule -package info.laht.threekt.external.controls +package three.external.controls -import info.laht.threekt.cameras.Camera -import info.laht.threekt.core.EventDispatcher -import info.laht.threekt.math.Vector3 import org.w3c.dom.HTMLElement import org.w3c.dom.Node +import three.cameras.Camera +import three.core.EventDispatcher +import three.math.Vector3 external interface `T$0` { var left: Number diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TransformControls.kt b/visionforge-threejs/src/main/kotlin/three/external/controls/TransformControls.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TransformControls.kt rename to visionforge-threejs/src/main/kotlin/three/external/controls/TransformControls.kt index 0a1c7a43..e03da682 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TransformControls.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/controls/TransformControls.kt @@ -25,10 +25,10 @@ @file:JsModule("three/examples/jsm/controls/TransformControls.js") @file:JsNonModule -package info.laht.threekt.external.controls +package three.external.controls -import info.laht.threekt.core.Object3D import org.w3c.dom.Node +import three.core.Object3D external class TransformControls(`object`: Object3D, domElement: Node = definedExternally) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/OBJExporter.kt b/visionforge-threejs/src/main/kotlin/three/external/exporters/OBJExporter.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/OBJExporter.kt rename to visionforge-threejs/src/main/kotlin/three/external/exporters/OBJExporter.kt index 36eefa9f..843a9f72 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/OBJExporter.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/exporters/OBJExporter.kt @@ -25,9 +25,9 @@ @file:JsModule("three/examples/jsm/exporters/OBJExporter.js") @file:JsNonModule -package info.laht.threekt.external.exporters +package three.external.exporters -import info.laht.threekt.core.Object3D +import three.core.Object3D external class OBJExporter { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/STLExporter.kt b/visionforge-threejs/src/main/kotlin/three/external/exporters/STLExporter.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/STLExporter.kt rename to visionforge-threejs/src/main/kotlin/three/external/exporters/STLExporter.kt index 4c6e3fb1..a89c1179 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/STLExporter.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/exporters/STLExporter.kt @@ -25,10 +25,10 @@ @file:JsModule("three/examples/jsm/exporters/STLExporter.js") @file:JsNonModule -package info.laht.threekt.external.exporters +package three.external.exporters -import info.laht.threekt.core.Object3D import org.khronos.webgl.DataView +import three.core.Object3D external class STLExporter { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/geometries/ConvexGeometry.kt b/visionforge-threejs/src/main/kotlin/three/external/geometries/ConvexGeometry.kt similarity index 64% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/geometries/ConvexGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/external/geometries/ConvexGeometry.kt index cbc0fbb5..6c981460 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/geometries/ConvexGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/geometries/ConvexGeometry.kt @@ -1,10 +1,10 @@ @file:JsModule("three/examples/jsm/geometries/ConvexGeometry.js") @file:JsNonModule -package info.laht.threekt.external.geometries +package three.external.geometries -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.math.Vector3 +import three.core.BufferGeometry +import three.math.Vector3 external class ConvexGeometry(points: Array) : BufferGeometry diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/GUIParams.kt b/visionforge-threejs/src/main/kotlin/three/external/libs/GUIParams.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/GUIParams.kt rename to visionforge-threejs/src/main/kotlin/three/external/libs/GUIParams.kt index 13d08a29..4b48bcc2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/GUIParams.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/libs/GUIParams.kt @@ -1,4 +1,4 @@ -package info.laht.threekt.external.libs +package three.external.libs /** * @param name The name of this GUI diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/Stats.kt b/visionforge-threejs/src/main/kotlin/three/external/libs/Stats.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/Stats.kt rename to visionforge-threejs/src/main/kotlin/three/external/libs/Stats.kt index a6c2e86f..fd72886e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/Stats.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/libs/Stats.kt @@ -25,7 +25,7 @@ @file:JsModule("three/examples/jsm/libs/stats.module.js") @file:JsNonModule -package info.laht.threekt.external.libs +package three.external.libs import org.w3c.dom.Node diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/datgui.kt b/visionforge-threejs/src/main/kotlin/three/external/libs/datgui.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/datgui.kt rename to visionforge-threejs/src/main/kotlin/three/external/libs/datgui.kt index c3496ea0..345d0cf5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/datgui.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/libs/datgui.kt @@ -24,7 +24,7 @@ @file:JsModule("three/examples/jsm/libs/dat.gui.module.js") @file:JsNonModule -package info.laht.threekt.external.libs +package three.external.libs import org.w3c.dom.Element diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/BabylonLoader.kt b/visionforge-threejs/src/main/kotlin/three/external/loaders/BabylonLoader.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/BabylonLoader.kt rename to visionforge-threejs/src/main/kotlin/three/external/loaders/BabylonLoader.kt index 2eae2988..437beba6 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/BabylonLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/loaders/BabylonLoader.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.core.Object3D -import info.laht.threekt.loaders.LoadingManager import org.w3c.xhr.XMLHttpRequest +import three.core.Object3D +import three.loaders.LoadingManager external class BabylonLoader( manager: LoadingManager = definedExternally diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/GLTFLoader.kt b/visionforge-threejs/src/main/kotlin/three/external/loaders/GLTFLoader.kt similarity index 89% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/GLTFLoader.kt rename to visionforge-threejs/src/main/kotlin/three/external/loaders/GLTFLoader.kt index e353372e..40fdd556 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/GLTFLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/loaders/GLTFLoader.kt @@ -1,14 +1,14 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.animation.AnimationClip -import info.laht.threekt.cameras.Camera -import info.laht.threekt.loaders.LoadingManager -import info.laht.threekt.scenes.Scene import org.khronos.webgl.ArrayBuffer import org.w3c.xhr.XMLHttpRequest +import three.animation.AnimationClip +import three.cameras.Camera +import three.loaders.LoadingManager +import three.scenes.Scene external interface GLTFOnLoadCallback { val animations: Array diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/LoaderSupport.kt b/visionforge-threejs/src/main/kotlin/three/external/loaders/LoaderSupport.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/LoaderSupport.kt rename to visionforge-threejs/src/main/kotlin/three/external/loaders/LoaderSupport.kt index de1bafcd..5636fdc9 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/LoaderSupport.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/loaders/LoaderSupport.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders external object LoaderSupport { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/MTLLoader.kt b/visionforge-threejs/src/main/kotlin/three/external/loaders/MTLLoader.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/MTLLoader.kt rename to visionforge-threejs/src/main/kotlin/three/external/loaders/MTLLoader.kt index 9af877f5..1eecd588 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/MTLLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/loaders/MTLLoader.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.core.Object3D -import info.laht.threekt.loaders.LoadingManager import org.w3c.xhr.XMLHttpRequest +import three.core.Object3D +import three.loaders.LoadingManager external class MTLLoader( loadingManager: LoadingManager = definedExternally diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader.kt b/visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader.kt rename to visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader.kt index ff4f2150..0bddd83a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.core.Object3D -import info.laht.threekt.loaders.LoadingManager -import info.laht.threekt.objects.Mesh import org.w3c.xhr.XMLHttpRequest +import three.core.Object3D +import three.loaders.LoadingManager +import three.objects.Mesh /** * A loader for loading a .obj resource. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader2.kt b/visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader2.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader2.kt rename to visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader2.kt index 009e5e81..e12ad3fe 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader2.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader2.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.loaders.LoadingManager -import info.laht.threekt.objects.Mesh import org.w3c.xhr.XMLHttpRequest +import three.loaders.LoadingManager +import three.objects.Mesh external interface Detail { var loaderRootNode: Mesh diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/STLLoader.kt b/visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/STLLoader.kt rename to visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt index 707fdc0c..5fa253ab 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/STLLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D import org.w3c.xhr.XMLHttpRequest +import three.core.BufferGeometry +import three.core.Object3D external class STLLoader { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Sky.kt b/visionforge-threejs/src/main/kotlin/three/external/objects/Sky.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Sky.kt rename to visionforge-threejs/src/main/kotlin/three/external/objects/Sky.kt index 47ad39ef..c7272138 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Sky.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/objects/Sky.kt @@ -25,8 +25,8 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.objects +package three.external.objects -import info.laht.threekt.objects.Mesh +import three.objects.Mesh external class Sky : Mesh \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Water.kt b/visionforge-threejs/src/main/kotlin/three/external/objects/Water.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Water.kt rename to visionforge-threejs/src/main/kotlin/three/external/objects/Water.kt index 9ad3f043..9a886a95 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Water.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/objects/Water.kt @@ -25,8 +25,8 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.objects +package three.external.objects -import info.laht.threekt.objects.Mesh +import three.objects.Mesh external class Water(width: Int, height: Int, options: WaterOptions = definedExternally) : Mesh \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/WaterOptions.kt b/visionforge-threejs/src/main/kotlin/three/external/objects/WaterOptions.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/WaterOptions.kt rename to visionforge-threejs/src/main/kotlin/three/external/objects/WaterOptions.kt index 74434846..498f9883 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/WaterOptions.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/objects/WaterOptions.kt @@ -22,10 +22,10 @@ * THE SOFTWARE. */ -package info.laht.threekt.external.objects +package three.external.objects -import info.laht.threekt.math.Vector3 -import info.laht.threekt.textures.Texture +import three.math.Vector3 +import three.textures.Texture data class WaterOptions( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/SceneUtils.kt b/visionforge-threejs/src/main/kotlin/three/extras/SceneUtils.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/SceneUtils.kt rename to visionforge-threejs/src/main/kotlin/three/extras/SceneUtils.kt index fb4338fd..1ad837d0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/SceneUtils.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/SceneUtils.kt @@ -1,13 +1,13 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras +package three.extras -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.materials.Material -import info.laht.threekt.objects.Group -import info.laht.threekt.scenes.Scene +import three.core.BufferGeometry +import three.core.Object3D +import three.materials.Material +import three.objects.Group +import three.scenes.Scene /** * A class containing useful utility functions for scene manipulation. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Curve.kt b/visionforge-threejs/src/main/kotlin/three/extras/core/Curve.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Curve.kt rename to visionforge-threejs/src/main/kotlin/three/extras/core/Curve.kt index f5a8ced6..4b688b1a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Curve.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/core/Curve.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.core +package three.extras.core external abstract class Curve { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/CurvePath.kt b/visionforge-threejs/src/main/kotlin/three/extras/core/CurvePath.kt similarity index 89% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/CurvePath.kt rename to visionforge-threejs/src/main/kotlin/three/extras/core/CurvePath.kt index 18ae2165..5a05ab14 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/CurvePath.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/core/CurvePath.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.core +package three.extras.core open external class CurvePath : Curve { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Path.kt b/visionforge-threejs/src/main/kotlin/three/extras/core/Path.kt similarity index 62% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Path.kt rename to visionforge-threejs/src/main/kotlin/three/extras/core/Path.kt index 7b944a7c..bd78a31d 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Path.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/core/Path.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.core +package three.extras.core -import info.laht.threekt.math.Vector2 +import three.math.Vector2 open external class Path : CurvePath { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Shape.kt b/visionforge-threejs/src/main/kotlin/three/extras/core/Shape.kt similarity index 55% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Shape.kt rename to visionforge-threejs/src/main/kotlin/three/extras/core/Shape.kt index 0b584f1f..d05486b5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Shape.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/core/Shape.kt @@ -1,8 +1,8 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.core +package three.extras.core -import info.laht.threekt.math.Vector2 +import three.math.Vector2 external class Shape(points: Array) : Path \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/ShapePath.kt b/visionforge-threejs/src/main/kotlin/three/extras/core/ShapePath.kt similarity index 64% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/ShapePath.kt rename to visionforge-threejs/src/main/kotlin/three/extras/core/ShapePath.kt index bd6e69b9..5ea28758 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/ShapePath.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/core/ShapePath.kt @@ -1,6 +1,6 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.core +package three.extras.core external class ShapePath \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/ArcCurve.kt b/visionforge-threejs/src/main/kotlin/three/extras/curves/ArcCurve.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/ArcCurve.kt rename to visionforge-threejs/src/main/kotlin/three/extras/curves/ArcCurve.kt index a6f2d172..c3891ff1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/ArcCurve.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/curves/ArcCurve.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves external class ArcCurve( aX: Number = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/CatmullRomCurve3.kt b/visionforge-threejs/src/main/kotlin/three/extras/curves/CatmullRomCurve3.kt similarity index 79% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/CatmullRomCurve3.kt rename to visionforge-threejs/src/main/kotlin/three/extras/curves/CatmullRomCurve3.kt index 93a5d931..e968cfb0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/CatmullRomCurve3.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/curves/CatmullRomCurve3.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector3 +import three.extras.core.Curve +import three.math.Vector3 external class CatmullRomCurve3( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/EllipseCurve.kt b/visionforge-threejs/src/main/kotlin/three/extras/curves/EllipseCurve.kt similarity index 85% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/EllipseCurve.kt rename to visionforge-threejs/src/main/kotlin/three/extras/curves/EllipseCurve.kt index d3ead4c5..dbcaec3f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/EllipseCurve.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/curves/EllipseCurve.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector2 +import three.extras.core.Curve +import three.math.Vector2 open external class EllipseCurve( aX: Number = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve.kt b/visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve.kt similarity index 67% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve.kt rename to visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve.kt index ca9dc41b..74c2d239 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector2 +import three.extras.core.Curve +import three.math.Vector2 external class LineCurve( v1: Vector2 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve3.kt b/visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve3.kt similarity index 67% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve3.kt rename to visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve3.kt index 90218d60..68f14b72 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve3.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve3.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector3 +import three.extras.core.Curve +import three.math.Vector3 external class LineCurve3( v1: Vector3 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve.kt b/visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve.kt similarity index 74% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve.kt rename to visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve.kt index aa7b2a95..849b41c0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector2 +import three.extras.core.Curve +import three.math.Vector2 external class QuadricBezierCurve : Curve { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve3.kt b/visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve3.kt similarity index 74% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve3.kt rename to visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve3.kt index b4b30426..0da5444f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve3.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve3.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector3 +import three.extras.core.Curve +import three.math.Vector3 external class QuadricBezierCurve3 : Curve { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/SplineCurve.kt b/visionforge-threejs/src/main/kotlin/three/extras/curves/SplineCurve.kt similarity index 68% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/SplineCurve.kt rename to visionforge-threejs/src/main/kotlin/three/extras/curves/SplineCurve.kt index df3fb8cd..357cf50f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/SplineCurve.kt +++ b/visionforge-threejs/src/main/kotlin/three/extras/curves/SplineCurve.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector2 +import three.extras.core.Curve +import three.math.Vector2 external class SplineCurve( points: Array = definedExternally diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/BoxGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/BoxGeometry.kt similarity index 77% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/BoxGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/BoxGeometry.kt index 8d0e5ec5..d80a96a2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/BoxGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/BoxGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class BoxGeometry( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ConeGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/ConeGeometry.kt similarity index 82% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ConeGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/ConeGeometry.kt index f98ad2dd..7492d5ec 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ConeGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/ConeGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class ConeGeometry( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/CylinderGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/CylinderGeometry.kt similarity index 82% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/CylinderGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/CylinderGeometry.kt index b10e5c11..f2f1160c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/CylinderGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/CylinderGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class CylinderGeometry( radiusTop: Number, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/EdgesGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/EdgesGeometry.kt similarity index 66% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/EdgesGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/EdgesGeometry.kt index b0a5c91b..fe53213e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/EdgesGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/EdgesGeometry.kt @@ -1,8 +1,8 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry public external class EdgesGeometry(geometry: BufferGeometry, thresholdAngle: Int = definedExternally) : BufferGeometry \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ExtrudeGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/ExtrudeGeometry.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ExtrudeGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/ExtrudeGeometry.kt index 4b30e7af..5c256878 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ExtrudeGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/ExtrudeGeometry.kt @@ -8,11 +8,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.extras.core.Shape -import info.laht.threekt.math.Vector2 +import three.core.BufferGeometry +import three.extras.core.Shape +import three.math.Vector2 external interface ExtrudeGeometryOptions { var curveSegments: Number? diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/PlaneGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/PlaneGeometry.kt similarity index 73% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/PlaneGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/PlaneGeometry.kt index 0b1072ef..aff535a2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/PlaneGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/PlaneGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class PlaneGeometry( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/SphereGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/SphereGeometry.kt similarity index 82% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/SphereGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/SphereGeometry.kt index 5b0c9fc6..2b9e5279 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/SphereGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/SphereGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class SphereGeometry( radius: Number, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TextGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/TextGeometry.kt similarity index 96% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TextGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/TextGeometry.kt index b8c935f3..aab53955 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TextGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/TextGeometry.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries external interface TextGeometryParameters { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TorusGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/TorusGeometry.kt similarity index 78% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TorusGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/TorusGeometry.kt index 0a53525f..493b7984 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TorusGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/TorusGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class TorusGeometry( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TubeGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/TubeGeometry.kt similarity index 73% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TubeGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/TubeGeometry.kt index 36afa6ae..e1dc9a75 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TubeGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/TubeGeometry.kt @@ -1,8 +1,8 @@ -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector3 +import three.core.BufferGeometry +import three.extras.core.Curve +import three.math.Vector3 /** diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/WireframeGeometry.kt b/visionforge-threejs/src/main/kotlin/three/geometries/WireframeGeometry.kt similarity index 71% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/WireframeGeometry.kt rename to visionforge-threejs/src/main/kotlin/three/geometries/WireframeGeometry.kt index f52c61cc..622ef80d 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/WireframeGeometry.kt +++ b/visionforge-threejs/src/main/kotlin/three/geometries/WireframeGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry /** * This can be used as a helper object to view a Geometry object as a wireframe. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/ArrowHelper.kt b/visionforge-threejs/src/main/kotlin/three/helpers/ArrowHelper.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/ArrowHelper.kt rename to visionforge-threejs/src/main/kotlin/three/helpers/ArrowHelper.kt index ea1764dd..18c0d8de 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/ArrowHelper.kt +++ b/visionforge-threejs/src/main/kotlin/three/helpers/ArrowHelper.kt @@ -25,13 +25,13 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector3 -import info.laht.threekt.objects.Line -import info.laht.threekt.objects.Mesh +import three.core.Object3D +import three.math.Color +import three.math.Vector3 +import three.objects.Line +import three.objects.Mesh external class ArrowHelper( dir: Vector3, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/AxesHelper.kt b/visionforge-threejs/src/main/kotlin/three/helpers/AxesHelper.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/AxesHelper.kt rename to visionforge-threejs/src/main/kotlin/three/helpers/AxesHelper.kt index d4b515be..5927991f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/AxesHelper.kt +++ b/visionforge-threejs/src/main/kotlin/three/helpers/AxesHelper.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.objects.LineSegments +import three.objects.LineSegments external class AxesHelper( size: Int = definedExternally diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/Box3Helper.kt b/visionforge-threejs/src/main/kotlin/three/helpers/Box3Helper.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/Box3Helper.kt rename to visionforge-threejs/src/main/kotlin/three/helpers/Box3Helper.kt index 27aef631..1eefb43b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/Box3Helper.kt +++ b/visionforge-threejs/src/main/kotlin/three/helpers/Box3Helper.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.math.Box3 -import info.laht.threekt.objects.LineSegments +import three.math.Box3 +import three.objects.LineSegments /** * Helper object to visualize a Box3. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/CameraHelper.kt b/visionforge-threejs/src/main/kotlin/three/helpers/CameraHelper.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/CameraHelper.kt rename to visionforge-threejs/src/main/kotlin/three/helpers/CameraHelper.kt index 6b199f3f..716f8234 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/CameraHelper.kt +++ b/visionforge-threejs/src/main/kotlin/three/helpers/CameraHelper.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.cameras.Camera -import info.laht.threekt.objects.LineSegments +import three.cameras.Camera +import three.objects.LineSegments external class CameraHelper( camera: Camera diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/GridHelper.kt b/visionforge-threejs/src/main/kotlin/three/helpers/GridHelper.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/GridHelper.kt rename to visionforge-threejs/src/main/kotlin/three/helpers/GridHelper.kt index 0d987ae5..0c080ead 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/GridHelper.kt +++ b/visionforge-threejs/src/main/kotlin/three/helpers/GridHelper.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.objects.LineSegments +import three.objects.LineSegments external class GridHelper( size: Int = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/HemisphereLightHelper.kt b/visionforge-threejs/src/main/kotlin/three/helpers/HemisphereLightHelper.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/HemisphereLightHelper.kt rename to visionforge-threejs/src/main/kotlin/three/helpers/HemisphereLightHelper.kt index 4351faa7..23f21837 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/HemisphereLightHelper.kt +++ b/visionforge-threejs/src/main/kotlin/three/helpers/HemisphereLightHelper.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.core.Object3D -import info.laht.threekt.lights.HemisphereLight -import info.laht.threekt.lights.Light +import three.core.Object3D +import three.lights.HemisphereLight +import three.lights.Light /** * Creates a visual aid consisting of a spherical Mesh for a HemisphereLight. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/PlaneHelper.kt b/visionforge-threejs/src/main/kotlin/three/helpers/PlaneHelper.kt similarity index 59% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/PlaneHelper.kt rename to visionforge-threejs/src/main/kotlin/three/helpers/PlaneHelper.kt index dbe6dc8d..338c9593 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/PlaneHelper.kt +++ b/visionforge-threejs/src/main/kotlin/three/helpers/PlaneHelper.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.math.Color -import info.laht.threekt.math.Plane -import info.laht.threekt.objects.LineSegments +import three.math.Color +import three.math.Plane +import three.objects.LineSegments /** * Helper object to visualize a [Plane]. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/ktutils.kt b/visionforge-threejs/src/main/kotlin/three/ktutils.kt similarity index 55% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/ktutils.kt rename to visionforge-threejs/src/main/kotlin/three/ktutils.kt index a0ef343e..d0735c84 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/ktutils.kt +++ b/visionforge-threejs/src/main/kotlin/three/ktutils.kt @@ -1,9 +1,9 @@ @file:Suppress("FunctionName") -package info.laht.threekt +package three -import info.laht.threekt.renderers.WebGLRenderer -import info.laht.threekt.renderers.WebGLRendererParams +import three.renderers.WebGLRenderer +import three.renderers.WebGLRendererParams fun WebGLRenderer(builder: WebGLRendererParams.() -> Unit): WebGLRenderer = WebGLRenderer(WebGLRendererParams().apply(builder)) \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/AmbientLight.kt b/visionforge-threejs/src/main/kotlin/three/lights/AmbientLight.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/AmbientLight.kt rename to visionforge-threejs/src/main/kotlin/three/lights/AmbientLight.kt index 0d2cae66..b5ddd88d 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/AmbientLight.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/AmbientLight.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights /** * This light globally illuminates all objects in the scene equally. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLight.kt b/visionforge-threejs/src/main/kotlin/three/lights/DirectionalLight.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLight.kt rename to visionforge-threejs/src/main/kotlin/three/lights/DirectionalLight.kt index f85d3e24..482fd628 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLight.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/DirectionalLight.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.core.Object3D +import three.core.Object3D external class DirectionalLight( color: Int = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLightShadow.kt b/visionforge-threejs/src/main/kotlin/three/lights/DirectionalLightShadow.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLightShadow.kt rename to visionforge-threejs/src/main/kotlin/three/lights/DirectionalLightShadow.kt index e2886e0b..205c46bb 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLightShadow.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/DirectionalLightShadow.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights external class DirectionalLightShadow : LightShadow { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/HemisphereLight.kt b/visionforge-threejs/src/main/kotlin/three/lights/HemisphereLight.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/HemisphereLight.kt rename to visionforge-threejs/src/main/kotlin/three/lights/HemisphereLight.kt index c98fbd5d..bf761479 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/HemisphereLight.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/HemisphereLight.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.math.Color +import three.math.Color /** * A light source positioned directly above the scene, with color fading from the sky color to the ground color. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/Light.kt b/visionforge-threejs/src/main/kotlin/three/lights/Light.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/Light.kt rename to visionforge-threejs/src/main/kotlin/three/lights/Light.kt index 6ffd9a2d..d0c07d15 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/Light.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/Light.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Color +import three.core.Object3D +import three.math.Color /** * Abstract base class for lights - all other light types inherit the properties and methods described here. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/LightShadow.kt b/visionforge-threejs/src/main/kotlin/three/lights/LightShadow.kt similarity index 90% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/LightShadow.kt rename to visionforge-threejs/src/main/kotlin/three/lights/LightShadow.kt index ef62b843..b7fc1f12 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/LightShadow.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/LightShadow.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.cameras.Camera -import info.laht.threekt.math.Matrix4 -import info.laht.threekt.math.Vector2 +import three.cameras.Camera +import three.math.Matrix4 +import three.math.Vector2 open external class LightShadow(camera: Camera) { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/PointLight.kt b/visionforge-threejs/src/main/kotlin/three/lights/PointLight.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/PointLight.kt rename to visionforge-threejs/src/main/kotlin/three/lights/PointLight.kt index 6a708e58..9ff6627a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/PointLight.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/PointLight.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights external class PointLight( color: Int = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLight.kt b/visionforge-threejs/src/main/kotlin/three/lights/SpotLight.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLight.kt rename to visionforge-threejs/src/main/kotlin/three/lights/SpotLight.kt index 70c14e6a..ebd422f7 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLight.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/SpotLight.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.core.Object3D +import three.core.Object3D external class SpotLight( color: Int = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLightShadow.kt b/visionforge-threejs/src/main/kotlin/three/lights/SpotLightShadow.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLightShadow.kt rename to visionforge-threejs/src/main/kotlin/three/lights/SpotLightShadow.kt index 8d8e052f..14df1315 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLightShadow.kt +++ b/visionforge-threejs/src/main/kotlin/three/lights/SpotLightShadow.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights external class SpotLightShadow : LightShadow { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Cache.kt b/visionforge-threejs/src/main/kotlin/three/loaders/Cache.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Cache.kt rename to visionforge-threejs/src/main/kotlin/three/loaders/Cache.kt index 1424d8e7..38278cf1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Cache.kt +++ b/visionforge-threejs/src/main/kotlin/three/loaders/Cache.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders external object Cache { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/CompressedTextureLoader.kt b/visionforge-threejs/src/main/kotlin/three/loaders/CompressedTextureLoader.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/CompressedTextureLoader.kt rename to visionforge-threejs/src/main/kotlin/three/loaders/CompressedTextureLoader.kt index 889c5d18..d827d4a5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/CompressedTextureLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/loaders/CompressedTextureLoader.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders -import info.laht.threekt.textures.Texture import org.w3c.xhr.XMLHttpRequest +import three.textures.Texture /** * Abstract base class for block based textures loader (dds, pvr, ...). diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/ImageLoader.kt b/visionforge-threejs/src/main/kotlin/three/loaders/ImageLoader.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/ImageLoader.kt rename to visionforge-threejs/src/main/kotlin/three/loaders/ImageLoader.kt index ade47d72..555f268b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/ImageLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/loaders/ImageLoader.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders import org.w3c.dom.Element import org.w3c.xhr.XMLHttpRequest diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/JSONLoader.kt b/visionforge-threejs/src/main/kotlin/three/loaders/JSONLoader.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/JSONLoader.kt rename to visionforge-threejs/src/main/kotlin/three/loaders/JSONLoader.kt index db38edb6..8871b540 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/JSONLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/loaders/JSONLoader.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.materials.Material import org.w3c.xhr.XMLHttpRequest +import three.core.BufferGeometry +import three.core.Object3D +import three.materials.Material /** * A loader for loading objects in JSON format. This uses the FileLoader internally for loading files. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Loader.kt b/visionforge-threejs/src/main/kotlin/three/loaders/Loader.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Loader.kt rename to visionforge-threejs/src/main/kotlin/three/loaders/Loader.kt index 2d60ee93..d094b6d9 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Loader.kt +++ b/visionforge-threejs/src/main/kotlin/three/loaders/Loader.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders /** * Base class for implementing loaders. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/LoadingManager.kt b/visionforge-threejs/src/main/kotlin/three/loaders/LoadingManager.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/LoadingManager.kt rename to visionforge-threejs/src/main/kotlin/three/loaders/LoadingManager.kt index ebf5d2bc..e9180dad 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/LoadingManager.kt +++ b/visionforge-threejs/src/main/kotlin/three/loaders/LoadingManager.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders external object DefaultLoadingManager : LoadingManager diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/MaterialLoader.kt b/visionforge-threejs/src/main/kotlin/three/loaders/MaterialLoader.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/MaterialLoader.kt rename to visionforge-threejs/src/main/kotlin/three/loaders/MaterialLoader.kt index ef30c71f..f294ffd5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/MaterialLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/loaders/MaterialLoader.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders -import info.laht.threekt.materials.Material -import info.laht.threekt.textures.Texture import org.w3c.xhr.XMLHttpRequest +import three.materials.Material +import three.textures.Texture external class MaterialLoader { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/TextureLoader.kt b/visionforge-threejs/src/main/kotlin/three/loaders/TextureLoader.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/TextureLoader.kt rename to visionforge-threejs/src/main/kotlin/three/loaders/TextureLoader.kt index 5d57ab88..5ddac48b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/TextureLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/loaders/TextureLoader.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders -import info.laht.threekt.textures.Texture import org.w3c.xhr.XMLHttpRequest +import three.textures.Texture /** * Class for loading a texture. This uses the ImageLoader internally for loading files. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineBasicMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/LineBasicMaterial.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineBasicMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/LineBasicMaterial.kt index 308e5a52..1445c427 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineBasicMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/LineBasicMaterial.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color +import three.math.Color open external class LineBasicMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineDashedMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/LineDashedMaterial.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineDashedMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/LineDashedMaterial.kt index 79ad5ada..aa2a5d6a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineDashedMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/LineDashedMaterial.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials external class LineDashedMaterial : LineBasicMaterial { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/Material.kt b/visionforge-threejs/src/main/kotlin/three/materials/Material.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/Material.kt rename to visionforge-threejs/src/main/kotlin/three/materials/Material.kt index 9a2b72d0..2edbca90 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/Material.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/Material.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials @JsName("Material") open external class Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshBasicMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/MeshBasicMaterial.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshBasicMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/MeshBasicMaterial.kt index 96eae5e0..f1ee1f27 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshBasicMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/MeshBasicMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.textures.Texture +import three.math.Color +import three.textures.Texture external class MeshBasicMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshDepthMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/MeshDepthMaterial.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshDepthMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/MeshDepthMaterial.kt index 185dce93..584bcab6 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshDepthMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/MeshDepthMaterial.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.textures.Texture +import three.textures.Texture external class MeshDepthMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshLambertMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/MeshLambertMaterial.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshLambertMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/MeshLambertMaterial.kt index dcd0670a..089c96c1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshLambertMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/MeshLambertMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.textures.Texture +import three.math.Color +import three.textures.Texture external class MeshLambertMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshNormalMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/MeshNormalMaterial.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshNormalMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/MeshNormalMaterial.kt index ea7c0960..5972a702 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshNormalMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/MeshNormalMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Vector2 -import info.laht.threekt.textures.Texture +import three.math.Vector2 +import three.textures.Texture external class MeshNormalMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhongMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/MeshPhongMaterial.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhongMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/MeshPhongMaterial.kt index 693ba8b4..eaabf8ca 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhongMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/MeshPhongMaterial.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector2 -import info.laht.threekt.textures.Texture +import three.math.Color +import three.math.Vector2 +import three.textures.Texture external class MeshPhongMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhysicalMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/MeshPhysicalMaterial.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhysicalMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/MeshPhysicalMaterial.kt index 42fef98f..e6674917 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhysicalMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/MeshPhysicalMaterial.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials external class MeshPhysicalMaterial : MeshStandardMaterial { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshStandardMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/MeshStandardMaterial.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshStandardMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/MeshStandardMaterial.kt index 19b6901e..137ee095 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshStandardMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/MeshStandardMaterial.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector2 -import info.laht.threekt.textures.Texture +import three.math.Color +import three.math.Vector2 +import three.textures.Texture open external class MeshStandardMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/PointsMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/PointsMaterial.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/PointsMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/PointsMaterial.kt index bb9c4bd8..a46fb65e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/PointsMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/PointsMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.textures.Texture +import three.math.Color +import three.textures.Texture external class PointsMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/RawShaderMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/RawShaderMaterial.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/RawShaderMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/RawShaderMaterial.kt index 2a096459..d1f53c16 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/RawShaderMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/RawShaderMaterial.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials external class RawShaderMaterial : ShaderMaterial { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/ShaderMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/ShaderMaterial.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/ShaderMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/ShaderMaterial.kt index 016520eb..3ca841db 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/ShaderMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/ShaderMaterial.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials open external class ShaderMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/SpriteMaterial.kt b/visionforge-threejs/src/main/kotlin/three/materials/SpriteMaterial.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/SpriteMaterial.kt rename to visionforge-threejs/src/main/kotlin/three/materials/SpriteMaterial.kt index 32056537..13587157 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/SpriteMaterial.kt +++ b/visionforge-threejs/src/main/kotlin/three/materials/SpriteMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.textures.Texture +import three.math.Color +import three.textures.Texture external class SpriteMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box2.kt b/visionforge-threejs/src/main/kotlin/three/math/Box2.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box2.kt rename to visionforge-threejs/src/main/kotlin/three/math/Box2.kt index c00da8eb..5b446e3c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box2.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Box2.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Box2( min: Vector2 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box3.kt b/visionforge-threejs/src/main/kotlin/three/math/Box3.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box3.kt rename to visionforge-threejs/src/main/kotlin/three/math/Box3.kt index a34622fa..25730ad2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box3.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Box3.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math -import info.laht.threekt.core.Object3D +import three.core.Object3D /** * Represents a box or cube in 3D space. The main purpose of this is to represent the Minimum Bounding Boxes for objects. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Color.kt b/visionforge-threejs/src/main/kotlin/three/math/Color.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Color.kt rename to visionforge-threejs/src/main/kotlin/three/math/Color.kt index 26a2a760..485d04f1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Color.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Color.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Color { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt b/visionforge-threejs/src/main/kotlin/three/math/ColorConstants.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt rename to visionforge-threejs/src/main/kotlin/three/math/ColorConstants.kt index 34475bd1..e60aba4a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/ColorConstants.kt @@ -23,7 +23,7 @@ */ -package info.laht.threekt.math +package three.math object ColorConstants { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Cylindrical.kt b/visionforge-threejs/src/main/kotlin/three/math/Cylindrical.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Cylindrical.kt rename to visionforge-threejs/src/main/kotlin/three/math/Cylindrical.kt index 9e0cd8ba..bee46185 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Cylindrical.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Cylindrical.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Cylindrical( radius: Number, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Euler.kt b/visionforge-threejs/src/main/kotlin/three/math/Euler.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Euler.kt rename to visionforge-threejs/src/main/kotlin/three/math/Euler.kt index 5b8dc1ce..5cd2f5cf 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Euler.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Euler.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Euler( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Frustrum.kt b/visionforge-threejs/src/main/kotlin/three/math/Frustrum.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Frustrum.kt rename to visionforge-threejs/src/main/kotlin/three/math/Frustrum.kt index cce6a0bc..8d6fe374 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Frustrum.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Frustrum.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Frustrum( p0: Plane = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Line3.kt b/visionforge-threejs/src/main/kotlin/three/math/Line3.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Line3.kt rename to visionforge-threejs/src/main/kotlin/three/math/Line3.kt index 6bb1b4e2..4596edd9 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Line3.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Line3.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Line3( start: Vector3 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Math.kt b/visionforge-threejs/src/main/kotlin/three/math/Math.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Math.kt rename to visionforge-threejs/src/main/kotlin/three/math/Math.kt index 9bae9dba..7a340d51 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Math.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Math.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Math { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix3.kt b/visionforge-threejs/src/main/kotlin/three/math/Matrix3.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix3.kt rename to visionforge-threejs/src/main/kotlin/three/math/Matrix3.kt index 6f31380b..f5ea461a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix3.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Matrix3.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math -import info.laht.threekt.core.BufferAttribute +import three.core.BufferAttribute external class Matrix3 { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix4.kt b/visionforge-threejs/src/main/kotlin/three/math/Matrix4.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix4.kt rename to visionforge-threejs/src/main/kotlin/three/math/Matrix4.kt index 49ed3bfe..20e03eae 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix4.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Matrix4.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry /** * A class representing a 4x4 matrix. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Plane.kt b/visionforge-threejs/src/main/kotlin/three/math/Plane.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Plane.kt rename to visionforge-threejs/src/main/kotlin/three/math/Plane.kt index 2848938d..41568fc8 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Plane.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Plane.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Plane() { constructor(normal: Vector3, constant: Double) diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Quaternion.kt b/visionforge-threejs/src/main/kotlin/three/math/Quaternion.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Quaternion.kt rename to visionforge-threejs/src/main/kotlin/three/math/Quaternion.kt index a3a0af8b..b1916723 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Quaternion.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Quaternion.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Quaternion( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Ray.kt b/visionforge-threejs/src/main/kotlin/three/math/Ray.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Ray.kt rename to visionforge-threejs/src/main/kotlin/three/math/Ray.kt index 731a3d2b..707985b9 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Ray.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Ray.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Ray { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Sphere.kt b/visionforge-threejs/src/main/kotlin/three/math/Sphere.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Sphere.kt rename to visionforge-threejs/src/main/kotlin/three/math/Sphere.kt index cbbc24c4..abea7add 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Sphere.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Sphere.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Sphere { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Spherical.kt b/visionforge-threejs/src/main/kotlin/three/math/Spherical.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Spherical.kt rename to visionforge-threejs/src/main/kotlin/three/math/Spherical.kt index 187dcd94..1596bd25 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Spherical.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Spherical.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Spherical { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Triangle.kt b/visionforge-threejs/src/main/kotlin/three/math/Triangle.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Triangle.kt rename to visionforge-threejs/src/main/kotlin/three/math/Triangle.kt index 9dd99c52..890d1f87 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Triangle.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Triangle.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Triangle( a: Vector3 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector2.kt b/visionforge-threejs/src/main/kotlin/three/math/Vector2.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector2.kt rename to visionforge-threejs/src/main/kotlin/three/math/Vector2.kt index 86049df0..c508421a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector2.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Vector2.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Vector2( x: Number = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector3.kt b/visionforge-threejs/src/main/kotlin/three/math/Vector3.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector3.kt rename to visionforge-threejs/src/main/kotlin/three/math/Vector3.kt index 85f1c74b..881bc586 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector3.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Vector3.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math -import info.laht.threekt.cameras.Camera +import three.cameras.Camera /** * Class representing a 3D vector. A 3D vector is an ordered triplet of numbers (labeled x, y, and z), which can be used to represent a number of things, such as: diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector4.kt b/visionforge-threejs/src/main/kotlin/three/math/Vector4.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector4.kt rename to visionforge-threejs/src/main/kotlin/three/math/Vector4.kt index f017f4d4..5bd672d5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector4.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/Vector4.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Vector4( x: Number = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/operators.kt b/visionforge-threejs/src/main/kotlin/three/math/operators.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/operators.kt rename to visionforge-threejs/src/main/kotlin/three/math/operators.kt index b30baf00..245cc83f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/operators.kt +++ b/visionforge-threejs/src/main/kotlin/three/math/operators.kt @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -package info.laht.threekt.math +package three.math operator fun Vector3.unaryMinus() = this.clone().negate() operator fun Vector3.plusAssign(v: Vector3) = this.let { add(v); Unit } diff --git a/visionforge-threejs/src/main/kotlin/three/meshline/MeshLine.kt b/visionforge-threejs/src/main/kotlin/three/meshline/MeshLine.kt new file mode 100644 index 00000000..21e0ce34 --- /dev/null +++ b/visionforge-threejs/src/main/kotlin/three/meshline/MeshLine.kt @@ -0,0 +1,37 @@ +@file:JsModule("three.meshline") +@file:JsNonModule + +package three.meshline + +import three.core.BufferGeometry +import three.materials.ShaderMaterial +import three.math.Color +import three.math.Vector3 +import three.textures.Texture + +/* + * https://github.com/spite/THREE.MeshLine + */ + +public external class MeshLine : BufferGeometry { + public fun setGeometry(geometry: BufferGeometry) + public fun setPoints(points: Array) +} + +public external class MeshLineMaterial : ShaderMaterial { + @JsName("lineWidth") + public var thickness: Float + public var color: Color + + public var map: Texture? + public var useMap: Boolean + public var alphaMap: Texture? + public var useAlphaMap: Boolean + + public var repeat: dynamic // - THREE.Vector2 to define the texture tiling (applies to map and alphaMap - MIGHT CHANGE IN THE FUTURE) + public var dashArray: dynamic //- the length and space between dashes. (0 - no dash) + public var dashOffset: dynamic // - defines the location where the dash will begin. Ideal to animate the line. + public var dashRatio: dynamic // - defines the ratio between that is visible or not (0 - more visible, 1 - more invisible). + public var resolution: dynamic // - THREE.Vector2 specifying the canvas size (REQUIRED) + public var sizeAttenuation: Int // - makes the line width constant regardless distance (1 unit is 1px on screen) (0 - attenuate, 1 - don't attenuate) +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt b/visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt new file mode 100644 index 00000000..a2bfa57a --- /dev/null +++ b/visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt @@ -0,0 +1,8 @@ +package three.meshline + +import three.core.BufferGeometry +import three.math.Vector3 + +public fun MeshLine(geometry: BufferGeometry): MeshLine = MeshLine().apply { setGeometry(geometry) } + +public fun MeshLine(points: Array): MeshLine = MeshLine().apply { setPoints(points) } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Group.kt b/visionforge-threejs/src/main/kotlin/three/objects/Group.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Group.kt rename to visionforge-threejs/src/main/kotlin/three/objects/Group.kt index e5420f29..a280a11f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Group.kt +++ b/visionforge-threejs/src/main/kotlin/three/objects/Group.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.Object3D +import three.core.Object3D external class Group : Object3D diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LOD.kt b/visionforge-threejs/src/main/kotlin/three/objects/LOD.kt similarity index 88% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LOD.kt rename to visionforge-threejs/src/main/kotlin/three/objects/LOD.kt index 89e405ac..4eec3195 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LOD.kt +++ b/visionforge-threejs/src/main/kotlin/three/objects/LOD.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.cameras.Camera -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster +import three.cameras.Camera +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster external class LOD : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Line.kt b/visionforge-threejs/src/main/kotlin/three/objects/Line.kt similarity index 85% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Line.kt rename to visionforge-threejs/src/main/kotlin/three/objects/Line.kt index e0a217bc..799884f8 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Line.kt +++ b/visionforge-threejs/src/main/kotlin/three/objects/Line.kt @@ -25,13 +25,13 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.materials.Material +import three.core.BufferGeometry +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster +import three.materials.Material open external class Line(geometry: BufferGeometry, material: Material) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineLoop.kt b/visionforge-threejs/src/main/kotlin/three/objects/LineLoop.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineLoop.kt rename to visionforge-threejs/src/main/kotlin/three/objects/LineLoop.kt index 50aa390e..e3e8cbc3 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineLoop.kt +++ b/visionforge-threejs/src/main/kotlin/three/objects/LineLoop.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.materials.Material +import three.core.BufferGeometry +import three.materials.Material external class LineLoop(geometry: BufferGeometry, material: Material) : Line \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineSegments.kt b/visionforge-threejs/src/main/kotlin/three/objects/LineSegments.kt similarity index 89% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineSegments.kt rename to visionforge-threejs/src/main/kotlin/three/objects/LineSegments.kt index 03bef34e..2ffd85ee 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineSegments.kt +++ b/visionforge-threejs/src/main/kotlin/three/objects/LineSegments.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.materials.Material +import three.core.BufferGeometry +import three.core.Object3D +import three.materials.Material open external class LineSegments(geometry: BufferGeometry, material: Material) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Mesh.kt b/visionforge-threejs/src/main/kotlin/three/objects/Mesh.kt similarity index 86% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Mesh.kt rename to visionforge-threejs/src/main/kotlin/three/objects/Mesh.kt index fc91e333..867b8000 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Mesh.kt +++ b/visionforge-threejs/src/main/kotlin/three/objects/Mesh.kt @@ -25,13 +25,13 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.materials.Material +import three.core.BufferGeometry +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster +import three.materials.Material open external class Mesh(geometry: BufferGeometry?, material: Material?) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Points.kt b/visionforge-threejs/src/main/kotlin/three/objects/Points.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Points.kt rename to visionforge-threejs/src/main/kotlin/three/objects/Points.kt index f296937a..7fede72c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Points.kt +++ b/visionforge-threejs/src/main/kotlin/three/objects/Points.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.materials.Material +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster +import three.materials.Material external class Points : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Sprite.kt b/visionforge-threejs/src/main/kotlin/three/objects/Sprite.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Sprite.kt rename to visionforge-threejs/src/main/kotlin/three/objects/Sprite.kt index 60e2d0de..c9e06bac 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Sprite.kt +++ b/visionforge-threejs/src/main/kotlin/three/objects/Sprite.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.materials.Material +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster +import three.materials.Material external class Sprite(material: Material = definedExternally) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2Renderer.kt b/visionforge-threejs/src/main/kotlin/three/renderers/WebGL2Renderer.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2Renderer.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/WebGL2Renderer.kt index 1c5208ad..7ca6120f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2Renderer.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/WebGL2Renderer.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers +package three.renderers -import info.laht.threekt.cameras.Camera -import info.laht.threekt.scenes.Scene +import three.cameras.Camera +import three.scenes.Scene external class WebGL2Renderer { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2RendererParams.kt b/visionforge-threejs/src/main/kotlin/three/renderers/WebGL2RendererParams.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2RendererParams.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/WebGL2RendererParams.kt index a2ef9eaf..8379d142 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2RendererParams.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/WebGL2RendererParams.kt @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -package info.laht.threekt.renderers +package three.renderers import org.w3c.dom.Node diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTarget.kt b/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTarget.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTarget.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTarget.kt index 08c44a36..2cbd272b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTarget.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTarget.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers +package three.renderers -import info.laht.threekt.math.Vector4 -import info.laht.threekt.textures.Texture +import three.math.Vector4 +import three.textures.Texture external class WebGLRenderTarget { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTargetOptions.kt b/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTargetOptions.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTargetOptions.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTargetOptions.kt index 4ba8b941..145431ce 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTargetOptions.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTargetOptions.kt @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -package info.laht.threekt.renderers +package three.renderers data class WebGLRenderTargetOptions( val wrapS: Int? = undefined, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderer.kt b/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderer.kt similarity index 96% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderer.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderer.kt index aa95f1ba..45fc212e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderer.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderer.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers +package three.renderers -import info.laht.threekt.cameras.Camera -import info.laht.threekt.math.Plane -import info.laht.threekt.scenes.Scene import org.w3c.dom.Node +import three.cameras.Camera +import three.math.Plane +import three.scenes.Scene external class WebGLRenderer(params: WebGLRendererParams = definedExternally) { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRendererParams.kt b/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRendererParams.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRendererParams.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/WebGLRendererParams.kt index e6800673..6b979e8f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRendererParams.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRendererParams.kt @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -package info.laht.threekt.renderers +package three.renderers import org.w3c.dom.Node diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderChunk.kt b/visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderChunk.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderChunk.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderChunk.kt index f70c7137..ccf4d37f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderChunk.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderChunk.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers.shaders +package three.renderers.shaders external object ShaderChunk { val alphamap_fragment: String diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderLib.kt b/visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderLib.kt similarity index 96% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderLib.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderLib.kt index f168f740..67ed1215 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderLib.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderLib.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers.shaders +package three.renderers.shaders external object ShaderLib { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/UniformsUtil.kt b/visionforge-threejs/src/main/kotlin/three/renderers/shaders/UniformsUtil.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/UniformsUtil.kt rename to visionforge-threejs/src/main/kotlin/three/renderers/shaders/UniformsUtil.kt index fb68d712..3d68f177 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/UniformsUtil.kt +++ b/visionforge-threejs/src/main/kotlin/three/renderers/shaders/UniformsUtil.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers.shaders +package three.renderers.shaders -import info.laht.threekt.core.Uniform +import three.core.Uniform external object UniformsUtil { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Fog.kt b/visionforge-threejs/src/main/kotlin/three/scenes/Fog.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Fog.kt rename to visionforge-threejs/src/main/kotlin/three/scenes/Fog.kt index c5682f36..87b67fb0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Fog.kt +++ b/visionforge-threejs/src/main/kotlin/three/scenes/Fog.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.scenes +package three.scenes -import info.laht.threekt.math.Color +import three.math.Color external class Fog { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/FogExp2.kt b/visionforge-threejs/src/main/kotlin/three/scenes/FogExp2.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/FogExp2.kt rename to visionforge-threejs/src/main/kotlin/three/scenes/FogExp2.kt index 017fd34b..fed2c580 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/FogExp2.kt +++ b/visionforge-threejs/src/main/kotlin/three/scenes/FogExp2.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.scenes +package three.scenes -import info.laht.threekt.math.Color +import three.math.Color external class FogExp2 { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Scene.kt b/visionforge-threejs/src/main/kotlin/three/scenes/Scene.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Scene.kt rename to visionforge-threejs/src/main/kotlin/three/scenes/Scene.kt index 16e5e3cd..41fc011c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Scene.kt +++ b/visionforge-threejs/src/main/kotlin/three/scenes/Scene.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.scenes +package three.scenes -import info.laht.threekt.core.Object3D -import info.laht.threekt.materials.Material +import three.core.Object3D +import three.materials.Material /** * Scenes allow you to set up what and where is to be rendered by three.js. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CompressedTexture.kt b/visionforge-threejs/src/main/kotlin/three/textures/CompressedTexture.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CompressedTexture.kt rename to visionforge-threejs/src/main/kotlin/three/textures/CompressedTexture.kt index 1d25e61d..10b72f45 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CompressedTexture.kt +++ b/visionforge-threejs/src/main/kotlin/three/textures/CompressedTexture.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.textures +package three.textures /** * Creates a texture based on data in compressed form, for example from a DDS file. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CubeTexture.kt b/visionforge-threejs/src/main/kotlin/three/textures/CubeTexture.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CubeTexture.kt rename to visionforge-threejs/src/main/kotlin/three/textures/CubeTexture.kt index b5eb6e89..b386f264 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CubeTexture.kt +++ b/visionforge-threejs/src/main/kotlin/three/textures/CubeTexture.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.textures +package three.textures import org.w3c.dom.Element diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/DepthTexture.kt b/visionforge-threejs/src/main/kotlin/three/textures/DepthTexture.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/DepthTexture.kt rename to visionforge-threejs/src/main/kotlin/three/textures/DepthTexture.kt index 0ce9a308..eabc7d9c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/DepthTexture.kt +++ b/visionforge-threejs/src/main/kotlin/three/textures/DepthTexture.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.textures +package three.textures external class DepthTexture( width: Int, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/Texture.kt b/visionforge-threejs/src/main/kotlin/three/textures/Texture.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/Texture.kt rename to visionforge-threejs/src/main/kotlin/three/textures/Texture.kt index b936c2f5..853ae54e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/Texture.kt +++ b/visionforge-threejs/src/main/kotlin/three/textures/Texture.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.textures +package three.textures -import info.laht.threekt.math.Matrix3 -import info.laht.threekt.math.Vector2 import org.w3c.dom.Element +import three.math.Matrix3 +import three.math.Vector2 /** * Create a texture to apply to a surface or as a reflection or refraction map. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/utils/BufferGeometryUtils.kt b/visionforge-threejs/src/main/kotlin/three/utils/BufferGeometryUtils.kt similarity index 88% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/utils/BufferGeometryUtils.kt rename to visionforge-threejs/src/main/kotlin/three/utils/BufferGeometryUtils.kt index dd15b514..9c52f8be 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/utils/BufferGeometryUtils.kt +++ b/visionforge-threejs/src/main/kotlin/three/utils/BufferGeometryUtils.kt @@ -1,8 +1,8 @@ @file:JsModule("three/examples/jsm/utils/BufferGeometryUtils") @file:JsNonModule -package info.laht.threekt.utils +package three.utils -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry public external object BufferGeometryUtils { From 67afa4e45b5008cdfe4416c35d561d1ae9e8fd7c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 15 Aug 2022 09:47:56 +0300 Subject: [PATCH 025/112] Fix light --- demo/playground/src/jvmMain/kotlin/gdmlCubes.kt | 11 +++++++++-- .../src/main/kotlin/ru/mipt/npm/sat/satServer.kt | 7 ++++++- .../kotlin/space/kscience/visionforge/VisionChange.kt | 11 ++++++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt b/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt index d5d483bc..fc134408 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt @@ -1,13 +1,20 @@ package space.kscience.visionforge.examples import space.kscience.gdml.GdmlShowCase +import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.set -fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){ +fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { vision("canvas") { requirePlugin(Solids) - GdmlShowCase.cubes().toVision() + GdmlShowCase.cubes().toVision().also { + it.ambientLight { + color.set(Colors.white) + } + } } } \ No newline at end of file diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index 41ac4d2f..e7326982 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -8,6 +8,7 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Colors import space.kscience.visionforge.html.Page import space.kscience.visionforge.html.plus import space.kscience.visionforge.server.close @@ -28,7 +29,11 @@ fun main() { val solids = satContext.fetch(Solids) //Create a geometry - val sat = solids.visionOfSatellite(ySegments = 3) + val sat = solids.visionOfSatellite(ySegments = 3).apply { + ambientLight { + color.set(Colors.white) + } + } val server = satContext.visionManager.serve { page(header = Page.threeJsHeader + Page.styleSheetHeader("css/styles.css")) { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 1edcdf70..0001dd44 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -9,6 +9,7 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.plus import kotlin.jvm.Synchronized import kotlin.time.Duration @@ -17,7 +18,7 @@ import kotlin.time.Duration * Create a deep copy of given Vision without external connections. */ private fun Vision.deepCopy(manager: VisionManager): Vision { - if(this is NullVision) return NullVision + if (this is NullVision) return NullVision //Assuming that unrooted visions are already isolated //TODO replace by efficient deep copy @@ -49,7 +50,7 @@ public object NullVision : Vision { public class VisionChangeBuilder(private val manager: VisionManager) : MutableVisionContainer { private var vision: Vision? = null - private val propertyChange = MutableMeta() + private var propertyChange = MutableMeta() private val children: HashMap = HashMap() public fun isEmpty(): Boolean = propertyChange.isEmpty() && propertyChange.isEmpty() && children.isEmpty() @@ -61,7 +62,11 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi public fun propertyChanged(visionName: Name, propertyName: Name, item: Meta?) { if (visionName == Name.EMPTY) { //Write property removal as [Null] - propertyChange[propertyName] = (item ?: Meta(Null)) + if (propertyName.isEmpty()) { + propertyChange = item?.toMutableMeta() ?: MutableMeta() + } else { + propertyChange[propertyName] = (item ?: Meta(Null)) + } } else { getOrPutChild(visionName).propertyChanged(Name.EMPTY, propertyName, item) } From 40b784f55143ab8f31f887eac0c3ae58dad90cc3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 19 Aug 2022 11:22:10 +0300 Subject: [PATCH 026/112] More universal treatment of highlighting in three --- .../space/kscience/visionforge/StyleSheet.kt | 2 +- .../kscience/visionforge/VisionProperties.kt | 5 +- .../space/kscience/visionforge/solid/Solid.kt | 2 + .../visionforge/solid/three/ThreeCanvas.kt | 34 +++++++++--- .../solid/three/ThreeLabelFactory.kt | 8 +-- .../visionforge/solid/three/ThreeMaterials.kt | 52 +++++++++++++------ .../solid/three/ThreeMeshFactory.kt | 2 +- .../main/kotlin/three/meshline/meshLineExt.kt | 5 +- 8 files changed, 79 insertions(+), 31 deletions(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 9db79e19..7320839d 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -67,7 +67,7 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) * List of names of styles applied to this object. Order matters. Not inherited. */ public var Vision.styles: List - get() = properties.getValue(Vision.STYLE_KEY, inherit = false, includeStyles = false)?.stringList ?: emptyList() + get() = properties.own?.getValue(Vision.STYLE_KEY)?.stringList ?: emptyList() set(value) { properties.setValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue()) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index fd7befdf..3a80dcf2 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -143,8 +143,11 @@ private class VisionPropertiesItem( override fun hashCode(): Int = Meta.hashCode(this) } +/** + * A base implementation of [MutableVisionProperties] + */ public abstract class AbstractVisionProperties( - private val vision: Vision, + public val vision: Vision, ) : MutableVisionProperties { override val descriptor: MetaDescriptor? get() = vision.descriptor diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 7d0d0b94..5585a970 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -58,6 +58,8 @@ public interface Solid : Vision { public val ROTATION_KEY: Name = "rotation".asName() + public val QUATERNION_KEY: Name = "quaternion".asName() + public val X_ROTATION_KEY: Name = ROTATION_KEY + X_KEY public val Y_ROTATION_KEY: Name = ROTATION_KEY + Y_KEY public val Z_ROTATION_KEY: Name = ROTATION_KEY + Z_KEY diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index 04b04699..4e6935a8 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -20,9 +20,12 @@ import three.external.controls.OrbitControls import three.external.controls.TrackballControls import three.geometries.EdgesGeometry import three.helpers.AxesHelper +import three.materials.Material import three.math.* import three.meshline.MeshLine import three.meshline.MeshLineMaterial +import three.meshline.isMeshLineMaterial +import three.objects.LineSegments import three.objects.Mesh import three.scenes.Scene import kotlin.math.cos @@ -276,7 +279,7 @@ public class ThreeCanvas( private fun Object3D.toggleHighlight( highlight: Boolean, edgesName: String, - material: MeshLineMaterial, + material: Material, ) { if (userData[DO_NOT_HIGHLIGHT_TAG] == true) { @@ -284,16 +287,21 @@ public class ThreeCanvas( } if (isMesh(this)) { - val highlightMesh = getObjectByName(edgesName) ?: Mesh( - MeshLine(EdgesGeometry(geometry)), - material - ).also { + val highlightMesh = getObjectByName(edgesName) ?: if (isMeshLineMaterial(material)) { + Mesh( + MeshLine(EdgesGeometry(geometry)), + material + ) + } else { + LineSegments(EdgesGeometry(geometry), material) + }.also { it.name = edgesName add(it) } highlightMesh.visible = highlight } else { - children.filter { !it.name.startsWith("@") && it.name != edgesName }.forEach { + //ignore service objects if they are not statics + children.filter { it.name.startsWith("@static") || !it.name.startsWith("@") }.forEach { it.toggleHighlight(highlight, edgesName, material) } } @@ -319,15 +327,25 @@ public class ThreeCanvas( public companion object { public val SELECTED_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply { color.set(Colors.ivory) - linewidth = 2.0 + thickness = 2f cached = true } public val HIGHLIGHT_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply { color.set(Colors.blue) - linewidth = 2.0 + thickness = 2f cached = true } +// +// public val SELECTED_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { +// color.set(Colors.ivory) +// cached = true +// } +// +// public val HIGHLIGHT_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { +// color.set(Colors.blue) +// cached = true +// } public const val DO_NOT_HIGHLIGHT_TAG: String = "doNotHighlight" diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index 49796fb0..2bd8c572 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -1,14 +1,14 @@ package space.kscience.visionforge.solid.three -import three.core.Object3D -import three.geometries.TextBufferGeometry -import three.objects.Mesh import kotlinx.js.jso import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.warn import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.SolidLabel +import three.core.Object3D +import three.geometries.TextBufferGeometry +import three.objects.Mesh import kotlin.reflect.KClass /** @@ -25,7 +25,7 @@ public object ThreeLabelFactory : ThreeFactory { curveSegments = 1 }) return Mesh(textGeo, ThreeMaterials.DEFAULT).apply { - createMaterial(vision) + setMaterial(vision) updatePosition(vision) if(observe) { vision.onPropertyChange(three.context) { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index abcd5df5..5966ee30 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -60,6 +60,7 @@ public object ThreeMaterials { color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false } + else -> MeshStandardMaterial().apply { color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR @@ -71,10 +72,18 @@ public object ThreeMaterials { needsUpdate = true } - private val materialCache = HashMap() +// private val materialCache = HashMap() +// +// internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta.hashCode()) { +// buildMaterial(meta).apply { +// cached = true +// } +// } + + private val visionMaterialCache = HashMap() - internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta.hashCode()) { - buildMaterial(meta).apply { + internal fun cacheMaterial(vision: Vision): Material = visionMaterialCache.getOrPut(vision) { + buildMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)).apply { cached = true } } @@ -84,7 +93,7 @@ public object ThreeMaterials { * Compute color */ public fun Meta.threeColor(): Color? { - if(isEmpty()) return null + if (isEmpty()) return null val value = value return if (isLeaf) { when { @@ -118,13 +127,19 @@ internal var Material.cached: Boolean userData["cached"] = value } -public fun Mesh.createMaterial(vision: Vision) { - val ownMaterialMeta = vision.properties.own?.get(SolidMaterial.MATERIAL_KEY) - if (ownMaterialMeta == null) { - if (vision is SolidReference && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty()) { - createMaterial(vision.prototype) +public fun Mesh.setMaterial(vision: Vision) { + if ( + vision.properties.own?.get(SolidMaterial.MATERIAL_KEY) == null + && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty() + ) { + //if this is a reference, use material of the prototype + if (vision is SolidReference) { + ThreeMaterials.cacheMaterial(vision.prototype) } else { - material = ThreeMaterials.cacheMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)) + material = vision.parent?.let { parent -> + //TODO cache parent material + ThreeMaterials.buildMaterial(parent.properties.getProperty(SolidMaterial.MATERIAL_KEY)) + } ?: ThreeMaterials.cacheMaterial(vision) } } else { material = ThreeMaterials.buildMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)) @@ -138,22 +153,27 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { || propertyName == SolidMaterial.MATERIAL_KEY + SolidMaterial.TYPE_KEY ) { //generate a new material since cached material should not be changed - createMaterial(vision) + setMaterial(vision) } else { when (propertyName) { SolidMaterial.MATERIAL_COLOR_KEY -> { - material.asDynamic().color = vision.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).threeColor() - ?: ThreeMaterials.DEFAULT_COLOR + material.asDynamic().color = + vision.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).threeColor() + ?: ThreeMaterials.DEFAULT_COLOR } + SolidMaterial.SPECULAR_COLOR_KEY -> { - material.asDynamic().specular = vision.properties.getProperty(SolidMaterial.SPECULAR_COLOR_KEY).threeColor() - ?: ThreeMaterials.DEFAULT_COLOR + material.asDynamic().specular = + vision.properties.getProperty(SolidMaterial.SPECULAR_COLOR_KEY).threeColor() + ?: ThreeMaterials.DEFAULT_COLOR } + SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { material.asDynamic().emissive = vision.properties.getProperty(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY) .threeColor() ?: ThreeMaterials.BLACK_COLOR } + SolidMaterial.MATERIAL_OPACITY_KEY -> { val opacity = vision.properties.getValue( SolidMaterial.MATERIAL_OPACITY_KEY, @@ -162,12 +182,14 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { material.opacity = opacity material.transparent = opacity < 1.0 } + SolidMaterial.MATERIAL_WIREFRAME_KEY -> { material.asDynamic().wireframe = vision.properties.getValue( SolidMaterial.MATERIAL_WIREFRAME_KEY, inherit = true, )?.boolean ?: false } + else -> console.warn("Unrecognized material property: $propertyName") } material.needsUpdate = true diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index ef7f5120..b27bdcab 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -85,7 +85,7 @@ public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit } internal fun Mesh.applyProperties(vision: Solid): Mesh = apply { - createMaterial(vision) + setMaterial(vision) applyEdges(vision) //applyWireFrame(obj) layers.set(vision.layer) diff --git a/visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt b/visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt index a2bfa57a..60047884 100644 --- a/visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt +++ b/visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt @@ -1,8 +1,11 @@ package three.meshline import three.core.BufferGeometry +import three.materials.Material import three.math.Vector3 public fun MeshLine(geometry: BufferGeometry): MeshLine = MeshLine().apply { setGeometry(geometry) } -public fun MeshLine(points: Array): MeshLine = MeshLine().apply { setPoints(points) } \ No newline at end of file +public fun MeshLine(points: Array): MeshLine = MeshLine().apply { setPoints(points) } + +internal fun isMeshLineMaterial(material: Material): Boolean = material.asDynamic().isMeshLineMaterial == true \ No newline at end of file From 75540a078f70d5e5d4b7d3811791994c4bd6ffe7 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 21 Aug 2022 17:21:36 +0300 Subject: [PATCH 027/112] Add quaternion support --- .../visionforge/html/HtmlVisionContext.kt | 8 ++++---- .../kscience/visionforge/solid/FX3DPlugin.kt | 2 ++ .../space/kscience/visionforge/solid/Solid.kt | 20 +++++++++++++++++++ .../solid/transform/RemoveSingleChild.kt | 1 + .../visionforge/solid/three/ThreeFactory.kt | 15 +++++++++++++- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt index 513676d4..007658b1 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt @@ -34,11 +34,11 @@ public interface HtmlVisionContext : ContextAware { public typealias HtmlVisionContextFragment = context(HtmlVisionContext) TagConsumer<*>.() -> Unit -context(HtmlVisionContext) - public fun HtmlVisionContextFragment(content: TagConsumer<*>.() -> Unit): HtmlVisionFragment = content +context(HtmlVisionContext) public fun HtmlVisionFragment( + content: TagConsumer<*>.() -> Unit +): HtmlVisionFragment = content -context(HtmlVisionContext) - private fun TagConsumer.vision( +context(HtmlVisionContext) private fun TagConsumer.vision( visionManager: VisionManager, name: Name, vision: Vision, diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt index 8a0abcdb..990b0b54 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt @@ -97,6 +97,8 @@ public class FX3DPlugin : AbstractPlugin() { scaleYProperty().bind(binding[Solid.Y_SCALE_KEY].float(obj.scaleY.toFloat())) scaleZProperty().bind(binding[Solid.Z_SCALE_KEY].float(obj.scaleZ.toFloat())) + if(obj.quaternion!= null) TODO("Quaternion support not implemented") + val rotateX = Rotate(0.0, Rotate.X_AXIS).apply { angleProperty().bind(binding[Solid.X_ROTATION_KEY].float(obj.rotationX.toFloat()).multiply(180.0 / PI)) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 5585a970..b87f0c93 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -203,6 +203,26 @@ public var Solid.rotationX: Number by float(X_ROTATION_KEY, 0f) public var Solid.rotationY: Number by float(Y_ROTATION_KEY, 0f) public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f) +public var Solid.quaternion: Pair? + get() = properties.getValue(Solid.QUATERNION_KEY)?.list?.let { + require(it.size == 4) { "Quaternion must be a number array of 4 elements" } + it[0].float to Point3D(it[1].float, it[2].float, it[3].float) + } + set(value) { + properties.setValue( + Solid.QUATERNION_KEY, + value?.let { + ListValue( + value.first, + value.second.x, + value.second.y, + value.second.z + ) + } + ) + } + + //public var Solid.quaternion: Quaternion? // get() = meta[Solid::quaternion.name]?.value?.doubleArray?.let { Quaternion(it) } // set(value) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index d1e6fe5a..6a309d94 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -14,6 +14,7 @@ internal fun Solid.updateFrom(other: Solid): Solid { x += other.x y += other.y z += other.y + if(quaternion != null || other.quaternion != null) TODO("Quaternion support not implemented") rotationX += other.rotationX rotationY += other.rotationY rotationZ += other.rotationZ diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index cf42c139..a0852c72 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -11,6 +11,7 @@ import space.kscience.visionforge.visible import three.core.BufferGeometry import three.core.Object3D import three.math.Euler +import three.math.Quaternion import kotlin.reflect.KClass /** @@ -48,8 +49,20 @@ public fun Object3D.updatePosition(vision: Vision) { // } else { // setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) // } + val quaternion = vision.quaternion - setRotationFromEuler(Euler(vision.rotationX, vision.rotationY, vision.rotationZ, vision.rotationOrder.name)) + if (quaternion != null) { + setRotationFromQuaternion( + Quaternion( + quaternion.second.x, + quaternion.second.y, + quaternion.second.z, + quaternion.first + ) + ) + } else { + setRotationFromEuler(Euler(vision.rotationX, vision.rotationY, vision.rotationZ, vision.rotationOrder.name)) + } scale.set(vision.scaleX, vision.scaleY, vision.scaleZ) updateMatrix() From 25fc143363f9cc37779d6df5fae1be14b00b47a4 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 23 Aug 2022 12:06:27 +0300 Subject: [PATCH 028/112] Performance optimization --- build.gradle.kts | 3 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 1 - .../ru/mipt/npm/muon/monitor/Monitor.kt | 85 +++++++++++-------- .../kscience/visionforge/VisionProperties.kt | 4 +- .../solid/three/ThreeCanvasLabelFactory.kt | 22 +++-- .../visionforge/solid/three/ThreeMaterials.kt | 17 ++-- .../solid/three/ThreeReferenceFactory.kt | 23 ++--- 7 files changed, 85 insertions(+), 70 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4c76b98f..939d197b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ plugins { // id("org.jetbrains.kotlinx.kover") version "0.5.0" } -val dataforgeVersion by extra("0.6.0-dev-13") +val dataforgeVersion by extra("0.6.0-dev-15") val fxVersion by extra("11") allprojects{ @@ -15,6 +15,7 @@ subprojects { if (name.startsWith("visionforge")) apply() repositories { + mavenLocal() maven("https://repo.kotlin.link") mavenCentral() maven("https://maven.jzy3d.org/releases") diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index cf8caf80..1b8eb566 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -82,7 +82,6 @@ class Model(val manager: VisionManager) { } event.track?.let { tracks.polyline(*it.toTypedArray(), name = "track[${event.id}]") { - thickness = 4 color.set("red") } } diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt index 3e1db5bc..1a8c8aa9 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt @@ -11,12 +11,12 @@ import space.kscience.visionforge.solid.plus class SC1( val name: String, val center: Point3D, - val xSize: Float = PIXEL_XY_SIZE, val ySize: Float = PIXEL_XY_SIZE, val zSize: Float = PIXEL_Z_SIZE + val xSize: Float = PIXEL_XY_SIZE, val ySize: Float = PIXEL_XY_SIZE, val zSize: Float = PIXEL_Z_SIZE, ) class SC16( val name: String, - val center: Point3D + val center: Point3D, ) { /** @@ -28,73 +28,86 @@ class SC16( val y: Double when (index) { 7 -> { - x = 1.5 * Monitor.PIXEL_XY_SPACING; - y = 1.5 * Monitor.PIXEL_XY_SPACING; + x = 1.5 * Monitor.PIXEL_XY_SPACING + y = 1.5 * Monitor.PIXEL_XY_SPACING } + 4 -> { - x = 0.5 * Monitor.PIXEL_XY_SPACING; - y = 1.5 * Monitor.PIXEL_XY_SPACING; + x = 0.5 * Monitor.PIXEL_XY_SPACING + y = 1.5 * Monitor.PIXEL_XY_SPACING } + 6 -> { - x = 1.5 * Monitor.PIXEL_XY_SPACING; - y = 0.5 * Monitor.PIXEL_XY_SPACING; + x = 1.5 * Monitor.PIXEL_XY_SPACING + y = 0.5 * Monitor.PIXEL_XY_SPACING } + 5 -> { - x = 0.5 * Monitor.PIXEL_XY_SPACING; - y = 0.5 * Monitor.PIXEL_XY_SPACING; + x = 0.5 * Monitor.PIXEL_XY_SPACING + y = 0.5 * Monitor.PIXEL_XY_SPACING } 3 -> { - x = -1.5 * Monitor.PIXEL_XY_SPACING; - y = 1.5 * Monitor.PIXEL_XY_SPACING; + x = -1.5 * Monitor.PIXEL_XY_SPACING + y = 1.5 * Monitor.PIXEL_XY_SPACING } + 0 -> { - x = -0.5 * Monitor.PIXEL_XY_SPACING; - y = 1.5 * Monitor.PIXEL_XY_SPACING; + x = -0.5 * Monitor.PIXEL_XY_SPACING + y = 1.5 * Monitor.PIXEL_XY_SPACING } + 2 -> { - x = -1.5 * Monitor.PIXEL_XY_SPACING; - y = 0.5 * Monitor.PIXEL_XY_SPACING; + x = -1.5 * Monitor.PIXEL_XY_SPACING + y = 0.5 * Monitor.PIXEL_XY_SPACING } + 1 -> { - x = -0.5 * Monitor.PIXEL_XY_SPACING; - y = 0.5 * Monitor.PIXEL_XY_SPACING; + x = -0.5 * Monitor.PIXEL_XY_SPACING + y = 0.5 * Monitor.PIXEL_XY_SPACING } 11 -> { - x = -1.5 * Monitor.PIXEL_XY_SPACING; - y = -1.5 * Monitor.PIXEL_XY_SPACING; + x = -1.5 * Monitor.PIXEL_XY_SPACING + y = -1.5 * Monitor.PIXEL_XY_SPACING } + 8 -> { - x = -0.5 * Monitor.PIXEL_XY_SPACING; - y = -1.5 * Monitor.PIXEL_XY_SPACING; + x = -0.5 * Monitor.PIXEL_XY_SPACING + y = -1.5 * Monitor.PIXEL_XY_SPACING } + 10 -> { - x = -1.5 * Monitor.PIXEL_XY_SPACING; - y = -0.5 * Monitor.PIXEL_XY_SPACING; + x = -1.5 * Monitor.PIXEL_XY_SPACING + y = -0.5 * Monitor.PIXEL_XY_SPACING } + 9 -> { - x = -0.5 * Monitor.PIXEL_XY_SPACING; - y = -0.5 * Monitor.PIXEL_XY_SPACING; + x = -0.5 * Monitor.PIXEL_XY_SPACING + y = -0.5 * Monitor.PIXEL_XY_SPACING } 15 -> { - x = 1.5 * Monitor.PIXEL_XY_SPACING; - y = -1.5 * Monitor.PIXEL_XY_SPACING; + x = 1.5 * Monitor.PIXEL_XY_SPACING + y = -1.5 * Monitor.PIXEL_XY_SPACING } + 12 -> { - x = 0.5 * Monitor.PIXEL_XY_SPACING; - y = -1.5 * Monitor.PIXEL_XY_SPACING; + x = 0.5 * Monitor.PIXEL_XY_SPACING + y = -1.5 * Monitor.PIXEL_XY_SPACING } + 14 -> { - x = 1.5 * Monitor.PIXEL_XY_SPACING; - y = -0.5 * Monitor.PIXEL_XY_SPACING; + x = 1.5 * Monitor.PIXEL_XY_SPACING + y = -0.5 * Monitor.PIXEL_XY_SPACING } + 13 -> { - x = 0.5 * Monitor.PIXEL_XY_SPACING; - y = -0.5 * Monitor.PIXEL_XY_SPACING; + x = 0.5 * Monitor.PIXEL_XY_SPACING + y = -0.5 * Monitor.PIXEL_XY_SPACING } - else -> throw Error(); + + else -> throw Error() } val offset = Point3D(-y, x, 0)//rotateDetector(Point3D(x, y, 0.0)); val pixelName = "${name}_${index}" @@ -137,7 +150,7 @@ object Monitor { .mapNotNull { line -> if (line.startsWith(" ")) { val split = line.trim().split("\\s+".toRegex()) - val detectorName = split[1]; + val detectorName = split[1] val x = split[4].toDouble() - 500 val y = split[5].toDouble() - 500 val z = 180 - split[6].toDouble() diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 3a80dcf2..cddb6585 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -165,6 +165,8 @@ public abstract class AbstractVisionProperties( return properties!! } + private val descriptorCache = HashMap() + override fun getValue( name: Name, inherit: Boolean?, @@ -172,7 +174,7 @@ public abstract class AbstractVisionProperties( ): Value? { own?.get(name)?.value?.let { return it } - val descriptor = descriptor?.get(name) + val descriptor = descriptor?.let { descriptor -> descriptorCache.getOrPut(name) { descriptor[name] } } val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true if (stylesFlag) { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index 0b0019df..7a0f1c7b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -24,15 +24,19 @@ public object ThreeCanvasLabelFactory : ThreeFactory { override fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { val canvas = document.createElement("canvas") as HTMLCanvasElement - val context = canvas.getContext("2d") as CanvasRenderingContext2D - context.font = "Bold ${vision.fontSize}pt ${vision.fontFamily}" - context.fillStyle = vision.properties.getValue(SolidMaterial.MATERIAL_COLOR_KEY, false, true)?.value ?: "black" - context.textBaseline = CanvasTextBaseline.MIDDLE - val metrics = context.measureText(vision.text) - //canvas.width = metrics.width.toInt() - - - context.fillText(vision.text, (canvas.width - metrics.width) / 2, 0.5 * canvas.height) + canvas.getContext("2d").apply { + this as CanvasRenderingContext2D + font = "Bold ${vision.fontSize}pt ${vision.fontFamily}" + fillStyle = vision.properties.getValue( + SolidMaterial.MATERIAL_COLOR_KEY, + inherit = false, + includeStyles = true + )?.value ?: "black" + textBaseline = CanvasTextBaseline.MIDDLE + val metrics = measureText(vision.text) + //canvas.width = metrics.width.toInt() + fillText(vision.text, (canvas.width - metrics.width) / 2, 0.5 * canvas.height) + } // canvas contents will be used for a texture diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 5966ee30..f5ac5c2b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -93,22 +93,17 @@ public object ThreeMaterials { * Compute color */ public fun Meta.threeColor(): Color? { - if (isEmpty()) return null - val value = value - return if (isLeaf) { - when { - value == null -> null + value?.let { value -> + return when { value === Null -> null value.type == ValueType.NUMBER -> Color(value.int) else -> Color(value.string) } - } else { - Color( - getValue(Colors.RED_KEY.asName())?.int ?: 0, - getValue(Colors.GREEN_KEY.asName())?.int ?: 0, - getValue(Colors.BLUE_KEY.asName())?.int ?: 0 - ) } + val red = getValue(Colors.RED_KEY.asName())?.int + val green = getValue(Colors.GREEN_KEY.asName())?.int + val blue = getValue(Colors.BLUE_KEY.asName())?.int + return if (red == null && green == null && blue == null) null else Color(red ?: 0, green ?: 0, blue ?: 0) } public fun ColorAccessor.threeColor(): Color? { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index bde8c456..405956f8 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -16,17 +16,18 @@ public object ThreeReferenceFactory : ThreeFactory { override val type: KClass = SolidReference::class - private fun Object3D.replicate(): Object3D { - return when { - isMesh(this) -> Mesh(geometry, material).also { - it.applyMatrix4(matrix) - } - else -> clone(false) - }.also { obj: Object3D -> - obj.name = this.name - children.forEach { child: Object3D -> - obj.add(child.replicate()) - } + private fun Object3D.replicate(): Object3D = when { + isMesh(this) -> Mesh(geometry, material).also { + //clone geometry + it.material.cached = true + it.applyMatrix4(matrix) + } + + else -> clone(false) + }.also { obj: Object3D -> + obj.name = this.name + children.forEach { child: Object3D -> + obj.add(child.replicate()) } } From 56d577453a8cc52d0cf07f343445ea4ddfe48720 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 24 Aug 2022 09:19:13 +0300 Subject: [PATCH 029/112] Fix edges for composite --- CHANGELOG.md | 1 + .../visionforge/solid/demo/VariableBox.kt | 3 +- .../visionforge/solid/SolidMaterial.kt | 14 ++++++++- .../solid/three/ThreeCompositeFactory.kt | 12 ++++---- .../solid/three/ThreeMeshFactory.kt | 29 +++++-------------- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f60db403..2b7d7766 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - MeshLine for thick lines ### Changed +- Edges moved to solids module for easier construction - Visions **must** be rooted in order to subscribe to updates. - Visions use flows instead of direct subscriptions. - Radical change of inner workings of vision children and properties. diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index 1e626155..15e53129 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -8,6 +8,7 @@ import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.setChild import space.kscience.visionforge.solid.SolidGroup +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.three.* import three.core.Object3D @@ -60,7 +61,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision mesh.updateMatrix() } - name.startsWith(ThreeMeshFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox) + name.startsWith(EDGES_KEY) -> mesh.applyEdges(this@VariableBox) else -> mesh.updateProperty(this@VariableBox, name) } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index 7d5c4d00..df720e6c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -52,6 +52,11 @@ public class SolidMaterial : Scheme() { public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY public val MATERIAL_WIREFRAME_KEY: Name = MATERIAL_KEY + WIREFRAME_KEY + public val EDGES_KEY: Name = "edges".asName() + public val ENABLED_KEY: Name = "enabled".asName() + public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY + public val EDGES_MATERIAL_KEY: Name = EDGES_KEY + MATERIAL_KEY + public override val descriptor: MetaDescriptor by lazy { //must be lazy to avoid initialization bug MetaDescriptor { @@ -114,4 +119,11 @@ public var Solid.opacity: Number? get() = properties.getValue(MATERIAL_OPACITY_KEY, inherit = true)?.number set(value) { properties.setValue(MATERIAL_OPACITY_KEY, value?.asValue()) - } \ No newline at end of file + } + + +@VisionBuilder +public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { + properties[SolidMaterial.EDGES_ENABLED_KEY] = enabled + SolidMaterial.write(properties.getProperty(SolidMaterial.EDGES_MATERIAL_KEY)).apply(block) +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index 44bcb797..fe40022d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -5,6 +5,7 @@ import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.Composite import space.kscience.visionforge.solid.CompositeType +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY import three.objects.Mesh import kotlin.reflect.KClass @@ -38,10 +39,10 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory override val type: KClass get() = Composite::class override fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh { - val first = - three.buildObject3D(vision.first, observe).takeIfMesh() ?: error("First part of composite is not a mesh") - val second = - three.buildObject3D(vision.second, observe).takeIfMesh() ?: error("Second part of composite is not a mesh") + val first = three.buildObject3D(vision.first, observe).takeIfMesh() + ?: error("First part of composite is not a mesh") + val second = three.buildObject3D(vision.second, observe).takeIfMesh() + ?: error("Second part of composite is not a mesh") return when (vision.compositeType) { CompositeType.GROUP, CompositeType.UNION -> CSG.union(first, second) CompositeType.INTERSECT -> CSG.intersect(first, second) @@ -49,11 +50,12 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory }.apply { updatePosition(vision) applyProperties(vision) + if (observe) { vision.onPropertyChange { name -> when { //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) - name.startsWith(ThreeMeshFactory.EDGES_KEY) -> applyEdges(vision) + name.startsWith(EDGES_KEY) -> applyEdges(vision) else -> updateProperty(vision, name) } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index b27bdcab..b3281e4b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -1,18 +1,13 @@ package space.kscience.visionforge.solid.three import space.kscience.dataforge.meta.boolean -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith -import space.kscience.visionforge.VisionBuilder import space.kscience.visionforge.onPropertyChange -import space.kscience.visionforge.set import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidMaterial +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_ENABLED_KEY +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_MATERIAL_KEY import space.kscience.visionforge.solid.layer -import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_ENABLED_KEY -import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_MATERIAL_KEY import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_OBJECT_NAME import three.core.BufferGeometry import three.geometries.EdgesGeometry @@ -43,7 +38,7 @@ public abstract class ThreeMeshFactory( applyProperties(vision) } - if(observe) { + if (observe) { //add listener to object properties vision.onPropertyChange(three.context) { name -> when { @@ -66,24 +61,15 @@ public abstract class ThreeMeshFactory( } public companion object { - public val EDGES_KEY: Name = "edges".asName() internal const val EDGES_OBJECT_NAME: String = "@edges" //public val WIREFRAME_KEY: Name = "wireframe".asName() - public val ENABLED_KEY: Name = "enabled".asName() - public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY - public val EDGES_MATERIAL_KEY: Name = EDGES_KEY + SolidMaterial.MATERIAL_KEY + //public val WIREFRAME_ENABLED_KEY: Name = WIREFRAME_KEY + ENABLED_KEY //public val WIREFRAME_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY } } -@VisionBuilder -public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { - properties[EDGES_ENABLED_KEY] = enabled - SolidMaterial.write(properties.getProperty(EDGES_MATERIAL_KEY)).apply(block) -} - internal fun Mesh.applyProperties(vision: Solid): Mesh = apply { setMaterial(vision) applyEdges(vision) @@ -97,13 +83,12 @@ internal fun Mesh.applyProperties(vision: Solid): Mesh = apply { public fun Mesh.applyEdges(vision: Solid) { val edges = children.find { it.name == EDGES_OBJECT_NAME } as? LineSegments //inherited edges definition, enabled by default - if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = true)?.boolean != false) { - val bufferGeometry = geometry as? BufferGeometry ?: return + if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = false)?.boolean != false) { val material = ThreeMaterials.getLineMaterial(vision.properties.getProperty(EDGES_MATERIAL_KEY), true) if (edges == null) { add( LineSegments( - EdgesGeometry(bufferGeometry), + EdgesGeometry(geometry), material ).apply { name = EDGES_OBJECT_NAME From f0a6e12358f15f49f91a1054785d6a091221a869 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 24 Aug 2022 09:59:10 +0300 Subject: [PATCH 030/112] Fix light for GDML and ambient lighg updates --- .../src/jvmMain/kotlin/gdmlCubes.kt | 9 +--- .../src/jvmMain/kotlin/gdmlCurve.kt | 2 +- .../visionforge/gdml/GdmlLoaderOptions.kt | 8 +-- .../kscience/visionforge/gdml/gdmlLoader.kt | 49 ++++++++++++------- .../visionforge/solid/ColorAccessor.kt | 6 ++- .../kscience/visionforge/solid/LightSource.kt | 16 +++--- .../solid/three/ThreeAmbientLightFactory.kt | 16 ++++++ .../solid/three/ThreeMeshFactory.kt | 32 +----------- 8 files changed, 66 insertions(+), 72 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt b/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt index fc134408..3e5b0475 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt @@ -1,20 +1,13 @@ package space.kscience.visionforge.examples import space.kscience.gdml.GdmlShowCase -import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.Solids -import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.set fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { vision("canvas") { requirePlugin(Solids) - GdmlShowCase.cubes().toVision().also { - it.ambientLight { - color.set(Colors.white) - } - } + GdmlShowCase.cubes().toVision() } } \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt b/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt index f98a0b81..c2af2a8f 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt @@ -223,7 +223,7 @@ fun main() = makeVisionFile(Path.of("curves.html"), resourceLocation = ResourceL } } }.toVision { - configure { _, solid, _ -> + solids { _, solid, _ -> //disable visibility for the world box if(solid.name == "world"){ visible = false diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt index 34ab7d68..56158c55 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt @@ -4,9 +4,7 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.names.Name import space.kscience.gdml.* -import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidMaterial -import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.* import space.kscience.visionforge.useStyle import kotlin.random.Random @@ -70,7 +68,7 @@ public class GdmlLoaderOptions { } private set - public fun configure(block: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit) { + public fun solids(block: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit) { val oldConfigure = configureSolid configureSolid = { parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial -> oldConfigure(parent, solid, material) @@ -79,6 +77,8 @@ public class GdmlLoaderOptions { } + public var light: LightSource? = AmbientLightSource() + public companion object { private val random: Random = Random(222) diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index 18e2640e..58213437 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -27,10 +27,10 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { /** * A special group for local templates */ - private val proto = SolidGroup() + private val templates = SolidGroup() - private val solids = proto.solidGroup(solidsName) { - properties["edges.enabled"] = false + private val solids = templates.solidGroup(solidsName) { + edges(false) } private val referenceStore = HashMap>() @@ -46,7 +46,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { private fun proxySolid(root: Gdml, group: SolidGroup, solid: GdmlSolid, name: String): SolidReference { val templateName = solidsName + name - if (proto[templateName] == null) { + if (templates[templateName] == null) { solids.addSolid(root, solid, name) } val ref = group.ref(templateName, name) @@ -61,8 +61,8 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { volume: GdmlGroup, ): SolidReference { val templateName = volumesName + volume.name.asName() - if (proto[templateName] == null) { - proto.setChild(templateName, volume(root, volume)) + if (templates[templateName] == null) { + templates.setChild(templateName, volume(root, volume)) } val ref = group.ref(templateName, physVolume.name).withPosition(root, physVolume) referenceStore.getOrPut(templateName) { ArrayList() }.add(ref) @@ -139,6 +139,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { angle = solid.deltaphi * aScale, name = name ) + is GdmlCone -> if (solid.rmin1.toDouble() == 0.0 && solid.rmin2.toDouble() == 0.0) { cone( bottomRadius = solid.rmax1 * lScale, @@ -160,6 +161,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { name = name ) } + is GdmlXtru -> extruded(name) { shape { solid.vertices.forEach { @@ -175,6 +177,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { ) } } + is GdmlScaledSolid -> { //Add solid with modified scale val innerSolid: GdmlSolid = solid.solidref.resolve(root) @@ -186,6 +189,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { scaleZ = solid.scale.z.toFloat() } } + is GdmlSphere -> sphereLayer( outerRadius = solid.rmax * lScale, innerRadius = solid.rmin * lScale, @@ -195,6 +199,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { thetaStart = solid.starttheta * aScale, name = name, ) + is GdmlOrb -> sphere(solid.r * lScale, name = name) is GdmlPolyhedra -> extruded(name) { //getting the radius of first @@ -211,6 +216,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { layer(plane.z * lScale, scale = plane.rmax * lScale / baseRadius) } } + is GdmlBoolSolid -> { val first: GdmlSolid = solid.first.resolve(root) ?: error("") val second: GdmlSolid = solid.second.resolve(root) ?: error("") @@ -235,6 +241,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { } } + is GdmlTrapezoid -> { val dxBottom = solid.x1.toDouble() / 2 val dxTop = solid.x2.toDouble() / 2 @@ -251,6 +258,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { val node8 = Point3D(-dxTop, dyTop, dz) hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name) } + is GdmlEllipsoid -> TODO("Renderer for $solid not supported yet") is GdmlElTube -> TODO("Renderer for $solid not supported yet") is GdmlElCone -> TODO("Renderer for $solid not supported yet") @@ -271,9 +279,11 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { GdmlLoaderOptions.Action.ADD -> { addSolid(root, solid, name) } + GdmlLoaderOptions.Action.PROTOTYPE -> { proxySolid(root, this, solid, name ?: solid.name) } + GdmlLoaderOptions.Action.REJECT -> { //ignore null @@ -304,9 +314,11 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { val group: SolidGroup = volume(root, volume) this.setChild(physVolume.name, group.withPosition(root, physVolume)) } + GdmlLoaderOptions.Action.PROTOTYPE -> { proxyVolume(root, this, physVolume, volume) } + GdmlLoaderOptions.Action.REJECT -> { //ignore } @@ -348,35 +360,36 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { } } - private fun finalize(final: SolidGroup): SolidGroup { - val rootStyle by final.style("gdml") { + fun transform(root: Gdml): SolidGroup { + val rootSolid = volume(root, root.world.resolve(root) ?: error("GDML root is not resolved")) + + val rootStyle by rootSolid.style("gdml") { Solid.ROTATION_ORDER_KEY put RotationOrder.ZXY } - final.useStyle(rootStyle, false) - final.prototypes { - proto.items.forEach { (token, item) -> + rootSolid.useStyle(rootStyle, false) + + rootSolid.prototypes { + templates.items.forEach { (token, item) -> item.parent = null setChild(token.asName(), item as? Solid) } } settings.styleCache.forEach { - final.styleSheet { + rootSolid.styleSheet { define(it.key.toString(), it.value) } } - return final + return rootSolid } - - fun transform(root: Gdml): SolidGroup = - finalize(volume(root, root.world.resolve(root) ?: error("GDML root is not resolved"))) } public fun Gdml.toVision(block: GdmlLoaderOptions.() -> Unit = {}): SolidGroup { val settings = GdmlLoaderOptions().apply(block) - val context = GdmlLoader(settings) - return context.transform(this) + return GdmlLoader(settings).transform(this).also { + it.children["light"] = settings.light + } } /** diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index 29de1575..01abf310 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -28,8 +28,10 @@ public class ColorAccessor( } } -public fun Vision.color(): ReadOnlyProperty = ReadOnlyProperty { _, property -> - ColorAccessor(properties.root(true), property.name.asName()) +public fun Vision.color( + propertyName: Name? = null, +): ReadOnlyProperty = ReadOnlyProperty { _, property -> + ColorAccessor(properties.root(true), propertyName ?: property.name.asName()) } public var ColorAccessor?.string: String? diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt index 3db461ef..95aca618 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -7,16 +7,20 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.node import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.meta.number +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName import space.kscience.visionforge.* @Serializable public abstract class LightSource : SolidBase() { override val descriptor: MetaDescriptor get() = LightSource.descriptor - public val color: ColorAccessor by color() - public var intensity: Number by properties.root(includeStyles = false).number { 1.0 } + public val color: ColorAccessor by color(SolidMaterial.COLOR_KEY) + public var intensity: Number by properties.root(includeStyles = false).number(INTENSITY_KEY) { 1.0 } + + public companion object { + public val INTENSITY_KEY: Name = "intensity".asName() - public companion object{ public val descriptor: MetaDescriptor by lazy { MetaDescriptor { value(Vision.VISIBLE_KEY, ValueType.BOOLEAN) { @@ -27,6 +31,7 @@ public abstract class LightSource : SolidBase() { value(LightSource::color.name, ValueType.STRING, ValueType.NUMBER) { inherited = false widgetType = "color" + default(Colors.white) } value(LightSource::intensity.name, ValueType.NUMBER) { @@ -34,11 +39,6 @@ public abstract class LightSource : SolidBase() { default(1.0) } - value(SolidMaterial.COLOR_KEY, ValueType.STRING, ValueType.NUMBER) { - inherited = false - widgetType = "color" - } - node(Solid.POSITION_KEY) { hide() } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt index 3d420570..3f8e251c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt @@ -1,6 +1,12 @@ package space.kscience.visionforge.solid.three +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Vision +import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.AmbientLightSource +import space.kscience.visionforge.solid.LightSource +import space.kscience.visionforge.solid.SolidMaterial +import space.kscience.visionforge.visible import three.lights.AmbientLight import three.math.Color import kotlin.reflect.KClass @@ -14,6 +20,16 @@ public object ThreeAmbientLightFactory : ThreeFactory { intensity = vision.intensity.toDouble() } + if (observe) { + vision.onPropertyChange(three.context) { propertyName: Name -> + when (propertyName) { + Vision.VISIBLE_KEY -> res.visible = vision.visible ?: true + SolidMaterial.COLOR_KEY -> res.color = vision.color.threeColor() ?: Color(0x404040) + LightSource.INTENSITY_KEY -> res.intensity = vision.intensity.toDouble() + } + } + } + return res } } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index b3281e4b..30f3034b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -29,8 +29,6 @@ public abstract class ThreeMeshFactory( override fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh { val geometry = buildGeometry(vision) - //val meshMeta: Meta = obj.properties[Material3D.MATERIAL_KEY]?.node ?: Meta.empty - val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply { matrixAutoUpdate = false //set position for mesh @@ -46,11 +44,10 @@ public abstract class ThreeMeshFactory( val oldGeometry = mesh.geometry val newGeometry = buildGeometry(vision) oldGeometry.attributes = newGeometry.attributes - //mesh.applyWireFrame(obj) + mesh.applyEdges(vision) newGeometry.dispose() } - //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) name.startsWith(EDGES_KEY) -> mesh.applyEdges(vision) else -> mesh.updateProperty(vision, name) } @@ -62,18 +59,12 @@ public abstract class ThreeMeshFactory( public companion object { internal const val EDGES_OBJECT_NAME: String = "@edges" - - //public val WIREFRAME_KEY: Name = "wireframe".asName() - - //public val WIREFRAME_ENABLED_KEY: Name = WIREFRAME_KEY + ENABLED_KEY - //public val WIREFRAME_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY } } internal fun Mesh.applyProperties(vision: Solid): Mesh = apply { setMaterial(vision) applyEdges(vision) - //applyWireFrame(obj) layers.set(vision.layer) children.forEach { it.layers.set(vision.layer) @@ -104,24 +95,3 @@ public fun Mesh.applyEdges(vision: Solid) { } } } - -//public fun Mesh.applyWireFrame(obj: Solid) { -// children.find { it.name == "@wireframe" }?.let { -// remove(it) -// (it as LineSegments).dispose() -// } -// //inherited wireframe definition, disabled by default -// if (obj.getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY).boolean == true) { -// val bufferGeometry = geometry as? BufferGeometry ?: return -// val material = -// ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node, true) -// add( -// LineSegments( -// WireframeGeometry(bufferGeometry), -// material -// ).apply { -// name = "@wireframe" -// } -// ) -// } -//} \ No newline at end of file From 81aa5d2fcc878fb49308a5cf963eeb7bd484be5a Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 24 Aug 2022 22:46:27 +0300 Subject: [PATCH 031/112] Replace plot properties by a wrapper --- .../mipt/npm/muon/monitor/MMAppComponent.kt | 2 +- gradle.properties | 2 +- .../kscience/visionforge/VisionProperties.kt | 3 +- .../visionforge/plotly/VisionOfPlotly.kt | 72 +++++++++++++++++-- .../visionforge/plotly/VisionOfPlotlyTest.kt | 22 ++++++ 5 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 visionforge-plotly/src/commonTest/kotlin/space/kscience/visionforge/plotly/VisionOfPlotlyTest.kt diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index 3ecb7f9f..4c9649c6 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -25,9 +25,9 @@ import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.tab import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.edges import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.edges import styled.css import styled.styledDiv import styled.styledSpan diff --git a/gradle.properties b/gradle.properties index aeb2ca21..668f0f5d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.jupyter.add.scanner=false -#kotlin.incremental.js.ir=true +kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index cddb6585..eb001b64 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -297,5 +297,4 @@ public operator fun MutableVisionProperties.set(name: Name, value: String): Unit setValue(name, value.asValue()) public operator fun MutableVisionProperties.set(name: String, value: String): Unit = - set(name.parseAsName(), value) - + set(name.parseAsName(), value) \ No newline at end of file diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index 2e89dbf5..54ba4551 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -1,25 +1,83 @@ package space.kscience.visionforge.plotly +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.launch import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.asObservable +import kotlinx.serialization.Transient +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.plotly.Plot import space.kscience.plotly.Plotly -import space.kscience.visionforge.AbstractVision +import space.kscience.visionforge.MutableVisionProperties +import space.kscience.visionforge.Vision import space.kscience.visionforge.html.VisionOutput -import space.kscience.visionforge.root @Serializable @SerialName("vision.plotly") -public class VisionOfPlotly private constructor() : AbstractVision() { +public class VisionOfPlotly private constructor( + @Serializable(MutableMetaSerializer::class) public val meta: MutableMeta, +) : Vision { + public constructor(plot: Plot) : this(plot.meta) + + public val plot: Plot get() = Plot(meta.asObservable()) + + @Transient + override var parent: Vision? = null + + @Transient + override val properties: MutableVisionProperties = object : MutableVisionProperties { + override fun setProperty(name: Name, node: Meta?, notify: Boolean) { + meta.setMeta(name, node) + } + + override fun setValue(name: Name, value: Value?, notify: Boolean) { + meta.setValue(name, value) + } + + override val own: Meta get() = meta + + override val descriptor: MetaDescriptor? get() = this@VisionOfPlotly.descriptor + + override fun getProperty( + name: Name, + inherit: Boolean?, + includeStyles: Boolean?, + ): MutableMeta = meta.getMeta(name) ?: MutableMeta() + + override fun getValue( + name: Name, + inherit: Boolean?, + includeStyles: Boolean?, + ): Value? = meta.getValue(name) + + override val changes: Flow = if (meta is ObservableMeta) { + callbackFlow { + meta.onChange(this) { + launch { + send(it) + } + } + awaitClose { + meta.removeListener(this) + } + } + } else emptyFlow() + + + override fun invalidate(propertyName: Name) { + // Do nothing + } - public constructor(plot: Plot) : this() { - properties.setProperty(Name.EMPTY, plot.meta) } - public val plot: Plot get() = Plot(properties.root().asObservable()) + + override val descriptor: MetaDescriptor? = null // TODO add descriptor for Plot } public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this) diff --git a/visionforge-plotly/src/commonTest/kotlin/space/kscience/visionforge/plotly/VisionOfPlotlyTest.kt b/visionforge-plotly/src/commonTest/kotlin/space/kscience/visionforge/plotly/VisionOfPlotlyTest.kt new file mode 100644 index 00000000..7634e73d --- /dev/null +++ b/visionforge-plotly/src/commonTest/kotlin/space/kscience/visionforge/plotly/VisionOfPlotlyTest.kt @@ -0,0 +1,22 @@ +package space.kscience.visionforge.plotly + +import space.kscience.plotly.Plotly +import space.kscience.plotly.scatter +import kotlin.test.Test +import kotlin.test.assertTrue + +class VisionOfPlotlyTest { + @Test + fun conversion(){ + val plot = Plotly.plot { + scatter { + x(1,2,3) + y(1,2,3) + } + } + val vision = VisionOfPlotly(plot) +// println(vision.plot.toJsonString()) +// println(vision.plot.data.toJsonString()) + assertTrue { vision.plot.data.first().x.doubles.size == 3} + } +} \ No newline at end of file From 960d17855b6b78fbca348da3478f58cefcef8b36 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 25 Aug 2022 22:48:00 +0300 Subject: [PATCH 032/112] Fix client updates --- .../playground/src/jvmMain/kotlin/gdmlIaxo.kt | 6 --- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 4 +- .../kscience/visionforge/VisionChange.kt | 44 ++++++++++++------- .../kscience/visionforge/VisionProperties.kt | 8 +++- .../kscience/visionforge/VisionClient.kt | 32 ++++++++++---- .../visionforge/server/VisionServer.kt | 5 ++- .../kscience/visionforge/three/jsMain.kt | 6 ++- 7 files changed, 69 insertions(+), 36 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt b/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt index ee47c461..954a30c9 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt @@ -1,20 +1,14 @@ package space.kscience.visionforge.examples import space.kscience.gdml.GdmlShowCase -import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.gdml import space.kscience.visionforge.solid.Solids -import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.solid fun main() = makeVisionFile { vision("canvas") { requirePlugin(Solids) solid { - ambientLight { - color.set(Colors.white) - } gdml(GdmlShowCase.babyIaxo(), "D0") } } diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index e7326982..645073d3 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -6,6 +6,7 @@ import kotlinx.html.div import kotlinx.html.h1 import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.meta.Null import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors @@ -56,7 +57,8 @@ fun main() { val targetVision = sat[target] as Solid targetVision.color.set("red") delay(1000) - targetVision.color.clear() + //use to ensure that color is cleared + targetVision.color.value = Null delay(500) } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 0001dd44..369900bf 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -5,6 +5,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor @@ -47,7 +49,7 @@ public object NullVision : Vision { /** * An update for a [Vision] */ -public class VisionChangeBuilder(private val manager: VisionManager) : MutableVisionContainer { +public class VisionChangeBuilder : MutableVisionContainer { private var vision: Vision? = null private var propertyChange = MutableMeta() @@ -57,7 +59,14 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi @Synchronized private fun getOrPutChild(visionName: Name): VisionChangeBuilder = - children.getOrPut(visionName) { VisionChangeBuilder(manager) } + children.getOrPut(visionName) { VisionChangeBuilder() } + + @Synchronized + internal fun reset() { + vision = null + propertyChange = MutableMeta() + children.clear() + } public fun propertyChanged(visionName: Name, propertyName: Name, item: Meta?) { if (visionName == Name.EMPTY) { @@ -82,10 +91,10 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi /** * Isolate collected changes by creating detached copies of given visions */ - public fun deepCopy(): VisionChange = VisionChange( - vision?.deepCopy(manager), + public fun deepCopy(visionManager: VisionManager): VisionChange = VisionChange( + vision?.deepCopy(visionManager), if (propertyChange.isEmpty()) null else propertyChange.seal(), - if (children.isEmpty()) null else children.mapValues { it.value.deepCopy() } + if (children.isEmpty()) null else children.mapValues { it.value.deepCopy(visionManager) } ) } @@ -102,12 +111,13 @@ public data class VisionChange( ) public inline fun VisionManager.VisionChange(block: VisionChangeBuilder.() -> Unit): VisionChange = - VisionChangeBuilder(this).apply(block).deepCopy() + VisionChangeBuilder().apply(block).deepCopy(this) private fun CoroutineScope.collectChange( name: Name, source: Vision, + mutex: Mutex, collector: () -> VisionChangeBuilder, ) { @@ -120,7 +130,7 @@ private fun CoroutineScope.collectChange( val children = source.children //Subscribe for children changes children?.forEach { token, child -> - collectChange(name + token, child, collector) + collectChange(name + token, child, mutex, collector) } //Subscribe for structure change @@ -128,9 +138,11 @@ private fun CoroutineScope.collectChange( val after = children[changedName] val fullName = name + changedName if (after != null) { - collectChange(fullName, after, collector) + collectChange(fullName, after, mutex, collector) + } + mutex.withLock { + collector().setChild(fullName, after) } - collector().setChild(fullName, after) }?.launchIn(this) } @@ -141,24 +153,26 @@ public fun Vision.flowChanges( collectionDuration: Duration, ): Flow = flow { val manager = manager ?: error("Orphan vision could not collect changes") - - var collector = VisionChangeBuilder(manager) coroutineScope { - collectChange(Name.EMPTY, this@flowChanges) { collector } + val collector = VisionChangeBuilder() + val mutex = Mutex() + collectChange(Name.EMPTY, this@flowChanges, mutex) { collector } //Send initial vision state val initialChange = VisionChange(vision = deepCopy(manager)) emit(initialChange) - while (currentCoroutineContext().isActive) { + while (true) { //Wait for changes to accumulate delay(collectionDuration) //Propagate updates only if something is changed if (!collector.isEmpty()) { //emit changes - emit(collector.deepCopy()) + emit(collector.deepCopy(manager)) //Reset the collector - collector = VisionChangeBuilder(manager) + mutex.withLock { + collector.reset() + } } } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index eb001b64..52bdd52f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -189,7 +189,9 @@ public abstract class AbstractVisionProperties( } override fun setProperty(name: Name, node: Meta?, notify: Boolean) { - //TODO check old value? + //ignore if the value is the same as existing + if (own?.getMeta(name) == node) return + if (name.isEmpty()) { properties = node?.asMutableMeta() } else if (node == null) { @@ -203,7 +205,9 @@ public abstract class AbstractVisionProperties( } override fun setValue(name: Name, value: Value?, notify: Boolean) { - //TODO check old value? + //ignore if the value is the same as existing + if (own?.getValue(name) == value) return + if (value == null) { properties?.getMeta(name)?.value = null } else { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index 41e3b8e6..f54b7d5d 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -3,8 +3,8 @@ package space.kscience.visionforge import kotlinx.browser.document import kotlinx.browser.window import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import org.w3c.dom.* import org.w3c.dom.url.URL import space.kscience.dataforge.context.* @@ -63,6 +63,17 @@ public class VisionClient : AbstractPlugin() { private fun Element.getFlag(attribute: String): Boolean = attributes[attribute]?.value != null + + private val changeCollector = VisionChangeBuilder() + + public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { + changeCollector.propertyChanged(visionName, propertyName, item) + } + + public fun visionChanged(name: Name?, child: Vision?) { + changeCollector.setChild(name, child) + } + private fun renderVision(name: String, element: Element, vision: Vision?, outputMeta: Meta) { if (vision != null) { vision.setAsRoot(visionManager) @@ -115,12 +126,13 @@ public class VisionClient : AbstractPlugin() { val feedbackAggregationTime = meta["aggregationTime"]?.int ?: 300 onopen = { - feedbackJob = vision.flowChanges( - feedbackAggregationTime.milliseconds, - ).onEach { change -> - send(visionManager.encodeToString(change)) - }.launchIn(visionManager.context) - + feedbackJob = visionManager.context.launch { + delay(feedbackAggregationTime.milliseconds) + if (!changeCollector.isEmpty()) { + send(visionManager.encodeToString(changeCollector.deepCopy(visionManager))) + changeCollector.reset() + } + } console.info("WebSocket update channel established for output '$name'") } @@ -165,6 +177,7 @@ public class VisionClient : AbstractPlugin() { logger.info { "Found embedded vision for output with name $name" } renderVision(name, element, embeddedVision, outputMeta) } + element.attributes[OUTPUT_FETCH_ATTRIBUTE] != null -> { val attr = element.attributes[OUTPUT_FETCH_ATTRIBUTE]!! @@ -192,6 +205,7 @@ public class VisionClient : AbstractPlugin() { } } } + else -> error("No embedded vision data / fetch url for $name") } element.setAttribute(OUTPUT_RENDERED, "true") @@ -204,7 +218,7 @@ public class VisionClient : AbstractPlugin() { ) else super.content(target) public companion object : PluginFactory { - override fun build(context: Context, meta: Meta): VisionClient = VisionClient() + override fun build(context: Context, meta: Meta): VisionClient = VisionClient() override val tag: PluginTag = PluginTag(name = "vision.client", group = PluginTag.DATAFORGE_GROUP) diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index d4bf939f..967a5d82 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -122,8 +122,10 @@ public class VisionServer internal constructor( launch { incoming.consumeEach { + val data = it.data.decodeToString() + application.log.debug("Received update: \n$data") val change = visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(), it.data.decodeToString() + VisionChange.serializer(),data ) vision.update(change) } @@ -136,6 +138,7 @@ public class VisionServer internal constructor( VisionChange.serializer(), update ) + application.log.debug("Sending update: \n$json") outgoing.send(Frame.Text(json)) }.collect() } diff --git a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt index ed2908f5..69a9ac51 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt @@ -6,6 +6,8 @@ import space.kscience.visionforge.solid.three.ThreePlugin @DFExperimental -public fun main(): Unit = runVisionClient { - plugin(ThreePlugin) +public fun main(): Unit { + runVisionClient { + plugin(ThreePlugin) + } } \ No newline at end of file From 3c51060e2eb157489ace0e0e28637a34af38bea3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 17 Nov 2022 21:49:14 +0300 Subject: [PATCH 033/112] Refactor pages --- CHANGELOG.md | 1 + build.gradle.kts | 33 ++++--- .../mipt/npm/root/serialization/jsonToRoot.kt | 1 + .../src/jvmMain/kotlin/formServer.kt | 4 +- .../src/jvmMain/kotlin/plotlyVision.kt | 85 +++++++++++++++++- .../src/jvmMain/kotlin/serverExtensions.kt | 8 +- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 7 +- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../src/jvmMain/kotlin/JupyterPluginBase.kt | 2 +- .../visionforge/bootstrap/outputConfig.kt | 2 +- .../bootstrap/visionPropertyEditor.kt | 1 - .../kscience/visionforge/react/MetaViewer.kt | 2 +- .../visionforge/react/MultiSelectChooser.kt | 2 +- .../visionforge/react/PropertyEditor.kt | 2 +- .../visionforge/react/RangeValueChooser.kt | 2 +- .../kscience/visionforge/react/VisionTree.kt | 2 +- .../visionforge/react/valueChooser.kt | 2 +- .../ringPropertyEditor.kt | 1 - .../ringThreeControls.kt | 2 +- visionforge-core/build.gradle.kts | 2 +- .../kscience/visionforge/VisionChange.kt | 18 ++-- .../html/{Page.kt => VisionPage.kt} | 11 ++- .../kscience/visionforge/html/headers.kt | 2 +- .../kscience/visionforge/html/htmlExport.kt | 11 ++- .../visionforge/markup/MarkupPlugin.kt | 5 ++ .../visionforge/markup/MarkupPlugin.kt | 2 +- .../visionforge/markup/MarkupPlugin.kt | 24 ++++++ .../visionforge/server/VisionServer.kt | 86 ++++++++++++------- visionforge-threejs/build.gradle.kts | 1 + .../solid/three/ThreeCanvasLabelFactory.kt | 15 ++-- .../visionforge/three/serverExtensions.kt | 8 +- 32 files changed, 251 insertions(+), 97 deletions(-) rename visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/{Page.kt => VisionPage.kt} (82%) create mode 100644 visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt create mode 100644 visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b7d7766..afc740a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - MeshLine for thick lines ### Changed +- API update for server and pages - Edges moved to solids module for easier construction - Visions **must** be rooted in order to subscribe to updates. - Visions use flows instead of direct subscriptions. diff --git a/build.gradle.kts b/build.gradle.kts index 939d197b..7be6270f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,7 @@ +import space.kscience.gradle.isInDevelopment +import space.kscience.gradle.useApache2Licence +import space.kscience.gradle.useSPCTeam + plugins { id("space.kscience.gradle.project") // id("org.jetbrains.kotlinx.kover") version "0.5.0" @@ -6,9 +10,9 @@ plugins { val dataforgeVersion by extra("0.6.0-dev-15") val fxVersion by extra("11") -allprojects{ +allprojects { group = "space.kscience" - version = "0.3.0-dev-2" + version = "0.3.0-dev-3" } subprojects { @@ -21,16 +25,26 @@ subprojects { maven("https://maven.jzy3d.org/releases") } - tasks.withType{ - kotlinOptions{ + tasks.withType { + kotlinOptions { freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers" } } } ksciencePublish { - github("visionforge") - space() + pom("https://github.com/SciProgCentre/visionforge") { + useApache2Licence() + useSPCTeam() + } + github(githubProject = "visionforge", githubOrg = "SciProgCentre") + space( + if (isInDevelopment) { + "https://maven.pkg.jetbrains.space/spc/p/sci/dev" + } else { + "https://maven.pkg.jetbrains.space/spc/p/sci/maven" + } + ) sonatype() } @@ -38,9 +52,4 @@ apiValidation { ignoredPackages.add("info.laht.threekt") } -readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md") - - -//rootProject.extensions.configure { -// versions.webpackCli.version = "4.10.0" -//} \ No newline at end of file +readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md") \ No newline at end of file diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt index 96c6098c..1685c1ac 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt @@ -218,6 +218,7 @@ private object RootDecoder { var value: Any? = null + @Suppress("UNCHECKED_CAST") fun getOrPutValue(builder: (JsonElement) -> T): T { if (value == null) { value = builder(element) diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index 7397b6b6..4d60a423 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -4,7 +4,7 @@ import kotlinx.html.* import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.fetch import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.html.Page +import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.html.formFragment import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.server.close @@ -15,7 +15,7 @@ fun main() { val visionManager = Global.fetch(VisionManager) val server = visionManager.serve { - page(header = Page.scriptHeader("js/visionforge-playground.js")) { + page(VisionPage.scriptHeader("js/visionforge-playground.js")) { val form = formFragment("form") { label { htmlFor = "fname" diff --git a/demo/playground/src/jvmMain/kotlin/plotlyVision.kt b/demo/playground/src/jvmMain/kotlin/plotlyVision.kt index 4b91c352..c1ef18a8 100644 --- a/demo/playground/src/jvmMain/kotlin/plotlyVision.kt +++ b/demo/playground/src/jvmMain/kotlin/plotlyVision.kt @@ -1,15 +1,92 @@ package space.kscience.visionforge.examples -import space.kscience.plotly.scatter +import space.kscience.dataforge.meta.Value +import space.kscience.plotly.layout +import space.kscience.plotly.models.* import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.plotly.plotly fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { vision { + val trace1 = Violin { + text("sample length: 32") + marker { + line { + width = 2 + color("#bebada") + } + symbol = Symbol.valueOf("line-ns") + } + orientation = Orientation.h + hoveron = ViolinHoveron.`points+kde` + meanline { + visible = true + } + legendgroup = "F" + scalegroup = "F" + points = ViolinPoints.all + pointpos = 1.2 + jitter = 0 + box { + visible = true + } + scalemode = ViolinScaleMode.count + showlegend = false + side = ViolinSide.positive + y0 = Value.of(0) + line { + color("#bebada") + } + name = "F" + + x(10.07, 34.83, 10.65, 12.43, 24.08, 13.42, 12.48, 29.8, 14.52, 11.38, + 20.27, 11.17, 12.26, 18.26, 8.51, 10.33, 14.15, 13.16, 17.47, 27.05, 16.43, + 8.35, 18.64, 11.87, 19.81, 43.11, 13.0, 12.74, 13.0, 16.4, 16.47, 18.78) + } + + val trace2 = Violin { + text("sample length: 32") + marker { + line { + width = 2 + color("#8dd3c7") + } + symbol = Symbol.valueOf("line-ns") + } + orientation = Orientation.h + hoveron = ViolinHoveron.`points+kde` + meanline { + visible = true + } + legendgroup = "M" + scalegroup = "M" + points = ViolinPoints.all + pointpos = -1.2 + jitter = 0 + box { + visible = true + } + scalemode = ViolinScaleMode.count + showlegend = false + side = ViolinSide.negative + y0 = Value.of(0) + + line { + color("#8dd3c7") + } + name = "M" + + x(27.2, 22.76, 17.29, 19.44, 16.66, 32.68, 15.98, 13.03, 18.28, 24.71, + 21.16, 11.69, 14.26, 15.95, 8.52, 22.82, 19.08, 16.0, 34.3, 41.19, 9.78, + 7.51, 28.44, 15.48, 16.58, 7.56, 10.34, 13.51, 18.71, 20.53) + } + plotly { - scatter { - x(1, 2, 3) - y(5, 8, 7) + traces(trace1, trace2) + layout { + width = 800 + height = 800 + title = "Advanced Violin Plot" } } } diff --git a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt index e8be7112..eda8ba2b 100644 --- a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt +++ b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt @@ -2,8 +2,8 @@ package space.kscience.visionforge.examples import space.kscience.dataforge.context.Global import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.Page import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.html.importScriptHeader import space.kscience.visionforge.makeFile import java.awt.Desktop @@ -16,10 +16,10 @@ public fun makeVisionFile( show: Boolean = true, content: HtmlVisionFragment, ): Unit { - val actualPath = Page(Global, content = content).makeFile(path) { actualPath -> + val actualPath = VisionPage(Global, content = content).makeFile(path) { actualPath -> mapOf( - "title" to Page.title(title), - "playground" to Page.importScriptHeader("js/visionforge-playground.js", resourceLocation, actualPath), + "title" to VisionPage.title(title), + "playground" to VisionPage.importScriptHeader("js/visionforge-playground.js", resourceLocation, actualPath), ) } if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index 645073d3..9c645d81 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -10,8 +10,8 @@ import space.kscience.dataforge.meta.Null import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors -import space.kscience.visionforge.html.Page -import space.kscience.visionforge.html.plus +import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.server.DataServeMode import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser import space.kscience.visionforge.server.serve @@ -37,7 +37,8 @@ fun main() { } val server = satContext.visionManager.serve { - page(header = Page.threeJsHeader + Page.styleSheetHeader("css/styles.css")) { + dataMode = DataServeMode.UPDATE + page(VisionPage.threeJsHeader, VisionPage.styleSheetHeader("css/styles.css")) { div("flex-column") { h1 { +"Satellite detector demo" } vision { sat } diff --git a/gradle.properties b/gradle.properties index 668f0f5d..056b8ac8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,4 @@ kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.12.0-kotlin-1.7.20-Beta \ No newline at end of file +toolsVersion=0.13.3-kotlin-1.7.20 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa991fce..ae04661e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt b/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt index 2fbe51c8..944f1493 100644 --- a/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt +++ b/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt @@ -49,7 +49,7 @@ public abstract class JupyterPluginBase(final override val context: Context) : J } - render { page -> + render { page -> HTML(page.render(createHTML()), true) } diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt index 3dfba202..a37469ca 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt @@ -8,7 +8,7 @@ import kotlinx.css.padding import kotlinx.css.properties.border import kotlinx.css.px import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event +import kotlinx.html.org.w3c.dom.events.Event import org.w3c.files.Blob import org.w3c.files.BlobPropertyBag import react.FC diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index 5e30f838..6ea0659c 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -3,7 +3,6 @@ package space.kscience.visionforge.bootstrap import org.w3c.dom.Element import react.RBuilder import react.dom.client.createRoot -import react.key import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.isEmpty import space.kscience.visionforge.Vision diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt index 651c9d31..d6fff754 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge.react import kotlinx.css.Align import kotlinx.css.alignItems import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event +import kotlinx.html.org.w3c.dom.events.Event import react.* import react.dom.a import react.dom.attrs diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt index fc635d21..5e8da06c 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt @@ -1,10 +1,10 @@ package space.kscience.visionforge.react import kotlinx.html.js.onChangeFunction +import kotlinx.html.org.w3c.dom.events.Event import org.w3c.dom.HTMLOptionElement import org.w3c.dom.HTMLSelectElement import org.w3c.dom.asList -import org.w3c.dom.events.Event import react.FC import react.dom.attrs import react.dom.option diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index f5d28f19..a31a04fb 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.launch import kotlinx.css.* import kotlinx.css.properties.TextDecoration import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event +import kotlinx.html.org.w3c.dom.events.Event import react.* import react.dom.attrs import space.kscience.dataforge.meta.* diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index 309e4b7f..3ebe4d51 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -4,8 +4,8 @@ import kotlinx.css.pct import kotlinx.css.width import kotlinx.html.InputType import kotlinx.html.js.onChangeFunction +import kotlinx.html.org.w3c.dom.events.Event import org.w3c.dom.HTMLInputElement -import org.w3c.dom.events.Event import react.FC import react.dom.attrs import react.fc diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt index 9866c30e..8ec0185c 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt @@ -7,7 +7,7 @@ import kotlinx.css.cursor import kotlinx.css.properties.TextDecorationLine import kotlinx.css.properties.textDecoration import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event +import kotlinx.html.org.w3c.dom.events.Event import react.* import react.dom.attrs import space.kscience.dataforge.names.Name diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index 96c1e6fe..bc6f1979 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -7,9 +7,9 @@ import kotlinx.css.width import kotlinx.html.InputType import kotlinx.html.js.onChangeFunction import kotlinx.html.js.onKeyDownFunction +import kotlinx.html.org.w3c.dom.events.Event import org.w3c.dom.HTMLInputElement import org.w3c.dom.HTMLSelectElement -import org.w3c.dom.events.Event import react.FC import react.Props import react.dom.attrs diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt index b4ce3284..a3f81adb 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt @@ -4,7 +4,6 @@ import org.w3c.dom.Element import react.RBuilder import react.dom.client.createRoot import react.dom.p -import react.key import ringui.Island import ringui.SmartTabs import ringui.Tab diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt index 6a440e71..d59b37b9 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt @@ -8,7 +8,7 @@ import kotlinx.css.padding import kotlinx.css.properties.border import kotlinx.css.px import kotlinx.html.js.onClickFunction -import org.w3c.dom.events.Event +import kotlinx.html.org.w3c.dom.events.Event import org.w3c.files.Blob import org.w3c.files.BlobPropertyBag import react.FC diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index a8886521..6a170d02 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -9,7 +9,7 @@ kotlin { commonMain { dependencies { api("space.kscience:dataforge-context:$dataforgeVersion") - api(npmlibs.kotlinx.html) + api("org.jetbrains.kotlinx:kotlinx-html:0.8.0") api("org.jetbrains.kotlin-wrappers:kotlin-css") } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 369900bf..e95dbd1b 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -118,14 +118,14 @@ private fun CoroutineScope.collectChange( name: Name, source: Vision, mutex: Mutex, - collector: () -> VisionChangeBuilder, + collector: VisionChangeBuilder, ) { //Collect properties change - source.onPropertyChange(this) { propertyName -> + source.properties.changes.onEach { propertyName -> val newItem = source.properties.own?.get(propertyName) - collector().propertyChanged(name, propertyName, newItem) - } + collector.propertyChanged(name, propertyName, newItem) + }.launchIn(this) val children = source.children //Subscribe for children changes @@ -141,7 +141,7 @@ private fun CoroutineScope.collectChange( collectChange(fullName, after, mutex, collector) } mutex.withLock { - collector().setChild(fullName, after) + collector.setChild(fullName, after) } }?.launchIn(this) } @@ -156,7 +156,7 @@ public fun Vision.flowChanges( coroutineScope { val collector = VisionChangeBuilder() val mutex = Mutex() - collectChange(Name.EMPTY, this@flowChanges, mutex) { collector } + collectChange(Name.EMPTY, this@flowChanges, mutex, collector) //Send initial vision state val initialChange = VisionChange(vision = deepCopy(manager)) @@ -167,10 +167,10 @@ public fun Vision.flowChanges( delay(collectionDuration) //Propagate updates only if something is changed if (!collector.isEmpty()) { - //emit changes - emit(collector.deepCopy(manager)) - //Reset the collector mutex.withLock { + //emit changes + emit(collector.deepCopy(manager)) + //Reset the collector collector.reset() } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/Page.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt similarity index 82% rename from visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/Page.kt rename to visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt index bdd5e417..cb284b14 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/Page.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt @@ -3,9 +3,14 @@ package space.kscience.visionforge.html import kotlinx.html.* import space.kscience.dataforge.context.Context -public data class Page( +/** + * A structure representing a single page with Visions to be rendered. + * + * @param pageHeaders static headers for this page. + */ +public data class VisionPage( public val context: Context, - public val headers: Map = emptyMap(), + public val pageHeaders: Map = emptyMap(), public val content: HtmlVisionFragment, ) { public fun render(root: TagConsumer): R = root.apply { @@ -13,7 +18,7 @@ public data class Page( meta { charset = "utf-8" } - headers.values.forEach { + pageHeaders.values.forEach { fragment(it) } } diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt index d8be2a39..71410372 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt @@ -114,7 +114,7 @@ internal fun fileCssHeader( /** * Make a script header from a resource file, automatically copying file to appropriate location */ -public fun Page.Companion.importScriptHeader( +public fun VisionPage.Companion.importScriptHeader( scriptResource: String, resourceLocation: ResourceLocation, htmlPath: Path? = null, diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index 63f405c3..b3063eb1 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge import kotlinx.html.stream.createHTML import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.html.HtmlFragment -import space.kscience.visionforge.html.Page +import space.kscience.visionforge.html.VisionPage import java.awt.Desktop import java.nio.file.Files import java.nio.file.Path @@ -54,8 +54,11 @@ import java.nio.file.Path // } //} +/** + * Export a [VisionPage] to a file + */ @DFExperimental -public fun Page.makeFile( +public fun VisionPage.makeFile( path: Path?, defaultHeaders: ((Path) -> Map)? = null, ): Path { @@ -64,7 +67,7 @@ public fun Page.makeFile( } ?: Files.createTempFile("tempPlot", ".html") val actualDefaultHeaders = defaultHeaders?.invoke(actualFile) - val actualPage = if (actualDefaultHeaders == null) this else copy(headers = actualDefaultHeaders + headers) + val actualPage = if (actualDefaultHeaders == null) this else copy(pageHeaders = actualDefaultHeaders + pageHeaders) val htmlString = actualPage.render(createHTML()) @@ -73,7 +76,7 @@ public fun Page.makeFile( } @DFExperimental -public fun Page.show(path: Path? = null) { +public fun VisionPage.show(path: Path? = null) { val actualPath = makeFile(path) Desktop.getDesktop().browse(actualPath.toFile().toURI()) } \ No newline at end of file diff --git a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt new file mode 100644 index 00000000..7ff98f91 --- /dev/null +++ b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -0,0 +1,5 @@ +package space.kscience.visionforge.markup + +import space.kscience.visionforge.VisionPlugin + +public expect class MarkupPlugin: VisionPlugin \ No newline at end of file diff --git a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index 939669a0..d7ebba04 100644 --- a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -16,7 +16,7 @@ import space.kscience.visionforge.markup.VisionOfMarkup.Companion.COMMONMARK_FOR import space.kscience.visionforge.markup.VisionOfMarkup.Companion.GFM_FORMAT import kotlin.reflect.KClass -public class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { +public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { public val visionClient: VisionClient by require(VisionClient) override val tag: PluginTag get() = Companion.tag override val visionSerializersModule: SerializersModule get() = markupSerializersModule diff --git a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt new file mode 100644 index 00000000..211064ff --- /dev/null +++ b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -0,0 +1,24 @@ +package space.kscience.visionforge.markup + +import kotlinx.serialization.modules.SerializersModule +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.PluginFactory +import space.kscience.dataforge.context.PluginTag +import space.kscience.dataforge.meta.Meta +import space.kscience.visionforge.VisionPlugin +import kotlin.reflect.KClass + +public actual class MarkupPlugin : VisionPlugin() { + override val visionSerializersModule: SerializersModule get() = markupSerializersModule + + override val tag: PluginTag get() = Companion.tag + + public companion object : PluginFactory { + override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP) + + override val type: KClass = MarkupPlugin::class + + override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() + + } +} \ No newline at end of file diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 967a5d82..364d3162 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -1,7 +1,10 @@ package space.kscience.visionforge.server import io.ktor.http.* -import io.ktor.server.application.* +import io.ktor.server.application.Application +import io.ktor.server.application.call +import io.ktor.server.application.install +import io.ktor.server.application.log import io.ktor.server.cio.CIO import io.ktor.server.engine.ApplicationEngine import io.ktor.server.engine.embeddedServer @@ -24,7 +27,6 @@ import kotlinx.coroutines.withContext import kotlinx.html.* import kotlinx.html.stream.createHTML import space.kscience.dataforge.meta.* -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionChange @@ -32,6 +34,7 @@ import space.kscience.visionforge.VisionManager import space.kscience.visionforge.flowChanges import space.kscience.visionforge.html.HtmlFragment import space.kscience.visionforge.html.HtmlVisionFragment +import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.html.visionFragment import space.kscience.visionforge.server.VisionServer.Companion.DEFAULT_PAGE import java.awt.Desktop @@ -39,6 +42,23 @@ import java.net.URI import kotlin.time.Duration.Companion.milliseconds +public enum class DataServeMode { + /** + * Embed the initial state of the vision inside its html tag. + */ + EMBED, + + /** + * Fetch data on vision load. Do not embed data. + */ + FETCH, + + /** + * Connect to server to get pushes. The address of the server is embedded in the tag. + */ + UPDATE +} + /** * A ktor plugin container with given [routing] * @param serverUrl a server url including root route @@ -63,25 +83,20 @@ public class VisionServer internal constructor( */ public var cacheFragments: Boolean by meta.boolean(true) - /** - * Embed the initial state of the vision inside its html tag. Default: `true` - */ - public var dataEmbed: Boolean by meta.boolean(true, Name.parse("data.embed")) + public var dataMode: DataServeMode by meta.enum(DataServeMode.UPDATE) - /** - * Fetch data on vision load. Overrides embedded data. Default: `false` - */ - public var dataFetch: Boolean by meta.boolean(false, Name.parse("data.fetch")) + private val serverHeaders: MutableMap = mutableMapOf() /** - * Connect to server to get pushes. The address of the server is embedded in the tag. Default: `true` + * Set up a default header that is automatically added to all pages on this server */ - public var dataUpdate: Boolean by meta.boolean(true, Name.parse("data.update")) + public fun header(key: String, block: HtmlFragment) { + serverHeaders[key] = block + } private fun HTML.visionPage( - title: String, pagePath: String, - header: HtmlFragment, + headers: Map, visionFragment: HtmlVisionFragment, ): Map { var visionMap: Map? = null @@ -89,17 +104,18 @@ public class VisionServer internal constructor( head { meta { charset = "utf-8" - header() } - title(title) - consumer.header() + (serverHeaders + headers).values.forEach { + consumer.it() + } } body { //Load the fragment and remember all loaded visions visionMap = visionFragment( context = visionManager.context, - embedData = true, - fetchUpdatesUrl = "$serverUrl$pagePath/ws", + embedData = dataMode == DataServeMode.EMBED, + fetchDataUrl = if (dataMode != DataServeMode.EMBED) "$serverUrl$pagePath/data" else null, + fetchUpdatesUrl = if (dataMode == DataServeMode.UPDATE) "$serverUrl$pagePath/ws" else null, fragment = visionFragment ) } @@ -110,7 +126,6 @@ public class VisionServer internal constructor( /** * Server a map of visions without providing explicit html page for them */ - @OptIn(DFExperimental::class) private fun serveVisions(route: Route, visions: Map): Unit = route { application.log.info("Serving visions $visions at $route") @@ -125,7 +140,7 @@ public class VisionServer internal constructor( val data = it.data.decodeToString() application.log.debug("Received update: \n$data") val change = visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(),data + VisionChange.serializer(), data ) vision.update(change) } @@ -133,7 +148,7 @@ public class VisionServer internal constructor( try { withContext(visionManager.context.coroutineContext) { - vision.flowChanges(updateInterval.milliseconds).onEach { update -> + vision.flowChanges(updateInterval.milliseconds).onEach { update -> val json = visionManager.jsonFormat.encodeToString( VisionChange.serializer(), update @@ -191,12 +206,11 @@ public class VisionServer internal constructor( }.finalize() /** - * Serve a page, potentially containing any number of visions at a given [pagePath] with given [headers]. + * Serve a page, potentially containing any number of visions at a given [route] with given [header]. */ public fun page( - pagePath: String = DEFAULT_PAGE, - title: String = "VisionForge server page '$pagePath'", - header: HtmlFragment = {}, + route: String = DEFAULT_PAGE, + headers: Map, visionFragment: HtmlVisionFragment, ) { val visions = HashMap() @@ -204,13 +218,13 @@ public class VisionServer internal constructor( val cachedHtml: String? = if (cacheFragments) { //Create and cache page html and map of visions createHTML(true).html { - visions.putAll(visionPage(title, pagePath, header, visionFragment)) + visions.putAll(visionPage(route, headers, visionFragment)) } } else { null } - root.route(pagePath) { + root.route(route) { serveVisions(this, visions) //filled pages get { @@ -218,7 +232,7 @@ public class VisionServer internal constructor( //re-create html and vision list on each call call.respondHtml { visions.clear() - visions.putAll(visionPage(title, pagePath, header, visionFragment)) + visions.putAll(visionPage(route, headers, visionFragment)) } } else { //Use cached html @@ -226,8 +240,22 @@ public class VisionServer internal constructor( } } } + } + public fun page( + vararg headers: HtmlFragment, + route: String = DEFAULT_PAGE, + title: String = "VisionForge server page '$route'", + visionFragment: HtmlVisionFragment, + ) { + page(route, mapOf("title" to VisionPage.title(title)) + headers.associateBy { it.hashCode().toString() }, visionFragment) + } + /** + * Render given [VisionPage] at server + */ + public fun page(route: String, page: VisionPage) { + page(route = route, headers = page.pageHeaders, visionFragment = page.content) } public companion object { diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index 7ba2c555..7cf2a60f 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -3,6 +3,7 @@ plugins { } kotlin{ + explicitApi = org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode.Disabled js{ binaries.library() } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index 7a0f1c7b..b9f2a7d2 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -24,6 +24,9 @@ public object ThreeCanvasLabelFactory : ThreeFactory { override fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { val canvas = document.createElement("canvas") as HTMLCanvasElement + canvas.width = 200 + canvas.height = 200 + canvas.getContext("2d").apply { this as CanvasRenderingContext2D font = "Bold ${vision.fontSize}pt ${vision.fontFamily}" @@ -43,15 +46,13 @@ public object ThreeCanvasLabelFactory : ThreeFactory { val texture = Texture(canvas) texture.needsUpdate = true - val material = MeshBasicMaterial().apply { - map = texture - side = DoubleSide - transparent = true - } - val mesh = Mesh( PlaneGeometry(canvas.width, canvas.height), - material + MeshBasicMaterial().apply { + map = texture + side = DoubleSide + transparent = true + } ) mesh.updatePosition(vision) diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt index 6c70e0ed..1261a0de 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt @@ -8,7 +8,7 @@ import java.awt.Desktop import java.nio.file.Path -public val Page.Companion.threeJsHeader: HtmlFragment get() = scriptHeader("js/visionforge-three.js") +public val VisionPage.Companion.threeJsHeader: HtmlFragment get() = scriptHeader("js/visionforge-three.js") @DFExperimental @@ -19,10 +19,10 @@ public fun makeThreeJsFile( show: Boolean = true, content: HtmlVisionFragment, ): Unit { - val actualPath = Page(Global, content = content).makeFile(path) { actualPath -> + val actualPath = VisionPage(Global, content = content).makeFile(path) { actualPath -> mapOf( - "title" to Page.title(title), - "threeJs" to Page.importScriptHeader("js/visionforge-three.js", resourceLocation, actualPath) + "title" to VisionPage.title(title), + "threeJs" to VisionPage.importScriptHeader("js/visionforge-three.js", resourceLocation, actualPath) ) } if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) From eae1316de5fb9703c31589f358f2d06df731c49f Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 20 Nov 2022 19:42:05 +0300 Subject: [PATCH 034/112] Update static/dynamic rendering logic --- build.gradle.kts | 2 +- .../ru/mipt/npm/muon/monitor/MMDemoApp.kt | 4 +- demo/playground/notebooks/demo3D.ipynb | 339 ++++++++++++++++++ .../src/jsMain/kotlin/playgroundMain.kt | 2 + .../kotlin/VisionForgePlayGroundForJupyter.kt | 4 +- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 2 - .../visionforge/solid/demo/ThreeDemoApp.kt | 4 +- jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt | 51 +++ ...onForgeForNotebook.kt => VFForNotebook.kt} | 44 ++- ...yterPluginBase.kt => VFIntegrationBase.kt} | 31 +- .../src/jvmMain/kotlin/GdmlForJupyter.kt | 4 +- .../visionforge/html/HtmlVisionRenderer.kt | 28 +- .../kscience/visionforge/html/VisionPage.kt | 14 - .../space/kscience/visionforge/Application.kt | 22 +- .../kscience/visionforge/VisionClient.kt | 48 ++- .../kscience/visionforge/html/htmlExport.kt | 27 +- .../visionforge/server/VisionServer.kt | 17 +- 17 files changed, 539 insertions(+), 104 deletions(-) create mode 100644 demo/playground/notebooks/demo3D.ipynb create mode 100644 jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt rename jupyter/src/jvmMain/kotlin/{VisionForgeForNotebook.kt => VFForNotebook.kt} (70%) rename jupyter/src/jvmMain/kotlin/{JupyterPluginBase.kt => VFIntegrationBase.kt} (66%) diff --git a/build.gradle.kts b/build.gradle.kts index 7be6270f..b5e3fd7e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-3" + version = "0.3.0-dev-4" } subprojects { diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 4b18291b..50e51859 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -1,6 +1,6 @@ package ru.mipt.npm.muon.monitor -import kotlinx.browser.document +import org.w3c.dom.Document import react.dom.client.createRoot import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch @@ -13,7 +13,7 @@ import space.kscience.visionforge.startApplication private class MMDemoApp : Application { - override fun start(state: Map) { + override fun start(document: Document, state: Map) { val context = Context("MM-demo") { plugin(ThreePlugin) diff --git a/demo/playground/notebooks/demo3D.ipynb b/demo/playground/notebooks/demo3D.ipynb new file mode 100644 index 00000000..1efcd3c5 --- /dev/null +++ b/demo/playground/notebooks/demo3D.ipynb @@ -0,0 +1,339 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "pycharm": { + "is_executing": true + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + " " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "@file:DependsOn(\"../build/libs/playground-0.3.0-dev-4-all.jar\")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

Starting VisionForge server on http://localhost:7777

\n" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vf.startServer()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "\n" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import kotlinx.coroutines.*\n", + "import kotlin.random.Random\n", + "\n", + "Plotly.plot{\n", + " scatter{\n", + " x(1,2,3)\n", + " y(1,2,3)\n", + " if(vf.isServerRunning()){\n", + " vf.launch{\n", + " while(isActive){\n", + " delay(500)\n", + " y(Random.nextDouble(), Random.nextDouble(), Random.nextDouble())\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "vf.stopServer()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "language_info": { + "codemirror_mode": "text/x-kotlin", + "file_extension": ".kt", + "mimetype": "text/x-kotlin", + "name": "kotlin", + "nbconvert_exporter": "", + "pygments_lexer": "kotlin", + "version": "1.8.0-dev-3517" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/demo/playground/src/jsMain/kotlin/playgroundMain.kt b/demo/playground/src/jsMain/kotlin/playgroundMain.kt index 3ad34867..8e259d48 100644 --- a/demo/playground/src/jsMain/kotlin/playgroundMain.kt +++ b/demo/playground/src/jsMain/kotlin/playgroundMain.kt @@ -1,4 +1,5 @@ import space.kscience.dataforge.misc.DFExperimental +import space.kscience.visionforge.jupyter.VFNotebookPlugin import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.ring.ThreeWithControlsPlugin @@ -11,4 +12,5 @@ fun main() = runVisionClient { plugin(PlotlyPlugin) plugin(MarkupPlugin) plugin(TableVisionJsPlugin) + plugin(VFNotebookPlugin) } \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt b/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt index 651b580d..212d906e 100644 --- a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt +++ b/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt @@ -6,13 +6,13 @@ import space.kscience.dataforge.misc.DFExperimental import space.kscience.gdml.Gdml import space.kscience.plotly.Plot import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.jupyter.JupyterPluginBase +import space.kscience.visionforge.jupyter.VFIntegrationBase import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.plotly.asVision import space.kscience.visionforge.solid.Solids @DFExperimental -internal class VisionForgePlayGroundForJupyter : JupyterPluginBase( +internal class VisionForgePlayGroundForJupyter : VFIntegrationBase( Context("VisionForge") { plugin(Solids) plugin(PlotlyPlugin) diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index 9c645d81..23699443 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -11,7 +11,6 @@ import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors import space.kscience.visionforge.html.VisionPage -import space.kscience.visionforge.server.DataServeMode import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser import space.kscience.visionforge.server.serve @@ -37,7 +36,6 @@ fun main() { } val server = satContext.visionManager.serve { - dataMode = DataServeMode.UPDATE page(VisionPage.threeJsHeader, VisionPage.styleSheetHeader("css/styles.css")) { div("flex-column") { h1 { +"Satellite detector demo" } diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt index eb27f4d6..5bdbcefe 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.solid.demo -import kotlinx.browser.document import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import org.w3c.dom.Document import space.kscience.visionforge.Application import space.kscience.visionforge.solid.x import space.kscience.visionforge.solid.y @@ -12,7 +12,7 @@ import kotlin.random.Random private class ThreeDemoApp : Application { - override fun start(state: Map) { + override fun start(document: Document, state: Map) { val element = document.getElementById("demo") ?: error("Element with id 'demo' not found on page") diff --git a/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt b/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt new file mode 100644 index 00000000..c13586ba --- /dev/null +++ b/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt @@ -0,0 +1,51 @@ +package space.kscience.visionforge.jupyter + +import kotlinx.browser.window +import org.w3c.dom.Element +import space.kscience.dataforge.context.AbstractPlugin +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.PluginFactory +import space.kscience.dataforge.context.PluginTag +import space.kscience.dataforge.meta.Meta +import space.kscience.visionforge.VisionClient +import space.kscience.visionforge.renderAllVisions +import space.kscience.visionforge.renderAllVisionsById +import space.kscience.visionforge.renderAllVisionsIn +import kotlin.reflect.KClass + +@JsExport +public class VFNotebookPlugin : AbstractPlugin() { + private val client by require(VisionClient) + + public fun renderAllVisionsIn(element: Element) { + client.renderAllVisionsIn(element) + } + + public fun renderAllVisionsById(id: String) { + client.renderAllVisionsById(id) + } + + public fun renderAllVisions() { + client.renderAllVisions() + } + + + init { + //register VisionForge in the browser window + window.asDynamic().vf = this + window.asDynamic().VisionForge = this + } + + @Suppress("NON_EXPORTABLE_TYPE") + override val tag: PluginTag get() = Companion.tag + + @Suppress("NON_EXPORTABLE_TYPE") + public companion object : PluginFactory { + override fun build(context: Context, meta: Meta): VFNotebookPlugin = VFNotebookPlugin() + + override val tag: PluginTag = PluginTag(name = "vision.notebook", group = PluginTag.DATAFORGE_GROUP) + + override val type: KClass = VFNotebookPlugin::class + } + +} \ No newline at end of file diff --git a/jupyter/src/jvmMain/kotlin/VisionForgeForNotebook.kt b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt similarity index 70% rename from jupyter/src/jvmMain/kotlin/VisionForgeForNotebook.kt rename to jupyter/src/jvmMain/kotlin/VFForNotebook.kt index a91733ce..4c7b4e29 100644 --- a/jupyter/src/jvmMain/kotlin/VisionForgeForNotebook.kt +++ b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt @@ -1,11 +1,9 @@ package space.kscience.visionforge.jupyter import io.ktor.server.engine.ApplicationEngine -import kotlinx.html.FORM -import kotlinx.html.TagConsumer -import kotlinx.html.p +import kotlinx.coroutines.CoroutineScope +import kotlinx.html.* import kotlinx.html.stream.createHTML -import kotlinx.html.style import org.jetbrains.kotlinx.jupyter.api.HTML import org.jetbrains.kotlinx.jupyter.api.MimeTypedResult import space.kscience.dataforge.context.Context @@ -21,11 +19,21 @@ import space.kscience.visionforge.html.visionFragment import space.kscience.visionforge.server.VisionServer import space.kscience.visionforge.server.serve import space.kscience.visionforge.visionManager +import kotlin.coroutines.CoroutineContext +import kotlin.random.Random +import kotlin.random.nextUInt + +internal fun TagConsumer<*>.renderScriptForId(id: String) { + script { + type = "text/javascript" + unsafe { +"VisionForge.renderAllVisionsById(\"$id\");" } + } +} /** * A handler class that includes a server and common utilities */ -public class VisionForgeForNotebook(override val context: Context) : ContextAware { +public class VFForNotebook(override val context: Context) : ContextAware, CoroutineScope { private var counter = 0 private var engine: ApplicationEngine? = null @@ -33,6 +41,8 @@ public class VisionForgeForNotebook(override val context: Context) : ContextAwar public var isolateFragments: Boolean = false + override val coroutineContext: CoroutineContext get() = context.coroutineContext + public fun legacyMode() { isolateFragments = true } @@ -68,15 +78,29 @@ public class VisionForgeForNotebook(override val context: Context) : ContextAwar public fun stopServer() { engine?.apply { logger.info { "Stopping VisionForge server" } - }?.stop(1000, 2000) + stop(1000, 2000) + engine = null + server = null + } } private fun produceHtmlString( fragment: HtmlVisionFragment, - ): String = server?.serveVisionsFromFragment("content[${counter++}]", fragment) - ?: createHTML().apply { - visionFragment(context, fragment = fragment) - }.finalize() + ): String = createHTML().apply { + val server = server + val id = "fragment[${fragment.hashCode()}/${Random.nextUInt()}]" + div { + this.id = id + if (server != null) { + //if server exist, serve dynamically + server.serveVisionsFromFragment(consumer, "content-${counter++}", fragment) + } else { + //if not, use static rendering + visionFragment(context, fragment = fragment) + } + } + renderScriptForId(id) + }.finalize() public fun produceHtml(isolated: Boolean? = null, fragment: HtmlVisionFragment): MimeTypedResult = HTML(produceHtmlString(fragment), isolated ?: isolateFragments) diff --git a/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt b/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt similarity index 66% rename from jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt rename to jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt index 944f1493..c8f6831d 100644 --- a/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt +++ b/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt @@ -1,8 +1,7 @@ package space.kscience.visionforge.jupyter -import kotlinx.html.p +import kotlinx.html.* import kotlinx.html.stream.createHTML -import kotlinx.html.style import org.jetbrains.kotlinx.jupyter.api.HTML import org.jetbrains.kotlinx.jupyter.api.declare import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration @@ -11,11 +10,16 @@ import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.Vision import space.kscience.visionforge.html.* +import kotlin.random.Random +import kotlin.random.nextUInt +/** + * A base class for different Jupyter VF integrations + */ @DFExperimental -public abstract class JupyterPluginBase(final override val context: Context) : JupyterIntegration(), ContextAware { +public abstract class VFIntegrationBase(final override val context: Context) : JupyterIntegration(), ContextAware { - protected val handler: VisionForgeForNotebook = VisionForgeForNotebook(context) + protected val handler: VFForNotebook = VFForNotebook(context) protected abstract fun Builder.afterLoaded() @@ -50,7 +54,24 @@ public abstract class JupyterPluginBase(final override val context: Context) : J } render { page -> - HTML(page.render(createHTML()), true) + HTML(createHTML().apply { + head { + meta { + charset = "utf-8" + } + page.pageHeaders.values.forEach { + fragment(it) + } + } + body { + val id = "fragment[${page.hashCode()}/${Random.nextUInt()}]" + div { + this.id = id + visionFragment(context, fragment = page.content) + } + renderScriptForId(id) + } + }.finalize(), true) } render { fragment -> diff --git a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt index 0a112ba2..0f430053 100644 --- a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt +++ b/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt @@ -5,11 +5,11 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.misc.DFExperimental import space.kscience.gdml.Gdml import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.jupyter.JupyterPluginBase +import space.kscience.visionforge.jupyter.VFIntegrationBase import space.kscience.visionforge.solid.Solids @DFExperimental -internal class GdmlForJupyter : JupyterPluginBase( +internal class GdmlForJupyter : VFIntegrationBase( Context("GDML") { plugin(Solids) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt index 5a4395af..e8c91b1e 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt @@ -8,8 +8,6 @@ import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager -import kotlin.random.Random -import kotlin.random.nextUInt public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit @@ -17,9 +15,6 @@ public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit public fun HtmlVisionFragment(content: VisionTagConsumer<*>.() -> Unit): HtmlVisionFragment = content -internal const val RENDER_FUNCTION_NAME = "renderAllVisionsById" - - /** * Render a fragment in the given consumer and return a map of extracted visions * @param context a context used to create a vision fragment @@ -35,7 +30,6 @@ public fun TagConsumer<*>.visionFragment( fetchDataUrl: String? = null, fetchUpdatesUrl: String? = null, idPrefix: String? = null, - renderScript: Boolean = true, fragment: HtmlVisionFragment, ): Map { val visionMap = HashMap() @@ -63,19 +57,9 @@ public fun TagConsumer<*>.visionFragment( } } } - if (renderScript) { - val id = "fragment[${fragment.hashCode()}/${Random.nextUInt()}]" - div { - this.id = id - fragment(consumer) - } - script { - type = "text/javascript" - unsafe { +"window.${RENDER_FUNCTION_NAME}(\"$id\");" } - } - } else { - fragment(consumer) - } + + fragment(consumer) + return visionMap } @@ -83,16 +67,14 @@ public fun FlowContent.visionFragment( context: Context = Global, embedData: Boolean = true, fetchDataUrl: String? = null, - fetchUpdatesUrl: String? = null, + flowDataUrl: String? = null, idPrefix: String? = null, - renderScript: Boolean = true, fragment: HtmlVisionFragment, ): Map = consumer.visionFragment( context, embedData, fetchDataUrl, - fetchUpdatesUrl, + flowDataUrl, idPrefix, - renderScript, fragment ) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt index cb284b14..1f297abe 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt @@ -13,20 +13,6 @@ public data class VisionPage( public val pageHeaders: Map = emptyMap(), public val content: HtmlVisionFragment, ) { - public fun render(root: TagConsumer): R = root.apply { - head { - meta { - charset = "utf-8" - } - pageHeaders.values.forEach { - fragment(it) - } - } - body { - visionFragment(context, fragment = content) - } - }.finalize() - public companion object{ /** * Use a script with given [src] as a global header for all pages. diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt index 5e1e2470..85ead127 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt @@ -2,7 +2,7 @@ package space.kscience.visionforge import kotlinx.browser.document import kotlinx.coroutines.CoroutineScope -import kotlinx.dom.hasClass +import org.w3c.dom.Document import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext @@ -36,7 +36,7 @@ public interface Application: CoroutineScope { * Starting point for an application. * @param state Initial state between Hot Module Replacement (HMR). */ - public fun start(state: Map) + public fun start(document: Document, state: Map) /** * Ending point for an application. @@ -46,17 +46,13 @@ public interface Application: CoroutineScope { } public fun startApplication(builder: () -> Application) { - fun start(state: dynamic): Application? { - return if (document.body?.hasClass("application") == true) { - val application = builder() + fun start(document: Document, state: dynamic): Application{ + val application = builder() - @Suppress("UnsafeCastFromDynamic") - application.start(state?.appState ?: emptyMap()) + @Suppress("UnsafeCastFromDynamic") + application.start(document, state?.appState ?: emptyMap()) - application - } else { - null - } + return application } var application: Application? = null @@ -73,9 +69,9 @@ public fun startApplication(builder: () -> Application) { } if (document.body != null) { - application = start(state) + application = start(document, state) } else { application = null - document.addEventListener("DOMContentLoaded", { application = start(state) }) + document.addEventListener("DOMContentLoaded", { application = start(document, state) }) } } \ No newline at end of file diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index f54b7d5d..a84a5a42 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -13,7 +13,6 @@ import space.kscience.dataforge.meta.MetaSerializer import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name -import space.kscience.visionforge.html.RENDER_FUNCTION_NAME import space.kscience.visionforge.html.VisionTagConsumer import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_CONNECT_ATTRIBUTE import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_ENDPOINT_ATTRIBUTE @@ -46,18 +45,16 @@ public class VisionClient : AbstractPlugin() { return attribute?.value } - private fun getRenderers() = context.gather(ElementVisionRenderer.TYPE).values + private val renderers by lazy { context.gather(ElementVisionRenderer.TYPE).values } - private fun findRendererFor(vision: Vision): ElementVisionRenderer? { - return getRenderers().mapNotNull { - val rating = it.rateVision(vision) - if (rating > 0) { - rating to it - } else { - null - } - }.maxByOrNull { it.first }?.second - } + private fun findRendererFor(vision: Vision): ElementVisionRenderer? = renderers.mapNotNull { + val rating = it.rateVision(vision) + if (rating > 0) { + rating to it + } else { + null + } + }.maxByOrNull { it.first }?.second private fun Element.getEmbeddedData(className: String): String? = getElementsByClassName(className)[0]?.innerHTML @@ -78,7 +75,7 @@ public class VisionClient : AbstractPlugin() { if (vision != null) { vision.setAsRoot(visionManager) val renderer = findRendererFor(vision) - ?: error("Could not find renderer for ${visionManager.encodeToString(vision)}") + ?: error("Could not find renderer for ${vision::class}") renderer.render(element, vision, outputMeta) element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> @@ -228,7 +225,7 @@ public class VisionClient : AbstractPlugin() { private fun whenDocumentLoaded(block: Document.() -> Unit): Unit { - if (document.readyState == DocumentReadyState.COMPLETE) { + if (document.body != null) { block(document) } else { document.addEventListener("DOMContentLoaded", { block(document) }) @@ -267,14 +264,29 @@ public fun VisionClient.renderAllVisions(): Unit = whenDocumentLoaded { renderAllVisionsIn(element) } +public class VisionClientApplication(public val context: Context) : Application { + private val client = context.fetch(VisionClient) + + override fun start(document: Document, state: Map) { + console.info("Starting Vision Client") + val element = document.body ?: error("Document does not have a body") + client.renderAllVisionsIn(element) + } +} + + /** * Create a vision client context and render all visions on the page. */ public fun runVisionClient(contextBuilder: ContextBuilder.() -> Unit) { console.info("Starting VisionForge context") - val context = Context("VisionForge", contextBuilder) - val visionClient = context.fetch(VisionClient) - window.asDynamic()[RENDER_FUNCTION_NAME] = visionClient::renderAllVisionsById - //visionClient.renderAllVisions() + val context = Context("VisionForge") { + plugin(VisionClient) + contextBuilder() + } + + startApplication { + VisionClientApplication(context) + } } \ No newline at end of file diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index b3063eb1..223a9473 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -1,9 +1,14 @@ package space.kscience.visionforge +import kotlinx.html.body +import kotlinx.html.head +import kotlinx.html.meta import kotlinx.html.stream.createHTML import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.html.HtmlFragment import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.html.fragment +import space.kscience.visionforge.html.visionFragment import java.awt.Desktop import java.nio.file.Files import java.nio.file.Path @@ -56,20 +61,34 @@ import java.nio.file.Path /** * Export a [VisionPage] to a file + * + * @param fileHeaders additional file-system specific headers. */ @DFExperimental public fun VisionPage.makeFile( path: Path?, - defaultHeaders: ((Path) -> Map)? = null, + fileHeaders: ((Path) -> Map)? = null, ): Path { val actualFile = path?.let { Path.of(System.getProperty("user.home")).resolve(path) } ?: Files.createTempFile("tempPlot", ".html") - val actualDefaultHeaders = defaultHeaders?.invoke(actualFile) - val actualPage = if (actualDefaultHeaders == null) this else copy(pageHeaders = actualDefaultHeaders + pageHeaders) + val actualDefaultHeaders = fileHeaders?.invoke(actualFile) + val actualHeaders = if (actualDefaultHeaders == null) pageHeaders else actualDefaultHeaders + pageHeaders - val htmlString = actualPage.render(createHTML()) + val htmlString = createHTML().apply { + head { + meta { + charset = "utf-8" + } + actualHeaders.values.forEach { + fragment(it) + } + } + body { + visionFragment(context, fragment = content) + } + }.finalize() Files.writeString(actualFile, htmlString) return actualFile diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 364d3162..a4bfa7b9 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -115,7 +115,7 @@ public class VisionServer internal constructor( context = visionManager.context, embedData = dataMode == DataServeMode.EMBED, fetchDataUrl = if (dataMode != DataServeMode.EMBED) "$serverUrl$pagePath/data" else null, - fetchUpdatesUrl = if (dataMode == DataServeMode.UPDATE) "$serverUrl$pagePath/ws" else null, + flowDataUrl = if (dataMode == DataServeMode.UPDATE) "$serverUrl$pagePath/ws" else null, fragment = visionFragment ) } @@ -192,18 +192,19 @@ public class VisionServer internal constructor( * Compile a fragment to string and serve visions from it */ public fun serveVisionsFromFragment( + consumer: TagConsumer<*>, route: String, fragment: HtmlVisionFragment, - ): String = createHTML().apply { - val visions = visionFragment( + ): Unit { + val visions = consumer.visionFragment( visionManager.context, embedData = true, fetchUpdatesUrl = "$serverUrl$route/ws", - renderScript = true, fragment = fragment ) + serveVisions(route, visions) - }.finalize() + } /** * Serve a page, potentially containing any number of visions at a given [route] with given [header]. @@ -248,7 +249,11 @@ public class VisionServer internal constructor( title: String = "VisionForge server page '$route'", visionFragment: HtmlVisionFragment, ) { - page(route, mapOf("title" to VisionPage.title(title)) + headers.associateBy { it.hashCode().toString() }, visionFragment) + page( + route, + mapOf("title" to VisionPage.title(title)) + headers.associateBy { it.hashCode().toString() }, + visionFragment + ) } /** From b2624cb10b83c43903638d3365741aba3ca941a1 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 20 Nov 2022 20:28:16 +0300 Subject: [PATCH 035/112] Fix API --- .../space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt | 4 ++-- demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index ab2b35e0..e2d7ad51 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.gdml.demo -import kotlinx.browser.document import kotlinx.css.* +import org.w3c.dom.Document import react.dom.client.createRoot import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch @@ -20,7 +20,7 @@ import styled.injectGlobal private class GDMLDemoApp : Application { - override fun start(state: Map) { + override fun start(document: Document, state: Map) { val context = Context("gdml-demo"){ plugin(ThreePlugin) } diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index 1ee7e013..2c93d31f 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -1,5 +1,5 @@ -import kotlinx.browser.document import kotlinx.css.* +import org.w3c.dom.Document import react.dom.client.createRoot import ringui.SmartTabs import ringui.Tab @@ -30,7 +30,7 @@ fun Trace.appendXYLatest(x: Number, y: Number, history: Int = 400, xErr: Number? private class JsPlaygroundApp : Application { - override fun start(state: Map) { + override fun start(document: Document, state: Map) { val playgroundContext = Context { plugin(ThreeWithControlsPlugin) From 279b84803912dcabadf17be13280219fa8123e94 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 20 Nov 2022 20:35:36 +0300 Subject: [PATCH 036/112] Add demo notebook --- .gitignore | 1 + demo/playground/notebooks/demo3D.ipynb | 339 ------------------- demo/playground/notebooks/dynamic-demo.ipynb | 91 +++++ 3 files changed, 92 insertions(+), 339 deletions(-) delete mode 100644 demo/playground/notebooks/demo3D.ipynb create mode 100644 demo/playground/notebooks/dynamic-demo.ipynb diff --git a/.gitignore b/.gitignore index 6d07da58..44f45e0e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ data/ !gradle-wrapper.jar /kotlin-js-store/yarn.lock +. diff --git a/demo/playground/notebooks/demo3D.ipynb b/demo/playground/notebooks/demo3D.ipynb deleted file mode 100644 index 1efcd3c5..00000000 --- a/demo/playground/notebooks/demo3D.ipynb +++ /dev/null @@ -1,339 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "pycharm": { - "is_executing": true - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "@file:DependsOn(\"../build/libs/playground-0.3.0-dev-4-all.jar\")" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "

Starting VisionForge server on http://localhost:7777

\n" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vf.startServer()" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "\n" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import kotlinx.coroutines.*\n", - "import kotlin.random.Random\n", - "\n", - "Plotly.plot{\n", - " scatter{\n", - " x(1,2,3)\n", - " y(1,2,3)\n", - " if(vf.isServerRunning()){\n", - " vf.launch{\n", - " while(isActive){\n", - " delay(500)\n", - " y(Random.nextDouble(), Random.nextDouble(), Random.nextDouble())\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "vf.stopServer()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Kotlin", - "language": "kotlin", - "name": "kotlin" - }, - "language_info": { - "codemirror_mode": "text/x-kotlin", - "file_extension": ".kt", - "mimetype": "text/x-kotlin", - "name": "kotlin", - "nbconvert_exporter": "", - "pygments_lexer": "kotlin", - "version": "1.8.0-dev-3517" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/demo/playground/notebooks/dynamic-demo.ipynb b/demo/playground/notebooks/dynamic-demo.ipynb new file mode 100644 index 00000000..ff7ca7ea --- /dev/null +++ b/demo/playground/notebooks/dynamic-demo.ipynb @@ -0,0 +1,91 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "is_executing": true + }, + "tags": [] + }, + "outputs": [], + "source": [ + "@file:DependsOn(\"../build/libs/playground-0.3.0-dev-4-all.jar\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vf.startServer()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "import kotlinx.coroutines.*\n", + "import kotlin.random.Random\n", + "\n", + "Plotly.plot{\n", + " scatter{\n", + " x(1,2,3)\n", + " y(1,2,3)\n", + " if(vf.isServerRunning()){\n", + " vf.launch{\n", + " while(isActive){\n", + " delay(500)\n", + " y(Random.nextDouble(), Random.nextDouble(), Random.nextDouble())\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vf.stopServer()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "language_info": { + "codemirror_mode": "text/x-kotlin", + "file_extension": ".kt", + "mimetype": "text/x-kotlin", + "name": "kotlin", + "nbconvert_exporter": "", + "pygments_lexer": "kotlin", + "version": "1.8.0-dev-3517" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 4ceffef67a02f23f9739cb3d45c6dd818e5cd373 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 21 Nov 2022 13:28:39 +0300 Subject: [PATCH 037/112] Update connection logic --- demo/playground/notebooks/dynamic-demo.ipynb | 4 +- .../kscience/visionforge/VisionChange.kt | 11 +- .../kscience/visionforge/VisionClient.kt | 164 ++++++++++-------- 3 files changed, 100 insertions(+), 79 deletions(-) diff --git a/demo/playground/notebooks/dynamic-demo.ipynb b/demo/playground/notebooks/dynamic-demo.ipynb index ff7ca7ea..7200d15b 100644 --- a/demo/playground/notebooks/dynamic-demo.ipynb +++ b/demo/playground/notebooks/dynamic-demo.ipynb @@ -4,10 +4,10 @@ "cell_type": "code", "execution_count": null, "metadata": { + "tags": [], "pycharm": { "is_executing": true - }, - "tags": [] + } }, "outputs": [], "source": [ diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index e95dbd1b..1fbc33bc 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -148,9 +148,12 @@ private fun CoroutineScope.collectChange( /** * Generate a flow of changes of this vision and its children + * + * @param sendInitial if true, send the initial vision state as first change */ public fun Vision.flowChanges( collectionDuration: Duration, + sendInitial: Boolean = false ): Flow = flow { val manager = manager ?: error("Orphan vision could not collect changes") coroutineScope { @@ -158,9 +161,11 @@ public fun Vision.flowChanges( val mutex = Mutex() collectChange(Name.EMPTY, this@flowChanges, mutex, collector) - //Send initial vision state - val initialChange = VisionChange(vision = deepCopy(manager)) - emit(initialChange) + if(sendInitial) { + //Send initial vision state + val initialChange = VisionChange(vision = deepCopy(manager)) + emit(initialChange) + } while (true) { //Wait for changes to accumulate diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index a84a5a42..81655335 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -45,7 +45,7 @@ public class VisionClient : AbstractPlugin() { return attribute?.value } - private val renderers by lazy { context.gather(ElementVisionRenderer.TYPE).values } + internal val renderers by lazy { context.gather(ElementVisionRenderer.TYPE).values } private fun findRendererFor(vision: Vision): ElementVisionRenderer? = renderers.mapNotNull { val rating = it.rateVision(vision) @@ -71,76 +71,77 @@ public class VisionClient : AbstractPlugin() { changeCollector.setChild(name, child) } - private fun renderVision(name: String, element: Element, vision: Vision?, outputMeta: Meta) { - if (vision != null) { - vision.setAsRoot(visionManager) - val renderer = findRendererFor(vision) - ?: error("Could not find renderer for ${vision::class}") - renderer.render(element, vision, outputMeta) + private fun renderVision(element: Element, vision: Vision, outputMeta: Meta) { + vision.setAsRoot(visionManager) + val renderer = findRendererFor(vision) ?: error("Could not find renderer for ${vision::class}") + renderer.render(element, vision, outputMeta) + } - element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> - val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { - val endpoint = resolveEndpoint(element) - logger.info { "Vision server is resolved to $endpoint" } - URL(endpoint).apply { - pathname += "/ws" - } - } else { - URL(attr.value) - }.apply { - protocol = "ws" - searchParams.append("name", name) + private fun updateVision(name: String, element: Element, vision: Vision?, outputMeta: Meta) { + element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> + val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { + val endpoint = resolveEndpoint(element) + logger.info { "Vision server is resolved to $endpoint" } + URL(endpoint).apply { + pathname += "/ws" } + } else { + URL(attr.value) + }.apply { + protocol = "ws" + searchParams.append("name", name) + } - logger.info { "Updating vision data from $wsUrl" } - - //Individual websocket for this element - WebSocket(wsUrl.toString()).apply { - onmessage = { messageEvent -> - val stringData: String? = messageEvent.data as? String - if (stringData != null) { - val change: VisionChange = visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(), - stringData - ) - - if (change.vision != null) { - renderer.render(element, vision, outputMeta) - } - - logger.debug { "Got update $change for output with name $name" } - vision.update(change) - } else { - console.error("WebSocket message data is not a string") + logger.info { "Updating vision data from $wsUrl" } + + //Individual websocket for this element + WebSocket(wsUrl.toString()).apply { + onmessage = { messageEvent -> + val stringData: String? = messageEvent.data as? String + if (stringData != null) { + val change: VisionChange = visionManager.jsonFormat.decodeFromString( + VisionChange.serializer(), + stringData + ) + + // If change contains root vision replacement, do it + change.vision?.let { vision -> + renderVision(element, vision, outputMeta) } + + logger.debug { "Got update $change for output with name $name" } + if (vision == null) error("Can't update vision because it is not loaded.") + vision.update(change) + } else { + logger.error { "WebSocket message data is not a string" } } + } - //Backward change propagation - var feedbackJob: Job? = null + //Backward change propagation + var feedbackJob: Job? = null - //Feedback changes aggregation time in milliseconds - val feedbackAggregationTime = meta["aggregationTime"]?.int ?: 300 + //Feedback changes aggregation time in milliseconds + val feedbackAggregationTime = meta["aggregationTime"]?.int ?: 300 - onopen = { - feedbackJob = visionManager.context.launch { - delay(feedbackAggregationTime.milliseconds) - if (!changeCollector.isEmpty()) { - send(visionManager.encodeToString(changeCollector.deepCopy(visionManager))) - changeCollector.reset() - } + onopen = { + feedbackJob = visionManager.context.launch { + delay(feedbackAggregationTime.milliseconds) + if (!changeCollector.isEmpty()) { + send(visionManager.encodeToString(changeCollector.deepCopy(visionManager))) + changeCollector.reset() } - console.info("WebSocket update channel established for output '$name'") } + logger.info { "WebSocket update channel established for output '$name'" } + } - onclose = { - feedbackJob?.cancel() - console.info("WebSocket update channel closed for output '$name'") - } - onerror = { - feedbackJob?.cancel() - console.error("WebSocket update channel error for output '$name'") - } + onclose = { + feedbackJob?.cancel() + logger.info { "WebSocket update channel closed for output '$name'" } + } + onerror = { + feedbackJob?.cancel() + logger.error { "WebSocket update channel error for output '$name'" } } } } @@ -164,17 +165,8 @@ public class VisionClient : AbstractPlugin() { VisionManager.defaultJson.decodeFromString(MetaSerializer, it) } ?: Meta.EMPTY - //Trying to render embedded vision - val embeddedVision = element.getEmbeddedData(VisionTagConsumer.OUTPUT_DATA_CLASS)?.let { - visionManager.decodeFromString(it) - } - when { - embeddedVision != null -> { - logger.info { "Found embedded vision for output with name $name" } - renderVision(name, element, embeddedVision, outputMeta) - } - + // fetch data if path is provided element.attributes[OUTPUT_FETCH_ATTRIBUTE] != null -> { val attr = element.attributes[OUTPUT_FETCH_ATTRIBUTE]!! @@ -195,7 +187,8 @@ public class VisionClient : AbstractPlugin() { if (response.ok) { response.text().then { text -> val vision = visionManager.decodeFromString(text) - renderVision(name, element, vision, outputMeta) + renderVision(element, vision, outputMeta) + updateVision(name, element, vision, outputMeta) } } else { logger.error { "Failed to fetch initial vision state from $fetchUrl" } @@ -203,6 +196,22 @@ public class VisionClient : AbstractPlugin() { } } + // use embedded data if it is available + element.getElementsByClassName(VisionTagConsumer.OUTPUT_DATA_CLASS).length > 0 -> { + //Getting embedded vision data + val embeddedVision = element.getEmbeddedData(VisionTagConsumer.OUTPUT_DATA_CLASS)!!.let { + visionManager.decodeFromString(it) + } + logger.info { "Found embedded vision for output with name $name" } + renderVision(element, embeddedVision, outputMeta) + updateVision(name, element, embeddedVision, outputMeta) + } + + //Try to load vision via websocket + element.attributes[OUTPUT_CONNECT_ATTRIBUTE] != null -> { + updateVision(name, element, null, outputMeta) + } + else -> error("No embedded vision data / fetch url for $name") } element.setAttribute(OUTPUT_RENDERED, "true") @@ -237,7 +246,7 @@ private fun whenDocumentLoaded(block: Document.() -> Unit): Unit { */ public fun VisionClient.renderAllVisionsIn(element: Element) { val elements = element.getElementsByClassName(VisionTagConsumer.OUTPUT_CLASS) - console.info("Finished search for outputs. Found ${elements.length} items") + logger.info { "Finished search for outputs. Found ${elements.length} items" } elements.asList().forEach { child -> renderVisionIn(child) } @@ -251,7 +260,7 @@ public fun VisionClient.renderAllVisionsById(id: String): Unit = whenDocumentLoa if (element != null) { renderAllVisionsIn(element) } else { - console.warn("Element with id $id not found") + logger.warn { "Element with id $id not found" } } } @@ -268,7 +277,14 @@ public class VisionClientApplication(public val context: Context) : Application private val client = context.fetch(VisionClient) override fun start(document: Document, state: Map) { - console.info("Starting Vision Client") + context.logger.info { + "Starting VisionClient with renderers: ${ + client.renderers.joinToString( + prefix = "\n\t", + separator = "\n\t" + ) { it.name.toString() } + }" + } val element = document.body ?: error("Document does not have a body") client.renderAllVisionsIn(element) } @@ -279,7 +295,7 @@ public class VisionClientApplication(public val context: Context) : Application * Create a vision client context and render all visions on the page. */ public fun runVisionClient(contextBuilder: ContextBuilder.() -> Unit) { - console.info("Starting VisionForge context") + Global.logger.info { "Starting VisionForge context" } val context = Context("VisionForge") { plugin(VisionClient) From d6c974fcbc2d35e73e44c5e5ab02c3f76e6cb67e Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 23 Nov 2022 13:41:36 +0300 Subject: [PATCH 038/112] Fix loading duplicating plugins in visionServer --- .../kscience/visionforge/VisionContainer.kt | 18 +++++++++--------- .../visionforge/server/VisionServer.kt | 17 ++++++++++------- .../visionforge/solid/SolidReference.kt | 4 ++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index 975e170a..7ac01b74 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -24,7 +24,7 @@ public interface MutableVisionContainer { * A serializable representation of [Vision] children container */ public interface VisionChildren : VisionContainer { - public val group: Vision? + public val parent: Vision? public val keys: Set @@ -35,7 +35,7 @@ public interface VisionChildren : VisionContainer { public operator fun get(token: NameToken): Vision? override fun getChild(name: Name): Vision? = when (name.length) { - 0 -> group + 0 -> parent 1 -> get(name.first()) else -> get(name.first())?.children?.getChild(name.cutFirst()) } @@ -44,7 +44,7 @@ public interface VisionChildren : VisionContainer { public const val STATIC_TOKEN_BODY: String = "@static" public fun empty(owner: Vision): VisionChildren = object : VisionChildren { - override val group: Vision get() = owner + override val parent: Vision get() = owner override val keys: Set get() = emptySet() override val changes: Flow get() = emptyFlow() override fun get(token: NameToken): Vision? = null @@ -64,7 +64,7 @@ public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) { public interface MutableVisionChildren : VisionChildren, MutableVisionContainer { - public override val group: MutableVisionGroup + public override val parent: MutableVisionGroup public operator fun set(token: NameToken, value: Vision?) @@ -85,7 +85,7 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer< else -> { val currentParent = get(name.first()) if (currentParent != null && currentParent !is MutableVisionGroup) error("Can't assign a child to $currentParent") - val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group.createGroup().also { + val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: parent.createGroup().also { set(name.first(), it) } parent.children.setChild(name.cutFirst(), child) @@ -125,7 +125,7 @@ public fun MutableVisionContainer.setChild( ): Unit = setChild(str?.parseAsName(), vision) internal abstract class VisionChildrenImpl( - override val group: MutableVisionGroup, + override val parent: MutableVisionGroup, ) : MutableVisionChildren { private val updateJobs = HashMap() @@ -140,7 +140,7 @@ internal abstract class VisionChildrenImpl( return items!! } - private val scope: CoroutineScope? get() = group.manager?.context + private val scope: CoroutineScope? get() = parent.manager?.context override val keys: Set get() = items?.keys ?: emptySet() @@ -170,9 +170,9 @@ internal abstract class VisionChildrenImpl( } else { (items ?: buildItems())[token] = value //check if parent already exists and is different from the current one - if (value.parent != null && value.parent != group) error("Can't reassign parent Vision for $value") + if (value.parent != null && value.parent != parent) error("Can't reassign parent Vision for $value") //set parent - value.parent = group + value.parent = parent //start update jobs (only if the vision is rooted) scope?.let { scope -> val job = value.children?.changes?.onEach { diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index a4bfa7b9..d806c278 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -1,10 +1,7 @@ package space.kscience.visionforge.server import io.ktor.http.* -import io.ktor.server.application.Application -import io.ktor.server.application.call -import io.ktor.server.application.install -import io.ktor.server.application.log +import io.ktor.server.application.* import io.ktor.server.cio.CIO import io.ktor.server.engine.ApplicationEngine import io.ktor.server.engine.embeddedServer @@ -18,6 +15,7 @@ import io.ktor.server.routing.* import io.ktor.server.util.getOrFail import io.ktor.server.websocket.WebSockets import io.ktor.server.websocket.webSocket +import io.ktor.util.pipeline.Pipeline import io.ktor.websocket.Frame import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.flow.collect @@ -270,6 +268,11 @@ public class VisionServer internal constructor( } } +public fun

, B : Any, F : Any> P.require( + plugin: Plugin, + configure: B.() -> Unit = {}, +): F = pluginOrNull(plugin) ?: install(plugin, configure) + /** * Attach VisionForge server application to given server */ @@ -278,8 +281,8 @@ public fun Application.visionServer( webServerUrl: Url, path: String = DEFAULT_PAGE, ): VisionServer { - install(WebSockets) - install(CORS) { + require(WebSockets) + require(CORS) { anyHost() } @@ -287,7 +290,7 @@ public fun Application.visionServer( // install(CallLogging) // } - val serverRoute = install(Routing).createRouteFromPath(path) + val serverRoute = require(Routing).createRouteFromPath(path) serverRoute { static { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index b54e3ab6..80db0b3e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -124,7 +124,7 @@ public class SolidReference( override val children: VisionChildren get() = object : VisionChildren { - override val group: Vision get() = this@SolidReference + override val parent: Vision get() = this@SolidReference override val keys: Set get() = prototype.children?.keys ?: emptySet() @@ -198,7 +198,7 @@ internal class SolidReferenceChild( override val children: VisionChildren = object : VisionChildren { - override val group: Vision get() = this@SolidReferenceChild + override val parent: Vision get() = this@SolidReferenceChild override val keys: Set get() = prototype.children?.keys ?: emptySet() From 20b20a621f5145137aebb845a67fe608ac98925d Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 2 Dec 2022 22:38:37 +0300 Subject: [PATCH 039/112] Refactor server API --- build.gradle.kts | 2 +- .../src/jvmMain/kotlin/formServer.kt | 80 ++-- .../src/jvmMain/kotlin/serverExtensions.kt | 3 +- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 29 +- jupyter/src/jvmMain/kotlin/VFForNotebook.kt | 69 ++- .../src/jvmMain/kotlin/VFIntegrationBase.kt | 4 +- .../visionforge/html/HtmlVisionRenderer.kt | 50 ++- .../kscience/visionforge/html/VisionPage.kt | 4 +- .../visionforge/html/VisionTagConsumer.kt | 46 +- .../visionforge/html/HtmlVisionContext.kt | 29 +- .../kscience/visionforge/html/htmlExport.kt | 3 +- .../visionforge/server/VisionServer.kt | 393 +++++++----------- .../kscience/visionforge/solid/Solids.kt | 2 +- .../visionforge/three/serverExtensions.kt | 3 +- 14 files changed, 361 insertions(+), 356 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b5e3fd7e..5a82b18c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-4" + version = "0.3.0-dev-5" } subprojects { diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index 4d60a423..4b63b569 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -1,5 +1,8 @@ package space.kscience.visionforge.examples +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import io.ktor.server.routing.routing import kotlinx.html.* import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.fetch @@ -9,51 +12,54 @@ import space.kscience.visionforge.html.formFragment import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser -import space.kscience.visionforge.server.serve +import space.kscience.visionforge.server.visionPage fun main() { val visionManager = Global.fetch(VisionManager) - val server = visionManager.serve { - page(VisionPage.scriptHeader("js/visionforge-playground.js")) { - val form = formFragment("form") { - label { - htmlFor = "fname" - +"First name:" - } - br() - input { - type = InputType.text - id = "fname" - name = "fname" - value = "John" - } - br() - label { - htmlFor = "lname" - +"Last name:" - } - br() - input { - type = InputType.text - id = "lname" - name = "lname" - value = "Doe" - } - br() - br() - input { - type = InputType.submit - value = "Submit" + val server = embeddedServer(CIO, 7777, "localhost") { + + routing { + visionPage(visionManager, VisionPage.scriptHeader("js/visionforge-playground.js")) { + val form = formFragment("form") { + label { + htmlFor = "fname" + +"First name:" + } + br() + input { + type = InputType.text + id = "fname" + name = "fname" + value = "John" + } + br() + label { + htmlFor = "lname" + +"Last name:" + } + br() + input { + type = InputType.text + id = "lname" + name = "lname" + value = "Doe" + } + br() + br() + input { + type = InputType.submit + value = "Submit" + } } - } - vision("form") { form } - form.onPropertyChange { - println(this) + vision("form") { form } + form.onPropertyChange { + println(this) + } } } - } + }.start(false) server.openInBrowser() diff --git a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt index eda8ba2b..a3bde8d6 100644 --- a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt +++ b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt @@ -6,6 +6,7 @@ import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.html.importScriptHeader import space.kscience.visionforge.makeFile +import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Path @@ -16,7 +17,7 @@ public fun makeVisionFile( show: Boolean = true, content: HtmlVisionFragment, ): Unit { - val actualPath = VisionPage(Global, content = content).makeFile(path) { actualPath -> + val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath -> mapOf( "title" to VisionPage.title(title), "playground" to VisionPage.importScriptHeader("js/visionforge-playground.js", resourceLocation, actualPath), diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index 23699443..a55020a2 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -1,26 +1,28 @@ package ru.mipt.npm.sat +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import io.ktor.server.http.content.resources +import io.ktor.server.http.content.static +import io.ktor.server.routing.routing import kotlinx.coroutines.* import kotlinx.html.div import kotlinx.html.h1 import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch import space.kscience.dataforge.meta.Null -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser -import space.kscience.visionforge.server.serve +import space.kscience.visionforge.server.visionPage import space.kscience.visionforge.solid.* import space.kscience.visionforge.three.threeJsHeader -import space.kscience.visionforge.visionManager import kotlin.random.Random -@OptIn(DFExperimental::class) fun main() { val satContext = Context("sat") { plugin(Solids) @@ -35,14 +37,21 @@ fun main() { } } - val server = satContext.visionManager.serve { - page(VisionPage.threeJsHeader, VisionPage.styleSheetHeader("css/styles.css")) { - div("flex-column") { - h1 { +"Satellite detector demo" } - vision { sat } + val server = embeddedServer(CIO,7777, "localhost") { + routing { + + static { + resources() + } + + visionPage(solids.visionManager, VisionPage.threeJsHeader, VisionPage.styleSheetHeader("css/styles.css")) { + div("flex-column") { + h1 { +"Satellite detector demo" } + vision { sat } + } } } - } + }.start(false) server.openInBrowser() diff --git a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt index 4c7b4e29..c3b79734 100644 --- a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt +++ b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt @@ -1,6 +1,14 @@ package space.kscience.visionforge.jupyter +import io.ktor.http.URLProtocol +import io.ktor.server.application.install +import io.ktor.server.cio.CIO import io.ktor.server.engine.ApplicationEngine +import io.ktor.server.engine.embeddedServer +import io.ktor.server.routing.Routing +import io.ktor.server.routing.route +import io.ktor.server.util.url +import io.ktor.server.websocket.WebSockets import kotlinx.coroutines.CoroutineScope import kotlinx.html.* import kotlinx.html.stream.createHTML @@ -13,11 +21,14 @@ import space.kscience.dataforge.context.logger import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.string +import space.kscience.visionforge.VisionManager import space.kscience.visionforge.html.HtmlFormFragment import space.kscience.visionforge.html.HtmlVisionFragment +import space.kscience.visionforge.html.VisionCollector import space.kscience.visionforge.html.visionFragment -import space.kscience.visionforge.server.VisionServer -import space.kscience.visionforge.server.serve +import space.kscience.visionforge.server.VisionRouteConfiguration +import space.kscience.visionforge.server.require +import space.kscience.visionforge.server.serveVisionData import space.kscience.visionforge.visionManager import kotlin.coroutines.CoroutineContext import kotlin.random.Random @@ -34,10 +45,14 @@ internal fun TagConsumer<*>.renderScriptForId(id: String) { * A handler class that includes a server and common utilities */ public class VFForNotebook(override val context: Context) : ContextAware, CoroutineScope { + + public val visionManager: VisionManager = context.visionManager + + private val configuration = VisionRouteConfiguration(visionManager) + private var counter = 0 private var engine: ApplicationEngine? = null - private var server: VisionServer? = null public var isolateFragments: Boolean = false @@ -47,16 +62,15 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout isolateFragments = true } - public fun isServerRunning(): Boolean = server != null + public fun isServerRunning(): Boolean = engine != null public fun html(block: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(createHTML().apply(block).finalize()) public fun startServer( host: String = context.properties["visionforge.host"].string ?: "localhost", - port: Int = context.properties["visionforge.port"].int ?: VisionServer.DEFAULT_PORT, - configuration: VisionServer.() -> Unit = {}, + port: Int = context.properties["visionforge.port"].int ?: VisionRouteConfiguration.DEFAULT_PORT, ): MimeTypedResult = html { - if (server != null) { + if (engine != null) { p { style = "color: red;" +"Stopping current VisionForge server" @@ -64,10 +78,9 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout } engine?.stop(1000, 2000) - engine = context.visionManager.serve(host, port) { - configuration() - server = this - }.start() + engine = context.embeddedServer(CIO, port, host) { + install(WebSockets) + }.start(false) p { style = "color: blue;" @@ -80,20 +93,46 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout logger.info { "Stopping VisionForge server" } stop(1000, 2000) engine = null - server = null } } private fun produceHtmlString( fragment: HtmlVisionFragment, ): String = createHTML().apply { - val server = server val id = "fragment[${fragment.hashCode()}/${Random.nextUInt()}]" div { this.id = id - if (server != null) { + val engine = engine + if (engine != null) { //if server exist, serve dynamically - server.serveVisionsFromFragment(consumer, "content-${counter++}", fragment) + //server.serveVisionsFromFragment(consumer, "content-${counter++}", fragment) + val cellRoute = "content-${counter++}" + + val collector: VisionCollector = mutableMapOf() + + val url = engine.environment.connectors.first().let { + url{ + protocol = URLProtocol.WS + host = it.host + port = it.port + pathSegments = listOf(cellRoute, "ws") + } + } + + visionFragment( + context, + embedData = true, + updatesUrl = url, + collector = collector, + fragment = fragment + ) + + engine.application.require(Routing) { + route(cellRoute) { + serveVisionData(TODO(), collector) + } + } + } else { //if not, use static rendering visionFragment(context, fragment = fragment) diff --git a/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt b/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt index c8f6831d..8aa9348a 100644 --- a/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt +++ b/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt @@ -48,7 +48,7 @@ public abstract class VFIntegrationBase(final override val context: Context) : J render { vision -> handler.produceHtml { - vision { vision } + vision(vision) } } @@ -83,7 +83,7 @@ public abstract class VFIntegrationBase(final override val context: Context) : J } } fragment(fragment.formBody) - vision { fragment.vision } + vision(fragment.vision) } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt index e8c91b1e..341c38ab 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt @@ -2,10 +2,11 @@ package space.kscience.visionforge.html import kotlinx.html.* import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.Global import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.asName import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager @@ -14,31 +15,48 @@ public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit @DFExperimental public fun HtmlVisionFragment(content: VisionTagConsumer<*>.() -> Unit): HtmlVisionFragment = content +public typealias VisionCollector = MutableMap> + /** * Render a fragment in the given consumer and return a map of extracted visions * @param context a context used to create a vision fragment * @param embedData embed Vision initial state in the HTML * @param fetchDataUrl fetch data after first render from given url - * @param fetchUpdatesUrl receive push updates from the server at given url + * @param updatesUrl receive push updates from the server at given url * @param idPrefix a prefix to be used before vision ids - * @param renderScript if true add rendering script after the fragment */ public fun TagConsumer<*>.visionFragment( - context: Context = Global, + context: Context, embedData: Boolean = true, fetchDataUrl: String? = null, - fetchUpdatesUrl: String? = null, + updatesUrl: String? = null, idPrefix: String? = null, + collector: VisionCollector = mutableMapOf(), fragment: HtmlVisionFragment, -): Map { - val visionMap = HashMap() +) { val consumer = object : VisionTagConsumer(this@visionFragment, context, idPrefix) { + + override fun TagConsumer.vision(name: Name?, buildOutput: VisionOutput.() -> Vision): T { + //Avoid re-creating cached visions + val actualName = name ?: NameToken( + DEFAULT_VISION_NAME, + buildOutput.hashCode().toUInt().toString() + ).asName() + + val (output, vision) = collector.getOrPut(actualName) { + val output = VisionOutput(context, actualName) + val vision = output.buildOutput() + output to vision + } + + return addVision(actualName, output.visionManager, vision, output.meta) + } + override fun DIV.renderVision(manager: VisionManager, name: Name, vision: Vision, outputMeta: Meta) { - visionMap[name] = vision // Toggle update mode - fetchUpdatesUrl?.let { + updatesUrl?.let { attributes[OUTPUT_CONNECT_ATTRIBUTE] = it } @@ -59,22 +77,22 @@ public fun TagConsumer<*>.visionFragment( } fragment(consumer) - - return visionMap } public fun FlowContent.visionFragment( - context: Context = Global, + context: Context, embedData: Boolean = true, fetchDataUrl: String? = null, - flowDataUrl: String? = null, + updatesUrl: String? = null, idPrefix: String? = null, + visionCache: VisionCollector = mutableMapOf(), fragment: HtmlVisionFragment, -): Map = consumer.visionFragment( +): Unit = consumer.visionFragment( context, embedData, fetchDataUrl, - flowDataUrl, + updatesUrl, idPrefix, - fragment + visionCache, + fragment = fragment ) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt index 1f297abe..de18ced5 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.html import kotlinx.html.* -import space.kscience.dataforge.context.Context +import space.kscience.visionforge.VisionManager /** * A structure representing a single page with Visions to be rendered. @@ -9,7 +9,7 @@ import space.kscience.dataforge.context.Context * @param pageHeaders static headers for this page. */ public data class VisionPage( - public val context: Context, + public val visionManager: VisionManager, public val pageHeaders: Map = emptyMap(), public val content: HtmlVisionFragment, ) { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt index df0b9391..6fc915ef 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt @@ -7,7 +7,6 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaSerializer import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.isEmpty -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName @@ -25,9 +24,8 @@ public annotation class VisionDSL /** * A placeholder object to attach inline vision builders. */ -@DFExperimental @VisionDSL -public class VisionOutput @PublishedApi internal constructor(public val context: Context, public val name: Name?) { +public class VisionOutput @PublishedApi internal constructor(public val context: Context, public val name: Name) { public var meta: Meta = Meta.EMPTY private val requirements: MutableSet> = HashSet() @@ -36,8 +34,8 @@ public class VisionOutput @PublishedApi internal constructor(public val context: requirements.add(factory) } - internal fun buildVisionManager(): VisionManager = - if (requirements.all { req -> context.plugins.find(true) { it.tag == req.tag } != null }) { + public val visionManager: VisionManager + get() = if (requirements.all { req -> context.plugins.find(true) { it.tag == req.tag } != null }) { context.visionManager } else { val newContext = context.buildContext(NameToken(DEFAULT_VISION_NAME, name.toString()).asName()) { @@ -56,7 +54,6 @@ public class VisionOutput @PublishedApi internal constructor(public val context: * Modified [TagConsumer] that allows rendering output fragments and visions in them */ @VisionDSL -@OptIn(DFExperimental::class) public abstract class VisionTagConsumer( private val root: TagConsumer, public val context: Context, @@ -78,12 +75,14 @@ public abstract class VisionTagConsumer( * Create a placeholder for a vision output with optional [Vision] in it * TODO with multi-receivers could be replaced by [VisionTagConsumer, TagConsumer] extension */ - private fun TagConsumer.vision( + protected fun TagConsumer.addVision( name: Name, manager: VisionManager, - vision: Vision, + vision: Vision?, outputMeta: Meta = Meta.EMPTY, - ): T = div { + ): T = if (vision == null) div { + +"Empty Vision output" + } else div { id = resolveId(name) classes = setOf(OUTPUT_CLASS) if (vision.parent == null) { @@ -106,26 +105,35 @@ public abstract class VisionTagConsumer( * Insert a vision in this HTML. * TODO replace by multi-receiver */ - @OptIn(DFExperimental::class) - public fun TagConsumer.vision( + @VisionDSL + public open fun TagConsumer.vision( name: Name? = null, - @OptIn(DFExperimental::class) visionProvider: VisionOutput.() -> Vision, + buildOutput: VisionOutput.() -> Vision, ): T { - val output = VisionOutput(context, name) - val vision = output.visionProvider() - val actualName = name ?: NameToken(DEFAULT_VISION_NAME, vision.hashCode().toUInt().toString()).asName() - return vision(actualName, output.buildVisionManager(), vision, output.meta) + val actualName = name ?: NameToken(DEFAULT_VISION_NAME, buildOutput.hashCode().toUInt().toString()).asName() + val output = VisionOutput(context, actualName) + val vision = output.buildOutput() + return addVision(actualName, output.visionManager, vision, output.meta) } /** * TODO to be replaced by multi-receiver */ - @OptIn(DFExperimental::class) @VisionDSL public fun TagConsumer.vision( name: String?, - @OptIn(DFExperimental::class) visionProvider: VisionOutput.() -> Vision, - ): T = vision(name?.parseAsName(), visionProvider) + buildOutput: VisionOutput.() -> Vision, + ): T = vision(name?.parseAsName(), buildOutput) + + @VisionDSL + public open fun TagConsumer.vision( + vision: Vision, + name: Name? = null, + outputMeta: Meta = Meta.EMPTY, + ) { + val actualName = name ?: NameToken(DEFAULT_VISION_NAME, vision.hashCode().toUInt().toString()).asName() + addVision(actualName, context.visionManager, vision, outputMeta) + } /** * Process the resulting object produced by [TagConsumer] diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt index 007658b1..7d82da49 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt @@ -5,13 +5,13 @@ import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaSerializer import space.kscience.dataforge.meta.isEmpty -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.parseAsName import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.html.VisionTagConsumer.Companion.DEFAULT_VISION_NAME import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.visionManager @@ -34,11 +34,13 @@ public interface HtmlVisionContext : ContextAware { public typealias HtmlVisionContextFragment = context(HtmlVisionContext) TagConsumer<*>.() -> Unit -context(HtmlVisionContext) public fun HtmlVisionFragment( - content: TagConsumer<*>.() -> Unit +context(HtmlVisionContext) +public fun HtmlVisionFragment( + content: TagConsumer<*>.() -> Unit, ): HtmlVisionFragment = content -context(HtmlVisionContext) private fun TagConsumer.vision( +context(HtmlVisionContext) +private fun TagConsumer.vision( visionManager: VisionManager, name: Name, vision: Vision, @@ -61,7 +63,7 @@ context(HtmlVisionContext) private fun TagConsumer.vision( } context(HtmlVisionContext) - private fun TagConsumer.vision( +private fun TagConsumer.vision( name: Name, vision: Vision, outputMeta: Meta = Meta.EMPTY, @@ -71,26 +73,23 @@ context(HtmlVisionContext) * Insert a vision in this HTML. */ context(HtmlVisionContext) - @DFExperimental - @VisionDSL - public fun TagConsumer.vision( +@VisionDSL +public fun TagConsumer.vision( name: Name? = null, visionProvider: VisionOutput.() -> Vision, ): T { - val output = VisionOutput(context, name) + val actualName = name ?: NameToken(DEFAULT_VISION_NAME, visionProvider.hashCode().toUInt().toString()).asName() + val output = VisionOutput(context, actualName) val vision = output.visionProvider() - val actualName = - name ?: NameToken(VisionTagConsumer.DEFAULT_VISION_NAME, vision.hashCode().toUInt().toString()).asName() - return vision(output.buildVisionManager(), actualName, vision, output.meta) + return vision(output.visionManager, actualName, vision, output.meta) } /** * Insert a vision in this HTML. */ context(HtmlVisionContext) - @DFExperimental - @VisionDSL - public fun TagConsumer.vision( +@VisionDSL +public fun TagConsumer.vision( name: String?, visionProvider: VisionOutput.() -> Vision, ): T = vision(name?.parseAsName(), visionProvider) \ No newline at end of file diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index 223a9473..cba1ee31 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -4,6 +4,7 @@ import kotlinx.html.body import kotlinx.html.head import kotlinx.html.meta import kotlinx.html.stream.createHTML +import space.kscience.dataforge.context.Global import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.html.HtmlFragment import space.kscience.visionforge.html.VisionPage @@ -86,7 +87,7 @@ public fun VisionPage.makeFile( } } body { - visionFragment(context, fragment = content) + visionFragment(Global, fragment = content) } }.finalize() diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index d806c278..2fe84660 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -2,39 +2,34 @@ package space.kscience.visionforge.server import io.ktor.http.* import io.ktor.server.application.* -import io.ktor.server.cio.CIO -import io.ktor.server.engine.ApplicationEngine -import io.ktor.server.engine.embeddedServer -import io.ktor.server.html.respondHtml -import io.ktor.server.http.content.resources -import io.ktor.server.http.content.static -import io.ktor.server.plugins.cors.routing.CORS -import io.ktor.server.response.respond -import io.ktor.server.response.respondText +import io.ktor.server.cio.* +import io.ktor.server.engine.* +import io.ktor.server.html.* +import io.ktor.server.http.content.* +import io.ktor.server.plugins.* +import io.ktor.server.plugins.cors.routing.* +import io.ktor.server.request.* +import io.ktor.server.response.* import io.ktor.server.routing.* -import io.ktor.server.util.getOrFail -import io.ktor.server.websocket.WebSockets -import io.ktor.server.websocket.webSocket -import io.ktor.util.pipeline.Pipeline -import io.ktor.websocket.Frame +import io.ktor.server.util.* +import io.ktor.server.websocket.* +import io.ktor.util.pipeline.* +import io.ktor.websocket.* import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.html.* -import kotlinx.html.stream.createHTML +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionChange import space.kscience.visionforge.VisionManager import space.kscience.visionforge.flowChanges -import space.kscience.visionforge.html.HtmlFragment -import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.VisionPage -import space.kscience.visionforge.html.visionFragment -import space.kscience.visionforge.server.VisionServer.Companion.DEFAULT_PAGE +import space.kscience.visionforge.html.* import java.awt.Desktop import java.net.URI import kotlin.time.Duration.Companion.milliseconds @@ -57,215 +52,182 @@ public enum class DataServeMode { UPDATE } -/** - * A ktor plugin container with given [routing] - * @param serverUrl a server url including root route - */ -public class VisionServer internal constructor( - private val visionManager: VisionManager, - private val serverUrl: Url, - private val root: Route, -) : Configurable { - - public val application: Application get() = root.application +public class VisionRouteConfiguration( + public val visionManager: VisionManager, + override val meta: ObservableMutableMeta = MutableMeta(), +) : Configurable, ContextAware { - override val meta: ObservableMutableMeta = MutableMeta() + override val context: Context get() = visionManager.context /** * Update minimal interval between updates in milliseconds (if there are no updates, push will not happen */ public var updateInterval: Long by meta.long(300, key = UPDATE_INTERVAL_KEY) - /** - * Cache page fragments. If false, pages will be reconstructed on each call. Default: `true` - */ - public var cacheFragments: Boolean by meta.boolean(true) - public var dataMode: DataServeMode by meta.enum(DataServeMode.UPDATE) - private val serverHeaders: MutableMap = mutableMapOf() - - /** - * Set up a default header that is automatically added to all pages on this server - */ - public fun header(key: String, block: HtmlFragment) { - serverHeaders[key] = block + public companion object { + public const val DEFAULT_PORT: Int = 7777 + public const val DEFAULT_PAGE: String = "/" + public val UPDATE_INTERVAL_KEY: Name = Name.parse("update.interval") } +} - private fun HTML.visionPage( - pagePath: String, - headers: Map, - visionFragment: HtmlVisionFragment, - ): Map { - var visionMap: Map? = null - head { - meta { - charset = "utf-8" - } - (serverHeaders + headers).values.forEach { - consumer.it() +/** + * Serve visions in a given [route] without providing a page template. + * [visions] could be changed during the service. + */ +public fun Route.serveVisionData( + configuration: VisionRouteConfiguration, + resolveVision: (Name) -> Vision?, +) { + application.log.info("Serving visions at ${this@serveVisionData}") + + //Update websocket + webSocket("ws") { + val name: String = call.request.queryParameters.getOrFail("name") + application.log.debug("Opened server socket for $name") + val vision: Vision = resolveVision(Name.parse(name)) ?: error("Plot with id='$name' not registered") + + launch { + incoming.consumeEach { + val data = it.data.decodeToString() + application.log.debug("Received update: \n$data") + val change = configuration.visionManager.jsonFormat.decodeFromString( + VisionChange.serializer(), data + ) + vision.update(change) } } - body { - //Load the fragment and remember all loaded visions - visionMap = visionFragment( - context = visionManager.context, - embedData = dataMode == DataServeMode.EMBED, - fetchDataUrl = if (dataMode != DataServeMode.EMBED) "$serverUrl$pagePath/data" else null, - flowDataUrl = if (dataMode == DataServeMode.UPDATE) "$serverUrl$pagePath/ws" else null, - fragment = visionFragment - ) - } - - return visionMap!! - } - /** - * Server a map of visions without providing explicit html page for them - */ - private fun serveVisions(route: Route, visions: Map): Unit = route { - application.log.info("Serving visions $visions at $route") - - //Update websocket - webSocket("ws") { - val name: String = call.request.queryParameters.getOrFail("name") - application.log.debug("Opened server socket for $name") - val vision: Vision = visions[Name.parse(name)] ?: error("Plot with id='$name' not registered") - - launch { - incoming.consumeEach { - val data = it.data.decodeToString() - application.log.debug("Received update: \n$data") - val change = visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(), data + try { + withContext(configuration.context.coroutineContext) { + vision.flowChanges(configuration.updateInterval.milliseconds).onEach { update -> + val json = configuration.visionManager.jsonFormat.encodeToString( + VisionChange.serializer(), + update ) - vision.update(change) - } - } - - try { - withContext(visionManager.context.coroutineContext) { - vision.flowChanges(updateInterval.milliseconds).onEach { update -> - val json = visionManager.jsonFormat.encodeToString( - VisionChange.serializer(), - update - ) - application.log.debug("Sending update: \n$json") - outgoing.send(Frame.Text(json)) - }.collect() - } - } catch (t: Throwable) { - application.log.info("WebSocket update channel for $name is closed with exception: $t") - } - } - //Plots in their json representation - get("data") { - val name: String = call.request.queryParameters.getOrFail("name") - - val vision: Vision? = visions[Name.parse(name)] - if (vision == null) { - call.respond(HttpStatusCode.NotFound, "Vision with name '$name' not found") - } else { - call.respondText( - visionManager.encodeToString(vision), - contentType = ContentType.Application.Json, - status = HttpStatusCode.OK - ) + application.log.debug("Sending update: \n$json") + outgoing.send(Frame.Text(json)) + }.collect() } + } catch (t: Throwable) { + this.application.log.info("WebSocket update channel for $name is closed with exception: $t") } } + //Plots in their json representation + get("data") { + val name: String = call.request.queryParameters.getOrFail("name") - - /** - * Serve visions in a given [route] without providing a page template - */ - public fun serveVisions(route: String, visions: Map) { - root.route(route) { - serveVisions(this, visions) + val vision: Vision? = resolveVision(Name.parse(name)) + if (vision == null) { + call.respond(HttpStatusCode.NotFound, "Vision with name '$name' not found") + } else { + call.respondText( + configuration.visionManager.encodeToString(vision), + contentType = ContentType.Application.Json, + status = HttpStatusCode.OK + ) } } +} - /** - * Compile a fragment to string and serve visions from it - */ - public fun serveVisionsFromFragment( - consumer: TagConsumer<*>, - route: String, - fragment: HtmlVisionFragment, - ): Unit { - val visions = consumer.visionFragment( - visionManager.context, - embedData = true, - fetchUpdatesUrl = "$serverUrl$route/ws", - fragment = fragment - ) +public fun Route.serveVisionData( + configuration: VisionRouteConfiguration, + cache: VisionCollector, +): Unit = serveVisionData(configuration) { cache[it]?.second } +// +///** +// * Compile a fragment to string and serve visions from it +// */ +//public fun Route.serveVisionsFromFragment( +// consumer: TagConsumer<*>, +// sererPageUrl: Url, +// visionManager: VisionManager, +// fragment: HtmlVisionFragment, +//): Unit { +// val visions = consumer.visionFragment( +// visionManager.context, +// embedData = true, +// fetchUpdatesUrl = "$serverUrl$route/ws", +// fragment = fragment +// ) +// +// serveVisionData(visionManager, visions) +//} - serveVisions(route, visions) - } - /** - * Serve a page, potentially containing any number of visions at a given [route] with given [header]. - */ - public fun page( - route: String = DEFAULT_PAGE, - headers: Map, - visionFragment: HtmlVisionFragment, - ) { - val visions = HashMap() - - val cachedHtml: String? = if (cacheFragments) { - //Create and cache page html and map of visions - createHTML(true).html { - visions.putAll(visionPage(route, headers, visionFragment)) - } - } else { - null - } +/** + * Serve a page, potentially containing any number of visions at a given [route] with given [header]. + */ +public fun Route.visionPage( + configuration: VisionRouteConfiguration, + headers: Collection, + visionFragment: HtmlVisionFragment, +) { + application.require(WebSockets) + require(CORS) { + anyHost() + } - root.route(route) { - serveVisions(this, visions) - //filled pages - get { - if (cachedHtml == null) { - //re-create html and vision list on each call - call.respondHtml { - visions.clear() - visions.putAll(visionPage(route, headers, visionFragment)) - } - } else { - //Use cached html - call.respondText(cachedHtml, ContentType.Text.Html.withCharset(Charsets.UTF_8)) + val visionCache: VisionCollector = mutableMapOf() + serveVisionData(configuration, visionCache) + + //filled pages + get { + //re-create html and vision list on each call + call.respondHtml { + val callbackUrl = call.url() + head { + meta { + charset = "utf-8" + } + headers.forEach { header -> + consumer.header() } } + body { + //Load the fragment and remember all loaded visions + visionFragment( + context = configuration.context, + embedData = configuration.dataMode == DataServeMode.EMBED, + fetchDataUrl = if (configuration.dataMode != DataServeMode.EMBED) { + URLBuilder(callbackUrl).apply { + pathSegments = pathSegments + "data" + }.buildString() + } else null, + updatesUrl = if (configuration.dataMode == DataServeMode.UPDATE) { + URLBuilder(callbackUrl).apply { + protocol = URLProtocol.WS + pathSegments = pathSegments + "ws" + }.buildString() + } else null, + visionCache = visionCache, + fragment = visionFragment + ) + } } - } - public fun page( - vararg headers: HtmlFragment, - route: String = DEFAULT_PAGE, - title: String = "VisionForge server page '$route'", - visionFragment: HtmlVisionFragment, - ) { - page( - route, - mapOf("title" to VisionPage.title(title)) + headers.associateBy { it.hashCode().toString() }, - visionFragment - ) } +} - /** - * Render given [VisionPage] at server - */ - public fun page(route: String, page: VisionPage) { - page(route = route, headers = page.pageHeaders, visionFragment = page.content) - } +public fun Route.visionPage( + visionManager: VisionManager, + vararg headers: HtmlFragment, + configurationBuilder: VisionRouteConfiguration.() -> Unit = {}, + visionFragment: HtmlVisionFragment, +) { + val configuration = VisionRouteConfiguration(visionManager).apply(configurationBuilder) + visionPage(configuration, listOf(*headers), visionFragment) +} - public companion object { - public const val DEFAULT_PORT: Int = 7777 - public const val DEFAULT_PAGE: String = "/" - public val UPDATE_INTERVAL_KEY: Name = Name.parse("update.interval") - } +/** + * Render given [VisionPage] at server + */ +public fun Route.visionPage(page: VisionPage, configurationBuilder: VisionRouteConfiguration.() -> Unit = {}) { + val configuration = VisionRouteConfiguration(page.visionManager).apply(configurationBuilder) + visionPage(configuration, page.pageHeaders.values, visionFragment = page.content) } public fun

, B : Any, F : Any> P.require( @@ -273,45 +235,6 @@ public fun

, B : Any, F : Any> P.require( configure: B.() -> Unit = {}, ): F = pluginOrNull(plugin) ?: install(plugin, configure) -/** - * Attach VisionForge server application to given server - */ -public fun Application.visionServer( - visionManager: VisionManager, - webServerUrl: Url, - path: String = DEFAULT_PAGE, -): VisionServer { - require(WebSockets) - require(CORS) { - anyHost() - } - -// if (pluginOrNull(CallLogging) == null) { -// install(CallLogging) -// } - - val serverRoute = require(Routing).createRouteFromPath(path) - - serverRoute { - static { - resources() - } - } - - return VisionServer(visionManager, URLBuilder(webServerUrl).apply { encodedPath = path }.build(), serverRoute) -} - -/** - * Start a stand-alone VisionForge server at given host/port - */ -public fun VisionManager.serve( - host: String = "localhost", - port: Int = VisionServer.DEFAULT_PORT, - block: VisionServer.() -> Unit, -): ApplicationEngine = context.embeddedServer(CIO, port, host) { - val url = URLBuilder(host = host, port = port).build() - visionServer(this@serve, url).apply(block) -}.start() /** * Connect to a given Ktor server using browser diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 43640182..919ac4cd 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -33,7 +33,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer = Solids::class public val default: Solids by lazy { - Context("@Solids"){ + Context("@Solids") { plugin(Solids) }.fetch(Solids) } diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt index 1261a0de..8f52ccf1 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt @@ -4,6 +4,7 @@ import space.kscience.dataforge.context.Global import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.html.* import space.kscience.visionforge.makeFile +import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Path @@ -19,7 +20,7 @@ public fun makeThreeJsFile( show: Boolean = true, content: HtmlVisionFragment, ): Unit { - val actualPath = VisionPage(Global, content = content).makeFile(path) { actualPath -> + val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath -> mapOf( "title" to VisionPage.title(title), "threeJs" to VisionPage.importScriptHeader("js/visionforge-three.js", resourceLocation, actualPath) From c8141c633842b1aa16fffbcbede53e5a1aa5f7f1 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 3 Dec 2022 13:53:34 +0300 Subject: [PATCH 040/112] Refactor server API --- .../src/jvmMain/kotlin/formServer.kt | 80 +++--- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 20 +- jupyter/src/jvmMain/kotlin/VFForNotebook.kt | 24 +- .../visionforge/server/VisionServer.kt | 269 +++++++++--------- .../server/applicationExtensions.kt | 38 +++ 5 files changed, 240 insertions(+), 191 deletions(-) create mode 100644 visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index 4b63b569..9e635dc9 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.examples import io.ktor.server.cio.CIO import io.ktor.server.engine.embeddedServer +import io.ktor.server.http.content.resources import io.ktor.server.routing.routing import kotlinx.html.* import space.kscience.dataforge.context.Global @@ -10,6 +11,7 @@ import space.kscience.visionforge.VisionManager import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.html.formFragment import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.server.EngineConnectorConfig import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser import space.kscience.visionforge.server.visionPage @@ -17,48 +19,54 @@ import space.kscience.visionforge.server.visionPage fun main() { val visionManager = Global.fetch(VisionManager) - val server = embeddedServer(CIO, 7777, "localhost") { + + val connector = EngineConnectorConfig("localhost", 7777) + + val server = embeddedServer(CIO, connector.port, connector.host) { routing { - visionPage(visionManager, VisionPage.scriptHeader("js/visionforge-playground.js")) { - val form = formFragment("form") { - label { - htmlFor = "fname" - +"First name:" - } - br() - input { - type = InputType.text - id = "fname" - name = "fname" - value = "John" - } - br() - label { - htmlFor = "lname" - +"Last name:" - } - br() - input { - type = InputType.text - id = "lname" - name = "lname" - value = "Doe" - } - br() - br() - input { - type = InputType.submit - value = "Submit" - } - } + resources() + } - vision("form") { form } - form.onPropertyChange { - println(this) + visionPage(connector, visionManager, VisionPage.scriptHeader("js/visionforge-playground.js")) { + val form = formFragment("form") { + label { + htmlFor = "fname" + +"First name:" + } + br() + input { + type = InputType.text + id = "fname" + name = "fname" + value = "John" + } + br() + label { + htmlFor = "lname" + +"Last name:" + } + br() + input { + type = InputType.text + id = "lname" + name = "lname" + value = "Doe" + } + br() + br() + input { + type = InputType.submit + value = "Submit" } } + + vision("form") { form } + form.onPropertyChange { + println(this) + } } + }.start(false) server.openInBrowser() diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index a55020a2..ed8ae38f 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -15,6 +15,7 @@ import space.kscience.dataforge.meta.Null import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.server.EngineConnectorConfig import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser import space.kscience.visionforge.server.visionPage @@ -36,21 +37,26 @@ fun main() { color.set(Colors.white) } } + val connector = EngineConnectorConfig("localhost", 7777) - val server = embeddedServer(CIO,7777, "localhost") { + val server = embeddedServer(CIO, connector.port, connector.host) { routing { - static { resources() } + } - visionPage(solids.visionManager, VisionPage.threeJsHeader, VisionPage.styleSheetHeader("css/styles.css")) { - div("flex-column") { - h1 { +"Satellite detector demo" } - vision { sat } - } + visionPage( + connector, + solids.visionManager, VisionPage.threeJsHeader, + VisionPage.styleSheetHeader("css/styles.css") + ) { + div("flex-column") { + h1 { +"Satellite detector demo" } + vision { sat } } } + }.start(false) server.openInBrowser() diff --git a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt index c3b79734..1d6a430c 100644 --- a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt +++ b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt @@ -4,9 +4,8 @@ import io.ktor.http.URLProtocol import io.ktor.server.application.install import io.ktor.server.cio.CIO import io.ktor.server.engine.ApplicationEngine +import io.ktor.server.engine.EngineConnectorConfig import io.ktor.server.engine.embeddedServer -import io.ktor.server.routing.Routing -import io.ktor.server.routing.route import io.ktor.server.util.url import io.ktor.server.websocket.WebSockets import kotlinx.coroutines.CoroutineScope @@ -26,8 +25,8 @@ import space.kscience.visionforge.html.HtmlFormFragment import space.kscience.visionforge.html.HtmlVisionFragment import space.kscience.visionforge.html.VisionCollector import space.kscience.visionforge.html.visionFragment -import space.kscience.visionforge.server.VisionRouteConfiguration -import space.kscience.visionforge.server.require +import space.kscience.visionforge.server.EngineConnectorConfig +import space.kscience.visionforge.server.VisionRoute import space.kscience.visionforge.server.serveVisionData import space.kscience.visionforge.visionManager import kotlin.coroutines.CoroutineContext @@ -48,8 +47,6 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout public val visionManager: VisionManager = context.visionManager - private val configuration = VisionRouteConfiguration(visionManager) - private var counter = 0 private var engine: ApplicationEngine? = null @@ -68,7 +65,7 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout public fun startServer( host: String = context.properties["visionforge.host"].string ?: "localhost", - port: Int = context.properties["visionforge.port"].int ?: VisionRouteConfiguration.DEFAULT_PORT, + port: Int = context.properties["visionforge.port"].int ?: VisionRoute.DEFAULT_PORT, ): MimeTypedResult = html { if (engine != null) { p { @@ -77,6 +74,8 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout } } + val connector: EngineConnectorConfig = EngineConnectorConfig(host, port) + engine?.stop(1000, 2000) engine = context.embeddedServer(CIO, port, host) { install(WebSockets) @@ -111,7 +110,7 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout val collector: VisionCollector = mutableMapOf() val url = engine.environment.connectors.first().let { - url{ + url { protocol = URLProtocol.WS host = it.host port = it.port @@ -119,6 +118,8 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout } } + engine.application.serveVisionData(VisionRoute(cellRoute, visionManager), collector) + visionFragment( context, embedData = true, @@ -126,13 +127,6 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout collector = collector, fragment = fragment ) - - engine.application.require(Routing) { - route(cellRoute) { - serveVisionData(TODO(), collector) - } - } - } else { //if not, use static rendering visionFragment(context, fragment = fragment) diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 2fe84660..957936a3 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.html.* +import kotlinx.html.stream.createHTML import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.meta.* @@ -30,33 +31,32 @@ import space.kscience.visionforge.VisionChange import space.kscience.visionforge.VisionManager import space.kscience.visionforge.flowChanges import space.kscience.visionforge.html.* -import java.awt.Desktop -import java.net.URI import kotlin.time.Duration.Companion.milliseconds -public enum class DataServeMode { - /** - * Embed the initial state of the vision inside its html tag. - */ - EMBED, - - /** - * Fetch data on vision load. Do not embed data. - */ - FETCH, - - /** - * Connect to server to get pushes. The address of the server is embedded in the tag. - */ - UPDATE -} - -public class VisionRouteConfiguration( +public class VisionRoute( + public val route: String, public val visionManager: VisionManager, override val meta: ObservableMutableMeta = MutableMeta(), ) : Configurable, ContextAware { + public enum class Mode { + /** + * Embed the initial state of the vision inside its html tag. + */ + EMBED, + + /** + * Fetch data on vision load. Do not embed data. + */ + FETCH, + + /** + * Connect to server to get pushes. The address of the server is embedded in the tag. + */ + UPDATE + } + override val context: Context get() = visionManager.context /** @@ -64,7 +64,7 @@ public class VisionRouteConfiguration( */ public var updateInterval: Long by meta.long(300, key = UPDATE_INTERVAL_KEY) - public var dataMode: DataServeMode by meta.enum(DataServeMode.UPDATE) + public var dataMode: Mode by meta.enum(Mode.UPDATE) public companion object { public const val DEFAULT_PORT: Int = 7777 @@ -78,65 +78,74 @@ public class VisionRouteConfiguration( * Serve visions in a given [route] without providing a page template. * [visions] could be changed during the service. */ -public fun Route.serveVisionData( - configuration: VisionRouteConfiguration, +public fun Application.serveVisionData( + configuration: VisionRoute, resolveVision: (Name) -> Vision?, ) { - application.log.info("Serving visions at ${this@serveVisionData}") - - //Update websocket - webSocket("ws") { - val name: String = call.request.queryParameters.getOrFail("name") - application.log.debug("Opened server socket for $name") - val vision: Vision = resolveVision(Name.parse(name)) ?: error("Plot with id='$name' not registered") - - launch { - incoming.consumeEach { - val data = it.data.decodeToString() - application.log.debug("Received update: \n$data") - val change = configuration.visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(), data - ) - vision.update(change) + require(WebSockets) + routing { + route(configuration.route) { + install(CORS) { + anyHost() } - } + application.log.info("Serving visions at ${configuration.route}") + + //Update websocket + webSocket("ws") { + val name: String = call.request.queryParameters.getOrFail("name") + application.log.debug("Opened server socket for $name") + val vision: Vision = resolveVision(Name.parse(name)) ?: error("Plot with id='$name' not registered") + + launch { + incoming.consumeEach { + val data = it.data.decodeToString() + application.log.debug("Received update: \n$data") + val change = configuration.visionManager.jsonFormat.decodeFromString( + VisionChange.serializer(), data + ) + vision.update(change) + } + } - try { - withContext(configuration.context.coroutineContext) { - vision.flowChanges(configuration.updateInterval.milliseconds).onEach { update -> - val json = configuration.visionManager.jsonFormat.encodeToString( - VisionChange.serializer(), - update + try { + withContext(configuration.context.coroutineContext) { + vision.flowChanges(configuration.updateInterval.milliseconds).onEach { update -> + val json = configuration.visionManager.jsonFormat.encodeToString( + VisionChange.serializer(), + update + ) + application.log.debug("Sending update: \n$json") + outgoing.send(Frame.Text(json)) + }.collect() + } + } catch (t: Throwable) { + this.application.log.info("WebSocket update channel for $name is closed with exception: $t") + } + } + //Plots in their json representation + get("data") { + val name: String = call.request.queryParameters.getOrFail("name") + + val vision: Vision? = resolveVision(Name.parse(name)) + if (vision == null) { + call.respond(HttpStatusCode.NotFound, "Vision with name '$name' not found") + } else { + call.respondText( + configuration.visionManager.encodeToString(vision), + contentType = ContentType.Application.Json, + status = HttpStatusCode.OK ) - application.log.debug("Sending update: \n$json") - outgoing.send(Frame.Text(json)) - }.collect() + } } - } catch (t: Throwable) { - this.application.log.info("WebSocket update channel for $name is closed with exception: $t") - } - } - //Plots in their json representation - get("data") { - val name: String = call.request.queryParameters.getOrFail("name") - - val vision: Vision? = resolveVision(Name.parse(name)) - if (vision == null) { - call.respond(HttpStatusCode.NotFound, "Vision with name '$name' not found") - } else { - call.respondText( - configuration.visionManager.encodeToString(vision), - contentType = ContentType.Application.Json, - status = HttpStatusCode.OK - ) } } } -public fun Route.serveVisionData( - configuration: VisionRouteConfiguration, +public fun Application.serveVisionData( + configuration: VisionRoute, cache: VisionCollector, ): Unit = serveVisionData(configuration) { cache[it]?.second } + // ///** // * Compile a fragment to string and serve visions from it @@ -161,91 +170,85 @@ public fun Route.serveVisionData( /** * Serve a page, potentially containing any number of visions at a given [route] with given [header]. */ -public fun Route.visionPage( - configuration: VisionRouteConfiguration, +public fun Application.visionPage( + route: String, + configuration: VisionRoute, + connector: EngineConnectorConfig, headers: Collection, visionFragment: HtmlVisionFragment, ) { - application.require(WebSockets) - require(CORS) { - anyHost() - } + require(WebSockets) - val visionCache: VisionCollector = mutableMapOf() - serveVisionData(configuration, visionCache) + val collector: VisionCollector = mutableMapOf() - //filled pages - get { - //re-create html and vision list on each call - call.respondHtml { - val callbackUrl = call.url() - head { - meta { - charset = "utf-8" - } - headers.forEach { header -> - consumer.header() - } + val html = createHTML().apply { + head { + meta { + charset = "utf-8" } - body { - //Load the fragment and remember all loaded visions - visionFragment( - context = configuration.context, - embedData = configuration.dataMode == DataServeMode.EMBED, - fetchDataUrl = if (configuration.dataMode != DataServeMode.EMBED) { - URLBuilder(callbackUrl).apply { - pathSegments = pathSegments + "data" - }.buildString() - } else null, - updatesUrl = if (configuration.dataMode == DataServeMode.UPDATE) { - URLBuilder(callbackUrl).apply { - protocol = URLProtocol.WS - pathSegments = pathSegments + "ws" - }.buildString() - } else null, - visionCache = visionCache, - fragment = visionFragment - ) + headers.forEach { header -> + consumer.header() } } + body { + //Load the fragment and remember all loaded visions + visionFragment( + context = configuration.context, + embedData = configuration.dataMode == VisionRoute.Mode.EMBED, + fetchDataUrl = if (configuration.dataMode != VisionRoute.Mode.EMBED) { + url { + host = connector.host + port = connector.port + path(route, "data") + } + } else null, + updatesUrl = if (configuration.dataMode == VisionRoute.Mode.UPDATE) { + url { + protocol = URLProtocol.WS + host = connector.host + port = connector.port + path(route, "ws") + } + } else null, + visionCache = collector, + fragment = visionFragment + ) + } + }.finalize() + + //serve data + serveVisionData(configuration, collector) + //filled pages + routing { + get(route) { + call.respondText(html, ContentType.Text.Html) + } } } -public fun Route.visionPage( +public fun Application.visionPage( + connector: EngineConnectorConfig, visionManager: VisionManager, vararg headers: HtmlFragment, - configurationBuilder: VisionRouteConfiguration.() -> Unit = {}, + route: String = "/", + configurationBuilder: VisionRoute.() -> Unit = {}, visionFragment: HtmlVisionFragment, ) { - val configuration = VisionRouteConfiguration(visionManager).apply(configurationBuilder) - visionPage(configuration, listOf(*headers), visionFragment) + val configuration = VisionRoute(route, visionManager).apply(configurationBuilder) + visionPage(route, configuration, connector, listOf(*headers), visionFragment) } /** * Render given [VisionPage] at server */ -public fun Route.visionPage(page: VisionPage, configurationBuilder: VisionRouteConfiguration.() -> Unit = {}) { - val configuration = VisionRouteConfiguration(page.visionManager).apply(configurationBuilder) - visionPage(configuration, page.pageHeaders.values, visionFragment = page.content) -} - -public fun

, B : Any, F : Any> P.require( - plugin: Plugin, - configure: B.() -> Unit = {}, -): F = pluginOrNull(plugin) ?: install(plugin, configure) - - -/** - * Connect to a given Ktor server using browser - */ -public fun ApplicationEngine.openInBrowser() { - val connector = environment.connectors.first() - val uri = URI("http", null, connector.host, connector.port, null, null, null) - Desktop.getDesktop().browse(uri) +public fun Application.visionPage( + connector: EngineConnectorConfig, + page: VisionPage, + route: String = "/", + configurationBuilder: VisionRoute.() -> Unit = {}, +) { + val configuration = VisionRoute(route, page.visionManager).apply(configurationBuilder) + visionPage(route, configuration, connector, page.pageHeaders.values, visionFragment = page.content) } -/** - * Stop the server with default timeouts - */ -public fun ApplicationEngine.close(): Unit = stop(1000, 5000) \ No newline at end of file diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt new file mode 100644 index 00000000..f33b59b2 --- /dev/null +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt @@ -0,0 +1,38 @@ +package space.kscience.visionforge.server + +import io.ktor.server.application.ApplicationCall +import io.ktor.server.application.Plugin +import io.ktor.server.application.install +import io.ktor.server.application.pluginOrNull +import io.ktor.server.engine.ApplicationEngine +import io.ktor.server.engine.EngineConnectorBuilder +import io.ktor.server.engine.EngineConnectorConfig +import io.ktor.util.pipeline.Pipeline +import java.awt.Desktop +import java.net.URI + + +public fun

, B : Any, F : Any> P.require( + plugin: Plugin, +): F = pluginOrNull(plugin) ?: install(plugin) + + +/** + * Connect to a given Ktor server using browser + */ +public fun ApplicationEngine.openInBrowser() { + val connector = environment.connectors.first() + val uri = URI("http", null, connector.host, connector.port, null, null, null) + Desktop.getDesktop().browse(uri) +} + +/** + * Stop the server with default timeouts + */ +public fun ApplicationEngine.close(): Unit = stop(1000, 5000) + + +public fun EngineConnectorConfig(host: String, port: Int): EngineConnectorConfig = EngineConnectorBuilder().apply { + this.host = host + this.port = port +} \ No newline at end of file From fd8f693151381f1bab1f2e8d27215cfec21c1264 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 3 Dec 2022 14:51:32 +0300 Subject: [PATCH 041/112] Refactor server API --- .../visionforge/ElementVisionRenderer.kt | 10 ++-- .../kscience/visionforge/VisionClient.kt | 49 ++++++++++++------- .../kscience/visionforge/inputRenderers.kt | 36 ++++++++------ .../visionforge/markup/MarkupPlugin.kt | 3 +- 4 files changed, 61 insertions(+), 37 deletions(-) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt index bf9f00df..75ec785a 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt @@ -34,7 +34,7 @@ public interface ElementVisionRenderer : Named { * Display the [vision] inside a given [element] replacing its current content. * @param meta additional parameters for rendering container */ - public fun render(element: Element, vision: Vision, meta: Meta = Meta.EMPTY) + public fun render(element: Element, name: Name, vision: Vision, meta: Meta = Meta.EMPTY) public companion object { public const val TYPE: String = "elementVisionRenderer" @@ -49,7 +49,7 @@ public interface ElementVisionRenderer : Named { public class SingleTypeVisionRenderer( public val kClass: KClass, private val acceptRating: Int = ElementVisionRenderer.DEFAULT_RATING, - private val renderFunction: TagConsumer.(vision: T, meta: Meta) -> Unit, + private val renderFunction: TagConsumer.(name: Name, vision: T, meta: Meta) -> Unit, ) : ElementVisionRenderer { @OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class) @@ -60,15 +60,15 @@ public class SingleTypeVisionRenderer( override fun rateVision(vision: Vision): Int = if (vision::class == kClass) acceptRating else ElementVisionRenderer.ZERO_RATING - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { element.clear() element.append { - renderFunction(kClass.cast(vision), meta) + renderFunction(name, kClass.cast(vision), meta) } } } public inline fun ElementVisionRenderer( acceptRating: Int = ElementVisionRenderer.DEFAULT_RATING, - noinline renderFunction: TagConsumer.(vision: T, meta: Meta) -> Unit, + noinline renderFunction: TagConsumer.(name: Name, vision: T, meta: Meta) -> Unit, ): ElementVisionRenderer = SingleTypeVisionRenderer(T::class, acceptRating, renderFunction) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index 81655335..efb8a9fe 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -13,6 +13,7 @@ import space.kscience.dataforge.meta.MetaSerializer import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.parseAsName import space.kscience.visionforge.html.VisionTagConsumer import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_CONNECT_ATTRIBUTE import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_ENDPOINT_ATTRIBUTE @@ -67,17 +68,29 @@ public class VisionClient : AbstractPlugin() { changeCollector.propertyChanged(visionName, propertyName, item) } + public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: Boolean) { + visionPropertyChanged(visionName, propertyName, Meta(item)) + } + + public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: String) { + visionPropertyChanged(visionName, propertyName, Meta(item)) + } + + public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: Number) { + visionPropertyChanged(visionName, propertyName, Meta(item)) + } + public fun visionChanged(name: Name?, child: Vision?) { changeCollector.setChild(name, child) } - private fun renderVision(element: Element, vision: Vision, outputMeta: Meta) { + private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) { vision.setAsRoot(visionManager) val renderer = findRendererFor(vision) ?: error("Could not find renderer for ${vision::class}") - renderer.render(element, vision, outputMeta) + renderer.render(element, name, vision, outputMeta) } - private fun updateVision(name: String, element: Element, vision: Vision?, outputMeta: Meta) { + private fun updateVision(element: Element, name: Name, vision: Vision?, outputMeta: Meta) { element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { val endpoint = resolveEndpoint(element) @@ -89,7 +102,7 @@ public class VisionClient : AbstractPlugin() { URL(attr.value) }.apply { protocol = "ws" - searchParams.append("name", name) + searchParams.append("name", name.toString()) } logger.info { "Updating vision data from $wsUrl" } @@ -106,7 +119,7 @@ public class VisionClient : AbstractPlugin() { // If change contains root vision replacement, do it change.vision?.let { vision -> - renderVision(element, vision, outputMeta) + renderVision(element, name, vision, outputMeta) } logger.debug { "Got update $change for output with name $name" } @@ -152,7 +165,7 @@ public class VisionClient : AbstractPlugin() { */ public fun renderVisionIn(element: Element) { if (!element.classList.contains(VisionTagConsumer.OUTPUT_CLASS)) error("The element $element is not an output element") - val name = resolveName(element) ?: error("The element is not a vision output") + val name = resolveName(element)?.parseAsName() ?: error("The element is not a vision output") if (element.attributes[OUTPUT_RENDERED]?.value == "true") { logger.info { "VF output in element $element is already rendered" } @@ -179,7 +192,7 @@ public class VisionClient : AbstractPlugin() { } else { URL(attr.value) }.apply { - searchParams.append("name", name) + searchParams.append("name", name.toString()) } logger.info { "Fetching vision data from $fetchUrl" } @@ -187,8 +200,8 @@ public class VisionClient : AbstractPlugin() { if (response.ok) { response.text().then { text -> val vision = visionManager.decodeFromString(text) - renderVision(element, vision, outputMeta) - updateVision(name, element, vision, outputMeta) + renderVision(element, name, vision, outputMeta) + updateVision(element, name, vision, outputMeta) } } else { logger.error { "Failed to fetch initial vision state from $fetchUrl" } @@ -203,13 +216,13 @@ public class VisionClient : AbstractPlugin() { visionManager.decodeFromString(it) } logger.info { "Found embedded vision for output with name $name" } - renderVision(element, embeddedVision, outputMeta) - updateVision(name, element, embeddedVision, outputMeta) + renderVision(element, name, embeddedVision, outputMeta) + updateVision(element, name, embeddedVision, outputMeta) } //Try to load vision via websocket element.attributes[OUTPUT_CONNECT_ATTRIBUTE] != null -> { - updateVision(name, element, null, outputMeta) + updateVision(element, name, null, outputMeta) } else -> error("No embedded vision data / fetch url for $name") @@ -217,11 +230,13 @@ public class VisionClient : AbstractPlugin() { element.setAttribute(OUTPUT_RENDERED, "true") } - override fun content(target: String): Map = if (target == ElementVisionRenderer.TYPE) mapOf( - numberVisionRenderer.name to numberVisionRenderer, - textVisionRenderer.name to textVisionRenderer, - formVisionRenderer.name to formVisionRenderer - ) else super.content(target) + override fun content(target: String): Map = if (target == ElementVisionRenderer.TYPE) { + listOf( + numberVisionRenderer(this), + textVisionRenderer(this), + formVisionRenderer(this) + ).toMap() + } else super.content(target) public companion object : PluginFactory { override fun build(context: Context, meta: Meta): VisionClient = VisionClient() diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index c6d87b19..86324d89 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -16,42 +16,46 @@ import space.kscience.visionforge.html.VisionOfHtmlForm import space.kscience.visionforge.html.VisionOfNumberField import space.kscience.visionforge.html.VisionOfTextField -public val textVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { vision, _ -> - val name = vision.name ?: "input[${vision.hashCode().toUInt()}]" +internal fun textVisionRenderer( + client: VisionClient, +): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> + val fieldName = vision.name ?: "input[${vision.hashCode().toUInt()}]" vision.label?.let { label { - htmlFor = name + htmlFor = fieldName +it } } input { type = InputType.text - this.name = name + this.name = fieldName vision.useProperty(VisionOfTextField::text) { value = it ?: "" } onChangeFunction = { - vision.text = value +// client.visionPropertyChanged(name, VisionOfTextField::text.name.pa, value) } } } -public val numberVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { vision, _ -> - val name = vision.name ?: "input[${vision.hashCode().toUInt()}]" +internal fun numberVisionRenderer( + client: VisionClient, +): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> + val fieldName = vision.name ?: "input[${vision.hashCode().toUInt()}]" vision.label?.let { label { - htmlFor = name + htmlFor = fieldName +it } } input { type = InputType.text - this.name = name + this.name = fieldName vision.useProperty(VisionOfNumberField::value) { value = it?.toDouble() ?: 0.0 } onChangeFunction = { - vision.value = value.toDoubleOrNull() +// vision.value = value.toDoubleOrNull() } } } @@ -61,7 +65,8 @@ internal fun FormData.toMeta(): Meta { //val res = js("Object.fromEntries(formData);") val `object` = js("{}") //language=JavaScript - js(""" + js( + """ formData.forEach(function(value, key){ // Reflect.has in favor of: object.hasOwnProperty(key) if(!Reflect.has(object, key)){ @@ -73,11 +78,14 @@ internal fun FormData.toMeta(): Meta { } object[key].push(value); }); - """) + """ + ) return DynamicMeta(`object`) } -public val formVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { vision, _ -> +internal fun formVisionRenderer( + client: VisionClient, +): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> val form = document.getElementById(vision.formId) as? HTMLFormElement ?: error("An element with id = '${vision.formId} is not a form") @@ -95,7 +103,7 @@ public val formVisionRenderer: ElementVisionRenderer = ElementVisionRenderer ElementVisionRenderer.ZERO_RATING } - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { require(vision is VisionOfMarkup) { "The vision is not a markup vision" } val div = document.createElement("div") val flavour = when (vision.format) { From fef1df3ab4a309b1d9932f994f133c49239a76ab Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 6 Dec 2022 15:54:34 +0300 Subject: [PATCH 042/112] Refactor server API --- .../kotlin/VisionForgePlayGroundForJupyter.kt | 3 +- .../src/jvmMain/kotlin/formServer.kt | 22 ++++++---- .../src/jvmMain/kotlin/serverExtensions.kt | 6 +-- jupyter/src/jvmMain/kotlin/VFForNotebook.kt | 12 +++--- .../src/jvmMain/kotlin/VFIntegrationBase.kt | 10 +++-- jupyter/src/jvmMain/kotlin/forms.kt | 27 ++++++++++++ .../src/jvmMain/kotlin/GdmlForJupyter.kt | 3 +- .../ThreeWithControlsPlugin.kt | 2 +- .../visionforge/html/HtmlVisionRenderer.kt | 41 +++++++++++-------- .../visionforge/html/VisionOfHtmlForm.kt | 30 +++----------- .../visionforge/html/VisionTagConsumer.kt | 7 +++- .../kscience/visionforge/html/HtmlTagTest.kt | 2 +- .../kscience/visionforge/VisionClient.kt | 38 +++++++++-------- .../kscience/visionforge/inputRenderers.kt | 14 ++++--- .../kscience/visionforge/html/htmlExport.kt | 9 ++-- .../kscience/visionforge/plotly/plotlyJs.kt | 2 +- .../visionforge/server/VisionServer.kt | 15 ++++--- .../visionforge/tables/TableVisionJsPlugin.kt | 2 +- .../visionforge/solid/three/ThreePlugin.kt | 4 +- .../visionforge/three/serverExtensions.kt | 1 - 20 files changed, 142 insertions(+), 108 deletions(-) create mode 100644 jupyter/src/jvmMain/kotlin/forms.kt diff --git a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt b/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt index 212d906e..0b87e06d 100644 --- a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt +++ b/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt @@ -10,13 +10,14 @@ import space.kscience.visionforge.jupyter.VFIntegrationBase import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.plotly.asVision import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.visionManager @DFExperimental internal class VisionForgePlayGroundForJupyter : VFIntegrationBase( Context("VisionForge") { plugin(Solids) plugin(PlotlyPlugin) - } + }.visionManager ) { override fun Builder.afterLoaded() { diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index 9e635dc9..cef13f0b 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -8,8 +8,9 @@ import kotlinx.html.* import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.fetch import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.html.VisionOfHtmlForm import space.kscience.visionforge.html.VisionPage -import space.kscience.visionforge.html.formFragment +import space.kscience.visionforge.html.bindForm import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.server.EngineConnectorConfig import space.kscience.visionforge.server.close @@ -28,8 +29,18 @@ fun main() { resources() } - visionPage(connector, visionManager, VisionPage.scriptHeader("js/visionforge-playground.js")) { - val form = formFragment("form") { + val form = VisionOfHtmlForm("form").apply { + onPropertyChange(visionManager.context) { + println(this) + } + } + + visionPage( + connector, + visionManager, + VisionPage.scriptHeader("js/visionforge-playground.js"), + ) { + bindForm(form) { label { htmlFor = "fname" +"First name:" @@ -61,10 +72,7 @@ fun main() { } } - vision("form") { form } - form.onPropertyChange { - println(this) - } + vision(form) } }.start(false) diff --git a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt index a3bde8d6..b22c6514 100644 --- a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt +++ b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt @@ -1,11 +1,7 @@ package space.kscience.visionforge.examples import space.kscience.dataforge.context.Global -import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.ResourceLocation -import space.kscience.visionforge.html.VisionPage -import space.kscience.visionforge.html.importScriptHeader -import space.kscience.visionforge.makeFile +import space.kscience.visionforge.html.* import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Path diff --git a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt index 1d6a430c..eb61f889 100644 --- a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt +++ b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt @@ -20,10 +20,10 @@ import space.kscience.dataforge.context.logger import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.string +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.html.HtmlFormFragment import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.VisionCollector import space.kscience.visionforge.html.visionFragment import space.kscience.visionforge.server.EngineConnectorConfig import space.kscience.visionforge.server.VisionRoute @@ -107,7 +107,7 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout //server.serveVisionsFromFragment(consumer, "content-${counter++}", fragment) val cellRoute = "content-${counter++}" - val collector: VisionCollector = mutableMapOf() + val collector: MutableMap = mutableMapOf() val url = engine.environment.connectors.first().let { url { @@ -121,15 +121,15 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout engine.application.serveVisionData(VisionRoute(cellRoute, visionManager), collector) visionFragment( - context, + visionManager, embedData = true, updatesUrl = url, - collector = collector, + onVisionRendered = { name, vision -> collector[name] = vision }, fragment = fragment ) } else { //if not, use static rendering - visionFragment(context, fragment = fragment) + visionFragment(visionManager, fragment = fragment) } } renderScriptForId(id) diff --git a/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt b/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt index 8aa9348a..bf6322e9 100644 --- a/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt +++ b/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt @@ -9,6 +9,7 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionManager import space.kscience.visionforge.html.* import kotlin.random.Random import kotlin.random.nextUInt @@ -17,9 +18,12 @@ import kotlin.random.nextUInt * A base class for different Jupyter VF integrations */ @DFExperimental -public abstract class VFIntegrationBase(final override val context: Context) : JupyterIntegration(), ContextAware { +public abstract class VFIntegrationBase( + public val visionManager: VisionManager, +) : JupyterIntegration(), ContextAware { - protected val handler: VFForNotebook = VFForNotebook(context) + override val context: Context get() = visionManager.context + protected val handler: VFForNotebook = VFForNotebook(visionManager.context) protected abstract fun Builder.afterLoaded() @@ -67,7 +71,7 @@ public abstract class VFIntegrationBase(final override val context: Context) : J val id = "fragment[${page.hashCode()}/${Random.nextUInt()}]" div { this.id = id - visionFragment(context, fragment = page.content) + visionFragment(visionManager, fragment = page.content) } renderScriptForId(id) } diff --git a/jupyter/src/jvmMain/kotlin/forms.kt b/jupyter/src/jvmMain/kotlin/forms.kt new file mode 100644 index 00000000..bccce2e7 --- /dev/null +++ b/jupyter/src/jvmMain/kotlin/forms.kt @@ -0,0 +1,27 @@ +package space.kscience.visionforge.jupyter + +import kotlinx.html.FORM +import kotlinx.html.form +import kotlinx.html.id +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.get +import space.kscience.visionforge.html.HtmlFragment +import space.kscience.visionforge.html.VisionOfHtmlForm + +public class HtmlFormFragment internal constructor( + public val vision: VisionOfHtmlForm, + public val formBody: HtmlFragment, +){ + public val values: Meta? get() = vision.values + public operator fun get(valueName: String): Meta? = values?.get(valueName) +} + +public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment { + val realId = id ?: "form[${builder.hashCode().toUInt()}]" + return HtmlFormFragment(VisionOfHtmlForm(realId)) { + form { + this.id = realId + builder() + } + } +} \ No newline at end of file diff --git a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt index 0f430053..0d55be2e 100644 --- a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt +++ b/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt @@ -7,12 +7,13 @@ import space.kscience.gdml.Gdml import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.jupyter.VFIntegrationBase import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.visionManager @DFExperimental internal class GdmlForJupyter : VFIntegrationBase( Context("GDML") { plugin(Solids) - } + }.visionManager ) { override fun Builder.afterLoaded() { diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt index 191742ca..03cbb722 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt @@ -25,7 +25,7 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { override fun rateVision(vision: Vision): Int = if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { createRoot(element).render { child(ThreeCanvasWithControls) { attrs { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt index 341c38ab..d3c2427f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt @@ -1,7 +1,6 @@ package space.kscience.visionforge.html import kotlinx.html.* -import space.kscience.dataforge.context.Context import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name @@ -15,8 +14,6 @@ public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit @DFExperimental public fun HtmlVisionFragment(content: VisionTagConsumer<*>.() -> Unit): HtmlVisionFragment = content -public typealias VisionCollector = MutableMap> - /** * Render a fragment in the given consumer and return a map of extracted visions @@ -27,15 +24,18 @@ public typealias VisionCollector = MutableMap> * @param idPrefix a prefix to be used before vision ids */ public fun TagConsumer<*>.visionFragment( - context: Context, + visionManager: VisionManager, embedData: Boolean = true, fetchDataUrl: String? = null, updatesUrl: String? = null, idPrefix: String? = null, - collector: VisionCollector = mutableMapOf(), + onVisionRendered: (Name, Vision) -> Unit = { _, _ -> }, fragment: HtmlVisionFragment, ) { - val consumer = object : VisionTagConsumer(this@visionFragment, context, idPrefix) { + + val collector: MutableMap> = mutableMapOf() + + val consumer = object : VisionTagConsumer(this@visionFragment, visionManager, idPrefix) { override fun TagConsumer.vision(name: Name?, buildOutput: VisionOutput.() -> Vision): T { //Avoid re-creating cached visions @@ -47,6 +47,7 @@ public fun TagConsumer<*>.visionFragment( val (output, vision) = collector.getOrPut(actualName) { val output = VisionOutput(context, actualName) val vision = output.buildOutput() + onVisionRendered(actualName, vision) output to vision } @@ -54,8 +55,15 @@ public fun TagConsumer<*>.visionFragment( } override fun DIV.renderVision(manager: VisionManager, name: Name, vision: Vision, outputMeta: Meta) { - // Toggle update mode + val (_, actualVision) = collector.getOrPut(name) { + val output = VisionOutput(context, name) + onVisionRendered(name, vision) + output to vision + } + + + // Toggle update mode updatesUrl?.let { attributes[OUTPUT_CONNECT_ATTRIBUTE] = it } @@ -69,7 +77,7 @@ public fun TagConsumer<*>.visionFragment( type = "text/json" attributes["class"] = OUTPUT_DATA_CLASS unsafe { - +"\n${manager.encodeToString(vision)}\n" + +"\n${manager.encodeToString(actualVision)}\n" } } } @@ -80,19 +88,20 @@ public fun TagConsumer<*>.visionFragment( } public fun FlowContent.visionFragment( - context: Context, + visionManager: VisionManager, embedData: Boolean = true, fetchDataUrl: String? = null, updatesUrl: String? = null, + onVisionRendered: (Name, Vision) -> Unit = { _, _ -> }, idPrefix: String? = null, - visionCache: VisionCollector = mutableMapOf(), + fragment: HtmlVisionFragment, ): Unit = consumer.visionFragment( - context, - embedData, - fetchDataUrl, - updatesUrl, - idPrefix, - visionCache, + visionManager = visionManager, + embedData = embedData, + fetchDataUrl = fetchDataUrl, + updatesUrl = updatesUrl, + idPrefix = idPrefix, + onVisionRendered = onVisionRendered, fragment = fragment ) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt index 4315066a..d9c0347d 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt @@ -7,7 +7,6 @@ import kotlinx.html.id import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.node @Serializable @@ -18,29 +17,10 @@ public class VisionOfHtmlForm( public var values: Meta? by mutableProperties.node() } -public class HtmlFormFragment internal constructor( - public val vision: VisionOfHtmlForm, - public val formBody: HtmlFragment, -){ - public val values: Meta? get() = vision.values - public operator fun get(valueName: String): Meta? = values?.get(valueName) -} - -public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment { - val realId = id ?: "form[${builder.hashCode().toUInt()}]" - return HtmlFormFragment(VisionOfHtmlForm(realId)) { - form { - this.id = realId - builder() - } - } -} - -public fun TagConsumer.formFragment( - id: String? = null, +public fun TagConsumer.bindForm( + visionOfForm: VisionOfHtmlForm, builder: FORM.() -> Unit, -): VisionOfHtmlForm { - val formFragment = HtmlFormFragment(id, builder) - fragment(formFragment.formBody) - return formFragment.vision +): R = form { + this.id = visionOfForm.formId + builder() } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt index 6fc915ef..80a7be7e 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.html import kotlinx.html.* import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaSerializer @@ -56,9 +57,11 @@ public class VisionOutput @PublishedApi internal constructor(public val context: @VisionDSL public abstract class VisionTagConsumer( private val root: TagConsumer, - public val context: Context, + public val visionManager: VisionManager, private val idPrefix: String? = null, -) : TagConsumer by root { +) : TagConsumer by root, ContextAware { + + override val context: Context get() = visionManager.context public open fun resolveId(name: Name): String = (idPrefix ?: "output") + "[$name]" diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index 670f2018..efc7cfd0 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -18,7 +18,7 @@ fun FlowContent.renderVisionFragment( fragment: HtmlVisionFragment, ): Map { val visionMap = HashMap() - val consumer = object : VisionTagConsumer(consumer, Global, idPrefix) { + val consumer = object : VisionTagConsumer(consumer, Global.visionManager, idPrefix) { override fun DIV.renderVision(manager: VisionManager, name: Name, vision: Vision, outputMeta: Meta) { visionMap[name] = vision renderer(name, vision, outputMeta) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index efb8a9fe..9a6547ce 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -4,6 +4,7 @@ import kotlinx.browser.document import kotlinx.browser.window import kotlinx.coroutines.Job import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import org.w3c.dom.* import org.w3c.dom.url.URL @@ -68,18 +69,6 @@ public class VisionClient : AbstractPlugin() { changeCollector.propertyChanged(visionName, propertyName, item) } - public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: Boolean) { - visionPropertyChanged(visionName, propertyName, Meta(item)) - } - - public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: String) { - visionPropertyChanged(visionName, propertyName, Meta(item)) - } - - public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: Number) { - visionPropertyChanged(visionName, propertyName, Meta(item)) - } - public fun visionChanged(name: Name?, child: Vision?) { changeCollector.setChild(name, child) } @@ -139,10 +128,12 @@ public class VisionClient : AbstractPlugin() { onopen = { feedbackJob = visionManager.context.launch { - delay(feedbackAggregationTime.milliseconds) - if (!changeCollector.isEmpty()) { - send(visionManager.encodeToString(changeCollector.deepCopy(visionManager))) - changeCollector.reset() + while (isActive) { + delay(feedbackAggregationTime.milliseconds) + if (!changeCollector.isEmpty()) { + send(visionManager.encodeToString(changeCollector.deepCopy(visionManager))) + changeCollector.reset() + } } } logger.info { "WebSocket update channel established for output '$name'" } @@ -247,6 +238,21 @@ public class VisionClient : AbstractPlugin() { } } +public fun VisionClient.visionPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { + visionPropertyChanged(visionName, propertyName.parseAsName(true), item) +} + +public fun VisionClient.visionPropertyChanged(visionName: Name, propertyName: String, item: Number) { + visionPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} + +public fun VisionClient.visionPropertyChanged(visionName: Name, propertyName: String, item: String) { + visionPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} + +public fun VisionClient.visionPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { + visionPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} private fun whenDocumentLoaded(block: Document.() -> Unit): Unit { if (document.body != null) { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index 86324d89..390058ea 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -9,8 +9,11 @@ import org.w3c.dom.HTMLFormElement import org.w3c.dom.HTMLInputElement import org.w3c.dom.get import org.w3c.xhr.FormData +import space.kscience.dataforge.context.debug +import space.kscience.dataforge.context.logger import space.kscience.dataforge.meta.DynamicMeta import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.toMap import space.kscience.dataforge.meta.valueSequence import space.kscience.visionforge.html.VisionOfHtmlForm import space.kscience.visionforge.html.VisionOfNumberField @@ -33,7 +36,7 @@ internal fun textVisionRenderer( value = it ?: "" } onChangeFunction = { -// client.visionPropertyChanged(name, VisionOfTextField::text.name.pa, value) + client.visionPropertyChanged(name, VisionOfTextField::text.name, value) } } } @@ -55,7 +58,7 @@ internal fun numberVisionRenderer( value = it?.toDouble() ?: 0.0 } onChangeFunction = { -// vision.value = value.toDoubleOrNull() + client.visionPropertyChanged(name, VisionOfNumberField::value.name, value) } } } @@ -90,9 +93,10 @@ internal fun formVisionRenderer( val form = document.getElementById(vision.formId) as? HTMLFormElement ?: error("An element with id = '${vision.formId} is not a form") - console.info("Adding hooks to form '$form'") + client.logger.debug{"Adding hooks to form with id = '$vision.formId'"} vision.useProperty(VisionOfHtmlForm::values) { values -> + client.logger.debug{"Updating form '${vision.formId}' with values $values"} val inputs = form.getElementsByTagName("input") values?.valueSequence()?.forEach { (token, value) -> (inputs[token.toString()] as? HTMLInputElement)?.value = value.toString() @@ -102,8 +106,8 @@ internal fun formVisionRenderer( form.onsubmit = { event -> event.preventDefault() val formData = FormData(form).toMeta() - //console.log(formData.toString()) - //vision.values = formData + client.visionPropertyChanged(name, VisionOfHtmlForm::values.name, formData) + console.info("Sent: ${formData.toMap()}") false } } \ No newline at end of file diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index cba1ee31..ff0c3eee 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -1,4 +1,4 @@ -package space.kscience.visionforge +package space.kscience.visionforge.html import kotlinx.html.body import kotlinx.html.head @@ -6,10 +6,7 @@ import kotlinx.html.meta import kotlinx.html.stream.createHTML import space.kscience.dataforge.context.Global import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.html.HtmlFragment -import space.kscience.visionforge.html.VisionPage -import space.kscience.visionforge.html.fragment -import space.kscience.visionforge.html.visionFragment +import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Files import java.nio.file.Path @@ -87,7 +84,7 @@ public fun VisionPage.makeFile( } } body { - visionFragment(Global, fragment = content) + visionFragment(Global.visionManager, fragment = content) } }.finalize() diff --git a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt index d3b8473e..8344e52e 100644 --- a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt +++ b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt @@ -28,7 +28,7 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { else -> ElementVisionRenderer.ZERO_RATING } - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { val plot = (vision as? VisionOfPlotly)?.plot ?: error("VisionOfPlotly expected but ${vision::class} found") val config = PlotlyConfig.read(meta) element.plot(plot, config) diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 957936a3..42f02e75 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -15,7 +15,6 @@ import io.ktor.server.util.* import io.ktor.server.websocket.* import io.ktor.util.pipeline.* import io.ktor.websocket.* -import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -97,8 +96,8 @@ public fun Application.serveVisionData( val vision: Vision = resolveVision(Name.parse(name)) ?: error("Plot with id='$name' not registered") launch { - incoming.consumeEach { - val data = it.data.decodeToString() + for(frame in incoming) { + val data = frame.data.decodeToString() application.log.debug("Received update: \n$data") val change = configuration.visionManager.jsonFormat.decodeFromString( VisionChange.serializer(), data @@ -143,8 +142,8 @@ public fun Application.serveVisionData( public fun Application.serveVisionData( configuration: VisionRoute, - cache: VisionCollector, -): Unit = serveVisionData(configuration) { cache[it]?.second } + data: Map, +): Unit = serveVisionData(configuration) { data[it] } // ///** @@ -179,7 +178,7 @@ public fun Application.visionPage( ) { require(WebSockets) - val collector: VisionCollector = mutableMapOf() + val collector: MutableMap = mutableMapOf() val html = createHTML().apply { head { @@ -193,7 +192,7 @@ public fun Application.visionPage( body { //Load the fragment and remember all loaded visions visionFragment( - context = configuration.context, + visionManager = configuration.visionManager, embedData = configuration.dataMode == VisionRoute.Mode.EMBED, fetchDataUrl = if (configuration.dataMode != VisionRoute.Mode.EMBED) { url { @@ -210,7 +209,7 @@ public fun Application.visionPage( path(route, "ws") } } else null, - visionCache = collector, + onVisionRendered = { name, vision -> collector[name] = vision }, fragment = visionFragment ) } diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index 28ad7327..dcf7ce4f 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -35,7 +35,7 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { else -> ElementVisionRenderer.ZERO_RATING } - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { val table: VisionOfTable = (vision as? VisionOfTable) ?: error("VisionOfTable expected but ${vision::class} found") diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index bae26853..5aacba18 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -86,7 +86,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { }.launchIn(context) vision.children.changes.onEach { childName -> - if(childName.isEmpty()) return@onEach + if (childName.isEmpty()) return@onEach val child = vision.children.getChild(childName) @@ -147,7 +147,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { render(vision) } - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { renderSolid( element, vision as? Solid ?: error("Solid expected but ${vision::class} found"), diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt index 8f52ccf1..ba533979 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt @@ -3,7 +3,6 @@ package space.kscience.visionforge.three import space.kscience.dataforge.context.Global import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.html.* -import space.kscience.visionforge.makeFile import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Path From d28873e796fc8315da750417ff00dbf7a4132c18 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 6 Dec 2022 17:04:13 +0300 Subject: [PATCH 043/112] Refactor server API --- .../src/jvmMain/kotlin/formServer.kt | 4 +-- .../kscience/visionforge/VisionChange.kt | 6 +++-- .../kscience/visionforge/VisionClient.kt | 21 ++++++++------- .../visionforge/server/VisionServer.kt | 27 +++---------------- 4 files changed, 20 insertions(+), 38 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index cef13f0b..461262a5 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -31,7 +31,7 @@ fun main() { val form = VisionOfHtmlForm("form").apply { onPropertyChange(visionManager.context) { - println(this) + println(values) } } @@ -71,7 +71,7 @@ fun main() { value = "Submit" } } - + println(form.values) vision(form) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 1fbc33bc..358e72aa 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -55,6 +55,8 @@ public class VisionChangeBuilder : MutableVisionContainer { private var propertyChange = MutableMeta() private val children: HashMap = HashMap() + public operator fun get(name: Name): VisionChangeBuilder? = children[name] + public fun isEmpty(): Boolean = propertyChange.isEmpty() && propertyChange.isEmpty() && children.isEmpty() @Synchronized @@ -153,7 +155,7 @@ private fun CoroutineScope.collectChange( */ public fun Vision.flowChanges( collectionDuration: Duration, - sendInitial: Boolean = false + sendInitial: Boolean = false, ): Flow = flow { val manager = manager ?: error("Orphan vision could not collect changes") coroutineScope { @@ -161,7 +163,7 @@ public fun Vision.flowChanges( val mutex = Mutex() collectChange(Name.EMPTY, this@flowChanges, mutex, collector) - if(sendInitial) { + if (sendInitial) { //Send initial vision state val initialChange = VisionChange(vision = deepCopy(manager)) emit(initialChange) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index 9a6547ce..6f322268 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -69,9 +69,9 @@ public class VisionClient : AbstractPlugin() { changeCollector.propertyChanged(visionName, propertyName, item) } - public fun visionChanged(name: Name?, child: Vision?) { - changeCollector.setChild(name, child) - } +// public fun visionChanged(name: Name?, child: Vision?) { +// changeCollector.setChild(name, child) +// } private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) { vision.setAsRoot(visionManager) @@ -79,7 +79,7 @@ public class VisionClient : AbstractPlugin() { renderer.render(element, name, vision, outputMeta) } - private fun updateVision(element: Element, name: Name, vision: Vision?, outputMeta: Meta) { + private fun startVisionUpdate(element: Element, name: Name, vision: Vision?, outputMeta: Meta) { element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { val endpoint = resolveEndpoint(element) @@ -130,9 +130,10 @@ public class VisionClient : AbstractPlugin() { feedbackJob = visionManager.context.launch { while (isActive) { delay(feedbackAggregationTime.milliseconds) - if (!changeCollector.isEmpty()) { - send(visionManager.encodeToString(changeCollector.deepCopy(visionManager))) - changeCollector.reset() + val change = changeCollector[name] ?: continue + if (!change.isEmpty()) { + send(visionManager.encodeToString(change.deepCopy(visionManager))) + change.reset() } } } @@ -192,7 +193,7 @@ public class VisionClient : AbstractPlugin() { response.text().then { text -> val vision = visionManager.decodeFromString(text) renderVision(element, name, vision, outputMeta) - updateVision(element, name, vision, outputMeta) + startVisionUpdate(element, name, vision, outputMeta) } } else { logger.error { "Failed to fetch initial vision state from $fetchUrl" } @@ -208,12 +209,12 @@ public class VisionClient : AbstractPlugin() { } logger.info { "Found embedded vision for output with name $name" } renderVision(element, name, embeddedVision, outputMeta) - updateVision(element, name, embeddedVision, outputMeta) + startVisionUpdate(element, name, embeddedVision, outputMeta) } //Try to load vision via websocket element.attributes[OUTPUT_CONNECT_ATTRIBUTE] != null -> { - updateVision(element, name, null, outputMeta) + startVisionUpdate(element, name, null, outputMeta) } else -> error("No embedded vision data / fetch url for $name") diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 42f02e75..c05a1834 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -93,12 +93,12 @@ public fun Application.serveVisionData( webSocket("ws") { val name: String = call.request.queryParameters.getOrFail("name") application.log.debug("Opened server socket for $name") - val vision: Vision = resolveVision(Name.parse(name)) ?: error("Plot with id='$name' not registered") + val vision: Vision = resolveVision(Name.parse(name)) ?: error("Vision with id='$name' not registered") launch { for(frame in incoming) { val data = frame.data.decodeToString() - application.log.debug("Received update: \n$data") + application.log.debug("Received update for $name: \n$data") val change = configuration.visionManager.jsonFormat.decodeFromString( VisionChange.serializer(), data ) @@ -113,7 +113,7 @@ public fun Application.serveVisionData( VisionChange.serializer(), update ) - application.log.debug("Sending update: \n$json") + application.log.debug("Sending update for $name: \n$json") outgoing.send(Frame.Text(json)) }.collect() } @@ -145,27 +145,6 @@ public fun Application.serveVisionData( data: Map, ): Unit = serveVisionData(configuration) { data[it] } -// -///** -// * Compile a fragment to string and serve visions from it -// */ -//public fun Route.serveVisionsFromFragment( -// consumer: TagConsumer<*>, -// sererPageUrl: Url, -// visionManager: VisionManager, -// fragment: HtmlVisionFragment, -//): Unit { -// val visions = consumer.visionFragment( -// visionManager.context, -// embedData = true, -// fetchUpdatesUrl = "$serverUrl$route/ws", -// fragment = fragment -// ) -// -// serveVisionData(visionManager, visions) -//} - - /** * Serve a page, potentially containing any number of visions at a given [route] with given [header]. */ From 2bdaea2e82fd0dff22783d6c1c4687ee5c63ce5c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 17 Jan 2023 18:50:19 +0300 Subject: [PATCH 044/112] Update dependencies and compatibility --- demo/gdml/build.gradle.kts | 4 +- .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 2 +- demo/js-playground/build.gradle.kts | 4 +- .../src/main/kotlin/JsPlaygroundApp.kt | 2 +- demo/muon-monitor/build.gradle.kts | 2 +- .../ru/mipt/npm/muon/monitor/MMDemoApp.kt | 2 +- demo/playground/build.gradle.kts | 6 ++- .../src/jvmMain/kotlin/serverExtensions.kt | 6 ++- demo/sat-demo/build.gradle.kts | 2 +- .../src/main/kotlin/ru/mipt/npm/sat/static.kt | 21 ++++++++++ gradle.properties | 3 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../visionforge-jupyter-gdml/build.gradle.kts | 4 +- .../bootstrap/visionPropertyEditor.kt | 3 +- .../kscience/visionforge/react/createRoot.kt | 17 ++++++++ ui/ring/build.gradle.kts | 4 +- .../ThreeWithControlsPlugin.kt | 3 +- .../ringPropertyEditor.kt | 1 - .../kscience/visionforge/html/headers.kt | 40 +++++++++++++------ visionforge-tables/build.gradle.kts | 4 +- .../visionforge/tables/TableVisionJsPlugin.kt | 2 +- .../solid/three/ThreeLabelFactory.kt | 2 +- .../kscience/visionforge/three/jsMain.kt | 6 +-- .../visionforge/three/serverExtensions.kt | 7 +++- .../visionforge/three/TestServerExtensions.kt | 23 +++++++++++ 25 files changed, 130 insertions(+), 42 deletions(-) create mode 100644 demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt create mode 100644 ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt create mode 100644 visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index 39c82290..69f56419 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -21,7 +21,9 @@ kotlin { useCommonJs() browser { commonWebpackConfig { - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } } diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index e2d7ad51..5f1d24e1 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -2,13 +2,13 @@ package space.kscience.visionforge.gdml.demo import kotlinx.css.* import org.w3c.dom.Document -import react.dom.client.createRoot import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Application import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.react.createRoot import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index ada5841a..3368c5ef 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -12,7 +12,9 @@ kotlin{ useCommonJs() browser { commonWebpackConfig { - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } } diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index 2c93d31f..781aa897 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -1,6 +1,5 @@ import kotlinx.css.* import org.w3c.dom.Document -import react.dom.client.createRoot import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.context.Context @@ -11,6 +10,7 @@ import space.kscience.visionforge.Application import space.kscience.visionforge.Colors import space.kscience.visionforge.VisionClient import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.react.createRoot import space.kscience.visionforge.react.render import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.ThreeWithControlsPlugin diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index fe3f89cb..f25c8371 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { browser { commonWebpackConfig { cssSupport { - enabled = false + enabled.set(false) } } } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 50e51859..d28516d0 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -1,11 +1,11 @@ package ru.mipt.npm.muon.monitor import org.w3c.dom.Document -import react.dom.client.createRoot import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch import space.kscience.visionforge.Application import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.react.createRoot import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.three.ThreePlugin diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index 076f9d37..57c6bfd2 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -16,11 +16,13 @@ kotlin { useCommonJs() browser { webpackTask { - this.outputFileName = "js/visionforge-playground.js" + outputFileName = "js/visionforge-playground.js" } commonWebpackConfig { sourceMaps = true - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } binaries.executable() diff --git a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt index b22c6514..9eb87730 100644 --- a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt +++ b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt @@ -16,7 +16,11 @@ public fun makeVisionFile( val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath -> mapOf( "title" to VisionPage.title(title), - "playground" to VisionPage.importScriptHeader("js/visionforge-playground.js", resourceLocation, actualPath), + "playground" to VisionPage.importScriptHeader( + "js/visionforge-playground.js", + resourceLocation, + actualPath + ), ) } if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 870f3388..406591ee 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -15,7 +15,7 @@ group = "ru.mipt.npm" dependencies{ implementation(project(":visionforge-threejs:visionforge-threejs-server")) - implementation("ch.qos.logback:logback-classic:1.2.11") + implementation("ch.qos.logback:logback-classic:1.4.5") } application { diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt new file mode 100644 index 00000000..2a1fd240 --- /dev/null +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt @@ -0,0 +1,21 @@ +package ru.mipt.npm.sat + +import space.kscience.dataforge.misc.DFExperimental +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.solid.box +import space.kscience.visionforge.solid.material +import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.three.makeThreeJsFile + +@OptIn(DFExperimental::class) +fun main() = makeThreeJsFile(resourceLocation = ResourceLocation.SYSTEM) { + vision ("canvas") { + solid { + box(100, 100, 100) + material { + emissiveColor.set("red") + } + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 056b8ac8..b80e2265 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,8 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true -kotlin.jupyter.add.scanner=false kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.13.3-kotlin-1.7.20 \ No newline at end of file +toolsVersion=0.13.4-kotlin-1.8.0 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661e..070cb702 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/jupyter/visionforge-jupyter-gdml/build.gradle.kts index 3129de1e..1198f022 100644 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ b/jupyter/visionforge-jupyter-gdml/build.gradle.kts @@ -14,7 +14,9 @@ kotlin { } commonWebpackConfig { sourceMaps = false - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } binaries.executable() diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index 6ea0659c..8e7e1208 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.bootstrap import org.w3c.dom.Element import react.RBuilder -import react.dom.client.createRoot import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.isEmpty import space.kscience.visionforge.Vision @@ -67,6 +66,6 @@ public fun RBuilder.visionPropertyEditor( public fun Element.visionPropertyEditor( item: Vision, descriptor: MetaDescriptor? = item.descriptor, -): Unit = createRoot(this).render { +): Unit = space.kscience.visionforge.react.createRoot(this).render { visionPropertyEditor(item, descriptor = descriptor) } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt new file mode 100644 index 00000000..fec86770 --- /dev/null +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt @@ -0,0 +1,17 @@ + +@file:JsModule("react-dom/client") +@file:JsNonModule + +package space.kscience.visionforge.react + +import org.w3c.dom.Element +import react.dom.client.Root +import react.dom.client.RootOptions + +/** + * Compatibility method to work with old browser API + */ +public external fun createRoot( + container: Element, + options: RootOptions = definedExternally, +): Root diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts index aa168c11..8b4bf056 100644 --- a/ui/ring/build.gradle.kts +++ b/ui/ring/build.gradle.kts @@ -9,7 +9,9 @@ kotlin{ useCommonJs() browser { commonWebpackConfig { - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt index 03cbb722..60f36fb0 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.ring import kotlinx.coroutines.async import org.w3c.dom.Element -import react.dom.client.createRoot import space.kscience.dataforge.context.AbstractPlugin import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory @@ -26,7 +25,7 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { - createRoot(element).render { + space.kscience.visionforge.react.createRoot(element).render { child(ThreeCanvasWithControls) { attrs { this.solids = three.solids diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt index a3f81adb..83529d28 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.ring import org.w3c.dom.Element import react.RBuilder -import react.dom.client.createRoot import react.dom.p import ringui.Island import ringui.SmartTabs diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt index 71410372..4c4ab90a 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt @@ -4,12 +4,10 @@ import kotlinx.html.link import kotlinx.html.script import kotlinx.html.unsafe import org.slf4j.LoggerFactory -import space.kscience.visionforge.VisionManager import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardOpenOption import java.security.MessageDigest -import kotlin.io.path.ExperimentalPathApi import kotlin.io.path.readText @@ -47,15 +45,14 @@ private fun ByteArray.toHexString() = asUByteArray().joinToString("") { it.toStr * Check if the asset exists in given local location and put it there if it does not * @param */ -@OptIn(ExperimentalPathApi::class) -internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): Path { +internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String, classLoader: ClassLoader): Path { val logger = LoggerFactory.getLogger("") logger.info("Resolving or storing resource file $resource") val fullPath = htmlPath.resolveSibling(filePath).toAbsolutePath().resolve(resource) logger.debug("Full path to resource file $resource: $fullPath") - val bytes = VisionManager.Companion::class.java.getResourceAsStream("/$resource")?.readAllBytes() + val bytes = classLoader.getResourceAsStream(resource)?.readAllBytes() ?: error("Resource $resource not found on classpath") val md = MessageDigest.getInstance("MD5") @@ -66,8 +63,20 @@ internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): if (!skip) { logger.debug("File $fullPath does not exist or wrong checksum. Writing file") Files.createDirectories(fullPath.parent) - Files.write(fullPath, bytes, StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE) - Files.write(md5File, checksum.encodeToByteArray(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE) + Files.write( + fullPath, + bytes, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE + ) + Files.write( + md5File, + checksum.encodeToByteArray(), + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE + ) } return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) { @@ -89,11 +98,11 @@ internal fun fileScriptHeader( } } -internal fun embedScriptHeader(resource: String): HtmlFragment = { +internal fun embedScriptHeader(resource: String, classLoader: ClassLoader): HtmlFragment = { script { type = "text/javascript" unsafe { - val bytes = VisionManager::class.java.getResourceAsStream("/$resource")!!.readAllBytes() + val bytes = classLoader.getResourceAsStream(resource)!!.readAllBytes() +bytes.toString(Charsets.UTF_8) } } @@ -103,8 +112,9 @@ internal fun fileCssHeader( basePath: Path, cssPath: Path, resource: String, + classLoader: ClassLoader, ): HtmlFragment = { - val relativePath = checkOrStoreFile(basePath, cssPath, resource) + val relativePath = checkOrStoreFile(basePath, cssPath, resource, classLoader) link { rel = "stylesheet" href = relativePath.toString() @@ -118,22 +128,26 @@ public fun VisionPage.Companion.importScriptHeader( scriptResource: String, resourceLocation: ResourceLocation, htmlPath: Path? = null, + classLoader: ClassLoader = Thread.currentThread().contextClassLoader, ): HtmlFragment { val targetPath = when (resourceLocation) { ResourceLocation.LOCAL -> checkOrStoreFile( htmlPath ?: Path.of("."), Path.of(VISIONFORGE_ASSETS_PATH), - scriptResource + scriptResource, + classLoader ) + ResourceLocation.SYSTEM -> checkOrStoreFile( Path.of("."), Path.of(System.getProperty("user.home")).resolve(VISIONFORGE_ASSETS_PATH), - scriptResource + scriptResource, classLoader ) + ResourceLocation.EMBED -> null } return if (targetPath == null) { - embedScriptHeader(scriptResource) + embedScriptHeader(scriptResource, classLoader) } else { fileScriptHeader(targetPath) } diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index 55cc27e5..abc56455 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -14,7 +14,9 @@ kotlin { binaries.library() browser{ commonWebpackConfig{ - cssSupport.enabled = true + cssSupport{ + enabled.set(true) + } } } } diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index dcf7ce4f..4764069f 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -1,6 +1,6 @@ package space.kscience.visionforge.tables -import kotlinx.js.jso +import js.core.jso import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.AbstractPlugin diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index 2bd8c572..e168c1d2 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid.three -import kotlinx.js.jso +import js.core.jso import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.warn import space.kscience.visionforge.onPropertyChange diff --git a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt index 69a9ac51..ed2908f5 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt @@ -6,8 +6,6 @@ import space.kscience.visionforge.solid.three.ThreePlugin @DFExperimental -public fun main(): Unit { - runVisionClient { - plugin(ThreePlugin) - } +public fun main(): Unit = runVisionClient { + plugin(ThreePlugin) } \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt index ba533979..28f04f8d 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt @@ -10,7 +10,6 @@ import java.nio.file.Path public val VisionPage.Companion.threeJsHeader: HtmlFragment get() = scriptHeader("js/visionforge-three.js") - @DFExperimental public fun makeThreeJsFile( path: Path? = null, @@ -22,7 +21,11 @@ public fun makeThreeJsFile( val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath -> mapOf( "title" to VisionPage.title(title), - "threeJs" to VisionPage.importScriptHeader("js/visionforge-three.js", resourceLocation, actualPath) + "threeJs" to VisionPage.importScriptHeader( + "js/visionforge-three.js", + resourceLocation, + actualPath, + ) ) } if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt new file mode 100644 index 00000000..99e7fba6 --- /dev/null +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt @@ -0,0 +1,23 @@ +package space.kscience.visionforge.three + +import kotlinx.html.stream.createHTML +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.html.importScriptHeader +import kotlin.test.Test + +class TestServerExtensions { + + @Test + fun testServerHeader(){ + val string = createHTML().apply { + VisionPage.importScriptHeader( + "js/visionforge-three.js", + ResourceLocation.SYSTEM + ).invoke(this) + }.finalize() + + + //println(string) + } +} \ No newline at end of file From 35fc7a70426167d457ad0d09a62212b614e7ef15 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 17 Jan 2023 19:20:48 +0300 Subject: [PATCH 045/112] Update threejs server --- build.gradle.kts | 2 +- .../build.gradle.kts | 12 +++++++--- .../kscience/visionforge/three/jsMain.kt | 4 ++-- .../webpack.config.d/01.ring.js | 23 +++++++++++++++++++ .../webpack.config.d/02.bundle.js | 10 ++++++++ 5 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 visionforge-threejs/visionforge-threejs-server/webpack.config.d/01.ring.js create mode 100644 visionforge-threejs/visionforge-threejs-server/webpack.config.d/02.bundle.js diff --git a/build.gradle.kts b/build.gradle.kts index 5a82b18c..c9ee8e6d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-5" + version = "0.3.0-dev-7" } subprojects { diff --git a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts index 7623086d..d3ef8496 100644 --- a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts +++ b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts @@ -10,6 +10,11 @@ kotlin { webpackTask { this.outputFileName = "js/visionforge-three.js" } + commonWebpackConfig { + cssSupport{ + enabled.set(false) + } + } } binaries.executable() } @@ -17,17 +22,18 @@ kotlin { sourceSets { commonMain { dependencies { - api(project(":visionforge-solid")) + api(projects.visionforgeSolid) } } jvmMain { dependencies { - api(project(":visionforge-server")) + api(projects.visionforgeServer) } } jsMain { dependencies { - api(project(":visionforge-threejs")) + api(projects.visionforgeThreejs) + api(projects.ui.ring) } } } diff --git a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt index ed2908f5..d1635ddf 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt @@ -1,11 +1,11 @@ package space.kscience.visionforge.three import space.kscience.dataforge.misc.DFExperimental +import space.kscience.visionforge.ring.ThreeWithControlsPlugin import space.kscience.visionforge.runVisionClient -import space.kscience.visionforge.solid.three.ThreePlugin @DFExperimental public fun main(): Unit = runVisionClient { - plugin(ThreePlugin) + plugin(ThreeWithControlsPlugin) } \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/webpack.config.d/01.ring.js b/visionforge-threejs/visionforge-threejs-server/webpack.config.d/01.ring.js new file mode 100644 index 00000000..b3cc4770 --- /dev/null +++ b/visionforge-threejs/visionforge-threejs-server/webpack.config.d/01.ring.js @@ -0,0 +1,23 @@ +const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; +const path = require('path'); + +config.module.rules.push(...ringConfig.module.rules) + +config.module.rules.push( + { + test: /\.css$/, + exclude: [ + path.resolve(__dirname, "../../node_modules/@jetbrains/ring-ui") + ], + use: [ + { + loader: 'style-loader', + options: {} + }, + { + loader: 'css-loader', + options: {} + } + ] + } +) \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/webpack.config.d/02.bundle.js b/visionforge-threejs/visionforge-threejs-server/webpack.config.d/02.bundle.js new file mode 100644 index 00000000..947253ca --- /dev/null +++ b/visionforge-threejs/visionforge-threejs-server/webpack.config.d/02.bundle.js @@ -0,0 +1,10 @@ +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; + +module.exports = { + plugins: [ + new BundleAnalyzerPlugin({ + analyzerMode: "static", + reportFilename: "bundle-report.html" + }) + ] +} \ No newline at end of file From 4ec611eda39ddbfab6d924a813c54dab72250043 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 May 2023 18:33:30 +0300 Subject: [PATCH 046/112] Update versions --- build.gradle.kts | 2 +- cern-root-loader/build.gradle.kts | 15 +- demo/gdml/build.gradle.kts | 88 +++++----- .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 4 +- .../visionforge/gdml/demo/GdmlFxDemoApp.kt | 166 +++++++++--------- .../src/main/kotlin/JsPlaygroundApp.kt | 6 +- .../src/main/kotlin/plotlyComponent.kt | 4 +- demo/muon-monitor/build.gradle.kts | 78 +++----- .../ru/mipt/npm/muon/monitor/MMDemoApp.kt | 6 +- demo/playground/build.gradle.kts | 1 - .../src/jvmMain/kotlin/formServer.kt | 4 +- .../src/jvmMain/kotlin/generateSchema.kt | 1 + demo/sat-demo/build.gradle.kts | 9 +- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 4 +- demo/solid-showcase/build.gradle.kts | 33 +--- .../visionforge/solid/demo/ThreeDemoGrid.kt | 4 +- .../visionforge/solid/demo/FXDemoApp.kt | 0 .../visionforge/solid/demo/FXDemoGrid.kt | 0 .../visionforge/solid/demo/MetaEditorDemo.kt | 0 gradle.properties | 3 +- jupyter/build.gradle.kts | 23 ++- jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt | 3 - jupyter/src/jvmMain/kotlin/VFForNotebook.kt | 4 +- .../visionforge-jupyter-gdml/build.gradle.kts | 60 ++----- .../src/jsMain/kotlin/gdmlJupyter.kt | 2 +- settings.gradle.kts | 6 +- .../visionforge/react/ThreeCanvasComponent.kt | 4 +- .../ThreeWithControlsPlugin.kt | 2 - visionforge-core/build.gradle.kts | 35 ++-- .../kscience/visionforge/VisionManager.kt | 4 +- .../visionforge/meta/VisionPropertyTest.kt | 13 +- .../kscience/visionforge/VisionClient.kt | 7 +- visionforge-gdml/build.gradle.kts | 23 +-- visionforge-markdown/build.gradle.kts | 17 +- .../visionforge/markup/MarkupPlugin.kt | 2 - .../visionforge/markup/MarkupPlugin.kt | 3 - visionforge-plotly/build.gradle.kts | 19 +- .../kscience/visionforge/plotly/plotlyJs.kt | 4 +- .../kscience/visionforge/plotly/plotlyJvm.kt | 2 - visionforge-server/build.gradle.kts | 18 +- visionforge-solid/build.gradle.kts | 37 ++-- .../space/kscience/visionforge/solid/Solid.kt | 13 +- .../kscience/visionforge/solid/Solids.kt | 6 +- .../visionforge/solid/SolidPluginTest.kt | 4 +- .../visionforge/solid/VisionUpdateTest.kt | 27 +-- visionforge-tables/build.gradle.kts | 29 ++- .../visionforge/tables/TableVisionPlugin.kt | 2 - .../visionforge/tables/TableVisionJsPlugin.kt | 2 - visionforge-threejs/build.gradle.kts | 2 +- .../visionforge/solid/three/ThreePlugin.kt | 1 - .../build.gradle.kts | 59 ++----- 51 files changed, 345 insertions(+), 516 deletions(-) rename demo/solid-showcase/src/{jvmMain => jvmMain-fx}/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt (100%) rename demo/solid-showcase/src/{jvmMain => jvmMain-fx}/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt (100%) rename demo/solid-showcase/src/{jvmMain => jvmMain-fx}/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt (100%) diff --git a/build.gradle.kts b/build.gradle.kts index c9ee8e6d..62623756 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { // id("org.jetbrains.kotlinx.kover") version "0.5.0" } -val dataforgeVersion by extra("0.6.0-dev-15") +val dataforgeVersion by extra("0.6.1") val fxVersion by extra("11") allprojects { diff --git a/cern-root-loader/build.gradle.kts b/cern-root-loader/build.gradle.kts index 0ea3de8f..fb787187 100644 --- a/cern-root-loader/build.gradle.kts +++ b/cern-root-loader/build.gradle.kts @@ -3,17 +3,12 @@ plugins { } kscience{ + jvm() + js() + dependencies { + api(projects.visionforgeSolid) + } useSerialization { json() } -} - -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - api(project(":visionforge-solid")) - } - } - } } \ No newline at end of file diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index 69f56419..3ac3960a 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -1,62 +1,62 @@ -import space.kscience.gradle.DependencyConfiguration -import space.kscience.gradle.FXModule - plugins { id("space.kscience.gradle.mpp") - application } kscience { - val fxVersion: String by rootProject.extra - useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION) - application() -} - -kotlin { - jvm { - withJava() - } - + jvm() js { useCommonJs() browser { commonWebpackConfig { - cssSupport{ + cssSupport { enabled.set(false) } } } } - - sourceSets { - commonMain { - dependencies { - implementation(project(":visionforge-solid")) - implementation(project(":visionforge-gdml")) - } - } - jvmMain { - dependencies { - implementation(project(":visionforge-fx")) - implementation("ch.qos.logback:logback-classic:1.2.11") - } - } - jsMain { - dependencies { - implementation(project(":ui:ring")) - implementation(project(":visionforge-threejs")) - implementation(npm("react-file-drop", "3.0.6")) - } - } + dependencies { + implementation(projects.visionforgeSolid) + implementation(projects.visionforgeGdml) } + jvmMain { +// implementation(project(":visionforge-fx")) + implementation(spclibs.logback.classic) + } + jsMain { + implementation(projects.ui.ring) + implementation(projects.visionforgeThreejs) + implementation(npm("react-file-drop", "3.0.6")) + } + application() } -application { - mainClass.set("space.kscience.visionforge.gdml.demo.GdmlFxDemoAppKt") -} +//kotlin { +// +// sourceSets { +// commonMain { +// dependencies { +// implementation(project(":visionforge-solid")) +// implementation(project(":visionforge-gdml")) +// } +// } +// jvmMain { +// dependencies { +//// implementation(project(":visionforge-fx")) +// implementation("ch.qos.logback:logback-classic:1.2.11") +// } +// } +// jsMain { +// dependencies { +// implementation(project(":ui:ring")) +// implementation(project(":visionforge-threejs")) +// implementation(npm("react-file-drop", "3.0.6")) +// } +// } +// } +//} -val convertGdmlToJson by tasks.creating(JavaExec::class) { - group = "application" - classpath = sourceSets["main"].runtimeClasspath - mainClass.set("space.kscience.dataforge.vis.spatial.gdml.demo.SaveToJsonKt") -} \ No newline at end of file +//val convertGdmlToJson by tasks.creating(JavaExec::class) { +// group = "application" +// classpath = sourceSets["main"].runtimeClasspath +// mainClass.set("space.kscience.dataforge.vis.spatial.gdml.demo.SaveToJsonKt") +//} \ No newline at end of file diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index 5f1d24e1..cdca1957 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge.gdml.demo import kotlinx.css.* import org.w3c.dom.Document import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Application import space.kscience.visionforge.Colors @@ -54,7 +54,7 @@ private class GDMLDemoApp : Application { } //println(context.plugins.fetch(VisionManager).encodeToString(vision)) attrs { - this.solids = context.fetch(Solids) + this.solids = context.request(Solids) this.vision = vision } } diff --git a/demo/gdml/src/jvmMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlFxDemoApp.kt b/demo/gdml/src/jvmMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlFxDemoApp.kt index 83e750ba..92cc69aa 100644 --- a/demo/gdml/src/jvmMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlFxDemoApp.kt +++ b/demo/gdml/src/jvmMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlFxDemoApp.kt @@ -1,83 +1,83 @@ -package space.kscience.visionforge.gdml.demo - -import javafx.geometry.Orientation -import javafx.scene.Parent -import javafx.stage.FileChooser -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch -import space.kscience.gdml.GdmlShowCase -import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.editor.VisionEditorFragment -import space.kscience.visionforge.editor.VisionTreeFragment -import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.solid.FX3DPlugin -import space.kscience.visionforge.solid.FXCanvas3D -import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidMaterial -import tornadofx.* - -class GDMLDemoApp : App(GDMLView::class) - -class GDMLView : View() { - private val context = Context { - plugin(FX3DPlugin) - } - - private val fx3d = context.fetch(FX3DPlugin) - private val visionManager = context.fetch(VisionManager) - private val canvas = FXCanvas3D(fx3d) - - private val treeFragment = VisionTreeFragment().apply { - this.itemProperty.bind(canvas.rootObjectProperty) - } - - private val propertyEditor = VisionEditorFragment().apply { - descriptorProperty.set(SolidMaterial.descriptor) - visionProperty.bind(treeFragment.selectedProperty) - } - - override val root: Parent = borderpane { - top { - buttonbar { - button("Load GDML/json") { - action { - val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull() - if (file != null) { - runAsync { - visionManager.readFile(file) as Solid - } ui { - canvas.render(it) - } - } - } - } - } - } - center { - splitpane(Orientation.HORIZONTAL, treeFragment.root, canvas.root, propertyEditor.root) { - setDividerPositions(0.2, 0.6, 0.2) - } - } - } - - init { - runAsync { - GdmlShowCase.cubes().toVision() - } ui { - canvas.render(it) - } - } - - companion object { - private val fileNameFilter = arrayOf( - FileChooser.ExtensionFilter("GDML", "*.gdml", "*.xml"), - FileChooser.ExtensionFilter("JSON", "*.json"), - FileChooser.ExtensionFilter("JSON.ZIP", "*.json.zip"), - FileChooser.ExtensionFilter("JSON.GZ", "*.json.gz") - ) - } -} - -fun main() { - launch() -} \ No newline at end of file +//package space.kscience.visionforge.gdml.demo +// +//import javafx.geometry.Orientation +//import javafx.scene.Parent +//import javafx.stage.FileChooser +//import space.kscience.dataforge.context.Context +//import space.kscience.dataforge.context.fetch +//import space.kscience.gdml.GdmlShowCase +//import space.kscience.visionforge.VisionManager +//import space.kscience.visionforge.editor.VisionEditorFragment +//import space.kscience.visionforge.editor.VisionTreeFragment +//import space.kscience.visionforge.gdml.toVision +//import space.kscience.visionforge.solid.FX3DPlugin +//import space.kscience.visionforge.solid.FXCanvas3D +//import space.kscience.visionforge.solid.Solid +//import space.kscience.visionforge.solid.SolidMaterial +//import tornadofx.* +// +//class GDMLDemoApp : App(GDMLView::class) +// +//class GDMLView : View() { +// private val context = Context { +// plugin(FX3DPlugin) +// } +// +// private val fx3d = context.fetch(FX3DPlugin) +// private val visionManager = context.fetch(VisionManager) +// private val canvas = FXCanvas3D(fx3d) +// +// private val treeFragment = VisionTreeFragment().apply { +// this.itemProperty.bind(canvas.rootObjectProperty) +// } +// +// private val propertyEditor = VisionEditorFragment().apply { +// descriptorProperty.set(SolidMaterial.descriptor) +// visionProperty.bind(treeFragment.selectedProperty) +// } +// +// override val root: Parent = borderpane { +// top { +// buttonbar { +// button("Load GDML/json") { +// action { +// val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull() +// if (file != null) { +// runAsync { +// visionManager.readFile(file) as Solid +// } ui { +// canvas.render(it) +// } +// } +// } +// } +// } +// } +// center { +// splitpane(Orientation.HORIZONTAL, treeFragment.root, canvas.root, propertyEditor.root) { +// setDividerPositions(0.2, 0.6, 0.2) +// } +// } +// } +// +// init { +// runAsync { +// GdmlShowCase.cubes().toVision() +// } ui { +// canvas.render(it) +// } +// } +// +// companion object { +// private val fileNameFilter = arrayOf( +// FileChooser.ExtensionFilter("GDML", "*.gdml", "*.xml"), +// FileChooser.ExtensionFilter("JSON", "*.json"), +// FileChooser.ExtensionFilter("JSON.ZIP", "*.json.zip"), +// FileChooser.ExtensionFilter("JSON.GZ", "*.json.gz") +// ) +// } +//} +// +//fun main() { +// launch() +//} \ No newline at end of file diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index 781aa897..cb6eb3e6 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -3,7 +3,7 @@ import org.w3c.dom.Document import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.plotly.models.Trace import space.kscience.plotly.scatter import space.kscience.visionforge.Application @@ -52,7 +52,7 @@ private class JsPlaygroundApp : Application { Tab("gravity") { GravityDemo { attrs { - this.solids = playgroundContext.fetch(Solids) + this.solids = playgroundContext.request(Solids) } } } @@ -73,7 +73,7 @@ private class JsPlaygroundApp : Application { child(ThreeCanvasWithControls) { val random = Random(112233) attrs { - solids = playgroundContext.fetch(Solids) + solids = playgroundContext.request(Solids) solid { ambientLight { color.set(Colors.white) diff --git a/demo/js-playground/src/main/kotlin/plotlyComponent.kt b/demo/js-playground/src/main/kotlin/plotlyComponent.kt index 5a2c6a81..322e80c5 100644 --- a/demo/js-playground/src/main/kotlin/plotlyComponent.kt +++ b/demo/js-playground/src/main/kotlin/plotlyComponent.kt @@ -20,9 +20,9 @@ val Plotly = fc("Plotly") { props -> useEffect(props.plot, elementRef) { val element = elementRef.current as? HTMLElement ?: error("Plotly element not found") props.plot?.let { - element.plot(it, PlotlyConfig { + element.plot(PlotlyConfig { responsive = true - }) + }, it) } } diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index f25c8371..3d814223 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -5,74 +5,46 @@ plugins { group = "ru.mipt.npm" -val ktorVersion: String = npmlibs.versions.ktor.get() +val ktorVersion: String = spclibs.versions.ktor.get() kscience { useCoroutines() useSerialization() - application() -} - -kotlin { - jvm { - withJava() - } - js { - useCommonJs() - browser { - commonWebpackConfig { - cssSupport { - enabled.set(false) - } + useKtor() + fullStack( + "muon-monitor.js", + jvmConfig = { withJava() }, + jsConfig = { useCommonJs() } + ) { + commonWebpackConfig { + cssSupport { + enabled.set(false) } } } - sourceSets { - commonMain { - dependencies { - implementation(project(":visionforge-solid")) - } - } - jvmMain { - dependencies { - implementation("org.apache.commons:commons-math3:3.6.1") - implementation("io.ktor:ktor-server-cio:${ktorVersion}") - implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}") - implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}") - implementation("ch.qos.logback:logback-classic:1.2.11") - } - } - jsMain { - dependencies { - implementation(project(":ui:ring")) - implementation(project(":visionforge-threejs")) - //implementation(devNpm("webpack-bundle-analyzer", "4.4.0")) - } - } + commonMain { + implementation(projects.visionforgeSolid) + } + jvmMain { + implementation("org.apache.commons:commons-math3:3.6.1") + implementation("io.ktor:ktor-server-cio:${ktorVersion}") + implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}") + implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}") + implementation("ch.qos.logback:logback-classic:1.2.11") } + jsMain { + implementation(project(":ui:ring")) + implementation(project(":visionforge-threejs")) + //implementation(devNpm("webpack-bundle-analyzer", "4.4.0")) + } + application() } application { mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt") } -val jsBrowserDistribution by tasks.getting -val jsBrowserDevelopmentExecutableDistribution by tasks.getting - -val devMode = rootProject.findProperty("visionforge.development") as? Boolean - ?: rootProject.version.toString().contains("dev") - -tasks.getByName("jvmProcessResources") { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - if (devMode) { - dependsOn(jsBrowserDevelopmentExecutableDistribution) - from(jsBrowserDevelopmentExecutableDistribution) - } else { - dependsOn(jsBrowserDistribution) - from(jsBrowserDistribution) - } -} //distributions { // main { diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index d28516d0..afc9ce80 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -2,7 +2,7 @@ package ru.mipt.npm.muon.monitor import org.w3c.dom.Document import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.visionforge.Application import space.kscience.visionforge.VisionManager import space.kscience.visionforge.react.createRoot @@ -19,7 +19,7 @@ private class MMDemoApp : Application { plugin(ThreePlugin) } - val visionManager = context.fetch(VisionManager) + val visionManager = context.request(VisionManager) val model = Model(visionManager) @@ -28,7 +28,7 @@ private class MMDemoApp : Application { child(MMApp) { attrs { this.model = model - this.solids = context.fetch(Solids) + this.solids = context.request(Solids) } } } diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index 57c6bfd2..fbc0b736 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -29,7 +29,6 @@ kotlin { } jvm { - withJava() compilations.all { kotlinOptions { jvmTarget = "11" diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index 461262a5..2f5b4ea1 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -6,7 +6,7 @@ import io.ktor.server.http.content.resources import io.ktor.server.routing.routing import kotlinx.html.* import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.visionforge.VisionManager import space.kscience.visionforge.html.VisionOfHtmlForm import space.kscience.visionforge.html.VisionPage @@ -18,7 +18,7 @@ import space.kscience.visionforge.server.openInBrowser import space.kscience.visionforge.server.visionPage fun main() { - val visionManager = Global.fetch(VisionManager) + val visionManager = Global.request(VisionManager) val connector = EngineConnectorConfig("localhost", 7777) diff --git a/demo/playground/src/jvmMain/kotlin/generateSchema.kt b/demo/playground/src/jvmMain/kotlin/generateSchema.kt index 8331ac62..672cd0b3 100644 --- a/demo/playground/src/jvmMain/kotlin/generateSchema.kt +++ b/demo/playground/src/jvmMain/kotlin/generateSchema.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.json.Json import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.Solids +@OptIn(ExperimentalSerializationApi::class) private val json = Json { serializersModule = Solids.serializersModuleForSolids prettyPrintIndent = " " diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 406591ee..1b37bfad 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -9,15 +9,14 @@ kscience { // json() // } application() + dependencies{ + implementation(projects.visionforgeThreejs.visionforgeThreejsServer) + implementation("ch.qos.logback:logback-classic:1.4.5") + } } group = "ru.mipt.npm" -dependencies{ - implementation(project(":visionforge-threejs:visionforge-threejs-server")) - implementation("ch.qos.logback:logback-classic:1.4.5") -} - application { mainClass.set("ru.mipt.npm.sat.SatServerKt") } diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index ed8ae38f..d2c33c2c 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.* import kotlinx.html.div import kotlinx.html.h1 import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.Null import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors @@ -29,7 +29,7 @@ fun main() { plugin(Solids) } - val solids = satContext.fetch(Solids) + val solids = satContext.request(Solids) //Create a geometry val sat = solids.visionOfSatellite(ySegments = 3).apply { diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index 2da1299f..0a53b4e2 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -1,6 +1,3 @@ -import space.kscience.gradle.DependencyConfiguration -import space.kscience.gradle.FXModule - plugins { id("space.kscience.gradle.mpp") application @@ -8,34 +5,18 @@ plugins { kscience { useCoroutines() - val fxVersion: String by rootProject.extra - useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION) application() -} - -kotlin { - jvm { withJava() } + js() + dependencies { + implementation(projects.visionforgeSolid) + implementation(projects.visionforgeGdml) + } - sourceSets { - commonMain { - dependencies { - implementation(project(":visionforge-solid")) -// implementation(project(":visionforge-gdml")) - } - } - jvmMain { - dependencies { - implementation(project(":visionforge-fx")) - } - } - jsMain { - dependencies { - implementation(project(":visionforge-threejs")) - } - } + jsMain { + implementation(projects.visionforgeThreejs) } } diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt index d448349c..50e7f174 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt @@ -10,7 +10,7 @@ import org.w3c.dom.Element import org.w3c.dom.HTMLDivElement import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.string @@ -26,7 +26,7 @@ class ThreeDemoGrid(element: Element) : VisionLayout { private val outputs: MutableMap = HashMap() - private val three = Global.fetch(ThreePlugin) + private val three = Global.request(ThreePlugin) override val solids: Solids get() = three.solids diff --git a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt b/demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt similarity index 100% rename from demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt rename to demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt diff --git a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt b/demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt similarity index 100% rename from demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt rename to demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt diff --git a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt b/demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt similarity index 100% rename from demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt rename to demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt diff --git a/gradle.properties b/gradle.properties index b80e2265..11c3aafa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,9 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true +kotlin.js.compiler=ir kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.13.4-kotlin-1.8.0 \ No newline at end of file +toolsVersion=0.14.7-kotlin-1.8.20 \ No newline at end of file diff --git a/jupyter/build.gradle.kts b/jupyter/build.gradle.kts index 45aaeaa3..5808f287 100644 --- a/jupyter/build.gradle.kts +++ b/jupyter/build.gradle.kts @@ -1,25 +1,22 @@ plugins { id("space.kscience.gradle.mpp") - id("org.jetbrains.kotlin.jupyter.api") } description = "Common visionforge jupyter module" -kotlin { - sourceSets { - commonMain{ - dependencies{ - api(projects.visionforgeCore) - } - } - jvmMain { - dependencies { - api(projects.visionforgeServer) - } - } +kscience { + jvm() + js() + jupyterLibrary() + dependencies { + api(projects.visionforgeCore) + } + dependencies(jvmMain){ + api(projects.visionforgeServer) } } + readme { maturity = space.kscience.gradle.Maturity.EXPERIMENTAL } \ No newline at end of file diff --git a/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt b/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt index c13586ba..f6a37f23 100644 --- a/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt +++ b/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt @@ -11,7 +11,6 @@ import space.kscience.visionforge.VisionClient import space.kscience.visionforge.renderAllVisions import space.kscience.visionforge.renderAllVisionsById import space.kscience.visionforge.renderAllVisionsIn -import kotlin.reflect.KClass @JsExport public class VFNotebookPlugin : AbstractPlugin() { @@ -44,8 +43,6 @@ public class VFNotebookPlugin : AbstractPlugin() { override fun build(context: Context, meta: Meta): VFNotebookPlugin = VFNotebookPlugin() override val tag: PluginTag = PluginTag(name = "vision.notebook", group = PluginTag.DATAFORGE_GROUP) - - override val type: KClass = VFNotebookPlugin::class } } \ No newline at end of file diff --git a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt index eb61f889..50619e44 100644 --- a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt +++ b/jupyter/src/jvmMain/kotlin/VFForNotebook.kt @@ -4,7 +4,6 @@ import io.ktor.http.URLProtocol import io.ktor.server.application.install import io.ktor.server.cio.CIO import io.ktor.server.engine.ApplicationEngine -import io.ktor.server.engine.EngineConnectorConfig import io.ktor.server.engine.embeddedServer import io.ktor.server.util.url import io.ktor.server.websocket.WebSockets @@ -25,7 +24,6 @@ import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager import space.kscience.visionforge.html.HtmlVisionFragment import space.kscience.visionforge.html.visionFragment -import space.kscience.visionforge.server.EngineConnectorConfig import space.kscience.visionforge.server.VisionRoute import space.kscience.visionforge.server.serveVisionData import space.kscience.visionforge.visionManager @@ -74,7 +72,7 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout } } - val connector: EngineConnectorConfig = EngineConnectorConfig(host, port) + //val connector: EngineConnectorConfig = EngineConnectorConfig(host, port) engine?.stop(1000, 2000) engine = context.embeddedServer(CIO, port, host) { diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/jupyter/visionforge-jupyter-gdml/build.gradle.kts index 1198f022..5a67459e 100644 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ b/jupyter/visionforge-jupyter-gdml/build.gradle.kts @@ -4,56 +4,32 @@ plugins { description = "Jupyter api artifact for GDML rendering" -kotlin { - explicitApi = null - js { - useCommonJs() - browser { - webpackTask { - this.outputFileName = "js/gdml-jupyter.js" - } - commonWebpackConfig { - sourceMaps = false - cssSupport{ - enabled.set(false) - } +kscience { + fullStack("js/gdml-jupyter.js", + jsConfig = { useCommonJs() } + ) { + commonWebpackConfig { + sourceMaps = false + cssSupport { + enabled.set(false) } } - binaries.executable() } - afterEvaluate { - val jsBrowserDistribution by tasks.getting - - tasks.getByName("jvmProcessResources") { - dependsOn(jsBrowserDistribution) - from(jsBrowserDistribution) - } + dependencies{ + implementation(projects.visionforgeSolid) + implementation(projects.jupyter) } - sourceSets { - commonMain { - dependencies { - implementation(projects.visionforgeSolid) - implementation(projects.jupyter) - } - } - jvmMain { - dependencies { - implementation(projects.visionforgeGdml) - } - } - jsMain { - dependencies { - implementation(projects.visionforgeThreejs) - implementation(projects.ui.ring) - } - } - + dependencies(jvmMain){ + implementation(projects.visionforgeGdml) } -} -kscience { + dependencies(jsMain){ + implementation(projects.visionforgeThreejs) + implementation(projects.ui.ring) + } + jupyterLibrary("space.kscience.visionforge.gdml.jupyter.GdmlForJupyter") } diff --git a/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt index fef274a2..d4ee507e 100644 --- a/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt +++ b/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt @@ -6,7 +6,7 @@ import space.kscience.visionforge.runVisionClient @DFExperimental @JsExport -fun main(): Unit = runVisionClient { +public fun main(): Unit = runVisionClient { plugin(ThreeWithControlsPlugin) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 9bdf544a..b9d8bf5b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -34,7 +34,7 @@ dependencyResolutionManagement { } versionCatalogs { - create("npmlibs") { + create("spclibs") { from("space.kscience:version-catalog:$toolsVersion") } } @@ -48,7 +48,7 @@ include( ":ui:bootstrap", ":visionforge-core", ":visionforge-solid", - ":visionforge-fx", +// ":visionforge-fx", ":visionforge-threejs", ":visionforge-threejs:visionforge-threejs-server", ":visionforge-gdml", @@ -62,7 +62,7 @@ include( ":demo:muon-monitor", ":demo:sat-demo", ":demo:playground", - ":demo:plotly-fx", +// ":demo:plotly-fx", ":demo:js-playground", ":jupyter", ":jupyter:visionforge-jupyter-gdml" diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt index 4683f579..50c8a60a 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt @@ -5,7 +5,7 @@ import org.w3c.dom.Element import org.w3c.dom.HTMLElement import react.* import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.names.Name import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.specifications.Canvas3DOptions @@ -25,7 +25,7 @@ public val ThreeCanvasComponent: FC = fc("ThreeCanvasComponent val elementRef = useRef(null) var canvas by useState(null) - val three: ThreePlugin = useMemo(props.context) { props.context.fetch(ThreePlugin) } + val three: ThreePlugin = useMemo(props.context) { props.context.request(ThreePlugin) } useEffect(props.solid, props.options, elementRef) { if (canvas == null) { diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt index 60f36fb0..dd7f8e0d 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt @@ -14,7 +14,6 @@ import space.kscience.visionforge.Vision import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.three.ThreePlugin -import kotlin.reflect.KClass public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { public val three: ThreePlugin by require(ThreePlugin) @@ -44,7 +43,6 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.threejs.withControls", PluginTag.DATAFORGE_GROUP) - override val type: KClass = ThreeWithControlsPlugin::class override fun build(context: Context, meta: Meta): ThreeWithControlsPlugin = ThreeWithControlsPlugin() } diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index 6a170d02..505ff3be 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -4,29 +4,20 @@ plugins { val dataforgeVersion: String by rootProject.extra -kotlin { - sourceSets { - commonMain { - dependencies { - api("space.kscience:dataforge-context:$dataforgeVersion") - api("org.jetbrains.kotlinx:kotlinx-html:0.8.0") - api("org.jetbrains.kotlin-wrappers:kotlin-css") - } - } - commonTest{ - dependencies{ - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${space.kscience.gradle.KScienceVersions.coroutinesVersion}") - } - } - jsMain { - dependencies { - api("org.jetbrains.kotlin-wrappers:kotlin-extensions") - } - } - } -} - kscience{ + jvm() + js() + dependencies { + api("space.kscience:dataforge-context:$dataforgeVersion") + api(spclibs.kotlinx.html) + api("org.jetbrains.kotlin-wrappers:kotlin-css") + } + testDependencies { + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${space.kscience.gradle.KScienceVersions.coroutinesVersion}") + } + dependencies(jsMain){ + api("org.jetbrains.kotlin-wrappers:kotlin-extensions") + } useSerialization{ json() } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 4e64f63a..46266988 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -17,7 +17,6 @@ import space.kscience.visionforge.html.VisionOfCheckbox import space.kscience.visionforge.html.VisionOfHtmlForm import space.kscience.visionforge.html.VisionOfNumberField import space.kscience.visionforge.html.VisionOfTextField -import kotlin.reflect.KClass public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionContainer { override val tag: PluginTag get() = Companion.tag @@ -64,7 +63,6 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont public companion object : PluginFactory { override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP) - override val type: KClass = VisionManager::class public const val VISION_SERIALIZER_MODULE_TARGET: String = "visionSerializerModule" @@ -110,7 +108,7 @@ public abstract class VisionPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(met /** * Fetch a [VisionManager] from this plugin or create a child plugin with a [VisionManager] */ -public val Context.visionManager: VisionManager get() = fetch(VisionManager) +public val Context.visionManager: VisionManager get() = request(VisionManager ) public fun Vision.encodeToString(): String = manager?.encodeToString(this) ?: error("Orphan vision could not be encoded") diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 08497a57..7b7cdd31 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -1,12 +1,15 @@ package space.kscience.visionforge.meta -import kotlinx.coroutines.* +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.take import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.* import space.kscience.visionforge.* import kotlin.test.Test @@ -23,7 +26,7 @@ private class TestScheme : Scheme() { @OptIn(ExperimentalCoroutinesApi::class) internal class VisionPropertyTest { - private val manager = Global.fetch(VisionManager) + private val manager = Global.request(VisionManager) @Test fun testPropertyWrite() { @@ -56,7 +59,7 @@ internal class VisionPropertyTest { @Test fun testChildrenPropertyPropagation() = runTest(dispatchTimeoutMs = 200) { - val group = Global.fetch(VisionManager).group { + val group = Global.request(VisionManager).group { properties { "test" put 11 } @@ -91,7 +94,7 @@ internal class VisionPropertyTest { @Test fun testChildrenPropertyFlow() = runTest(dispatchTimeoutMs = 200) { - val group = Global.fetch(VisionManager).group { + val group = Global.request(VisionManager).group { properties { "test" put 11 diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index 6f322268..e87f01fa 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -21,7 +21,6 @@ import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_ENDPOI import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_FETCH_ATTRIBUTE import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_NAME_ATTRIBUTE import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_RENDERED -import kotlin.reflect.KClass import kotlin.time.Duration.Companion.milliseconds /** @@ -227,15 +226,13 @@ public class VisionClient : AbstractPlugin() { numberVisionRenderer(this), textVisionRenderer(this), formVisionRenderer(this) - ).toMap() + ).associateByName() } else super.content(target) public companion object : PluginFactory { override fun build(context: Context, meta: Meta): VisionClient = VisionClient() override val tag: PluginTag = PluginTag(name = "vision.client", group = PluginTag.DATAFORGE_GROUP) - - override val type: KClass = VisionClient::class } } @@ -296,7 +293,7 @@ public fun VisionClient.renderAllVisions(): Unit = whenDocumentLoaded { } public class VisionClientApplication(public val context: Context) : Application { - private val client = context.fetch(VisionClient) + private val client = context.request(VisionClient) override fun start(document: Document, state: Map) { context.logger.info { diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index 345445da..494e648e 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -2,21 +2,16 @@ plugins { id("space.kscience.gradle.mpp") } -kotlin { - js(IR){ +kscience { + jvm() + js { binaries.library() } - sourceSets { - commonMain{ - dependencies { - api(projects.visionforgeSolid) - api("space.kscience:gdml:0.4.0") - } - } - jvmTest{ - dependencies{ - implementation("ch.qos.logback:logback-classic:1.2.11") - } - } + dependencies { + api(projects.visionforgeSolid) + api("space.kscience:gdml:0.4.0") + } + dependencies(jvmTest) { + implementation("ch.qos.logback:logback-classic:1.2.11") } } \ No newline at end of file diff --git a/visionforge-markdown/build.gradle.kts b/visionforge-markdown/build.gradle.kts index 2909ab6d..502e2196 100644 --- a/visionforge-markdown/build.gradle.kts +++ b/visionforge-markdown/build.gradle.kts @@ -5,20 +5,13 @@ plugins { val markdownVersion = "0.2.4" kscience { - useSerialization() -} - -kotlin { + jvm() js { binaries.library() } - - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-core")) - api("org.jetbrains:markdown:$markdownVersion") - } - } + dependencies { + api(project(":visionforge-core")) + api("org.jetbrains:markdown:$markdownVersion") } + useSerialization() } \ No newline at end of file diff --git a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index ba960eae..08705c27 100644 --- a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -15,7 +15,6 @@ import space.kscience.dataforge.names.Name import space.kscience.visionforge.* import space.kscience.visionforge.markup.VisionOfMarkup.Companion.COMMONMARK_FORMAT import space.kscience.visionforge.markup.VisionOfMarkup.Companion.GFM_FORMAT -import kotlin.reflect.KClass public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { public val visionClient: VisionClient by require(VisionClient) @@ -47,7 +46,6 @@ public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP) - override val type: KClass = MarkupPlugin::class override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() diff --git a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index 211064ff..de71725c 100644 --- a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -6,7 +6,6 @@ import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta import space.kscience.visionforge.VisionPlugin -import kotlin.reflect.KClass public actual class MarkupPlugin : VisionPlugin() { override val visionSerializersModule: SerializersModule get() = markupSerializersModule @@ -16,8 +15,6 @@ public actual class MarkupPlugin : VisionPlugin() { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP) - override val type: KClass = MarkupPlugin::class - override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() } diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index 919dde07..56402f14 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -2,23 +2,16 @@ plugins { id("space.kscience.gradle.mpp") } -val plotlyVersion = "0.5.3-dev-1" +val plotlyVersion = "0.5.3" kscience { - useSerialization() -} - -kotlin { + jvm() js { binaries.library() } - - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-core")) - api("space.kscience:plotlykt-core:${plotlyVersion}") - } - } + dependencies { + api(project(":visionforge-core")) + api("space.kscience:plotlykt-core:${plotlyVersion}") } + useSerialization() } \ No newline at end of file diff --git a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt index 8344e52e..91518f34 100644 --- a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt +++ b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt @@ -14,7 +14,6 @@ import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionClient import space.kscience.visionforge.VisionPlugin -import kotlin.reflect.KClass public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { public val visionClient: VisionClient by require(VisionClient) @@ -31,7 +30,7 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { val plot = (vision as? VisionOfPlotly)?.plot ?: error("VisionOfPlotly expected but ${vision::class} found") val config = PlotlyConfig.read(meta) - element.plot(plot, config) + element.plot(config, plot) } override fun content(target: String): Map = when (target) { @@ -41,7 +40,6 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { public actual companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.plotly.js", PluginTag.DATAFORGE_GROUP) - override val type: KClass = PlotlyPlugin::class override fun build(context: Context, meta: Meta): PlotlyPlugin = PlotlyPlugin() diff --git a/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt b/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt index 8fda1d98..b9a8d373 100644 --- a/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt +++ b/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt @@ -6,7 +6,6 @@ import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta import space.kscience.visionforge.VisionPlugin -import kotlin.reflect.KClass public actual class PlotlyPlugin : VisionPlugin() { @@ -16,7 +15,6 @@ public actual class PlotlyPlugin : VisionPlugin() { public actual companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP) - override val type: KClass = PlotlyPlugin::class override fun build(context: Context, meta: Meta): PlotlyPlugin = PlotlyPlugin() diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index 236dda78..a4a7d848 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -2,12 +2,14 @@ plugins { id("space.kscience.gradle.jvm") } -val ktorVersion = npmlibs.versions.ktor.get() +kscience{ + useKtor() + dependencies { + api(projects.visionforgeCore) + api("io.ktor:ktor-server-cio") + api("io.ktor:ktor-server-html-builder") + api("io.ktor:ktor-server-websockets") + implementation("io.ktor:ktor-server-cors") + } +} -dependencies { - api(project(":visionforge-core")) - api("io.ktor:ktor-server-cio:${ktorVersion}") - api("io.ktor:ktor-server-html-builder:${ktorVersion}") - api("io.ktor:ktor-server-websockets:${ktorVersion}") - implementation("io.ktor:ktor-server-cors:${ktorVersion}") -} \ No newline at end of file diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index 7a0f145c..d135e045 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -1,35 +1,24 @@ -import space.kscience.gradle.KScienceVersions - plugins { id("space.kscience.gradle.mpp") } -kscience{ - useSerialization{ +kscience { + jvm() + js() + useSerialization { json() } -} - -kotlin { - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-core")) - } - } - commonTest{ - dependencies{ - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${KScienceVersions.coroutinesVersion}") - } - } - jvmTest{ - dependencies{ - implementation("ch.qos.logback:logback-classic:1.2.11") - } - } + dependencies { + api(projects.visionforgeCore) + } + testDependencies { + implementation(spclibs.kotlinx.coroutines.test) + } + dependencies(jvmTest) { + implementation(spclibs.logback.classic) } } -readme{ +readme { maturity = space.kscience.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index b87f0c93..f99e4bbf 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -169,14 +169,19 @@ internal fun float(name: Name, default: Number): ReadWriteProperty = +internal fun point( + name: Name, + defaultX: Float, + defaultY: Float = defaultX, + defaultZ: Float = defaultX, +): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Point3D? { val item = thisRef.properties.own?.get(name) ?: return null return object : Point3D { - override val x: Float get() = item[X_KEY]?.float ?: default - override val y: Float get() = item[Y_KEY]?.float ?: default - override val z: Float get() = item[Z_KEY]?.float ?: default + override val x: Float get() = item[X_KEY]?.float ?: defaultX + override val y: Float get() = item[Y_KEY]?.float ?: defaultY + override val z: Float get() = item[Z_KEY]?.float ?: defaultZ } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 919ac4cd..62e56d2b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -10,13 +10,12 @@ import kotlinx.serialization.serializer import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.* import space.kscience.visionforge.html.VisionOutput -import kotlin.reflect.KClass public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer { @@ -30,12 +29,11 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer, MutableVisionContainer { override val tag: PluginTag = PluginTag(name = "vision.solid", group = PluginTag.DATAFORGE_GROUP) - override val type: KClass = Solids::class public val default: Solids by lazy { Context("@Solids") { plugin(Solids) - }.fetch(Solids) + }.request(Solids) } override fun build(context: Context, meta: Meta): Solids = Solids(meta) diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt index ad9a06e9..1356c9b6 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.getChild import kotlin.test.Test @@ -19,7 +19,7 @@ class SolidPluginTest { @DFExperimental @Test fun testPluginConverter() { - val visionManager = Global.fetch(Solids).visionManager + val visionManager = Global.request(Solids).visionManager val meta = visionManager.encodeToMeta(vision) val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 65fdf373..6a38a194 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.names.asName @@ -12,18 +12,18 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue internal class VisionUpdateTest { - val solidManager = Global.fetch(Solids) + val solidManager = Global.request(Solids) val visionManager = solidManager.visionManager @Test - fun testVisionUpdate(){ + fun testVisionUpdate() { val targetVision = Solids.solidGroup { - box(200,200,200, name = "origin") + box(200, 200, 200, name = "origin") } - val dif = visionManager.VisionChange{ - solidGroup ("top") { + val dif = visionManager.VisionChange { + solidGroup("top") { color.set(123) - box(100,100,100) + box(100, 100, 100) } propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) @@ -31,15 +31,18 @@ internal class VisionUpdateTest { targetVision.update(dif) assertTrue { targetVision.children.getChild("top") is SolidGroup } assertEquals("red", (targetVision.children.getChild("origin") as Solid).color.string) // Should work - assertEquals("#00007b", (targetVision.children.getChild("top") as Solid).color.string) // new item always takes precedence + assertEquals( + "#00007b", + (targetVision.children.getChild("top") as Solid).color.string + ) // new item always takes precedence } @Test - fun testVisionChangeSerialization(){ - val change = visionManager.VisionChange{ + fun testVisionChangeSerialization() { + val change = visionManager.VisionChange { solidGroup("top") { color.set(123) - box(100,100,100) + box(100, 100, 100) } propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) @@ -47,6 +50,6 @@ internal class VisionUpdateTest { val serialized = visionManager.jsonFormat.encodeToString(VisionChange.serializer(), change) println(serialized) val reconstructed = visionManager.jsonFormat.decodeFromString(VisionChange.serializer(), serialized) - assertEquals(change.properties,reconstructed.properties) + assertEquals(change.properties, reconstructed.properties) } } \ No newline at end of file diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index abc56455..23d77912 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -2,13 +2,10 @@ plugins { id("space.kscience.gradle.mpp") } -val tablesVersion = "0.2.0-dev-3" +val tablesVersion = "0.2.0-dev-4" kscience { - useSerialization() -} - -kotlin { + jvm() js { useCommonJs() binaries.library() @@ -20,21 +17,15 @@ kotlin { } } } - - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-core")) - api("space.kscience:tables-kt:${tablesVersion}") - } - } - jsMain { - dependencies { - implementation(npm("tabulator-tables", "5.0.1")) - implementation(npm("@types/tabulator-tables", "5.0.1")) - } - } + dependencies { + api(projects.visionforgeCore) + api("space.kscience:tables-kt:${tablesVersion}") } + dependencies(jsMain){ + implementation(npm("tabulator-tables", "5.0.1")) + implementation(npm("@types/tabulator-tables", "5.0.1")) + } + useSerialization() } readme{ diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt index fd03b550..d6bc9b1d 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt @@ -9,7 +9,6 @@ import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionPlugin -import kotlin.reflect.KClass public class TableVisionPlugin : VisionPlugin() { override val tag: PluginTag get() = Companion.tag @@ -23,7 +22,6 @@ public class TableVisionPlugin : VisionPlugin() { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.table", PluginTag.DATAFORGE_GROUP) - override val type: KClass = TableVisionPlugin::class override fun build(context: Context, meta: Meta): TableVisionPlugin = TableVisionPlugin() } diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index 4764069f..d61e4664 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -16,7 +16,6 @@ import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionClient import tabulator.Tabulator import tabulator.TabulatorFull -import kotlin.reflect.KClass public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { public val visionClient: VisionClient by require(VisionClient) @@ -89,7 +88,6 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.table.js", PluginTag.DATAFORGE_GROUP) - override val type: KClass = TableVisionJsPlugin::class override fun build(context: Context, meta: Meta): TableVisionJsPlugin = TableVisionJsPlugin() } diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index 7cf2a60f..f04275f3 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -10,7 +10,7 @@ kotlin{ } dependencies { - api(project(":visionforge-solid")) + api(projects.visionforgeSolid) implementation(npm("three", "0.143.0")) implementation(npm("three-csg-ts", "3.1.10")) implementation(npm("three.meshline","1.4.0")) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 5aacba18..0a2d9f2a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -158,7 +158,6 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.threejs", PluginTag.DATAFORGE_GROUP) - override val type: KClass = ThreePlugin::class override fun build(context: Context, meta: Meta): ThreePlugin = ThreePlugin() } diff --git a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts index d3ef8496..059f3784 100644 --- a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts +++ b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts @@ -4,55 +4,26 @@ plugins { val ktorVersion: String by rootProject.extra -kotlin { - js(IR) { - browser { - webpackTask { - this.outputFileName = "js/visionforge-three.js" - } - commonWebpackConfig { - cssSupport{ - enabled.set(false) - } +kscience { + fullStack("js/visionforge-three.js") { + commonWebpackConfig { + cssSupport { + enabled.set(false) } } - binaries.executable() } - sourceSets { - commonMain { - dependencies { - api(projects.visionforgeSolid) - } - } - jvmMain { - dependencies { - api(projects.visionforgeServer) - } - } - jsMain { - dependencies { - api(projects.visionforgeThreejs) - api(projects.ui.ring) - } - } + dependencies { + api(projects.visionforgeSolid) } -} - -val jsBrowserDistribution by tasks.getting -val jsBrowserDevelopmentExecutableDistribution by tasks.getting - -val devMode = rootProject.findProperty("visionforge.development") as? Boolean - ?: rootProject.version.toString().contains("dev") + dependencies(jvmMain) { + api(projects.visionforgeServer) + } -tasks.getByName("jvmProcessResources") { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - if (devMode) { - dependsOn(jsBrowserDevelopmentExecutableDistribution) - from(jsBrowserDevelopmentExecutableDistribution) - } else { - dependsOn(jsBrowserDistribution) - from(jsBrowserDistribution) + dependencies(jsMain) { + api(projects.visionforgeThreejs) + api(projects.ui.ring) + compileOnly(npm("webpack-bundle-analyzer","4.5.0")) } -} +} \ No newline at end of file From c921d5541b8580bf051c19c4a662d000dec6e9f3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 16 May 2023 21:12:24 +0300 Subject: [PATCH 047/112] Cleanup and fix ROOT bug --- .gitignore | 1 - build.gradle.kts | 7 ++ .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 44 +++++----- .../kotlin/ru/mipt/npm/root/rootColor.kt | 2 +- .../ru/mipt/npm/muon/monitor/MMServer.kt | 4 +- .../src/jvmMain/kotlin/rootParser.kt | 83 ++++--------------- visionforge-core/build.gradle.kts | 3 +- .../kscience/visionforge/JvmSynchronized.kt | 5 ++ .../kscience/visionforge/VisionChange.kt | 5 +- .../kscience/visionforge/VisionContainer.kt | 3 +- .../kscience/visionforge/VisionProperties.kt | 3 +- .../kscience/visionforge/JvmSynchronized.kt | 3 + .../kscience/visionforge/html/htmlExport.kt | 4 +- visionforge-gdml/build.gradle.kts | 2 +- visionforge-markdown/build.gradle.kts | 2 +- visionforge-solid/build.gradle.kts | 1 + .../kscience/visionforge/solid/SolidGroup.kt | 7 +- .../kscience/visionforge/solid/Solids.kt | 15 +--- .../visionforge/solid/CompositeTest.kt | 2 +- .../kscience/visionforge/solid/ConvexTest.kt | 2 +- .../kscience/visionforge/solid/GroupTest.kt | 2 +- .../visionforge/solid/SerializationTest.kt | 4 +- .../visionforge/solid/SolidPluginTest.kt | 4 +- .../visionforge/solid/SolidPropertyTest.kt | 4 +- .../visionforge/solid/SolidReferenceTest.kt | 2 +- .../visionforge/solid/VisionUpdateTest.kt | 2 +- .../solid/three/ThreeSphereFactory.kt | 4 +- .../kscience/visionforge/solid/three/csg.kt | 3 +- 28 files changed, 93 insertions(+), 130 deletions(-) create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt create mode 100644 visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt diff --git a/.gitignore b/.gitignore index 44f45e0e..6d07da58 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,3 @@ data/ !gradle-wrapper.jar /kotlin-js-store/yarn.lock -. diff --git a/build.gradle.kts b/build.gradle.kts index 62623756..8cedd918 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,4 @@ +import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile import space.kscience.gradle.isInDevelopment import space.kscience.gradle.useApache2Licence import space.kscience.gradle.useSPCTeam @@ -30,6 +31,12 @@ subprojects { freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers" } } + + tasks.withType{ + kotlinOptions{ + useEsClasses = true + } + } } ksciencePublish { diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index af185db3..8015aea6 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -1,10 +1,8 @@ package ru.mipt.npm.root -import space.kscience.dataforge.meta.double -import space.kscience.dataforge.meta.doubleArray -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.isEmpty @@ -25,6 +23,8 @@ private data class RootToSolidContext( val prototypeHolder: PrototypeHolder, val currentLayer: Int = 0, val maxLayer: Int = 5, + val ignoreRootColors: Boolean = false, + val colorCache: MutableMap = mutableMapOf(), ) // converting to XYZ to Tait–Bryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix @@ -300,7 +300,7 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? layer = context.currentLayer val nodes = volume.fNodes - if (nodes.isEmpty() || context.currentLayer >= context.maxLayer) { + if (volume.typename != "TGeoVolumeAssembly" && (nodes.isEmpty() || context.currentLayer >= context.maxLayer)) { //TODO add smart filter volume.fShape?.let { shape -> addShape(shape, context) @@ -326,6 +326,16 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? group.items.values.first().apply { parent = null } } else { group + }.apply { + volume.fMedium?.let { medium -> + color.set(context.colorCache.getOrPut(medium.meta) { RootColors[11 + context.colorCache.size] }) + } + + if (!context.ignoreRootColors) { + volume.fFillColor?.let { + properties[MATERIAL_COLOR_KEY] = RootColors[it] + } + } } } @@ -338,6 +348,7 @@ private fun SolidGroup.addRootVolume( cache: Boolean = true, block: Solid.() -> Unit = {}, ) { + val combinedName = if (volume.fName.isEmpty()) { name } else if (name == null) { @@ -347,12 +358,7 @@ private fun SolidGroup.addRootVolume( } if (!cache) { - val group = buildVolume(volume, context)?.apply { - volume.fFillColor?.let { - properties[MATERIAL_COLOR_KEY] = RootColors[it] - } - block() - } + val group = buildVolume(volume, context)?.apply(block) setChild(combinedName?.let { Name.parse(it) }, group) } else { val templateName = volumesName + volume.name @@ -364,17 +370,17 @@ private fun SolidGroup.addRootVolume( } } - ref(templateName, name).apply { - volume.fFillColor?.let { - properties[MATERIAL_COLOR_KEY] = RootColors[it] - } - block() - } + ref(templateName, name).apply(block) } } -public fun MutableVisionContainer.rootGeo(dGeoManager: DGeoManager): SolidGroup = solidGroup { - val context = RootToSolidContext(this) +public fun MutableVisionContainer.rootGeo( + dGeoManager: DGeoManager, + name: String? = null, + maxLayer: Int = 5, + ignoreRootColors: Boolean = false, +): SolidGroup = solidGroup(name = name?.parseAsName()) { + val context = RootToSolidContext(this, maxLayer = maxLayer, ignoreRootColors = ignoreRootColors) dGeoManager.fNodes.forEach { node -> addRootNode(node, context) } diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/rootColor.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/rootColor.kt index 9ea9c040..9f06125e 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/rootColor.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/rootColor.kt @@ -1,7 +1,7 @@ package ru.mipt.npm.root public object RootColors { - private val colorMap = Array(924) { "white" } + private val colorMap = MutableList(924) { "white" } //colorMap[110] = "white" diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt index aa533431..b9b8ce4c 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt @@ -23,7 +23,7 @@ import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator import ru.mipt.npm.muon.monitor.sim.simulateOne import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.solid.Solids import java.awt.Desktop @@ -36,7 +36,7 @@ private val generator = Cos2TrackGenerator(JDKRandomGenerator(223)) fun Application.module(context: Context = Global) { val currentDir = File(".").absoluteFile environment.log.info("Current directory: $currentDir") - val solidManager = context.fetch(Solids) + val solidManager = context.request(Solids) install(ContentNegotiation) { json() diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/rootParser.kt index 1a4330f4..be70faf8 100644 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ b/demo/playground/src/jvmMain/kotlin/rootParser.kt @@ -7,9 +7,14 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.isLeaf import space.kscience.dataforge.meta.string +import space.kscience.visionforge.Colors +import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.Solids -import java.nio.file.Paths +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.solid import java.util.zip.ZipInputStream +import kotlin.io.path.Path import kotlin.io.path.writeText @@ -34,73 +39,17 @@ fun main() { println(it) } - val solid = Solids.rootGeo(geo) - - Paths.get("BM@N.vf.json").writeText(Solids.encodeToString(solid)) - //println(Solids.encodeToString(solid)) - - makeVisionFile { + makeVisionFile(path = Path("data/output.html"), resourceLocation = ResourceLocation.EMBED) { vision("canvas") { requirePlugin(Solids) - solid + solid { + ambientLight { + color.set(Colors.white) + } + rootGeo(geo,"BM@N", maxLayer = 3, ignoreRootColors = true).also { + Path("data/BM@N.vf.json").writeText(Solids.encodeToString(it)) + } + } } } -} - - -/* SolidGroup { - set( - "Coil", - solid.getPrototype("Coil".asName())!!.apply { - parent = null - } - ) - *//* group("Shade") { - y = 200 - color("red") - coneSurface( - bottomOuterRadius = 135, - bottomInnerRadius = 25, - height = 50, - topOuterRadius = 135, - topInnerRadius = 25, - angle = 1.5707964 - ) { - position = Point3D(79.6, 0, -122.1) - rotation = Point3D(-1.5707964, 0, 0) - } - coneSurface( - bottomOuterRadius = 135, - bottomInnerRadius = 25, - height = 50, - topOuterRadius = 135, - topInnerRadius = 25, - angle = 1.5707964 - ) { - position = Point3D(-79.6, 0, -122.1) - rotation = Point3D(1.5707964, 0, -3.1415927) - } - coneSurface( - bottomOuterRadius = 135, - bottomInnerRadius = 25, - height = 50, - topOuterRadius = 135, - topInnerRadius = 25, - angle = 1.5707964 - ) { - position = Point3D(79.6, 0, 122.1) - rotation = Point3D(1.5707964, 0, 0) - } - coneSurface( - bottomOuterRadius = 135, - bottomInnerRadius = 25, - height = 50, - topOuterRadius = 135, - topInnerRadius = 25, - angle = 1.5707964 - ) { - position = Point3D(-79.6, 0, 122.1) - rotation = Point3D(-1.5707964, 0, -3.1415927) - } - }*//* - }*/ +} \ No newline at end of file diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index 505ff3be..218a1710 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -7,10 +7,11 @@ val dataforgeVersion: String by rootProject.extra kscience{ jvm() js() + native() dependencies { api("space.kscience:dataforge-context:$dataforgeVersion") api(spclibs.kotlinx.html) - api("org.jetbrains.kotlin-wrappers:kotlin-css") +// api("org.jetbrains.kotlin-wrappers:kotlin-css") } testDependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${space.kscience.gradle.KScienceVersions.coroutinesVersion}") diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt new file mode 100644 index 00000000..a6f8c374 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt @@ -0,0 +1,5 @@ +package space.kscience.visionforge + +@OptIn(ExperimentalMultiplatform::class) +@OptionalExpectation +public expect annotation class JvmSynchronized() diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 358e72aa..15d59a0f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -13,7 +13,6 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.plus -import kotlin.jvm.Synchronized import kotlin.time.Duration /** @@ -59,11 +58,11 @@ public class VisionChangeBuilder : MutableVisionContainer { public fun isEmpty(): Boolean = propertyChange.isEmpty() && propertyChange.isEmpty() && children.isEmpty() - @Synchronized + @JvmSynchronized private fun getOrPutChild(visionName: Name): VisionChangeBuilder = children.getOrPut(visionName) { VisionChangeBuilder() } - @Synchronized + @JvmSynchronized internal fun reset() { vision = null propertyChange = MutableMeta() diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index 7ac01b74..77f989f4 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -6,7 +6,6 @@ import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import space.kscience.dataforge.names.* import space.kscience.visionforge.VisionChildren.Companion.STATIC_TOKEN_BODY -import kotlin.jvm.Synchronized @DslMarker public annotation class VisionBuilder @@ -132,7 +131,7 @@ internal abstract class VisionChildrenImpl( abstract var items: MutableMap? - @Synchronized + @JvmSynchronized private fun buildItems(): MutableMap { if (items == null) { items = LinkedHashMap() diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 52bdd52f..2fa88248 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -11,7 +11,6 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.names.* -import kotlin.jvm.Synchronized public interface VisionProperties { @@ -155,7 +154,7 @@ public abstract class AbstractVisionProperties( override val own: Meta? get() = properties - @Synchronized + @JvmSynchronized protected fun getOrCreateProperties(): MutableMeta { if (properties == null) { //TODO check performance issues diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt new file mode 100644 index 00000000..fc8fed09 --- /dev/null +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt @@ -0,0 +1,3 @@ +package space.kscience.visionforge + +public actual typealias JvmSynchronized = Synchronized \ No newline at end of file diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index ff0c3eee..f1efe1b4 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -67,9 +67,7 @@ public fun VisionPage.makeFile( path: Path?, fileHeaders: ((Path) -> Map)? = null, ): Path { - val actualFile = path?.let { - Path.of(System.getProperty("user.home")).resolve(path) - } ?: Files.createTempFile("tempPlot", ".html") + val actualFile = path ?: Files.createTempFile("tempPlot", ".html") val actualDefaultHeaders = fileHeaders?.invoke(actualFile) val actualHeaders = if (actualDefaultHeaders == null) pageHeaders else actualDefaultHeaders + pageHeaders diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index 494e648e..6dd3042a 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -12,6 +12,6 @@ kscience { api("space.kscience:gdml:0.4.0") } dependencies(jvmTest) { - implementation("ch.qos.logback:logback-classic:1.2.11") + implementation(spclibs.logback.classic) } } \ No newline at end of file diff --git a/visionforge-markdown/build.gradle.kts b/visionforge-markdown/build.gradle.kts index 502e2196..9790bf1a 100644 --- a/visionforge-markdown/build.gradle.kts +++ b/visionforge-markdown/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -val markdownVersion = "0.2.4" +val markdownVersion = "0.4.1" kscience { jvm() diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index d135e045..5eb92323 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -5,6 +5,7 @@ plugins { kscience { jvm() js() + native() useSerialization { json() } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index a089bf4d..f601a30e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -6,7 +6,10 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.parseAsName -import space.kscience.visionforge.* +import space.kscience.visionforge.AbstractVisionGroup +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.MutableVisionGroup +import space.kscience.visionforge.VisionBuilder /** @@ -53,7 +56,7 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable /** * Get a prototype redirecting the request to the parent if prototype is not found. - * If prototype is a ref, then it is unfolded automatically. + * If a prototype is a ref, then it is unfolded automatically. */ override fun getPrototype(name: Name): Solid? = prototypes?.get(name)?.prototype ?: (parent as? PrototypeHolder)?.getPrototype(name) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 62e56d2b..38d214bd 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -10,7 +10,6 @@ import kotlinx.serialization.serializer import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag -import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name @@ -27,15 +26,9 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer, MutableVisionContainer { + public companion object : PluginFactory { override val tag: PluginTag = PluginTag(name = "vision.solid", group = PluginTag.DATAFORGE_GROUP) - public val default: Solids by lazy { - Context("@Solids") { - plugin(Solids) - }.request(Solids) - } - override fun build(context: Context, meta: Meta): Solids = Solids(meta) private fun PolymorphicModuleBuilder.solids() { @@ -79,9 +72,9 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer(Sphere::class) { override fun buildGeometry(obj: Sphere): BufferGeometry { - return obj.detail?.let {detail -> + return obj.detail?.let { detail -> SphereGeometry( radius = obj.radius, phiStart = obj.phiStart, @@ -17,7 +17,7 @@ public object ThreeSphereFactory : ThreeMeshFactory(Sphere::class) { widthSegments = detail, heightSegments = detail ) - }?: SphereGeometry( + } ?: SphereGeometry( radius = obj.radius, phiStart = obj.phiStart, phiLength = obj.phi, diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt index 940d72c3..0d7f774d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt @@ -3,8 +3,7 @@ "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "EXTERNAL_DELEGATION", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING" + "EXTERNAL_DELEGATION" ) @file:JsModule("three-csg-ts") From c48e5aac25382c33061dc370292609898d532aff Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 29 May 2023 09:53:56 +0300 Subject: [PATCH 048/112] build update and minor API changes --- build.gradle.kts | 3 ++- demo/playground/build.gradle.kts | 2 +- gradle.properties | 3 ++- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 2 +- .../kscience/visionforge/VisionChange.kt | 17 +++++++++++++- .../visionforge/meta/VisionPropertyTest.kt | 3 ++- .../kscience/visionforge/VisionClient.kt | 22 ++++++++++++++----- .../kscience/visionforge/html/htmlExport.kt | 2 +- visionforge-plotly/build.gradle.kts | 2 +- .../visionforge/solid/SolidPropertyTest.kt | 3 ++- 11 files changed, 45 insertions(+), 16 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8cedd918..3ee913b2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-7" + version = "0.3.0-dev-8" } subprojects { @@ -24,6 +24,7 @@ subprojects { maven("https://repo.kotlin.link") mavenCentral() maven("https://maven.jzy3d.org/releases") + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") } tasks.withType { diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index fbc0b736..a2696fa6 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -65,7 +65,7 @@ kotlin { val jvmMain by getting { dependencies { implementation(projects.visionforgeServer) - implementation("ch.qos.logback:logback-classic:1.2.3") + implementation(spclibs.logback.classic) implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6") } } diff --git a/gradle.properties b/gradle.properties index 11c3aafa..75046b66 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,5 @@ kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.14.7-kotlin-1.8.20 \ No newline at end of file +toolsVersion=0.14.8-kotlin-1.8.20 +org.jetbrains.compose.experimental.jscanvas.enabled=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 070cb702..fae08049 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index b9d8bf5b..e9e3deba 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,6 @@ rootProject.name = "visionforge" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -enableFeaturePreview("VERSION_CATALOGS") pluginManagement { @@ -46,6 +45,7 @@ include( ":ui:ring", // ":ui:material", ":ui:bootstrap", +// ":ui:compose", ":visionforge-core", ":visionforge-solid", // ":visionforge-fx", diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 15d59a0f..847368f3 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -41,7 +41,6 @@ public object NullVision : Vision { override val properties: MutableVisionProperties get() = error("Can't get properties of `NullVision`") override val descriptor: MetaDescriptor? = null - } @@ -89,6 +88,12 @@ public class VisionChangeBuilder : MutableVisionContainer { } } + private fun build(visionManager: VisionManager): VisionChange = VisionChange( + vision, + if (propertyChange.isEmpty()) null else propertyChange, + if (children.isEmpty()) null else children.mapValues { it.value.build(visionManager) } + ) + /** * Isolate collected changes by creating detached copies of given visions */ @@ -97,6 +102,13 @@ public class VisionChangeBuilder : MutableVisionContainer { if (propertyChange.isEmpty()) null else propertyChange.seal(), if (children.isEmpty()) null else children.mapValues { it.value.deepCopy(visionManager) } ) + + /** + * Transform current change directly to Json string without protective copy + */ + public fun toJsonString(visionManager: VisionManager): String = visionManager.encodeToString( + build(visionManager) + ) } /** @@ -115,6 +127,9 @@ public inline fun VisionManager.VisionChange(block: VisionChangeBuilder.() -> Un VisionChangeBuilder().apply(block).deepCopy(this) +/** + * Collect changes that are made to [source] to [collector] using [mutex] as a synchronization lock. + */ private fun CoroutineScope.collectChange( name: Name, source: Vision, diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 7b7cdd31..6e113f7f 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -15,6 +15,7 @@ import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals +import kotlin.time.Duration.Companion.milliseconds private class TestScheme : Scheme() { @@ -58,7 +59,7 @@ internal class VisionPropertyTest { } @Test - fun testChildrenPropertyPropagation() = runTest(dispatchTimeoutMs = 200) { + fun testChildrenPropertyPropagation() = runTest(timeout = 200.milliseconds) { val group = Global.request(VisionManager).group { properties { "test" put 11 diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index e87f01fa..af3cd574 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -6,6 +6,8 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import org.w3c.dom.* import org.w3c.dom.url.URL import space.kscience.dataforge.context.* @@ -30,8 +32,6 @@ public class VisionClient : AbstractPlugin() { override val tag: PluginTag get() = Companion.tag private val visionManager: VisionManager by require(VisionManager) - //private val visionMap = HashMap() - /** * Up-going tree traversal in search for endpoint attribute. If element is null, return window URL */ @@ -61,11 +61,19 @@ public class VisionClient : AbstractPlugin() { private fun Element.getFlag(attribute: String): Boolean = attributes[attribute]?.value != null + private val mutex = Mutex() private val changeCollector = VisionChangeBuilder() + /** + * Communicate vision property changed from rendering engine to model + */ public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { - changeCollector.propertyChanged(visionName, propertyName, item) + context.launch { + mutex.withLock { + changeCollector.propertyChanged(visionName, propertyName, item) + } + } } // public fun visionChanged(name: Name?, child: Vision?) { @@ -131,8 +139,10 @@ public class VisionClient : AbstractPlugin() { delay(feedbackAggregationTime.milliseconds) val change = changeCollector[name] ?: continue if (!change.isEmpty()) { - send(visionManager.encodeToString(change.deepCopy(visionManager))) - change.reset() + mutex.withLock { + send(change.toJsonString(visionManager)) + change.reset() + } } } } @@ -232,7 +242,7 @@ public class VisionClient : AbstractPlugin() { public companion object : PluginFactory { override fun build(context: Context, meta: Meta): VisionClient = VisionClient() - override val tag: PluginTag = PluginTag(name = "vision.client", group = PluginTag.DATAFORGE_GROUP) + override val tag: PluginTag = PluginTag(name = "vision.client.js", group = PluginTag.DATAFORGE_GROUP) } } diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index f1efe1b4..ec31b7b4 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -60,7 +60,7 @@ import java.nio.file.Path /** * Export a [VisionPage] to a file * - * @param fileHeaders additional file-system specific headers. + * @param fileHeaders additional file system specific headers. */ @DFExperimental public fun VisionPage.makeFile( diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index 56402f14..8b0a99d1 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -10,7 +10,7 @@ kscience { binaries.library() } dependencies { - api(project(":visionforge-core")) + api(projects.visionforgeCore) api("space.kscience:plotlykt-core:${plotlyVersion}") } useSerialization() diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index 7589ee00..5fa22b86 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -10,6 +10,7 @@ import space.kscience.dataforge.names.asName import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.milliseconds @OptIn(ExperimentalCoroutinesApi::class) @Suppress("UNUSED_VARIABLE") @@ -26,7 +27,7 @@ class SolidPropertyTest { } @Test - fun testColorUpdate() = runTest(dispatchTimeoutMs = 200) { + fun testColorUpdate() = runTest(timeout = 200.milliseconds) { val box = Box(10.0f, 10.0f, 10.0f) val c = CompletableDeferred() From 33778801b66d3e76ca2912e150d6c7ace27046b2 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 29 May 2023 21:38:30 +0300 Subject: [PATCH 049/112] Multiple fixes --- .../mipt/npm/root/serialization/jsonToRoot.kt | 8 +-- demo/gdml/build.gradle.kts | 2 +- demo/js-playground/build.gradle.kts | 2 +- demo/muon-monitor/build.gradle.kts | 1 - demo/playground/build.gradle.kts | 8 ++- demo/playground/notebooks/dynamic-demo.ipynb | 57 ++++++++++++++++--- demo/playground/src/jvmMain/kotlin/shapes.kt | 39 +++++++++++++ demo/sat-demo/build.gradle.kts | 1 - .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 7 +-- demo/solid-showcase/build.gradle.kts | 6 +- .../visionforge/solid/demo/VisionLayout.kt | 4 +- gradle.properties | 2 +- .../kscience/visionforge/compose/ThreeJS.kt | 11 ++++ visionforge-core/build.gradle.kts | 12 ++-- .../kscience/visionforge/VisionManager.kt | 2 +- .../visionforge/meta/VisionPropertyTest.kt | 2 +- visionforge-markdown/build.gradle.kts | 3 +- .../visionforge/markup/MarkupPlugin.kt | 5 +- .../visionforge/markup/VisionOfMarkup.kt | 14 +++++ .../visionforge/markup/MarkupPlugin.kt | 2 +- .../visionforge/markup/MarkupPlugin.kt | 7 ++- .../visionforge/plotly/VisionOfPlotly.kt | 6 +- visionforge-solid/build.gradle.kts | 4 +- .../kscience/visionforge/solid/ConeSegment.kt | 56 +++++++++++------- .../kscience/visionforge/solid/ConeSurface.kt | 8 +-- .../kscience/visionforge/solid/Solids.kt | 3 +- .../solid/three/ThreeConeFactory.kt | 8 +-- .../visionforge/solid/three/ThreePlugin.kt | 2 +- 28 files changed, 205 insertions(+), 77 deletions(-) create mode 100644 demo/playground/src/jvmMain/kotlin/shapes.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeJS.kt diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt index 1685c1ac..c443f646 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt @@ -118,7 +118,7 @@ private object RootDecoder { subclass(TGeoCompositeShape.serializer().unref(refCache)) subclass(TGeoShapeAssembly.serializer().unref(refCache)) - default { + defaultDeserializer { if (it == null) { TGeoShape.serializer().unref(refCache) } else { @@ -136,7 +136,7 @@ private object RootDecoder { val unrefed = TGeoMatrix.serializer().unref(refCache) - default { + defaultDeserializer { if (it == null) { unrefed } else { @@ -149,7 +149,7 @@ private object RootDecoder { subclass(TGeoVolumeAssembly.serializer().unref(refCache)) val unrefed = TGeoVolume.serializer().unref(refCache) - default { + defaultDeserializer { if (it == null) { unrefed } else { @@ -163,7 +163,7 @@ private object RootDecoder { subclass(TGeoNodeOffset.serializer().unref(refCache)) val unrefed = TGeoNode.serializer().unref(refCache) - default { + defaultDeserializer { if (it == null) { unrefed } else { diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index 3ac3960a..c1e3be28 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -7,6 +7,7 @@ kscience { js { useCommonJs() browser { + binaries.executable() commonWebpackConfig { cssSupport { enabled.set(false) @@ -27,7 +28,6 @@ kscience { implementation(projects.visionforgeThreejs) implementation(npm("react-file-drop", "3.0.6")) } - application() } //kotlin { diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index 3368c5ef..86935c51 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -4,13 +4,13 @@ plugins { kscience{ useCoroutines() - application() } kotlin{ js(IR){ useCommonJs() browser { + binaries.executable() commonWebpackConfig { cssSupport{ enabled.set(false) diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index 3d814223..2ea4d0eb 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -38,7 +38,6 @@ kscience { implementation(project(":visionforge-threejs")) //implementation(devNpm("webpack-bundle-analyzer", "4.4.0")) } - application() } application { diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index a2696fa6..ddc1d6a8 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -2,6 +2,7 @@ plugins { kotlin("multiplatform") kotlin("jupyter.api") id("com.github.johnrengelman.shadow") version "7.1.2" +// application } repositories { @@ -29,6 +30,7 @@ kotlin { } jvm { +// withJava() compilations.all { kotlinOptions { jvmTarget = "11" @@ -88,4 +90,8 @@ val processJupyterApiResources by tasks.getting(org.jetbrains.kotlinx.jupyter.ap libraryProducers = listOf("space.kscience.visionforge.examples.VisionForgePlayGroundForJupyter") } -tasks.findByName("shadowJar")?.dependsOn(processJupyterApiResources) \ No newline at end of file +tasks.findByName("shadowJar")?.dependsOn(processJupyterApiResources) + +//application{ +// mainClass.set("space.kscience.visionforge.examples.ShapesKt") +//} \ No newline at end of file diff --git a/demo/playground/notebooks/dynamic-demo.ipynb b/demo/playground/notebooks/dynamic-demo.ipynb index 7200d15b..41289185 100644 --- a/demo/playground/notebooks/dynamic-demo.ipynb +++ b/demo/playground/notebooks/dynamic-demo.ipynb @@ -2,37 +2,73 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "tags": [], "pycharm": { "is_executing": true + }, + "ExecuteTime": { + "end_time": "2023-05-29T15:22:37.933397300Z", + "start_time": "2023-05-29T15:22:37.913872100Z" } }, "outputs": [], - "source": [ - "@file:DependsOn(\"../build/libs/playground-0.3.0-dev-4-all.jar\")" - ] + "source": [] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2023-05-29T15:22:50.486483300Z", + "start_time": "2023-05-29T15:22:50.457485500Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Line_2.jupyter.kts (1:1 - 3) Unresolved reference: vf" + ] + } + ], "source": [ "vf.startServer()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false + }, + "ExecuteTime": { + "end_time": "2023-05-29T15:22:51.410680600Z", + "start_time": "2023-05-29T15:22:51.250779400Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Line_3.jupyter.kts (1:16 - 26) Unresolved reference: coroutines\n", + "Line_3.jupyter.kts (4:1 - 7) Unresolved reference: Plotly\n", + "Line_3.jupyter.kts (5:5 - 12) Unresolved reference: scatter\n", + "Line_3.jupyter.kts (6:9 - 10) Unresolved reference: x\n", + "Line_3.jupyter.kts (7:9 - 10) Unresolved reference: y\n", + "Line_3.jupyter.kts (8:12 - 14) Unresolved reference: vf\n", + "Line_3.jupyter.kts (9:13 - 15) Unresolved reference: vf\n", + "Line_3.jupyter.kts (10:23 - 31) Unresolved reference: isActive\n", + "Line_3.jupyter.kts (11:21 - 26) Unresolved reference: delay\n", + "Line_3.jupyter.kts (12:21 - 22) Unresolved reference: y" + ] + } + ], "source": [ "import kotlinx.coroutines.*\n", "import kotlin.random.Random\n", @@ -84,6 +120,9 @@ "nbconvert_exporter": "", "pygments_lexer": "kotlin", "version": "1.8.0-dev-3517" + }, + "ktnbPluginMetadata": { + "isAddProjectLibrariesToClasspath": false } }, "nbformat": 4, diff --git a/demo/playground/src/jvmMain/kotlin/shapes.kt b/demo/playground/src/jvmMain/kotlin/shapes.kt new file mode 100644 index 00000000..bcd4f73a --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/shapes.kt @@ -0,0 +1,39 @@ +package space.kscience.visionforge.examples + +import kotlin.math.PI +import space.kscience.visionforge.Colors +import space.kscience.visionforge.solid.* + +fun main() = makeVisionFile{ + vision("canvas") { + solid { + ambientLight() + box(100.0, 100.0, 100.0) { + z = -110.0 + color.set("teal") + } + sphere(50.0) { + x = 110 + detail = 16 + color.set("red") + } + tube(50, height = 10, innerRadius = 25, angle = PI) { + y = 110 + detail = 16 + rotationX = PI / 4 + color.set("blue") + } + sphereLayer(50, 40, theta = PI / 2) { + rotationX = -PI * 3 / 4 + z = 110 + color.set(Colors.pink) + } + + + tube(30,20, 20){ + detail = 31 + y = - 220 + } + } + } +} \ No newline at end of file diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 1b37bfad..6afadf27 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -8,7 +8,6 @@ kscience { // useSerialization { // json() // } - application() dependencies{ implementation(projects.visionforgeThreejs.visionforgeThreejsServer) implementation("ch.qos.logback:logback-classic:1.4.5") diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index d2c33c2c..4f0ff70c 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -3,8 +3,7 @@ package ru.mipt.npm.sat import io.ktor.server.cio.CIO import io.ktor.server.engine.embeddedServer -import io.ktor.server.http.content.resources -import io.ktor.server.http.content.static +import io.ktor.server.http.content.staticResources import io.ktor.server.routing.routing import kotlinx.coroutines.* import kotlinx.html.div @@ -41,9 +40,7 @@ fun main() { val server = embeddedServer(CIO, connector.port, connector.host) { routing { - static { - resources() - } + staticResources("", null, null) } visionPage( diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index 0a53b4e2..d588e035 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -1,11 +1,11 @@ plugins { id("space.kscience.gradle.mpp") + `maven-publish` application } kscience { useCoroutines() - application() jvm { withJava() } @@ -22,4 +22,8 @@ kscience { application { mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt") +} + +kotlin{ + explicitApi = null } \ No newline at end of file diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt index 9b8c6b98..4b5bdf53 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt @@ -5,8 +5,8 @@ import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.solid.Solids -public interface VisionLayout { +interface VisionLayout { val solids: Solids - public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY) + fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY) } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 75046b66..e3a218ba 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,5 +6,5 @@ kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.14.8-kotlin-1.8.20 +toolsVersion=0.14.9-kotlin-1.8.20 org.jetbrains.compose.experimental.jscanvas.enabled=true \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeJS.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeJS.kt new file mode 100644 index 00000000..6033c712 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeJS.kt @@ -0,0 +1,11 @@ +package space.kscience.visionforge.compose + +import androidx.compose.material.Surface +import androidx.compose.runtime.Composable + +@Composable +public fun ThreeJs(){ + Surface { + + } +} \ No newline at end of file diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index 218a1710..f2cac4c6 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -4,26 +4,24 @@ plugins { val dataforgeVersion: String by rootProject.extra -kscience{ +kscience { jvm() js() native() + useCoroutines() dependencies { api("space.kscience:dataforge-context:$dataforgeVersion") api(spclibs.kotlinx.html) // api("org.jetbrains.kotlin-wrappers:kotlin-css") } - testDependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${space.kscience.gradle.KScienceVersions.coroutinesVersion}") - } - dependencies(jsMain){ + jsMain { api("org.jetbrains.kotlin-wrappers:kotlin-extensions") } - useSerialization{ + useSerialization { json() } } -readme{ +readme { maturity = space.kscience.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 46266988..2be8a6b3 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -70,7 +70,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont private val defaultSerialModule: SerializersModule = SerializersModule { polymorphic(Vision::class) { - default { SimpleVisionGroup.serializer() } + defaultDeserializer { SimpleVisionGroup.serializer() } subclass(NullVision.serializer()) subclass(SimpleVisionGroup.serializer()) subclass(VisionOfNumberField.serializer()) diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 6e113f7f..e9a0685e 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -94,7 +94,7 @@ internal class VisionPropertyTest { } @Test - fun testChildrenPropertyFlow() = runTest(dispatchTimeoutMs = 200) { + fun testChildrenPropertyFlow() = runTest(timeout = 200.milliseconds) { val group = Global.request(VisionManager).group { properties { diff --git a/visionforge-markdown/build.gradle.kts b/visionforge-markdown/build.gradle.kts index 9790bf1a..36559a09 100644 --- a/visionforge-markdown/build.gradle.kts +++ b/visionforge-markdown/build.gradle.kts @@ -10,8 +10,9 @@ kscience { binaries.library() } dependencies { - api(project(":visionforge-core")) + api(projects.visionforgeCore) api("org.jetbrains:markdown:$markdownVersion") + api("org.jetbrains:annotations:24.0.0") } useSerialization() } \ No newline at end of file diff --git a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index 7ff98f91..3508ba8b 100644 --- a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -1,5 +1,8 @@ package space.kscience.visionforge.markup +import space.kscience.dataforge.context.PluginFactory import space.kscience.visionforge.VisionPlugin -public expect class MarkupPlugin: VisionPlugin \ No newline at end of file +public expect class MarkupPlugin: VisionPlugin{ + public companion object : PluginFactory +} \ No newline at end of file diff --git a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt index ace39d2b..f3e255df 100644 --- a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt +++ b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt @@ -10,6 +10,8 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.html.VisionOutput import space.kscience.visionforge.root @Serializable @@ -38,4 +40,16 @@ internal val markupSerializersModule = SerializersModule { polymorphic(Vision::class) { subclass(VisionOfMarkup.serializer()) } +} + +/** + * Embed a dynamic markdown block in a vision + */ +@VisionBuilder +public inline fun VisionOutput.markdown( + format: String = VisionOfMarkup.COMMONMARK_FORMAT, + block: VisionOfMarkup.() -> Unit, +): VisionOfMarkup { + requirePlugin(MarkupPlugin) + return VisionOfMarkup(format).apply(block) } \ No newline at end of file diff --git a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index 08705c27..e79908f0 100644 --- a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -44,7 +44,7 @@ public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { element.append(div) } - public companion object : PluginFactory { + public actual companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP) override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() diff --git a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index de71725c..16cb6b24 100644 --- a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -1,6 +1,7 @@ package space.kscience.visionforge.markup import kotlinx.serialization.modules.SerializersModule +import org.intellij.lang.annotations.Language import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag @@ -12,10 +13,14 @@ public actual class MarkupPlugin : VisionPlugin() { override val tag: PluginTag get() = Companion.tag - public companion object : PluginFactory { + public actual companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP) override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() } +} + +public fun VisionOfMarkup.content(@Language("markdown") text: String) { + content = text } \ No newline at end of file diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index 54ba4551..10baa4ab 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -16,6 +16,7 @@ import space.kscience.plotly.Plot import space.kscience.plotly.Plotly import space.kscience.visionforge.MutableVisionProperties import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionBuilder import space.kscience.visionforge.html.VisionOutput @Serializable @@ -82,7 +83,10 @@ public class VisionOfPlotly private constructor( public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this) -@DFExperimental +/** + * Embed a dynamic plotly plot in a vision + */ +@VisionBuilder public inline fun VisionOutput.plotly( block: Plot.() -> Unit, ): VisionOfPlotly { diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index 5eb92323..a1d4fbc4 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -9,12 +9,10 @@ kscience { useSerialization { json() } + useCoroutines() dependencies { api(projects.visionforgeCore) } - testDependencies { - implementation(spclibs.kotlinx.coroutines.test) - } dependencies(jvmTest) { implementation(spclibs.logback.classic) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt index 873ae44e..6e2677af 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt @@ -18,42 +18,54 @@ public class ConeSegment( public val bottomRadius: Float, public val height: Float, public val topRadius: Float, - public val startAngle: Float = 0f, - public val angle: Float = PI2 + public val phiStart: Float = 0f, + public val phi: Float = PI2, ) : SolidBase(), GeometrySolid { + init { + require(bottomRadius > 0) { "Bottom radius must be positive" } + require(topRadius > 0) { "Top radius must be positive" } + } + override fun toGeometry(geometryBuilder: GeometryBuilder) { - val segments = detail ?: 32 + + val segments: Int = detail ?: 32 require(segments >= 4) { "The number of segments in cone segment is too small" } - val angleStep = angle / (segments - 1) - fun shape(r: Float, z: Float): List { - return (0 until segments).map { i -> - Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) - } + val angleStep = phi / (segments - 1) + + /** + * Top and bottom shape + */ + fun shape(r: Float, z: Float): List = (0 until segments).map { i -> + Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } - geometryBuilder.apply { + with(geometryBuilder) { + + // top and bottom faces + val bottomOuterPoints: List = shape(topRadius, -height / 2) + val upperOuterPoints: List = shape(bottomRadius, height / 2) - //creating shape in x-y plane with z = 0 - val bottomOuterPoints = shape(topRadius, -height / 2) - val upperOuterPoints = shape(bottomRadius, height / 2) //outer face - (1 until segments).forEach { + for (it in 1 until segments) { face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1]) } - if (angle == PI2) { + //if the cone is closed + if (phi == PI2) { face4(bottomOuterPoints.last(), bottomOuterPoints[0], upperOuterPoints[0], upperOuterPoints.last()) } - val zeroBottom = Point3D(0f, 0f, 0f) - val zeroTop = Point3D(0f, 0f, height) - (1 until segments).forEach { + //top and bottom cups + val zeroBottom = Point3D(0f, 0f, -height / 2) + val zeroTop = Point3D(0f, 0f, height / 2) + for (it in 1 until segments) { face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop) } - if (angle == PI2) { + // closed surface + if (phi == PI2) { face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop) } else { @@ -71,7 +83,7 @@ public inline fun MutableVisionContainer.cylinder( r: Number, height: Number, name: String? = null, - block: ConeSegment.() -> Unit = {} + block: ConeSegment.() -> Unit = {}, ): ConeSegment = ConeSegment( r.toFloat(), height.toFloat(), @@ -86,11 +98,11 @@ public inline fun MutableVisionContainer.cone( startAngle: Number = 0f, angle: Number = PI2, name: String? = null, - block: ConeSegment.() -> Unit = {} + block: ConeSegment.() -> Unit = {}, ): ConeSegment = ConeSegment( bottomRadius.toFloat(), height.toFloat(), topRadius = upperRadius.toFloat(), - startAngle = startAngle.toFloat(), - angle = angle.toFloat() + phiStart = startAngle.toFloat(), + phi = angle.toFloat() ).apply(block).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt index 0bc023e6..2a6bcdc5 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt @@ -38,10 +38,8 @@ public class ConeSurface( require(segments >= 4) { "The number of segments in tube is too small" } val angleStep = angle / (segments - 1) - fun shape(r: Float, z: Float): List { - return (0 until segments).map { i -> - Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) - } + fun shape(r: Float, z: Float): List = (0 until segments).map { i -> + Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) } geometryBuilder.apply { @@ -50,7 +48,7 @@ public class ConeSurface( val bottomOuterPoints = shape(bottomRadius, -height / 2) val topOuterPoints = shape(topRadius, height / 2) //outer face - (1 until segments).forEach { + for (it in 1 until segments) { face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1]) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 38d214bd..1fecd450 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -44,6 +44,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer()) } + defaultDeserializer { SolidBase.serializer(serializer()) } solids() } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt index acb81e1f..6b2db845 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt @@ -18,16 +18,16 @@ public object ThreeConeFactory : ThreeMeshFactory(ConeSegment::clas radialSegments = segments, heightSegments = segments, openEnded = false, - thetaStart = obj.startAngle, - thetaLength = obj.angle + thetaStart = obj.phiStart, + thetaLength = obj.phi ) } ?: CylinderGeometry( radiusTop = obj.topRadius, radiusBottom = obj.bottomRadius, height = obj.height, openEnded = false, - thetaStart = obj.startAngle, - thetaLength = obj.angle + thetaStart = obj.phiStart, + thetaLength = obj.phi ) return cylinder.rotateX(PI/2) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 0a2d9f2a..1913e332 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -111,7 +111,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { is Composite -> compositeFactory.build(this, vision, observe) else -> { - //find specialized factory for this type if it is present + //find a specialized factory for this type if it is present val factory: ThreeFactory? = findObjectFactory(vision::class) when { factory != null -> factory.build(this, vision, observe) From f6f74b54f60ecfd5b772b6cd82100fe136a4ba52 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 30 May 2023 13:56:14 +0300 Subject: [PATCH 050/112] Fix cone segmenta and cone surface representation --- demo/playground/src/jvmMain/kotlin/shapes.kt | 8 +-- .../kscience/visionforge/solid/ConeSegment.kt | 49 ++++++++----------- .../kscience/visionforge/solid/ConeSurface.kt | 28 +++++------ .../visionforge/solid/three/ThreePlugin.kt | 2 +- 4 files changed, 40 insertions(+), 47 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/shapes.kt b/demo/playground/src/jvmMain/kotlin/shapes.kt index bcd4f73a..1c702c5e 100644 --- a/demo/playground/src/jvmMain/kotlin/shapes.kt +++ b/demo/playground/src/jvmMain/kotlin/shapes.kt @@ -1,10 +1,10 @@ package space.kscience.visionforge.examples -import kotlin.math.PI import space.kscience.visionforge.Colors import space.kscience.visionforge.solid.* +import kotlin.math.PI -fun main() = makeVisionFile{ +fun main() = makeVisionFile { vision("canvas") { solid { ambientLight() @@ -30,9 +30,9 @@ fun main() = makeVisionFile{ } - tube(30,20, 20){ + cylinder(30,20, name = "cylinder"){ detail = 31 - y = - 220 + y = -220 } } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt index 6e2677af..94ea5eaf 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt @@ -22,60 +22,53 @@ public class ConeSegment( public val phi: Float = PI2, ) : SolidBase(), GeometrySolid { + init { - require(bottomRadius > 0) { "Bottom radius must be positive" } - require(topRadius > 0) { "Top radius must be positive" } + require(bottomRadius > 0) { "Cone segment bottom radius must be positive" } + require(height > 0) { "Cone segment height must be positive" } + require(topRadius >= 0) { "Cone segment top radius must be non-negative" } + //require(startAngle >= 0) + require(phi in (0f..(PI2))) } override fun toGeometry(geometryBuilder: GeometryBuilder) { - - val segments: Int = detail ?: 32 - require(segments >= 4) { "The number of segments in cone segment is too small" } - + val segments = detail ?: 32 + require(segments >= 4) { "The number of segments in cone is too small" } val angleStep = phi / (segments - 1) - /** - * Top and bottom shape - */ fun shape(r: Float, z: Float): List = (0 until segments).map { i -> Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } - with(geometryBuilder) { - - // top and bottom faces - val bottomOuterPoints: List = shape(topRadius, -height / 2) - val upperOuterPoints: List = shape(bottomRadius, height / 2) + geometryBuilder.apply { + //creating shape in x-y plane with z = 0 + val bottomPoints = shape(bottomRadius, -height / 2) + val topPoints = shape(topRadius, height / 2) //outer face for (it in 1 until segments) { - face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1]) + face4(bottomPoints[it - 1], bottomPoints[it], topPoints[it], topPoints[it - 1]) } - //if the cone is closed if (phi == PI2) { - face4(bottomOuterPoints.last(), bottomOuterPoints[0], upperOuterPoints[0], upperOuterPoints.last()) + face4(bottomPoints.last(), bottomPoints[0], topPoints[0], topPoints.last()) } - - //top and bottom cups val zeroBottom = Point3D(0f, 0f, -height / 2) - val zeroTop = Point3D(0f, 0f, height / 2) + val zeroTop = Point3D(0f, 0f, +height / 2) for (it in 1 until segments) { - face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) - face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop) + face(bottomPoints[it - 1], zeroBottom, bottomPoints[it]) + face(topPoints[it - 1], topPoints[it], zeroTop) } - // closed surface if (phi == PI2) { - face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) - face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop) + face(bottomPoints.last(), zeroBottom, bottomPoints[0]) + face(topPoints.last(), topPoints[0], zeroTop) } else { - face4(zeroTop, zeroBottom, bottomOuterPoints[0], upperOuterPoints[0]) - face4(zeroTop, zeroBottom, bottomOuterPoints.last(), upperOuterPoints.last()) + face4(zeroTop, zeroBottom, bottomPoints[0], topPoints[0]) + face4(zeroTop, zeroBottom, bottomPoints.last(), topPoints.last()) } } } - } @VisionBuilder diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt index 2a6bcdc5..75ff2161 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt @@ -21,8 +21,8 @@ public class ConeSurface( public val height: Float, public val topRadius: Float, public val topInnerRadius: Float, - public val startAngle: Float = 0f, - public val angle: Float = PI2, + public val phiStart: Float = 0f, + public val phi: Float = PI2, ) : SolidBase(), GeometrySolid { init { @@ -30,16 +30,16 @@ public class ConeSurface( require(height > 0) { "Cone surface height must be positive" } require(bottomInnerRadius >= 0) { "Cone surface bottom inner radius must be non-negative" } //require(startAngle >= 0) - require(angle in (0f..(PI2))) + require(phi in (0f..(PI2))) } override fun toGeometry(geometryBuilder: GeometryBuilder) { val segments = detail ?: 32 require(segments >= 4) { "The number of segments in tube is too small" } - val angleStep = angle / (segments - 1) + val angleStep = phi / (segments - 1) fun shape(r: Float, z: Float): List = (0 until segments).map { i -> - Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) + Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } geometryBuilder.apply { @@ -52,17 +52,17 @@ public class ConeSurface( face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1]) } - if (angle == PI2) { + if (phi == PI2) { face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last()) } if (bottomInnerRadius == 0f) { - val zeroBottom = Point3D(0f, 0f, 0f) - val zeroTop = Point3D(0f, 0f, height) + val zeroBottom = Point3D(0f, 0f, -height / 2) + val zeroTop = Point3D(0f, 0f, height / 2) (1 until segments).forEach { face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop) } - if (angle == PI2) { + if (phi == PI2) { face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) face(topOuterPoints.last(), topOuterPoints[0], zeroTop) } else { @@ -96,7 +96,7 @@ public class ConeSurface( topOuterPoints[it] ) } - if (angle == PI2) { + if (phi == PI2) { face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0]) face4( bottomInnerPoints.last(), @@ -135,8 +135,8 @@ public inline fun MutableVisionContainer.tube( height = height.toFloat(), topRadius = radius.toFloat(), topInnerRadius = innerRadius.toFloat(), - startAngle = startAngle.toFloat(), - angle = angle.toFloat() + phiStart = startAngle.toFloat(), + phi = angle.toFloat() ).apply(block).also { setChild(name, it) } @VisionBuilder @@ -156,6 +156,6 @@ public inline fun MutableVisionContainer.coneSurface( height = height.toFloat(), topRadius = topOuterRadius.toFloat(), topInnerRadius = topInnerRadius.toFloat(), - startAngle = startAngle.toFloat(), - angle = angle.toFloat() + phiStart = startAngle.toFloat(), + phi = angle.toFloat() ).apply(block).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 1913e332..234ded6f 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -34,7 +34,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { objectFactories[Box::class] = ThreeBoxFactory objectFactories[Convex::class] = ThreeConvexFactory objectFactories[Sphere::class] = ThreeSphereFactory - objectFactories[ConeSegment::class] = ThreeConeFactory +// objectFactories[ConeSegment::class] = ThreeConeFactory objectFactories[PolyLine::class] = ThreeSmartLineFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory From 18c39fc0768ec7a894fa3d03eb93a0dc37e62676 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 30 May 2023 17:06:27 +0300 Subject: [PATCH 051/112] Add solids configuration to vision builder --- build.gradle.kts | 2 +- demo/build.gradle.kts | 11 +++ demo/gdml/build.gradle.kts | 4 + .../src/jvmMain/kotlin/formServer.kt | 12 +-- demo/playground/src/jvmMain/kotlin/shapes.kt | 1 + .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 7 +- demo/solid-showcase/build.gradle.kts | 5 -- .../visionforge/server/VisionServer.kt | 85 +++++++++---------- .../server/applicationExtensions.kt | 3 +- .../kscience/visionforge/solid/Solids.kt | 8 +- .../visionforge/solid/three/ThreePlugin.kt | 9 +- 11 files changed, 76 insertions(+), 71 deletions(-) create mode 100644 demo/build.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts index 3ee913b2..30eea98f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-8" + version = "0.3.0-dev-9" } subprojects { diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts new file mode 100644 index 00000000..49476bc7 --- /dev/null +++ b/demo/build.gradle.kts @@ -0,0 +1,11 @@ +import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode +import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper + +subprojects { + plugins.withType { + configure { + explicitApi = ExplicitApiMode.Disabled + } + } +} \ No newline at end of file diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index c1e3be28..72b1b283 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -30,6 +30,10 @@ kscience { } } +kotlin { + explicitApi = null +} + //kotlin { // // sourceSets { diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index 2f5b4ea1..d832d85a 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -2,7 +2,7 @@ package space.kscience.visionforge.examples import io.ktor.server.cio.CIO import io.ktor.server.engine.embeddedServer -import io.ktor.server.http.content.resources +import io.ktor.server.http.content.staticResources import io.ktor.server.routing.routing import kotlinx.html.* import space.kscience.dataforge.context.Global @@ -12,21 +12,18 @@ import space.kscience.visionforge.html.VisionOfHtmlForm import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.html.bindForm import space.kscience.visionforge.onPropertyChange -import space.kscience.visionforge.server.EngineConnectorConfig import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser import space.kscience.visionforge.server.visionPage +@Suppress("ExtractKtorModule") fun main() { val visionManager = Global.request(VisionManager) - - val connector = EngineConnectorConfig("localhost", 7777) - - val server = embeddedServer(CIO, connector.port, connector.host) { + val server = embeddedServer(CIO) { routing { - resources() + staticResources("/", null) } val form = VisionOfHtmlForm("form").apply { @@ -36,7 +33,6 @@ fun main() { } visionPage( - connector, visionManager, VisionPage.scriptHeader("js/visionforge-playground.js"), ) { diff --git a/demo/playground/src/jvmMain/kotlin/shapes.kt b/demo/playground/src/jvmMain/kotlin/shapes.kt index 1c702c5e..a338d123 100644 --- a/demo/playground/src/jvmMain/kotlin/shapes.kt +++ b/demo/playground/src/jvmMain/kotlin/shapes.kt @@ -33,6 +33,7 @@ fun main() = makeVisionFile { cylinder(30,20, name = "cylinder"){ detail = 31 y = -220 + z = 15 } } } diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index 4f0ff70c..9e0c8282 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -14,7 +14,6 @@ import space.kscience.dataforge.meta.Null import space.kscience.dataforge.names.Name import space.kscience.visionforge.Colors import space.kscience.visionforge.html.VisionPage -import space.kscience.visionforge.server.EngineConnectorConfig import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser import space.kscience.visionforge.server.visionPage @@ -23,6 +22,7 @@ import space.kscience.visionforge.three.threeJsHeader import kotlin.random.Random +@Suppress("ExtractKtorModule") fun main() { val satContext = Context("sat") { plugin(Solids) @@ -36,15 +36,12 @@ fun main() { color.set(Colors.white) } } - val connector = EngineConnectorConfig("localhost", 7777) - - val server = embeddedServer(CIO, connector.port, connector.host) { + val server = embeddedServer(CIO, port = 7777) { routing { staticResources("", null, null) } visionPage( - connector, solids.visionManager, VisionPage.threeJsHeader, VisionPage.styleSheetHeader("css/styles.css") ) { diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index d588e035..78e7d163 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id("space.kscience.gradle.mpp") - `maven-publish` application } @@ -22,8 +21,4 @@ kscience { application { mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt") -} - -kotlin{ - explicitApi = null } \ No newline at end of file diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index c05a1834..84a87a65 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.html.* -import kotlinx.html.stream.createHTML import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.meta.* @@ -96,7 +95,7 @@ public fun Application.serveVisionData( val vision: Vision = resolveVision(Name.parse(name)) ?: error("Vision with id='$name' not registered") launch { - for(frame in incoming) { + for (frame in incoming) { val data = frame.data.decodeToString() application.log.debug("Received update for $name: \n$data") val change = configuration.visionManager.jsonFormat.decodeFromString( @@ -151,82 +150,82 @@ public fun Application.serveVisionData( public fun Application.visionPage( route: String, configuration: VisionRoute, - connector: EngineConnectorConfig, headers: Collection, + connector: EngineConnectorConfig? = null, visionFragment: HtmlVisionFragment, ) { require(WebSockets) val collector: MutableMap = mutableMapOf() - val html = createHTML().apply { - head { - meta { - charset = "utf-8" - } - headers.forEach { header -> - consumer.header() - } - } - body { - //Load the fragment and remember all loaded visions - visionFragment( - visionManager = configuration.visionManager, - embedData = configuration.dataMode == VisionRoute.Mode.EMBED, - fetchDataUrl = if (configuration.dataMode != VisionRoute.Mode.EMBED) { - url { - host = connector.host - port = connector.port - path(route, "data") - } - } else null, - updatesUrl = if (configuration.dataMode == VisionRoute.Mode.UPDATE) { - url { - protocol = URLProtocol.WS - host = connector.host - port = connector.port - path(route, "ws") - } - } else null, - onVisionRendered = { name, vision -> collector[name] = vision }, - fragment = visionFragment - ) - } - }.finalize() - //serve data serveVisionData(configuration, collector) //filled pages routing { get(route) { - call.respondText(html, ContentType.Text.Html) + val host = connector?.host ?: call.request.host() + val port = connector?.port ?: call.request.port() + call.respondHtml { + head { + meta { + charset = "utf-8" + } + headers.forEach { header -> + consumer.header() + } + } + body { + //Load the fragment and remember all loaded visions + visionFragment( + visionManager = configuration.visionManager, + embedData = configuration.dataMode == VisionRoute.Mode.EMBED, + fetchDataUrl = if (configuration.dataMode != VisionRoute.Mode.EMBED) { + url { + this.host = host + this.port = port + path(route, "data") + } + } else null, + updatesUrl = if (configuration.dataMode == VisionRoute.Mode.UPDATE) { + url { + protocol = URLProtocol.WS + this.host = host + this.port = port + path(route, "ws") + } + } else null, + onVisionRendered = { name, vision -> collector[name] = vision }, + fragment = visionFragment + ) + } + } } } } public fun Application.visionPage( - connector: EngineConnectorConfig, visionManager: VisionManager, vararg headers: HtmlFragment, route: String = "/", + connector: EngineConnectorConfig? = null, configurationBuilder: VisionRoute.() -> Unit = {}, visionFragment: HtmlVisionFragment, ) { val configuration = VisionRoute(route, visionManager).apply(configurationBuilder) - visionPage(route, configuration, connector, listOf(*headers), visionFragment) + visionPage(route, configuration, listOf(*headers), connector, visionFragment) } /** * Render given [VisionPage] at server */ public fun Application.visionPage( - connector: EngineConnectorConfig, page: VisionPage, route: String = "/", + connector: EngineConnectorConfig? = null, configurationBuilder: VisionRoute.() -> Unit = {}, ) { val configuration = VisionRoute(route, page.visionManager).apply(configurationBuilder) - visionPage(route, configuration, connector, page.pageHeaders.values, visionFragment = page.content) + visionPage(route, configuration, page.pageHeaders.values, connector, visionFragment = page.content) } diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt index f33b59b2..81f6e3e7 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt @@ -22,7 +22,8 @@ public fun

, B : Any, F : Any> P.require( */ public fun ApplicationEngine.openInBrowser() { val connector = environment.connectors.first() - val uri = URI("http", null, connector.host, connector.port, null, null, null) + val host = if (connector.host == "0.0.0.0") "127.0.0.1" else connector.host + val uri = URI("http", null, host, connector.port, null, null, null) Desktop.getDesktop().browse(uri) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 1fecd450..f828101b 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -11,10 +11,10 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.* import space.kscience.visionforge.html.VisionOutput +import space.kscience.visionforge.solid.specifications.Canvas3DOptions public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer { @@ -80,8 +80,10 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer Unit): SolidGroup { +public inline fun VisionOutput.solid(options: Canvas3DOptions? = null, block: SolidGroup.() -> Unit): SolidGroup { requirePlugin(Solids) + options?.let { + meta = options.meta + } return SolidGroup().apply(block) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 234ded6f..d1309849 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -34,7 +34,6 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { objectFactories[Box::class] = ThreeBoxFactory objectFactories[Convex::class] = ThreeConvexFactory objectFactories[Sphere::class] = ThreeSphereFactory -// objectFactories[ConeSegment::class] = ThreeConeFactory objectFactories[PolyLine::class] = ThreeSmartLineFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory @@ -143,7 +142,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { internal fun renderSolid( element: Element, vision: Solid, - ): ThreeCanvas = getOrCreateCanvas(element).apply { + options: Canvas3DOptions = Canvas3DOptions(), + ): ThreeCanvas = getOrCreateCanvas(element, options).apply { render(vision) } @@ -151,9 +151,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { renderSolid( element, vision as? Solid ?: error("Solid expected but ${vision::class} found"), - ).apply { - options.meta.update(meta) - } + Canvas3DOptions.read(meta) + ) } public companion object : PluginFactory { From d32dc3fa08b60018066776268473738ef457c51f Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 30 May 2023 17:38:40 +0300 Subject: [PATCH 052/112] Fix markup plugin tag --- .../kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index 16cb6b24..b95c291f 100644 --- a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -14,7 +14,7 @@ public actual class MarkupPlugin : VisionPlugin() { override val tag: PluginTag get() = Companion.tag public actual companion object : PluginFactory { - override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP) + override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP) override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() From c4b866f5b55e088b75c99ac7b08b6c6efa4a8341 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 30 May 2023 17:55:35 +0300 Subject: [PATCH 053/112] Fix markup plugin. --- .../space/kscience/visionforge/useProperty.kt | 18 +++++++++--------- .../visionforge/markup/MarkupPlugin.kt | 8 +++++++- .../visionforge/markup/MarkupPlugin.kt | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt index 4d00f15b..87312f6f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt @@ -13,20 +13,20 @@ import kotlin.reflect.KProperty1 /** - * Call [callBack] on initial value of the property and then on all subsequent values after change + * Call [callback] on initial value of the property and then on all subsequent values after change */ public fun Vision.useProperty( propertyName: Name, inherit: Boolean? = null, includeStyles: Boolean? = null, scope: CoroutineScope? = manager?.context, - callBack: (Meta) -> Unit, + callback: (Meta) -> Unit, ): Job { //Pass initial value. - callBack(properties.getProperty(propertyName, inherit, includeStyles)) + callback(properties.getProperty(propertyName, inherit, includeStyles)) return properties.changes.onEach { name -> if (name.startsWith(propertyName)) { - callBack(properties.getProperty(propertyName, inherit, includeStyles)) + callback(properties.getProperty(propertyName, inherit, includeStyles)) } }.launchIn(scope ?: error("Orphan Vision can't observe properties")) } @@ -36,19 +36,19 @@ public fun Vision.useProperty( inherit: Boolean? = null, includeStyles: Boolean? = null, scope: CoroutineScope? = manager?.context, - callBack: (Meta) -> Unit, -): Job = useProperty(propertyName.parseAsName(), inherit, includeStyles, scope, callBack) + callback: (Meta) -> Unit, +): Job = useProperty(propertyName.parseAsName(), inherit, includeStyles, scope, callback) public fun V.useProperty( property: KProperty1, scope: CoroutineScope? = manager?.context, - callBack: V.(T) -> Unit, + callback: V.(T) -> Unit, ): Job { //Pass initial value. - callBack(property.get(this)) + callback(property.get(this)) return properties.changes.onEach { name -> if (name.startsWith(property.name.asName())) { - callBack(property.get(this@useProperty)) + callback(property.get(this@useProperty)) } }.launchIn(scope ?: error("Orphan Vision can't observe properties")) } \ No newline at end of file diff --git a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index e79908f0..aad66f3f 100644 --- a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -12,6 +12,7 @@ import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName import space.kscience.visionforge.* import space.kscience.visionforge.markup.VisionOfMarkup.Companion.COMMONMARK_FORMAT import space.kscience.visionforge.markup.VisionOfMarkup.Companion.GFM_FORMAT @@ -44,8 +45,13 @@ public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { element.append(div) } + override fun content(target: String): Map = when (target) { + ElementVisionRenderer.TYPE -> mapOf("markup".asName() to this) + else -> super.content(target) + } + public actual companion object : PluginFactory { - override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP) + override val tag: PluginTag = PluginTag("vision.markup.js", PluginTag.DATAFORGE_GROUP) override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() diff --git a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index b95c291f..ce094ee9 100644 --- a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -14,7 +14,7 @@ public actual class MarkupPlugin : VisionPlugin() { override val tag: PluginTag get() = Companion.tag public actual companion object : PluginFactory { - override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP) + override val tag: PluginTag = PluginTag("vision.markup.jvm", PluginTag.DATAFORGE_GROUP) override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() From be52551564e7d8732001374283364583470bb91d Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 30 May 2023 19:37:03 +0300 Subject: [PATCH 054/112] Minor fixes --- .../src/jvmMain/kotlin/allThingsDemo.kt | 17 +++++++++++++---- .../visionforge/html/VisionTagConsumer.kt | 5 +++-- .../space/kscience/visionforge/VisionClient.kt | 6 ++++-- .../space/kscience/visionforge/solid/Solids.kt | 6 +++++- .../visionforge/solid/three/ThreePlugin.kt | 6 +++--- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt b/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt index 328387c1..5b272b72 100644 --- a/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt +++ b/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.examples import kotlinx.html.h2 import space.kscience.dataforge.meta.ValueType +import space.kscience.dataforge.meta.invoke import space.kscience.plotly.layout import space.kscience.plotly.models.ScatterMode import space.kscience.plotly.models.TextPosition @@ -12,13 +13,14 @@ import space.kscience.visionforge.markup.markdown import space.kscience.visionforge.plotly.plotly import space.kscience.visionforge.solid.box import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.z import space.kscience.visionforge.tables.columnTable -import java.nio.file.Paths +import kotlin.io.path.Path fun main() = makeVisionFile( - Paths.get("VisionForgeDemo.html"), + Path("VisionForgeDemo.html"), resourceLocation = ResourceLocation.EMBED ) { markdown { @@ -32,8 +34,15 @@ fun main() = makeVisionFile( h2 { +"3D visualization with Three-js" } vision("3D") { - solid { - box(100, 100, 100, name = "aBox"){ + solid( + Canvas3DOptions { + axes { + size = 200.0 + visible = true + } + } + ) { + box(100, 100, 100, name = "aBox") { z = 50.0 } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt index 80a7be7e..05bebfc2 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt @@ -26,7 +26,7 @@ public annotation class VisionDSL * A placeholder object to attach inline vision builders. */ @VisionDSL -public class VisionOutput @PublishedApi internal constructor(public val context: Context, public val name: Name) { +public class VisionOutput @PublishedApi internal constructor(override val context: Context, public val name: Name): ContextAware { public var meta: Meta = Meta.EMPTY private val requirements: MutableSet> = HashSet() @@ -95,9 +95,10 @@ public abstract class VisionTagConsumer( if (!outputMeta.isEmpty()) { //Hard-code output configuration script { + type = "text/json" attributes["class"] = OUTPUT_META_CLASS unsafe { - +manager.jsonFormat.encodeToString(MetaSerializer, outputMeta) + +("\n" + manager.jsonFormat.encodeToString(MetaSerializer, outputMeta) + "\n") } } } diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index af3cd574..7d61ce24 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -176,11 +176,13 @@ public class VisionClient : AbstractPlugin() { } val outputMeta = element.getEmbeddedData(VisionTagConsumer.OUTPUT_META_CLASS)?.let { - VisionManager.defaultJson.decodeFromString(MetaSerializer, it) + VisionManager.defaultJson.decodeFromString(MetaSerializer, it).also { + logger.info { "Output meta for $name: $it" } + } } ?: Meta.EMPTY when { - // fetch data if path is provided + // fetch data if the path is provided element.attributes[OUTPUT_FETCH_ATTRIBUTE] != null -> { val attr = element.attributes[OUTPUT_FETCH_ATTRIBUTE]!! diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index f828101b..4900fc1f 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -85,5 +85,9 @@ public inline fun VisionOutput.solid(options: Canvas3DOptions? = null, block: So options?.let { meta = options.meta } - return SolidGroup().apply(block) + return SolidGroup().apply(block).apply { + if (children.values.none { it is LightSource }) { + ambientLight() + } + } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index d1309849..064597e6 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -124,7 +124,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public fun getOrCreateCanvas( element: Element, - options: Canvas3DOptions = Canvas3DOptions(), + options: Canvas3DOptions, ): ThreeCanvas = canvasCache.getOrPut(element) { ThreeCanvas(this, element, options) } @@ -142,7 +142,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { internal fun renderSolid( element: Element, vision: Solid, - options: Canvas3DOptions = Canvas3DOptions(), + options: Canvas3DOptions, ): ThreeCanvas = getOrCreateCanvas(element, options).apply { render(vision) } @@ -166,7 +166,7 @@ public fun ThreePlugin.render( element: HTMLElement, obj: Solid, optionsBuilder: Canvas3DOptions.() -> Unit = {}, -): ThreeCanvas = renderSolid(element, obj).apply { +): ThreeCanvas = renderSolid(element, obj, Canvas3DOptions(optionsBuilder)).apply { options.apply(optionsBuilder) } From a872f10523d00d3067ffe0ff42971d6cbb078255 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 30 May 2023 20:04:23 +0300 Subject: [PATCH 055/112] Minor fixes --- .../space/kscience/visionforge/html/VisionTagConsumer.kt | 2 +- .../kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt index 05bebfc2..99a8ea0d 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt @@ -92,6 +92,7 @@ public abstract class VisionTagConsumer( vision.setAsRoot(manager) } attributes[OUTPUT_NAME_ATTRIBUTE] = name.toString() + renderVision(manager, name, vision, outputMeta) if (!outputMeta.isEmpty()) { //Hard-code output configuration script { @@ -102,7 +103,6 @@ public abstract class VisionTagConsumer( } } } - renderVision(manager, name, vision, outputMeta) } /** diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index 10baa4ab..f92e7d4d 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -14,6 +14,7 @@ import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.plotly.Plot import space.kscience.plotly.Plotly +import space.kscience.plotly.PlotlyConfig import space.kscience.visionforge.MutableVisionProperties import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionBuilder @@ -88,8 +89,10 @@ public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this) */ @VisionBuilder public inline fun VisionOutput.plotly( + config: PlotlyConfig = PlotlyConfig(), block: Plot.() -> Unit, ): VisionOfPlotly { requirePlugin(PlotlyPlugin) + meta = config.meta return VisionOfPlotly(Plotly.plot(block)) } \ No newline at end of file From 23cb8765b66fdbf504d496db0cac8b41deb55f19 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 2 Jun 2023 14:33:41 +0300 Subject: [PATCH 056/112] Minor fixes --- gradle.properties | 2 +- ui/bootstrap/build.gradle.kts | 22 +++++++++++++--------- visionforge-threejs/build.gradle.kts | 20 +++++++++++++------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/gradle.properties b/gradle.properties index e3a218ba..f38299f2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,5 +6,5 @@ kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.14.9-kotlin-1.8.20 +toolsVersion=0.14.9-kotlin-1.9.0-Beta org.jetbrains.compose.experimental.jscanvas.enabled=true \ No newline at end of file diff --git a/ui/bootstrap/build.gradle.kts b/ui/bootstrap/build.gradle.kts index c0b980d9..f50ae119 100644 --- a/ui/bootstrap/build.gradle.kts +++ b/ui/bootstrap/build.gradle.kts @@ -1,15 +1,19 @@ plugins { - kotlin("js") - id("space.kscience.gradle.js") + id("space.kscience.gradle.mpp") } val dataforgeVersion: String by rootProject.extra -dependencies { - api(project(":visionforge-solid")) - api(project(":ui:react")) - implementation(npm("file-saver", "2.0.2")) - implementation(npm("bootstrap","4.6.0")) - implementation(npm("jquery","3.5.1")) - implementation(npm("popper.js","1.16.1")) +kscience{ + js() + jsMain{ + dependencies { + api(project(":visionforge-solid")) + api(project(":ui:react")) + implementation(npm("file-saver", "2.0.2")) + implementation(npm("bootstrap","4.6.0")) + implementation(npm("jquery","3.5.1")) + implementation(npm("popper.js","1.16.1")) + } + } } \ No newline at end of file diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index f04275f3..41714618 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -1,17 +1,23 @@ plugins { - id("space.kscience.gradle.js") + id("space.kscience.gradle.mpp") } kotlin{ explicitApi = org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode.Disabled +} + +kscience{ js{ binaries.library() } + jsMain{ + dependencies { + api(projects.visionforgeSolid) + implementation(npm("three", "0.143.0")) + implementation(npm("three-csg-ts", "3.1.10")) + implementation(npm("three.meshline","1.4.0")) + } + } } -dependencies { - api(projects.visionforgeSolid) - implementation(npm("three", "0.143.0")) - implementation(npm("three-csg-ts", "3.1.10")) - implementation(npm("three.meshline","1.4.0")) -} + From 140c59497e24c76ff48325ce1786089ede0206bb Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 2 Jun 2023 20:58:32 +0300 Subject: [PATCH 057/112] Change all Js modules to MPP --- demo/muon-monitor/build.gradle.kts | 4 ++-- gradle.properties | 2 +- .../visionforge/bootstrap/bootstrap.kt | 0 .../visionforge/bootstrap/outputConfig.kt | 0 .../visionforge/bootstrap/reactBootstrap.kt | 0 .../visionforge/bootstrap/tabComponent.kt | 0 .../visionforge/bootstrap/threeControls.kt | 0 .../bootstrap/visionPropertyEditor.kt | 0 .../resources/css/custom-bootstrap.css | 0 ui/react/build.gradle.kts | 17 +++++++++++------ .../kscience/visionforge/react/MetaViewer.kt | 0 .../visionforge/react/MultiSelectChooser.kt | 0 .../visionforge/react/PropertyEditor.kt | 5 ++++- .../visionforge/react/RangeValueChooser.kt | 0 .../visionforge/react/ThreeCanvasComponent.kt | 0 .../kscience/visionforge/react/TreeStyles.kt | 0 .../kscience/visionforge/react/VisionTree.kt | 0 .../kscience/visionforge/react/createRoot.kt | 0 .../space/kscience/visionforge/react/ext.kt | 0 .../kscience/visionforge/react/layout.kt | 0 .../visionforge/react/valueChooser.kt | 0 ui/ring/build.gradle.kts | 19 +++++++++---------- .../{main => jsMain}/kotlin/ringui/Loader.kt | 0 .../kotlin/ringui/LoaderScreen.kt | 0 .../ThreeViewWithControls.kt | 0 .../ThreeWithControlsPlugin.kt | 0 .../ringPropertyEditor.kt | 0 .../ringThreeControls.kt | 0 visionforge-gdml/build.gradle.kts | 2 +- .../solid/three/ThreeAmbientLightFactory.kt | 0 .../solid/three/ThreeBoxFactory.kt | 0 .../visionforge/solid/three/ThreeCanvas.kt | 0 .../solid/three/ThreeCanvasLabelFactory.kt | 0 .../solid/three/ThreeCompositeFactory.kt | 0 .../solid/three/ThreeConeFactory.kt | 0 .../solid/three/ThreeConvexFactory.kt | 0 .../visionforge/solid/three/ThreeFactory.kt | 0 .../solid/three/ThreeGeometryBuilder.kt | 6 +++--- .../visionforge/solid/three/ThreeJsVision.kt | 2 +- .../solid/three/ThreeLabelFactory.kt | 0 .../solid/three/ThreeLineFactory.kt | 8 ++++---- .../visionforge/solid/three/ThreeMaterials.kt | 0 .../solid/three/ThreeMeshFactory.kt | 0 .../solid/three/ThreeMeshLineFactory.kt | 0 .../visionforge/solid/three/ThreePlugin.kt | 1 - .../solid/three/ThreePointLightFactory.kt | 0 .../solid/three/ThreeReferenceFactory.kt | 0 .../solid/three/ThreeSmartLineFactory.kt | 0 .../solid/three/ThreeSphereFactory.kt | 0 .../kscience/visionforge/solid/three/csg.kt | 0 .../kscience/visionforge/solid/three/three.kt | 0 .../{main => jsMain}/kotlin/three/THREE.kt | 0 .../kotlin/three/animation/AnimationAction.kt | 0 .../kotlin/three/animation/AnimationClip.kt | 0 .../kotlin/three/animation/AnimationMixer.kt | 0 .../kotlin/three/animation/AnimationUtils.kt | 0 .../kotlin/three/animation/KeyFrameTrack.kt | 0 .../kotlin/three/audio/Audio.kt | 0 .../kotlin/three/audio/AudioContext.kt | 0 .../kotlin/three/audio/AudioListener.kt | 0 .../kotlin/three/audio/PositionalAudio.kt | 0 .../kotlin/three/cameras/Camera.kt | 0 .../three/cameras/OrthographicCamera.kt | 0 .../kotlin/three/cameras/PerspectiveCamera.kt | 0 .../kotlin/three/core/BufferAttribute.kt | 0 .../kotlin/three/core/BufferGeometry.kt | 0 .../kotlin/three/core/Clock.kt | 0 .../kotlin/three/core/EventDispatcher.kt | 0 .../kotlin/three/core/Face3.kt | 0 .../three/core/InstancedBufferGeometry.kt | 0 .../kotlin/three/core/Layers.kt | 0 .../kotlin/three/core/Object3D.kt | 0 .../kotlin/three/core/Raycaster.kt | 0 .../kotlin/three/core/Uniform.kt | 0 .../kotlin/three/external/Detector.kt | 0 .../kotlin/three/external/ImprovedNoise.kt | 0 .../kotlin/three/external/SimplexNoise.kt | 0 .../three/external/controls/FlyControls.kt | 0 .../three/external/controls/OrbitControls.kt | 0 .../external/controls/TrackballControls.kt | 0 .../external/controls/TransformControls.kt | 0 .../three/external/exporters/OBJExporter.kt | 0 .../three/external/exporters/STLExporter.kt | 0 .../external/geometries/ConvexGeometry.kt | 0 .../kotlin/three/external/libs/GUIParams.kt | 0 .../kotlin/three/external/libs/Stats.kt | 0 .../kotlin/three/external/libs/datgui.kt | 0 .../three/external/loaders/BabylonLoader.kt | 0 .../three/external/loaders/GLTFLoader.kt | 0 .../three/external/loaders/LoaderSupport.kt | 0 .../three/external/loaders/MTLLoader.kt | 0 .../three/external/loaders/OBJLoader.kt | 0 .../three/external/loaders/OBJLoader2.kt | 0 .../three/external/loaders/STLLoader.kt | 0 .../kotlin/three/external/objects/Sky.kt | 0 .../kotlin/three/external/objects/Water.kt | 0 .../three/external/objects/WaterOptions.kt | 0 .../kotlin/three/extras/SceneUtils.kt | 0 .../kotlin/three/extras/core/Curve.kt | 0 .../kotlin/three/extras/core/CurvePath.kt | 0 .../kotlin/three/extras/core/Path.kt | 0 .../kotlin/three/extras/core/Shape.kt | 0 .../kotlin/three/extras/core/ShapePath.kt | 0 .../kotlin/three/extras/curves/ArcCurve.kt | 0 .../three/extras/curves/CatmullRomCurve3.kt | 0 .../three/extras/curves/EllipseCurve.kt | 0 .../kotlin/three/extras/curves/LineCurve.kt | 0 .../kotlin/three/extras/curves/LineCurve3.kt | 0 .../three/extras/curves/QuadricBezierCurve.kt | 0 .../extras/curves/QuadricBezierCurve3.kt | 0 .../kotlin/three/extras/curves/SplineCurve.kt | 0 .../kotlin/three/geometries/BoxGeometry.kt | 0 .../kotlin/three/geometries/ConeGeometry.kt | 0 .../three/geometries/CylinderGeometry.kt | 0 .../kotlin/three/geometries/EdgesGeometry.kt | 0 .../three/geometries/ExtrudeGeometry.kt | 0 .../kotlin/three/geometries/PlaneGeometry.kt | 0 .../kotlin/three/geometries/SphereGeometry.kt | 0 .../kotlin/three/geometries/TextGeometry.kt | 0 .../kotlin/three/geometries/TorusGeometry.kt | 0 .../kotlin/three/geometries/TubeGeometry.kt | 0 .../three/geometries/WireframeGeometry.kt | 0 .../kotlin/three/helpers/ArrowHelper.kt | 0 .../kotlin/three/helpers/AxesHelper.kt | 0 .../kotlin/three/helpers/Box3Helper.kt | 0 .../kotlin/three/helpers/CameraHelper.kt | 0 .../kotlin/three/helpers/GridHelper.kt | 0 .../three/helpers/HemisphereLightHelper.kt | 0 .../kotlin/three/helpers/PlaneHelper.kt | 0 .../{main => jsMain}/kotlin/three/ktutils.kt | 0 .../kotlin/three/lights/AmbientLight.kt | 0 .../kotlin/three/lights/DirectionalLight.kt | 0 .../three/lights/DirectionalLightShadow.kt | 0 .../kotlin/three/lights/HemisphereLight.kt | 0 .../kotlin/three/lights/Light.kt | 0 .../kotlin/three/lights/LightShadow.kt | 0 .../kotlin/three/lights/PointLight.kt | 0 .../kotlin/three/lights/SpotLight.kt | 0 .../kotlin/three/lights/SpotLightShadow.kt | 0 .../kotlin/three/loaders/Cache.kt | 0 .../three/loaders/CompressedTextureLoader.kt | 0 .../kotlin/three/loaders/ImageLoader.kt | 0 .../kotlin/three/loaders/JSONLoader.kt | 0 .../kotlin/three/loaders/Loader.kt | 0 .../kotlin/three/loaders/LoadingManager.kt | 0 .../kotlin/three/loaders/MaterialLoader.kt | 0 .../kotlin/three/loaders/TextureLoader.kt | 0 .../three/materials/LineBasicMaterial.kt | 0 .../three/materials/LineDashedMaterial.kt | 0 .../kotlin/three/materials/Material.kt | 0 .../three/materials/MeshBasicMaterial.kt | 0 .../three/materials/MeshDepthMaterial.kt | 0 .../three/materials/MeshLambertMaterial.kt | 0 .../three/materials/MeshNormalMaterial.kt | 0 .../three/materials/MeshPhongMaterial.kt | 0 .../three/materials/MeshPhysicalMaterial.kt | 0 .../three/materials/MeshStandardMaterial.kt | 0 .../kotlin/three/materials/PointsMaterial.kt | 0 .../three/materials/RawShaderMaterial.kt | 0 .../kotlin/three/materials/ShaderMaterial.kt | 0 .../kotlin/three/materials/SpriteMaterial.kt | 0 .../kotlin/three/math/Box2.kt | 0 .../kotlin/three/math/Box3.kt | 0 .../kotlin/three/math/Color.kt | 0 .../kotlin/three/math/ColorConstants.kt | 0 .../kotlin/three/math/Cylindrical.kt | 0 .../kotlin/three/math/Euler.kt | 0 .../kotlin/three/math/Frustrum.kt | 0 .../kotlin/three/math/Line3.kt | 0 .../kotlin/three/math/Math.kt | 0 .../kotlin/three/math/Matrix3.kt | 0 .../kotlin/three/math/Matrix4.kt | 0 .../kotlin/three/math/Plane.kt | 0 .../kotlin/three/math/Quaternion.kt | 0 .../{main => jsMain}/kotlin/three/math/Ray.kt | 0 .../kotlin/three/math/Sphere.kt | 0 .../kotlin/three/math/Spherical.kt | 0 .../kotlin/three/math/Triangle.kt | 0 .../kotlin/three/math/Vector2.kt | 0 .../kotlin/three/math/Vector3.kt | 0 .../kotlin/three/math/Vector4.kt | 0 .../kotlin/three/math/operators.kt | 0 .../kotlin/three/meshline/MeshLine.kt | 0 .../kotlin/three/meshline/meshLineExt.kt | 0 .../kotlin/three/objects/Group.kt | 0 .../kotlin/three/objects/LOD.kt | 0 .../kotlin/three/objects/Line.kt | 0 .../kotlin/three/objects/LineLoop.kt | 0 .../kotlin/three/objects/LineSegments.kt | 0 .../kotlin/three/objects/Mesh.kt | 0 .../kotlin/three/objects/Points.kt | 0 .../kotlin/three/objects/Sprite.kt | 0 .../kotlin/three/renderers/WebGL2Renderer.kt | 0 .../three/renderers/WebGL2RendererParams.kt | 0 .../three/renderers/WebGLRenderTarget.kt | 0 .../renderers/WebGLRenderTargetOptions.kt | 0 .../kotlin/three/renderers/WebGLRenderer.kt | 0 .../three/renderers/WebGLRendererParams.kt | 0 .../three/renderers/shaders/ShaderChunk.kt | 0 .../three/renderers/shaders/ShaderLib.kt | 0 .../three/renderers/shaders/UniformsUtil.kt | 0 .../kotlin/three/scenes/Fog.kt | 0 .../kotlin/three/scenes/FogExp2.kt | 0 .../kotlin/three/scenes/Scene.kt | 0 .../three/textures/CompressedTexture.kt | 0 .../kotlin/three/textures/CubeTexture.kt | 0 .../kotlin/three/textures/DepthTexture.kt | 0 .../kotlin/three/textures/Texture.kt | 0 .../kotlin/three/utils/BufferGeometryUtils.kt | 0 209 files changed, 36 insertions(+), 30 deletions(-) rename ui/bootstrap/src/{main => jsMain}/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt (100%) rename ui/bootstrap/src/{main => jsMain}/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt (100%) rename ui/bootstrap/src/{main => jsMain}/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt (100%) rename ui/bootstrap/src/{main => jsMain}/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt (100%) rename ui/bootstrap/src/{main => jsMain}/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt (100%) rename ui/bootstrap/src/{main => jsMain}/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt (100%) rename ui/bootstrap/src/{main => jsMain}/resources/css/custom-bootstrap.css (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/MetaViewer.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/PropertyEditor.kt (97%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/TreeStyles.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/VisionTree.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/createRoot.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/ext.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/layout.kt (100%) rename ui/react/src/{main => jsMain}/kotlin/space/kscience/visionforge/react/valueChooser.kt (100%) rename ui/ring/src/{main => jsMain}/kotlin/ringui/Loader.kt (100%) rename ui/ring/src/{main => jsMain}/kotlin/ringui/LoaderScreen.kt (100%) rename ui/ring/src/{main => jsMain}/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt (100%) rename ui/ring/src/{main => jsMain}/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt (100%) rename ui/ring/src/{main => jsMain}/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt (100%) rename ui/ring/src/{main => jsMain}/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt (99%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/csg.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/space/kscience/visionforge/solid/three/three.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/THREE.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/animation/AnimationAction.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/animation/AnimationClip.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/animation/AnimationMixer.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/animation/AnimationUtils.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/animation/KeyFrameTrack.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/audio/Audio.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/audio/AudioContext.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/audio/AudioListener.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/audio/PositionalAudio.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/cameras/Camera.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/cameras/OrthographicCamera.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/cameras/PerspectiveCamera.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/BufferAttribute.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/BufferGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/Clock.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/EventDispatcher.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/Face3.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/InstancedBufferGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/Layers.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/Object3D.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/Raycaster.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/core/Uniform.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/Detector.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/ImprovedNoise.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/SimplexNoise.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/controls/FlyControls.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/controls/OrbitControls.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/controls/TrackballControls.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/controls/TransformControls.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/exporters/OBJExporter.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/exporters/STLExporter.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/geometries/ConvexGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/libs/GUIParams.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/libs/Stats.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/libs/datgui.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/loaders/BabylonLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/loaders/GLTFLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/loaders/LoaderSupport.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/loaders/MTLLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/loaders/OBJLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/loaders/OBJLoader2.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/loaders/STLLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/objects/Sky.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/objects/Water.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/external/objects/WaterOptions.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/SceneUtils.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/core/Curve.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/core/CurvePath.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/core/Path.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/core/Shape.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/core/ShapePath.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/curves/ArcCurve.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/curves/CatmullRomCurve3.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/curves/EllipseCurve.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/curves/LineCurve.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/curves/LineCurve3.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/curves/QuadricBezierCurve.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/curves/QuadricBezierCurve3.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/extras/curves/SplineCurve.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/BoxGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/ConeGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/CylinderGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/EdgesGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/ExtrudeGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/PlaneGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/SphereGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/TextGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/TorusGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/TubeGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/geometries/WireframeGeometry.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/helpers/ArrowHelper.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/helpers/AxesHelper.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/helpers/Box3Helper.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/helpers/CameraHelper.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/helpers/GridHelper.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/helpers/HemisphereLightHelper.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/helpers/PlaneHelper.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/ktutils.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/AmbientLight.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/DirectionalLight.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/DirectionalLightShadow.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/HemisphereLight.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/Light.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/LightShadow.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/PointLight.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/SpotLight.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/lights/SpotLightShadow.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/loaders/Cache.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/loaders/CompressedTextureLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/loaders/ImageLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/loaders/JSONLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/loaders/Loader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/loaders/LoadingManager.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/loaders/MaterialLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/loaders/TextureLoader.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/LineBasicMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/LineDashedMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/Material.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/MeshBasicMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/MeshDepthMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/MeshLambertMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/MeshNormalMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/MeshPhongMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/MeshPhysicalMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/MeshStandardMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/PointsMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/RawShaderMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/ShaderMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/materials/SpriteMaterial.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Box2.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Box3.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Color.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/ColorConstants.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Cylindrical.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Euler.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Frustrum.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Line3.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Math.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Matrix3.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Matrix4.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Plane.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Quaternion.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Ray.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Sphere.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Spherical.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Triangle.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Vector2.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Vector3.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/Vector4.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/math/operators.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/meshline/MeshLine.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/meshline/meshLineExt.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/objects/Group.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/objects/LOD.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/objects/Line.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/objects/LineLoop.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/objects/LineSegments.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/objects/Mesh.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/objects/Points.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/objects/Sprite.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/WebGL2Renderer.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/WebGL2RendererParams.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/WebGLRenderTarget.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/WebGLRenderTargetOptions.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/WebGLRenderer.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/WebGLRendererParams.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/shaders/ShaderChunk.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/shaders/ShaderLib.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/renderers/shaders/UniformsUtil.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/scenes/Fog.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/scenes/FogExp2.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/scenes/Scene.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/textures/CompressedTexture.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/textures/CubeTexture.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/textures/DepthTexture.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/textures/Texture.kt (100%) rename visionforge-threejs/src/{main => jsMain}/kotlin/three/utils/BufferGeometryUtils.kt (100%) diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index 2ea4d0eb..154d4b0a 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -34,8 +34,8 @@ kscience { implementation("ch.qos.logback:logback-classic:1.2.11") } jsMain { - implementation(project(":ui:ring")) - implementation(project(":visionforge-threejs")) + implementation(projects.ui.ring) + implementation(projects.visionforgeThreejs) //implementation(devNpm("webpack-bundle-analyzer", "4.4.0")) } } diff --git a/gradle.properties b/gradle.properties index f38299f2..39926f4b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,5 +6,5 @@ kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.14.9-kotlin-1.9.0-Beta +toolsVersion=0.14.9-kotlin-1.9.0-Beta-2 org.jetbrains.compose.experimental.jscanvas.enabled=true \ No newline at end of file diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt similarity index 100% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt similarity index 100% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt similarity index 100% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt similarity index 100% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt similarity index 100% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt similarity index 100% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt diff --git a/ui/bootstrap/src/main/resources/css/custom-bootstrap.css b/ui/bootstrap/src/jsMain/resources/css/custom-bootstrap.css similarity index 100% rename from ui/bootstrap/src/main/resources/css/custom-bootstrap.css rename to ui/bootstrap/src/jsMain/resources/css/custom-bootstrap.css diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index acbe40cb..c4d40cf1 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -1,11 +1,16 @@ plugins { - id("space.kscience.gradle.js") + id("space.kscience.gradle.mpp") } -dependencies{ - api(project(":visionforge-solid")) - api("org.jetbrains.kotlin-wrappers:kotlin-styled") - api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") +kscience { + js() + jsMain { + dependencies { + api(projects.visionforgeSolid) + api("org.jetbrains.kotlin-wrappers:kotlin-styled") + api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") // implementation(npm("react-select","4.3.0")) - implementation(project(":visionforge-threejs")) + implementation(projects.visionforgeThreejs) + } + } } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt similarity index 97% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index a31a04fb..991ba2d5 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -13,10 +13,13 @@ import kotlinx.html.js.onClickFunction import kotlinx.html.org.w3c.dom.events.Event import react.* import react.dom.attrs -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.ObservableMutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.ValueRequirement import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.remove import space.kscience.dataforge.names.* import space.kscience.visionforge.hidden import styled.css diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/createRoot.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/createRoot.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ext.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ext.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/ext.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ext.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/layout.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/layout.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/layout.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/layout.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts index 8b4bf056..d1f2ff72 100644 --- a/ui/ring/build.gradle.kts +++ b/ui/ring/build.gradle.kts @@ -1,11 +1,11 @@ plugins { - id("space.kscience.gradle.js") + id("space.kscience.gradle.mpp") } val dataforgeVersion: String by rootProject.extra -kotlin{ - js(IR){ +kscience{ + js{ useCommonJs() browser { commonWebpackConfig { @@ -15,12 +15,11 @@ kotlin{ } } } -} - -dependencies{ - api(project(":ui:react")) - api("org.jetbrains.kotlin-wrappers:kotlin-ring-ui") + jsMain{ + api(projects.ui.react) + api("org.jetbrains.kotlin-wrappers:kotlin-ring-ui") - implementation(npm("core-js","3.12.1")) - implementation(npm("file-saver", "2.0.2")) + implementation(npm("core-js","3.12.1")) + implementation(npm("file-saver", "2.0.2")) + } } \ No newline at end of file diff --git a/ui/ring/src/main/kotlin/ringui/Loader.kt b/ui/ring/src/jsMain/kotlin/ringui/Loader.kt similarity index 100% rename from ui/ring/src/main/kotlin/ringui/Loader.kt rename to ui/ring/src/jsMain/kotlin/ringui/Loader.kt diff --git a/ui/ring/src/main/kotlin/ringui/LoaderScreen.kt b/ui/ring/src/jsMain/kotlin/ringui/LoaderScreen.kt similarity index 100% rename from ui/ring/src/main/kotlin/ringui/LoaderScreen.kt rename to ui/ring/src/jsMain/kotlin/ringui/LoaderScreen.kt diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt similarity index 100% rename from ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt rename to ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt similarity index 100% rename from ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt rename to ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt similarity index 100% rename from ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt rename to ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt similarity index 100% rename from ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt rename to ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index 6dd3042a..cdf4ad47 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -9,7 +9,7 @@ kscience { } dependencies { api(projects.visionforgeSolid) - api("space.kscience:gdml:0.4.0") + api("space.kscience:gdml:0.5.0") } dependencies(jvmTest) { implementation(spclibs.logback.classic) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt index e75e4847..d97c354a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt @@ -1,13 +1,13 @@ package space.kscience.visionforge.solid.three -import three.core.BufferGeometry -import three.core.Float32BufferAttribute -import three.math.Vector3 import space.kscience.dataforge.meta.Meta import space.kscience.visionforge.solid.GeometryBuilder import space.kscience.visionforge.solid.Point3D import space.kscience.visionforge.solid.cross import space.kscience.visionforge.solid.minus +import three.core.BufferGeometry +import three.core.Float32BufferAttribute +import three.math.Vector3 internal fun Point3D.toVector() = Vector3(x, y, z) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt index 3829698e..9d4b8e86 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid.three -import three.core.Object3D import space.kscience.visionforge.solid.SolidBase +import three.core.Object3D /** * A custom visual object that has its own Three.js renderer diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index adf4ce0d..edfd6b65 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -1,15 +1,15 @@ package space.kscience.visionforge.solid.three -import three.core.BufferGeometry -import three.core.Object3D -import three.math.Color -import three.objects.LineSegments import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.color import space.kscience.visionforge.solid.string import space.kscience.visionforge.solid.three.ThreeMaterials.DEFAULT_LINE_COLOR +import three.core.BufferGeometry +import three.core.Object3D +import three.math.Color +import three.objects.LineSegments import kotlin.math.ceil import kotlin.reflect.KClass diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 064597e6..8f577baa 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -6,7 +6,6 @@ import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.update import space.kscience.dataforge.names.* import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/csg.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/csg.kt diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/three.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/three.kt diff --git a/visionforge-threejs/src/main/kotlin/three/THREE.kt b/visionforge-threejs/src/jsMain/kotlin/three/THREE.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/THREE.kt rename to visionforge-threejs/src/jsMain/kotlin/three/THREE.kt diff --git a/visionforge-threejs/src/main/kotlin/three/animation/AnimationAction.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationAction.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/animation/AnimationAction.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationAction.kt diff --git a/visionforge-threejs/src/main/kotlin/three/animation/AnimationClip.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationClip.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/animation/AnimationClip.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationClip.kt diff --git a/visionforge-threejs/src/main/kotlin/three/animation/AnimationMixer.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationMixer.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/animation/AnimationMixer.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationMixer.kt diff --git a/visionforge-threejs/src/main/kotlin/three/animation/AnimationUtils.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationUtils.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/animation/AnimationUtils.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationUtils.kt diff --git a/visionforge-threejs/src/main/kotlin/three/animation/KeyFrameTrack.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/KeyFrameTrack.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/animation/KeyFrameTrack.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/KeyFrameTrack.kt diff --git a/visionforge-threejs/src/main/kotlin/three/audio/Audio.kt b/visionforge-threejs/src/jsMain/kotlin/three/audio/Audio.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/audio/Audio.kt rename to visionforge-threejs/src/jsMain/kotlin/three/audio/Audio.kt diff --git a/visionforge-threejs/src/main/kotlin/three/audio/AudioContext.kt b/visionforge-threejs/src/jsMain/kotlin/three/audio/AudioContext.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/audio/AudioContext.kt rename to visionforge-threejs/src/jsMain/kotlin/three/audio/AudioContext.kt diff --git a/visionforge-threejs/src/main/kotlin/three/audio/AudioListener.kt b/visionforge-threejs/src/jsMain/kotlin/three/audio/AudioListener.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/audio/AudioListener.kt rename to visionforge-threejs/src/jsMain/kotlin/three/audio/AudioListener.kt diff --git a/visionforge-threejs/src/main/kotlin/three/audio/PositionalAudio.kt b/visionforge-threejs/src/jsMain/kotlin/three/audio/PositionalAudio.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/audio/PositionalAudio.kt rename to visionforge-threejs/src/jsMain/kotlin/three/audio/PositionalAudio.kt diff --git a/visionforge-threejs/src/main/kotlin/three/cameras/Camera.kt b/visionforge-threejs/src/jsMain/kotlin/three/cameras/Camera.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/cameras/Camera.kt rename to visionforge-threejs/src/jsMain/kotlin/three/cameras/Camera.kt diff --git a/visionforge-threejs/src/main/kotlin/three/cameras/OrthographicCamera.kt b/visionforge-threejs/src/jsMain/kotlin/three/cameras/OrthographicCamera.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/cameras/OrthographicCamera.kt rename to visionforge-threejs/src/jsMain/kotlin/three/cameras/OrthographicCamera.kt diff --git a/visionforge-threejs/src/main/kotlin/three/cameras/PerspectiveCamera.kt b/visionforge-threejs/src/jsMain/kotlin/three/cameras/PerspectiveCamera.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/cameras/PerspectiveCamera.kt rename to visionforge-threejs/src/jsMain/kotlin/three/cameras/PerspectiveCamera.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/BufferAttribute.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/BufferAttribute.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/BufferAttribute.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/BufferAttribute.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/BufferGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/BufferGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/BufferGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/BufferGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/Clock.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Clock.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/Clock.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Clock.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/EventDispatcher.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/EventDispatcher.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/EventDispatcher.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/EventDispatcher.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/Face3.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Face3.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/Face3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Face3.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/InstancedBufferGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/InstancedBufferGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/InstancedBufferGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/InstancedBufferGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/Layers.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Layers.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/Layers.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Layers.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/Object3D.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Object3D.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/Object3D.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Object3D.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/Raycaster.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Raycaster.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/Raycaster.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Raycaster.kt diff --git a/visionforge-threejs/src/main/kotlin/three/core/Uniform.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Uniform.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/core/Uniform.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Uniform.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/Detector.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/Detector.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/Detector.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/Detector.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/ImprovedNoise.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/ImprovedNoise.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/ImprovedNoise.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/ImprovedNoise.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/SimplexNoise.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/SimplexNoise.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/SimplexNoise.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/SimplexNoise.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/controls/FlyControls.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/FlyControls.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/controls/FlyControls.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/controls/FlyControls.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/controls/OrbitControls.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/OrbitControls.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/controls/OrbitControls.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/controls/OrbitControls.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/controls/TrackballControls.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/TrackballControls.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/controls/TrackballControls.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/controls/TrackballControls.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/controls/TransformControls.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/TransformControls.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/controls/TransformControls.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/controls/TransformControls.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/exporters/OBJExporter.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/exporters/OBJExporter.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/exporters/OBJExporter.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/exporters/OBJExporter.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/exporters/STLExporter.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/exporters/STLExporter.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/exporters/STLExporter.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/exporters/STLExporter.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/geometries/ConvexGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/geometries/ConvexGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/geometries/ConvexGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/geometries/ConvexGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/libs/GUIParams.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/GUIParams.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/libs/GUIParams.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/libs/GUIParams.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/libs/Stats.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/Stats.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/libs/Stats.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/libs/Stats.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/libs/datgui.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/datgui.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/libs/datgui.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/libs/datgui.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/loaders/BabylonLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/BabylonLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/loaders/BabylonLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/BabylonLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/loaders/GLTFLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/GLTFLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/loaders/GLTFLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/GLTFLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/loaders/LoaderSupport.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/LoaderSupport.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/loaders/LoaderSupport.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/LoaderSupport.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/loaders/MTLLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/MTLLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/loaders/MTLLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/MTLLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader2.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader2.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/loaders/OBJLoader2.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader2.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/STLLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/STLLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/objects/Sky.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/Sky.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/objects/Sky.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/objects/Sky.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/objects/Water.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/Water.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/objects/Water.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/objects/Water.kt diff --git a/visionforge-threejs/src/main/kotlin/three/external/objects/WaterOptions.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/WaterOptions.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/external/objects/WaterOptions.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/objects/WaterOptions.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/SceneUtils.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/SceneUtils.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/SceneUtils.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/SceneUtils.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/core/Curve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Curve.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/core/Curve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/core/Curve.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/core/CurvePath.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/CurvePath.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/core/CurvePath.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/core/CurvePath.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/core/Path.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Path.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/core/Path.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/core/Path.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/core/Shape.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Shape.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/core/Shape.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/core/Shape.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/core/ShapePath.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/ShapePath.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/core/ShapePath.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/core/ShapePath.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/curves/ArcCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/ArcCurve.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/curves/ArcCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/ArcCurve.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/curves/CatmullRomCurve3.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/CatmullRomCurve3.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/curves/CatmullRomCurve3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/CatmullRomCurve3.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/curves/EllipseCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/EllipseCurve.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/curves/EllipseCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/EllipseCurve.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve3.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve3.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/curves/LineCurve3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve3.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve3.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve3.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/curves/QuadricBezierCurve3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve3.kt diff --git a/visionforge-threejs/src/main/kotlin/three/extras/curves/SplineCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/SplineCurve.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/extras/curves/SplineCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/SplineCurve.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/BoxGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/BoxGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/BoxGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/BoxGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/ConeGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/ConeGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/ConeGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/ConeGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/CylinderGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/CylinderGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/CylinderGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/CylinderGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/EdgesGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/EdgesGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/EdgesGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/EdgesGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/ExtrudeGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/ExtrudeGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/ExtrudeGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/ExtrudeGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/PlaneGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/PlaneGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/PlaneGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/PlaneGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/SphereGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/SphereGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/SphereGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/SphereGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/TextGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TextGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/TextGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/TextGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/TorusGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TorusGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/TorusGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/TorusGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/TubeGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TubeGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/TubeGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/TubeGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/geometries/WireframeGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/WireframeGeometry.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/geometries/WireframeGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/WireframeGeometry.kt diff --git a/visionforge-threejs/src/main/kotlin/three/helpers/ArrowHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/ArrowHelper.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/helpers/ArrowHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/ArrowHelper.kt diff --git a/visionforge-threejs/src/main/kotlin/three/helpers/AxesHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/AxesHelper.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/helpers/AxesHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/AxesHelper.kt diff --git a/visionforge-threejs/src/main/kotlin/three/helpers/Box3Helper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/Box3Helper.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/helpers/Box3Helper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/Box3Helper.kt diff --git a/visionforge-threejs/src/main/kotlin/three/helpers/CameraHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/CameraHelper.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/helpers/CameraHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/CameraHelper.kt diff --git a/visionforge-threejs/src/main/kotlin/three/helpers/GridHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/GridHelper.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/helpers/GridHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/GridHelper.kt diff --git a/visionforge-threejs/src/main/kotlin/three/helpers/HemisphereLightHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/HemisphereLightHelper.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/helpers/HemisphereLightHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/HemisphereLightHelper.kt diff --git a/visionforge-threejs/src/main/kotlin/three/helpers/PlaneHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/PlaneHelper.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/helpers/PlaneHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/PlaneHelper.kt diff --git a/visionforge-threejs/src/main/kotlin/three/ktutils.kt b/visionforge-threejs/src/jsMain/kotlin/three/ktutils.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/ktutils.kt rename to visionforge-threejs/src/jsMain/kotlin/three/ktutils.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/AmbientLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/AmbientLight.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/AmbientLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/AmbientLight.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/DirectionalLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLight.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/DirectionalLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLight.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/DirectionalLightShadow.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLightShadow.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/DirectionalLightShadow.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLightShadow.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/HemisphereLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/HemisphereLight.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/HemisphereLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/HemisphereLight.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/Light.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/Light.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/Light.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/Light.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/LightShadow.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/LightShadow.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/LightShadow.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/LightShadow.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/PointLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/PointLight.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/PointLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/PointLight.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/SpotLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLight.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/SpotLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLight.kt diff --git a/visionforge-threejs/src/main/kotlin/three/lights/SpotLightShadow.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLightShadow.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/lights/SpotLightShadow.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLightShadow.kt diff --git a/visionforge-threejs/src/main/kotlin/three/loaders/Cache.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/Cache.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/loaders/Cache.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/Cache.kt diff --git a/visionforge-threejs/src/main/kotlin/three/loaders/CompressedTextureLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/CompressedTextureLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/loaders/CompressedTextureLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/CompressedTextureLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/loaders/ImageLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/ImageLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/loaders/ImageLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/ImageLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/loaders/JSONLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/JSONLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/loaders/JSONLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/JSONLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/loaders/Loader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/Loader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/loaders/Loader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/Loader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/loaders/LoadingManager.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/LoadingManager.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/loaders/LoadingManager.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/LoadingManager.kt diff --git a/visionforge-threejs/src/main/kotlin/three/loaders/MaterialLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/MaterialLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/loaders/MaterialLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/MaterialLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/loaders/TextureLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/TextureLoader.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/loaders/TextureLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/TextureLoader.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/LineBasicMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/LineBasicMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/LineBasicMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/LineBasicMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/LineDashedMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/LineDashedMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/LineDashedMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/LineDashedMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/Material.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/Material.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/Material.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/Material.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/MeshBasicMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshBasicMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/MeshBasicMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshBasicMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/MeshDepthMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshDepthMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/MeshDepthMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshDepthMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/MeshLambertMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshLambertMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/MeshLambertMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshLambertMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/MeshNormalMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshNormalMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/MeshNormalMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshNormalMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/MeshPhongMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhongMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/MeshPhongMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhongMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/MeshPhysicalMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhysicalMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/MeshPhysicalMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhysicalMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/MeshStandardMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshStandardMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/MeshStandardMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshStandardMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/PointsMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/PointsMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/PointsMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/PointsMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/RawShaderMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/RawShaderMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/RawShaderMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/RawShaderMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/ShaderMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/ShaderMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/ShaderMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/ShaderMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/materials/SpriteMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/SpriteMaterial.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/materials/SpriteMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/SpriteMaterial.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Box2.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Box2.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Box2.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Box2.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Box3.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Box3.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Box3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Box3.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Color.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Color.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Color.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Color.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/ColorConstants.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/ColorConstants.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/ColorConstants.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/ColorConstants.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Cylindrical.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Cylindrical.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Cylindrical.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Cylindrical.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Euler.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Euler.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Euler.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Euler.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Frustrum.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Frustrum.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Frustrum.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Frustrum.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Line3.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Line3.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Line3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Line3.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Math.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Math.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Math.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Math.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Matrix3.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Matrix3.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Matrix3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Matrix3.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Matrix4.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Matrix4.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Matrix4.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Matrix4.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Plane.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Plane.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Plane.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Plane.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Quaternion.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Quaternion.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Quaternion.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Quaternion.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Ray.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Ray.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Ray.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Ray.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Sphere.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Sphere.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Sphere.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Sphere.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Spherical.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Spherical.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Spherical.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Spherical.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Triangle.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Triangle.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Triangle.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Triangle.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Vector2.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector2.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Vector2.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Vector2.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Vector3.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector3.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Vector3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Vector3.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/Vector4.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector4.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/Vector4.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Vector4.kt diff --git a/visionforge-threejs/src/main/kotlin/three/math/operators.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/operators.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/math/operators.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/operators.kt diff --git a/visionforge-threejs/src/main/kotlin/three/meshline/MeshLine.kt b/visionforge-threejs/src/jsMain/kotlin/three/meshline/MeshLine.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/meshline/MeshLine.kt rename to visionforge-threejs/src/jsMain/kotlin/three/meshline/MeshLine.kt diff --git a/visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt b/visionforge-threejs/src/jsMain/kotlin/three/meshline/meshLineExt.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/meshline/meshLineExt.kt rename to visionforge-threejs/src/jsMain/kotlin/three/meshline/meshLineExt.kt diff --git a/visionforge-threejs/src/main/kotlin/three/objects/Group.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Group.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/objects/Group.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Group.kt diff --git a/visionforge-threejs/src/main/kotlin/three/objects/LOD.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/LOD.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/objects/LOD.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/LOD.kt diff --git a/visionforge-threejs/src/main/kotlin/three/objects/Line.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Line.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/objects/Line.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Line.kt diff --git a/visionforge-threejs/src/main/kotlin/three/objects/LineLoop.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/LineLoop.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/objects/LineLoop.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/LineLoop.kt diff --git a/visionforge-threejs/src/main/kotlin/three/objects/LineSegments.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/LineSegments.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/objects/LineSegments.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/LineSegments.kt diff --git a/visionforge-threejs/src/main/kotlin/three/objects/Mesh.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Mesh.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/objects/Mesh.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Mesh.kt diff --git a/visionforge-threejs/src/main/kotlin/three/objects/Points.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Points.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/objects/Points.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Points.kt diff --git a/visionforge-threejs/src/main/kotlin/three/objects/Sprite.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Sprite.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/objects/Sprite.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Sprite.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/WebGL2Renderer.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2Renderer.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/WebGL2Renderer.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2Renderer.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/WebGL2RendererParams.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2RendererParams.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/WebGL2RendererParams.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2RendererParams.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTarget.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTarget.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTarget.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTarget.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTargetOptions.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTargetOptions.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderTargetOptions.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTargetOptions.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderer.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderer.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/WebGLRenderer.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderer.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/WebGLRendererParams.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRendererParams.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/WebGLRendererParams.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRendererParams.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderChunk.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderChunk.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderChunk.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderChunk.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderLib.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderLib.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/shaders/ShaderLib.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderLib.kt diff --git a/visionforge-threejs/src/main/kotlin/three/renderers/shaders/UniformsUtil.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/UniformsUtil.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/renderers/shaders/UniformsUtil.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/UniformsUtil.kt diff --git a/visionforge-threejs/src/main/kotlin/three/scenes/Fog.kt b/visionforge-threejs/src/jsMain/kotlin/three/scenes/Fog.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/scenes/Fog.kt rename to visionforge-threejs/src/jsMain/kotlin/three/scenes/Fog.kt diff --git a/visionforge-threejs/src/main/kotlin/three/scenes/FogExp2.kt b/visionforge-threejs/src/jsMain/kotlin/three/scenes/FogExp2.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/scenes/FogExp2.kt rename to visionforge-threejs/src/jsMain/kotlin/three/scenes/FogExp2.kt diff --git a/visionforge-threejs/src/main/kotlin/three/scenes/Scene.kt b/visionforge-threejs/src/jsMain/kotlin/three/scenes/Scene.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/scenes/Scene.kt rename to visionforge-threejs/src/jsMain/kotlin/three/scenes/Scene.kt diff --git a/visionforge-threejs/src/main/kotlin/three/textures/CompressedTexture.kt b/visionforge-threejs/src/jsMain/kotlin/three/textures/CompressedTexture.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/textures/CompressedTexture.kt rename to visionforge-threejs/src/jsMain/kotlin/three/textures/CompressedTexture.kt diff --git a/visionforge-threejs/src/main/kotlin/three/textures/CubeTexture.kt b/visionforge-threejs/src/jsMain/kotlin/three/textures/CubeTexture.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/textures/CubeTexture.kt rename to visionforge-threejs/src/jsMain/kotlin/three/textures/CubeTexture.kt diff --git a/visionforge-threejs/src/main/kotlin/three/textures/DepthTexture.kt b/visionforge-threejs/src/jsMain/kotlin/three/textures/DepthTexture.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/textures/DepthTexture.kt rename to visionforge-threejs/src/jsMain/kotlin/three/textures/DepthTexture.kt diff --git a/visionforge-threejs/src/main/kotlin/three/textures/Texture.kt b/visionforge-threejs/src/jsMain/kotlin/three/textures/Texture.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/textures/Texture.kt rename to visionforge-threejs/src/jsMain/kotlin/three/textures/Texture.kt diff --git a/visionforge-threejs/src/main/kotlin/three/utils/BufferGeometryUtils.kt b/visionforge-threejs/src/jsMain/kotlin/three/utils/BufferGeometryUtils.kt similarity index 100% rename from visionforge-threejs/src/main/kotlin/three/utils/BufferGeometryUtils.kt rename to visionforge-threejs/src/jsMain/kotlin/three/utils/BufferGeometryUtils.kt From 38302eac4c73e1de356c31c66bda3c80e6bd122a Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 3 Jun 2023 17:55:27 +0300 Subject: [PATCH 058/112] Use KMath-geometry for solids --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 24 ++-- .../npm/root/serialization/rootToSolid.kt | 6 +- demo/js-playground/build.gradle.kts | 1 + demo/muon-monitor/build.gradle.kts | 2 + .../kotlin/ru/mipt/npm/muon/monitor/Event.kt | 4 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 2 +- .../ru/mipt/npm/muon/monitor/Monitor.kt | 14 +-- .../ru/mipt/npm/muon/monitor/MMServer.kt | 7 +- .../ru/mipt/npm/muon/monitor/sim/line.kt | 8 +- .../ru/mipt/npm/muon/monitor/sim/monitor.kt | 2 +- demo/solid-showcase/build.gradle.kts | 2 + .../kscience/visionforge/solid/demo/demo.kt | 5 +- .../kscience/visionforge/gdml/gdmlLoader.kt | 16 +-- visionforge-solid/build.gradle.kts | 3 + .../kscience/visionforge/solid/ConeSegment.kt | 8 +- .../kscience/visionforge/solid/ConeSurface.kt | 8 +- .../kscience/visionforge/solid/Convex.kt | 6 +- .../kscience/visionforge/solid/Extruded.kt | 22 ++-- .../solid/Float32Euclidean2DSpace.kt | 71 +++++++++++ .../solid/Float32Euclidean3DSpace.kt | 113 +++++++++++++++++ .../visionforge/solid/GeometryBuilder.kt | 16 +-- .../kscience/visionforge/solid/Hexagon.kt | 64 +++++----- .../kscience/visionforge/solid/LightSource.kt | 2 +- .../kscience/visionforge/solid/PolyLine.kt | 9 +- .../space/kscience/visionforge/solid/Solid.kt | 23 ++-- .../kscience/visionforge/solid/Solids.kt | 1 + .../kscience/visionforge/solid/Sphere.kt | 4 +- .../kscience/visionforge/solid/SphereLayer.kt | 4 +- .../kscience/visionforge/solid/geometry.kt | 114 ++++-------------- .../kscience/visionforge/solid/ConvexTest.kt | 3 - .../solid/three/ThreeGeometryBuilder.kt | 25 ++-- .../visionforge/three/TestServerExtensions.kt | 1 + 32 files changed, 367 insertions(+), 223 deletions(-) create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean3DSpace.kt diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 8015aea6..a2e1f70a 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -32,12 +32,12 @@ private fun Solid.rotate(rot: DoubleArray) { val xAngle = atan2(-rot[5], rot[8]) val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2))) val zAngle = atan2(-rot[1], rot[0]) - rotation = Point3D(xAngle, yAngle, zAngle) + rotation = Float32Vector3D(xAngle, yAngle, zAngle) } private fun Solid.translate(trans: DoubleArray) { val (x, y, z) = trans - position = Point3D(x, y, z) + position = Float32Vector3D(x, y, z) } private fun Solid.useMatrix(matrix: DGeoMatrix?) { @@ -72,7 +72,7 @@ private fun Solid.useMatrix(matrix: DGeoMatrix?) { val fScale by matrix.meta.doubleArray() translate(fTranslation) rotate(fRotationMatrix) - scale = Point3D(fScale[0], fScale[1], fScale[2]) + scale = Float32Vector3D(fScale[0], fScale[1], fScale[2]) } } } @@ -248,14 +248,14 @@ private fun SolidGroup.addShape( val fDz by shape.meta.double(0.0) //TODO check proper node order - val node1 = Point3D(-fBl1, -fH1, -fDz) - val node2 = Point3D(fBl1, -fH1, -fDz) - val node3 = Point3D(fTl1, fH1, -fDz) - val node4 = Point3D(-fTl1, fH1, -fDz) - val node5 = Point3D(-fBl2, -fH2, fDz) - val node6 = Point3D(fBl2, -fH2, fDz) - val node7 = Point3D(fTl2, fH2, fDz) - val node8 = Point3D(-fTl2, fH2, fDz) + val node1 = Float32Vector3D(-fBl1, -fH1, -fDz) + val node2 = Float32Vector3D(fBl1, -fH1, -fDz) + val node3 = Float32Vector3D(fTl1, fH1, -fDz) + val node4 = Float32Vector3D(-fTl1, fH1, -fDz) + val node5 = Float32Vector3D(-fBl2, -fH2, fDz) + val node6 = Float32Vector3D(fBl2, -fH2, fDz) + val node7 = Float32Vector3D(fTl2, fH2, fDz) + val node8 = Float32Vector3D(-fTl2, fH2, fDz) hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name) } @@ -264,7 +264,7 @@ private fun SolidGroup.addShape( val fScale by shape.dObject(::DGeoScale) fShape?.let { scaledShape -> solidGroup(name?.let { Name.parse(it) }) { - scale = Point3D(fScale?.x ?: 1.0, fScale?.y ?: 1.0, fScale?.z ?: 1.0) + scale = Float32Vector3D(fScale?.x ?: 1.0, fScale?.y ?: 1.0, fScale?.z ?: 1.0) addShape(scaledShape, context) apply(block) } diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt index 50a4002a..eb39b8e7 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt @@ -25,12 +25,12 @@ private fun Solid.rotate(rot: DoubleArray) { val xAngle = atan2(-rot[5], rot[8]) val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2))) val zAngle = atan2(-rot[1], rot[0]) - rotation = Point3D(xAngle, yAngle, zAngle) + rotation = Float32Vector3D(xAngle, yAngle, zAngle) } private fun Solid.translate(trans: DoubleArray) { val (x, y, z) = trans - position = Point3D(x, y, z) + position = Float32Vector3D(x, y, z) } private fun Solid.useMatrix(matrix: TGeoMatrix?) { @@ -52,7 +52,7 @@ private fun Solid.useMatrix(matrix: TGeoMatrix?) { translate(matrix.fTranslation) rotate(matrix.fRotationMatrix) val (xScale, yScale, zScale) = matrix.fScale - scale = Point3D(xScale, yScale, zScale) + scale = Float32Vector3D(xScale, yScale, zScale) } } } diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index 86935c51..603b921a 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -7,6 +7,7 @@ kscience{ } kotlin{ + explicitApi = null js(IR){ useCommonJs() browser { diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index 2ea4d0eb..73336f1b 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -40,6 +40,8 @@ kscience { } } +kotlin.explicitApi = null + application { mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt") } diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt index b47c2b66..22a9d2e1 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt @@ -1,9 +1,9 @@ package ru.mipt.npm.muon.monitor import kotlinx.serialization.Serializable -import space.kscience.visionforge.solid.Point3D +import space.kscience.visionforge.solid.Float32Vector3D -typealias Track = List +typealias Track = List /** * diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 1b8eb566..82c20def 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -16,7 +16,7 @@ class Model(val manager: VisionManager) { private fun MutableVisionContainer.pixel(pixel: SC1) { val group = solidGroup(pixel.name) { - position = Point3D(pixel.center.x, pixel.center.y, pixel.center.z) + position = Float32Vector3D(pixel.center.x, pixel.center.y, pixel.center.z) box(pixel.xSize, pixel.ySize, pixel.zSize) label(pixel.name) { z = -Monitor.PIXEL_Z_SIZE / 2 - 5 diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt index 1a8c8aa9..48fe83d1 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt @@ -2,21 +2,21 @@ package ru.mipt.npm.muon.monitor import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE import ru.mipt.npm.muon.monitor.Monitor.PIXEL_Z_SIZE -import space.kscience.visionforge.solid.Point3D -import space.kscience.visionforge.solid.plus +import space.kscience.visionforge.solid.Float32Euclidean3DSpace +import space.kscience.visionforge.solid.Float32Vector3D /** * A single pixel */ class SC1( val name: String, - val center: Point3D, + val center: Float32Vector3D, val xSize: Float = PIXEL_XY_SIZE, val ySize: Float = PIXEL_XY_SIZE, val zSize: Float = PIXEL_Z_SIZE, ) class SC16( val name: String, - val center: Point3D, + val center: Float32Vector3D, ) { /** @@ -109,9 +109,9 @@ class SC16( else -> throw Error() } - val offset = Point3D(-y, x, 0)//rotateDetector(Point3D(x, y, 0.0)); + val offset = Float32Vector3D(-y, x, 0)//rotateDetector(Point3D(x, y, 0.0)); val pixelName = "${name}_${index}" - SC1(pixelName, offset + center) + SC1(pixelName, with(Float32Euclidean3DSpace) { offset + center }) } } } @@ -154,7 +154,7 @@ object Monitor { val x = split[4].toDouble() - 500 val y = split[5].toDouble() - 500 val z = 180 - split[6].toDouble() - SC16(detectorName, Point3D(x, y, z)) + SC16(detectorName, Float32Vector3D(x, y, z)) } else { null } diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt index b9b8ce4c..d3d50c5b 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt @@ -10,8 +10,7 @@ import io.ktor.server.application.install import io.ktor.server.application.log import io.ktor.server.cio.CIO import io.ktor.server.engine.embeddedServer -import io.ktor.server.http.content.resources -import io.ktor.server.http.content.static +import io.ktor.server.http.content.staticResources import io.ktor.server.plugins.contentnegotiation.ContentNegotiation import io.ktor.server.response.respond import io.ktor.server.response.respondText @@ -53,9 +52,7 @@ fun Application.module(context: Context = Global) { status = HttpStatusCode.OK ) } - static("/") { - resources() - } + staticResources("/", null) } try { Desktop.getDesktop().browse(URI("http://localhost:8080/index.html")) diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt index c2578783..d9492a74 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt @@ -5,7 +5,7 @@ import org.apache.commons.math3.geometry.euclidean.threed.Plane import org.apache.commons.math3.geometry.euclidean.threed.Vector3D import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.GEOMETRY_TOLERANCE -import space.kscience.visionforge.solid.Point3D +import space.kscience.visionforge.solid.Float32Vector3D /** * Created by darksnake on 11-May-16. @@ -50,12 +50,12 @@ fun makeTrack(x: Double, y: Double, theta: Double, phi: Double): Line { ) } -fun Vector3D.toPoint() = Point3D(x, y, z) +fun Vector3D.toKMathVector() = Float32Vector3D(x, y, z) -fun Line.toPoints(): List { +fun Line.toKMathVectors(): List { val basePoint = basePlane.intersection(this) val bottom = basePoint.subtract(2000.0, direction) val top = basePoint.add(2000.0, direction) - return listOf(bottom.toPoint(), top.toPoint()) + return listOf(bottom.toKMathVector(), top.toKMathVector()) } diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt index d2ec7235..e55b74db 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt @@ -43,7 +43,7 @@ fun readEffs(): Map { fun buildEventByTrack(index: Int, track: Line, hitResolver: (Line) -> Collection = defaultHitResolver): Event { - return Event(index, track.toPoints(), hitResolver(track).map { it.name }) + return Event(index, track.toKMathVectors(), hitResolver(track).map { it.name }) } val defaultHitResolver: (Line) -> Collection = { track: Line -> diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index 78e7d163..8f1c370b 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -19,6 +19,8 @@ kscience { } } +kotlin.explicitApi = null + application { mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt") } \ No newline at end of file diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index ef009b82..5fdec43b 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -130,7 +130,10 @@ fun VisionLayout.showcase() { color.set(Colors.blue) } repeat(20) { - polyline(Point3D(100, 100, 100), Point3D(-100, -100, -100)) { + polyline( + Float32Vector3D(100, 100, 100), + Float32Vector3D(-100, -100, -100) + ) { thickness = 3.0 rotationX = it * PI2 / 20 color.set(Colors.green) diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index 58213437..e17248ad 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -248,14 +248,14 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { val dyBottom = solid.y1.toDouble() / 2 val dyTop = solid.y2.toDouble() / 2 val dz = solid.z.toDouble() / 2 - val node1 = Point3D(-dxBottom, -dyBottom, -dz) - val node2 = Point3D(dxBottom, -dyBottom, -dz) - val node3 = Point3D(dxBottom, dyBottom, -dz) - val node4 = Point3D(-dxBottom, dyBottom, -dz) - val node5 = Point3D(-dxTop, -dyTop, dz) - val node6 = Point3D(dxTop, -dyTop, dz) - val node7 = Point3D(dxTop, dyTop, dz) - val node8 = Point3D(-dxTop, dyTop, dz) + val node1 = Float32Vector3D(-dxBottom, -dyBottom, -dz) + val node2 = Float32Vector3D(dxBottom, -dyBottom, -dz) + val node3 = Float32Vector3D(dxBottom, dyBottom, -dz) + val node4 = Float32Vector3D(-dxBottom, dyBottom, -dz) + val node5 = Float32Vector3D(-dxTop, -dyTop, dz) + val node6 = Float32Vector3D(dxTop, -dyTop, dz) + val node7 = Float32Vector3D(dxTop, dyTop, dz) + val node8 = Float32Vector3D(-dxTop, dyTop, dz) hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name) } diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index a1d4fbc4..f87cef77 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -2,6 +2,8 @@ plugins { id("space.kscience.gradle.mpp") } +val kmathVersion = "0.3.1" + kscience { jvm() js() @@ -11,6 +13,7 @@ kscience { } useCoroutines() dependencies { + api("space.kscience:kmath-geometry:0.3.1") api(projects.visionforgeCore) } dependencies(jvmTest) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt index 94ea5eaf..7b2679cd 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt @@ -36,8 +36,8 @@ public class ConeSegment( require(segments >= 4) { "The number of segments in cone is too small" } val angleStep = phi / (segments - 1) - fun shape(r: Float, z: Float): List = (0 until segments).map { i -> - Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) + fun shape(r: Float, z: Float): List = (0 until segments).map { i -> + Float32Vector3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } geometryBuilder.apply { @@ -53,8 +53,8 @@ public class ConeSegment( if (phi == PI2) { face4(bottomPoints.last(), bottomPoints[0], topPoints[0], topPoints.last()) } - val zeroBottom = Point3D(0f, 0f, -height / 2) - val zeroTop = Point3D(0f, 0f, +height / 2) + val zeroBottom = Float32Vector3D(0f, 0f, -height / 2) + val zeroTop = Float32Vector3D(0f, 0f, +height / 2) for (it in 1 until segments) { face(bottomPoints[it - 1], zeroBottom, bottomPoints[it]) face(topPoints[it - 1], topPoints[it], zeroTop) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt index 75ff2161..8ce9ba8c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt @@ -38,8 +38,8 @@ public class ConeSurface( require(segments >= 4) { "The number of segments in tube is too small" } val angleStep = phi / (segments - 1) - fun shape(r: Float, z: Float): List = (0 until segments).map { i -> - Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) + fun shape(r: Float, z: Float): List = (0 until segments).map { i -> + Float32Vector3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } geometryBuilder.apply { @@ -56,8 +56,8 @@ public class ConeSurface( face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last()) } if (bottomInnerRadius == 0f) { - val zeroBottom = Point3D(0f, 0f, -height / 2) - val zeroTop = Point3D(0f, 0f, height / 2) + val zeroBottom = Float32Vector3D(0f, 0f, -height / 2) + val zeroTop = Float32Vector3D(0f, 0f, height / 2) (1 until segments).forEach { face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt index 4d50c2c4..4fa174ac 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt @@ -7,7 +7,7 @@ import space.kscience.visionforge.setChild @Serializable @SerialName("solid.convex") -public class Convex(public val points: List) : SolidBase() +public class Convex(public val points: List) : SolidBase() public inline fun MutableVisionContainer.convex( name: String? = null, @@ -15,10 +15,10 @@ public inline fun MutableVisionContainer.convex( ): Convex = ConvexBuilder().apply(action).build().also { setChild(name, it) } public class ConvexBuilder { - private val points = ArrayList() + private val points = ArrayList() public fun point(x: Number, y: Number, z: Number) { - points.add(Point3D(x, y, z)) + points.add(Float32Vector3D(x, y, z)) } public fun build(): Convex { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index faec109b..1a6487b9 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -4,19 +4,23 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.names.Name -import space.kscience.visionforge.* +import space.kscience.kmath.geometry.component1 +import space.kscience.kmath.geometry.component2 +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin -public typealias Shape2D = List +public typealias Shape2D = List @Serializable -public class Shape2DBuilder(private val points: ArrayList = ArrayList()) { +public class Shape2DBuilder(private val points: ArrayList = ArrayList()) { public fun point(x: Number, y: Number) { - points.add(Point2D(x, y)) + points.add(Float32Vector2D(x, y)) } public infix fun Number.to(y: Number): Unit = point(this, y) @@ -38,7 +42,7 @@ public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Flo @Serializable @SerialName("solid.extrude") public class Extruded( - public val shape: List, + public val shape: List, public val layers: List, ) : SolidBase(), GeometrySolid { @@ -50,18 +54,18 @@ public class Extruded( /** * Expand the shape for specific layers */ - val layers: List> = layers.map { layer -> + val layers: List> = layers.map { layer -> shape.map { (x, y) -> val newX = layer.x + x * layer.scale val newY = layer.y + y * layer.scale - Point3D(newX, newY, layer.z) + Float32Vector3D(newX, newY, layer.z) } } if (layers.size < 2) error("Extruded shape requires more than one layer") var lowerLayer = layers.first() - var upperLayer: List + var upperLayer: List for (i in (1 until layers.size)) { upperLayer = layers[i] @@ -94,7 +98,7 @@ public class Extruded( } public class ExtrudeBuilder( - public var shape: List = emptyList(), + public var shape: List = emptyList(), public var layers: MutableList = ArrayList(), public val properties: MutableMeta = MutableMeta(), ) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt new file mode 100644 index 00000000..b9a2fdba --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt @@ -0,0 +1,71 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import space.kscience.kmath.geometry.GeometrySpace +import space.kscience.kmath.geometry.Vector2D +import space.kscience.kmath.operations.ScaleOperations +import kotlin.math.pow +import kotlin.math.sqrt + +@Serializable(Float32Euclidean2DSpace.VectorSerializer::class) +public interface Float32Vector2D: Vector2D + + +public object Float32Euclidean2DSpace : + GeometrySpace, + ScaleOperations { + + @Serializable + @SerialName("Float32Vector2D") + private data class Vector2DImpl( + override val x: Float, + override val y: Float, + ) : Float32Vector2D + + public object VectorSerializer : KSerializer { + private val proxySerializer = Vector2DImpl.serializer() + override val descriptor: SerialDescriptor get() = proxySerializer.descriptor + + override fun deserialize(decoder: Decoder): Float32Vector2D = decoder.decodeSerializableValue(proxySerializer) + + override fun serialize(encoder: Encoder, value: Float32Vector2D) { + val vector = value as? Vector2DImpl ?: Vector2DImpl(value.x, value.y) + encoder.encodeSerializableValue(proxySerializer, vector) + } + } + + public fun vector(x: Float, y: Float): Float32Vector2D = + Vector2DImpl(x, y) + + public fun vector(x: Number, y: Number): Float32Vector2D = + vector(x.toFloat(), y.toFloat()) + + override val zero: Float32Vector2D by lazy { vector(0f, 0f) } + + override fun norm(arg: Float32Vector2D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2)).toDouble() + + public fun Float32Vector2D.norm(): Double = norm(this) + + override fun Float32Vector2D.unaryMinus(): Float32Vector2D = vector(-x, -y) + + override fun Float32Vector2D.distanceTo(other: Float32Vector2D): Double = (this - other).norm() + + override fun add(left: Float32Vector2D, right: Float32Vector2D): Float32Vector2D = + vector(left.x + right.x, left.y + right.y) + + override fun scale(a: Float32Vector2D, value: Double): Float32Vector2D = + vector(a.x * value, a.y * value) + + override fun Float32Vector2D.dot(other: Float32Vector2D): Double = + (x * other.x + y * other.y).toDouble() + + public val xAxis: Float32Vector2D = vector(1.0, 0.0) + public val yAxis: Float32Vector2D = vector(0.0, 1.0) +} + +public fun Float32Vector2D(x: Number, y: Number): Float32Vector2D = Float32Euclidean2DSpace.vector(x, y) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean3DSpace.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean3DSpace.kt new file mode 100644 index 00000000..04b3df35 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean3DSpace.kt @@ -0,0 +1,113 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import space.kscience.kmath.geometry.GeometrySpace +import space.kscience.kmath.geometry.Vector3D +import space.kscience.kmath.operations.ScaleOperations +import kotlin.math.pow +import kotlin.math.sqrt + +@Serializable(Float32Euclidean3DSpace.VectorSerializer::class) +public interface Float32Vector3D: Vector3D + + +public object Float32Euclidean3DSpace : + GeometrySpace, + ScaleOperations{ + + @Serializable + @SerialName("Float32Vector3D") + private data class Vector3DImpl( + override val x: Float, + override val y: Float, + override val z: Float, + ) : Float32Vector3D + + public object VectorSerializer : KSerializer { + private val proxySerializer = Vector3DImpl.serializer() + override val descriptor: SerialDescriptor get() = proxySerializer.descriptor + + override fun deserialize(decoder: Decoder): Float32Vector3D = decoder.decodeSerializableValue(proxySerializer) + + override fun serialize(encoder: Encoder, value: Float32Vector3D) { + val vector = value as? Vector3DImpl ?: Vector3DImpl(value.x, value.y, value.z) + encoder.encodeSerializableValue(proxySerializer, vector) + } + } + + public fun vector(x: Float, y: Float, z: Float): Float32Vector3D = + Vector3DImpl(x, y, z) + + public fun vector(x: Number, y: Number, z: Number): Float32Vector3D = + vector(x.toFloat(), y.toFloat(), z.toFloat()) + + override val zero: Float32Vector3D by lazy { vector(0.0, 0.0, 0.0) } + + override fun norm(arg: Float32Vector3D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)).toDouble() + + public fun Float32Vector3D.norm(): Double = norm(this) + + override fun Float32Vector3D.unaryMinus(): Float32Vector3D = vector(-x, -y, -z) + + override fun Float32Vector3D.distanceTo(other: Float32Vector3D): Double = (this - other).norm() + + override fun add(left: Float32Vector3D, right: Float32Vector3D): Float32Vector3D = + vector(left.x + right.x, left.y + right.y, left.z + right.z) + + override fun scale(a: Float32Vector3D, value: Double): Float32Vector3D = + vector(a.x * value, a.y * value, a.z * value) + + override fun Float32Vector3D.dot(other: Float32Vector3D): Double = + (x * other.x + y * other.y + z * other.z).toDouble() + + private fun leviCivita(i: Int, j: Int, k: Int): Int = when { + // even permutation + i == 0 && j == 1 && k == 2 -> 1 + i == 1 && j == 2 && k == 0 -> 1 + i == 2 && j == 0 && k == 1 -> 1 + // odd permutations + i == 2 && j == 1 && k == 0 -> -1 + i == 0 && j == 2 && k == 1 -> -1 + i == 1 && j == 0 && k == 2 -> -1 + + else -> 0 + } + + /** + * Compute vector product of [first] and [second]. The basis is assumed to be right-handed. + */ + public fun vectorProduct( + first: Float32Vector3D, + second: Float32Vector3D, + ): Float32Vector3D { + var x = 0.0 + var y = 0.0 + var z = 0.0 + + for (j in (0..2)) { + for (k in (0..2)) { + x += leviCivita(0, j, k) * first[j] * second[k] + y += leviCivita(1, j, k) * first[j] * second[k] + z += leviCivita(2, j, k) * first[j] * second[k] + } + } + + return vector(x, y, z) + } + + /** + * Vector product in a right-handed basis + */ + public infix fun Float32Vector3D.cross(other: Float32Vector3D): Float32Vector3D = vectorProduct(this, other) + + public val xAxis: Float32Vector3D = vector(1.0, 0.0, 0.0) + public val yAxis: Float32Vector3D = vector(0.0, 1.0, 0.0) + public val zAxis: Float32Vector3D = vector(0.0, 0.0, 1.0) +} + +public fun Float32Vector3D(x: Number, y: Number, z: Number): Float32Vector3D = Float32Euclidean3DSpace.vector(x,y,z) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/GeometryBuilder.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/GeometryBuilder.kt index 3cfc5da9..ab24f8ce 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/GeometryBuilder.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/GeometryBuilder.kt @@ -13,17 +13,17 @@ public interface GeometryBuilder { * @param normal optional external normal to the face * @param meta optional additional platform-specific parameters like color or texture index */ - public fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = Meta.EMPTY) + public fun face(vertex1: Float32Vector3D, vertex2: Float32Vector3D, vertex3: Float32Vector3D, normal: Float32Vector3D? = null, meta: Meta = Meta.EMPTY) public fun build(): T } public fun GeometryBuilder<*>.face4( - vertex1: Point3D, - vertex2: Point3D, - vertex3: Point3D, - vertex4: Point3D, - normal: Point3D? = null, + vertex1: Float32Vector3D, + vertex2: Float32Vector3D, + vertex3: Float32Vector3D, + vertex4: Float32Vector3D, + normal: Float32Vector3D? = null, meta: Meta = Meta.EMPTY ) { face(vertex1, vertex2, vertex3, normal, meta) @@ -37,9 +37,9 @@ public interface GeometrySolid : Solid { public fun toGeometry(geometryBuilder: GeometryBuilder) } -public fun GeometryBuilder.cap(shape: List, normal: Point3D? = null) { +public fun GeometryBuilder.cap(shape: List, normal: Float32Vector3D? = null) { //FIXME won't work for non-convex shapes - val center = Point3D( + val center = Float32Vector3D( shape.map { it.x }.average(), shape.map { it.y }.average(), shape.map { it.z }.average() diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt index 92f11e1b..12e661eb 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt @@ -7,14 +7,14 @@ import space.kscience.visionforge.VisionBuilder import space.kscience.visionforge.setChild public interface Hexagon : GeometrySolid { - public val node1: Point3D - public val node2: Point3D - public val node3: Point3D - public val node4: Point3D - public val node5: Point3D - public val node6: Point3D - public val node7: Point3D - public val node8: Point3D + public val node1: Float32Vector3D + public val node2: Float32Vector3D + public val node3: Float32Vector3D + public val node4: Float32Vector3D + public val node5: Float32Vector3D + public val node6: Float32Vector3D + public val node7: Float32Vector3D + public val node8: Float32Vector3D override fun toGeometry(geometryBuilder: GeometryBuilder) { geometryBuilder.face4(node1, node4, node3, node2) @@ -41,14 +41,14 @@ public class Box( private inline val dy get() = ySize / 2 private inline val dz get() = zSize / 2 - override val node1: Point3D get() = Point3D(-dx, -dy, -dz) - override val node2: Point3D get() = Point3D(dx, -dy, -dz) - override val node3: Point3D get() = Point3D(dx, dy, -dz) - override val node4: Point3D get() = Point3D(-dx, dy, -dz) - override val node5: Point3D get() = Point3D(-dx, -dy, dz) - override val node6: Point3D get() = Point3D(dx, -dy, dz) - override val node7: Point3D get() = Point3D(dx, dy, dz) - override val node8: Point3D get() = Point3D(-dx, dy, dz) + override val node1: Float32Vector3D get() = Float32Vector3D(-dx, -dy, -dz) + override val node2: Float32Vector3D get() = Float32Vector3D(dx, -dy, -dz) + override val node3: Float32Vector3D get() = Float32Vector3D(dx, dy, -dz) + override val node4: Float32Vector3D get() = Float32Vector3D(-dx, dy, -dz) + override val node5: Float32Vector3D get() = Float32Vector3D(-dx, -dy, dz) + override val node6: Float32Vector3D get() = Float32Vector3D(dx, -dy, dz) + override val node7: Float32Vector3D get() = Float32Vector3D(dx, dy, dz) + override val node8: Float32Vector3D get() = Float32Vector3D(-dx, dy, dz) } @VisionBuilder @@ -63,26 +63,26 @@ public inline fun MutableVisionContainer.box( @Serializable @SerialName("solid.hexagon") public class GenericHexagon( - override val node1: Point3D, - override val node2: Point3D, - override val node3: Point3D, - override val node4: Point3D, - override val node5: Point3D, - override val node6: Point3D, - override val node7: Point3D, - override val node8: Point3D, + override val node1: Float32Vector3D, + override val node2: Float32Vector3D, + override val node3: Float32Vector3D, + override val node4: Float32Vector3D, + override val node5: Float32Vector3D, + override val node6: Float32Vector3D, + override val node7: Float32Vector3D, + override val node8: Float32Vector3D, ) : SolidBase(), Hexagon @VisionBuilder public inline fun MutableVisionContainer.hexagon( - node1: Point3D, - node2: Point3D, - node3: Point3D, - node4: Point3D, - node5: Point3D, - node6: Point3D, - node7: Point3D, - node8: Point3D, + node1: Float32Vector3D, + node2: Float32Vector3D, + node3: Float32Vector3D, + node4: Float32Vector3D, + node5: Float32Vector3D, + node6: Float32Vector3D, + node7: Float32Vector3D, + node8: Float32Vector3D, name: String? = null, action: Hexagon.() -> Unit = {}, ): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt index 95aca618..beeb4eb3 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -70,6 +70,6 @@ public fun MutableVisionContainer.pointLight( name: String? = null, block: PointLightSource.() -> Unit = {}, ): PointLightSource = PointLightSource().apply(block).also { - it.position = Point3D(x, y, z) + it.position = Float32Vector3D(x, y, z) setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt index 0f366dbe..1681f44a 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt @@ -3,11 +3,14 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.number -import space.kscience.visionforge.* +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.root +import space.kscience.visionforge.setChild @Serializable @SerialName("solid.line") -public class PolyLine(public val points: List) : SolidBase() { +public class PolyLine(public val points: List) : SolidBase() { //var lineType by string() public var thickness: Number by properties.root(inherit = false, includeStyles = true).number { DEFAULT_THICKNESS } @@ -19,7 +22,7 @@ public class PolyLine(public val points: List) : SolidBase() @VisionBuilder public fun MutableVisionContainer.polyline( - vararg points: Point3D, + vararg points: Float32Vector3D, name: String? = null, action: PolyLine.() -> Unit = {}, ): PolyLine = PolyLine(points.toList()).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index f99e4bbf..8bd64336 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -174,18 +174,21 @@ internal fun point( defaultX: Float, defaultY: Float = defaultX, defaultZ: Float = defaultX, -): ReadWriteProperty = - object : ReadWriteProperty { - override fun getValue(thisRef: Solid, property: KProperty<*>): Point3D? { +): ReadWriteProperty = + object : ReadWriteProperty { + override fun getValue(thisRef: Solid, property: KProperty<*>): Float32Vector3D? { val item = thisRef.properties.own?.get(name) ?: return null - return object : Point3D { + //using dynamic property accessor because values could change + return object : Float32Vector3D { override val x: Float get() = item[X_KEY]?.float ?: defaultX override val y: Float get() = item[Y_KEY]?.float ?: defaultY override val z: Float get() = item[Z_KEY]?.float ?: defaultZ + + override fun toString(): String = item.toString() } } - override fun setValue(thisRef: Solid, property: KProperty<*>, value: Point3D?) { + override fun setValue(thisRef: Solid, property: KProperty<*>, value: Float32Vector3D?) { if (value == null) { thisRef.properties.setProperty(name, null) } else { @@ -196,9 +199,9 @@ internal fun point( } } -public var Solid.position: Point3D? by point(POSITION_KEY, 0f) -public var Solid.rotation: Point3D? by point(ROTATION_KEY, 0f) -public var Solid.scale: Point3D? by point(SCALE_KEY, 1f) +public var Solid.position: Float32Vector3D? by point(POSITION_KEY, 0f) +public var Solid.rotation: Float32Vector3D? by point(ROTATION_KEY, 0f) +public var Solid.scale: Float32Vector3D? by point(SCALE_KEY, 1f) public var Solid.x: Number by float(X_POSITION_KEY, 0f) public var Solid.y: Number by float(Y_POSITION_KEY, 0f) @@ -208,10 +211,10 @@ public var Solid.rotationX: Number by float(X_ROTATION_KEY, 0f) public var Solid.rotationY: Number by float(Y_ROTATION_KEY, 0f) public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f) -public var Solid.quaternion: Pair? +public var Solid.quaternion: Pair? get() = properties.getValue(Solid.QUATERNION_KEY)?.list?.let { require(it.size == 4) { "Quaternion must be a number array of 4 elements" } - it[0].float to Point3D(it[1].float, it[2].float, it[3].float) + it[0].float to Float32Vector3D(it[1].float, it[2].float, it[3].float) } set(value) { properties.setValue( diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 4900fc1f..ab9fde1e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -51,6 +51,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer(), GeometrySolid { override fun toGeometry(geometryBuilder: GeometryBuilder) { - fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Point3D { + fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Float32Vector3D { // This transformation matches three.js sphere implementation val y = r * cos(theta) val z = r * sin(theta) * sin(phi) val x = -r * sin(theta) * cos(phi) - return Point3D(x, y, z) + return Float32Vector3D(x, y, z) } val segments = this.detail ?: 32 diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt index bb630772..fa025df2 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt @@ -27,12 +27,12 @@ public class SphereLayer( require(outerRadius > 0) { "Outer radius must be positive" } require(innerRadius >= 0) { "inner radius must be non-negative" } - fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Point3D { + fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Float32Vector3D { // This transformation matches three.js sphere implementation val y = r * cos(theta) val z = r * sin(theta) * sin(phi) val x = -r * sin(theta) * cos(phi) - return Point3D(x, y, z) + return Float32Vector3D(x, y, z) } val segments = detail ?: 32 diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt index e9c9c146..58c3021d 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt @@ -1,10 +1,5 @@ package space.kscience.visionforge.solid -import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaProvider import space.kscience.dataforge.meta.float @@ -13,105 +8,48 @@ import space.kscience.visionforge.solid.Solid.Companion.X_KEY import space.kscience.visionforge.solid.Solid.Companion.Y_KEY import space.kscience.visionforge.solid.Solid.Companion.Z_KEY import kotlin.math.PI -import kotlin.math.pow -import kotlin.math.sqrt public const val PI2: Float = 2 * PI.toFloat() -@Serializable -public data class Point2D(public var x: Float, public var y: Float) - -public fun Point2D(x: Number, y: Number): Point2D = Point2D(x.toFloat(), y.toFloat()) - -public fun Point2D.toMeta(): Meta = Meta { +public fun Float32Vector2D.toMeta(): Meta = Meta { X_KEY put x Y_KEY put y } -internal fun Meta.point2D(): Point2D = Point2D(this["x"].float ?: 0f, this["y"].float ?: 0f) - -@Serializable(Point3DSerializer::class) -public interface Point3D { - public val x: Float - public val y: Float - public val z: Float - - public companion object { - public val ZERO: Point3D = Point3D(0.0, 0.0, 0.0) - public val ONE: Point3D = Point3D(1.0, 1.0, 1.0) - } -} - -@Suppress("SERIALIZER_TYPE_INCOMPATIBLE") -@Serializable(Point3DSerializer::class) -public interface MutablePoint3D : Point3D { - override var x: Float - override var y: Float - override var z: Float -} - -@Serializable -private class Point3DImpl(override var x: Float, override var y: Float, override var z: Float) : MutablePoint3D - -internal object Point3DSerializer : KSerializer { - - override val descriptor: SerialDescriptor = Point3DImpl.serializer().descriptor - - override fun deserialize(decoder: Decoder): MutablePoint3D = decoder.decodeSerializableValue(Point3DImpl.serializer()) - - override fun serialize(encoder: Encoder, value: Point3D) { - val impl: Point3DImpl = (value as? Point3DImpl) ?: Point3DImpl(value.x, value.y, value.z) - encoder.encodeSerializableValue(Point3DImpl.serializer(), impl) - } -} - -public fun Point3D(x: Number, y: Number, z: Number): Point3D = Point3DImpl(x.toFloat(), y.toFloat(), z.toFloat()) - -public operator fun Point3D.plus(other: Point3D): Point3D = Point3D( - this.x + other.x, - this.y + other.y, - this.z + other.z -) - -public operator fun Point3D.minus(other: Point3D): Point3D = Point3D( - this.x - other.x, - this.y - other.y, - this.z - other.z -) - -public operator fun Point3D.unaryMinus(): Point3D = Point3D( - -x, - -y, - -z -) - -public infix fun Point3D.cross(other: Point3D): Point3D = Point3D( - y * other.z - z * other.y, - z * other.x - x * other.z, - x * other.y - y * other.x +internal fun Meta.toVector2D(): Float32Vector2D = + Float32Vector2D(this["x"].float ?: 0f, this["y"].float ?: 0f) + +//@Suppress("SERIALIZER_TYPE_INCOMPATIBLE") +//@Serializable(Point3DSerializer::class) +//public interface MutablePoint3D : Float32Vector3D { +// override var x: Float +// override var y: Float +// override var z: Float +//} +// +// +//public fun MutablePoint3D.normalizeInPlace() { +// val norm = sqrt(x.pow(2) + y.pow(2) + z.pow(2)) +// x /= norm +// y /= norm +// z /= norm +//} + +internal fun MetaProvider.point3D(default: Float = 0f) = Float32Euclidean3DSpace.vector( + getMeta(X_KEY).float ?: default, + getMeta(Y_KEY).float ?: default, + getMeta(Z_KEY).float ?: default ) -public fun MutablePoint3D.normalizeInPlace() { - val norm = sqrt(x.pow(2) + y.pow(2) + z.pow(2)) - x /= norm - y /= norm - z /= norm -} - -internal fun MetaProvider.point3D(default: Float = 0f) = object : Point3D { - override val x: Float by float(default) - override val y: Float by float(default) - override val z: Float by float(default) -} -public fun Point3D.toMeta(): Meta = Meta { +public fun Float32Vector3D.toMeta(): Meta = Meta { X_KEY put x Y_KEY put y Z_KEY put z } -internal fun Meta.toVector(default: Float = 0f) = Point3D( +internal fun Meta.toVector3D(default: Float = 0f) = Float32Vector3D( this[X_KEY].float ?: default, this[Y_KEY].float ?: default, this[Z_KEY].float ?: default diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt index 79274e62..8d838f6b 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt @@ -2,13 +2,10 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.meta.getIndexed import space.kscience.dataforge.meta.toMeta -import space.kscience.dataforge.misc.DFExperimental import kotlin.test.Test import kotlin.test.assertEquals class ConvexTest { - @OptIn(DFExperimental::class) - @Suppress("UNUSED_VARIABLE") @Test fun testConvexBuilder() { val group = testSolids.solidGroup { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt index e75e4847..7a5f3c49 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt @@ -1,15 +1,14 @@ package space.kscience.visionforge.solid.three +import space.kscience.dataforge.meta.Meta +import space.kscience.visionforge.solid.Float32Euclidean3DSpace +import space.kscience.visionforge.solid.Float32Vector3D +import space.kscience.visionforge.solid.GeometryBuilder import three.core.BufferGeometry import three.core.Float32BufferAttribute import three.math.Vector3 -import space.kscience.dataforge.meta.Meta -import space.kscience.visionforge.solid.GeometryBuilder -import space.kscience.visionforge.solid.Point3D -import space.kscience.visionforge.solid.cross -import space.kscience.visionforge.solid.minus -internal fun Point3D.toVector() = Vector3(x, y, z) +internal fun Float32Vector3D.toVector() = Vector3(x, y, z) internal fun MutableList.add(vararg values: T) { values.forEach { @@ -27,10 +26,10 @@ public class ThreeGeometryBuilder : GeometryBuilder { private val normals = ArrayList() // private val colors = ArrayList() - private val vertexCache = HashMap() + private val vertexCache = HashMap() private var counter: Short = -1 - private fun vertex(vertex: Point3D, normal: Point3D): Short = vertexCache.getOrPut(vertex) { + private fun vertex(vertex: Float32Vector3D, normal: Float32Vector3D): Short = vertexCache.getOrPut(vertex) { //add vertex and update cache if needed positions.add(vertex.x, vertex.y, vertex.z) normals.add(normal.x, vertex.y, vertex.z) @@ -39,8 +38,14 @@ public class ThreeGeometryBuilder : GeometryBuilder { counter } - override fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D?, meta: Meta) { - val actualNormal: Point3D = normal ?: ((vertex3 - vertex2) cross (vertex1 - vertex2)) + override fun face( + vertex1: Float32Vector3D, + vertex2: Float32Vector3D, + vertex3: Float32Vector3D, + normal: Float32Vector3D?, + meta: Meta, + ) = with(Float32Euclidean3DSpace) { + val actualNormal: Float32Vector3D = normal ?: ((vertex3 - vertex2) cross (vertex1 - vertex2)) indices.add( vertex(vertex1, actualNormal), vertex(vertex2, actualNormal), diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt index 99e7fba6..ef4eb39b 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt @@ -8,6 +8,7 @@ import kotlin.test.Test class TestServerExtensions { + @Suppress("UNUSED_VARIABLE") @Test fun testServerHeader(){ val string = createHTML().apply { From 442fcb6c5b91def1cab21f91d99f27befc9a5470 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 3 Jun 2023 18:29:04 +0300 Subject: [PATCH 059/112] Use KMath-geometry for solids --- .../kscience/visionforge/gdml/gdmlLoader.kt | 1 + .../space/kscience/visionforge/solid/Solid.kt | 42 ++++++++++++------- .../solid/transform/RemoveSingleChild.kt | 6 +-- .../visionforge/solid/three/ThreeFactory.kt | 10 ++--- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index e17248ad..230af4b0 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -6,6 +6,7 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.gdml.* +import space.kscience.kmath.geometry.RotationOrder import space.kscience.visionforge.* import space.kscience.visionforge.html.VisionOutput import space.kscience.visionforge.solid.* diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 8bd64336..e0140fe4 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -8,6 +8,10 @@ import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.geometry.RotationOrder +import space.kscience.kmath.geometry.fromEuler +import space.kscience.kmath.geometry.radians import space.kscience.visionforge.* import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY @@ -122,15 +126,6 @@ public var Solid.layer: Int // Common properties -public enum class RotationOrder { - XYZ, - YZX, - ZXY, - XZY, - YXZ, - ZYX -} - /** * Rotation order */ @@ -211,25 +206,42 @@ public var Solid.rotationX: Number by float(X_ROTATION_KEY, 0f) public var Solid.rotationY: Number by float(Y_ROTATION_KEY, 0f) public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f) -public var Solid.quaternion: Pair? +/** + * Raw quaternion value defined in properties + */ +public var Solid.quaternionValue: Quaternion? get() = properties.getValue(Solid.QUATERNION_KEY)?.list?.let { require(it.size == 4) { "Quaternion must be a number array of 4 elements" } - it[0].float to Float32Vector3D(it[1].float, it[2].float, it[3].float) + Quaternion(it[0].float, it[1].float, it[2].float, it[3].float) } set(value) { properties.setValue( Solid.QUATERNION_KEY, value?.let { ListValue( - value.first, - value.second.x, - value.second.y, - value.second.z + value.w, + value.x, + value.y, + value.z ) } ) } +/** + * Quaternion value including information from euler angles + */ +public var Solid.quaternion: Quaternion + get() = quaternionValue ?: Quaternion.fromEuler( + rotationX.radians, + rotationY.radians, + rotationZ.radians, + rotationOrder + ) + set(value) { + quaternionValue = value + } + //public var Solid.quaternion: Quaternion? // get() = meta[Solid::quaternion.name]?.value?.doubleArray?.let { Quaternion(it) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index 6a309d94..d2667e76 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -3,6 +3,7 @@ package space.kscience.visionforge.solid.transform import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName +import space.kscience.kmath.complex.QuaternionField import space.kscience.visionforge.root import space.kscience.visionforge.solid.* @@ -14,10 +15,7 @@ internal fun Solid.updateFrom(other: Solid): Solid { x += other.x y += other.y z += other.y - if(quaternion != null || other.quaternion != null) TODO("Quaternion support not implemented") - rotationX += other.rotationX - rotationY += other.rotationY - rotationZ += other.rotationZ + quaternion = with(QuaternionField) { other.quaternion * quaternion } scaleX *= other.scaleX scaleY *= other.scaleY scaleZ *= other.scaleZ diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index a0852c72..ec42a3c7 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -49,15 +49,15 @@ public fun Object3D.updatePosition(vision: Vision) { // } else { // setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) // } - val quaternion = vision.quaternion + val quaternion = vision.quaternionValue if (quaternion != null) { setRotationFromQuaternion( Quaternion( - quaternion.second.x, - quaternion.second.y, - quaternion.second.z, - quaternion.first + quaternion.x, + quaternion.y, + quaternion.z, + quaternion.w ) ) } else { From 8204eb63c3fd03b96462c4ea6d8126b34e2b0ad3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 3 Jun 2023 20:49:57 +0300 Subject: [PATCH 060/112] Make threeJS object generation suspend --- .../visionforge/solid/demo/VariableBox.kt | 2 +- .../solid/three/ThreeAmbientLightFactory.kt | 2 +- .../visionforge/solid/three/ThreeCanvas.kt | 12 +++++++----- .../solid/three/ThreeCanvasLabelFactory.kt | 2 +- .../solid/three/ThreeCompositeFactory.kt | 2 +- .../visionforge/solid/three/ThreeFactory.kt | 10 +--------- .../visionforge/solid/three/ThreeJsVision.kt | 17 +++++++++++++++-- .../solid/three/ThreeLabelFactory.kt | 2 +- .../visionforge/solid/three/ThreeLineFactory.kt | 10 +++++----- .../visionforge/solid/three/ThreeMeshFactory.kt | 2 +- .../solid/three/ThreeMeshLineFactory.kt | 2 +- .../visionforge/solid/three/ThreePlugin.kt | 3 +-- .../solid/three/ThreePointLightFactory.kt | 2 +- .../solid/three/ThreeReferenceFactory.kt | 2 +- .../solid/three/ThreeSmartLineFactory.kt | 2 +- .../kscience/visionforge/solid/three/three.kt | 4 ---- 16 files changed, 39 insertions(+), 37 deletions(-) diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index 15e53129..701df81b 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -25,7 +25,7 @@ internal fun SolidGroup.varBox( internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision() { - override fun render(three: ThreePlugin): Object3D { + override suspend fun render(three: ThreePlugin): Object3D { val geometry = BoxGeometry(xSize, ySize, 1) val material = ThreeMaterials.DEFAULT.clone() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt index 3f8e251c..f15f2c78 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt @@ -14,7 +14,7 @@ import kotlin.reflect.KClass public object ThreeAmbientLightFactory : ThreeFactory { override val type: KClass get() = AmbientLightSource::class - override fun build(three: ThreePlugin, vision: AmbientLightSource, observe: Boolean): AmbientLight { + override suspend fun build(three: ThreePlugin, vision: AmbientLightSource, observe: Boolean): AmbientLight { val res = AmbientLight().apply { color = vision.color.threeColor() ?: Color(0x404040) intensity = vision.intensity.toDouble() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index 4e6935a8..6ecdad78 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -1,6 +1,7 @@ package space.kscience.visionforge.solid.three import kotlinx.browser.window +import kotlinx.coroutines.launch import org.w3c.dom.Element import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.Node @@ -264,11 +265,12 @@ public class ThreeCanvas( scene.findChild("@root".asName())?.let { scene.remove(it) } root?.dispose() } - - val object3D = three.buildObject3D(vision) - object3D.name = "@root" - scene.add(object3D) - root = object3D + three.context.launch { + val object3D = three.buildObject3D(vision) + object3D.name = "@root" + scene.add(object3D) + root = object3D + } } private var selected: Object3D? = null diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index b9f2a7d2..93bf170b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -22,7 +22,7 @@ import kotlin.reflect.KClass public object ThreeCanvasLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { val canvas = document.createElement("canvas") as HTMLCanvasElement canvas.width = 200 canvas.height = 200 diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index fe40022d..e6e9641c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -38,7 +38,7 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory override val type: KClass get() = Composite::class - override fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh { + override suspend fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh { val first = three.buildObject3D(vision.first, observe).takeIfMesh() ?: error("First part of composite is not a mesh") val second = three.buildObject3D(vision.second, observe).takeIfMesh() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index ec42a3c7..7c87a0f3 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -26,7 +26,7 @@ public interface ThreeFactory { * Build an [Object3D] from [vision]. * @param observe if false, does not observe the changes in [vision] after render (useful for statics). */ - public fun build(three: ThreePlugin, vision: T, observe: Boolean = true): Object3D + public suspend fun build(three: ThreePlugin, vision: T, observe: Boolean = true): Object3D public companion object { public const val TYPE: String = "threeFactory" @@ -41,14 +41,6 @@ public fun Object3D.updatePosition(vision: Vision) { if (vision is Solid) { position.set(vision.x, vision.y, vision.z) -// val quaternion = obj.quaternion -// -// if (quaternion != null) { -// val (x, y, z, w) = quaternion -// setRotationFromQuaternion(Quaternion(x, y, z, w)) -// } else { -// setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) -// } val quaternion = vision.quaternionValue if (quaternion != null) { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt index 3829698e..dcb328a1 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt @@ -1,11 +1,24 @@ package space.kscience.visionforge.solid.three -import three.core.Object3D +import org.w3c.dom.url.URL import space.kscience.visionforge.solid.SolidBase +import three.core.Object3D /** * A custom visual object that has its own Three.js renderer */ public abstract class ThreeJsVision : SolidBase() { - public abstract fun render(three: ThreePlugin): Object3D + public abstract suspend fun render(three: ThreePlugin): Object3D +} + +public class ThreeStlVision(val url: URL): ThreeJsVision(){ + override suspend fun render(three: ThreePlugin): Object3D { +// suspendCoroutine { +// +// } +// STLLoader() + + TODO() + } + } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index e168c1d2..45068a3a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -17,7 +17,7 @@ import kotlin.reflect.KClass public object ThreeLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { val textGeo = TextBufferGeometry(vision.text, jso { font = vision.fontFamily size = 20 diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index adf4ce0d..45325430 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -1,22 +1,22 @@ package space.kscience.visionforge.solid.three -import three.core.BufferGeometry -import three.core.Object3D -import three.math.Color -import three.objects.LineSegments import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.color import space.kscience.visionforge.solid.string import space.kscience.visionforge.solid.three.ThreeMaterials.DEFAULT_LINE_COLOR +import three.core.BufferGeometry +import three.core.Object3D +import three.math.Color +import three.objects.LineSegments import kotlin.math.ceil import kotlin.reflect.KClass public object ThreeLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { val geometry = BufferGeometry().apply { setFromPoints(Array((vision.points.size - 1) * 2) { vision.points[ceil(it / 2.0).toInt()].toVector() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index 30f3034b..ab067326 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -26,7 +26,7 @@ public abstract class ThreeMeshFactory( */ public abstract fun buildGeometry(obj: T): BufferGeometry - override fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh { + override suspend fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh { val geometry = buildGeometry(vision) val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt index 3d9b4c3b..4a94823b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt @@ -15,7 +15,7 @@ import kotlin.reflect.KClass public object ThreeMeshLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { val geometry = MeshLine( Array((vision.points.size - 1) * 2) { vision.points[ceil(it / 2.0).toInt()].toVector() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 064597e6..17249648 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -6,7 +6,6 @@ import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.update import space.kscience.dataforge.names.* import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision @@ -47,7 +46,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { as ThreeFactory? } - public fun buildObject3D(vision: Solid, observe: Boolean = true): Object3D = when (vision) { + public suspend fun buildObject3D(vision: Solid, observe: Boolean = true): Object3D = when (vision) { is ThreeJsVision -> vision.render(this) is SolidReference -> ThreeReferenceFactory.build(this, vision, observe) is SolidGroup -> { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt index fdd2e019..b0a0bfeb 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt @@ -13,7 +13,7 @@ public object ThreePointLightFactory : ThreeFactory { private val DEFAULT_COLOR = Color(0x404040) - override fun build(three: ThreePlugin, vision: PointLightSource, observe: Boolean): PointLight { + override suspend fun build(three: ThreePlugin, vision: PointLightSource, observe: Boolean): PointLight { val res = PointLight().apply { matrixAutoUpdate = false color = vision.color.threeColor() ?: DEFAULT_COLOR diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index 405956f8..beb59df8 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -31,7 +31,7 @@ public object ThreeReferenceFactory : ThreeFactory { } } - override fun build(three: ThreePlugin, vision: SolidReference, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: SolidReference, observe: Boolean): Object3D { val template = vision.prototype val cachedObject = cache.getOrPut(template) { three.buildObject3D(template) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt index 2e7329da..6f2ee1a5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt @@ -7,7 +7,7 @@ import kotlin.reflect.KClass public object ThreeSmartLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { return if (vision.thickness == 1.0) { ThreeLineFactory.build(three, vision, observe) } else { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt index 9c9d5b2b..f3fc0594 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt @@ -12,14 +12,10 @@ import three.math.Vector3 import three.objects.Mesh import three.textures.Texture import kotlin.contracts.contract -import kotlin.math.PI public val Meta.vector: Vector3 get() = Vector3(this["x"].float ?: 0f, this["y"].float ?: 0f, this["z"].float ?: 0f) -internal fun Double.toRadians() = this * PI / 180 - - internal fun Any.dispose() { when (this) { is BufferGeometry -> dispose() From 2b70afdb869a7f812762d133877fea9f65ea1a81 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 4 Jun 2023 20:58:03 +0300 Subject: [PATCH 061/112] Suspended renderers and property change listeners --- demo/js-playground/build.gradle.kts | 2 +- demo/solid-showcase/build.gradle.kts | 14 +++---- .../kscience/visionforge/solid/demo/demo.kt | 4 ++ .../space/kscience/visionforge/Vision.kt | 2 +- .../kscience/visionforge/solid/StlVision.kt | 25 ++++++++++++ .../solid/three/ThreeBoxFactory.kt | 2 +- .../solid/three/ThreeConeFactory.kt | 2 +- .../solid/three/ThreeConvexFactory.kt | 2 +- .../visionforge/solid/three/ThreeFactory.kt | 2 +- .../visionforge/solid/three/ThreeJsVision.kt | 13 ------- .../solid/three/ThreeMeshFactory.kt | 3 +- .../visionforge/solid/three/ThreePlugin.kt | 1 + .../solid/three/ThreeSphereFactory.kt | 2 +- .../solid/three/ThreeStlFactory.kt | 38 +++++++++++++++++++ .../three/external/loaders/STLLoader.kt | 13 +++++-- 15 files changed, 93 insertions(+), 32 deletions(-) create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/StlVision.kt create mode 100644 visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index 603b921a..94835588 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -8,7 +8,7 @@ kscience{ kotlin{ explicitApi = null - js(IR){ + js{ useCommonJs() browser { binaries.executable() diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index 8f1c370b..05a02260 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -1,14 +1,14 @@ plugins { id("space.kscience.gradle.mpp") - application +// application } kscience { useCoroutines() - jvm { - withJava() + jvm() + js{ + binaries.executable() } - js() dependencies { implementation(projects.visionforgeSolid) implementation(projects.visionforgeGdml) @@ -21,6 +21,6 @@ kscience { kotlin.explicitApi = null -application { - mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt") -} \ No newline at end of file +//application { +// mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt") +//} \ No newline at end of file diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index 5fdec43b..6f2cb61f 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -150,6 +150,10 @@ fun VisionLayout.showcase() { z = 26 } } + + demo("STL", "STL loaded from URL"){ + stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl") + } } fun VisionLayout.showcaseCSG() { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index aa698409..ce5f588f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -67,7 +67,7 @@ public var Vision.visible: Boolean? */ public fun Vision.onPropertyChange( scope: CoroutineScope? = manager?.context, - callback: (Name) -> Unit + callback: suspend (Name) -> Unit ): Job = properties.changes.onEach { callback(it) }.launchIn(scope ?: error("Orphan Vision can't observe properties")) \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/StlVision.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/StlVision.kt new file mode 100644 index 00000000..8c975c47 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/StlVision.kt @@ -0,0 +1,25 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild + + +public sealed class StlVision: SolidBase() + +@Serializable +@SerialName("solid.stl.url") +public class StlUrlVision(public val url: String) : StlVision() + +@Serializable +@SerialName("solid.stl.binary") +public class StlBinaryVision(public val data: ByteArray) : StlVision() + +@VisionBuilder +public inline fun MutableVisionContainer.stl( + url: String, + name: String? = null, + action: StlVision.() -> Unit = {}, +): StlVision = StlUrlVision(url).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt index 21c52198..d6840f75 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt @@ -5,7 +5,7 @@ import space.kscience.visionforge.solid.detail import three.geometries.BoxGeometry public object ThreeBoxFactory : ThreeMeshFactory(Box::class) { - override fun buildGeometry(obj: Box): BoxGeometry = + override suspend fun buildGeometry(obj: Box): BoxGeometry = obj.detail?.let { detail -> BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail) } ?: BoxGeometry(obj.xSize, obj.ySize, obj.zSize) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt index 6b2db845..bcc147c7 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt @@ -8,7 +8,7 @@ import kotlin.math.PI import kotlin.math.pow public object ThreeConeFactory : ThreeMeshFactory(ConeSegment::class) { - override fun buildGeometry(obj: ConeSegment): BufferGeometry { + override suspend fun buildGeometry(obj: ConeSegment): BufferGeometry { val cylinder = obj.detail?.let { val segments = it.toDouble().pow(0.5).toInt() CylinderGeometry( diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt index 83115b13..b772c1bf 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt @@ -4,7 +4,7 @@ import space.kscience.visionforge.solid.Convex import three.external.geometries.ConvexBufferGeometry public object ThreeConvexFactory : ThreeMeshFactory(Convex::class) { - override fun buildGeometry(obj: Convex): ConvexBufferGeometry { + override suspend fun buildGeometry(obj: Convex): ConvexBufferGeometry { val vectors = obj.points.map { it.toVector() }.toTypedArray() return ConvexBufferGeometry(vectors) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 7c87a0f3..dcf94717 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -84,7 +84,7 @@ public fun Object3D.updateProperty(source: Vision, propertyName: Name) { * Generic factory for elements which provide inside geometry builder */ public object ThreeShapeFactory : ThreeMeshFactory(GeometrySolid::class) { - override fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply { + override suspend fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply { obj.toGeometry(this) }.build() } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt index dcb328a1..6f6e166a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt @@ -1,6 +1,5 @@ package space.kscience.visionforge.solid.three -import org.w3c.dom.url.URL import space.kscience.visionforge.solid.SolidBase import three.core.Object3D @@ -10,15 +9,3 @@ import three.core.Object3D public abstract class ThreeJsVision : SolidBase() { public abstract suspend fun render(three: ThreePlugin): Object3D } - -public class ThreeStlVision(val url: URL): ThreeJsVision(){ - override suspend fun render(three: ThreePlugin): Object3D { -// suspendCoroutine { -// -// } -// STLLoader() - - TODO() - } - -} diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index ab067326..06224bbb 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -21,10 +21,11 @@ import kotlin.reflect.KClass public abstract class ThreeMeshFactory( override val type: KClass, ) : ThreeFactory { + /** * Build a geometry for an object */ - public abstract fun buildGeometry(obj: T): BufferGeometry + public abstract suspend fun buildGeometry(obj: T): BufferGeometry override suspend fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh { val geometry = buildGeometry(vision) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 17249648..e2af8c30 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -37,6 +37,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory objectFactories[PointLightSource::class] = ThreePointLightFactory + objectFactories[StlVision::class] = ThreeStlFactory } @Suppress("UNCHECKED_CAST") diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt index d738c073..9753f9ad 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt @@ -6,7 +6,7 @@ import three.core.BufferGeometry import three.geometries.SphereGeometry public object ThreeSphereFactory : ThreeMeshFactory(Sphere::class) { - override fun buildGeometry(obj: Sphere): BufferGeometry { + override suspend fun buildGeometry(obj: Sphere): BufferGeometry { return obj.detail?.let { detail -> SphereGeometry( radius = obj.radius, diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt new file mode 100644 index 00000000..d21389aa --- /dev/null +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt @@ -0,0 +1,38 @@ +package space.kscience.visionforge.solid.three + +import org.khronos.webgl.ArrayBuffer +import org.khronos.webgl.Int8Array +import space.kscience.visionforge.solid.StlBinaryVision +import space.kscience.visionforge.solid.StlUrlVision +import space.kscience.visionforge.solid.StlVision +import three.core.BufferGeometry +import three.external.loaders.STLLoader +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + +fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast() + +public object ThreeStlFactory : ThreeMeshFactory(StlVision::class) { + + private val loader = STLLoader().apply { + requestHeader = listOf("Access-Control-Allow-Origin: *") + } + + override suspend fun buildGeometry(obj: StlVision): BufferGeometry = when (obj) { + is StlBinaryVision -> loader.parse(obj.data) + is StlUrlVision -> suspendCoroutine { continuation -> + loader.load( + url = obj.url, + onLoad = { + continuation.resume(it) + }, + onError = { + continuation.resumeWithException(RuntimeException("Failed to load STL object from ${obj.url}")) + } + ) + } + } + + +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt b/visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt index 5fa253ab..e3e6133f 100644 --- a/visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt +++ b/visionforge-threejs/src/main/kotlin/three/external/loaders/STLLoader.kt @@ -22,17 +22,19 @@ * THE SOFTWARE. */ -@file:JsModule("three") +@file:JsModule("three/examples/jsm/loaders/STLLoader.js") @file:JsNonModule package three.external.loaders +import org.khronos.webgl.ArrayBuffer import org.w3c.xhr.XMLHttpRequest import three.core.BufferGeometry -import three.core.Object3D external class STLLoader { + var requestHeader: List + fun load( url: String, onLoad: (BufferGeometry) -> Unit, @@ -40,7 +42,10 @@ external class STLLoader { onError: () -> Unit = definedExternally ) - fun parse(data: String): Object3D - fun parse(data: ByteArray): Object3D + fun parse(data: String): BufferGeometry + + fun parse(data: ByteArray): BufferGeometry + + fun parse(data: ArrayBuffer): BufferGeometry } \ No newline at end of file From a695e5e7c9da730a41ee97049f6c67ed6a702f5e Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 6 Jun 2023 09:52:46 +0300 Subject: [PATCH 062/112] Use K2 --- gradle.properties | 1 + visionforge-gdml/build.gradle.kts | 1 + 2 files changed, 2 insertions(+) diff --git a/gradle.properties b/gradle.properties index 39926f4b..9b345a25 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,4 +7,5 @@ org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G toolsVersion=0.14.9-kotlin-1.9.0-Beta-2 +kotlin.experimental.tryK2=true org.jetbrains.compose.experimental.jscanvas.enabled=true \ No newline at end of file diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index cdf4ad47..c1c86059 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -10,6 +10,7 @@ kscience { dependencies { api(projects.visionforgeSolid) api("space.kscience:gdml:0.5.0") + implementation("com.github.h0tk3y.betterParse:better-parse:0.4.4") } dependencies(jvmTest) { implementation(spclibs.logback.classic) From 20851baaf521a9de883ae89deefad27c62854d5a Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 6 Jun 2023 18:43:18 +0300 Subject: [PATCH 063/112] Make Axes a separate object --- demo/playground/src/jvmMain/kotlin/axes.kt | 22 ++++++++++++++++ .../kscience/visionforge/solid/MiscSolid.kt | 26 +++++++++++++++++++ .../space/kscience/visionforge/solid/Solid.kt | 21 +++++++-------- .../kscience/visionforge/solid/Solids.kt | 2 ++ .../solid/{StlVision.kt => StlSolid.kt} | 10 +++---- .../solid/specifications/AxesScheme.kt | 2 ++ .../solid/specifications/Canvas3DOptions.kt | 2 ++ .../solid/three/ThreeAxesFactory.kt | 22 ++++++++++++++++ .../visionforge/solid/three/ThreeCanvas.kt | 17 +++--------- .../visionforge/solid/three/ThreeFactory.kt | 2 +- .../visionforge/solid/three/ThreePlugin.kt | 3 ++- .../solid/three/ThreeSmartLineFactory.kt | 14 +++++----- .../solid/three/ThreeStlFactory.kt | 14 +++++----- 13 files changed, 112 insertions(+), 45 deletions(-) create mode 100644 demo/playground/src/jvmMain/kotlin/axes.kt create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt rename visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/{StlVision.kt => StlSolid.kt} (61%) create mode 100644 visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAxesFactory.kt diff --git a/demo/playground/src/jvmMain/kotlin/axes.kt b/demo/playground/src/jvmMain/kotlin/axes.kt new file mode 100644 index 00000000..b8178887 --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/axes.kt @@ -0,0 +1,22 @@ +package space.kscience.visionforge.examples + +import space.kscience.kmath.geometry.Euclidean3DSpace +import space.kscience.kmath.geometry.radians +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.solid.* +import kotlin.math.PI + +fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { + vision("canvas") { + requirePlugin(Solids) + solid { + axes(100, "root-axes") + solidGroup("group") { + z = 100 + rotate((PI / 4).radians, Euclidean3DSpace.vector(1, 1, 1)) + axes(100, "local-axes") + box(50, 50, 50, "box") + } + } + } +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt new file mode 100644 index 00000000..f83f6cb9 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt @@ -0,0 +1,26 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild + +public abstract class MiscSolid: SolidBase() + +@Serializable +@SerialName("solid.axes") +public class AxesSolid(public val size: Double): MiscSolid(){ + public companion object{ + public const val AXES_NAME: String = "@xes" + } +} + +@VisionBuilder +public fun MutableVisionContainer.axes( + size: Number, + name: String = "@axes", + block: AxesSolid.() -> Unit = {}, +): AxesSolid = AxesSolid(size.toDouble()).apply(block).also { + setChild(name, it) +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index e0140fe4..cb0c90f0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -9,9 +9,7 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.kmath.complex.Quaternion -import space.kscience.kmath.geometry.RotationOrder -import space.kscience.kmath.geometry.fromEuler -import space.kscience.kmath.geometry.radians +import space.kscience.kmath.geometry.* import space.kscience.visionforge.* import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY @@ -242,14 +240,13 @@ public var Solid.quaternion: Quaternion quaternionValue = value } - -//public var Solid.quaternion: Quaternion? -// get() = meta[Solid::quaternion.name]?.value?.doubleArray?.let { Quaternion(it) } -// set(value) { -// meta[Solid::quaternion.name] = value?.values?.asValue() -// } - - public var Solid.scaleX: Number by float(X_SCALE_KEY, 1f) public var Solid.scaleY: Number by float(Y_SCALE_KEY, 1f) -public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f) \ No newline at end of file +public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f) + +/** + * Add rotation with given [angle] relative to given [axis] + */ +public fun Solid.rotate(angle: Angle, axis: DoubleVector3D) { + quaternion = Quaternion.fromRotation(angle, axis) +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index ab9fde1e..e9301f67 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -48,6 +48,8 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer() +public sealed class StlSolid: SolidBase() @Serializable @SerialName("solid.stl.url") -public class StlUrlVision(public val url: String) : StlVision() +public class StlUrlSolid(public val url: String) : StlSolid() @Serializable @SerialName("solid.stl.binary") -public class StlBinaryVision(public val data: ByteArray) : StlVision() +public class StlBinarySolid(public val data: ByteArray) : StlSolid() @VisionBuilder public inline fun MutableVisionContainer.stl( url: String, name: String? = null, - action: StlVision.() -> Unit = {}, -): StlVision = StlUrlVision(url).apply(action).also { setChild(name, it) } \ No newline at end of file + action: StlSolid.() -> Unit = {}, +): StlSolid = StlUrlSolid(url).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt index d4eb8e2b..0ed9126e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt @@ -7,11 +7,13 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.meta.double +@Deprecated("Use separate axes object instead") public class AxesScheme : Scheme() { public var visible: Boolean by boolean(false) public var size: Double by double(AXIS_SIZE) public var width: Double by double(AXIS_WIDTH) + @Suppress("DEPRECATION") public companion object : SchemeSpec(::AxesScheme) { public const val AXIS_SIZE: Double = 1000.0 public const val AXIS_WIDTH: Double = 3.0 diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt index 78e35dfa..b24c9b75 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt @@ -59,6 +59,7 @@ public class CanvasSize : Scheme() { } public class Canvas3DOptions : Scheme() { + @Suppress("DEPRECATION") public var axes: AxesScheme by spec(AxesScheme) public var camera: CameraScheme by spec(CameraScheme) public var controls: ControlsScheme by spec(ControlsScheme) @@ -75,6 +76,7 @@ public class Canvas3DOptions : Scheme() { public companion object : SchemeSpec(::Canvas3DOptions) { override val descriptor: MetaDescriptor by lazy { MetaDescriptor { + @Suppress("DEPRECATION") scheme(Canvas3DOptions::axes, AxesScheme) value(Canvas3DOptions::layers) { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAxesFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAxesFactory.kt new file mode 100644 index 00000000..8af445b9 --- /dev/null +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAxesFactory.kt @@ -0,0 +1,22 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.AxesSolid +import three.helpers.AxesHelper +import kotlin.reflect.KClass + +public object ThreeAxesFactory : ThreeFactory { + override val type: KClass get() = AxesSolid::class + + override suspend fun build(three: ThreePlugin, vision: AxesSolid, observe: Boolean): AxesHelper { + val res = AxesHelper(vision.size.toInt()) + + if (observe) { + vision.onPropertyChange(three.context) { propertyName -> + res.updateProperty(vision, propertyName) + } + } + + return res + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index 6ecdad78..c692b88d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -57,16 +57,6 @@ public class ThreeCanvas( axesObject.name = AXES_NAME add(axesObject) } - -// //Set up light -// options.useProperty(Canvas3DOptions::light, this) { lightConfig -> -// //remove old light if present -// getObjectByName(LIGHT_NAME)?.let { remove(it) } -// //add new light -// val lightObject = buildLight(lightConfig) -// lightObject.name = LIGHT_NAME -// add(lightObject) -// } } @@ -110,7 +100,7 @@ public class ThreeCanvas( } /** - * Force camera aspect ration and renderer size recalculation + * Force camera aspect ratio and renderer size recalculation */ private fun updateSize() { val width = element.clientWidth @@ -202,7 +192,7 @@ public class ThreeCanvas( } /** - * Resolve full name of the object relative to the global root + * Resolve the full name of the object relative to the global root */ private fun Object3D.fullName(): Name { if (root == null) error("Can't resolve element name without the root") @@ -213,7 +203,7 @@ public class ThreeCanvas( } } - //find first non-static parent in this object ancestry + //find the first non-static parent in this object ancestry private tailrec fun Object3D.upTrace(): Object3D? = if (!name.startsWith("@")) this else parent?.upTrace() private fun pick(): Object3D? { @@ -267,6 +257,7 @@ public class ThreeCanvas( } three.context.launch { val object3D = three.buildObject3D(vision) + object3D.name = "@root" scene.add(object3D) root = object3D diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index dcf94717..46e3d41b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -37,7 +37,7 @@ public interface ThreeFactory { * Update position, rotation and visibility */ public fun Object3D.updatePosition(vision: Vision) { - visible = vision.visible ?: true +// visible = vision.visible ?: true if (vision is Solid) { position.set(vision.x, vision.y, vision.z) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index e2af8c30..c1c2cf4d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -37,7 +37,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory objectFactories[PointLightSource::class] = ThreePointLightFactory - objectFactories[StlVision::class] = ThreeStlFactory + objectFactories[StlSolid::class] = ThreeStlFactory + objectFactories[AxesSolid::class] = ThreeAxesFactory } @Suppress("UNCHECKED_CAST") diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt index 6f2ee1a5..b3609b66 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt @@ -7,11 +7,13 @@ import kotlin.reflect.KClass public object ThreeSmartLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { - return if (vision.thickness == 1.0) { - ThreeLineFactory.build(three, vision, observe) - } else { - ThreeMeshLineFactory.build(three, vision, observe) - } + override suspend fun build( + three: ThreePlugin, + vision: PolyLine, + observe: Boolean, + ): Object3D = if (vision.thickness == 1.0) { + ThreeLineFactory.build(three, vision, observe) + } else { + ThreeMeshLineFactory.build(three, vision, observe) } } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt index d21389aa..e3fb676f 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt @@ -2,9 +2,9 @@ package space.kscience.visionforge.solid.three import org.khronos.webgl.ArrayBuffer import org.khronos.webgl.Int8Array -import space.kscience.visionforge.solid.StlBinaryVision -import space.kscience.visionforge.solid.StlUrlVision -import space.kscience.visionforge.solid.StlVision +import space.kscience.visionforge.solid.StlBinarySolid +import space.kscience.visionforge.solid.StlSolid +import space.kscience.visionforge.solid.StlUrlSolid import three.core.BufferGeometry import three.external.loaders.STLLoader import kotlin.coroutines.resume @@ -13,15 +13,15 @@ import kotlin.coroutines.suspendCoroutine fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast() -public object ThreeStlFactory : ThreeMeshFactory(StlVision::class) { +public object ThreeStlFactory : ThreeMeshFactory(StlSolid::class) { private val loader = STLLoader().apply { requestHeader = listOf("Access-Control-Allow-Origin: *") } - override suspend fun buildGeometry(obj: StlVision): BufferGeometry = when (obj) { - is StlBinaryVision -> loader.parse(obj.data) - is StlUrlVision -> suspendCoroutine { continuation -> + override suspend fun buildGeometry(obj: StlSolid): BufferGeometry = when (obj) { + is StlBinarySolid -> loader.parse(obj.data) + is StlUrlSolid -> suspendCoroutine { continuation -> loader.load( url = obj.url, onLoad = { From 4bce9ad34cbeff8c4caa219ffcf892d737059b6d Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 7 Jun 2023 17:44:52 +0300 Subject: [PATCH 064/112] update version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 30eea98f..8997eeda 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-9" + version = "0.3.0-dev-10" } subprojects { From 07b54fde51391c4e68a520f101143e0553521e90 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 7 Jun 2023 19:43:15 +0300 Subject: [PATCH 065/112] Use quaternion as rotation value --- .../kotlin/space/kscience/visionforge/solid/Solid.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index cb0c90f0..a24192a8 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -60,8 +60,6 @@ public interface Solid : Vision { public val ROTATION_KEY: Name = "rotation".asName() - public val QUATERNION_KEY: Name = "quaternion".asName() - public val X_ROTATION_KEY: Name = ROTATION_KEY + X_KEY public val Y_ROTATION_KEY: Name = ROTATION_KEY + Y_KEY public val Z_ROTATION_KEY: Name = ROTATION_KEY + Z_KEY @@ -208,13 +206,13 @@ public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f) * Raw quaternion value defined in properties */ public var Solid.quaternionValue: Quaternion? - get() = properties.getValue(Solid.QUATERNION_KEY)?.list?.let { + get() = properties.getValue(ROTATION_KEY)?.list?.let { require(it.size == 4) { "Quaternion must be a number array of 4 elements" } Quaternion(it[0].float, it[1].float, it[2].float, it[3].float) } set(value) { properties.setValue( - Solid.QUATERNION_KEY, + ROTATION_KEY, value?.let { ListValue( value.w, From f2d7e20fd3258830aa84d7b19e75b399c6fd3ad9 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 7 Jun 2023 21:29:40 +0300 Subject: [PATCH 066/112] Add dynamic rotation example --- .../space/kscience/visionforge/solid/demo/demo.kt | 13 +++++++++++-- .../space/kscience/visionforge/solid/Solid.kt | 5 +++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index 6f2cb61f..baee4c71 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -4,6 +4,8 @@ import kotlinx.coroutines.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.invoke import space.kscience.dataforge.names.Name +import space.kscience.kmath.geometry.Euclidean3DSpace +import space.kscience.kmath.geometry.radians import space.kscience.visionforge.Colors import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions @@ -103,8 +105,15 @@ fun VisionLayout.showcase() { solidGroup { x = 200 rotationY = PI / 4 + axes(200) box(100, 100, 100) { - rotationZ = PI / 4 + rotate((PI / 4).radians, Euclidean3DSpace.zAxis) + GlobalScope.launch(Dispatchers.Main) { + while (isActive) { + delay(100) + rotate((PI/20).radians,Euclidean3DSpace.yAxis) + } + } color.set(Colors.red) } } @@ -151,7 +160,7 @@ fun VisionLayout.showcase() { } } - demo("STL", "STL loaded from URL"){ + demo("STL", "STL loaded from URL") { stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl") } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index a24192a8..c58b849d 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -9,6 +9,7 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.complex.QuaternionField import space.kscience.kmath.geometry.* import space.kscience.visionforge.* import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY @@ -245,6 +246,6 @@ public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f) /** * Add rotation with given [angle] relative to given [axis] */ -public fun Solid.rotate(angle: Angle, axis: DoubleVector3D) { - quaternion = Quaternion.fromRotation(angle, axis) +public fun Solid.rotate(angle: Angle, axis: DoubleVector3D) = with(QuaternionField) { + quaternion = Quaternion.fromRotation(angle, axis)*quaternion } \ No newline at end of file From 8611327cc4bc8711e5e6dd6723b20ee7f53398e3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 8 Jun 2023 10:04:31 +0300 Subject: [PATCH 067/112] antenna example --- demo/playground/src/jvmMain/kotlin/antenna.kt | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 demo/playground/src/jvmMain/kotlin/antenna.kt diff --git a/demo/playground/src/jvmMain/kotlin/antenna.kt b/demo/playground/src/jvmMain/kotlin/antenna.kt new file mode 100644 index 00000000..5b92f46f --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/antenna.kt @@ -0,0 +1,43 @@ +package space.kscience.visionforge.examples + +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.geometry.RotationOrder +import space.kscience.kmath.geometry.degrees +import space.kscience.kmath.geometry.fromEuler +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.solid.* +import kotlin.math.PI + +fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { + + val direction = Quaternion.fromEuler( 45.degrees, 45.degrees, 0.degrees, RotationOrder.XYZ) + + vision("canvas") { + requirePlugin(Solids) + solid { + rotationX = -PI / 2 + rotationZ = PI + axes(200) + ambientLight() + cylinder(50, 5, name = "base") + solidGroup("frame") { + rotationY = PI/2 + rotationX = -PI/2 + rotationZ = -PI/2 + z = 60 + axes(200) + solidGroup("antenna") { + tube(40, 10, 30) + sphereLayer(100, 95, theta = PI / 6) { + z = 100 + rotationX = -PI / 2 + } + cylinder(5, 30) { + z = 15 + } + this.quaternion = direction + } + } + } + } +} \ No newline at end of file From 04b4a129461f54476530c4b5d8ffb20a2495b49c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 22 Jun 2023 08:32:52 +0300 Subject: [PATCH 068/112] antenna example --- demo/playground/src/jvmMain/kotlin/antenna.kt | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/antenna.kt b/demo/playground/src/jvmMain/kotlin/antenna.kt index 5b92f46f..cd711d11 100644 --- a/demo/playground/src/jvmMain/kotlin/antenna.kt +++ b/demo/playground/src/jvmMain/kotlin/antenna.kt @@ -1,16 +1,27 @@ package space.kscience.visionforge.examples import space.kscience.kmath.complex.Quaternion -import space.kscience.kmath.geometry.RotationOrder +import space.kscience.kmath.complex.QuaternionField +import space.kscience.kmath.geometry.Angle +import space.kscience.kmath.geometry.Euclidean3DSpace import space.kscience.kmath.geometry.degrees -import space.kscience.kmath.geometry.fromEuler +import space.kscience.kmath.geometry.fromRotation import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.* import kotlin.math.PI fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { - val direction = Quaternion.fromEuler( 45.degrees, 45.degrees, 0.degrees, RotationOrder.XYZ) + val azimuth = 60.degrees + val inclination = 15.degrees + + val direction = with(QuaternionField) { + Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) * + Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis) + } + + //val direction2 = Quaternion.fromEuler(Angle.zero, Angle.piDiv2 - inclination, -azimuth, RotationOrder.ZYX) + vision("canvas") { requirePlugin(Solids) @@ -21,9 +32,6 @@ fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { ambientLight() cylinder(50, 5, name = "base") solidGroup("frame") { - rotationY = PI/2 - rotationX = -PI/2 - rotationZ = -PI/2 z = 60 axes(200) solidGroup("antenna") { @@ -35,7 +43,7 @@ fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { cylinder(5, 30) { z = 15 } - this.quaternion = direction + quaternion = direction } } } From ea9d37b9a160262fcc1c88baf08b41760417803e Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 22 Jun 2023 20:33:23 +0300 Subject: [PATCH 069/112] 1.9.0-RC --- gradle.properties | 6 ++++-- visionforge-gdml/build.gradle.kts | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9b345a25..2cb4bdbf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,8 @@ kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.14.9-kotlin-1.9.0-Beta-2 +org.jetbrains.compose.experimental.jscanvas.enabled=true + +toolsVersion=0.14.9-kotlin-1.9.0-RC-dev-1 kotlin.experimental.tryK2=true -org.jetbrains.compose.experimental.jscanvas.enabled=true \ No newline at end of file +#kscience.wasm.disabled=true diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index c1c86059..cdf4ad47 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -10,7 +10,6 @@ kscience { dependencies { api(projects.visionforgeSolid) api("space.kscience:gdml:0.5.0") - implementation("com.github.h0tk3y.betterParse:better-parse:0.4.4") } dependencies(jvmTest) { implementation(spclibs.logback.classic) From 25c3a19eedb171ebd245267967f00fb0ce0fb231 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 27 Jun 2023 20:30:29 +0300 Subject: [PATCH 070/112] Fix demo package name to ensure proper package resolution --- demo/gdml/build.gradle.kts | 2 ++ ui/react/build.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index 72b1b283..4cccf686 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -2,6 +2,8 @@ plugins { id("space.kscience.gradle.mpp") } +group = "demo" + kscience { jvm() js { diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index c4d40cf1..1770feeb 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -10,7 +10,7 @@ kscience { api("org.jetbrains.kotlin-wrappers:kotlin-styled") api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") // implementation(npm("react-select","4.3.0")) - implementation(projects.visionforgeThreejs) + api(projects.visionforgeThreejs) } } } \ No newline at end of file From 086948492c6689a0fa22cc578582ae6fde6a96ce Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 14 Jul 2023 20:11:37 +0300 Subject: [PATCH 071/112] update build plugin --- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- jupyter/build.gradle.kts | 2 +- jupyter/visionforge-jupyter-gdml/build.gradle.kts | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gradle.properties b/gradle.properties index 2cb4bdbf..dde47c66 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ org.gradle.jvmargs=-Xmx4G org.jetbrains.compose.experimental.jscanvas.enabled=true -toolsVersion=0.14.9-kotlin-1.9.0-RC-dev-1 +toolsVersion=0.14.9-kotlin-1.9.0 kotlin.experimental.tryK2=true #kscience.wasm.disabled=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fae08049..84a0b92f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jupyter/build.gradle.kts b/jupyter/build.gradle.kts index 5808f287..1c32732b 100644 --- a/jupyter/build.gradle.kts +++ b/jupyter/build.gradle.kts @@ -11,7 +11,7 @@ kscience { dependencies { api(projects.visionforgeCore) } - dependencies(jvmMain){ + jvmMain { api(projects.visionforgeServer) } } diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/jupyter/visionforge-jupyter-gdml/build.gradle.kts index 5a67459e..65df0c80 100644 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ b/jupyter/visionforge-jupyter-gdml/build.gradle.kts @@ -16,16 +16,16 @@ kscience { } } - dependencies{ + commonMain{ implementation(projects.visionforgeSolid) implementation(projects.jupyter) } - dependencies(jvmMain){ + jvmMain{ implementation(projects.visionforgeGdml) } - dependencies(jsMain){ + jsMain{ implementation(projects.visionforgeThreejs) implementation(projects.ui.ring) } From 8b25761dc6a37cd51413641e8374c85707497c53 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 19 Jul 2023 22:25:32 +0300 Subject: [PATCH 072/112] Refactor jupyter integratin --- build.gradle.kts | 2 +- demo/playground/build.gradle.kts | 5 +- demo/playground/notebooks/common-demo.ipynb | 104 ++++++++++++++++++ demo/playground/notebooks/dynamic-demo.ipynb | 50 +-------- .../src/jsMain/kotlin/playgroundMain.kt | 4 +- demo/sat-demo/build.gradle.kts | 6 +- jupyter/visionforge-jupyter-gdml/README.md | 32 ------ .../src/jsMain/kotlin/gdmlJupyter.kt | 12 -- .../src/jvmMain/kotlin/GdmlForJupyter.kt | 38 ------- .../webpack.config.d/01.ring.js | 3 - settings.gradle.kts | 4 +- .../kscience/visionforge/html/VisionPage.kt | 2 +- {jupyter => visionforge-jupyter}/README.md | 0 .../build.gradle.kts | 2 + .../src/jsMain/kotlin/VFNotebookClient.kt | 6 +- .../src/jvmMain/kotlin/VisionForge.kt | 22 ++-- .../jvmMain/kotlin/VisionForgeIntegration.kt | 19 +++- .../src/jvmMain/kotlin/forms.kt | 11 +- .../build.gradle.kts | 22 ++-- .../src/jsMain/kotlin/commonJupyter.kt | 17 +++ .../kotlin/JupyterCommonIntegration.kt | 40 ++++--- .../webpack.config.d/01.ring.js | 24 ++++ visionforge-server/build.gradle.kts | 2 +- .../visionforge/server/VisionServer.kt | 1 - .../space/kscience/visionforge/solid/Solid.kt | 2 +- .../kscience/visionforge/solid/SolidGroup.kt | 5 + visionforge-tables/build.gradle.kts | 14 +-- .../visionforge/tables/VisionOfTable.kt | 5 + 28 files changed, 264 insertions(+), 190 deletions(-) create mode 100644 demo/playground/notebooks/common-demo.ipynb delete mode 100644 jupyter/visionforge-jupyter-gdml/README.md delete mode 100644 jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt delete mode 100644 jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt delete mode 100644 jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js rename {jupyter => visionforge-jupyter}/README.md (100%) rename {jupyter => visionforge-jupyter}/build.gradle.kts (87%) rename jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt => visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt (90%) rename jupyter/src/jvmMain/kotlin/VFForNotebook.kt => visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt (88%) rename jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt => visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt (85%) rename {jupyter => visionforge-jupyter}/src/jvmMain/kotlin/forms.kt (82%) rename {jupyter/visionforge-jupyter-gdml => visionforge-jupyter/visionforge-jupyter-common}/build.gradle.kts (54%) create mode 100644 visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt rename demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt => visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt (51%) create mode 100644 visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js diff --git a/build.gradle.kts b/build.gradle.kts index 8997eeda..73f03bbd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-10" + version = "0.3.0-dev-11" } subprojects { diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index ddc1d6a8..77dd565e 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -47,12 +47,11 @@ kotlin { val commonMain by getting { dependencies { implementation(projects.visionforgeSolid) - implementation(projects.visionforgeGdml) implementation(projects.visionforgePlotly) implementation(projects.visionforgeMarkdown) implementation(projects.visionforgeTables) implementation(projects.cernRootLoader) - implementation(projects.jupyter) + implementation(projects.visionforgeJupyter.visionforgeJupyterCommon) } } @@ -66,6 +65,8 @@ kotlin { val jvmMain by getting { dependencies { + implementation("io.ktor:ktor-server-cio:${spclibs.versions.ktor.get()}") + implementation(projects.visionforgeGdml) implementation(projects.visionforgeServer) implementation(spclibs.logback.classic) implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6") diff --git a/demo/playground/notebooks/common-demo.ipynb b/demo/playground/notebooks/common-demo.ipynb new file mode 100644 index 00000000..73409ae7 --- /dev/null +++ b/demo/playground/notebooks/common-demo.ipynb @@ -0,0 +1,104 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "@file:Repository(\"*mavenLocal\")\n", + "@file:Repository(\"https://repo.kotlin.link\")\n", + "@file:Repository(\"https://maven.pkg.jetbrains.space/spc/p/sci/dev\")\n", + "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-11\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + ":classpath" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "vf.startServer()" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "import space.kscience.visionforge.plotly.plotly\n", + "\n", + "vf.page {\n", + " h1 { +\"AAA\" }\n", + " vision {\n", + " solid {\n", + " ambientLight()\n", + " box(100, 100, 200)\n", + "\n", + " sphere(100) {\n", + " x = 300\n", + " }\n", + " }\n", + " }\n", + "\n", + " vision {\n", + " plotly {\n", + " scatter {\n", + " x(1, 2, 3, 1)\n", + " y(1, 2, 3, 4)\n", + " }\n", + " }\n", + " }\n", + "}" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + } + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "language_info": { + "name": "kotlin", + "version": "1.8.20", + "mimetype": "text/x-kotlin", + "file_extension": ".kt", + "pygments_lexer": "kotlin", + "codemirror_mode": "text/x-kotlin", + "nbconvert_exporter": "" + }, + "ktnbPluginMetadata": { + "isAddProjectLibrariesToClasspath": false + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/demo/playground/notebooks/dynamic-demo.ipynb b/demo/playground/notebooks/dynamic-demo.ipynb index 41289185..ac70b4c2 100644 --- a/demo/playground/notebooks/dynamic-demo.ipynb +++ b/demo/playground/notebooks/dynamic-demo.ipynb @@ -2,15 +2,11 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "tags": [], "pycharm": { "is_executing": true - }, - "ExecuteTime": { - "end_time": "2023-05-29T15:22:37.933397300Z", - "start_time": "2023-05-29T15:22:37.913872100Z" } }, "outputs": [], @@ -18,57 +14,23 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "ExecuteTime": { - "end_time": "2023-05-29T15:22:50.486483300Z", - "start_time": "2023-05-29T15:22:50.457485500Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Line_2.jupyter.kts (1:1 - 3) Unresolved reference: vf" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "vf.startServer()" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false - }, - "ExecuteTime": { - "end_time": "2023-05-29T15:22:51.410680600Z", - "start_time": "2023-05-29T15:22:51.250779400Z" } }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Line_3.jupyter.kts (1:16 - 26) Unresolved reference: coroutines\n", - "Line_3.jupyter.kts (4:1 - 7) Unresolved reference: Plotly\n", - "Line_3.jupyter.kts (5:5 - 12) Unresolved reference: scatter\n", - "Line_3.jupyter.kts (6:9 - 10) Unresolved reference: x\n", - "Line_3.jupyter.kts (7:9 - 10) Unresolved reference: y\n", - "Line_3.jupyter.kts (8:12 - 14) Unresolved reference: vf\n", - "Line_3.jupyter.kts (9:13 - 15) Unresolved reference: vf\n", - "Line_3.jupyter.kts (10:23 - 31) Unresolved reference: isActive\n", - "Line_3.jupyter.kts (11:21 - 26) Unresolved reference: delay\n", - "Line_3.jupyter.kts (12:21 - 22) Unresolved reference: y" - ] - } - ], + "outputs": [], "source": [ "import kotlinx.coroutines.*\n", "import kotlin.random.Random\n", diff --git a/demo/playground/src/jsMain/kotlin/playgroundMain.kt b/demo/playground/src/jsMain/kotlin/playgroundMain.kt index 8e259d48..feff4de1 100644 --- a/demo/playground/src/jsMain/kotlin/playgroundMain.kt +++ b/demo/playground/src/jsMain/kotlin/playgroundMain.kt @@ -1,5 +1,5 @@ import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.jupyter.VFNotebookPlugin +import space.kscience.visionforge.jupyter.VFNotebookClient import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.ring.ThreeWithControlsPlugin @@ -12,5 +12,5 @@ fun main() = runVisionClient { plugin(PlotlyPlugin) plugin(MarkupPlugin) plugin(TableVisionJsPlugin) - plugin(VFNotebookPlugin) + plugin(VFNotebookClient) } \ No newline at end of file diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 6afadf27..5e881b63 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -8,13 +8,15 @@ kscience { // useSerialization { // json() // } + useKtor() dependencies{ + implementation("io.ktor:ktor-server-cio") implementation(projects.visionforgeThreejs.visionforgeThreejsServer) - implementation("ch.qos.logback:logback-classic:1.4.5") + implementation(spclibs.logback.classic) } } -group = "ru.mipt.npm" +group = "center.sciprog" application { mainClass.set("ru.mipt.npm.sat.SatServerKt") diff --git a/jupyter/visionforge-jupyter-gdml/README.md b/jupyter/visionforge-jupyter-gdml/README.md deleted file mode 100644 index cae8af86..00000000 --- a/jupyter/visionforge-jupyter-gdml/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Module visionforge-jupyter-gdml - -Jupyter api artifact for GDML rendering - -## Usage - -## Artifact: - -The Maven coordinates of this project are `space.kscience:visionforge-jupyter-gdml:0.2.0`. - -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:visionforge-jupyter-gdml:0.2.0' -} -``` -**Gradle Kotlin DSL:** -```kotlin -repositories { - maven("https://repo.kotlin.link") - mavenCentral() -} - -dependencies { - implementation("space.kscience:visionforge-jupyter-gdml:0.2.0") -} -``` diff --git a/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt deleted file mode 100644 index d4ee507e..00000000 --- a/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt +++ /dev/null @@ -1,12 +0,0 @@ -package space.kscience.visionforge.gdml.jupyter - -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.ring.ThreeWithControlsPlugin -import space.kscience.visionforge.runVisionClient - -@DFExperimental -@JsExport -public fun main(): Unit = runVisionClient { - plugin(ThreeWithControlsPlugin) -} - diff --git a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt deleted file mode 100644 index 0d55be2e..00000000 --- a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt +++ /dev/null @@ -1,38 +0,0 @@ -package space.kscience.visionforge.gdml.jupyter - -import org.jetbrains.kotlinx.jupyter.api.libraries.resources -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.gdml.Gdml -import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.jupyter.VFIntegrationBase -import space.kscience.visionforge.solid.Solids -import space.kscience.visionforge.visionManager - -@DFExperimental -internal class GdmlForJupyter : VFIntegrationBase( - Context("GDML") { - plugin(Solids) - }.visionManager -) { - - override fun Builder.afterLoaded() { - - resources { - js("three") { - classPath("js/gdml-jupyter.js") - } - } - - import( - "space.kscience.gdml.*", - "space.kscience.visionforge.gdml.jupyter.*" - ) - - render { gdmlModel -> - handler.produceHtml { - vision { gdmlModel.toVision() } - } - } - } -} diff --git a/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js b/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js deleted file mode 100644 index 41da041c..00000000 --- a/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js +++ /dev/null @@ -1,3 +0,0 @@ -const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; - -config.module.rules.push(...ringConfig.module.rules) \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index e9e3deba..31119a06 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -64,6 +64,6 @@ include( ":demo:playground", // ":demo:plotly-fx", ":demo:js-playground", - ":jupyter", - ":jupyter:visionforge-jupyter-gdml" + ":visionforge-jupyter", + ":visionforge-jupyter:visionforge-jupyter-common" ) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt index de18ced5..f92454f0 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt @@ -26,7 +26,7 @@ public data class VisionPage( } /** - * Use css with given stylesheet link as a global header for all pages. + * Use css with the given stylesheet link as a global header for all pages. */ public fun styleSheetHeader(href: String, block: LINK.() -> Unit = {}): HtmlFragment = { link { diff --git a/jupyter/README.md b/visionforge-jupyter/README.md similarity index 100% rename from jupyter/README.md rename to visionforge-jupyter/README.md diff --git a/jupyter/build.gradle.kts b/visionforge-jupyter/build.gradle.kts similarity index 87% rename from jupyter/build.gradle.kts rename to visionforge-jupyter/build.gradle.kts index 5808f287..ed4ab76d 100644 --- a/jupyter/build.gradle.kts +++ b/visionforge-jupyter/build.gradle.kts @@ -5,6 +5,7 @@ plugins { description = "Common visionforge jupyter module" kscience { + useKtor() jvm() js() jupyterLibrary() @@ -12,6 +13,7 @@ kscience { api(projects.visionforgeCore) } dependencies(jvmMain){ + api("io.ktor:ktor-server-cio") api(projects.visionforgeServer) } } diff --git a/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt similarity index 90% rename from jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt rename to visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt index f6a37f23..24304136 100644 --- a/jupyter/src/jsMain/kotlin/VFNotebookPlugin.kt +++ b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt @@ -13,7 +13,7 @@ import space.kscience.visionforge.renderAllVisionsById import space.kscience.visionforge.renderAllVisionsIn @JsExport -public class VFNotebookPlugin : AbstractPlugin() { +public class VFNotebookClient : AbstractPlugin() { private val client by require(VisionClient) public fun renderAllVisionsIn(element: Element) { @@ -39,8 +39,8 @@ public class VFNotebookPlugin : AbstractPlugin() { override val tag: PluginTag get() = Companion.tag @Suppress("NON_EXPORTABLE_TYPE") - public companion object : PluginFactory { - override fun build(context: Context, meta: Meta): VFNotebookPlugin = VFNotebookPlugin() + public companion object : PluginFactory { + override fun build(context: Context, meta: Meta): VFNotebookClient = VFNotebookClient() override val tag: PluginTag = PluginTag(name = "vision.notebook", group = PluginTag.DATAFORGE_GROUP) } diff --git a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt similarity index 88% rename from jupyter/src/jvmMain/kotlin/VFForNotebook.kt rename to visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt index 50619e44..0a538a3e 100644 --- a/jupyter/src/jvmMain/kotlin/VFForNotebook.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt @@ -16,9 +16,7 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.context.info import space.kscience.dataforge.context.logger -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.int -import space.kscience.dataforge.meta.string +import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager @@ -26,7 +24,6 @@ import space.kscience.visionforge.html.HtmlVisionFragment import space.kscience.visionforge.html.visionFragment import space.kscience.visionforge.server.VisionRoute import space.kscience.visionforge.server.serveVisionData -import space.kscience.visionforge.visionManager import kotlin.coroutines.CoroutineContext import kotlin.random.Random import kotlin.random.nextUInt @@ -41,9 +38,14 @@ internal fun TagConsumer<*>.renderScriptForId(id: String) { /** * A handler class that includes a server and common utilities */ -public class VFForNotebook(override val context: Context) : ContextAware, CoroutineScope { +public class VisionForge( + public val visionManager: VisionManager, + meta: Meta = Meta.EMPTY, +) : ContextAware, CoroutineScope { - public val visionManager: VisionManager = context.visionManager + override val context: Context get() = visionManager.context + + public val configuration: ObservableMutableMeta = meta.toMutableMeta() private var counter = 0 @@ -61,9 +63,11 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout public fun html(block: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(createHTML().apply(block).finalize()) + public fun getProperty(name: String): TypedMeta<*>? = configuration[name] ?: context.properties[name] + public fun startServer( - host: String = context.properties["visionforge.host"].string ?: "localhost", - port: Int = context.properties["visionforge.port"].int ?: VisionRoute.DEFAULT_PORT, + host: String = getProperty("visionforge.host").string ?: "localhost", + port: Int = getProperty("visionforge.port").int ?: VisionRoute.DEFAULT_PORT, ): MimeTypedResult = html { if (engine != null) { p { @@ -141,4 +145,4 @@ public class VFForNotebook(override val context: Context) : ContextAware, Corout public fun form(builder: FORM.() -> Unit): HtmlFormFragment = HtmlFormFragment("form[${counter++}]", builder = builder) -} \ No newline at end of file +} diff --git a/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt similarity index 85% rename from jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt rename to visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt index bf6322e9..3029ef32 100644 --- a/jupyter/src/jvmMain/kotlin/VFIntegrationBase.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt @@ -18,12 +18,12 @@ import kotlin.random.nextUInt * A base class for different Jupyter VF integrations */ @DFExperimental -public abstract class VFIntegrationBase( +public abstract class VisionForgeIntegration( public val visionManager: VisionManager, ) : JupyterIntegration(), ContextAware { override val context: Context get() = visionManager.context - protected val handler: VFForNotebook = VFForNotebook(visionManager.context) + protected val handler: VisionForge = VisionForge(visionManager) protected abstract fun Builder.afterLoaded() @@ -33,13 +33,15 @@ public abstract class VFIntegrationBase( declare("VisionForge" to handler, "vf" to handler) } + onShutdown { handler.stopServer() } import( "kotlinx.html.*", - "space.kscience.visionforge.html.*" + "space.kscience.visionforge.html.*", + "space.kscience.visionforge.jupyter.*" ) render { fragment -> @@ -54,7 +56,6 @@ public abstract class VFIntegrationBase( handler.produceHtml { vision(vision) } - } render { page -> @@ -93,4 +94,12 @@ public abstract class VFIntegrationBase( afterLoaded() } -} \ No newline at end of file +} + +/** + * Create a standalone page in the notebook + */ +public fun VisionForge.page( + pageHeaders: Map = emptyMap(), + content: HtmlVisionFragment +): VisionPage = VisionPage(visionManager, pageHeaders, content) \ No newline at end of file diff --git a/jupyter/src/jvmMain/kotlin/forms.kt b/visionforge-jupyter/src/jvmMain/kotlin/forms.kt similarity index 82% rename from jupyter/src/jvmMain/kotlin/forms.kt rename to visionforge-jupyter/src/jvmMain/kotlin/forms.kt index bccce2e7..fe072887 100644 --- a/jupyter/src/jvmMain/kotlin/forms.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/forms.kt @@ -11,11 +11,14 @@ import space.kscience.visionforge.html.VisionOfHtmlForm public class HtmlFormFragment internal constructor( public val vision: VisionOfHtmlForm, public val formBody: HtmlFragment, -){ +) { public val values: Meta? get() = vision.values public operator fun get(valueName: String): Meta? = values?.get(valueName) } +/** + * Top level function to create a form + */ public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment { val realId = id ?: "form[${builder.hashCode().toUInt()}]" return HtmlFormFragment(VisionOfHtmlForm(realId)) { @@ -24,4 +27,8 @@ public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlF builder() } } -} \ No newline at end of file +} + + +public fun VisionForge.form(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment = + HtmlFormFragment(id, builder) \ No newline at end of file diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts similarity index 54% rename from jupyter/visionforge-jupyter-gdml/build.gradle.kts rename to visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts index 5a67459e..c71b33d0 100644 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ b/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts @@ -2,10 +2,11 @@ plugins { id("space.kscience.gradle.mpp") } -description = "Jupyter api artifact for GDML rendering" +description = "Jupyter api artifact including all common modules" kscience { - fullStack("js/gdml-jupyter.js", + fullStack( + "js/visionforge-jupyter-common.js", jsConfig = { useCommonJs() } ) { commonWebpackConfig { @@ -16,21 +17,24 @@ kscience { } } - dependencies{ + dependencies { implementation(projects.visionforgeSolid) - implementation(projects.jupyter) + implementation(projects.visionforgePlotly) + implementation(projects.visionforgeTables) + implementation(projects.visionforgeMarkdown) + implementation(projects.visionforgeJupyter) } - dependencies(jvmMain){ + jvmMain { implementation(projects.visionforgeGdml) } - dependencies(jsMain){ - implementation(projects.visionforgeThreejs) + jsMain { implementation(projects.ui.ring) + implementation(projects.visionforgeThreejs) } - - jupyterLibrary("space.kscience.visionforge.gdml.jupyter.GdmlForJupyter") + + jupyterLibrary("space.kscience.visionforge.jupyter.JupyterCommonIntegration") } readme { diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt new file mode 100644 index 00000000..e5fb4edd --- /dev/null +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt @@ -0,0 +1,17 @@ +package space.kscience.visionforge.gdml.jupyter + +import space.kscience.visionforge.jupyter.VFNotebookClient +import space.kscience.visionforge.markup.MarkupPlugin +import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.ring.ThreeWithControlsPlugin +import space.kscience.visionforge.runVisionClient +import space.kscience.visionforge.tables.TableVisionJsPlugin + +public fun main(): Unit = runVisionClient { + plugin(ThreeWithControlsPlugin) + plugin(PlotlyPlugin) + plugin(MarkupPlugin) + plugin(TableVisionJsPlugin) + plugin(VFNotebookClient) +} + diff --git a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt similarity index 51% rename from demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt rename to visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt index 0b87e06d..6bca7036 100644 --- a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt @@ -1,46 +1,52 @@ -package space.kscience.visionforge.examples +package space.kscience.visionforge.jupyter +import kotlinx.html.* import org.jetbrains.kotlinx.jupyter.api.libraries.resources import space.kscience.dataforge.context.Context import space.kscience.dataforge.misc.DFExperimental import space.kscience.gdml.Gdml import space.kscience.plotly.Plot +import space.kscience.tables.* import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.jupyter.VFIntegrationBase +import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.plotly.asVision import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.tables.TableVisionPlugin +import space.kscience.visionforge.tables.toVision import space.kscience.visionforge.visionManager + @DFExperimental -internal class VisionForgePlayGroundForJupyter : VFIntegrationBase( - Context("VisionForge") { - plugin(Solids) - plugin(PlotlyPlugin) - }.visionManager -) { +public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionManager) { override fun Builder.afterLoaded() { + resources { - js("VisionForge") { - classPath("js/visionforge-playground.js") + js("three") { + classPath("js/visionforge-jupyter-common.js") } } import( "space.kscience.gdml.*", - "space.kscience.plotly.*", - "space.kscience.plotly.models.*", "space.kscience.visionforge.solid.*", + "space.kscience.tables.*", + "space.kscience.dataforge.meta.*", ) - render { gdmlModel -> handler.produceHtml { vision { gdmlModel.toVision() } } } + render> { table -> + handler.produceHtml { + vision { table.toVision() } + } + } + render { plot -> handler.produceHtml { vision { plot.asVision() } @@ -48,4 +54,12 @@ internal class VisionForgePlayGroundForJupyter : VFIntegrationBase( } } + public companion object { + private val CONTEXT: Context = Context("Jupyter-common") { + plugin(Solids) + plugin(PlotlyPlugin) + plugin(TableVisionPlugin) + plugin(MarkupPlugin) + } + } } diff --git a/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js b/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js new file mode 100644 index 00000000..cfb15cb8 --- /dev/null +++ b/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js @@ -0,0 +1,24 @@ +const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; + +const path = require('path'); + +config.module.rules.push(...ringConfig.module.rules) + +config.module.rules.push( + { + test: /\.css$/, + exclude: [ + path.resolve(__dirname, "../../node_modules/@jetbrains/ring-ui") + ], + use: [ + { + loader: 'style-loader', + options: {} + }, + { + loader: 'css-loader', + options: {} + } + ] + } +) \ No newline at end of file diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index a4a7d848..00331969 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -6,7 +6,7 @@ kscience{ useKtor() dependencies { api(projects.visionforgeCore) - api("io.ktor:ktor-server-cio") + api("io.ktor:ktor-server-host-common") api("io.ktor:ktor-server-html-builder") api("io.ktor:ktor-server-websockets") implementation("io.ktor:ktor-server-cors") diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 84a87a65..47c5db84 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.server import io.ktor.http.* import io.ktor.server.application.* -import io.ktor.server.cio.* import io.ktor.server.engine.* import io.ktor.server.html.* import io.ktor.server.http.content.* diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index c58b849d..8b719b54 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -246,6 +246,6 @@ public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f) /** * Add rotation with given [angle] relative to given [axis] */ -public fun Solid.rotate(angle: Angle, axis: DoubleVector3D) = with(QuaternionField) { +public fun Solid.rotate(angle: Angle, axis: DoubleVector3D): Unit = with(QuaternionField) { quaternion = Quaternion.fromRotation(angle, axis)*quaternion } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index f601a30e..791bb0c9 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -99,3 +99,8 @@ public inline fun MutableVisionContainer.solidGroup( name: String, action: SolidGroup.() -> Unit = {}, ): SolidGroup = solidGroup(name.parseAsName(), action) + +/** + * Create a [SolidGroup] using given configuration [block] + */ +public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block) \ No newline at end of file diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index 23d77912..cf813e6e 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -9,9 +9,9 @@ kscience { js { useCommonJs() binaries.library() - browser{ - commonWebpackConfig{ - cssSupport{ + browser { + commonWebpackConfig { + cssSupport { enabled.set(true) } } @@ -21,13 +21,13 @@ kscience { api(projects.visionforgeCore) api("space.kscience:tables-kt:${tablesVersion}") } - dependencies(jsMain){ - implementation(npm("tabulator-tables", "5.0.1")) - implementation(npm("@types/tabulator-tables", "5.0.1")) + dependencies(jsMain) { + implementation(npm("tabulator-tables", "5.4.4")) + implementation(npm("@types/tabulator-tables", "5.4.8")) } useSerialization() } -readme{ +readme { maturity = space.kscience.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt index 20332974..3e4f9da8 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt @@ -86,6 +86,11 @@ public fun Table.toVision(): VisionOfTable = toVision { (it ?: "").asVal @JvmName("numberTableToVision") public fun Table.toVision(): VisionOfTable = toVision { (it ?: Double.NaN).asValue() } +@JvmName("anyTableToVision") +public fun Table.toVision(): VisionOfTable = toVision { + (it as? Number)?.asValue() ?: it?.toString()?.asValue() ?: Null +} + @DFExperimental public inline fun VisionOutput.table( vararg headers: ColumnHeader, From c1f275ce450f4471494a02a6ef9f4b61da748221 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 19 Jul 2023 22:54:13 +0300 Subject: [PATCH 073/112] Work-around for strange dependency resolution in notebooks --- demo/playground/notebooks/common-demo.ipynb | 75 ++++++++++--------- .../build.gradle.kts | 12 +-- visionforge-server/build.gradle.kts | 2 +- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/demo/playground/notebooks/common-demo.ipynb b/demo/playground/notebooks/common-demo.ipynb index 73409ae7..2c397a15 100644 --- a/demo/playground/notebooks/common-demo.ipynb +++ b/demo/playground/notebooks/common-demo.ipynb @@ -3,45 +3,50 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "@file:Repository(\"*mavenLocal\")\n", "@file:Repository(\"https://repo.kotlin.link\")\n", "@file:Repository(\"https://maven.pkg.jetbrains.space/spc/p/sci/dev\")\n", - "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-11\")" + "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-11\")\n", + "@file:DependsOn(\"io.ktor:ktor-server-cio-jvm:2.3.0\")\n", + "@file:DependsOn(\"io.ktor:ktor-server-websockets-jvm:2.3.0\")\n", + "@file:DependsOn(\"io.ktor:ktor-server-cors-jvm:2.3.0\")" ] }, { "cell_type": "code", "execution_count": null, - "outputs": [], - "source": [ - ":classpath" - ], "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": null, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ + "import io.ktor.server.cio.CIO\n", + "\n", + "println(CIO)\n", + "\n", "vf.startServer()" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "import space.kscience.visionforge.plotly.plotly\n", + "import space.kscience.plotly.*\n", + "import space.kscience.plotly.models.*\n", "\n", "vf.page {\n", " h1 { +\"AAA\" }\n", @@ -65,19 +70,19 @@ " }\n", " }\n", "}" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, - "outputs": [], - "source": [], "metadata": { - "collapsed": false - } + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [] } ], "metadata": { @@ -86,19 +91,19 @@ "language": "kotlin", "name": "kotlin" }, + "ktnbPluginMetadata": { + "isAddProjectLibrariesToClasspath": false + }, "language_info": { - "name": "kotlin", - "version": "1.8.20", - "mimetype": "text/x-kotlin", + "codemirror_mode": "text/x-kotlin", "file_extension": ".kt", + "mimetype": "text/x-kotlin", + "name": "kotlin", + "nbconvert_exporter": "", "pygments_lexer": "kotlin", - "codemirror_mode": "text/x-kotlin", - "nbconvert_exporter": "" - }, - "ktnbPluginMetadata": { - "isAddProjectLibrariesToClasspath": false + "version": "1.8.20" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 4 } diff --git a/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts b/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts index c71b33d0..e6fd162b 100644 --- a/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts +++ b/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts @@ -18,15 +18,15 @@ kscience { } dependencies { - implementation(projects.visionforgeSolid) - implementation(projects.visionforgePlotly) - implementation(projects.visionforgeTables) - implementation(projects.visionforgeMarkdown) - implementation(projects.visionforgeJupyter) + api(projects.visionforgeSolid) + api(projects.visionforgePlotly) + api(projects.visionforgeTables) + api(projects.visionforgeMarkdown) + api(projects.visionforgeJupyter) } jvmMain { - implementation(projects.visionforgeGdml) + api(projects.visionforgeGdml) } jsMain { diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index 00331969..59034dd1 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -9,7 +9,7 @@ kscience{ api("io.ktor:ktor-server-host-common") api("io.ktor:ktor-server-html-builder") api("io.ktor:ktor-server-websockets") - implementation("io.ktor:ktor-server-cors") + api("io.ktor:ktor-server-cors") } } From 5783cf14300249f4d52599af25754178cfbbfdca Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 20 Jul 2023 08:58:41 +0300 Subject: [PATCH 074/112] Work-around for strange dependency resolution in notebooks --- demo/playground/notebooks/common-demo.ipynb | 34 ++++++++++++++++----- visionforge-jupyter/build.gradle.kts | 4 ++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/demo/playground/notebooks/common-demo.ipynb b/demo/playground/notebooks/common-demo.ipynb index 2c397a15..165acf2d 100644 --- a/demo/playground/notebooks/common-demo.ipynb +++ b/demo/playground/notebooks/common-demo.ipynb @@ -1,5 +1,16 @@ { "cells": [ + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "//SessionOptions.resolveMpp = true" + ], + "metadata": { + "collapsed": false + } + }, { "cell_type": "code", "execution_count": null, @@ -10,9 +21,9 @@ "@file:Repository(\"https://repo.kotlin.link\")\n", "@file:Repository(\"https://maven.pkg.jetbrains.space/spc/p/sci/dev\")\n", "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-11\")\n", - "@file:DependsOn(\"io.ktor:ktor-server-cio-jvm:2.3.0\")\n", - "@file:DependsOn(\"io.ktor:ktor-server-websockets-jvm:2.3.0\")\n", - "@file:DependsOn(\"io.ktor:ktor-server-cors-jvm:2.3.0\")" + "//@file:DependsOn(\"io.ktor:ktor-server-cio-jvm:2.3.0\")\n", + "//@file:DependsOn(\"io.ktor:ktor-server-websockets-jvm:2.3.0\")\n", + "//@file:DependsOn(\"io.ktor:ktor-server-cors-jvm:2.3.0\")" ] }, { @@ -26,10 +37,6 @@ }, "outputs": [], "source": [ - "import io.ktor.server.cio.CIO\n", - "\n", - "println(CIO)\n", - "\n", "vf.startServer()" ] }, @@ -82,7 +89,18 @@ } }, "outputs": [], - "source": [] + "source": [ + "vf.stopServer()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + } } ], "metadata": { diff --git a/visionforge-jupyter/build.gradle.kts b/visionforge-jupyter/build.gradle.kts index ed4ab76d..49943631 100644 --- a/visionforge-jupyter/build.gradle.kts +++ b/visionforge-jupyter/build.gradle.kts @@ -13,7 +13,9 @@ kscience { api(projects.visionforgeCore) } dependencies(jvmMain){ - api("io.ktor:ktor-server-cio") + api("io.ktor:ktor-server-cio-jvm") + api("io.ktor:ktor-server-websockets-jvm") + api("io.ktor:ktor-server-cors-jvm") api(projects.visionforgeServer) } } From a49a4f1a7f5ede88dee8a171a035476cd4e9371c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 20 Jul 2023 09:13:24 +0300 Subject: [PATCH 075/112] add plotly imports --- demo/playground/notebooks/common-demo.ipynb | 65 ++++++++++++------- .../kotlin/JupyterCommonIntegration.kt | 3 + 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/demo/playground/notebooks/common-demo.ipynb b/demo/playground/notebooks/common-demo.ipynb index 165acf2d..2e4b6110 100644 --- a/demo/playground/notebooks/common-demo.ipynb +++ b/demo/playground/notebooks/common-demo.ipynb @@ -2,59 +2,76 @@ "cells": [ { "cell_type": "code", - "execution_count": null, - "outputs": [], - "source": [ - "//SessionOptions.resolveMpp = true" - ], + "execution_count": 2, "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, + "ExecuteTime": { + "end_time": "2023-07-20T06:12:13.305060400Z", + "start_time": "2023-07-20T06:12:13.011273800Z" + } + }, "outputs": [], "source": [ "@file:Repository(\"*mavenLocal\")\n", "@file:Repository(\"https://repo.kotlin.link\")\n", "@file:Repository(\"https://maven.pkg.jetbrains.space/spc/p/sci/dev\")\n", - "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-11\")\n", - "//@file:DependsOn(\"io.ktor:ktor-server-cio-jvm:2.3.0\")\n", - "//@file:DependsOn(\"io.ktor:ktor-server-websockets-jvm:2.3.0\")\n", - "//@file:DependsOn(\"io.ktor:ktor-server-cors-jvm:2.3.0\")" + "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-11\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false + }, + "ExecuteTime": { + "end_time": "2023-07-20T06:12:19.603077Z", + "start_time": "2023-07-20T06:12:19.419504300Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": "

Starting VisionForge server on http://localhost:7777

\n" + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "vf.startServer()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false + }, + "ExecuteTime": { + "end_time": "2023-07-20T06:12:21.490069100Z", + "start_time": "2023-07-20T06:12:20.694188600Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": "
\n

AAA

\n
\n \n
\n
\n \n
\n
\n\n" + }, + "execution_count": 4, + "metadata": { + "text/html": { + "isolated": true + } + }, + "output_type": "execute_result" + } + ], "source": [ - "import space.kscience.visionforge.plotly.plotly\n", - "import space.kscience.plotly.*\n", - "import space.kscience.plotly.models.*\n", - "\n", "vf.page {\n", " h1 { +\"AAA\" }\n", " vision {\n", diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt index 6bca7036..54f2e266 100644 --- a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt @@ -33,6 +33,9 @@ public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionMan "space.kscience.visionforge.solid.*", "space.kscience.tables.*", "space.kscience.dataforge.meta.*", + "space.kscience.plotly.*", + "space.kscience.plotly.models.*", + "space.kscience.visionforge.plotly.plotly" ) render { gdmlModel -> From b3f68d879fd8be470f62f9aaf2567626491484f7 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 22 Jul 2023 15:39:43 +0300 Subject: [PATCH 076/112] Jupyter renderers are working for lab and Idea --- build.gradle.kts | 2 +- demo/playground/build.gradle.kts | 2 +- demo/playground/notebooks/common-demo.ipynb | 85 +++------- .../visionforge/react/ThreeCanvasComponent.kt | 3 +- .../kscience/visionforge/html/HtmlFragment.kt | 31 ++-- .../visionforge/html/HtmlVisionRenderer.kt | 11 +- .../kscience/visionforge/html/VisionPage.kt | 6 +- .../kscience/visionforge/html/HtmlTagTest.kt | 4 +- .../kscience/visionforge/VisionClient.kt | 4 +- .../visionforge/html/HtmlVisionContext.kt | 8 +- .../kscience/visionforge/html/headers.kt | 6 +- .../kscience/visionforge/html/htmlExport.kt | 2 +- .../src/jsMain/kotlin/VFNotebookClient.kt | 5 +- .../src/jvmMain/kotlin/VisionForge.kt | 158 +++++++++++------- .../jvmMain/kotlin/VisionForgeIntegration.kt | 53 ++++-- .../kotlin/JupyterCommonIntegration.kt | 24 ++- .../visionforge/three/TestServerExtensions.kt | 3 +- 17 files changed, 223 insertions(+), 184 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 73f03bbd..35502755 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-11" + version = "0.3.0-dev-12" } subprojects { diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index 77dd565e..36bd6b7b 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -51,7 +51,7 @@ kotlin { implementation(projects.visionforgeMarkdown) implementation(projects.visionforgeTables) implementation(projects.cernRootLoader) - implementation(projects.visionforgeJupyter.visionforgeJupyterCommon) + api(projects.visionforgeJupyter.visionforgeJupyterCommon) } } diff --git a/demo/playground/notebooks/common-demo.ipynb b/demo/playground/notebooks/common-demo.ipynb index 2e4b6110..78797545 100644 --- a/demo/playground/notebooks/common-demo.ipynb +++ b/demo/playground/notebooks/common-demo.ipynb @@ -2,77 +2,31 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { - "ExecuteTime": { - "end_time": "2023-07-20T06:12:13.305060400Z", - "start_time": "2023-07-20T06:12:13.011273800Z" - } + "tags": [] }, "outputs": [], "source": [ "@file:Repository(\"*mavenLocal\")\n", "@file:Repository(\"https://repo.kotlin.link\")\n", "@file:Repository(\"https://maven.pkg.jetbrains.space/spc/p/sci/dev\")\n", - "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-11\")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "ExecuteTime": { - "end_time": "2023-07-20T06:12:19.603077Z", - "start_time": "2023-07-20T06:12:19.419504300Z" - } - }, - "outputs": [ - { - "data": { - "text/html": "

Starting VisionForge server on http://localhost:7777

\n" - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vf.startServer()" + "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-12\")\n", + "//import space.kscience.visionforge.jupyter.JupyterCommonIntegration\n", + "//\n", + "//val integration = JupyterCommonIntegration()\n", + "//USE(integration.getDefinitions(notebook).first())" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - }, - "ExecuteTime": { - "end_time": "2023-07-20T06:12:21.490069100Z", - "start_time": "2023-07-20T06:12:20.694188600Z" - } + "tags": [] }, - "outputs": [ - { - "data": { - "text/html": "
\n

AAA

\n
\n \n
\n
\n \n
\n
\n\n" - }, - "execution_count": 4, - "metadata": { - "text/html": { - "isolated": true - } - }, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "vf.page {\n", + "vf.fragment {\n", " h1 { +\"AAA\" }\n", " vision {\n", " solid {\n", @@ -100,24 +54,27 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ - "vf.stopServer()" + "Plotly.plot { \n", + " scatter{\n", + " x(1,2,3)\n", + " y(1,2,3)\n", + " }\n", + "}" ] }, { "cell_type": "code", "execution_count": null, + "metadata": {}, "outputs": [], - "source": [], - "metadata": { - "collapsed": false - } + "source": [] } ], "metadata": { diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt index 50c8a60a..8cfa515d 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.react import kotlinx.css.* import org.w3c.dom.Element -import org.w3c.dom.HTMLElement import react.* import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.request @@ -29,7 +28,7 @@ public val ThreeCanvasComponent: FC = fc("ThreeCanvasComponent useEffect(props.solid, props.options, elementRef) { if (canvas == null) { - val element = elementRef.current as? HTMLElement ?: error("Canvas element not found") + val element = elementRef.current ?: error("Canvas element not found") canvas = ThreeCanvas(three, element, props.options ?: Canvas3DOptions()) } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlFragment.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlFragment.kt index b733e6a4..ec3f3605 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlFragment.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlFragment.kt @@ -4,19 +4,28 @@ import kotlinx.html.FlowContent import kotlinx.html.TagConsumer import kotlinx.html.stream.createHTML -public typealias HtmlFragment = TagConsumer<*>.() -> Unit +/** + * A standalone HTML fragment + */ +public fun interface HtmlFragment { + public fun TagConsumer<*>.append() +} -public fun HtmlFragment.renderToString(): String = createHTML().apply(this).finalize() +/** + * Convenience method to append fragment to the given [consumer] + */ +public fun HtmlFragment.appendTo(consumer: TagConsumer<*>): Unit = consumer.append() -public fun TagConsumer<*>.fragment(fragment: HtmlFragment) { - fragment() -} +/** + * Create a string from this [HtmlFragment] + */ +public fun HtmlFragment.renderToString(): String = createHTML().apply { append() }.finalize() -public fun FlowContent.fragment(fragment: HtmlFragment) { - fragment(consumer) -} +public fun TagConsumer<*>.appendFragment(fragment: HtmlFragment): Unit = fragment.appendTo(this) + +public fun FlowContent.appendFragment(fragment: HtmlFragment): Unit = fragment.appendTo(consumer) -public operator fun HtmlFragment.plus(other: HtmlFragment): HtmlFragment = { - this@plus() - other() +public operator fun HtmlFragment.plus(other: HtmlFragment): HtmlFragment = HtmlFragment { + this@plus.appendTo(this) + other.appendTo(this) } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt index d3c2427f..c02b6e64 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt @@ -2,18 +2,17 @@ package space.kscience.visionforge.html import kotlinx.html.* import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager -public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit - -@DFExperimental -public fun HtmlVisionFragment(content: VisionTagConsumer<*>.() -> Unit): HtmlVisionFragment = content +public fun interface HtmlVisionFragment{ + public fun VisionTagConsumer<*>.append() +} +public fun HtmlVisionFragment.appendTo(consumer: VisionTagConsumer<*>): Unit = consumer.append() /** * Render a fragment in the given consumer and return a map of extracted visions @@ -84,7 +83,7 @@ public fun TagConsumer<*>.visionFragment( } } - fragment(consumer) + fragment.appendTo(consumer) } public fun FlowContent.visionFragment( diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt index f92454f0..1ea216c5 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt @@ -17,7 +17,7 @@ public data class VisionPage( /** * Use a script with given [src] as a global header for all pages. */ - public fun scriptHeader(src: String, block: SCRIPT.() -> Unit = {}): HtmlFragment = { + public fun scriptHeader(src: String, block: SCRIPT.() -> Unit = {}): HtmlFragment = HtmlFragment{ script { type = "text/javascript" this.src = src @@ -28,7 +28,7 @@ public data class VisionPage( /** * Use css with the given stylesheet link as a global header for all pages. */ - public fun styleSheetHeader(href: String, block: LINK.() -> Unit = {}): HtmlFragment = { + public fun styleSheetHeader(href: String, block: LINK.() -> Unit = {}): HtmlFragment = HtmlFragment{ link { rel = "stylesheet" this.href = href @@ -36,7 +36,7 @@ public data class VisionPage( } } - public fun title(title:String): HtmlFragment = { + public fun title(title:String): HtmlFragment = HtmlFragment{ title(title) } } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index efc7cfd0..eaea0a4e 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -24,7 +24,7 @@ fun FlowContent.renderVisionFragment( renderer(name, vision, outputMeta) } } - fragment(consumer) + fragment.appendTo(consumer) return visionMap } @@ -35,7 +35,7 @@ private fun VisionOutput.base(block: VisionGroup.() -> Unit) = context.visionMan @DFExperimental class HtmlTagTest { - val fragment: HtmlVisionFragment = { + val fragment = HtmlVisionFragment{ div { h1 { +"Head" } vision("ddd") { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index 7d61ce24..c9146efd 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -286,8 +286,8 @@ public fun VisionClient.renderAllVisionsIn(element: Element) { /** * Render all visions in an element with a given [id] */ -public fun VisionClient.renderAllVisionsById(id: String): Unit = whenDocumentLoaded { - val element = getElementById(id) +public fun VisionClient.renderAllVisionsById(document: Document, id: String): Unit { + val element = document.getElementById(id) if (element != null) { renderAllVisionsIn(element) } else { diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt index 7d82da49..3796d436 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt @@ -34,10 +34,10 @@ public interface HtmlVisionContext : ContextAware { public typealias HtmlVisionContextFragment = context(HtmlVisionContext) TagConsumer<*>.() -> Unit -context(HtmlVisionContext) -public fun HtmlVisionFragment( - content: TagConsumer<*>.() -> Unit, -): HtmlVisionFragment = content +//context(HtmlVisionContext) +//public fun HtmlVisionFragment( +// content: TagConsumer<*>.() -> Unit, +//): HtmlVisionFragment = HtmlVisionFragment { } context(HtmlVisionContext) private fun TagConsumer.vision( diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt index 4c4ab90a..bf880e84 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt @@ -91,14 +91,14 @@ internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String, */ internal fun fileScriptHeader( path: Path, -): HtmlFragment = { +): HtmlFragment = HtmlFragment{ script { type = "text/javascript" src = path.toString() } } -internal fun embedScriptHeader(resource: String, classLoader: ClassLoader): HtmlFragment = { +internal fun embedScriptHeader(resource: String, classLoader: ClassLoader): HtmlFragment = HtmlFragment{ script { type = "text/javascript" unsafe { @@ -113,7 +113,7 @@ internal fun fileCssHeader( cssPath: Path, resource: String, classLoader: ClassLoader, -): HtmlFragment = { +): HtmlFragment = HtmlFragment{ val relativePath = checkOrStoreFile(basePath, cssPath, resource, classLoader) link { rel = "stylesheet" diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index ec31b7b4..e45dd9b5 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -78,7 +78,7 @@ public fun VisionPage.makeFile( charset = "utf-8" } actualHeaders.values.forEach { - fragment(it) + appendFragment(it) } } body { diff --git a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt index 24304136..84c6908b 100644 --- a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt +++ b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt @@ -1,6 +1,7 @@ package space.kscience.visionforge.jupyter import kotlinx.browser.window +import org.w3c.dom.Document import org.w3c.dom.Element import space.kscience.dataforge.context.AbstractPlugin import space.kscience.dataforge.context.Context @@ -20,8 +21,8 @@ public class VFNotebookClient : AbstractPlugin() { client.renderAllVisionsIn(element) } - public fun renderAllVisionsById(id: String) { - client.renderAllVisionsById(id) + public fun renderAllVisionsById(document: Document, id: String) { + client.renderAllVisionsById(document, id) } public fun renderAllVisions() { diff --git a/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt index 0a538a3e..d2acefde 100644 --- a/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.html.* import kotlinx.html.stream.createHTML import org.jetbrains.kotlinx.jupyter.api.HTML +import org.jetbrains.kotlinx.jupyter.api.KotlinKernelHost import org.jetbrains.kotlinx.jupyter.api.MimeTypedResult import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware @@ -20,24 +21,33 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.visionFragment +import space.kscience.visionforge.html.* import space.kscience.visionforge.server.VisionRoute import space.kscience.visionforge.server.serveVisionData import kotlin.coroutines.CoroutineContext import kotlin.random.Random import kotlin.random.nextUInt -internal fun TagConsumer<*>.renderScriptForId(id: String) { - script { - type = "text/javascript" - unsafe { +"VisionForge.renderAllVisionsById(\"$id\");" } - } + +@Suppress("FunctionName") +internal inline fun HTML(isolated: Boolean = false, block: TagConsumer<*>.() -> Unit): MimeTypedResult = + HTML(createHTML().apply(block).finalize(), isolated) + +internal fun KotlinKernelHost.displayHtml(block: TagConsumer<*>.() -> Unit) { + display(HTML(false, block), null) +} + +public enum class VisionForgeCompatibility { + JUPYTER, + JUPYTER_LAB, + DATALORE, + IDEA } /** * A handler class that includes a server and common utilities */ +@Suppress("ExtractKtorModule") public class VisionForge( public val visionManager: VisionManager, meta: Meta = Meta.EMPTY, @@ -51,29 +61,28 @@ public class VisionForge( private var engine: ApplicationEngine? = null - public var isolateFragments: Boolean = false + public var notebookMode: VisionForgeCompatibility = VisionForgeCompatibility.IDEA override val coroutineContext: CoroutineContext get() = context.coroutineContext - public fun legacyMode() { - isolateFragments = true - } public fun isServerRunning(): Boolean = engine != null - public fun html(block: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(createHTML().apply(block).finalize()) - public fun getProperty(name: String): TypedMeta<*>? = configuration[name] ?: context.properties[name] - public fun startServer( + internal fun startServer( + kernel: KotlinKernelHost, host: String = getProperty("visionforge.host").string ?: "localhost", port: Int = getProperty("visionforge.port").int ?: VisionRoute.DEFAULT_PORT, - ): MimeTypedResult = html { + ) { if (engine != null) { - p { - style = "color: red;" - +"Stopping current VisionForge server" + kernel.displayHtml { + p { + style = "color: red;" + +"Stopping current VisionForge server" + } } + } //val connector: EngineConnectorConfig = EngineConnectorConfig(host, port) @@ -83,66 +92,91 @@ public class VisionForge( install(WebSockets) }.start(false) - p { - style = "color: blue;" - +"Starting VisionForge server on http://$host:$port" + kernel.displayHtml { + p { + style = "color: blue;" + +"Starting VisionForge server on port $port" + } } } - public fun stopServer() { + internal fun stopServer(kernel: KotlinKernelHost) { engine?.apply { logger.info { "Stopping VisionForge server" } stop(1000, 2000) engine = null } - } - - private fun produceHtmlString( - fragment: HtmlVisionFragment, - ): String = createHTML().apply { - val id = "fragment[${fragment.hashCode()}/${Random.nextUInt()}]" - div { - this.id = id - val engine = engine - if (engine != null) { - //if server exist, serve dynamically - //server.serveVisionsFromFragment(consumer, "content-${counter++}", fragment) - val cellRoute = "content-${counter++}" - - val collector: MutableMap = mutableMapOf() - - val url = engine.environment.connectors.first().let { - url { - protocol = URLProtocol.WS - host = it.host - port = it.port - pathSegments = listOf(cellRoute, "ws") - } - } - engine.application.serveVisionData(VisionRoute(cellRoute, visionManager), collector) + kernel.displayHtml { + p { + style = "color: red;" + +"VisionForge server stopped" + } + } + } - visionFragment( - visionManager, - embedData = true, - updatesUrl = url, - onVisionRendered = { name, vision -> collector[name] = vision }, - fragment = fragment - ) + internal fun TagConsumer<*>.renderScriptForId(id: String, iframeIsolation: Boolean = false) { + script { + type = "text/javascript" + if (iframeIsolation) { + //language=JavaScript + unsafe { +"parent.VisionForge.renderAllVisionsById(document, \"$id\");" } } else { - //if not, use static rendering - visionFragment(visionManager, fragment = fragment) + //language=JavaScript + unsafe { +"VisionForge.renderAllVisionsById(document, \"$id\");" } } } - renderScriptForId(id) - }.finalize() + } - public fun produceHtml(isolated: Boolean? = null, fragment: HtmlVisionFragment): MimeTypedResult = - HTML(produceHtmlString(fragment), isolated ?: isolateFragments) - public fun fragment(body: HtmlVisionFragment): MimeTypedResult = produceHtml(fragment = body) - public fun page(body: HtmlVisionFragment): MimeTypedResult = produceHtml(true, body) + public fun produceHtml( + isolated: Boolean? = null, + fragment: HtmlVisionFragment, + ): MimeTypedResult { + val iframeIsolation = isolated + ?: (notebookMode == VisionForgeCompatibility.JUPYTER || notebookMode == VisionForgeCompatibility.DATALORE) + return HTML( + iframeIsolation + ) { + val id = "fragment[${fragment.hashCode()}/${Random.nextUInt()}]" + div { + this.id = id + val engine = engine + if (engine != null) { + //if server exist, serve dynamically + //server.serveVisionsFromFragment(consumer, "content-${counter++}", fragment) + val cellRoute = "content-${counter++}" + + val collector: MutableMap = mutableMapOf() + + val url = engine.environment.connectors.first().let { + url { + protocol = URLProtocol.WS + host = it.host + port = it.port + pathSegments = listOf(cellRoute, "ws") + } + } + + engine.application.serveVisionData(VisionRoute(cellRoute, visionManager), collector) + + visionFragment( + visionManager, + embedData = true, + updatesUrl = url, + onVisionRendered = { name, vision -> collector[name] = vision }, + fragment = fragment + ) + } else { + //if not, use static rendering + visionFragment(visionManager, fragment = fragment) + } + } + renderScriptForId(id, iframeIsolation = iframeIsolation) + } + } public fun form(builder: FORM.() -> Unit): HtmlFormFragment = HtmlFormFragment("form[${counter++}]", builder = builder) } + diff --git a/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt index 3029ef32..e7175dd0 100644 --- a/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt @@ -1,8 +1,7 @@ package space.kscience.visionforge.jupyter import kotlinx.html.* -import kotlinx.html.stream.createHTML -import org.jetbrains.kotlinx.jupyter.api.HTML +import org.jetbrains.kotlinx.jupyter.api.MimeTypedResult import org.jetbrains.kotlinx.jupyter.api.declare import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration import space.kscience.dataforge.context.Context @@ -31,11 +30,12 @@ public abstract class VisionForgeIntegration( onLoaded { declare("VisionForge" to handler, "vf" to handler) + handler.startServer(this) } onShutdown { - handler.stopServer() + handler.stopServer(this) } import( @@ -43,14 +43,14 @@ public abstract class VisionForgeIntegration( "space.kscience.visionforge.html.*", "space.kscience.visionforge.jupyter.*" ) - - render { fragment -> - handler.produceHtml(fragment = fragment) - } - - render { fragment -> - handler.produceHtml(fragment = fragment) - } +// +// render { fragment -> +// HTML(fragment.renderToString()) +// } +// +// render { fragment -> +// handler.produceHtml(fragment = fragment) +// } render { vision -> handler.produceHtml { @@ -59,13 +59,13 @@ public abstract class VisionForgeIntegration( } render { page -> - HTML(createHTML().apply { + HTML(true) { head { meta { charset = "utf-8" } page.pageHeaders.values.forEach { - fragment(it) + appendFragment(it) } } body { @@ -74,9 +74,11 @@ public abstract class VisionForgeIntegration( this.id = id visionFragment(visionManager, fragment = page.content) } - renderScriptForId(id) + with(handler) { + renderScriptForId(id, true) + } } - }.finalize(), true) + } } render { fragment -> @@ -87,7 +89,7 @@ public abstract class VisionForgeIntegration( +"The server is not running. Forms are not interactive. Start server with `VisionForge.startServer()." } } - fragment(fragment.formBody) + appendFragment(fragment.formBody) vision(fragment.vision) } } @@ -96,10 +98,25 @@ public abstract class VisionForgeIntegration( } } + +/** + * Create a fragment without a head to be embedded in the page + */ +@Suppress("UnusedReceiverParameter") +public fun VisionForge.html(body: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(false, body) + + +/** + * Create a fragment without a head to be embedded in the page + */ +public fun VisionForge.fragment(body: VisionTagConsumer<*>.() -> Unit): MimeTypedResult = produceHtml(false, body) + + /** * Create a standalone page in the notebook */ public fun VisionForge.page( pageHeaders: Map = emptyMap(), - content: HtmlVisionFragment -): VisionPage = VisionPage(visionManager, pageHeaders, content) \ No newline at end of file + body: VisionTagConsumer<*>.() -> Unit, +): VisionPage = VisionPage(visionManager, pageHeaders, body) + diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt index 54f2e266..c326a816 100644 --- a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt @@ -6,8 +6,12 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.misc.DFExperimental import space.kscience.gdml.Gdml import space.kscience.plotly.Plot +import space.kscience.plotly.PlotlyPage +import space.kscience.plotly.StaticPlotlyRenderer import space.kscience.tables.* import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.html.HtmlFragment +import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.plotly.asVision @@ -23,7 +27,7 @@ public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionMan override fun Builder.afterLoaded() { resources { - js("three") { + js("visionforge-common") { classPath("js/visionforge-jupyter-common.js") } } @@ -55,6 +59,24 @@ public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionMan vision { plot.asVision() } } } + + + render { plotlyPage -> + val headers = plotlyPage.headers.associate { plotlyFragment -> + plotlyFragment.hashCode().toString(16) to HtmlFragment { + plotlyFragment.visit(this) + } + + } + VisionPage(visionManager, headers) { + div{ + p { +"Plotly page renderer is not recommended in VisionForge, use `vf.page{}`" } + } + div { + plotlyPage.fragment.render.invoke(this, StaticPlotlyRenderer) + } + } + } } public companion object { diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt index ef4eb39b..95d9e6f7 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt @@ -3,6 +3,7 @@ package space.kscience.visionforge.three import kotlinx.html.stream.createHTML import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.html.appendTo import space.kscience.visionforge.html.importScriptHeader import kotlin.test.Test @@ -15,7 +16,7 @@ class TestServerExtensions { VisionPage.importScriptHeader( "js/visionforge-three.js", ResourceLocation.SYSTEM - ).invoke(this) + ).appendTo(this) }.finalize() From ed491bdae093d5e54ba5f6289d3350a3cd94f7b6 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 22 Jul 2023 18:25:11 +0300 Subject: [PATCH 077/112] cleanup --- .../src/jsMain/kotlin/VFNotebookClient.kt | 5 +-- .../src/jvmMain/kotlin/VisionForge.kt | 35 ++++++++----------- .../jvmMain/kotlin/VisionForgeIntegration.kt | 33 +++++++++++------ .../kotlin/JupyterCommonIntegration.kt | 8 ++--- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt index 84c6908b..7f06c6ac 100644 --- a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt +++ b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt @@ -31,9 +31,10 @@ public class VFNotebookClient : AbstractPlugin() { init { + console.info("Loading VisionForge global hooks") //register VisionForge in the browser window - window.asDynamic().vf = this - window.asDynamic().VisionForge = this + window.parent.asDynamic().vf = this + window.parent.asDynamic().VisionForge = this } @Suppress("NON_EXPORTABLE_TYPE") diff --git a/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt index d2acefde..49d5fe23 100644 --- a/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt @@ -10,9 +10,7 @@ import io.ktor.server.websocket.WebSockets import kotlinx.coroutines.CoroutineScope import kotlinx.html.* import kotlinx.html.stream.createHTML -import org.jetbrains.kotlinx.jupyter.api.HTML -import org.jetbrains.kotlinx.jupyter.api.KotlinKernelHost -import org.jetbrains.kotlinx.jupyter.api.MimeTypedResult +import org.jetbrains.kotlinx.jupyter.api.* import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.context.info @@ -21,7 +19,8 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.html.* +import space.kscience.visionforge.html.HtmlVisionFragment +import space.kscience.visionforge.html.visionFragment import space.kscience.visionforge.server.VisionRoute import space.kscience.visionforge.server.serveVisionData import kotlin.coroutines.CoroutineContext @@ -50,6 +49,7 @@ public enum class VisionForgeCompatibility { @Suppress("ExtractKtorModule") public class VisionForge( public val visionManager: VisionManager, + public val notebook: Notebook, meta: Meta = Meta.EMPTY, ) : ContextAware, CoroutineScope { @@ -61,8 +61,6 @@ public class VisionForge( private var engine: ApplicationEngine? = null - public var notebookMode: VisionForgeCompatibility = VisionForgeCompatibility.IDEA - override val coroutineContext: CoroutineContext get() = context.coroutineContext @@ -75,19 +73,19 @@ public class VisionForge( host: String = getProperty("visionforge.host").string ?: "localhost", port: Int = getProperty("visionforge.port").int ?: VisionRoute.DEFAULT_PORT, ) { - if (engine != null) { + engine?.let { kernel.displayHtml { p { style = "color: red;" +"Stopping current VisionForge server" } } - + it.stop(1000, 2000) } //val connector: EngineConnectorConfig = EngineConnectorConfig(host, port) - engine?.stop(1000, 2000) + engine = context.embeddedServer(CIO, port, host) { install(WebSockets) }.start(false) @@ -115,16 +113,11 @@ public class VisionForge( } } - internal fun TagConsumer<*>.renderScriptForId(id: String, iframeIsolation: Boolean = false) { + internal fun TagConsumer<*>.renderScriptForId(id: String) { script { type = "text/javascript" - if (iframeIsolation) { - //language=JavaScript - unsafe { +"parent.VisionForge.renderAllVisionsById(document, \"$id\");" } - } else { - //language=JavaScript - unsafe { +"VisionForge.renderAllVisionsById(document, \"$id\");" } - } + //language=JavaScript + unsafe { +"parent.VisionForge.renderAllVisionsById(document, \"$id\");" } } } @@ -133,8 +126,10 @@ public class VisionForge( isolated: Boolean? = null, fragment: HtmlVisionFragment, ): MimeTypedResult { - val iframeIsolation = isolated - ?: (notebookMode == VisionForgeCompatibility.JUPYTER || notebookMode == VisionForgeCompatibility.DATALORE) + val iframeIsolation = isolated ?: when (notebook.jupyterClientType) { + JupyterClientType.DATALORE, JupyterClientType.JUPYTER_NOTEBOOK -> true + else -> false + } return HTML( iframeIsolation ) { @@ -172,7 +167,7 @@ public class VisionForge( visionFragment(visionManager, fragment = fragment) } } - renderScriptForId(id, iframeIsolation = iframeIsolation) + renderScriptForId(id) } } diff --git a/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt index e7175dd0..afc2ecc2 100644 --- a/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt @@ -1,6 +1,7 @@ package space.kscience.visionforge.jupyter import kotlinx.html.* +import org.jetbrains.kotlinx.jupyter.api.KotlinKernelHost import org.jetbrains.kotlinx.jupyter.api.MimeTypedResult import org.jetbrains.kotlinx.jupyter.api.declare import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration @@ -22,20 +23,30 @@ public abstract class VisionForgeIntegration( ) : JupyterIntegration(), ContextAware { override val context: Context get() = visionManager.context - protected val handler: VisionForge = VisionForge(visionManager) - protected abstract fun Builder.afterLoaded() + protected abstract fun Builder.afterLoaded(vf: VisionForge) final override fun Builder.onLoaded() { + val vf: VisionForge = VisionForge(visionManager, notebook) + onLoaded { - declare("VisionForge" to handler, "vf" to handler) - handler.startServer(this) + val kernel: KotlinKernelHost = this + declare("VisionForge" to vf, "vf" to vf) + vf.startServer(kernel) + vf.configuration.onChange(this) { name -> + if (name.toString() == "visionforge.port") { + kernel.displayHtml { + p { +"Property 'visionforge.port' changed. Restarting server" } + } + vf.startServer(kernel) + } + } } onShutdown { - handler.stopServer(this) + vf.stopServer(this) } import( @@ -53,7 +64,7 @@ public abstract class VisionForgeIntegration( // } render { vision -> - handler.produceHtml { + vf.produceHtml { vision(vision) } } @@ -74,16 +85,16 @@ public abstract class VisionForgeIntegration( this.id = id visionFragment(visionManager, fragment = page.content) } - with(handler) { - renderScriptForId(id, true) + with(vf) { + renderScriptForId(id) } } } } render { fragment -> - handler.produceHtml { - if (!handler.isServerRunning()) { + vf.produceHtml { + if (!vf.isServerRunning()) { p { style = "color: red;" +"The server is not running. Forms are not interactive. Start server with `VisionForge.startServer()." @@ -94,7 +105,7 @@ public abstract class VisionForgeIntegration( } } - afterLoaded() + afterLoaded(vf) } } diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt index c326a816..6200bd5d 100644 --- a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt @@ -24,7 +24,7 @@ import space.kscience.visionforge.visionManager @DFExperimental public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionManager) { - override fun Builder.afterLoaded() { + override fun Builder.afterLoaded(vf: VisionForge) { resources { js("visionforge-common") { @@ -43,19 +43,19 @@ public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionMan ) render { gdmlModel -> - handler.produceHtml { + vf.produceHtml { vision { gdmlModel.toVision() } } } render> { table -> - handler.produceHtml { + vf.produceHtml { vision { table.toVision() } } } render { plot -> - handler.produceHtml { + vf.produceHtml { vision { plot.asVision() } } } From f5fba4747eb6e107b761f0c8cd6513cbb7236dc6 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 25 Jul 2023 13:35:55 +0300 Subject: [PATCH 078/112] Some refactoring and new server demo --- CHANGELOG.md | 2 + build.gradle.kts | 2 +- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 2 +- .../visionforge/gdml/demo/GDMLAppComponent.kt | 4 +- .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 4 +- .../src/main/kotlin/JsPlaygroundApp.kt | 4 +- .../src/main/kotlin/gravityDemo.kt | 4 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 6 +- .../mipt/npm/muon/monitor/MMAppComponent.kt | 4 +- demo/playground/src/jvmMain/kotlin/antenna.kt | 91 +++++++++++++++---- .../src/jvmMain/kotlin/gdmlCurve.kt | 4 +- .../src/jvmMain/kotlin/randomSpheres.kt | 4 +- .../src/jvmMain/kotlin/rootParser.kt | 4 +- .../src/jvmMain/kotlin/serverExtensions.kt | 52 +++++++++++ demo/playground/src/jvmMain/kotlin/shapes.kt | 8 +- .../src/jvmMain/kotlin/simpleCube.kt | 4 +- .../main/kotlin/ru/mipt/npm/sat/geometry.kt | 2 +- .../main/kotlin/ru/mipt/npm/sat/satServer.kt | 4 +- .../src/main/kotlin/ru/mipt/npm/sat/static.kt | 4 +- .../kscience/visionforge/solid/demo/demo.kt | 30 +++--- .../ThreeWithControlsPlugin.kt | 18 +++- .../visionforge/gdml/GdmlLoaderOptions.kt | 2 +- .../visionforge/server/VisionServer.kt | 6 +- .../visionforge/solid/ColorAccessor.kt | 8 +- .../kscience/visionforge/solid/LightSource.kt | 2 +- .../kscience/visionforge/solid/SolidGroup.kt | 5 + .../kscience/visionforge/solid/Solids.kt | 4 + .../visionforge/solid/CompositeTest.kt | 2 +- .../kscience/visionforge/solid/GroupTest.kt | 6 +- .../visionforge/solid/SerializationTest.kt | 6 +- .../visionforge/solid/SolidPropertyTest.kt | 4 +- .../visionforge/solid/SolidReferenceTest.kt | 2 +- .../visionforge/solid/VisionUpdateTest.kt | 4 +- 33 files changed, 215 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afc740a3..dbb44a80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - MeshLine for thick lines ### Changed +- Color accessor property is now `colorProperty`. Color uses `invoke` instead of `set` - API update for server and pages - Edges moved to solids module for easier construction - Visions **must** be rooted in order to subscribe to updates. @@ -20,6 +21,7 @@ ### Removed ### Fixed +- Jupyter integration for IDEA and Jupyter lab. ### Security diff --git a/build.gradle.kts b/build.gradle.kts index 35502755..68c3569b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-12" + version = "0.3.0-dev-13" } subprojects { diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index a2e1f70a..be9372b5 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -328,7 +328,7 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? group }.apply { volume.fMedium?.let { medium -> - color.set(context.colorCache.getOrPut(medium.meta) { RootColors[11 + context.colorCache.size] }) + color(context.colorCache.getOrPut(medium.meta) { RootColors[11 + context.colorCache.size] }) } if (!context.ignoreRootColors) { diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt index 4301966a..37c178f4 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt @@ -23,7 +23,7 @@ import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.invoke import styled.css import styled.styledDiv @@ -53,7 +53,7 @@ val GDMLApp = fc("GDMLApp") { props -> console.info("Marking layers for file $name") markLayers() ambientLight { - color.set(Colors.white) + color(Colors.white) } } } diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index cdca1957..7c6514bf 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -12,7 +12,7 @@ import space.kscience.visionforge.react.createRoot import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication import styled.injectGlobal @@ -49,7 +49,7 @@ private class GDMLDemoApp : Application { child(GDMLApp) { val vision = GdmlShowCase.cubes().toVision().apply { ambientLight { - color.set(Colors.white) + color(Colors.white) } } //println(context.plugins.fetch(VisionManager).encodeToString(vision)) diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index cb6eb3e6..d77d8f52 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -76,7 +76,7 @@ private class JsPlaygroundApp : Application { solids = playgroundContext.request(Solids) solid { ambientLight { - color.set(Colors.white) + color(Colors.white) } repeat(100) { sphere(5, name = "sphere[$it]") { @@ -84,7 +84,7 @@ private class JsPlaygroundApp : Application { y = random.nextDouble(-300.0, 300.0) z = random.nextDouble(-300.0, 300.0) material { - color.set(random.nextInt()) + color(random.nextInt()) } detail = 16 } diff --git a/demo/js-playground/src/main/kotlin/gravityDemo.kt b/demo/js-playground/src/main/kotlin/gravityDemo.kt index c04baf98..a4bc9057 100644 --- a/demo/js-playground/src/main/kotlin/gravityDemo.kt +++ b/demo/js-playground/src/main/kotlin/gravityDemo.kt @@ -42,13 +42,13 @@ val GravityDemo = fc { props -> solids = props.solids solid { pointLight(200, 200, 200, name = "light"){ - color.set(Colors.white) + color(Colors.white) } ambientLight() sphere(5.0, "ball") { detail = 16 - color.set("red") + color("red") val h = 100.0 y = h solids.context.launch { diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 82c20def..f11c9e01 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -39,7 +39,7 @@ class Model(val manager: VisionManager) { val root: SolidGroup = SolidGroup().apply { setAsRoot(this@Model.manager) material { - color.set("darkgreen") + color("darkgreen") } rotationX = PI / 2 solidGroup("bottom") { @@ -64,7 +64,7 @@ class Model(val manager: VisionManager) { private fun highlight(pixel: String) { println("highlight $pixel") - map[pixel]?.color.set("blue") + map[pixel]?.color("blue") } fun reset() { @@ -82,7 +82,7 @@ class Model(val manager: VisionManager) { } event.track?.let { tracks.polyline(*it.toTypedArray(), name = "track[${event.id}]") { - color.set("red") + color("red") } } } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index 4c9649c6..07dc7c7c 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -26,7 +26,7 @@ import space.kscience.visionforge.ring.tab import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight import space.kscience.visionforge.solid.edges -import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.specifications.Canvas3DOptions import styled.css import styled.styledDiv @@ -58,7 +58,7 @@ val MMApp = fc("Muon monitor") { props -> props.model.root.apply { edges() ambientLight{ - color.set(Colors.white) + color(Colors.white) } } } diff --git a/demo/playground/src/jvmMain/kotlin/antenna.kt b/demo/playground/src/jvmMain/kotlin/antenna.kt index cd711d11..6e9b759b 100644 --- a/demo/playground/src/jvmMain/kotlin/antenna.kt +++ b/demo/playground/src/jvmMain/kotlin/antenna.kt @@ -1,16 +1,19 @@ package space.kscience.visionforge.examples +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import space.kscience.dataforge.meta.configure import space.kscience.kmath.complex.Quaternion import space.kscience.kmath.complex.QuaternionField -import space.kscience.kmath.geometry.Angle -import space.kscience.kmath.geometry.Euclidean3DSpace -import space.kscience.kmath.geometry.degrees -import space.kscience.kmath.geometry.fromRotation -import space.kscience.visionforge.html.ResourceLocation +import space.kscience.kmath.complex.conjugate +import space.kscience.kmath.geometry.* import space.kscience.visionforge.solid.* import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin -fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { +fun main() = serve { val azimuth = 60.degrees val inclination = 15.degrees @@ -22,28 +25,76 @@ fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { //val direction2 = Quaternion.fromEuler(Angle.zero, Angle.piDiv2 - inclination, -azimuth, RotationOrder.ZYX) + val target = Quaternion.fromEuler((-45).degrees, 45.degrees, Angle.zero, RotationOrder.XYZ) + vision("canvas") { requirePlugin(Solids) - solid { + + solid(options = { + configure { "controls.enabled" put false } + }) { rotationX = -PI / 2 rotationZ = PI - axes(200) + //axes(200) ambientLight() - cylinder(50, 5, name = "base") - solidGroup("frame") { - z = 60 - axes(200) - solidGroup("antenna") { - tube(40, 10, 30) - sphereLayer(100, 95, theta = PI / 6) { - z = 100 - rotationX = -PI / 2 + val platform = solidGroup("platform") { + cylinder(50, 5, name = "base") + solidGroup("frame") { + z = 60 + + val antenna = solidGroup("antenna") { + axes(200) + tube(40, 10, 30) + sphereLayer(100, 95, theta = PI / 6) { + z = 100 + rotationX = -PI / 2 + } + cylinder(5, 30) { + z = 15 + } + + sphereLayer(101, 94, phi = PI / 32, theta = PI / 6) { + z = 100 + rotationX = -PI / 2 + color("red") + } + + quaternion = target } - cylinder(5, 30) { - z = 15 + } + } + + val frame = platform["frame"] as SolidGroup + + val antenna = frame["antenna"] as SolidGroup + + val xPeriod = 5000 //ms + val yPeriod = 7000 //ms + + val incRot = Quaternion.fromRotation(30.degrees, Euclidean3DSpace.zAxis) + + + val rotationJob = context.launch { + var time: Long = 0L + while (isActive) { + with(QuaternionField) { + delay(200) + platform.quaternion = Quaternion.fromRotation( + 15.degrees * sin(time.toDouble() * 2 * PI / xPeriod), + Euclidean3DSpace.xAxis + ) * Quaternion.fromRotation( + 15.degrees * cos(time * 2 * PI / yPeriod), + Euclidean3DSpace.yAxis + ) + + val qi = platform.quaternion * incRot + + antenna.quaternion = qi.conjugate * incRot.conjugate * target + + time += 200 + //antenna.quaternion = Quaternion.fromRotation(5.degrees, Euclidean3DSpace.zAxis) * antenna.quaternion } - quaternion = direction } } } diff --git a/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt b/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt index c2af2a8f..4cac02b1 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt @@ -7,7 +7,7 @@ import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.color -import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.visible import java.nio.file.Path @@ -229,7 +229,7 @@ fun main() = makeVisionFile(Path.of("curves.html"), resourceLocation = ResourceL visible = false } if(solid.name.startsWith("gas")){ - color.set("green") + color("green") } else { //make all solids semi-transparent transparent() diff --git a/demo/playground/src/jvmMain/kotlin/randomSpheres.kt b/demo/playground/src/jvmMain/kotlin/randomSpheres.kt index 47201ff8..fd1b9865 100644 --- a/demo/playground/src/jvmMain/kotlin/randomSpheres.kt +++ b/demo/playground/src/jvmMain/kotlin/randomSpheres.kt @@ -19,7 +19,7 @@ fun main() = makeVisionFile( vision { solid { ambientLight { - color.set(Colors.white) + color(Colors.white) } repeat(100) { sphere(5, name = "sphere[$it]") { @@ -27,7 +27,7 @@ fun main() = makeVisionFile( y = random.nextDouble(-300.0, 300.0) z = random.nextDouble(-300.0, 300.0) material { - color.set(random.nextInt()) + color(random.nextInt()) } detail = 16 } diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/rootParser.kt index be70faf8..d5fea32e 100644 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ b/demo/playground/src/jvmMain/kotlin/rootParser.kt @@ -11,7 +11,7 @@ import space.kscience.visionforge.Colors import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.solid import java.util.zip.ZipInputStream import kotlin.io.path.Path @@ -44,7 +44,7 @@ fun main() { requirePlugin(Solids) solid { ambientLight { - color.set(Colors.white) + color(Colors.white) } rootGeo(geo,"BM@N", maxLayer = 3, ignoreRootColors = true).also { Path("data/BM@N.vf.json").writeText(Solids.encodeToString(it)) diff --git a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt index 9eb87730..c20f27c7 100644 --- a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt +++ b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt @@ -1,11 +1,24 @@ package space.kscience.visionforge.examples +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import io.ktor.server.http.content.staticResources +import io.ktor.server.routing.routing +import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Global import space.kscience.visionforge.html.* +import space.kscience.visionforge.markup.MarkupPlugin +import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.server.close +import space.kscience.visionforge.server.openInBrowser +import space.kscience.visionforge.server.visionPage +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.tables.TableVisionPlugin import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Path + public fun makeVisionFile( path: Path? = null, title: String = "VisionForge page", @@ -26,6 +39,45 @@ public fun makeVisionFile( if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) } +public fun serve( + title: String = "VisionForge page", + show: Boolean = true, + content: HtmlVisionFragment, +) { + val context = Context("playground") { + plugin(Solids) + plugin(PlotlyPlugin) + plugin(MarkupPlugin) + plugin(TableVisionPlugin) + } + + val server = embeddedServer(CIO, port = 7779) { + routing { + staticResources("", null, null) + } + + visionPage( + context.visionManager, + VisionPage.scriptHeader("js/visionforge-playground.js") { + defer = true + }, + VisionPage.title(title), + visionFragment = content + ) + }.start(false) + + if (show) { + server.openInBrowser() + } + + println("Enter 'exit' to close server") + while (readlnOrNull() != "exit") { + // + } + + server.close() +} + //@DFExperimental //public fun Context.makeVisionFile( // vision: Vision, diff --git a/demo/playground/src/jvmMain/kotlin/shapes.kt b/demo/playground/src/jvmMain/kotlin/shapes.kt index a338d123..55ce28d5 100644 --- a/demo/playground/src/jvmMain/kotlin/shapes.kt +++ b/demo/playground/src/jvmMain/kotlin/shapes.kt @@ -10,23 +10,23 @@ fun main() = makeVisionFile { ambientLight() box(100.0, 100.0, 100.0) { z = -110.0 - color.set("teal") + color("teal") } sphere(50.0) { x = 110 detail = 16 - color.set("red") + color("red") } tube(50, height = 10, innerRadius = 25, angle = PI) { y = 110 detail = 16 rotationX = PI / 4 - color.set("blue") + color("blue") } sphereLayer(50, 40, theta = PI / 2) { rotationX = -PI * 3 / 4 z = 110 - color.set(Colors.pink) + color(Colors.pink) } diff --git a/demo/playground/src/jvmMain/kotlin/simpleCube.kt b/demo/playground/src/jvmMain/kotlin/simpleCube.kt index 5dae515c..e1fc91eb 100644 --- a/demo/playground/src/jvmMain/kotlin/simpleCube.kt +++ b/demo/playground/src/jvmMain/kotlin/simpleCube.kt @@ -2,8 +2,8 @@ package space.kscience.visionforge.examples import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.box +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.material -import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.solid fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { @@ -11,7 +11,7 @@ fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { solid { box(100, 100, 100) material { - emissiveColor.set("red") + emissiveColor("red") } } } diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt index 052fb6e0..d2c30422 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt @@ -15,7 +15,7 @@ internal fun Solids.visionOfSatellite( ySegmentSize: Number = xSegmentSize, fiberDiameter: Number = 1.0, ): SolidGroup = solidGroup { - color.set("darkgreen") + color("darkgreen") val transparent by style { this[SolidMaterial.MATERIAL_OPACITY_KEY] = 0.3 } diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index 9e0c8282..9f2f7e59 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -33,7 +33,7 @@ fun main() { //Create a geometry val sat = solids.visionOfSatellite(ySegments = 3).apply { ambientLight { - color.set(Colors.white) + color(Colors.white) } } val server = embeddedServer(CIO, port = 7777) { @@ -63,7 +63,7 @@ fun main() { val randomJ = Random.nextInt(1, 4) val target = Name.parse("layer[$randomLayer].segment[$randomI,$randomJ]") val targetVision = sat[target] as Solid - targetVision.color.set("red") + targetVision.color("red") delay(1000) //use to ensure that color is cleared targetVision.color.value = Null diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt index 2a1fd240..89dc3a09 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt @@ -3,8 +3,8 @@ package ru.mipt.npm.sat import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.box +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.material -import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.solid import space.kscience.visionforge.three.makeThreeJsFile @@ -14,7 +14,7 @@ fun main() = makeThreeJsFile(resourceLocation = ResourceLocation.SYSTEM) { solid { box(100, 100, 100) material { - emissiveColor.set("red") + emissiveColor("red") } } } diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index baee4c71..9e2ecedb 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -23,7 +23,7 @@ fun VisionLayout.demo(name: String, title: String = name, block: SolidGro val vision = solids.solidGroup { block() ambientLight { - color.set(Colors.white) + color(Colors.white) } } render(Name.parse(name), vision, meta) @@ -49,23 +49,23 @@ fun VisionLayout.showcase() { ambientLight() box(100.0, 100.0, 100.0) { z = -110.0 - color.set("teal") + color("teal") } sphere(50.0) { x = 110 detail = 16 - color.set("red") + color("red") } tube(50, height = 10, innerRadius = 25, angle = PI) { y = 110 detail = 16 rotationX = PI / 4 - color.set("blue") + color("blue") } sphereLayer(50, 40, theta = PI / 2) { rotationX = -PI * 3 / 4 z = 110 - color.set(Colors.pink) + color(Colors.pink) } } @@ -80,7 +80,7 @@ fun VisionLayout.showcase() { visible = false x = 110.0 //override color for this cube - color.set(1530) + color(1530) GlobalScope.launch(Dispatchers.Main) { while (isActive) { @@ -95,7 +95,7 @@ fun VisionLayout.showcase() { val random = Random(111) while (isActive) { delay(1000) - group.color.set(random.nextInt(0, Int.MAX_VALUE)) + group.color(random.nextInt(0, Int.MAX_VALUE)) } } } @@ -114,7 +114,7 @@ fun VisionLayout.showcase() { rotate((PI/20).radians,Euclidean3DSpace.yAxis) } } - color.set(Colors.red) + color(Colors.red) } } } @@ -127,7 +127,7 @@ fun VisionLayout.showcase() { for (i in 0..100) { layer(i * 5, 20 * sin(2 * PI / 100 * i), 20 * cos(2 * PI / 100 * i)) } - color.set(Colors.teal) + color(Colors.teal) rotationX = -PI / 2 } } @@ -136,7 +136,7 @@ fun VisionLayout.showcase() { sphere(100) { detail = 32 opacity = 0.4 - color.set(Colors.blue) + color(Colors.blue) } repeat(20) { polyline( @@ -145,7 +145,7 @@ fun VisionLayout.showcase() { ) { thickness = 3.0 rotationX = it * PI2 / 20 - color.set(Colors.green) + color(Colors.green) //rotationY = it * PI2 / 20 } } @@ -176,7 +176,7 @@ fun VisionLayout.showcaseCSG() { detail = 32 } material { - color.set(Colors.pink) + color(Colors.pink) } } composite(CompositeType.UNION) { @@ -186,7 +186,7 @@ fun VisionLayout.showcaseCSG() { sphere(50) { detail = 32 } - color.set("lightgreen") + color("lightgreen") opacity = 0.7 } composite(CompositeType.SUBTRACT) { @@ -197,7 +197,7 @@ fun VisionLayout.showcaseCSG() { sphere(50) { detail = 32 } - color.set("teal") + color("teal") opacity = 0.7 } } @@ -208,7 +208,7 @@ fun VisionLayout.showcaseCSG() { detail = 32 } box(100, 100, 100) - color.set("red") + color("red") opacity = 0.5 } } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt index dd7f8e0d..94259b2f 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt @@ -7,12 +7,15 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.boolean +import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.ThreePlugin public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { @@ -24,11 +27,16 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { - space.kscience.visionforge.react.createRoot(element).render { - child(ThreeCanvasWithControls) { - attrs { - this.solids = three.solids - this.builderOfSolid = context.async { vision as Solid} + if(meta["controls.enabled"].boolean == false){ + three.render(element, name, vision, meta) + } else { + space.kscience.visionforge.react.createRoot(element).render { + child(ThreeCanvasWithControls) { + attrs { + this.solids = three.solids + this.options = Canvas3DOptions.read(meta) + this.builderOfSolid = context.async { vision as Solid } + } } } } diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt index 56158c55..2d3c18c9 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt @@ -42,7 +42,7 @@ public class GdmlLoaderOptions { * Configure paint for given solid with given [GdmlMaterial] */ public var configurePaint: SolidMaterial.(material: GdmlMaterial, solid: GdmlSolid) -> Unit = - { material, _ -> color.set(randomColor(material)) } + { material, _ -> color(randomColor(material)) } private set public fun paint(block: SolidMaterial.(material: GdmlMaterial, solid: GdmlSolid) -> Unit) { diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 47c5db84..61952497 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -57,7 +57,7 @@ public class VisionRoute( override val context: Context get() = visionManager.context /** - * Update minimal interval between updates in milliseconds (if there are no updates, push will not happen + * Update the minimal interval between updates in milliseconds (if there are no updates, push will not happen */ public var updateInterval: Long by meta.long(300, key = UPDATE_INTERVAL_KEY) @@ -170,8 +170,8 @@ public fun Application.visionPage( meta { charset = "utf-8" } - headers.forEach { header -> - consumer.header() + headers.forEach { headerContent -> + headerContent.appendTo(consumer) } } body { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index 01abf310..60789027 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -28,7 +28,7 @@ public class ColorAccessor( } } -public fun Vision.color( +public fun Vision.colorProperty( propertyName: Name? = null, ): ReadOnlyProperty = ReadOnlyProperty { _, property -> ColorAccessor(properties.root(true), propertyName ?: property.name.asName()) @@ -43,21 +43,21 @@ public var ColorAccessor?.string: String? /** * Set [webcolor](https://en.wikipedia.org/wiki/Web_colors) as string */ -public fun ColorAccessor?.set(webColor: String) { +public operator fun ColorAccessor?.invoke(webColor: String) { this?.value = webColor.asValue() } /** * Set color as RGB integer */ -public fun ColorAccessor?.set(rgb: Int) { +public operator fun ColorAccessor?.invoke(rgb: Int) { this?.value = Colors.rgbToString(rgb).asValue() } /** * Set color as RGB */ -public fun ColorAccessor?.set(r: UByte, g: UByte, b: UByte) { +public operator fun ColorAccessor?.invoke(r: UByte, g: UByte, b: UByte) { this?.value = Colors.rgbToString(r, g, b).asValue() } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt index beeb4eb3..6064e6ed 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -15,7 +15,7 @@ import space.kscience.visionforge.* public abstract class LightSource : SolidBase() { override val descriptor: MetaDescriptor get() = LightSource.descriptor - public val color: ColorAccessor by color(SolidMaterial.COLOR_KEY) + public val color: ColorAccessor by colorProperty(SolidMaterial.COLOR_KEY) public var intensity: Number by properties.root(includeStyles = false).number(INTENSITY_KEY) { 1.0 } public companion object { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index 791bb0c9..8e04b638 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -43,6 +43,9 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable it to value }.toMap() + /** + * Get a child solid with given relative [name] if it exists + */ public operator fun get(name: Name): Solid? = children.getChild(name) as? Solid private var prototypes: SolidGroup? @@ -84,6 +87,8 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable } } +public operator fun SolidGroup.get(name:String): Solid? = get(name.parseAsName()) + @VisionBuilder public inline fun MutableVisionContainer.solidGroup( name: Name? = null, diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index e9301f67..1477c2a0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -94,3 +94,7 @@ public inline fun VisionOutput.solid(options: Canvas3DOptions? = null, block: So } } } + +@VisionBuilder +public inline fun VisionOutput.solid(options: Canvas3DOptions.() -> Unit, block: SolidGroup.() -> Unit): SolidGroup = + solid(Canvas3DOptions(options), block) diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt index e426aee2..a7c1c688 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt @@ -18,7 +18,7 @@ class CompositeTest { detail = 32 } material { - color.set("pink") + color("pink") } } } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt index 7f5138b1..78e2f03c 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt @@ -18,7 +18,7 @@ class GroupTest { } box(100, 100, 100) material { - color.set(Colors.lightgreen) + color(Colors.lightgreen) opacity = 0.3f } } @@ -30,7 +30,7 @@ class GroupTest { } box(100, 100, 100) y = 300 - color.set(Colors.red) + color(Colors.red) } subtract("subtract") { box(100, 100, 100) { @@ -40,7 +40,7 @@ class GroupTest { } box(100, 100, 100) y = -300 - color.set(Colors.blue) + color(Colors.blue) } } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index 2497b5b3..e3069647 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -24,7 +24,7 @@ class SerializationTest { @Test fun testCubeSerialization() { val cube = Box(100f, 100f, 100f).apply { - color.set(222) + color(222) x = 100 z = -100 } @@ -37,7 +37,7 @@ class SerializationTest { @Test fun testProxySerialization() { val cube = Box(100f, 100f, 100f).apply { - color.set(222) + color(222) x = 100 z = -100 } @@ -59,7 +59,7 @@ class SerializationTest { fun lightSerialization(){ val group = testSolids.solidGroup { ambientLight { - color.set(Colors.white) + color(Colors.white) intensity = 100.0 } } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index 5fa22b86..87ba368c 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -20,7 +20,7 @@ class SolidPropertyTest { val box = Box(10.0f, 10.0f, 10.0f) box.material { //meta["color"] = "pink" - color.set("pink") + color("pink") } assertEquals("pink", box.properties.getValue("material.color")?.string) assertEquals("pink", box.color.string) @@ -41,7 +41,7 @@ class SolidPropertyTest { delay(5) box.material { - color.set("pink") + color("pink") } assertEquals("pink", c.await()) diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt index 8e851cb5..d8d971bb 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt @@ -16,7 +16,7 @@ class SolidReferenceTest { SolidMaterial.MATERIAL_COLOR_KEY put "red" } newRef("test", Box(100f,100f,100f).apply { - color.set("blue") + color("blue") useStyle(theStyle) }) } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 50e9362d..0e495aaa 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -22,7 +22,7 @@ internal class VisionUpdateTest { } val dif = visionManager.VisionChange { solidGroup("top") { - color.set(123) + color(123) box(100, 100, 100) } propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) @@ -41,7 +41,7 @@ internal class VisionUpdateTest { fun testVisionChangeSerialization() { val change = visionManager.VisionChange { solidGroup("top") { - color.set(123) + color(123) box(100, 100, 100) } propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) From 1e29c5dbaa7a52ea5cde8513ac82a4a8a134455c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 22 Aug 2023 21:47:07 +0300 Subject: [PATCH 079/112] add a workaround for root duplicating names --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 27 +++++++++--------- .../src/jvmMain/kotlin/rootParser.kt | 2 +- .../resources/root/geometry_run_7-2076.zip | Bin 0 -> 48731 bytes .../kscience/visionforge/solid/SolidGroup.kt | 2 +- .../visionforge/solid/SolidReference.kt | 15 +++++++--- 5 files changed, 27 insertions(+), 19 deletions(-) create mode 100644 demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.zip diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index be9372b5..13b1cb55 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -4,6 +4,7 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus +import space.kscience.dataforge.names.withIndex import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.isEmpty import space.kscience.visionforge.set @@ -223,7 +224,7 @@ private fun SolidGroup.addShape( "TGeoShapeAssembly" -> { val fVolume by shape.dObject(::DGeoVolume) fVolume?.let { volume -> - addRootVolume(volume, context, block = block) + addRootVolume(volume, context, name = volume.fName.ifEmpty { null }, block = block) } } @@ -348,29 +349,29 @@ private fun SolidGroup.addRootVolume( cache: Boolean = true, block: Solid.() -> Unit = {}, ) { - - val combinedName = if (volume.fName.isEmpty()) { - name - } else if (name == null) { - volume.fName - } else { - "${name}_${volume.fName}" + val combinedName = name?.parseAsName()?.let { + // this fix is required to work around malformed root files with duplicated node names + if (get(it) != null) { + it.withIndex(volume.hashCode().toString(16)) + } else { + it + } } if (!cache) { - val group = buildVolume(volume, context)?.apply(block) - setChild(combinedName?.let { Name.parse(it) }, group) + val group = buildVolume(volume, context)?.apply(block) ?: return + setChild(combinedName, group) } else { val templateName = volumesName + volume.name - val existing = getPrototype(templateName) + val existing = context.prototypeHolder.getPrototype(templateName) if (existing == null) { context.prototypeHolder.prototypes { - val group = buildVolume(volume, context) + val group = buildVolume(volume, context) ?: return@prototypes setChild(templateName, group) } } - ref(templateName, name).apply(block) + ref(templateName, combinedName).apply(block) } } diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/rootParser.kt index d5fea32e..85a2f0d3 100644 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ b/demo/playground/src/jvmMain/kotlin/rootParser.kt @@ -26,7 +26,7 @@ private fun Meta.countTypes(): Sequence = sequence { } fun main() { - val string = ZipInputStream(TGeoManager::class.java.getResourceAsStream("/root/BM@N_geometry.zip")!!).use { + val string = ZipInputStream(TGeoManager::class.java.getResourceAsStream("/root/geometry_run_7-2076.zip")!!).use { it.nextEntry it.readAllBytes().decodeToString() } diff --git a/demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.zip b/demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.zip new file mode 100644 index 0000000000000000000000000000000000000000..1680404cd90cbb11d16f618bbda808c0c0208873 GIT binary patch literal 48731 zcma&NWn3I>^CgVCI|O%kcemi~&fpf@-8HzoyF(yA@W>1h90myx+yVr*carPi4kkirS+Mp8ofvtPaDfrL7s}^ zS2}R#z)fSli@7=V_<6SkZ)v?d;sAtAa^9I{{hdb*_U z3xC>g?t1mQJIHQt9wfX@PF`-Gu~*miqt zk=sR8FZEmKEZGQV9Fpd>H2)ZMyY=Y1D=;)%BhbIi!7QFI)O*MHlD=JW_ck$g+sz~h zFEj&kQb0g4Zf>B>lJe2eX$8B-H_VhlrU9z#WKvw9Yx7pa3D{Z4M+1Tvo(z}D+zFoa! zV^M4`=VejuD5qo@VyOqfcNh*kXJ=i)?iw?FQU+w@ax%heb(aPxWTiFu>L~R<4h$N6 zqm-HHN7^eh->^Gv*8{Fo8uAxJnjQ7diFDz1Mdb0N?o%}7G{mZZ!tbVE38P*h^&nE7lE#*0qCf&4VN#2@xq)gLW|9dDL@F{b-EZ zbvQBN2`mrBG9p0Yt2pPQ=1n-272PhP{0Z~|BH*MI6DVjwk?ZkEoYM+Z@&r0AOXtMm zChVvJN=Hub9~NqB%v$jTU%e6XPcb3aQU*KAh?dFL6j6LB!B~reH-8ospbc+IE+bpB z+c8IszKSC`F+EZ?R-OEJ0j0Gg{Sr1xVoUuF_vJr-ocE`PmPxM`4s*}XLxqAs=k@mo zkI(DYX6h0W8{)4)M?v>jr@dzy!d%Old>-9dAB>lKn((EoxI1*OPjD(eS|0weWc<2UKM>GwH>9VP6Z%p$ z$ks<<$8!Bby7nwOww|YKs=3Cl^HQ19N!Yt;K=3u)(gmG zd^QZtij8w@&S*#m8(y#shALABv*i3trIYTk2R?#Vse_h)ckgt5;!`;n5;|YCLs%=a z-AD~#eMn;ulb|nBHSt%g!GpB~8hf#~GbzxY!)r+kDV2AKD3ue=l#rQ5-`ldlZ*pIv zavs;bT9)r<36SY`LWfD=u~+T*bLgF=Voj?1OAYVY8yHB)$ zE0QU%B+tdsLMU>vtE|b)#6LWjFd`rI+NVn|00|5{*>{%-kND@-@H$){pne=f~kXu zN@qM)Gsm&SXP-{{H&iBWeRB|Ooyx?#4;ytvhCb(sXqr};s(mmhUJe}M(n$xZz3!$Y zbXgHPBKpR%n==7C&%0RfFzA#XY(MP~6@b;ka-k+)QEgf;izbJIvLXm#d(rKl#yXBT z940!BS7=0C+u~Z(PBkFB3$bprYc|MfU{@7Tpg3klN-U4cmSW?s9U|=)Xkw@n5fG_P zh#B=!(Z!TKucxkfLH~Z`MxW%n=&8yv;#K|pzDLm$U(p=1mEiQJsu478B6f}~GAJEy zoJ(aVNS_WdZ1gwDX1*Nvz9r*z{~%7&QsiQJ;*=To980959TsUopQ0;5d@+SeoDXI( zh%$u|o=cZE5~cCj1-)qWq50>4invXJx0qX&y|H_u*3y;Uerq#>_lNG;r1c}%7>Bxu zS3G*WLUY@Q9L9^?wQ*U{ZV_SC{*d}7OP2siSqr182$DAOgyPJRUpRudG@x?He#1px z*o7-62u}?$p1~68oF;FP_l}mrlz{-dx7cQ+~NPeFWdo1x%O@QJu-h7yFmYp(~VT)k^Mav;DBStYy3OvjVu$W z9nC@+l_*m{NH60&PCATA(xEV-(w<4;0x#RUq=E-E=e7$#%li8|;*rFmu2uz{hD%hX z29&Sfr#tGYTQW(`ai8;4Kr&5Opy9XMD@u^&=l;+Ut&0-5dhTn+?BbD%@Dt-<#jKI!o z$*`5okgduV7@kT@9y@@x*Ie>ScP~$Y=r^C$?PceLGeKgPw3|C$Bwp25l_55a@an^o z!=7=z8Qy1}=l2y>c0fLbB}g!J&O+P=xvPl?HCuij$_gVdL z;>FlJo{l>I*Ad9Bc?w3}5G8d(w9kK3fj+8X{D0<;{+Iuwt0mt5%AXe!;o%F=zA_6# zcJZ*|=i@-hogtWnEIdFd{>}TJT)24rXCKXf_mN79FJj#+)CWmgV8mA83`f2IqRIh5 zmKhfU&vzG?9nQH$SZKfiLh}Bk!Sn1)?;XX-IA9p!dKj8}2Qahvxh-!k52KE?{^plW;5VIasd5RnF|mT7`7xKSwS&8{(r#3bt= zYWUnd)@D8-3ve4u3l6C3qHk5z_6g1t!mstO8G$SICCFXuN?TPS1eViA)D0(6mhO3@ za2AhrdGxdQDG!S-0Z#i49>O$>yKp})w;ks@T-jZ?q`RnI3C6lq_?TwGY!d9y-xE~1 z_l)-_^|LEWxhA@0I6JK>26uxB6fN5wDnyN2kMqBjF>p4yEYVS+T9O0*CoJ`3L?5Zv*8u13|aj3j&avcLjry*bbZ?yRjigGaoa%F~1x5b$=vHrSKT-6WTLh$V-47ubi}9TR*P z6ijo4(F`t5PL-}KVALtG+d0BGq=#GBU+FcK>JyT<_UCu~^xoA~9byuwtSAs$BR)N0 zs#RG~tzBYwH6?*Vx5EqU^ha+hsCx%9x2N05NKs{34LY`8w@Jp$0*dMl@x`7*;fw|Cv?>iP*; zrC@2U94#y+kH4kHdu~S+LR7p6iWGnl1?2C8Fy>0PeG#eAkiI17lhimA60gojr+FWL zCb38kJ&tKVgCeqosVA&fN=mwLTL*BzxU{v{iD6gcE_37zGfwc1etlffF<9y-LsEYq z#I?>usl3orp6b>qGxFq8Ao3pMnFt&~^BD0B; zq5A}1;iu~?YhiS+ISTq z{roSVsyj#(+L*Gt(5}$3(aBb&^YdD(dC)+^(%%-<>{cizjbgloCnqG!Y_)2xoZQzO z4Cf9>-{`m+WqS!v_Om8H^V-Vs&Z(&G=gZbfHJh%8iF)kohnU3X&ygw@>`CodNs>w){3Q5MgWoY7Y|N443 zV}UV1wEXxuODed$sSc1p7|FEs6Rk~oO!nm9Wrz?@c+gKU-W+=}EqAO7$VTewj-OC* z4oJY8>SBQfW(QT)5tRb^N)1&ifRx=3{>=Q*ZW*3f}MxlU&krT?CG&4>;r zH@&q2ok(9T^Z%j1MT1aa&E+G<>~Xocn&LR^5#>+zw0SEv=God4fcLWL+5p9n>J)6R zl*RM*FhV@gK~~`9d`J{t-b5$Qw~#1HGosz97bi2K`NnBu`CnoHZ7$AYI8J~!`Qu$5 zb`=}*+#pG;_VckP0kO$jfubPQ;O{1g_uq5&ba7>Z#3Y6!t1KE~Xk<_D4FUdiijxGc zOXQoqR(LN@QngMOXJ{H-HptS5V||*n86-p*P!|l~a+z6~d;60o(Mj92%WSpSpY_dH zr%0r|YkO@@ryao@0>fT_QXs&?g&B@oWz{;~HZs@84hvoW#%t~bxV36Qsw=QCMcS=8 z-ss(N3fx{HZT99l16qRD9FtrZi-b(xm^{v^4)VmhSc~>|B+@T=d3*l)1Eci0ViZH* zwU*L?C_4;r^-at{^^d&q4k44{y&rj_-5*TV`;`0u?k?`B#EYt<5C)mY`&L(iVnfk4 zV_hP1_O3O|KIy_Wd#h`M7ALfUYM|~ivE^mU7t+Yb^|sO9LVIe27O^XyXvMpqFf#UY zg#{wX_NKV}GimcCMiF|T}CV$+EoN#)i)ODmRTW*j>?kl&Ac0wF4tYQrzj(HOp z8GE_HB`IWkK(1U=C=r!BYxXM`pIoj`H$uCVM`hL**ZO?6tYL_eTR_3iJMUyuWiUzx^WL z)edk6T!>qhM{Y+BMljU_p$YNa^N)AFrEzd&mgoHoFOTKeS3^Q|4|BqP2d434xM{0E zng?OjPL@Yv3ep4cEb)MVLdeG&6&?3q0vQ?y_b-w5e+9I`)0h7Zu$O%m_pgGg_q;tS zs{ceVpiTa3+5LfyNR~%o>OXBpvSuX9>-iI+a9N(cJdXwBjNgG7 zJgIKh1#aVu4{ERP)|hoGjnIH0lr(*LSu{jO5r0N8C(Z=v25gfG0>V&M=w8-!h%W(Poj%9mlI^+%8x(R3G`D4GL(8qD)L0^2$m3*26-Vw zR$!v(vy<{Ke5U__Bbxt#Z&~cCry;4S8=%Vn;JJ6nI)QAA{tT_pxymPrHP4?iAIIUBLMG5CEM@Y4WiWc-t%@OD%oF(6r$hg*Pm|e~ zHce7vfdINm`K)N~1_hNzx0@@-1?#2Yd7gi)^A#Y`hR$_7v@&fkg9d>zRU7Xa;8ShA zb%P5$Npb_UmY6|e2t+=waf|GLiBI;kSBN*JEhL(NQ@>*n9))aus(pEvrx`kU2C9Zb zg!76n#OiK5zd&4-yGoQGuKM-QyxbzAV69Vz_bYiDIgS$H5Z4Kv#}#XcYxU|hsWu&c zfRXv7ZJLJ|iz0R*(9b_?l5!`Y+Z|zNx$)CA+P2pqdPkETZcT>^34MT%2f}8|WL2?C z;fMfkr$=z-G)>gd?uaN|9{2s@wWSCt=c zj6F1Xuf76*fH~C~->5i`ihT#N^5nUUni%(FFUNS6=NSWp!Sb;-jgSKvum}s}+l~qc zPpn6UB;=b35NNS>(3`}U0aV!sbAlILcBf**gyNTjuhpSq(Bpq4L`dYKc6 zP%cPZB6sieN|zJg;W&GHUN63-eyp=8fEgRMbg=mpc}@8vkWCI!~;oo1&*)EKh!r<&Wi1xgQG_X_KE_5G0NebIG7(16?-!=vM{?fizvN=EPWFp7bAE zBKBWm#e9pg;H9wMW0{kmA8u^hN9mM!#Qc$sfUPB5~AOu^fj(#T!rE)-n1iCJ!C>sYj(&BD+tx=7+5koz zaXfUfPG+bpD5kg_CFuL7U(vS-h0yKr^f3xJlhs?r`1wlDF8f;pEph`-Nd7K`(4HnEtK*Ho{Ev-C+{x~)aI z_56Jqng?FlzZo#P zYsJcdvn8Ts+SXn!F4`}C2vp+a+ffe=r5Rue6GM@SL;?P8c4XeA>Ej z4|*;cm3eva6!I|-U8PWONxcVWWlv{a* zc`ja%&zcYo1CQenyf06la1jgoEW?$FC7*5&J6Zj{f`}36Gxn+M3hz6-eT_F#YU8sV zlao&`p!FFar0=Kd)bAbQ;JpUPaFt0f%%4|Z>$4Hmpl?YMM~4~Z3hnN`ZJqHrjT{7! z(HwuNXJPw9SSYg$$MEZ2eSb1&Xn)ySBiN`%MiJFW=p)y?mB$HMF%Q$ zmZ+DH#C+#yqNlXI06ZBPvYCL`4ax5iON(UJ#&d%@q$uwdEIg4RN{1heq;DdIt5HIn zTI<>;Zhk0_?^4fP?ouD{??yuHAtP9bp^ zAVzJ8QQhJgpqiN{mqMf=Qb4L8CdcE8zMQE&+_l<*&)DYOol5umk_pHAIbK%Mkvbid zuGrB}@N}Km6v`{h4cA?IkWV<9q?kHt&md+@0HfKY03f^b@vp zO*3r>fKU{+DLaKl{vFp#k8h8g@td%|O0B|7SzrUn*5U3;?@&u`y}%rmM)RHNOZM>0 zUdgP)E6GclG}G=R_<23|WPH|*8AHtY17hZbWCJ1Iqm;k1i6Z_4BF)RomZ_PXB;q`F zMSz}GDK88Y*$iA#iVG*P22;|{0_nOeu-P|6`5e?S*-DAi&F3_I3?Bl^^l?fm4|y!0 zyi@S2d%Y7j2^}7dB(C!8+Za8~s*7g_AlGLnujge_8IeatntI5fH;fc7+ehLMt zi~3)F@0h$$Tz<1lq#U!#--}A@VZMq7X_h_Tun$dBs4-V^q{d2P)qtrmqbp96x+q*J z)M>B=x5Nm9Ty}cU>Z1~lejSe0BE%!;_}??z`1$#XHZ_mK(ruq3s;-;6QB*3jiq*B; z7tK$++}*#R2QH?$GTN)f;%c8q-aOTOJZPIno79k`aeiwlj8T(%vNTOE{ua@mqY%Tt zC6>dtMEk?+~M6aoNA)q{B);Cxh<~UwEA@Wh7hNr!Cs{mO%D5qPdO5& zEViuJ?0E*3+`%G-W)zlO8hTrdyCWWzc06@b?oLbqD8&Hg;S8l>Ae$ze$aCz0z1ng5 z+k?p>xGCgJHE`)Lj%t&XtCLIt4PHTIp5|E`ImMvI$9*h{CqxBSL92GEMJzS%KkLE^ zvMIT4*loaE8v1vw^8sdy`|TU9*PiN9jdR!)YzoelE-9rss}7!HA{+BQAH2ICdlI7- zleA|a!Pfhhuq3@JRg3=OJv`_{8+rWQZ&YdXz%2`d<*p^@D6xc?V_3Ac#=?wM*g|cZ zyjIAS1Yuyd#Ynp@8MJgpHQY6}2A^m;>@&VdFsj})f-hDt)rS-4(J)Fp%{VM5!*mos zr<-89(qFLUc$G+FOrHkqn4NF5R)6q)taA#Y$#K5Qwi(TK&d8qSr(0R9+&Wc+HBJjK zQnU2TVkmsc&GRr^55?N1(i( zQ;o13vXwCMO5E*?t1V?IEBYrvxnK~XswOv(scpo zn%m2u?BLr|K;M!tHcE5hhFCw4l~eDAZXV$8Rxq zy(-jg9pwbEtKvWD8C<@X?1oG>3vx7*=%{Yamw#Spw4cLBdYP1A=LG;Z* zB3Wf&yB{l8omnp;_4W?^ZDvP;^}AR_QtEtVE^r(BG;u>F@@}wM7`S3>roX{@sSLOqILl5exZluor zxuLIB&*?rb!_B9jz~-3pm>i-ol%C4C)dx1=q8Ykd-LaJ3(zPJf%I>95s#^3viGeL|Szm2iPId#VZ)}iZK@F4IRyphH6 z8LU@M2<)w|>=vHF6Zq)rP{`CbYgxF3On##`nOB}TQ05_zXL`sv^%)K`5VUhbQM0p8 zr3vzE+x%&MDI(K80yoTCMk)h<*E3BweNy)EAKz{In)6!CRDIw4QU1}q5NYt|r1m}3 zS=~T?>FfQ?)rCPx{@$4W#jEkSga26NlS0B>Xc%KSa>5)hRU9oboBFBVJSpsu8F|F9 zm5D?o^%=!N$HA^4@@-ORF&)$j+g4LSwfVq$hgt*s>=w!k^pwU9@%CU*{Gb!iD8>Vz zu~0CMX>+h8A&JMJ&Qctx;gBot8QOvSj4DUV_OgqtJTdQ|`?)TKVLaZ1NWFkuJ;8IC zv-opVoy)HjFNK}zfr>VddLnktdXQKNEK3YLe|eugtsH|a>Y^xOvtPOmPicY&Ec%DA zsUB;sa7E6U1PXh5-uu513dvIEODv1XrhB#25gmTn5}%ilO}`J!xqDzJ?@IyHVC)MN3(Zg3M!e?5O!l;)cHV5m{sbI`r9$5z`+ACb^6kcLosdr zY=+D`F6dIr|J9Bw^`~*>A=+1_;4-8B zFWTp@6CaJ=lUVV2u4zE78&A1m)uj|1cAZP_#x!!nnl;Yg(Sj8kF2c~zQi^^>;!kdHQMLc(M&%=@p7y`FVXF0OxP+9os)hQ{=3eO+pS@D0+{k}aWBgIA&kB?>w&53RlPz>A zr`7BDlYez!h7cnT2Z8xCE^1!fA|&_c9xRKM8@sJTtDrA~N64A%|(=Yk57 zd|&F7%roP|zV%`wZN4q4 z!614n6W{)tPqE8k2N-`2sUJGO)_o3c8Ct%T@zu|1SzLZPyct!%uX}mAS9MjZ$6roP z{*m)C_mtjiuG~r}+<%m3)HKo5 z^`-Baghc5)tNy3!CUICoQ5=@CCSh$;GwFAOq<~g8{|V*8Gv)<2TLK<~nesKRG^(iix6#WatwSwx)EH7GY6Xt(i zbDAzBEeNQ~1dJ&#+3+|WDJErn?l)HbD48&JEU$LL6(Dr(qGP0YF3GXwlOxU#fa9IA zXc+m^9lx-gbC+a9Wp{#!(Zxv_RQROT$%`=3Bt#P6C}=Mh)-=M~y_KH~7OQa-v>5vr zKlQUeT|7#H8OL{6EY%+wE=_a~QP7KY1tw3BfGuFU?NDSqgf8EPh^`N=Zw`cnvJSR0 z;7x^+k)LzI=-HO{(q3PjY? z`n#mU4I;6&3)vvFP8O}L?`kXGr^97RBF@@zcANZ~i)72`8bI7LFgXLo+g+?+?j>%zlNbL$0vuP$)Tk`a@%i5htq;ZwOp!wi zvWWU#gP$){Csm#88!sgyy^@one&-z7EFTJahSW6b!CFcuuLvmIV?0%9M(HIV&;P4(B)Rlp8|#k{L= z*J*EeyNtD>e+X0xr}nzw1nc~BOQc6!t%*}XtEMFFfOD%R&Gm3jp~fdxjScNUK**Dx zJ4=NTI(06wJNbNg)s_yg><))$;O`Hlpm6FVqKS~az{wb7?lc#lT^dizA;k{5eDMzf zQoID;ajRXQnue5gL@JERLT-uFt4PSd_G@T*bH0wA?kFL(z1e_D)#L*haKbfQj@IC^ z5aQkbHrL&Gz8W3faR_fZ3|@McFFi*mXTn<^e=k#Uy5n4{ySk703Zh;gSuzNnacEEj#XS?_dwAhY#kh80uJT|cco zjcJ5)!897wXPvpEJ`ILv<8b_j(j^-8R*O9QI!GYAHbmcW;c9MHtJ-0ex|OV*y7u~c zK}HXGySV>4O}D%^JVcv{W&Cs=jAqE>+On7?hh!MfZir0P03X#j1CY@h$d3J@($ae# zVEg>`doy<)_Gj>h4L$6-DdH48&+=bY1`t)Hfi8U^3Wh~ru|h>0`>9x@z>(SK_^6#9 zSFcGIyMo+2@07bf_5?b}eI0EtK9^P=YG^#V_tW~!3|lH^A!dW$GdL9TS^47Wj9*$W zVc%N-zg=rBrU#UkwcRa>ZWxuOYrXA$JWOS?8~ho?jo)U$$v+qPJK?dJ5H9rhmuAkq zLsNN2Z*JHYZyUIPK%2@I!4oyx(yzmxE>hZsvy`6yXP!bx(P$&~nzgN?I!{wLVJL5%U!_#|9as_{nA@f=+x`v{aME%a zJ2~2>Ci%5)Z#=+5P}Q0;e^|-LdBGQ#mdc>=9D(**auK&BCQG#iZe;<<7!Ql+?XQ=+ zn=qWPejMSH(!$z%PX2~1r%8aNcf!_xH zSyAYd*mSuwNn>f1&pMPznZ(->ot%}#s#57`&S9C~ru43_CExV^cBV{}g5%LyKJ}7( z$@%Hb`xb>E0t+UcS4qijV)8)dU3W}94^eaBl(Qr~s_GPfDcZY5e_auTbo7_2!9~Ta za+Q*eF?BaBD$H@tT?Y>W+se|GcMJp+ykFas(B_{4&8pq(R*7UCRG=al-y%up0)bqML+DFwAqc-&61U@ZWu)ijKQ^W78pEp7aH-?n@LZf5?lDfi<`t+w>Fl za;}v=e}dha$u|TB&6t1!-9|+PCil-=e$k((!Xp|2yby4H2ku}vhzUkPi=n~#2s?|t z@vYpFRQd)l;lj?^n@wkWGMUbf{~5g9h;Zx4FZix_KrC9)EKw|;jVTQp8BT7Ng@7^r zEaKC%*PAhi=kd?|>s#L6* zZjzeQfHv780kj^Xb6PbrB8@8|vIF@lH;7Wn~Rwbh8ul!i4U zl5xP2?#kWD!jvu)JCI$e7$kB+M=oE0a=;Y#uQ(awB~7|EC~PMkI=^j8S)3juXT;yz zH-%HGlIl!w9_u=iOeqhDSl-fD-m>)6^CgV3ND?}KT3`foTgJy`ygQ_HTu=2;IR(Eu z;W3t*wl4-$=uo4m;W*tn7qUpKP`zHEjooAkD^SB2MRi@Rtbr#cSLTCR;Vt)F#AGCVBH7cI_wpe_~W@kk_SLNcVBu3OLLW5-;(ep;y9x`XJb}cFE z=PZrEh&*fW8m>THjY8ugtmc!h(-mXu4LgPY(;I-wYU6c8njA?D+5xL@>I<8T)l-Me zVOoc0`T9vDG3t!_a2VE1 zgKfFr^0fEN*Tk^mn%I{h)B~pC*SRzWqytmE7HLU0;{UCP@eETP;44O^-t;S#FuN;v zMszzD#qg-GjXYWN_i=bpfpY0cP;JU`+uySn-dlFog%w92MKB-Yqv|LLbb8b2QagSl z(M8TDn0eby5PlkF7Gbp6k9@!sP1#&vYzIOFOWzGY{))WIB{XeoqOfn%og2)*Vora& zBmrC9e^frX`KY`)1Xz0SF!=(+8JqmbU-56POy#8JamtsmGy3%Y>mnjA@!R7 zRuU{ejbbv;$;gP2^xB5h2gTDzc6%{WhV|>Hflke6cQ-zucUP~b(8%*C*PqOsX7}wyfcClaTwPP$FoC4T;^WOvNGJXQPt*OM zinlc-(Zi!YZP-$=z};kHFGm)jpP=`M_Rb7gy?5G+#VkTevzUvGS$}(6ct0~(r4%#U zyBMRR7n^jjDCu7H`7~A78XvY<=S+j`bt+ z(-FxgPL{F$hV`7)P#?f(dp~05W^MW5E&F%@wvzivHRHMVi+zyfSPI6K!E%J#@mA1>y6}_b&@{~L!xGLV0jEM=3-8hyp7Q=gy4PMf8Pqyu5xPMGM zWg^F%$5MoEL;8cXsAH9}_0*Z-YJhv3l0Q+#k=OEK_XJwc+7Zx`@2y4~!|_VWbp6=+o}g!W z@Y|iQ=%vZ7$?xC(9s7z|wQ_BZ4LFkwx{x6j1h!=$S1ed1`O`uw0prxR<=H&5-P}z1 z9r!NN4Dz?zy>gZ!eTX6%A_4{06IOh2sG(5@W;A$}^mt3qtQ_TmpXap0H{@;wF=V__ z#VkX-Fk=qLY0|SEan>UXlFuM*vsbfr&S4W!#wvJ^Yn2 z(tdvmloQ8aVk(m(DBko=%yj#E$m09=oppDAMjihleqv|5;#(7$0wmf&HJ5a?q;ool z#F3C7H;c#Og}Y)S!RA;>=; zj@Ea84W3YX)a?q3g70`EcLCaT_6g0^ap4sCBOcq&4GszOJ-B*{!SQV%{1ESCw|HO^ z%XyoBo4F|uADdTxC*z5F$&Ow)V$Ein)l{y_X{x3u&Orcb9L1xxs2It?`U}yxb_5B` zcVxvTuTbC$#TO$?3@IkeNUb6a@ajwMRY_Jub)IpAtK>D8&G z$3qXYI%yhU{xUr?bh?dRc;>SHP68Z9lMZUZMwyIOr()&U4kR)~3BpNnyAW&iQ`3;4 zq#E=!oJYABupPVo0oVx~Wy3V{g4`AqNc~78JiP%bZ_${2gOsNO(m#L86ZE${UcR*^ zZ*%?>08*Xo|4|*(PGlYMwWE1~hSUW~ml8tt_-#VY&fUf*1o4Iou`YMWgPC4wK`YSy zrZnToqej#nuR*s}qQs0<140O2jnVw2BUpR^CLCc|vI7R!a-3nv6u6F5%cP<{WW73wkjlfC`_cXy-Dnnl*jA*@ zr9ay(^CS87>;ip>>HDZ)J_aLC!`3lg9)$6W>h<|_>m`{%tL$^L0bc4epD_aKdA_t} z=rrC}>WIhka800#12+fpNW7Gbb)M}Ck|pjnezW&5qpN}qu3+G0+&#!kUk*hJ_cK6+ zTXW5+7e7MN-u!BHRP!`jX&!+5q{lp>q%+PB_rP zVUpp>;dnY6`Qu?@YudoX80Lqr&7U<-r-$xO&7BI1KSwFqj zkJrENmnqm!!nxy>ZR+WD>rC*W0;x#g*=QdB{1D7Gcs-5I6=B!N8Ic?2T)L7al#Hq# z@`HHuCuS<-1t69$cx2y%o?QA$Zq7qKQxJ_Z!fHlfrzDmnBNjhCkJgo`V?|@j!t<$R z*p#+O?BAAL?hGFNEO>`t&g&GGl{5Kt(N>+vMP2JPG+x=FR+T8Qc0B%rVntxszIY$< z^1@~;$BxeC#_p|vW5fWK%EbInUI?l(>EPyame=zg>DGewgxMxT@5zfU~yEdPDt z!Pj)pWmlx%Wo=KozC=^m!WLF8(}J2 zr+KKjN?w0fGWY>tJXfc7XfSYSfG6%xd~=hKtDH z^&QPw8O>W-i0SNKaD9dOsCfSMOes(fp?|XCH*NXZA$jgaYhb(C`{A<-#+^v_@lTi7 zP`J-?s;^F+k*x~83dka#r}9%)FxrWQJ{2oq{D6^042oFj16m;ZlZ%9*B9TMd3h0xz z{~fkB?3a`;-IOx~kbnS`UWChk0BpG4Ff5o(Vwq3HlUP4sB9LYPc+i35au5?5$pR0! z6Ms@@cFMGwbsFpLNYPZ{_9g=l&h0hW>^KMnHOl_HFhBrWtx5-rv=4YED- zdpH}Objkl1YnkLzbX(v{qELOmofuTnJ44@77BUh3{jiaS3cn`PjPYcaP znI7gWj}!MljekLmdpBu4$z;V+X@5Y%w?e{SL&6hcDfO=9`m^&aOF=mQn5}DP14KSU z#x zXu2dMX_Szp{SVGW+MtY*`lvl8^_4)^njf(UU?wLA!wuy{@VBN9%Qgc)Q^kv_Yz88t zDkBeUqxXy1=Dv2%UR>$WtQ!$59R@@XO;sJkC#o!or2X`kt*?KVrK|_tNl4ukH8Ajf z5~)6F07;%JnoE^&44DK3MwQBhNw;B)rc~SA~3%31EwBNud@6S$n3Z&*E{9QnL%_!D96hmMK!TgDWmPa^CAV z!w{7(<$aI+ayGlq1?$>FFLQKyLS9zZplH$1j|d6i5P9lB`>*F@H*g$I5m4MYzrxU+~1Ou$^b)Zu0k(WU$-Yn?4OJA2eW{$DSvt_wx zIrKr~Y(_Ej*jd_9a8u^_Zjh9Hrat%q_Gc10u+4Zqlb+4O zFMY~s(XoyUGT$qzms!GyGms`fW}9!pLrA8Z%ld=b6dzr*!iRs9Bhh4Gn>rPn>hZ^B zZD@zVK?EIy25*0<#BOS5J-qq8KlmXHry^DAj-y6Eo+eIoM5rP~L5^1qF;%sHd9cp2 zgzL0e*xDMZsl*H0sSCG;fOO1EXKgH>snIm^ITcJ*S}nAR9BKUJd^2_pHvR2tKRc~w zjxoWUohp;*3Zcw3wuV#v?ln%SkN4DN;r2#4iamTt42_&$wpha@)07nO)8WCM79CM} zj^ueF8FErq7`!WeO5Kp;=$eD^o(5f_N$K$(H`_1^wJUbEHE%bvLOud$pE_s0E(*<9 zg=8amnj|pq&;&&3Xp(CE*hZvKEgz!~O{334H#6R#LNscgi%8g)KBZ~QF&yE+fHldM zb2LKp8%@F4q~I4;WlwX>?|U%y-&TpcAf?%`*jp-7I4H2?2UEGCq`QY=+9@*$GDKRK zVl$j_^5AUfyOauMPE_jqgUxbU;poN-#SUS}2zl5MGh%M(#F?I&Ns(dpspK3j zx_Z&)WybKRiBZ z(cPYTf+8RU;UO+IwT1o{5wM{HFX;}NL48Zt&-5CM0dre7jvW9(8E@#I{hJ``zX|+O z0NGOCz19%UDcQywJQ#7RRK$#P_2SOQsRu$3*3e^9U6^quK^(18_?ZBlesSc%^k=~J zVWls5TJt}Le$j~Blaa9v*Lg5vPl|#Bq3{y}CCi5)IX+^o2Yy%7(Bxn zg`a?yBKB z5EVC5!Nue&d<87#BnuPB12O!_Wt5FaJmO3B?GX;oemNzEAGnN2Jj(8)+F!qxY{SCT zg6n(-MFVooIB^&7v@B8-)UZ7jchCVnLSN%1o7*2*FYi&G7%4eoFcH|G0-B4N)S_ly*p(eR*L<$PMpRRE{p|0nulDaglu5@mKdYg)L4DZIb)%7#a z-?gURFpTddFxEZ3IB0*Wc^h!`{@_x$*=}{I$Dr;cV$I;?`xUiF?}-k93?Ou$QyPCL zAc5_z|EV@Be`Ycr_2Gc?;j!og_Yb?8FzjP&57?Kj2DBTyk2{{W0{aE>^=BaNqUfN3k7xyqDC0V7K|2G`SHKFk)aZA(m7XNY1}1d#Jq#x2 zO)N-#tt$CenyuYkba90j*ySbVQ>|=RRysj*Mj|_xmlyRhkTUJGN%LMP8r6Ga;ivI+ zvXY$F&GiCU1wNGm{phipIn_I|lkU+TIaClicTUD_4e}aJm2DTn(W0)SMk&S;tH;$bX+24?2ipkLvdOmGj0Y z;e$zWrqyx?T$*$oeHA>}uvBrbyu zU0z8($%T>WC)k?|yXsIQ4$Xs1sZ#t*_=m zT3^fhc=Yn_HwYnQ@Dt`>u7MII=Is%I+(SK(Z;&C^kE&9q+d*=$)Ft7 zy)X7b?eTqUDvyX^Ki1>dpwRf-*QI z@aGlFPk!D#yt%ek!3lKiL`P}$rz-34D$ru}b7k>RTy?9vIzF^ z?D!8)ue%y+Vq~%Ea^zz!7?W8IO+WZSk8M)#KyPT0GO|@dDS5?TZ?Z*%SKHa8p+fe! z6kg9Xf)ycB#0UCklgt>RfkF#OPowWpjSkX(J-0oL0+b$ayy*ynda?T;i7c$JemK9Z ze@oXrI7?4RV`H0Q%muAem*JD4pY7dfPMu#}dFuigBR<6q5;rRb4Fn{Au6H*bJo3VD zd)z;M;qmd~SRv;nR#IR@UEeCYDK!&*6I@CX5&T1ZjZ}&BV-mMCo+(6lIqoZzh!Mee zQ0p#Cq&a)RYbxpGeGy4iZ(S>YMHYWBRmgx(V0Vz)%dN}LE4uLL%%&(=7-uhxWi$hO zWc)|!nkwxU&?Ejf$vk-kF+S&rlroOcHX5U!;IZ5uu$U}4Qf;TCql|Bhr-_)8 zi)~7q@i0Y6uYOxj_k33Tf{e@5*WV~WE-_-n#z)>)jbyLX2S=1rY~bDz*Xr7HC*R4L z{7!J|kT8KiU9l(@M`vF?SL=h=NoN!NS+W838QI+p)rl3972Xz!O#MLUuElkvm~^){ zq`rT@NpS`Ogf@0h>LNCJ5P5oOVM-w-GUe?f!;+{?x?!T~eazcxlc7sS_-+*mj0#HS zJqcuZMN^Ib)R7cON)MJ27(5xBe3fWA0OC)3Dqak6sf>I6gls>*U0wFKsh5|q!@F^f;pN@$aVCTyFEnb+4P2QMBYwVVL6;ET{W1FIK?m;z>CHu3&f{Z~G>DSbZ?;}T=Pbmq5%P8KuuYoy6+J4oC-Z7!Cayj4So&yLdP(6pEbIM`_llU zFtOzVqiPn6i}>&+8?QYaSk7a=|(C>@|!a%lgr+veJ>=(6S?a*> z6Sb1dYD+qj2J#{f?(~}&GYKCTYMDL-ju`tXZ(1IbV!{}o==@Jm3DAHEnk=i*6naYu z$~VrJE6h}T=JC7#Xf7=m4K3GSNfXbw!)w#+z$ zVVNu3++=UDd9MhD*;|<`@QJK7KchLhm~`MECZcmQg_Ys%S~f+5n%%c}kb)?Tt?-Gi z_l8yPmcB}`b1_`GAhf-bFR|wsxa^6{+-lLhZhx!vg#LKZnyciNq+?JQ(J?F}5U;_{ zf&UTT<^{$A11B9#3!_z29zILSb&yk}vX!!-vcQ?7uCZoEW@do1q=?g3&Mx0z3VV{E z&Ut5o+nS$n#`XMPS7FwL6K%hU!rc_vmeGU;PdmUdeiCst)RSIXD<&x?4?SOwa0>Y&$l zZz!ut-doOZ7bJQ-P+XJq_Gt{_L?@l`uYLJ!_V(0Uc+-Ldv29ySO$yb2$KLC$j7C^z z*L#B#a$pZo9=os8Tf-XD{#tsq2Y9nq7fRn5gNkx`4mc-a=i|Ze)?%9G6 zHwJ5fEFAjU9FlbC)QM>o^h^w;4QkZp6sLb`jyYp$Q02xduV86PRV!?cs@fX4uelyj3H_=LmsrHw+82P3 zSn4wJT9aUJQ5jeCNvMe>7llDfXZ!}DuQW45%~5PNR{aML_7?Fpkx*MD8x6?*mghHK z)0d3HbyViZ?9@z+-vul0R7%uvPd!tmd2AAz5qtLN%&_O9*ek3E>PEBK6HlTuP14WR z!0DSBW}zaTh^?od7@^@R!7A95;J`$6)B4^9OJiX~vrBQ(zf#xXE1Ah{_J+KP<{%GW z&Mvc9%O8pN!#6=t2f|mf#VyErY@?|z1EG+PpY-WCaNhBHe4G9XO?0|3#Gc-yV6GLe zh(3QZmeVJR-u4QOhTO0a(*Zpa*1L|vGh`D6dZAmD8>c}*Hkb_s+~>Hf*Wg3% ztMRc@6BeQ*{}O8%5vXRpZqvk{2+qIzy_xj$H=Bb%<>{-yr9KZg*wUNM3gSd(A0UvW zf=wLnp=FyGDsa1I+P!$x4{>5eJNO>UT4H}O^3cKomLf1`WHCZ!{(vOx&7 z=fa2=uiQUi)Z`UIf}0lx=(?&3DQ99n8e^FGhU}-Gdh}(h`QhyT;{NNdNk-QBio+Kn ze-)AV%^~N7!lZ|Dp+bf@*sUkQh)zupA2BVP8P?EfWaNzWaFp<*n#t32lkNa>#EX$1OhvdSi````cf|KH^E^ z$yIe{6)HJnyDQC1Nhz$*be8U(T#j}6(SnP#QCI6tDBII(AMK818veL=yd3*AS3L9P5K06VIbybX*vRDyF4@=g|c#m z_o?XF;z+PG`UTNme#K_HqEV2L21HP#A1=yDobL&SvgF?Omt-h2YtUdfoQ{DF`;d_5 zQ+T2*-_fP7JvzVLw?j8reT0cGau<9+CJ6_yV}QvbI1u6zZ~@jwxMNzOXmVOSgh{hH z4eXCp!WK0p2Aml(%|q#I#H+g~w5#;}tF;Adb7$0|B#__6J8G5~UbERVFit5NxDJHi ziw^`T!6tI@VD}?_%N+!)s8nagS6CvGqZFXY*qVQ%4d?YX{g~ceqK?7B8fy{3i-UJI zkZ9!6iIR(76-I)E4)aSr+P-YzzCNjFXV^k=SZBl^F65EFAwYw$eeYFF*zBTwVSh1? z8t$9cj`ZyUEnz0?j%hVdk}C48{pl*k7Y~lVZ7 zYFh?*ArvlS_Fm0#-|^ArntC!GkLhnPmeJo{d$N657*^$_o6dR+>v>295opJFIn9Xn z+|GV`PQ|38j=qAM3QR0M9$?aM)kJq2{r0Rk9R6W%YAz6sQI z8yUlf2$*nJa z^IX3HlfeamFz-0t=g;jmTO7#L>zI6vEgBp7>}@G2Zq_*Sw}K zxttKyu6rg(rRjHRSFLAXME#G@u2t|Xk)zin`+LftsY-)SALB<5uIX8Lya^@z{XSML zmyy5oE-=b3N0-Bpbj}S2eUQ)4kx%*o-1M!np|n0 zb9Sk`AEmip2fUT@7R^dEHtn{}*BftYsI{E)Ap34+o{{8!ap0J$NV**Vvv0SB`Z1 zW8-OLHZ_L(#hM(@VJbJ3l6d=KQv(+n>ktM*OGm70>1q;ky<=~x>y+v$DrIf=@XyKv zLrK2tU`wqmB^SYh3H0%ZO>!zP;lbC3?pPapeCR;&Q(O}|=PE&bR7xf(JTO8iD0$yu zX{GQ5B>;Qeus1e#z+=ViaO-n!oYxhE1Ns%T#JFd2 z+jk#{@l{j>HwbF|T_E>AUXSkXzD$nhEmZxGC{&T;!doT5vY^IsUbXo&`@=oyooe)wVY^CIedNJ$KhPI@IC8J=1Bw{%dK|2K6w**65_(XscKoE)|B)yFa zA{|tydHLP#UqQHC`)dRAVwK(s{LtZwrm4u5a3Lqm9kK}dV$-GqV!DUNldtQeyJ<%{ zBRxOVVcp3nsNtVp*8O`0HIUQ|=Br$$F2O<3Lx&V|PuS^lUbiz6=Z2QG^D8`W9EX}9 zbSWHG=Y8cCYLWTgkDNDx_ioay zGxj?M8uzD7(og-~KkMs%fSyf{ynK_MGQZ&O8p2=OoxF8;ser@C*pK^>H4`%N8fUZ; zS^GMP*>O()U7k4&;ino#rZ?u2bt%DMt9WjR612@s2={>fm(=P+V=K|j8E_iGx^0T& zAN|hv(IMgkuP|t`G8p3e3}@g5xO>dblr~w{&6)gB4x(kMwlQQdqD&irwZ=*$BahE# zVp>S6_DJ=VIhyNsO5N&=GnIlS2Q)F4PKY5v-J2qjQdoRXeBJ=CX^sf=3Mxxz;f(Qm z#*@@R>}n0`bi-&h9^M*av1~M+MbL7=Ty!kgBD}~vyr5^O!jjU5MeO*uVCK}FoWXjj zYvfYYuLZD}-$tX~Kt?|g)P8JQ_S5QfqD4BFr*0UYt2G!2iN&rJC1ct*4jy9<9apAz zeG3f^S|X(afW^B=gKO$u+C+exls~%ZKe8ss4%5z?>b_QLth7Dre{RaAQja$SgL|(M zB-7RXdXW7o-nz&!-$^dqN!Q*@ua0ffSv262GvODH_Fa%r2$^<=qo+^Hq=?mf%}4Lbd34pv#-m;^;PoE*L&xmG~pBF z2g?#>lxkYW>N+#Mt}LgTNu*bIw5HN8zVz5DW*7}M;oMvmQ6(Tk1ESZKi!Wo8N zVY@kZcJ-DhM8mXNjH-#{{u+{)pMa4VihCYdg*n}9jq;GY?Uo;v_O_gUgBboB> zFd)h1t@Bf%L}Ornq2GJ#=)D z;f@txI&}2tPUEcw{kIm^$9hO~_Vu-~H-c^Kd&R-B*((NsvALGX#y}_Q&P1j@T_5Wq zt0yo+4xP9@xyaE)z$#4|W+ZV&eEfu&3jzJIK-s$%eaZ(+tz$1}dq1cE3_dlM#7cV*b)xgOK5mcfM7y31Il_5`%@GZ4H0!6UREDx@ zns=~qF+~jm()GWquBmfHaudtWMcy={8*^V_(N7L?^=>+)i?*x|pngBz@Aj?+_SqFh8?#cQx^wk|z7 zk`zN}N!KF0m2TkJv)h2*A8f3l)MO@J)WFMXf(V((%QsBX^A;; zHuIn9Mh#ScA-T_8g!ZSUn@CufFL{&Rvw9wHvt80ux-PG++LG1SYs%_SF>Z*df$L`j zld~=_Sd{gZ%-S%mEwv@+=3ClNG{u*V#_0>5%HS4yQ23hMj7x(hq3)_>z{NA zr`25pc|j1E6Ny=D_1&Yt`Sdj_)7j_x?2?}VvkjtX#&i|i9YC6ST7E$BhGN+=%u;gv zwVRW2sV6Mc%UnQtCUkBp_Es}K7k%NL5MU();|$s(M%i7l4;c2trz*M_h?ms~QM91{ zGSgG8ZLq#~8g?6cxRxDLfJ?VYIhuPg@1vT0WqwTkK7^05b#FA%OnQvxlN7fz^3Xiv zCku5eWWFsQ&xw_Y1*U7+tv$zaD`Xj$@r+v=E#+)Rgj7YsMrpFTA(|F| zFEhR6sNh!gJ;w9W!6P5+;K8lxgMYADy)jYH@?TW3{1qGMI$L94cm26t38VmB&O4ZS z0~lq?WPP`$(!_e~Y|YG$#&-GV&$F`AQiJg`TD4M-91MH8XS3NN`?Xeo1;jhJl`VX2 zj?9FS(Kn6WlBa_3R{9I>g#|7VWX#K{N$1K(^`G_dXv;*J%=f~h^u3mqdd`Tt8OyyJ z`MGa0DyC-9O>#@@-Sc>8WkD}?Vp4F&p*7wWG`(3bxD<#+qhOCoV+x}h=KPf5m7bAB z0f*@6EE$8GAiMh@?m$Nr*AIgwEVr1Ynef-f%@RySIRpA{1Bb*_ixwW3AF*-5L^Oc< z6Gw}?x3rhhKJEVrb2u@npf{Q_W90$H#E0bB!Ou~H(gbus@-bj>;*S$6)GV( zX~>#hQEI@@2=fk;(+iYou#3d^k5N4xty5W(|>nJvc>bm>D#%dl_@ zWl}8}5RR6-LNm6Yk>P-W6VOO-V(pYja9_cP>%X8#+tgbatU&~}DqJB3aRwViu2h2;H}h!+x&>dZ_M%2lF~^Lo^fEOX$~Y@RyDCOM)<0c^e@R8_2~c<}(nHP*`2;@$due z!{^`$UAAbS)x5auJ@vxG9xu`4N=?rcTInp>LQQ>>YlnF(kw;2*%(QTAgAun^$oO5c(_;oXrYXb`qiLz+O>gdCN~9Zx;M9{X z$Y9{9eJ?B+rcMXT$y*i!klF0*Pk;*e7#RWEDRAPNG+y6XEXxW0nSMnc<(foT!f=JF0(aP!n=By* zHUy9(hlVo}M~UELMxueDk9OfXT4enqWE~(D72)U{Y!W4rWEsmJLy57EWDcdK(M@+; z4G95&LKEYyfTP9N0J0zN%tC2{G219GxhF|H(0Lk=OoSh0llgxT+a7C#c}3hlB9nu} z``m>3vk|}>MciqRxhT%VPv$~6TD(YvRgUf1Y=O109H+Dv*)PQ8gvydeJsh7oeP~Va zV40Ay%&~RjhB{9fxr>FU-;G9;*LITOH98QY%+O>sbYm?>KXGhTrwwl zH<$&?J_*BEO)E6zL(Ds!K(-5PLp8@xN16(yMqgo_fH<)dCAY#8SaKE$?*d7Yh#G)a z?nx9^!^63l6gtKaS!+RsyW88iccsUq4~KL=r2J_^bd+nf`9m+BUL(Q8EFH08q+Ne_}K_rhj&#mt5H&OK`(o}hdw~%j#f5ON1;&?;)^2#5G6lp zYG-P$6XPi;a@jcRBdf(L9ZEwFh-s~Px!2L5VPlE&n zTWyUVwVCmnEfd~5aPn*aGr8V7j-VPEOw>c%%TFRlRY1~3FnUVI;8?^A${x*_urvJ1 zCWOPA>9o8hY5J;!$6ibMas-|$IsrY!2=HMB=Srrx2EemwNYFHf{_2jQwxmQ`3(X%| ziVLWrdbdE}nvzxNI-EYF9j0+8$EcaqP@?^9lfXByszuUI-u-DJa(uh zTZH-T9F4O*u5{bPot)g7>rhYFSt*g+^3b=wU8@gLT|t_AN1@5^4A+OR?lVcK?-;Bx zkp)H>rJ$FztNJkn<3%&Iv=QkwK9VkQR4{N222^XwYfK0Ed%YaqU*BJ;j3t#kFSPCC(V*|>?6aV=4z|o0*gTb-YHrBe(F3_Cli)TsRp(#Vm@M8y=ewjE zi|!5g?Xh&sJ7=Pdf?1hle)61K8P-7{!*!Nc&484%5~sqp2HoV~^c&E(q>hnyG}=_* z4e=)(IsDH|?};`Wd-!<~=gmE2iHGndq10tP{H;#ekeqRj0vy)#iSrLzTTzdhMtGHq zL1&*4M}W_bC^UY}t&?aor=Nk(U54AmvSFr{?c*)h$&ctT@bCZ~N#*=?abwaAL#)2_ zd30BY9|^K>+(vU#b1lm1)HfVba1xy?*?PR-aGwoKH-Dqez#||yvr(28j5CHKl%rv) z%^&o<9Ea)FS=WfVxWoky8$6*Z2e%R{Gz)7A*3P?P*?0B~#(el5yjV3o8P8g(=n#?} z1VsA>$aD(4*aRz$YBg5m5B;^pZ+e3qXE19t)l~9q8mcHYD%B1nzG0 z=yFEv`)ffHczt1zVvNd=8}TSk#Ula)mDfwDNF%`)nt(94NH2Uje(kFuGQ=8xJQ%@u z(uDe~>1I>Hg|zlpS*U-|XCq{L*-S_m)aQ++0g%PNpfD*;XTl*xm3c`SNu$9RK~UOo zDf+ti;6mg(V z&7#B$b{GCV{w4$u><599bB0Rh+A4f8EtOOz>KJ_R>zeUywB$Jb@G_8KV|oZS?~Rre z7bb5Ktn7r77O&OM3q#ZO%9j}V@5rzxFh01W8=H*!k>iVNLEkN^&2H2+0&&Nq(Byz` znex>AB1T?Je)sMCKDf&@b0nQ(Jytc-QC)t&Dgy`vw)QLc&a5kSxpXtKv&! ziwR;Wm851Jc_*&%+tc?1YGE`Z8_BhNl7LokZ&7C$nQl~oEI$=1CILXvl-lCUS(@r* zrSECXvj=U3hj#x-cnX7|i&~;`#jN6(utMdRQL^f@(W&*Equ%((R^<;YEFUwEUA5Xy zgLAR*9ZdAX!Nm7sqS5$yv6VeFM9UzuxK+aU`wq7eB<>vC(Kaa2IZePYWM%mgB3+xdffCxz9oGU#zMW#V7R(6UF!M6yA_L>Y` z{J7}xraYCvgPC9Y##N|&>Qj2Olp_{wzkCW#UbJIK=?+$J3b8vaXQ`F@GE>awRv`1n zVLzBVV*PC8V#3$rJWF()v!w&j>8CJm5YjB ziwP~z4Sx|vfe4`m=y@V8)=_$Av7fk39f3zD(8YRaZ6C3EL3i(jAZ)Xhep%cuEm%Sn z?J`ETP(M*(E+H%>*tzCU@3Q`M2l1Kt?d=9u{~P(M31h{;t}E9}(EaW$qm`eLL#X{R z+Z(%Mu6i@6$^35_Gcz-pyx5}`Yuz8kahavGMeGrGGc%dJ;P{Vukl%!M)dZ?m4!oFnkeTQ<5rP$JuabC|EKdANJfe0IkQqtgfl1RCs(a2-PM^)j1Kb zJxNV)DA`^TKVwmxDQB|Nyg)PnU>gj#Fn81D2jHqeai*YB|UX!VJ9*R==zuJaaSK0El9B2WYr6FLt6i+5plIv-Q$Yj7~V{ zcAh!tIy;bb4|6uLYXx;;K!Y>1JI^z;ogFvRu5(;yMqwC6C$69&SJ2Rw&QYFT8tLF7 zv=R_ndK03%0a_{3*-Z%t6Rl@cMWE;Z!c+{EAA8Yz7q8B#0N?a+D;QauMYXYsmA;m+pbB3Ie{Uh zcb~yva-GRVAo@uuN%^WHL3z7Gz(22D2g-F@9`ft*C;81;R<-vZHi8gf;dE1qVe3G z3mXQiZYZbK*h8wW3?tC#{u7=xGqTzNo|3M)E zw_QM%BHWZ9&K1zk7+`ewtW9mn0+v&ZZgins_5JaxE|dev_NHG+gDk*fhOuXqZf=h= zWh!!IozyO739k0Ty17Z@vHqQQ40+;05_A`Y5aqR&osp@$D2|+1v21F15&4m+3|dMO1_$sw5thKy z1kg;YM92B6OyUe|j*J4YLS=ME4%S5U)(!~xb8RLYlCuhZoO6_*R)-%3GTSH)#iHG= z5#_xa7$2A$(Ks(8{~Pie-d`6IjoR&A-`x*(PCMx7-1-GZ*xA;p9opH!2b0D8u=GpK zv(F#1J09bk7OF_K;_RFU##d4)au4bqzhgBT!|#MbTbzQ*1#?f^8Z`-n%0(qefZY!E zGG2W@S0Bt*a6nHz$vdYz4R=(-v;vWNhw?s^DM1LhJFGw}HS>{OxUCaWnoZdPfZbdU zy620nHybTx3J(43B@gL`i~-n=PDW`JWs4Xr(BA(BF5L$u`6fc z!iHt95x8S|cxQuTYh3EcsM~8s`e&s-L`WD8bD$B*%${!pYrI1%!Vn8l(^n5&ADq%A`|B{z&YC>!+xuGi0;Ciqws)Pk z^K>@goi2BOK2U68yUz3`y^%>VKRrpqG7;|1m1k=WtHe=3KWE-lD`$3w5Kg~MFS!V;OZ!2RofX%*`)ic2WNUmOelg6&B`bJqvfP(pJb$I)mWev`!;H{zu z)=h@sY?P_qGeJk9i|g6>_e<|Xi6U(b>E74B?@Q~HLLqzdriwseJfKgaDP|8rgo^!u z{zW{T!E^ewG>qheiri+ztm`fnsrLu(BBimuo-eX{JYtExc%jg)RGZEAIw}(N@`oLE z7FYTEx8YHN@$&qO>@0juofhw>sP;*SzziU^cIa7*a6T_}MM7PLD7loFtC2eFfNen{ zI$ok>u_9hAqPhU0_{SpHn~=H(F!cwS1|>v>sfo{^vM3(jhi(dt9L`b*-cjl=l_WZo z*9$A8WKC>hQaWD3fo{HDOmYUm@{d$dsL6$^v+ow3$2(pkWwFLxEiO2NP)8%0P1Uv} z{O@4(lj*y>B4=?Uc(Zsoh@x*p=AFqo8`iJJa9JZZ1%?l2Aq4L*^&gFCyEzlPMc}d` z@DjjxIo-oiyNh*-9`j%JqHj|gt#1~!IiExsa~mjkOt)Z_{mbKW1@EL3g%?YYSXd7E zSWCXb($CBE)=x_qtsX!!+i{1`FZ|G1KcF;NKPX|fzX`$N&YMa<*5RNRY}x&Lump#@ zZV{_U;ZZh=%jaY^*T2|e&cHrancKho3kcprQFyD@axO;XSSRcnJ?}a%?@291_sN3X z5hk+`OU_}o&jFWyHb&4ywIXb?RH7IBwb4;kh-(|9pZsZr7t-R8(op5vFb)QY?|(ls!-9mIz!v|gN1@Kl6? z-JZI3!3S6ZXf=4I!jrc7DOGIlg&!8qau%yB`+fsyWp&2M-IerkZTIg?tdo8n>5-=Ji~lZbF?EBBk5& zJT9~f^gdSbP4#}e)ARj36r}Y@yUMiWWj_v27EzPee5n@;t|kMM@3EY!1Fl1a^7Xt9 z2gjwpt>`86w$JgIPU6}QUs@S>h!@M(o#_5sIbfwli7{kI|Fdf79(o)-o3Nebcz1@Zxv$)Lfd{LRHo(^S9D1-GYHeDjvFF2@D4 zsO_A=kxGae3U~8%E^gD;zQ=;T$F8asBc)!ASSy}Dtw*ZM@9U7Q`hLf}3zH1hzQ_UN!{=w# z-~jS9jn7d}e#y52@@2&_VB-|HRaAGzb&k;T9aGLCWH_8Gp}QaF!{%boG+Rc@bV`Mw zxt!<2_Vwt0$wzJP(cjOnDiz*#JD>LvCJwaXdsE!)Hg7?&cs3*n;@V=gYDYt%Jn;Po{DIFQ%(_k58x6#NX6_58(dh8Y9qsHS^r;{1!Gd?L{X}C@L4|Fx{10O?wCWfOh#9q_bx@dG zAe+hjvYE_z*(9a}cByTG6sZ9yYRW-TBm6v-D)FX#x`fEj^+ZLOfAwGy$Mef5xPmTAntNXPsp)x99RN6#waO zsDeB1;y+O3e?tLCb(TO-HtnKCocw4hiCi|EGDVyO-&0D>tKUcgv@QovV$uqg0fJf@ zwGa&$3Lijui+12w-fBrBLB-LG2DwbZKQ41hIZMFoOMW^Jz&&Y`hBaMku}r|JbwN%@ zBl!*lA+||*DfF^lvy7*Y-AYw3EHVsBB7?HX(yuIn?ss|}t{PFTYX+3pjxMR`oy8qV(Gf4QUG|_N9M&HtpY@t@J#l zCWDw?Qx#|R#7g<( z?f*wa3?`_fa#Z)7Ux4+`myZGN{1u$fCmjFlH9P<7HAmGa5#<7;1*Qu`#4|FJxqJ*7 z`ve4}1~;!m{&yksgbx0ouM*dw3iIbJd4K*_?ti0?_rIg>8hD#>n1E0N|0|!Bl`Rk| z!dwI0>V3)}{C4P&Ux!rr7emVWjI$_e!VK2e3+~+I_Cw14aqxe=^7H?C(1Wdg#vO&Ny~Hydq0F{F%_lJ8ke+I$sfA@Bbq?r0PLC+;c|5Xx=J=uIzO+IhiTD1M_>ZMcX@v^^NX&owSH5vwlF8&|NUlt% z45>^wdb=zQ{oD@xtV~oPQNXJ!aGJhqQ&#o>yroZoO_b9t)(njy08JyxekE?odmu=7 z1l5j-(xhKiatTx=Ndxq4$~aGd+r&(nkT_OWCYM_-12Ib8g>te2$G*utcaW7yGxmS^}e(n>A=;P46Zr> z>VLT6KWTgPk1PI1+U{nShc>2N>~a(A)HGE z+@AyXq^c3+E15{R{x!{?OuHs!bzS`@yrupM@6IV(@Hv{ih>KUkPcZzq$Qb@9GOR*{T)%bd`?t|= zKt|`3`<2(^FX0Kq_bO1a&O^Cu(yJ%9I1PIbeuVgdayS=*>|uf5et8>xTvWopwlDu} zd(WkPlRvgk`^)xNveZPGTWP`O+T&6WumcRHXH$vFeVZ{sdgW)*lo zIMqrYNBjR06!71IQqcyO+mu0BY*?R`mw|jd8kBdqYYASjcu)TVY~KY2fHKK{!~GL8 zf5H7n%$Nhp+Hpb0iModh+qjca5Zf)$X(rfN``>+5Ca{nw;FL>kzgZXn5Hf@Oko#Yk z$@}9nib+v_6zBMt%V2J~uVPlIW(*xy%Kx?o4{^Z837H1Jd~;=j+MP|=Fe&#;B)@&S z`BS*hL1i3$-0^>iUHQkp%lkfm#LoLWws``~bIM#vKN~LQZAf+o0@@=%kAH z2)_H2*%#kR>v3-uRDzC@>EnWq`i&wvrFM%@A|CU$c3RyQ9{O2uTNVj`^PZ^fq zg*C&&GKA~WGANsEyPOvCo|@-QP|EyMT;2Z^SAo;(sXx&N_&fU2gj=^%V>!LjOBRTU zqd_H0K(6IDvGT71b6`DN?w2Z*yJRC*mc^p}_p~YNj}qmRWd7t?!@uLM|1QNMsnt-n z_jXDB?qeCG>gn4ynH*bviTw)s9n$P9;l-3P=8VAnEEK7GVME*(KWJ+H1`8v5?%OY@ zvl1dQWk3?#@-m5Ob-%mzy4Q!S*vVC|&9&5nE5t&Bf}dKSW>K}OXY_)cVh_{8@Y-&U zF1gtLPi=1jRn^w@jnfDSNH-`Y-QAr6hwkp~?v_>*X$eUQ={lq!NTYOvlr+-Ke;?52 z-ut}w9slutV|~l&yM8PV!W1nBnl~*>?5|o)_#gk%9fwEgI zoST%(h$Dz-%7$bNwO1}Dlf%MlA+sm*&37Nt9|zt{lq@;~=NJns!9TXll{wuHQD!jC z1ZPL69Cc~6K0gM%HrtOFBR`oY-#mYF6iHgoO~G~c)3+%;ch;?G;G$%|pm$*f+rMDA zQ0;0#E>PDP*#}kBQ>vd}7_H-*^<+nAQeF06EKbH#jeT%OI@>V@1TF;Jj1_4%IQ@bvBE6c zeO#usYW0>}|Gc?jis?3^O?${;{ZMfXmu-pY1=RRgV-u_IlsIC1i`J6rmo8t2W%x}r z+28^qh{5(y%h4}>)x8WTpO@RRoGUZ)T$qRPY}@rge_cPbiABw*!v>unwyDozR5X^Fac*^#rV z6oD8?H(|uEOLNJrk;BD})#XJql}OsLJJqX% z?_pfb^o;X1!z$T6_B6{7sxUf5(rsM6tVKKA+2NCI>MH%$ z+2^yN;#ovt4h`>lo#tbtp>j^0o?-wnyU1QpO8YW5x5%Eqp zt0qP9b$b_%;*6C#UJYSYEIYufvm{h3yFt6t*wNgKFITdjj>Ir=Wt3;3g`;|I7na-ZRBADO^WeAq6glBD0m~u2t!hEQ%`Djx@p+ z7qz;^)pi9cRA=F zezVaVhQmRx)ko9sMV=jlI^%u8YT!@@r+5^_`yg_%WRm z!gWMjGlspf0g-ekJQPHaDoIB=^WJT|=sD|jW)a+(V;d2+!GGJl(82Q4s4bCkkhJA> zwIA^dN!H#MTvVdgQRX{G$+cZ)*#m3Ye%Jw21&lw=oX^+PUQGQwxayyeG`e}&w3`4Q zTz-=D!pI;j!&78Q(n{$G>j61w%Wi5gPP{=^PHY|QN6XPjLz{i(h8IrYq`?EJhOA#i zoL>4YqK1TEUgOtD(Jw|6+XuXAj?lHkIz_rypio-S3Z)2*_Pe zb~i)YJAHcP=GnfpS^{8lg6LKz4AsoxKz1P(M6j7ROFpgVB9Trzxzy;9m{#zLw@!Mu zFNGHIlxfXkt?cLfG@nJsY-(3Y5;yRBJ-;_YlSvX)IMJ6^Wb>S!;qgh6?xUGgANaP* zOKItdjO}~u;mIBqc`HrY=f}O8ewmhA{hDiYfPY%rZBxJ3RBcK<_w)(4PDDBtp_Wx+ zy>d&Spx<*%fiFOFA@8dGuv;oyw|xY=MzW^=1f*Bz_G!UkHz&i6Agja`l@xg^`8cOJ zz?-bk)3OPHkZXn^8wcUdvVnCRc^)>2?5gpTc@u=FA7{BU9I+ZI(kr5yo!;E?*t64| zZSV6k*CTyo&Yj(P=NU9-d02L$gaeGM)NMe|O_NAV#zL2KHdx}y{fJ3rER5C$>%Ps( zl9@~xvA5`J2kCf|j|Cu!6OBAt3_bPWowdWm+c#`WzYVzUE3%Oes>fX1ZL}Oih~eL_ z{dE1!>#ju~sn?QoCfrf;`X{sRYQ5m@HtCH&*|!cdWRmgTbQ5%@=5EC<$J>tV?k+Vv8t*m z0(Lve8*gkJ%X619aIB5BZZT%BY9+}kdkuBR+)CPfFDSUKZTpGqcMWy7iU#jy#Cq)g zCa+K9qQ7}~4DL@U9HeDkXm||{JBc^17m~=7EPkj%vI`KkL9wHy%`Me7kZnU<_tZ)=UrES3R!Ba!+w1&eWL|G1fGItG~Yf-F%@z>8dxLHKv%1oo9 z?R18TGxz=4KJq*rTO#c+xkEQx(Mn$9BO>k?5VMyZd1S?NhgZ4qC_A)c*;3uef*Scr z%|eCSAR)F#l-v~u@%V6z3GNbij$vf$DJ5$ggQu>WhTFd1UwgXb{eMSd)(tMF&RMPrgr8KE$D<8akTu7|LHho8eYWA!Z+a3EFCAqG5jM~=k5yS-24KKNlWe7DA;NVqV8Z$Sc#a9j9!f|+ zf2@_Had@eT~}AX~D~Cp5Et#rjC5orWkd0+p9Ck}=9KOfX2p%0OlfrA7B0YS-~)lzkrb zR+a-_aq`I4>|U6vt({`3Qvk-B;@Rg`i2%|+i zvm97e*ToYYQ2Vx*nM6ey00uH^pNA#g6=ibCK535tK2z-J@#b&KjKR zmn?~1@f8Zg(8cyhB@iCRYMFkRcSd+ywei;{7M&3}Vkvh7gj=D0vzQtfz}WgQbeDYK z?g^P0L>lyLAW+fJf648)4~6$3`e7Htn-t101tlO{bznp9@mST56CxAA3eY&+FiRJ&!?o@`lxhPqY!9Asp@tI}24@ z84m=$&mxbhtuyIi`Jz(@h)q4jlX52@EQxCi#Hn0XDhWVvWZId6!ykcc`r8yh(@yZ6 zWNq~Pj`Vutg0@P_mfquqE_*uu(eDXh5QD!0$M?o<%9s#doqIV(kWK82P_~y zjH7GU{|gIW5g~h}@7Pf=1zp>~HtAwQX3`otmC*`5g!;nJn z+!y+Y-K_EfrfoosjOZaAAZW{nI6o%U{z1v42Xv1T#MC`Xmj6Ua{2nE1TMH}*H23fU z0}NA0g!gy=S-6w_sRdmuJaE1HkExA+Px}8_oH`Z-g0sJx`1o6o52&@3W5Gt~JB>U5L*3Wk{^T z()Sg57G0}|_0af#O8QWTB8`bZI6>ABWO2mbXD5zrn@RnTw11oWpT(vGn)(4-nh8Ft zf2*o;sk_|2C77$V{T2>riQlX1KPyF|a)K7=-|>_EgI@}Z)Xl~Pq?NgLvKzNYkNh=H zo8Fv$CwcR}X@C(1!E=5Mjk7~wKO`5hr-`=uc?p4M6Pi`J3 z9swsd?w+b25?|^)E4C|wakNpLvJZ7}v4&w)b?Pp=D7Edp-ZugwNGbAPaT8R( z`X!~&J4V{esGK0ni-aX7?eFx$EPCy|va#4MRvbQ-oIJMxHFiJyhtFX%kp!&NJ|9^* zfH5sF<~y_KN&!(%K2AXTa@bSEk~3tA&r1C^3c1r%tWuAa?nRO5XX#iZ^O3WI6c7V* zEHc*C`3#1s7=Z{s#3VGtgoZO<0)YZ80SVq;nC`_B_oc~~qN0}^EG%@`VOI^H9JCJv z>~wR^sj29C)V~r3DEFoY<`B8wc*$B~diq)H!Dh)eQ*uP{OR=8?f1@-|N$VmhOucHi z#$=XN_z^!o;BUkkm0UyZ++({gbdc61Z}O(Wl*^SYMd1fkt?Zn0dL#NA^-1Dv-d@At z9HPS;pI&b`k1`Ko2C^m6tV_|EvkCidFS--zs!FA%j`02eQ)zB*SPga=LZPeyVsr#@b;UX z%I}~GxL^ZZtjEt{19k@hyNxSc5MxJ)vu1k@3jb%KsX#gf4_g0C4mAui{0g3Z0c1H2 zMnX?OCTkc3(qMP*wzr5vpR)k+Nab7Ms_sH`U0RW0W%-T^@u z01y?kJFv?Gz%&BDcs`h+K1-Zk{Vl!~Rk!H!-$7MVB#QnOg^htW8bdAHCA1+t2^cTA(jm?4J%di5Cz4Tgoztm+utO0Vtox%U!U(*)`^_WIIHsxc-`e`p+#W-bnS z-e@TZ)tSd004GM18sNk@1vxS911Co8X?63CXmWXZ|xOGJ>5*2pb^`uWmU0?5v);E z)yG0CPvUT0(b*KYWHLt-lIDgyCKpUM%@*#T(Sp4%DW8BQA+Iq+Z4 zkS!FMaT^e`X)S5VRH*UiYz*g=qDUkYqh0e(xMc)*do(NrtR87}EbSTka?bOBI4ocz z1Z>@TSYuYg)ULanO(L8!K;6GYE_f6{Hb#5qD`DTDOkFcTOwFEMWP*wn2F_(2XSNw2 zi7XCb^zJARp&T?n`+fqVnw5c6H-a?fOv_Vvrvlbn59flHmev8JOLh_1mW{Y90n0Bi zo{e4$v}@ZAk3E~U=LPdr8x3;=Wb0?pnm7RG0G{+`UsBYs*i3(8UyGH6{$fy2^oxd%=a4TNL6o64t9z-WnQiMx{;F;^d5J+{I^Xf#~0JP;x% z9$pQaSQ$q$_~VkYMn5CG>U|_CAWc9Akfhm)3UNQ5sIwTBqdJd()J_{Cs86S&$>9L$eJ7rwdh&nl4pah5H(} zuMdhZZ@R*|=oN0?3{(ehmwjh}arBS%oKm!G@if%*2xRM=QuHTw!E;=8X>}G{fCe)3 zy#{a;kkDbVg_{a#w4dU5@oi2UGWhKULc%mb_!#s5%@4WfEB_BZ3>YH+`hW04?)l&T z!Kbl>!`5}HhfkL}X{w5>5qQf9<0eyWH0tz>5g?-(n`R>vISBe zL@FgcXDh7L=xs58tT6sc5CdfQZ61&+___Dnl<_F&Z>Avo!tY|*6e5uvL|h8Mc|Zom zA`S`&004-#3H%5c5Pi3s;!yj4&o_??GLG4+Ga5}X&^&!b{SXui7b+ekKBKAJ-(ZnH zAo3@Th+-(8QyWXM+(6;^8#_iC_2A;ZLrAH0%fM z$Qe^OVIIKB{ps)?u39Px^#NaafV}r24m>ySjnTxTir>Z{q zfwq2_0`vi6&;ME6ya!YuXCO#se@jy3Kba^#0D12pAY~pp<-W%symS^ocFEQqr5Hv4 z{P&2B{#%kMxnS$Rg$yD8)Pw^9olNz8P5y&o!A}Rmf5Sx8jT`lEZ3R@y^uFv3kg|6_ zMEj@gOaF1f@XxZx|F30-7`smbcsu$#B0T@UWe3*C|B}f66aHJykjM8c{oSU!IlA>f zSNi?b{TfXF=SqJCStG`ykfYFl)-BLk0Bm0$dJ!m-_n*Q--W6@(2>!}^+mPZs^3Xyl zbhv!MKW!dn5K~IqF^X&>IRtSX6#Ju{?Ngws z3|15IL8~|dBDovau z7Vo!|%5SO(Ih8qDhC~!xW2vF0-4SfuP7n)S-7ity5hhY9a|S92Nr|F4O92;|y=;I< z+O%ar!<`V&Ab^HwtOo)b6HyQivy+s{<#;^x-6x!4cGw1ox#9cf z*90m5-zK8j#q1t2dn@0on?6V(do~x@Y^1W9bjlm3K?3pp5_=!WXA|{1XeNndlnU>}#N74}La67e8h8*H$3u=2}Cu%$8;Hw|x z7*+aDpvm*V?6MRqsg z+KEfq>N#x`oSCuK>MqMumIn5mbK>3<_t%)lfZNMfZKy%yzP@0CXNbb z7TZlBfy8L9)|cjcx4XLyxX+h#9SzDH>Z(<~Y%hNOq)KpAKtOu({uALE_=>JHYmeyV z+ck;3xHH=ymGL2pc!-&zeE!?}nEC|jJyzyEU}?>w!Z$T0edSeHEW0fH&aSfV8`DU{ z)8QWZ$09ae@u}*2*~dRjz~`>F7QEn8C3y}E>mC~vbj}vFuf(&<9_9lz$vM%UF}YLE;c~OU=k`>nO~B`=W{q{1uN+Edr*yc0?-UjgSI=FUr_0ZC zn#EBQ_9b(wL3Eb#ufYKK%=T+q=Nf!)2#Y&VN8&mn)yG*Jn5f?Fo~2q-Th&%y>UBLl zaAYfPH9Hcny`$+(SvSw$P5*=!x4n2~ziMdtYx2}#-V${yMB4A^ijv!^G~W+)lJPI3 zU8rDf)uk&J!n5S*YQr%TvqWs|G#m+n*JFL$qjOQWDO*PugBF!HdcpyTEFa$l@`L>Z zKRxfI&3uxm`o7{VhN$mpougbpVD)^`z#Alm?;&gX;G}O7vnht_ll4a@r3l*LnHdT% z*$h509$N@5+Idj1NvWp271qxIF6vX@=akn3NJ+zUeE+n*eKFXk5t!B&Se;=woE}vd zb)J6mQEkNI+lHh2>RHpl_7{tiO%$c3+vHTg?eG(w_c|`_V0%hmcweb^Tbf&5?$y&$ z3Tn8{3+;u={O;e|4EJ}=9Ey55P8i}aXq3^!8)f>RMJr+^uFibl--t=bN^81NjyKLv zP)9Ql`Du7HY6otbC}pgvY8zq>xI8!-kNMb@esS3`IF5Hy@S*wR(aFpHWQHyNt@@PG z=QW9!>fstyo!h?*Ji(p6PNIT25yI!3OF+dSvew*H*t0MMgHS^Enle8{i4{E+rjMh# z8S-?JsF`zE8;SnUYkD>0rSe`KI;6z;g6DLI*OB70>gdNV497b@2$!KbB8PS;e(HkRHT8c@;8Gb()x_b z-SFyE{O)6JLW`~1_66JH8j=k*C*$_NVA*cJQirkir92U^)P6sl^`==(pN+PPAxA(# z%OH;yYdki1G7q1*_66{$j1Y5No%+vWB-z9f#@c0Eh;vimf#nVT53?FzXK`|IR}m0p%=)YdWXh8l2NX(VtPdzvcn z49#Mn_z@4D!XHsSF41O+Ya~gM6iNA*#gsOVeJvY?HlHonm7+Pi`D( zwhF<9U2{&feoPL5wJ_H-UG*fau_;3p!+k&~kvGYPxf*Lj?eS)Y9HGp-K!L2z3~THQ@#eV4JUjIa zD;XT=Ebun3?`Q9@QKZP14SzHQ+-DX`d@Q_q>&?dR9pQP`d~9@85#J+vy6+yDSn7&C zrpVD3o7(|a;&eH(1 zW(BhVMH&3r1!0dBl#JcX9IgbtZz{qz+^(+a=q=ig1FM;>2faluQU*_hIQzVblRgnn zPuVFcgkGy$cRR#vDLRP$0Q-BHyJ#?_`BHQ!Jt#hSVjZfBR=$Jk{5|}LKlHKgj$kCL z`6DlQx_ZQ$QeEiR?Ipx|?z7AyG4LbBPhs>}LFKxf9l>S@3s492K^AZ#)ldz1#4;}D zLL)*!z8#`OLCE1yYc3$A11h)*esWlQC_@moNEMVjtq9T5bNQgH{(fS;5G5@G3n0^E zI6X|77uhT<5^MSh`!MvWPFh@{<^-kep{Os6%Z$imRcHosScoYTvFl!nk0WVmv{&(# zvJ)dD5>L>DGKQ=usE91XOwdI#!gMD-VOe;aoNZT3;st<;#w;51DEKoRa;SlxK?p8} z5vnZm_P}zCicxnzI2(x=CQAIN^UG80V~Nkx3sk|$2a-=L1j5Z#wPcZXyOuSfq#{7) zI5fdN5lTbt?dk?0c;+A?0zWl`j;xMhRFa@W%w{}36iURpa_T!IM-6}T~g3xa?ou7(45*%S|yJs zkekXR(QK1Cbk-^~M%G0VvYW$dLq14B+oQQ5KRU*LM7;gmCWxMAA^E}P7_tuz93P5A z`vRj8I?j__7##%Y4a|{D8fN3NrJ`p`MbP@lFfH#6nM!ep@gxvz;ahm1rHP??;9qy@ z;8bWhbzwMJVT}l(SiQ>e6~{6f{5W{AlpmB#&;VyD=Plboh0jUj#zJ#!)+et;k6`=7 zs0;`_v{ufzOhu~%``sFdCv<$N!Vaw;7li+_krjlG4?Lv^#PPIJ_Bs+{EZ`wFRwX3Eiw zqN&d?E-cIJ6J$Uy3f!>h^7~$8g1Pza&${Q+GwZHC-~SH1=SYB54Qt%&yNCkudf2#&eo?-P6noD1C=sbE?fA!+B_%6g&S4ReQtlPG-GX8 zU)|J~Y+uYQUj^RHWbOstePZ`y4%~Ng^4@pSx*5vsGi>lZ@!S(S_1tSc@#9Z-*uX;@ z+}^%pZ*k?eEnnOl3-{SpJaNP-WNg#tiC8Fy+2gwfel^|g{;=&?G`g`4&qLTV8kuM( zL6gHfGG%|lQ}Wq!bnqSN%~;$=Z&RC63mjp23HrpwVHcE9<&cM~8Xkk9fnv zgG~B|diL-c0TJlswFl6lxJ>Un(|70QuefJVess^zNG0L<@;jeiY6?3DmEC?4KWXzl zn&+-=!`*{{4ZPUfUChu}8sBbfx!UmC-n&_B4%j`snVpWz=bvmyOE6?AFQ0S9tVi+O zXVTr@TdSsZKRYBV_%z>g?V)Vyu&#~CVPqj%`t6weY$l)j`0RY$ z;{2ndQ1Guc2>WKt9IW4j4X|r(PE}Vv^OuNhsy6g{)9LQ-%xfC*AJY!aFW=0OObwF| zHn>J2?9CMi^LyGX4b5M$Za8G7xJIJwG@2rw&K1M@?#%@YW;qahoNsm;2L^7{Y$}n| zXExajxKCZ)-5A~-c~mmkQ@Td6~R7a3fz|cbnhoe4D=lyhef7 z5%A)-z5AY-AGqm6diH%;U@w2vdrrRas3CbYt~1`CbuDd!mly2 zQ9R(tr;xA#oY6$&RFVvKXyHFzY?QiFz?#_HyQ;@=Dha=spD;HW+_3;V=||2yY3vjQ z6lfa2uGUC<#JVB68_(9k$PMG4eQMpOkm$vi8j#(k-6BKQPZU{4)H*7WiT9c+oHx-O z^sYjQl5dx~YlY7pe*KzRwkz^(@kQmyyY<}n{1`e}y^WrXmf10XmAPf)y73)(p|LK6 z$$vS{*05nObgvbN@{G_4-=V^{&6lLX6*hemJQ>tUb$%~j?QD(29nZMzh{m4P@5%1~ z7U!<;YXk?JrFSw?_j!VEx0s0by#}rtfdWC z2?8%H&KUR5IT5~{&TX$mlf&Ve=ukbA^V(8F8Mj(hgdU&uoxM%?^pVa_eg10rh|KVg zXSN&<@95H7q4t#i1o-yoR;^E#S)S;Es*9;*ljCv1e4oxQJirYpjEnPSpDa3C*5=!A zxnbLWtl9YU8lqn(9-0nJ#!OdjTztYy-(9Y5OSczt->(_I4Ya&76>Q_XGUUz2+40Z} z%O}=z@k-6lloxe%s{Xk^`8Ei#kaAOR9cfz+$NL-38d7-j0TZ-3Iq{>>Jl|w$?THr3 zY|J&PW)wA1)n~Ui37Hcb^|Ly*mX^cs{Tc(oi=F|EDgGCZ@=NvbWG|h)Qr(54vI!cr z-5lR7;tKF6z@69WbK>$sAt^m-4)a7RQt?J@vp;jVu1VdZQw!}19MT*I+jQPcT8Do5vNPQH+5OJk{mQKIQj1{!IrrK&pO`tkft{^=Rh|sl z?d`UW_oTo%v@*lpS!jDg$!?+dd_y{Ttx7cuyp2A%D7%qRBAi_Bi*t7|eBr|jp6BqW zK3bB(%j6ynoa6?7(62v8zLd)BY0C`MD|LwQxlE|Gd45HTnw+)fE{*z~@GaRMKNJzI z724BL=mG!6cwOha!jm0~>I{2%#<5zZ_kzW@*8EH3v*UHG7odJ&848s<*xNJz98ap- z^)kB?CF$o1^F*0`$}Qq+LdpgONX>8)Zvd1!FnF+**di&Mpu6C}Gc0{rdiesp z&Vd-giv`~>X|IolaGJ52tyf>i3lbk%5H9J%N1snlk+JNSu83g}llXInRm=90R@4H1PxhVFP7kZJ$w0HkHEC4i&9Ynaflz zOi?_PypBOg72JS(pFB@sFsai;OUK%RS)_>ZNKC){2>H*$MC^&wPQ3i~SMNMUv3TGx zBSn5Z*`@s%6;|CM&jW1)*~<|RX?Y>j%NoZl`9(lcs49}4TCjkI4|)kQf-NfKE&jHd zL+k)HbKHpC@7k4L-|yty;r*1M)1e~U4jrKP*AFnQstY16!e~1(>>`Ad5Vs z3XOvg*iRnAb5Ouv&%uwGbr_eiY0>`-#^Ehh2XwYB*x*Y;@7= zbd`nh+7Q^_uSR9rv(!sZD3(N?x@eWaOdzAN!o-`y5Sl?VvK(7l!3=16r?$&OGedt$ z5}~7n?u1i#$_^uljI5u0h&d76p~L!nI|tduP0)p#^I{Jfaq=*vcUHk;Bls}&K!1gX z>6AgL2zv`PD!u$wkzkAxmZY#5Zr>a<>@-(M3vBK`u&*7oIJM^!CuR@_IDBnL@&vM& zS#sM?bhmz!WiWh~!EEb7Et@8+9=n>J)vB!2ct$HPnA)f`>fU?vC2+XE-apV=N%n2h z%v~q?(ePQI4XKC6$+n$0xA6J)BG(c3eqh>-_RX$M-P}OBa9e7bW&fJrML?~=#37@k z`hw0UhmGxBlh&2Y*2^.() -> Unit) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 80db0b3e..7203f06f 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -2,7 +2,9 @@ package space.kscience.visionforge.solid import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -61,7 +63,7 @@ public class SolidReference( } override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? { - if(name == Vision.STYLE_KEY){ + if (name == Vision.STYLE_KEY) { return buildList { properties?.getValue(Vision.STYLE_KEY)?.list?.forEach { add(it) @@ -90,7 +92,7 @@ public class SolidReference( prototype.getStyleProperty(name)?.value?.let { return it } } - if(inheritFlag){ + if (inheritFlag) { //5. own inheritance parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it } //6. prototype inheritance @@ -226,9 +228,14 @@ internal class SolidReferenceChild( */ public fun MutableVisionContainer.ref( templateName: Name, - name: String? = null, + name: Name? = null, ): SolidReference = SolidReference(templateName).also { setChild(name, it) } +public fun MutableVisionContainer.ref( + templateName: Name, + name: String? = null, +): SolidReference = ref(templateName, name?.parseAsName()) + public fun MutableVisionContainer.ref( templateName: String, name: String? = null, From 3529d0efc64302e538694638c75a58c8d8a4ff45 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 22 Aug 2023 22:52:17 +0300 Subject: [PATCH 080/112] Fix polygon builders --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 6 +++--- .../playground/src/jvmMain/kotlin/extruded.kt | 21 +++++++++++++++++++ .../src/jvmMain/kotlin/rootParser.kt | 2 +- .../kscience/visionforge/VisionManager.kt | 2 -- .../kscience/visionforge/gdml/gdmlLoader.kt | 4 ++-- .../kscience/visionforge/solid/Extruded.kt | 2 -- 6 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 demo/playground/src/jvmMain/kotlin/extruded.kt diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 13b1cb55..07112c06 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -209,9 +209,9 @@ private fun SolidGroup.addShape( require(fNz > 1) { "The polyhedron geometry requires at least two planes" } val baseRadius = fRmax[0] shape { - (0..fNedges).forEach { - val phi = deltaphi * fNedges * it + startphi - (baseRadius * cos(phi) to baseRadius * sin(phi)) + (0.. diff --git a/demo/playground/src/jvmMain/kotlin/extruded.kt b/demo/playground/src/jvmMain/kotlin/extruded.kt new file mode 100644 index 00000000..8a25549f --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/extruded.kt @@ -0,0 +1,21 @@ +package space.kscience.visionforge.examples + +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.extruded +import space.kscience.visionforge.solid.polygon +import space.kscience.visionforge.solid.solid + +fun main() = makeVisionFile { + vision("canvas") { + solid { + ambientLight() + extruded("extruded") { + shape{ + polygon(8, 100) + layer(-30) + layer(30) + } + } + } + } +} \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/rootParser.kt index 85a2f0d3..1faa8d0b 100644 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ b/demo/playground/src/jvmMain/kotlin/rootParser.kt @@ -46,7 +46,7 @@ fun main() { ambientLight { color(Colors.white) } - rootGeo(geo,"BM@N", maxLayer = 3, ignoreRootColors = true).also { + rootGeo(geo,"BM@N", ignoreRootColors = true).also { Path("data/BM@N.vf.json").writeText(Solids.encodeToString(it)) } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 2be8a6b3..e4ca1cdb 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -35,7 +35,6 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont public val jsonFormat: Json get() = Json(defaultJson) { - encodeDefaults = false serializersModule = this@VisionManager.serializersModule } @@ -85,7 +84,6 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont serializersModule = defaultSerialModule prettyPrint = true useArrayPolymorphism = false - encodeDefaults = false ignoreUnknownKeys = true explicitNulls = false } diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index 230af4b0..0c81d258 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -207,9 +207,9 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { require(solid.planes.size > 1) { "The polyhedron geometry requires at least two planes" } val baseRadius = solid.planes.first().rmax * lScale shape { - (0..solid.numsides).forEach { + (0.. diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 1a6487b9..014db562 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -23,8 +23,6 @@ public class Shape2DBuilder(private val points: ArrayList = Arr points.add(Float32Vector2D(x, y)) } - public infix fun Number.to(y: Number): Unit = point(this, y) - public fun build(): Shape2D = points } From cd28f377abb4c2b0c033a6861a47d7cef4b24023 Mon Sep 17 00:00:00 2001 From: SPC-code <112205870+SPC-code@users.noreply.github.com> Date: Wed, 23 Aug 2023 09:24:17 +0300 Subject: [PATCH 081/112] Update build.yml --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8c73f7d9..4b57e1c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,15 +8,15 @@ on: jobs: build: runs-on: ubuntu-latest - timeout-minutes: 40 + timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3.5.3 - name: Set up JDK 11 - uses: actions/setup-java@v2.5.0 + uses: actions/setup-java@v3.12.0 with: java-version: 11 distribution: liberica - name: execute build - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v2.7.1 with: arguments: build From 6a801f9999df5d29640802f74f6bff5c93ceff51 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 23 Aug 2023 09:34:58 +0300 Subject: [PATCH 082/112] Fix solid ref signature --- .../kscience/visionforge/solid/SolidReference.kt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 7203f06f..2770a7aa 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -233,13 +233,8 @@ public fun MutableVisionContainer.ref( public fun MutableVisionContainer.ref( templateName: Name, - name: String? = null, -): SolidReference = ref(templateName, name?.parseAsName()) - -public fun MutableVisionContainer.ref( - templateName: String, - name: String? = null, -): SolidReference = ref(Name.parse(templateName), name) + name: String, +): SolidReference = ref(templateName, name.parseAsName()) /** * Add new [SolidReference] wrapping given object and automatically adding it to the prototypes. @@ -258,7 +253,7 @@ public fun SolidGroup.newRef( } else if (existing != obj) { error("Can't add different prototype on top of existing one") } - return children.ref(prototypeName, name) + return children.ref(prototypeName, name?.parseAsName()) } From 92bfb173d8b49cb8b951a1b3f665ec310188069c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 16 Sep 2023 12:27:09 +0300 Subject: [PATCH 083/112] minor fix to Root rotations --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 15 +++++++++------ demo/playground/src/jvmMain/kotlin/antenna.kt | 14 +++++++------- .../space/kscience/visionforge/solid/Solid.kt | 6 +++--- .../visionforge/solid/three/ThreeFactory.kt | 2 +- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 07112c06..ef72de52 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -5,12 +5,17 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.withIndex +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.geometry.fromRotationMatrix +import space.kscience.kmath.linear.VirtualMatrix import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.isEmpty import space.kscience.visionforge.set import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY -import kotlin.math.* +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin private val volumesName = Name.EMPTY //"volumes".asName() @@ -28,12 +33,10 @@ private data class RootToSolidContext( val colorCache: MutableMap = mutableMapOf(), ) -// converting to XYZ to Tait–Bryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix +// apply rotation from a matrix private fun Solid.rotate(rot: DoubleArray) { - val xAngle = atan2(-rot[5], rot[8]) - val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2))) - val zAngle = atan2(-rot[1], rot[0]) - rotation = Float32Vector3D(xAngle, yAngle, zAngle) + val matrix = VirtualMatrix(3, 3) { i, j -> rot[i * 3 + j] } + quaternion = Quaternion.fromRotationMatrix(matrix) } private fun Solid.translate(trans: DoubleArray) { diff --git a/demo/playground/src/jvmMain/kotlin/antenna.kt b/demo/playground/src/jvmMain/kotlin/antenna.kt index 6e9b759b..5ec997f7 100644 --- a/demo/playground/src/jvmMain/kotlin/antenna.kt +++ b/demo/playground/src/jvmMain/kotlin/antenna.kt @@ -15,13 +15,13 @@ import kotlin.math.sin fun main() = serve { - val azimuth = 60.degrees - val inclination = 15.degrees +// val azimuth = 60.degrees +// val inclination = 15.degrees - val direction = with(QuaternionField) { - Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) * - Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis) - } +// val direction = with(QuaternionField) { +// Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) * +// Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis) +// } //val direction2 = Quaternion.fromEuler(Angle.zero, Angle.piDiv2 - inclination, -azimuth, RotationOrder.ZYX) @@ -43,7 +43,7 @@ fun main() = serve { solidGroup("frame") { z = 60 - val antenna = solidGroup("antenna") { + solidGroup("antenna") { axes(200) tube(40, 10, 30) sphereLayer(100, 95, theta = PI / 6) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 8b719b54..f33573d7 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -206,7 +206,7 @@ public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f) /** * Raw quaternion value defined in properties */ -public var Solid.quaternionValue: Quaternion? +public var Solid.quaternionOrNull: Quaternion? get() = properties.getValue(ROTATION_KEY)?.list?.let { require(it.size == 4) { "Quaternion must be a number array of 4 elements" } Quaternion(it[0].float, it[1].float, it[2].float, it[3].float) @@ -229,14 +229,14 @@ public var Solid.quaternionValue: Quaternion? * Quaternion value including information from euler angles */ public var Solid.quaternion: Quaternion - get() = quaternionValue ?: Quaternion.fromEuler( + get() = quaternionOrNull ?: Quaternion.fromEuler( rotationX.radians, rotationY.radians, rotationZ.radians, rotationOrder ) set(value) { - quaternionValue = value + quaternionOrNull = value } public var Solid.scaleX: Number by float(X_SCALE_KEY, 1f) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 46e3d41b..122a2c30 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -41,7 +41,7 @@ public fun Object3D.updatePosition(vision: Vision) { if (vision is Solid) { position.set(vision.x, vision.y, vision.z) - val quaternion = vision.quaternionValue + val quaternion = vision.quaternionOrNull if (quaternion != null) { setRotationFromQuaternion( From ba70af3a2445b5473abd87dff7a883a5facd9961 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 16 Sep 2023 14:05:19 +0300 Subject: [PATCH 084/112] 1.9.20-Beta --- build.gradle.kts | 10 +------ demo/js-playground/build.gradle.kts | 26 +++++++++++-------- .../kotlin/JsPlaygroundApp.kt | 0 .../{main => jsMain}/kotlin/gravityDemo.kt | 0 .../kotlin/markupComponent.kt | 0 .../kotlin/plotlyComponent.kt | 0 .../src/{main => jsMain}/resources/index.html | 0 gradle.properties | 4 +-- gradle/wrapper/gradle-wrapper.properties | 2 +- .../visionforge/bootstrap/outputConfig.kt | 2 +- .../kscience/visionforge/react/MetaViewer.kt | 2 +- .../visionforge/react/MultiSelectChooser.kt | 2 +- .../visionforge/react/PropertyEditor.kt | 6 ++--- .../visionforge/react/RangeValueChooser.kt | 7 ++--- .../kscience/visionforge/react/TreeStyles.kt | 6 ++--- .../kscience/visionforge/react/VisionTree.kt | 11 +++----- .../visionforge/react/valueChooser.kt | 9 +++---- .../ringThreeControls.kt | 2 +- .../visionforge/tables/TableVisionJsPlugin.kt | 4 +-- 19 files changed, 42 insertions(+), 51 deletions(-) rename demo/js-playground/src/{main => jsMain}/kotlin/JsPlaygroundApp.kt (100%) rename demo/js-playground/src/{main => jsMain}/kotlin/gravityDemo.kt (100%) rename demo/js-playground/src/{main => jsMain}/kotlin/markupComponent.kt (100%) rename demo/js-playground/src/{main => jsMain}/kotlin/plotlyComponent.kt (100%) rename demo/js-playground/src/{main => jsMain}/resources/index.html (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 68c3569b..775fd191 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,4 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile -import space.kscience.gradle.isInDevelopment import space.kscience.gradle.useApache2Licence import space.kscience.gradle.useSPCTeam @@ -45,14 +44,7 @@ ksciencePublish { useApache2Licence() useSPCTeam() } - github(githubProject = "visionforge", githubOrg = "SciProgCentre") - space( - if (isInDevelopment) { - "https://maven.pkg.jetbrains.space/spc/p/sci/dev" - } else { - "https://maven.pkg.jetbrains.space/spc/p/sci/maven" - } - ) + repository("spc","https://maven.sciprog.center/kscience") sonatype() } diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index 94835588..eca736e4 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -1,19 +1,19 @@ plugins { - id("space.kscience.gradle.js") + id("space.kscience.gradle.mpp") } -kscience{ +kscience { useCoroutines() } -kotlin{ +kotlin { explicitApi = null - js{ + js { useCommonJs() browser { binaries.executable() commonWebpackConfig { - cssSupport{ + cssSupport { enabled.set(false) } } @@ -21,11 +21,15 @@ kotlin{ } } +kscience { -dependencies{ - implementation(projects.visionforge.visionforgeGdml) - implementation(projects.visionforge.visionforgePlotly) - implementation(projects.visionforge.visionforgeMarkdown) - implementation(projects.visionforge.visionforgeThreejs) - implementation(projects.ui.ring) + dependencies { + implementation(projects.visionforge.visionforgeGdml) + implementation(projects.visionforge.visionforgePlotly) + implementation(projects.visionforge.visionforgeMarkdown) + implementation(projects.visionforge.visionforgeThreejs) + } + jsMain { + implementation(projects.ui.ring) + } } \ No newline at end of file diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt similarity index 100% rename from demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt rename to demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt diff --git a/demo/js-playground/src/main/kotlin/gravityDemo.kt b/demo/js-playground/src/jsMain/kotlin/gravityDemo.kt similarity index 100% rename from demo/js-playground/src/main/kotlin/gravityDemo.kt rename to demo/js-playground/src/jsMain/kotlin/gravityDemo.kt diff --git a/demo/js-playground/src/main/kotlin/markupComponent.kt b/demo/js-playground/src/jsMain/kotlin/markupComponent.kt similarity index 100% rename from demo/js-playground/src/main/kotlin/markupComponent.kt rename to demo/js-playground/src/jsMain/kotlin/markupComponent.kt diff --git a/demo/js-playground/src/main/kotlin/plotlyComponent.kt b/demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt similarity index 100% rename from demo/js-playground/src/main/kotlin/plotlyComponent.kt rename to demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt diff --git a/demo/js-playground/src/main/resources/index.html b/demo/js-playground/src/jsMain/resources/index.html similarity index 100% rename from demo/js-playground/src/main/resources/index.html rename to demo/js-playground/src/jsMain/resources/index.html diff --git a/gradle.properties b/gradle.properties index dde47c66..a16b8d7b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ org.gradle.jvmargs=-Xmx4G org.jetbrains.compose.experimental.jscanvas.enabled=true -toolsVersion=0.14.9-kotlin-1.9.0 -kotlin.experimental.tryK2=true +toolsVersion=0.15.0-kotlin-1.9.20-Beta +#kotlin.experimental.tryK2=true #kscience.wasm.disabled=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 84a0b92f..db9a6b82 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt index a37469ca..3dfba202 100644 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt @@ -8,7 +8,7 @@ import kotlinx.css.padding import kotlinx.css.properties.border import kotlinx.css.px import kotlinx.html.js.onClickFunction -import kotlinx.html.org.w3c.dom.events.Event +import org.w3c.dom.events.Event import org.w3c.files.Blob import org.w3c.files.BlobPropertyBag import react.FC diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt index d6fff754..651c9d31 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge.react import kotlinx.css.Align import kotlinx.css.alignItems import kotlinx.html.js.onClickFunction -import kotlinx.html.org.w3c.dom.events.Event +import org.w3c.dom.events.Event import react.* import react.dom.a import react.dom.attrs diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt index 5e8da06c..fc635d21 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt @@ -1,10 +1,10 @@ package space.kscience.visionforge.react import kotlinx.html.js.onChangeFunction -import kotlinx.html.org.w3c.dom.events.Event import org.w3c.dom.HTMLOptionElement import org.w3c.dom.HTMLSelectElement import org.w3c.dom.asList +import org.w3c.dom.events.Event import react.FC import react.dom.attrs import react.dom.option diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index 991ba2d5..58986076 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.launch import kotlinx.css.* import kotlinx.css.properties.TextDecoration import kotlinx.html.js.onClickFunction -import kotlinx.html.org.w3c.dom.events.Event +import org.w3c.dom.events.Event import react.* import react.dom.attrs import space.kscience.dataforge.meta.MutableMeta @@ -151,7 +151,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { css { //+TreeStyles.resizeableInput width = 160.px - margin(1.px, 5.px) + margin = Margin(1.px, 5.px) } ValueChooser { attrs { @@ -170,7 +170,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { css { width = 24.px alignSelf = Align.stretch - margin(1.px, 5.px) + margin = Margin(1.px, 5.px) backgroundColor = Color.white borderStyle = BorderStyle.solid borderRadius = 2.px diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index 3ebe4d51..4a82a6e9 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -4,8 +4,9 @@ import kotlinx.css.pct import kotlinx.css.width import kotlinx.html.InputType import kotlinx.html.js.onChangeFunction -import kotlinx.html.org.w3c.dom.events.Event +import kotlinx.html.js.onInputFunction import org.w3c.dom.HTMLInputElement +import org.w3c.dom.events.Event import react.FC import react.dom.attrs import react.fc @@ -58,8 +59,8 @@ public val RangeValueChooser: FC = fc("RangeValueChooser") { attrs { disabled = rangeDisabled value = innerValue?.toString() ?: "" - onChangeFunction = handleChange - consumer.onTagEvent(this, "input", handleChange) +// onChangeFunction = handleChange + onInputFunction = handleChange val minValue = props.descriptor?.attributes?.get("min").string minValue?.let { min = it diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt index 5d693a3c..109d0256 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt @@ -52,10 +52,10 @@ public object TreeStyles : StyleSheet("treeStyles", true) { } public val treeLabel:RuleSet by css { - border = "none" - padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) + border = Border.none + padding = Padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) textAlign = TextAlign.left - flex(1.0) + flex = Flex(1.0) } public val treeLabelInactive: RuleSet by css { diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt index 8ec0185c..6212a456 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt @@ -1,13 +1,10 @@ package space.kscience.visionforge.react -import kotlinx.css.Color -import kotlinx.css.Cursor -import kotlinx.css.color -import kotlinx.css.cursor +import kotlinx.css.* +import kotlinx.css.properties.TextDecoration import kotlinx.css.properties.TextDecorationLine -import kotlinx.css.properties.textDecoration import kotlinx.html.js.onClickFunction -import kotlinx.html.org.w3c.dom.events.Event +import org.w3c.dom.events.Event import react.* import react.dom.attrs import space.kscience.dataforge.names.Name @@ -37,7 +34,7 @@ private val TreeLabel = fc { props -> color = Color("#069") cursor = Cursor.pointer hover { - textDecoration(TextDecorationLine.underline) + textDecoration = TextDecoration(setOf(TextDecorationLine.underline)) } if (props.name == props.selected) { +TreeStyles.treeLabelSelected diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt index bc6f1979..5d0c7c3d 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -1,15 +1,12 @@ package space.kscience.visionforge.react -import kotlinx.css.margin -import kotlinx.css.pct -import kotlinx.css.px -import kotlinx.css.width +import kotlinx.css.* import kotlinx.html.InputType import kotlinx.html.js.onChangeFunction import kotlinx.html.js.onKeyDownFunction -import kotlinx.html.org.w3c.dom.events.Event import org.w3c.dom.HTMLInputElement import org.w3c.dom.HTMLSelectElement +import org.w3c.dom.events.Event import react.FC import react.Props import react.dom.attrs @@ -145,7 +142,7 @@ public val ColorValueChooser: FC = fc("ColorValueChooser") { styledInput(type = InputType.color) { css { width = 100.pct - margin(0.px) + margin = Margin(0.px) } attrs { this.value = props.value?.let { value -> diff --git a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt index d59b37b9..6a440e71 100644 --- a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt +++ b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt @@ -8,7 +8,7 @@ import kotlinx.css.padding import kotlinx.css.properties.border import kotlinx.css.px import kotlinx.html.js.onClickFunction -import kotlinx.html.org.w3c.dom.events.Event +import org.w3c.dom.events.Event import org.w3c.files.Blob import org.w3c.files.BlobPropertyBag import react.FC diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index d61e4664..469d4af8 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -25,8 +25,8 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { override fun attach(context: Context) { super.attach(context) - kotlinext.js.require("tabulator-tables/dist/css/tabulator.min.css") - kotlinext.js.require("tabulator-tables/src/js/modules/ResizeColumns/ResizeColumns.js") + kotlinext.js.require("tabulator-tables/dist/css/tabulator.min.css") + kotlinext.js.require("tabulator-tables/src/js/modules/ResizeColumns/ResizeColumns.js") } override fun rateVision(vision: Vision): Int = when (vision) { From 35ec4bac0ee54830d35cecbdcd158b38ccfcaa15 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 30 Sep 2023 09:40:12 +0300 Subject: [PATCH 085/112] 1.9.20-Beta --- .../space/kscience/visionforge/gdml/demo/fileDrop.kt | 3 +-- .../src/jsMain/kotlin/JsPlaygroundApp.kt | 4 ++-- .../src/jsMain/kotlin/markupComponent.kt | 7 +++---- .../src/jsMain/kotlin/plotlyComponent.kt | 5 ++--- gradle.properties | 4 ++-- .../kscience/visionforge/bootstrap/bootstrap.kt | 4 ++-- .../kscience/visionforge/bootstrap/outputConfig.kt | 12 ++++-------- .../kscience/visionforge/bootstrap/threeControls.kt | 7 +++---- .../ThreeViewWithControls.kt | 6 +++--- .../ringThreeControls.kt | 12 ++++-------- 10 files changed, 26 insertions(+), 38 deletions(-) diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/fileDrop.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/fileDrop.kt index e91fedee..2478c3af 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/fileDrop.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/fileDrop.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.gdml.demo import drop.FileDrop import kotlinx.css.* -import kotlinx.css.properties.border import org.w3c.files.FileList import react.RBuilder import styled.css @@ -13,7 +12,7 @@ import styled.styledDiv fun RBuilder.fileDrop(title: String, action: (files: FileList?) -> Unit) { styledDiv { css { - border(style = BorderStyle.dashed, width = 1.px, color = Color.orange) + border = Border(style = BorderStyle.dashed, width = 1.px, color = Color.orange) flexGrow = 0.0 alignContent = Align.center } diff --git a/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt index d77d8f52..0bdee628 100644 --- a/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt @@ -43,8 +43,8 @@ private class JsPlaygroundApp : Application { createRoot(element).render { styledDiv { css { - padding(0.pt) - margin(0.pt) + padding = Padding(0.pt) + margin = Margin(0.pt) height = 100.vh width = 100.vw } diff --git a/demo/js-playground/src/jsMain/kotlin/markupComponent.kt b/demo/js-playground/src/jsMain/kotlin/markupComponent.kt index 4bbe4b80..a47c28cf 100644 --- a/demo/js-playground/src/jsMain/kotlin/markupComponent.kt +++ b/demo/js-playground/src/jsMain/kotlin/markupComponent.kt @@ -1,5 +1,4 @@ import kotlinx.css.* -import kotlinx.css.properties.border import kotlinx.dom.clear import kotlinx.html.dom.append import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor @@ -45,10 +44,10 @@ val Markup = fc("Markup") { props -> css { width = 100.pct height = 100.pct - border(2.pt, BorderStyle.solid, Color.blue) - padding(left = 8.pt) + border= Border(2.pt, BorderStyle.solid, Color.blue) + padding = Padding(left = 8.pt) backgroundColor = Color.white - flex(1.0) + flex = Flex(1.0) zIndex = 10000 } ref = elementRef diff --git a/demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt b/demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt index 322e80c5..80417dde 100644 --- a/demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt +++ b/demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt @@ -1,5 +1,4 @@ import kotlinx.css.* -import kotlinx.css.properties.border import org.w3c.dom.Element import org.w3c.dom.HTMLElement import react.* @@ -30,8 +29,8 @@ val Plotly = fc("Plotly") { props -> css { width = 100.pct height = 100.pct - border(2.pt, BorderStyle.solid, Color.blue) - flex(1.0) + border = Border(2.pt, BorderStyle.solid, Color.blue) + flex = Flex(1.0) } ref = elementRef } diff --git a/gradle.properties b/gradle.properties index a16b8d7b..e65394ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ org.gradle.jvmargs=-Xmx4G org.jetbrains.compose.experimental.jscanvas.enabled=true -toolsVersion=0.15.0-kotlin-1.9.20-Beta -#kotlin.experimental.tryK2=true +toolsVersion=0.15.0-kotlin-1.9.20-Beta2 +kotlin.experimental.tryK2=true #kscience.wasm.disabled=true diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt index 2f924ecc..c0171cb7 100644 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt @@ -1,8 +1,8 @@ package space.kscience.visionforge.bootstrap public fun useBootstrap(){ - kotlinext.js.require("bootstrap/dist/css/bootstrap.min.css") - kotlinext.js.require("bootstrap") + kotlinext.js.require("bootstrap/dist/css/bootstrap.min.css") + kotlinext.js.require("bootstrap") } //public inline fun TagConsumer.card(title: String, crossinline block: TagConsumer.() -> Unit) { diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt index 3dfba202..f42235a8 100644 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt @@ -2,11 +2,7 @@ package space.kscience.visionforge.bootstrap import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope -import kotlinx.css.BorderStyle -import kotlinx.css.Color -import kotlinx.css.padding -import kotlinx.css.properties.border -import kotlinx.css.px +import kotlinx.css.* import kotlinx.html.js.onClickFunction import org.w3c.dom.events.Event import org.w3c.files.Blob @@ -29,7 +25,7 @@ private fun saveData(event: Event, fileName: String, mimeType: String = "text/pl event.stopPropagation(); event.preventDefault(); - val fileSaver = kotlinext.js.require("file-saver") + val fileSaver = kotlinext.js.require("file-saver") val blob = Blob(arrayOf(dataBuilder()), BlobPropertyBag("$mimeType;charset=utf-8")) fileSaver.saveAs(blob, fileName) } @@ -53,8 +49,8 @@ public val CanvasControls: FC = fc("CanvasControls") { prop flexColumn { flexRow { css { - border(1.px, BorderStyle.solid, Color.blue) - padding(4.px) + border = Border(1.px, BorderStyle.solid, Color.blue) + padding = Padding(4.px) } props.vision?.let { vision -> button { diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt index 9ab0403c..0d5578a7 100644 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt @@ -1,7 +1,6 @@ package space.kscience.visionforge.bootstrap import kotlinx.css.* -import kotlinx.css.properties.border import react.FC import react.PropsWithChildren import react.RBuilder @@ -33,13 +32,13 @@ public val ThreeControls: FC = fc { props -> } tab("Tree") { css { - border(1.px, BorderStyle.solid, Color.lightGray) - padding(10.px) + border = Border(1.px, BorderStyle.solid, Color.lightGray) + padding = Padding(10.px) } h2 { +"Object tree" } styledDiv { css { - flex(1.0, 1.0, FlexBasis.inherit) + flex = Flex(1.0, 1.0, FlexBasis.inherit) } props.vision?.let { visionTree(it, props.selected, props.onSelect) diff --git a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index 3b7133e9..6ae2ec62 100644 --- a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -130,7 +130,7 @@ public val ThreeCanvasWithControls: FC = fc("Three css { height = 100.pct minWidth = 600.px - flex(10.0, 1.0, FlexBasis("600px")) + flex = Flex(10.0, 1.0, FlexBasis("600px")) position = Position.relative } @@ -199,11 +199,11 @@ public val ThreeCanvasWithControls: FC = fc("Three } flexColumn { css { - padding(4.px) + padding = Padding(4.px) minWidth = 400.px height = 100.pct overflowY = Overflow.auto - flex(1.0, 10.0, FlexBasis("300px")) + flex = Flex(1.0, 10.0, FlexBasis("300px")) } ringThreeControls(options, solid, selected, onSelect, additionalTabs = props.additionalTabs) } diff --git a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt index 6a440e71..6cdc0707 100644 --- a/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt +++ b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt @@ -2,11 +2,7 @@ package space.kscience.visionforge.ring import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope -import kotlinx.css.BorderStyle -import kotlinx.css.Color -import kotlinx.css.padding -import kotlinx.css.properties.border -import kotlinx.css.px +import kotlinx.css.* import kotlinx.html.js.onClickFunction import org.w3c.dom.events.Event import org.w3c.files.Blob @@ -34,7 +30,7 @@ internal fun saveData(event: Event, fileName: String, mimeType: String = "text/p event.stopPropagation(); event.preventDefault(); - val fileSaver = kotlinext.js.require("file-saver") + val fileSaver = kotlinext.js.require("file-saver") val blob = Blob(arrayOf(dataBuilder()), BlobPropertyBag("$mimeType;charset=utf-8")) fileSaver.saveAs(blob, fileName) } @@ -58,8 +54,8 @@ internal val CanvasControls: FC = fc("CanvasControls") { pr flexColumn { flexRow { css { - border(1.px, BorderStyle.solid, Color.blue) - padding(4.px) + border = Border(1.px, BorderStyle.solid, Color.blue) + padding = Padding(4.px) } props.vision?.let { vision -> button { From ae12084dee1cab085869cd219494b8ba263ab21a Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 30 Sep 2023 12:51:11 +0300 Subject: [PATCH 086/112] Fix angle problems in Root importer --- .../kotlin/ru/mipt/npm/root/DObject.kt | 61 +++++++++++++++--- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 59 ++++++++--------- .../jvmMain/resources/root/BM@N_geometry.zip | Bin 84791 -> 0 bytes .../resources/root/geometry_run_7-2076.root | 0 .../resources/root/geometry_run_8_8000.zip | Bin 0 -> 220311 bytes 5 files changed, 78 insertions(+), 42 deletions(-) create mode 100644 demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.root create mode 100644 demo/playground/src/jvmMain/resources/root/geometry_run_8_8000.zip diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt index 8b67c108..6d959f4f 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt @@ -42,7 +42,7 @@ public open class DObject(public val meta: Meta, public val refCache: DObjectCac } internal fun tObjectArray( - builder: (Meta, DObjectCache) -> T + builder: (Meta, DObjectCache) -> T, ): ReadOnlyProperty> = ReadOnlyProperty { _, property -> meta.getIndexed(Name.of(property.name, "arr")).values.mapNotNull { resolve(builder, it) @@ -51,9 +51,9 @@ public open class DObject(public val meta: Meta, public val refCache: DObjectCac internal fun dObject( builder: (Meta, DObjectCache) -> T, - key: Name? = null + key: Name? = null, ): ReadOnlyProperty = ReadOnlyProperty { _, property -> - meta[key ?: property.name.asName()]?.let { resolve(builder, it) } + meta[key ?: property.name.asName()]?.takeIf { it.value != Null }?.let { resolve(builder, it) } } } @@ -62,8 +62,7 @@ public open class DNamed(meta: Meta, refCache: DObjectCache) : DObject(meta, ref public val fTitle: String by meta.string("") } -public class DGeoMaterial(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) { -} +public class DGeoMaterial(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) public class DGeoMedium(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) { public val fMaterial: DGeoMaterial? by dObject(::DGeoMaterial) @@ -90,27 +89,69 @@ public class DGeoNode(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCach public val fVolume: DGeoVolume? by dObject(::DGeoVolume) } -public open class DGeoMatrix(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) +public sealed class DGeoMatrix(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) -public open class DGeoScale(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { +public class DGeoIdentity(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) + +public class DGeoScale(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { public val fScale: DoubleArray by meta.doubleArray(1.0, 1.0, 1.0) public val x: Double get() = fScale[0] public val y: Double get() = fScale[1] public val z: Double get() = fScale[2] } +public class DGeoRotation(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { + public val fRotationMatrix: DoubleArray by meta.doubleArray() +} + +public class DGeoTranslation(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { + public val fTranslation: DoubleArray by meta.doubleArray() +} + +public open class DGeoCombiTrans(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { + public val fRotation: DGeoRotation? by dObject(::DGeoRotation) + public val fTranslation: DoubleArray by meta.doubleArray() +} + +public class DGeoGenTrans(meta: Meta, refCache: DObjectCache) : DGeoCombiTrans(meta, refCache) { + public val fScale: DoubleArray by meta.doubleArray() +} + +public class DGeoHMatrix(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { + public val fRotation: DGeoRotation? by dObject(::DGeoRotation) + public val fTranslation: DoubleArray by meta.doubleArray() + public val fScale: DoubleArray by meta.doubleArray() +} + +/** + * Create a specialized version of [DGeoMatrix] + */ +internal fun dGeoMatrix( + meta: Meta, + refCache: DObjectCache, +): DGeoMatrix = when (val typename = meta["_typename"].string) { + null -> error("Type name is undefined") + "TGeoIdentity" -> DGeoIdentity(meta, refCache) + "TGeoScale" -> DGeoScale(meta, refCache) + "TGeoRotation" -> DGeoRotation(meta, refCache) + "TGeoTranslation" -> DGeoTranslation(meta, refCache) + "TGeoCombiTrans" -> DGeoCombiTrans(meta, refCache) + "TGeoGenTrans" -> DGeoGenTrans(meta, refCache) + "TGeoHMatrix" -> DGeoHMatrix(meta, refCache) + else -> error("$typename is not a member of TGeoMatrix") +} public class DGeoBoolNode(meta: Meta, refCache: DObjectCache) : DObject(meta, refCache) { public val fLeft: DGeoShape? by dObject(::DGeoShape) - public val fLeftMat: DGeoMatrix? by dObject(::DGeoMatrix) + public val fLeftMat: DGeoMatrix? by dObject(::dGeoMatrix) public val fRight: DGeoShape? by dObject(::DGeoShape) - public val fRightMat: DGeoMatrix? by dObject(::DGeoMatrix) + public val fRightMat: DGeoMatrix? by dObject(::dGeoMatrix) } public class DGeoManager(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) { - public val fMatrices: List by tObjectArray(::DGeoMatrix) + public val fMatrices: List by tObjectArray(::dGeoMatrix) public val fShapes: List by tObjectArray(::DGeoShape) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index ef72de52..e2e662da 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -1,6 +1,8 @@ package ru.mipt.npm.root -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.double +import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus @@ -44,39 +46,32 @@ private fun Solid.translate(trans: DoubleArray) { position = Float32Vector3D(x, y, z) } -private fun Solid.useMatrix(matrix: DGeoMatrix?) { - if (matrix == null) return - when (matrix.typename) { - "TGeoIdentity" -> { - //do nothing - } - - "TGeoTranslation" -> { - val fTranslation by matrix.meta.doubleArray() - translate(fTranslation) - } +private fun Solid.scale(s: DoubleArray) { + scale = Float32Vector3D(s[0], s[1], s[2]) +} - "TGeoRotation" -> { - val fRotationMatrix by matrix.meta.doubleArray() - rotate(fRotationMatrix) +private fun Solid.useMatrix(matrix: DGeoMatrix?): Unit { + when (matrix) { + null -> {} + is DGeoIdentity -> {} + is DGeoTranslation -> translate(matrix.fTranslation) + is DGeoRotation -> rotate(matrix.fRotationMatrix) + is DGeoScale -> scale(matrix.fScale) + is DGeoGenTrans -> { + translate(matrix.fTranslation) + matrix.fRotation?.fRotationMatrix?.let { rotate(it) } + scale(matrix.fScale) } - "TGeoCombiTrans" -> { - val fTranslation by matrix.meta.doubleArray() - - translate(fTranslation) - matrix.meta["fRotation.fRotationMatrix"]?.value?.let { - rotate(it.doubleArray) - } + is DGeoCombiTrans -> { + translate(matrix.fTranslation) + matrix.fRotation?.fRotationMatrix?.let { rotate(it) } } - "TGeoHMatrix" -> { - val fTranslation by matrix.meta.doubleArray() - val fRotationMatrix by matrix.meta.doubleArray() - val fScale by matrix.meta.doubleArray() - translate(fTranslation) - rotate(fRotationMatrix) - scale = Float32Vector3D(fScale[0], fScale[1], fScale[2]) + is DGeoHMatrix -> { + translate(matrix.fTranslation) + matrix.fRotation?.fRotationMatrix?.let { rotate(it) } + scale(matrix.fScale) } } } @@ -99,10 +94,10 @@ private fun SolidGroup.addShape( } smartComposite(compositeType, name = name) { addShape(node.fLeft!!, context, null) { - this.useMatrix(node.fLeftMat) + useMatrix(node.fLeftMat) } addShape(node.fRight!!, context, null) { - this.useMatrix(node.fRightMat) + useMatrix(node.fRightMat) } }.apply(block) } @@ -286,7 +281,7 @@ private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) { addRootVolume(volume, context, obj.fName) { when (obj.typename) { "TGeoNodeMatrix" -> { - val fMatrix by obj.dObject(::DGeoMatrix) + val fMatrix by obj.dObject(::dGeoMatrix) this.useMatrix(fMatrix) } diff --git a/demo/playground/src/jvmMain/resources/root/BM@N_geometry.zip b/demo/playground/src/jvmMain/resources/root/BM@N_geometry.zip index 47701be0b5a9ea2751ef0e50cad6d2b13eb2445e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 84791 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�$b)h#m@G}kY48=2~o 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

TX}=St^JoS5_t$=RWLVJ~+~ zR?*m7k&%xg=JCLs5B17lGqH=Ywo_;1R8YMO0L54X1R8##%quaP-lB59GJ3o*d zMd5z9ria{P5hl{~g}6Kav=?=B9n&N}eER&t_iuR&4g#u&&<(l3ed^C_{+ECL zFa`i5@Vci}Ek0jbbY&Pt7TmUc{0mz@_1}tM9@V&4R~IQWE-Uk^kN#Lz&X7CZyZ`>^MpS6_W-%?6Y6Ac zmyle_q$Z<#2S(_yxmdD3t2HGeiba(o6CUKtAgMl#02QDi3HpQDgK4-Q$c=nyqisy8 zva=p_S~Go2jj@H_fzalvv4276Gf!8b`Dcv3hT9pXTu7B^oY;*-3sipemD&6R^B{Bn zV9?K5ymbmM7Hb!fY_{ErFCHLBGp6b9;Ad3;eul4yT4RhkGZ4o5!94Cj=Gtg5*161W z{5qZa`Is{}{qFsSl4=jy4kW!z4=Y!=TKFQXz5)HumUqVn-8wku;lO(ichED@VTkGl zh8T(T31AJtp#Q?pm#emVvbg6T?u=&Nv3s=S%{rllr(;OA^!t*~CK&v6C@V^c)o_K` zV6)fmJD~?8B|7B^>2;B3AJ9F)Uk1Zb@VgN5> z{ACAC5xfjkk{ps%P4aGarGyQMqn(>#Cz^i zMln}~Y0-1oeyag~F0JWl<@Z@v30bcKC-)w+ZvVt>5H`(FnJk!$W(RN2;a+*@8TSPn zb?-G6tDZOP`xzY}a2t5yw3Ypq$&6X-Dw@>PCspGiJ>FVPzit{D8|okAvbp&cm0q2% zBAWMp^eqhKNuclIdbw2LIpEcwHBTQ6+}>O)tcHPp=QLlvz3jc7bK?a57>KY=r28Iq zd!;Hc?a*|KoI;Gz&7~R6+PnMRu5Mp!A3AxTUymKH7)D$QYYbOy6#<)_Oo#3C8@2mg zb=~gYqN*vPqLHAGprD{&p{Qn2>qys?%VHRyqk!9$QOJSPyALV~{huQWinXP~YfBd= mPh%(7H^zd-f={15<+5{jc%!C>f%#Vw6-5q62m=;SQ2rnKYp;v| literal 0 HcmV?d00001 From 4b91e5d62b1e1a7ec015012d4569dec6f0eab830 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 30 Sep 2023 20:01:29 +0300 Subject: [PATCH 087/112] BM@N and fixes --- .../commonMain/kotlin/ru/mipt/npm/root/BMN.kt | 50 + .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 7 +- .../src/jvmMain/kotlin/rootParser.kt | 3 + .../src/jvmMain/resources/root/event_0.json | 7912 +++++++++++++++++ .../src/jvmMain/resources/root/event_1.json | 215 + .../src/jvmMain/resources/root/event_2.json | 5150 +++++++++++ .../src/jvmMain/resources/root/event_3.json | 1370 +++ .../kscience/visionforge/solid/Extruded.kt | 51 +- .../solid/Float32Euclidean2DSpace.kt | 1 - .../visionforge/solid/LayersSurface.kt | 136 + 10 files changed, 14868 insertions(+), 27 deletions(-) create mode 100644 cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt create mode 100644 demo/playground/src/jvmMain/resources/root/event_0.json create mode 100644 demo/playground/src/jvmMain/resources/root/event_1.json create mode 100644 demo/playground/src/jvmMain/resources/root/event_2.json create mode 100644 demo/playground/src/jvmMain/resources/root/event_3.json create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LayersSurface.kt diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt new file mode 100644 index 00000000..78053d1d --- /dev/null +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt @@ -0,0 +1,50 @@ +package ru.mipt.npm.root + +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonArray + + +@Serializable +public data class FairTrackParam( + val fX: Double, + val fY: Double, + val fZ: Double, + val fTx: Double, + val fTy: Double, + val fQp: Double, +) + +@Serializable +public data class CbmStsTrack( + val fParamFirst: FairTrackParam, + val fParamLast: FairTrackParam, +) + +@Serializable +public data class BmnGlobalTrack( + val fParamFirst: FairTrackParam, + val fParamLast: FairTrackParam, +) + +public class BmnEventContainer( + public val cbmTracks: List, + public val bmnGlobalTracks: List, +) + +public object BMN { + public val json: Json = Json { + ignoreUnknownKeys = true + classDiscriminator = "_typename" + } + + public fun readEventJson(string: String): BmnEventContainer { + val jsonArray = json.parseToJsonElement(string) as JsonArray + val cbmTracks: List = + json.decodeFromJsonElement(ListSerializer(CbmStsTrack.serializer()), jsonArray[0]) + val bmnGlobalTracks: List = + json.decodeFromJsonElement(ListSerializer(BmnGlobalTrack.serializer()), jsonArray[1]) + return BmnEventContainer(cbmTracks, bmnGlobalTracks) + } +} \ No newline at end of file diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index e2e662da..c81ca577 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -113,8 +113,8 @@ private fun SolidGroup.addShape( val fScale by shape.meta.doubleArray() extruded(name = name) { - (0 until fNvert).forEach { index -> - shape { + shape { + (0 until fNvert).forEach { index -> point(fX[index], fY[index]) } } @@ -181,10 +181,9 @@ private fun SolidGroup.addShape( name = name, ) { z = (fZ[1] + fZ[0]) / 2 - }.apply(block) } else { - TODO() + TODO("Polycone is not implemented") } } diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/rootParser.kt index 1faa8d0b..04aa71f7 100644 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ b/demo/playground/src/jvmMain/kotlin/rootParser.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.examples +import ru.mipt.npm.root.BMN import ru.mipt.npm.root.DGeoManager import ru.mipt.npm.root.rootGeo import ru.mipt.npm.root.serialization.TGeoManager @@ -39,6 +40,8 @@ fun main() { println(it) } + val events = BMN.readEventJson(TGeoManager::class.java.getResourceAsStream("/root/event_0.json")!!.bufferedReader().readText()) + makeVisionFile(path = Path("data/output.html"), resourceLocation = ResourceLocation.EMBED) { vision("canvas") { requirePlugin(Solids) diff --git a/demo/playground/src/jvmMain/resources/root/event_0.json b/demo/playground/src/jvmMain/resources/root/event_0.json new file mode 100644 index 00000000..6ed9451b --- /dev/null +++ b/demo/playground/src/jvmMain/resources/root/event_0.json @@ -0,0 +1,7912 @@ +[ + [ + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509938528, + "fStsHits": [ + 974, + 1006, + 24, + 90, + 180, + 313, + 362, + 632, + 779 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.5345516204834, + "fY": 1.250044465065, + "fZ": 36.8064994812012, + "fTx": -0.0872875526547432, + "fTy": 0.0181172806769609, + "fQp": 0.171960204839706, + "fCovMatrix": [ + 1.27937266370282e-4, + -4.85821627080441e-4, + -3.7555223570962e-6, + 3.6864985304419e-6, + 1.01499799711746e-5, + 0.0232641790062189, + 1.69457871379564e-5, + -1.66413359693252e-4, + -6.65305415168405e-5, + 4.00254350552132e-7, + -1.53248109313608e-7, + -9.94260062725516e-7, + 1.80128506599431e-6, + 7.03108355537552e-7, + 7.72671501181321e-6 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -12.6429347991943, + "fY": 5.05208110809326, + "fZ": 253.266006469727, + "fTx": 7.01297190971673e-4, + "fTy": 0.0169959291815758, + "fQp": 0.172035798430443, + "fCovMatrix": [ + 0.00105739186983556, + 0.00144061620812863, + 1.79473590833368e-5, + 1.12270981844631e-5, + 4.8466074076714e-5, + 0.0194979812949896, + 2.82164965028642e-5, + 1.43817713251337e-4, + 8.1607504398562e-5, + 5.34483035607991e-7, + 2.24166527118541e-7, + 1.38559039442043e-6, + 1.63161871569173e-6, + 6.84420911056804e-7, + 7.74139425629983e-6 + ] + }, + "fFlag": 0, + "fChi2": 12.2162303924561, + "fNDF": 13, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509938528, + "fStsHits": [ + 961, + 991, + 6, + 75, + 178, + 247, + 350, + 430, + 741 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.51734781265259, + "fY": 3.06508040428162, + "fZ": 36.8764991760254, + "fTx": 0.217250749468803, + "fTy": 0.0643623322248459, + "fQp": 0.205487444996834, + "fCovMatrix": [ + 1.31504551973194e-4, + 5.73850178625435e-4, + -3.47611194229103e-6, + -3.85523071599891e-6, + 8.39247604744742e-6, + 0.0246394574642181, + -2.53617758971814e-6, + -1.77185094798915e-4, + -1.41971704579191e-5, + 3.95388326523971e-7, + -8.45878389554855e-9, + -1.00948807357781e-6, + 1.90104719877127e-6, + 3.02061550883082e-7, + 8.24428207124583e-6 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 67.0765991210938, + "fY": 17.0353946685791, + "fZ": 253.266006469727, + "fTx": 0.331152737140656, + "fTy": 0.0661555081605911, + "fQp": 0.206363037228584, + "fCovMatrix": [ + 0.00106893514748663, + 0.00143959815613925, + 1.87995410669828e-5, + 1.16089695438859e-5, + 4.3531610572245e-5, + 0.0197235085070133, + 2.83265908365138e-5, + 1.49970132042654e-4, + 5.78232829866465e-5, + 6.29673479579651e-7, + 2.26611533094001e-7, + 1.31542185499711e-6, + 1.82977680651675e-6, + 4.36535003700556e-7, + 8.22780566522852e-6 + ] + }, + "fFlag": 0, + "fChi2": 41.6662788391113, + "fNDF": 13, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509940368, + "fStsHits": [ + 1016, + 38, + 120, + 220, + 317, + 371, + 633, + 863 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 6.3819899559021, + "fY": -4.55210590362549, + "fZ": 42.3520011901855, + "fTx": 0.186407506465912, + "fTy": -0.114231139421463, + "fQp": 0.564049184322357, + "fCovMatrix": [ + 2.09370467928238e-4, + -7.88959383498877e-4, + -4.99387397212558e-6, + 7.36422498448519e-6, + 9.89626551017864e-6, + 0.0280679222196341, + 1.20942240755539e-6, + -2.68892734311521e-4, + -5.33221191290068e-6, + 1.47621835822065e-6, + -3.43512951417324e-8, + -2.07013545150403e-6, + 5.11011558046448e-6, + 1.62103575007677e-7, + 3.53423638443928e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 78.3410491943359, + "fY": -30.1586742401123, + "fZ": 248.565994262695, + "fTx": 0.519947171211243, + "fTy": -0.138447120785713, + "fQp": 0.568591356277466, + "fCovMatrix": [ + 0.00111755426041782, + -0.00150139129254967, + 3.1857311114436e-5, + -1.81215455086203e-5, + 5.22565605933778e-5, + 0.0204639304429293, + -6.45808249828406e-5, + 2.0539241086226e-4, + -8.36852050269954e-5, + 2.64465393229329e-6, + -8.06947014098114e-7, + 2.75229331236915e-6, + 4.93603874929249e-6, + -1.25252370253293e-6, + 3.4731492633e-5 + ] + }, + "fFlag": 0, + "fChi2": 48.1372489929199, + "fNDF": 11, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509936688, + "fStsHits": [ + 893, + 938, + 971, + 1001, + 17, + 86, + 163, + 254, + 339, + 429 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.88969993591309, + "fY": 1.39906001091003, + "fZ": 19.2385005950928, + "fTx": -0.166057333350182, + "fTy": 0.081357829272747, + "fQp": 1.93327069282532, + "fCovMatrix": [ + 1.96733133634552e-4, + -0.0016653569182381, + -1.310913648922e-5, + 2.73616478807526e-5, + 2.41490324697224e-5, + 0.0733450576663017, + 3.03498036373639e-5, + -0.0012214258313179, + 1.01110737887211e-4, + 3.97112444261438e-6, + -8.57961822475772e-7, + -7.769801413815e-6, + 3.36613557010423e-5, + 7.30538772586442e-7, + 3.78385477233678e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 67.4413909912109, + "fY": 18.4549140930176, + "fZ": 217.451995849609, + "fTx": 1.14467430114746, + "fTy": 0.122764363884926, + "fQp": 1.95217978954315, + "fCovMatrix": [ + 0.00171380024403334, + -0.00418118108063936, + 1.0429337999085e-4, + -7.7113312727306e-5, + 1.41469237860292e-4, + 0.0365858227014542, + -3.63614817615598e-4, + 6.59077544696629e-4, + -4.98083070851862e-4, + 2.47048610617639e-5, + -2.76183914138528e-6, + 2.36326213780558e-5, + 3.55777374352328e-5, + -4.08496134696179e-6, + 3.6235831794329e-4 + ] + }, + "fFlag": 0, + "fChi2": 26.7674999237061, + "fNDF": 15, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509936688, + "fStsHits": [ + 899, + 940, + 973, + 1004, + 20, + 188, + 287, + 337, + 434, + 715 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -2.68070912361145, + "fY": 2.10225534439087, + "fZ": 19.2385005950928, + "fTx": -0.121914230287075, + "fTy": 0.0926407650113106, + "fQp": 0.867175340652466, + "fCovMatrix": [ + 1.68846847373061e-4, + -0.00122805847786367, + -8.67153812578181e-6, + 1.14171198219992e-5, + 1.75226996361744e-5, + 0.0474106967449188, + 3.05320900224615e-5, + -4.7915696632117e-4, + -7.76774395490065e-5, + 1.27255077586597e-6, + -3.17726517096162e-7, + -2.61566196968488e-6, + 9.19102785701398e-6, + 7.4841182140517e-7, + 7.94506777310744e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 26.3584899902344, + "fY": 23.1596603393555, + "fZ": 253.266006469727, + "fTx": 0.386137813329697, + "fTy": 0.0894111171364784, + "fQp": 0.872905194759369, + "fCovMatrix": [ + 0.00141222530510277, + 0.00261890306137502, + 4.1884839447448e-5, + 3.52654060407076e-5, + 6.37184057268314e-5, + 0.026132557541132, + 1.03059472166933e-4, + 3.20465071126819e-4, + 1.36897549964488e-4, + 3.59388832293916e-6, + 1.2825257726945e-6, + 4.27736631536391e-6, + 8.88297381607117e-6, + 1.62169681061641e-6, + 7.93475410318933e-5 + ] + }, + "fFlag": 0, + "fChi2": 36.3777732849121, + "fNDF": 15, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509938528, + "fStsHits": [ + 957, + 986, + 52, + 159, + 230, + 327, + 409, + 694, + 872 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.74364900588989, + "fY": -2.54444789886475, + "fZ": 25.0970001220703, + "fTx": -0.142562881112099, + "fTy": -0.107907794415951, + "fQp": 0.321766316890717, + "fCovMatrix": [ + 1.39540192321874e-4, + 6.25495449639857e-4, + -5.4858128351043e-6, + -4.96140728500905e-6, + 8.31528905109735e-6, + 0.028283754363656, + -2.80246349575464e-5, + -2.21876412979327e-4, + 6.13260344834998e-5, + 7.6472900900626e-7, + 2.21928303290042e-7, + -8.54944346428965e-7, + 3.13729537992913e-6, + -5.67445340493578e-7, + 1.44416608236497e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -15.6737995147705, + "fY": -26.5016078948975, + "fZ": 248.565994262695, + "fTx": 0.0339683443307877, + "fTy": -0.106621921062469, + "fQp": 0.322487384080887, + "fCovMatrix": [ + 9.68566455412656e-4, + -0.00108841923065484, + 1.94350541278254e-5, + -9.72522593656322e-6, + 4.41747761215083e-5, + 0.0180964469909668, + -2.95923709927592e-5, + 1.45901823998429e-4, + -6.44115061732009e-5, + 9.45050828704552e-7, + -2.62571404618939e-7, + 1.67258588135155e-6, + 2.29809893426136e-6, + -6.07894776294415e-7, + 1.44884925248334e-5 + ] + }, + "fFlag": 0, + "fChi2": 18.3176460266113, + "fNDF": 13, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509940368, + "fStsHits": [ + 895, + 939, + 972, + 1003, + 27, + 84, + 174, + 250 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.42452311515808, + "fY": 1.31336784362793, + "fZ": 19.2385005950928, + "fTx": -0.139086008071899, + "fTy": 0.0885453298687935, + "fQp": 2.47033476829529, + "fCovMatrix": [ + 2.12573911994696e-4, + -0.00202700681984425, + -1.55479410750559e-5, + 3.68334476661403e-5, + 4.15232061641291e-5, + 0.0915368050336838, + 3.206187102478e-5, + -0.00166892097331583, + 5.4530892521143e-4, + 6.06955200055381e-6, + -1.22259484669485e-6, + -1.8674476450542e-5, + 5.09153614984825e-5, + -4.35777155871619e-6, + 0.00107842439319938 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 35.9676246643066, + "fY": 14.2686767578125, + "fZ": 154.856994628906, + "fTx": 0.896000862121582, + "fTy": 0.118299603462219, + "fQp": 2.51388120651245, + "fCovMatrix": [ + 0.001817143172957, + -0.00485007045790553, + 1.14804308395833e-4, + -9.64944920269772e-5, + 2.9752537375316e-4, + 0.0413326025009155, + -4.27107122959569e-4, + 7.91111495345831e-4, + -0.00113374111242592, + 2.6783502107719e-5, + -3.85322800866561e-6, + 5.09271048940718e-5, + 4.6236724301707e-5, + -1.47345344885252e-5, + 0.00102324690669775 + ] + }, + "fFlag": 0, + "fChi2": 40.4142456054688, + "fNDF": 11, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509942208, + "fStsHits": [ + 1033, + 48, + 160, + 331, + 407, + 697, + 870 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -13.5733032226562, + "fY": -2.11779046058655, + "fZ": 41.3269996643066, + "fTx": -0.303289979696274, + "fTy": -0.0571999363601208, + "fQp": 0.409863412380219, + "fCovMatrix": [ + 1.92375795450062e-4, + 3.54970485204831e-4, + -6.03487251282786e-6, + -3.4954239254148e-6, + 1.08150279629626e-5, + 0.0272667352110147, + -3.07323098240886e-5, + -2.24761650315486e-4, + 1.51475287566427e-5, + 2.28913427235966e-6, + 3.55021910536379e-7, + -1.29986210595234e-6, + 5.10126847075298e-6, + -6.66355504108651e-7, + 2.43799313466297e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -53.5613479614258, + "fY": -13.3742799758911, + "fZ": 248.565994262695, + "fTx": -0.0919805094599724, + "fTy": -0.051100492477417, + "fQp": 0.409756720066071, + "fCovMatrix": [ + 0.00102374202106148, + -0.00121821509674191, + 2.25714866246562e-5, + -9.65455365076195e-6, + 5.50462027604226e-5, + 0.0189228896051645, + -3.68259061360732e-5, + 1.56089285155758e-4, + -8.76016565598547e-5, + 1.22756193832174e-6, + -2.51058338562871e-7, + 2.36619644056191e-6, + 2.87100806417584e-6, + -4.09444822935257e-7, + 2.46403506025672e-5 + ] + }, + "fFlag": 0, + "fChi2": 22.5092430114746, + "fNDF": 9, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509942208, + "fStsHits": [ + 1023, + 71, + 242, + 332, + 411, + 691, + 874 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.793833792209625, + "fY": -5.07560539245605, + "fZ": 41.2070007324219, + "fTx": -0.00528146233409643, + "fTy": -0.0801199078559875, + "fQp": 0.212064072489738, + "fCovMatrix": [ + 2.20483358134516e-4, + -0.00113531132228673, + -2.9238908609841e-6, + 7.47520653021638e-6, + 6.19972524873447e-6, + 0.0372364558279514, + -2.69870015472407e-5, + -2.56144820014015e-4, + 9.13071853574365e-5, + 9.30207363580848e-7, + 1.75039787109199e-7, + -1.16978264941281e-6, + 2.98273744192556e-6, + -6.90119065893668e-7, + 1.02850199255045e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 9.50048065185547, + "fY": -21.8310127258301, + "fZ": 248.565994262695, + "fTx": 0.10227494686842, + "fTy": -0.0813720002770424, + "fQp": 0.212042018771172, + "fCovMatrix": [ + 9.97935771010816e-4, + -0.00117292185314, + 1.91287272173213e-5, + -1.25147380458657e-5, + 5.18714150530286e-5, + 0.0186820216476917, + -2.78511197393527e-5, + 1.57315167598426e-4, + -6.73831964377314e-5, + 7.11255154328683e-7, + -3.22366929594864e-7, + 1.75655213752179e-6, + 2.28617523134744e-6, + -8.3049457089146e-7, + 1.02555823104922e-5 + ] + }, + "fFlag": 0, + "fChi2": 24.935546875, + "fNDF": 9, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509942208, + "fStsHits": [ + 71, + 156, + 231, + 329, + 408, + 696, + 869 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.829330503940582, + "fY": -6.16100406646729, + "fZ": 60.8950004577637, + "fTx": -0.0424437262117863, + "fTy": -0.0929087698459625, + "fQp": -1.00865876674652, + "fCovMatrix": [ + 0.00144624512176961, + -0.00277250865474343, + -4.15815084124915e-5, + 3.73268521798309e-5, + 8.46372786327265e-5, + 0.0276215653866529, + 1.01451587397605e-4, + -3.41085076797754e-4, + -1.64008262800053e-4, + 3.33984257849806e-6, + -1.22679557534866e-6, + -7.20000844012247e-6, + 8.97274912858848e-6, + 2.28002954827389e-6, + 1.18834454042371e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -58.270393371582, + "fY": -24.5115928649902, + "fZ": 248.565994262695, + "fTx": -0.582086145877838, + "fTy": -0.102219641208649, + "fQp": -1.00568675994873, + "fCovMatrix": [ + 0.00128551793750376, + -0.00207453384064138, + 4.9034886615118e-5, + -2.93046323349699e-5, + 8.9734407083597e-5, + 0.0242247544229031, + -1.19483127491549e-4, + 3.08274960843846e-4, + -2.00828450033441e-4, + 5.85356519877678e-6, + -1.18506238777627e-6, + 6.76520085107768e-6, + 1.06499564935802e-5, + -3.04863306155312e-6, + 1.18108830065466e-4 + ] + }, + "fFlag": 0, + "fChi2": 32.4650840759277, + "fNDF": 9, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509944048, + "fStsHits": [ + 906, + 945, + 977, + 42, + 107, + 211 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 5.86967897415161, + "fY": -1.55108439922333, + "fZ": 16.2285003662109, + "fTx": 0.393072992563248, + "fTy": -0.102556817233562, + "fQp": 0.870569229125977, + "fCovMatrix": [ + 1.81187831913121e-4, + -0.00166891247499734, + -9.88784813671373e-6, + 2.22598482650938e-5, + 2.58275067608338e-5, + 0.0929074883460999, + -3.55086922354531e-5, + -0.00123381358571351, + 5.46134833712131e-4, + 1.74404340214096e-6, + 3.28533360516303e-7, + -7.56158124204376e-6, + 2.22407834371552e-5, + -9.71335612121038e-6, + 2.2154524049256e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 64.4297180175781, + "fY": -13.9177446365356, + "fZ": 123.677001953125, + "fTx": 0.72672039270401, + "fTy": -0.134330794215202, + "fQp": 0.878399670124054, + "fCovMatrix": [ + 0.00160757114645094, + -0.00398816168308258, + 7.29574530851096e-5, + -8.36182516650297e-5, + 2.40785084315576e-4, + 0.0378738828003407, + -2.46375158894807e-4, + 6.83184887748212e-4, + -7.99094792455435e-4, + 7.44503131500096e-6, + -5.03312639921205e-6, + 2.31208141485695e-5, + 2.11625283554895e-5, + -1.67757134477142e-5, + 2.12662940612063e-4 + ] + }, + "fFlag": 0, + "fChi2": 4.79613256454468, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509944048, + "fStsHits": [ + 80, + 169, + 252, + 353, + 449, + 777 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 9.38197612762451, + "fY": 1.63796663284302, + "fZ": 92.3769989013672, + "fTx": 0.13623172044754, + "fTy": 0.0324348509311676, + "fQp": 0.174530282616615, + "fCovMatrix": [ + 0.00136274169199169, + -0.00250188261270523, + -3.33625248458702e-5, + 2.60251836152747e-5, + 1.30423548398539e-4, + 0.0255636107176542, + 7.64829601394013e-5, + -2.38627530052327e-4, + -3.43920895829797e-4, + 1.30118041852256e-6, + -8.77133004451025e-7, + -5.70030306334957e-6, + 3.12928341372753e-6, + 4.27608256359235e-6, + 3.17654630634934e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 36.9998054504395, + "fY": 6.80868768692017, + "fZ": 253.266006469727, + "fTx": 0.204165861010551, + "fTy": 0.0321086347103119, + "fQp": 0.174466639757156, + "fCovMatrix": [ + 0.00132604071404785, + 0.00240976945497096, + 3.02924581774278e-5, + 2.5230410756194e-5, + 1.25503007438965e-4, + 0.025324797257781, + 6.86817729729228e-5, + 2.36949999816716e-4, + 3.32722527673468e-4, + 1.11861686491466e-6, + 7.92246112268913e-7, + 5.05562411490246e-6, + 3.14955241265125e-6, + 4.21537333750166e-6, + 3.16932710120454e-5 + ] + }, + "fFlag": 0, + "fChi2": 8.98170948028564, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509944048, + "fStsHits": [ + 154, + 238, + 333, + 420, + 700, + 883 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.4566935300827, + "fY": -5.42157125473022, + "fZ": 97.0770034790039, + "fTx": 0.0110252797603607, + "fTy": -0.0553293600678444, + "fQp": 0.26590359210968, + "fCovMatrix": [ + 0.00118249095976353, + 0.00176220992580056, + -3.13560085487552e-5, + -1.92533934750827e-5, + 1.27977749798447e-4, + 0.0225056633353233, + -6.29064234090038e-5, + -2.16538173845038e-4, + 2.94552708510309e-4, + 1.49477023114741e-6, + 7.45524857848068e-7, + -6.63162018099683e-6, + 3.22147957376728e-6, + -3.78141567125567e-6, + 4.35887268395163e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.82009363174438, + "fY": -13.8860502243042, + "fZ": 248.565994262695, + "fTx": 0.107870183885098, + "fTy": -0.0562192648649216, + "fQp": 0.266337841749191, + "fCovMatrix": [ + 0.00115839694626629, + -0.00171898689586669, + 2.91786582238274e-5, + -1.94178428500891e-5, + 1.24229423818178e-4, + 0.0224172528833151, + -5.91218558838591e-5, + 2.1739570365753e-4, + -2.88082315819338e-4, + 1.38089103529637e-6, + -7.26864755051793e-7, + 5.93746290178387e-6, + 3.33536263497081e-6, + -3.93559366784757e-6, + 4.36123991676141e-5 + ] + }, + "fFlag": 0, + "fChi2": 13.1549520492554, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509944048, + "fStsHits": [ + 987, + 1030, + 49, + 137, + 222, + 330 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -4.15340709686279, + "fY": -6.02573776245117, + "fZ": 33.6940002441406, + "fTx": -0.147238731384277, + "fTy": -0.201069056987762, + "fQp": -0.562814176082611, + "fCovMatrix": [ + 1.60062161739916e-4, + 9.04108746908605e-4, + -8.78184346220223e-6, + -1.01532896223944e-5, + 3.31195587932598e-5, + 0.0440464429557323, + -3.74387273041066e-5, + -5.32485079020262e-4, + 2.48558444582159e-5, + 1.46108300214109e-6, + 2.84713451037533e-7, + -6.11977429798571e-6, + 9.40160316531546e-6, + 1.8087304169967e-6, + 9.25581334740855e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -34.5075836181641, + "fY": -31.8353710174561, + "fZ": 159.557006835938, + "fTx": -0.346722215414047, + "fTy": -0.21097306907177, + "fQp": -0.572068274021149, + "fCovMatrix": [ + 0.00153660564683378, + 0.00338289677165449, + 4.58140784758143e-5, + 4.59371112810913e-5, + 1.61742660566233e-4, + 0.0334698744118214, + 1.14889880933333e-4, + 4.34220593888313e-4, + 3.44392232364044e-4, + 2.73831551567127e-6, + 1.49882725963835e-6, + 1.05627932498464e-5, + 8.82463154994184e-6, + 3.68091014024685e-6, + 9.21655009733513e-5 + ] + }, + "fFlag": 0, + "fChi2": 50.0074996948242, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 841823542, + "fStsHits": [ + 918, + 950, + 982, + 1027, + 112, + 202 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.11198008060455, + "fY": -3.55741095542908, + "fZ": 15.018500328064, + "fTx": -0.0508718937635422, + "fTy": -0.263699769973755, + "fQp": 2.05216598510742, + "fCovMatrix": [ + 2.28203454753384e-4, + -0.00292489072307944, + -1.44636278491816e-5, + 3.46158849424683e-5, + 7.70416154409759e-5, + 0.13354517519474, + 3.51274684362579e-5, + -0.00166058784816414, + -6.19782193098217e-4, + 4.62498428532854e-6, + -5.25030770859303e-7, + -1.74180840986082e-5, + 3.94191229133867e-5, + 1.19795095088193e-6, + 9.7273662686348e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 24.8955745697021, + "fY": -33.7819709777832, + "fZ": 123.677001953125, + "fTx": 0.604310631752014, + "fTy": -0.315734297037125, + "fQp": 2.09776401519775, + "fCovMatrix": [ + 0.00176150107290596, + -0.00480693858116865, + 1.03912498161662e-4, + -1.12679801532067e-4, + 2.87616538116708e-4, + 0.042500589042902, + -4.01500758016482e-4, + 8.34156293421984e-4, + -9.35784832108766e-4, + 1.83507636393188e-5, + -7.35896674086689e-6, + 5.00350506627001e-5, + 4.53848879260477e-5, + -1.4240275049815e-5, + 9.32074501179159e-4 + ] + }, + "fFlag": 0, + "fChi2": 66.7220230102539, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 2045861141, + "fStsHits": [ + 212, + 323, + 384, + 682, + 867 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 9.17882251739502, + "fY": -4.51064395904541, + "fZ": 123.647003173828, + "fTx": 0.0928313285112381, + "fTy": -0.0324885919690132, + "fQp": 0.203487545251846, + "fCovMatrix": [ + 0.00148212176281959, + -0.00283645675517619, + -4.24430181737989e-5, + 2.94141318590846e-5, + 1.98712878045626e-4, + 0.0291197914630175, + 8.29956625238992e-5, + -3.13738972181454e-4, + -3.60756297595799e-4, + 2.1217551875452e-6, + -6.54201699035184e-7, + -1.1963853467023e-5, + 4.89495641886606e-6, + 1.76691435171961e-6, + 8.14418744994327e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 24.739673614502, + "fY": -8.64188003540039, + "fZ": 248.565994262695, + "fTx": 0.153393998742104, + "fTy": -0.0334637500345707, + "fQp": 0.203488066792488, + "fCovMatrix": [ + 0.00120611628517509, + -0.00176589959301054, + 3.30342554661911e-5, + -1.81667473952984e-5, + 1.64499200764112e-4, + 0.0246628411114216, + -4.92055478389375e-5, + 2.77021696092561e-4, + -1.80929011548869e-4, + 1.72334603121271e-6, + -2.53595430876885e-7, + 1.0244283657812e-5, + 4.93520428790362e-6, + 1.19064839054772e-6, + 8.14808299764991e-5 + ] + }, + "fFlag": 0, + "fChi2": 2.79397416114807, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 780009769, + "fStsHits": [ + 950, + 983, + 46, + 133, + 228 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.33684980869293, + "fY": -5.68583679199219, + "fZ": 23.8120002746582, + "fTx": -0.046341560781002, + "fTy": -0.264156848192215, + "fQp": 0.47034752368927, + "fCovMatrix": [ + 1.77758207428269e-4, + -0.00167154613882303, + -7.95815140008926e-6, + 2.09124373213854e-5, + 4.17731207562611e-5, + 0.097347117960453, + -1.18779353215359e-4, + -0.00133563904091716, + 0.0013626089785248, + 2.10728740057675e-6, + 1.98282441488118e-6, + -1.53840901475633e-5, + 2.21159116335912e-5, + -2.405090162938e-5, + 2.14614119613543e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.12681382894516, + "fY": -32.1258316040039, + "fZ": 123.677001953125, + "fTx": 0.0742319375276566, + "fTy": -0.26606622338295, + "fQp": 0.47090420126915, + "fCovMatrix": [ + 0.00158424722030759, + -0.00395862851291895, + 6.28770649200305e-5, + -8.84528126334772e-5, + 3.37789009790868e-4, + 0.0385282747447491, + -2.04121737624519e-4, + 7.34325964003801e-4, + -0.00110242667142302, + 4.39162113252678e-6, + -4.81559709442081e-6, + 2.59254975389922e-5, + 2.14575829886599e-5, + -2.56246821663808e-5, + 2.14337997022085e-4 + ] + }, + "fFlag": 0, + "fChi2": 3.55766558647156, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 1783775740, + "fStsHits": [ + 94, + 185, + 309, + 460, + 771 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -8.756911277771, + "fY": 6.0902042388916, + "fZ": 92.3769989013672, + "fTx": 0.0795530304312706, + "fTy": 0.0387041419744492, + "fQp": 0.383857846260071, + "fCovMatrix": [ + 0.00146504561416805, + -0.00267798593267798, + -4.07527695642784e-5, + 3.33584466716275e-5, + 1.62895128596574e-4, + 0.0262860096991062, + 8.85876797838137e-5, + -2.59445048868656e-4, + -3.90272907679901e-4, + 1.9929259451601e-6, + -1.31975889416935e-6, + -8.48969739308814e-6, + 4.3192999328312e-6, + 6.5653002820909e-6, + 6.07283327553887e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 16.5165977478027, + "fY": 12.2913675308228, + "fZ": 253.266006469727, + "fTx": 0.229917138814926, + "fTy": 0.0385008491575718, + "fQp": 0.383702665567398, + "fCovMatrix": [ + 0.00140638451557606, + 0.0031376676633954, + 3.78932563762646e-5, + 3.06943329633214e-5, + 1.49175975820981e-4, + 0.0336156375706196, + 1.34585134219378e-4, + 2.975782554131e-4, + 6.11140800174326e-4, + 2.04978573492554e-6, + 1.21983202916454e-6, + 7.85819793236442e-6, + 4.30095087722293e-6, + 5.96624204263208e-6, + 6.05825152888428e-5 + ] + }, + "fFlag": 0, + "fChi2": 4.29511213302612, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1753091105, + "fStsHits": [ + 952, + 984, + 44, + 136, + 226 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.62948191165924, + "fY": -5.86752128601074, + "fZ": 23.8120002746582, + "fTx": -0.0600441806018353, + "fTy": -0.26595738530159, + "fQp": 0.319428592920303, + "fCovMatrix": [ + 1.76074434421025e-4, + -0.00165681610815227, + -7.5707353062171e-6, + 2.02684732357739e-5, + 4.31656080763787e-5, + 0.0970297381281853, + -1.21578275866341e-4, + -0.00131977954879403, + 0.00141425943002105, + 1.95939787772659e-6, + 2.08528990697232e-6, + -1.57428039528895e-5, + 2.11153437703615e-5, + -2.46925937972264e-5, + 1.80507020559162e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.65879273414612, + "fY": -32.4332733154297, + "fZ": 123.677001953125, + "fTx": 0.021767932921648, + "fTy": -0.266411513090134, + "fQp": 0.319602519273758, + "fCovMatrix": [ + 0.00156673660967499, + -0.00387575500644743, + 6.05840032221749e-5, + -8.63880923134275e-5, + 3.30092705553398e-4, + 0.0381363146007061, + -1.93470521480776e-4, + 7.24260287825018e-4, + -0.0010770196095109, + 3.9610790736333e-6, + -4.63677679363173e-6, + 2.43303911702242e-5, + 2.08122073672712e-5, + -2.54360911640106e-5, + 1.80816088686697e-4 + ] + }, + "fFlag": 0, + "fChi2": 5.04423904418945, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1727319917, + "fStsHits": [ + 196, + 284, + 364, + 617, + 838 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0453771762549877, + "fY": 7.03937816619873, + "fZ": 128.34700012207, + "fTx": 0.00845559220761061, + "fTy": 0.047437522560358, + "fQp": 0.107237465679646, + "fCovMatrix": [ + 0.00123450730461627, + 0.00183064327575266, + -3.61626989615615e-5, + -1.8157712474931e-5, + 1.78052068804391e-4, + 0.0247203707695007, + -5.3579336963594e-5, + -2.74032790912315e-4, + 2.21665206481703e-4, + 1.94701146938314e-6, + 2.26964857574785e-7, + -1.18611933430657e-5, + 4.69406131742289e-6, + 9.15381235699897e-7, + 8.15421881270595e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 3.12280011177063, + "fY": 12.9418659210205, + "fZ": 253.266006469727, + "fTx": 0.0393691956996918, + "fTy": 0.0470872633159161, + "fQp": 0.107262767851353, + "fCovMatrix": [ + 0.00143866648431867, + 0.00267561944201589, + 3.81068348360714e-5, + 2.64393638644833e-5, + 1.97235814994201e-4, + 0.0286122001707554, + 7.03344339854084e-5, + 3.05421301163733e-4, + 3.22181411320344e-4, + 1.72607190052076e-6, + 4.73346517537721e-7, + 1.10340961327893e-5, + 4.70324175694259e-6, + 7.17808632089145e-7, + 8.15572566352785e-5 + ] + }, + "fFlag": 0, + "fChi2": 5.80071449279785, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -570815414, + "fStsHits": [ + 71, + 152, + 324, + 412, + 688 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.803397238254547, + "fY": -6.56422710418701, + "fZ": 60.8950004577637, + "fTx": -0.00771209271624684, + "fTy": -0.108717255294323, + "fQp": 0.300887942314148, + "fCovMatrix": [ + 0.00141080969478935, + -0.0031610825099051, + -3.76598727598321e-5, + 3.06488036585506e-5, + 1.47927450598218e-4, + 0.0337333455681801, + 1.34264904772863e-4, + -2.94755038339645e-4, + -6.17008830886334e-4, + 1.84850216555787e-6, + -1.25635426684312e-6, + -7.9250839917222e-6, + 3.78815661861154e-6, + 6.15704539086437e-6, + 4.82227878819685e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.91399574279785, + "fY": -24.2552947998047, + "fZ": 222.151992797852, + "fTx": 0.11579817533493, + "fTy": -0.110671669244766, + "fQp": 0.300759524106979, + "fCovMatrix": [ + 0.00144522078335285, + 0.00259754969738424, + 3.88384942198172e-5, + 3.15018660330679e-5, + 1.55900037498213e-4, + 0.0258977226912975, + 8.17190230009146e-5, + 2.48358410317451e-4, + 3.75826784875244e-4, + 1.75587786088727e-6, + 1.22047936201852e-6, + 7.71112809161423e-6, + 3.81520703740534e-6, + 6.17916612100089e-6, + 4.81271272292361e-5 + ] + }, + "fFlag": 0, + "fChi2": 9.90100955963135, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 1256349111, + "fStsHits": [ + 88, + 182, + 364, + 610, + 762 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -7.7644305229187, + "fY": 4.62638235092163, + "fZ": 92.3769989013672, + "fTx": 0.05038708075881, + "fTy": 0.0621802993118763, + "fQp": 0.322648286819458, + "fCovMatrix": [ + 0.00143061450216919, + -0.00323629332706332, + -3.96349423681386e-5, + 3.10439791064709e-5, + 1.59761097165756e-4, + 0.034010075032711, + 1.41817727126181e-4, + -2.96661688480526e-4, + -6.54383446089923e-4, + 2.02863679987786e-6, + -1.29700083562057e-6, + -8.92197112989379e-6, + 3.86577039535041e-6, + 6.31388365945895e-6, + 5.65568916499615e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 10.7545213699341, + "fY": 14.619312286377, + "fZ": 253.266006469727, + "fTx": 0.175300538539886, + "fTy": 0.0621379911899567, + "fQp": 0.323985666036606, + "fCovMatrix": [ + 0.00143892969936132, + 0.0025955606251955, + 3.82889738830272e-5, + 3.2501597161172e-5, + 1.61684947670437e-4, + 0.0259502083063126, + 8.20754066808149e-5, + 2.53723876085132e-4, + 3.79059580154717e-4, + 1.79275116352073e-6, + 1.24236237297737e-6, + 7.63735897635343e-6, + 4.16995817431598e-6, + 6.60814203001792e-6, + 5.67811584915034e-5 + ] + }, + "fFlag": 0, + "fChi2": 13.0799026489258, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 1631218441, + "fStsHits": [ + 214, + 320, + 365, + 644, + 845 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 12.9226551055908, + "fY": -13.7240266799927, + "fZ": 123.647003173828, + "fTx": 0.130619913339615, + "fTy": -0.108535282313824, + "fQp": 0.209555685520172, + "fCovMatrix": [ + 0.00148277322296053, + -0.00284381420351565, + -4.21922559326049e-5, + 2.9940787499072e-5, + 1.88498030183837e-4, + 0.0291615109890699, + 8.29962300485931e-5, + -3.15275421598926e-4, + -3.49751790054142e-4, + 2.09275822271593e-6, + -6.84486224145076e-7, + -1.12324069050374e-5, + 4.92670187668409e-6, + 1.95221741705609e-6, + 7.34898276277818e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 33.516040802002, + "fY": -27.4323062896729, + "fZ": 248.565994262695, + "fTx": 0.196304440498352, + "fTy": -0.110583245754242, + "fQp": 0.210500478744507, + "fCovMatrix": [ + 0.00120895623695105, + -0.00177905173040926, + 3.32296367560048e-5, + -1.8623793948791e-5, + 1.56467198394239e-4, + 0.0247090216726065, + -5.03061746712774e-5, + 2.78040184639394e-4, + -1.6888887330424e-4, + 1.74129593233374e-6, + -2.8823438924519e-7, + 9.76290812104708e-6, + 4.95667654831777e-6, + 1.07869789189863e-6, + 7.42414413252845e-5 + ] + }, + "fFlag": 0, + "fChi2": 14.8659296035767, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1089573783, + "fStsHits": [ + 98, + 192, + 283, + 351, + 456 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -8.8950252532959, + "fY": 6.66752052307129, + "fZ": 92.3769989013672, + "fTx": 0.134052261710167, + "fTy": 0.0280783623456955, + "fQp": 0.193836763501167, + "fCovMatrix": [ + 0.00146598450373858, + -0.00278011965565383, + -4.09681779274251e-5, + 2.82712917396566e-5, + 1.85466415132396e-4, + 0.028964975848794, + 7.84197472967207e-5, + -3.11124749714509e-4, + -3.21005441946909e-4, + 2.00165459318669e-6, + -5.77290904857364e-7, + -1.10228729681694e-5, + 4.85223381474498e-6, + 1.17897820928192e-6, + 7.34671484678984e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 11.7369527816772, + "fY": 10.1584901809692, + "fZ": 217.451995849609, + "fTx": 0.195405215024948, + "fTy": 0.0278738830238581, + "fQp": 0.193810537457466, + "fCovMatrix": [ + 0.00122305878903717, + -0.00181355641689152, + 3.46680826623924e-5, + -1.83849115273915e-5, + 1.60300332936458e-4, + 0.0247811619192362, + -5.19911627634428e-5, + 2.76879087323323e-4, + -1.93408704944886e-4, + 1.84531995728321e-6, + -2.47711994916244e-7, + 1.04186356111313e-5, + 4.85624241264304e-6, + 9.14421434572432e-7, + 7.33600318199024e-5 + ] + }, + "fFlag": 0, + "fChi2": 15.9439134597778, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -572594012, + "fStsHits": [ + 1000, + 26, + 179, + 277, + 360 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.45930767059326, + "fY": 6.92299270629883, + "fZ": 46.757999420166, + "fTx": -0.0997228920459747, + "fTy": 0.126160323619843, + "fQp": -1.08766162395477, + "fCovMatrix": [ + 2.355308533879e-4, + 0.00165701541118324, + -3.18914771924028e-6, + -1.781737228157e-5, + 2.42890519075445e-6, + 0.0631281286478043, + 1.61764794029295e-4, + -7.06360558979213e-4, + -6.62483798805624e-4, + 5.00110809298349e-6, + -1.24003827295383e-6, + -9.39585697778966e-6, + 1.63867207447765e-5, + 7.21116703061853e-6, + 2.10776037420146e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -45.8982467651367, + "fY": 26.5154438018799, + "fZ": 190.85400390625, + "fTx": -0.550392150878906, + "fTy": 0.153908878564835, + "fQp": -1.0933438539505, + "fCovMatrix": [ + 0.0016527270199731, + 0.00375722139142454, + 5.61533379368484e-5, + 5.73905490455218e-5, + 1.73844207893126e-4, + 0.0337851718068123, + 1.5984958736226e-4, + 4.66885743662715e-4, + 5.14892512001097e-4, + 5.31236173628713e-6, + 1.87523312433768e-6, + 1.50291079989984e-5, + 1.36366652441211e-5, + 7.82930146669969e-6, + 2.06039971089922e-4 + ] + }, + "fFlag": 0, + "fChi2": 17.9824352264404, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1619730797, + "fStsHits": [ + 165, + 258, + 338, + 431, + 716 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 12.3870306015015, + "fY": 11.0686092376709, + "fZ": 128.34700012207, + "fTx": 0.131722062826157, + "fTy": 0.0759622156620026, + "fQp": 0.261173069477081, + "fCovMatrix": [ + 0.00124171550851315, + 0.00187338155228645, + -3.69237168342806e-5, + -1.9492090359563e-5, + 1.73412641743198e-4, + 0.0249464139342308, + -5.82418651902117e-5, + -2.8073534485884e-4, + 2.31354613788426e-4, + 2.10472785511229e-6, + 3.32169463490573e-7, + -1.17652871267637e-5, + 5.04569197801175e-6, + 4.14970998008357e-7, + 8.72551318025216e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 33.9409980773926, + "fY": 20.5864219665527, + "fZ": 253.266006469727, + "fTx": 0.210582479834557, + "fTy": 0.0765761435031891, + "fQp": 0.26235419511795, + "fCovMatrix": [ + 0.00145445531234145, + 0.00275185145437717, + 3.95754941564519e-5, + 2.84991037915461e-5, + 1.90182065125555e-4, + 0.0289667211472988, + 7.69189500715584e-5, + 3.15010925987735e-4, + 3.13600699882954e-4, + 1.93685445992742e-6, + 5.99234567744134e-7, + 1.08821486719535e-5, + 5.13304030391737e-6, + 9.56498297455255e-7, + 8.76150515978225e-5 + ] + }, + "fFlag": 0, + "fChi2": 19.2227821350098, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 317411667, + "fStsHits": [ + 891, + 933, + 969, + 26, + 103 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.118693307042122, + "fY": 3.28726029396057, + "fZ": 20.4885005950928, + "fTx": -0.0277622360736132, + "fTy": 0.111176677048206, + "fQp": -1.19562482833862, + "fCovMatrix": [ + 2.35528306802735e-4, + 0.00313890515826643, + -1.5442321455339e-5, + -6.0346610553097e-5, + 1.6858137678355e-4, + 0.148759827017784, + -5.5129228712758e-5, + -0.00262891850434244, + 4.23989520641044e-4, + 2.86749855149537e-6, + 2.28715475714125e-6, + -4.02842524636071e-5, + 5.76369639020413e-5, + -3.13870623358525e-5, + 0.001336490502581 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -9.37472343444824, + "fY": 11.430046081543, + "fZ": 92.4069976806641, + "fTx": -0.238975748419762, + "fTy": 0.116884142160416, + "fQp": -1.2022613286972, + "fCovMatrix": [ + 0.00181734294164926, + -0.00530816009268165, + 7.91477577877231e-5, + -1.48450635606423e-4, + 5.27066120412201e-4, + 0.047173984348774, + -2.73892597761005e-4, + 0.00118228862993419, + -0.00185405183583498, + 8.10304391052341e-6, + -5.2895188673574e-6, + 6.60147197777405e-5, + 5.66577327845152e-5, + -3.31722803821322e-5, + 0.00132040248718113 + ] + }, + "fFlag": 0, + "fChi2": 22.2989349365234, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1938391410, + "fStsHits": [ + 990, + 1034, + 43, + 138, + 225 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -13.7463674545288, + "fY": -8.49878787994385, + "fZ": 32.5089988708496, + "fTx": -0.353216707706451, + "fTy": -0.281654328107834, + "fQp": 2.23452591896057, + "fCovMatrix": [ + 2.40419758483768e-4, + 0.00225452845916152, + -2.05391843337566e-5, + -4.39578507211991e-5, + 9.27949513425119e-5, + 0.0848906114697456, + -1.73469685250893e-4, + -0.00167269050143659, + 0.00111202069092542, + 6.10797815170372e-6, + 3.83878614229616e-6, + -3.20881226798519e-5, + 5.32719241164159e-5, + -3.73771363229025e-5, + 0.00151395157445222 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -20.3196315765381, + "fY": -32.7212295532227, + "fZ": 123.677001953125, + "fTx": 0.20149177312851, + "fTy": -0.26336732506752, + "fQp": 2.23557496070862, + "fCovMatrix": [ + 0.00191347696818411, + -0.00565362721681595, + 1.08587002614513e-4, + -1.2761885591317e-4, + 5.17589738592505e-4, + 0.0476216077804565, + -4.27084742113948e-4, + 9.8123773932457e-4, + -0.00190889881923795, + 1.62221658683848e-5, + -8.1552079791436e-6, + 6.61053418298252e-5, + 4.30222571594641e-5, + -3.38782410835847e-5, + 0.00154678162652999 + ] + }, + "fFlag": 0, + "fChi2": 23.6136322021484, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1148839103, + "fStsHits": [ + 1015, + 40, + 110, + 210, + 316 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 15.3931322097778, + "fY": -5.86246490478516, + "fZ": 41.1969985961914, + "fTx": 0.425355613231659, + "fTy": -0.167463481426239, + "fQp": 0.66620284318924, + "fCovMatrix": [ + 2.32632548431866e-4, + -0.00139971077442169, + -7.05169713910436e-6, + 1.88414396689041e-5, + 3.04557925119298e-5, + 0.0488575883209705, + 1.53349592437735e-5, + -6.44137908238918e-4, + -3.31959425238892e-4, + 2.50099969889561e-6, + -5.98936765072722e-7, + -6.69307655698503e-6, + 1.28128649521386e-5, + 8.02432987256907e-6, + 9.66489169513807e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 81.8046035766602, + "fY": -27.8622398376465, + "fZ": 159.557006835938, + "fTx": 0.712900757789612, + "fTy": -0.214687287807465, + "fQp": 0.6629798412323, + "fCovMatrix": [ + 0.00161223881877959, + 0.00377275561913848, + 5.2143404900562e-5, + 4.81264833069872e-5, + 1.53602843056433e-4, + 0.0361070893704891, + 1.45044105011038e-4, + 4.82708710478619e-4, + 4.52368607511744e-4, + 3.82798089049174e-6, + 1.44914736210922e-6, + 1.09584916572203e-5, + 1.07873020169791e-5, + 3.82571352020022e-6, + 9.4176190032158e-5 + ] + }, + "fFlag": 0, + "fChi2": 29.0788040161133, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 334, + 416, + 702, + 878 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.35294222831726, + "fY": -2.94638586044312, + "fZ": 159.526992797852, + "fTx": -0.00160328403580934, + "fTy": -0.0169267207384109, + "fQp": 0.10196129232645, + "fCovMatrix": [ + 0.00179960147943348, + 0.00482485769316554, + -9.23326733754948e-5, + -9.07427238416858e-5, + 7.38598289899528e-4, + 0.0417420007288456, + -3.3866785815917e-4, + -7.00218544807285e-4, + 0.00302853807806969, + 7.63753359933617e-6, + 7.02233910487848e-6, + -6.8635301431641e-5, + 1.55159104906488e-5, + -6.57245327602141e-5, + 6.4580439357087e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.532455503940582, + "fY": -4.46498012542725, + "fZ": 248.565994262695, + "fTx": 0.0189191028475761, + "fTy": -0.0171638447791338, + "fQp": 0.101984426379204, + "fCovMatrix": [ + 0.00173512159381062, + -0.00453752232715487, + 8.09849516372196e-5, + -8.93523174454458e-5, + 7.11599015630782e-4, + 0.040440745651722, + -2.90200347080827e-4, + 6.92508299835026e-4, + -0.00289812195114791, + 6.1066607486282e-6, + -6.37889570498373e-6, + 6.09674789302517e-5, + 1.58358107000822e-5, + -6.72492606099695e-5, + 6.46489846985787e-4 + ] + }, + "fFlag": 0, + "fChi2": 0.246076673269272, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 299, + 363, + 631, + 835 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.876356244087219, + "fY": 4.59287118911743, + "fZ": 154.826995849609, + "fTx": 0.0117781879380345, + "fTy": 0.0225483179092407, + "fQp": 0.158706292510033, + "fCovMatrix": [ + 0.00191981764510274, + -0.00540495757013559, + -7.71153063396923e-5, + 9.03008331079036e-5, + 5.39929606020451e-4, + 0.0448320657014847, + 2.76860781013966e-4, + -6.93060865160078e-4, + -0.00220356229692698, + 4.92713297717273e-6, + -5.18905198987341e-6, + -3.95706665585749e-5, + 1.40935781018925e-5, + 4.43687822553329e-5, + 3.44185682479292e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.1041431427002, + "fY": 6.79212951660156, + "fZ": 253.266006469727, + "fTx": 0.0468702279031277, + "fTy": 0.0221596695482731, + "fQp": 0.158737048506737, + "fCovMatrix": [ + 0.00187287107110023, + 0.00517367757856846, + 6.87778447172605e-5, + 8.69970317580737e-5, + 5.25635492522269e-4, + 0.0436974242329597, + 2.40288529312238e-4, + 6.76476571243256e-4, + 0.00211965525522828, + 3.98110887545045e-6, + 4.53476877737558e-6, + 3.50696209352463e-5, + 1.39108415169176e-5, + 4.35302827099804e-5, + 3.44250904163346e-4 + ] + }, + "fFlag": 0, + "fChi2": 0.626406669616699, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 0, + "fStsHits": [ + 60, + 157, + 234, + 419 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -5.18759298324585, + "fY": -0.0998069643974304, + "fZ": 60.8950004577637, + "fTx": 0.0214630328118801, + "fTy": -0.033104483038187, + "fQp": 0.2199397534132, + "fCovMatrix": [ + 0.00159321434330195, + -0.00335911754518747, + -4.65064476884436e-5, + 4.81843162560835e-5, + 1.99641872313805e-4, + 0.0316577106714249, + 1.0396541620139e-4, + -4.05301689170301e-4, + -3.7617507041432e-4, + 2.28655767386954e-6, + -1.41693453770131e-6, + -1.16198334580986e-5, + 8.46501461637672e-6, + 2.66416714111983e-6, + 7.98600594862364e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.81798672676086, + "fY": -4.31223726272583, + "fZ": 186.154006958008, + "fTx": 0.0906062945723534, + "fTy": -0.0340937301516533, + "fQp": 0.220142289996147, + "fCovMatrix": [ + 0.00228732591494918, + -0.00766046345233917, + 4.16833136114292e-5, + -7.82218339736573e-5, + 1.34086134494282e-4, + 0.0586880035698414, + -9.49596069403924e-5, + 6.17937359493226e-4, + -8.07608885224909e-5, + 1.95375764633354e-6, + -6.85975749092904e-7, + 1.08221520349616e-5, + 8.30812223284738e-6, + 2.07624725589994e-6, + 7.99878544057719e-5 + ] + }, + "fFlag": 0, + "fChi2": 9.89065361022949, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 200, + 280, + 625, + 819 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.28802347183228, + "fY": 6.78667116165161, + "fZ": 128.34700012207, + "fTx": -0.00295145390555263, + "fTy": 0.066863514482975, + "fQp": -0.0631726533174515, + "fCovMatrix": [ + 0.00143133662641048, + 0.00306019233539701, + -6.01537140028086e-5, + -1.5882706065895e-5, + 3.39286430971697e-4, + 0.0325751826167107, + -2.009497693507e-4, + -2.5962368818e-4, + 0.00121131900232285, + 4.89485682919621e-6, + -3.542085380559e-8, + -3.16990190185606e-5, + 4.67263043901767e-6, + 2.65530707110884e-6, + 2.13194463867694e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.728297472000122, + "fY": 15.1543607711792, + "fZ": 253.266006469727, + "fTx": -0.0212028790265322, + "fTy": 0.0670934021472931, + "fQp": -0.0630813986063004, + "fCovMatrix": [ + 0.00170980067923665, + 0.00438810000196099, + 6.43509774818085e-5, + 2.79260748357046e-5, + 3.84177605155855e-4, + 0.0395979657769203, + 2.32808495638892e-4, + 3.1552481232211e-4, + 0.00148620537947863, + 4.30931640948984e-6, + 6.17797468294157e-7, + 2.9539532988565e-5, + 4.65721086584381e-6, + 1.86477541319618e-6, + 2.11488266359083e-4 + ] + }, + "fFlag": 0, + "fChi2": 12.0721521377563, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 200, + 278, + 457, + 769 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.22705960273743, + "fY": 6.41402244567871, + "fZ": 128.34700012207, + "fTx": 0.0584860555827618, + "fTy": 0.0308030731976032, + "fQp": 0.264887034893036, + "fCovMatrix": [ + 0.0014375695027411, + 0.00309103447943926, + -6.08879199717194e-5, + -1.67893485922832e-5, + 3.37220088113099e-4, + 0.0327315106987953, + -2.04334617592394e-4, + -2.64919508481398e-4, + 0.00120495993178338, + 5.05339949086192e-6, + 3.06302361252619e-8, + -3.16862751787994e-5, + 5.05134403283591e-6, + 2.47289267463202e-6, + 2.21960639464669e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 14.576849937439, + "fY": 10.2098379135132, + "fZ": 253.266006469727, + "fTx": 0.135617300868034, + "fTy": 0.0301221162080765, + "fQp": 0.264727205038071, + "fCovMatrix": [ + 0.00171579921152443, + 0.00442134169861674, + 6.48677450953983e-5, + 2.92732129310025e-5, + 3.80714831408113e-4, + 0.0397795774042606, + 2.3569269978907e-4, + 3.22912295814604e-4, + 0.00147179246414453, + 4.43919816461857e-6, + 7.01510657563631e-7, + 2.92453114525415e-5, + 5.09910523760482e-6, + 1.95571692529484e-6, + 2.21771551878192e-4 + ] + }, + "fFlag": 0, + "fChi2": 12.6950998306274, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 79, + 177, + 354, + 435 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 14.6889057159424, + "fY": 1.59998142719269, + "fZ": 92.3769989013672, + "fTx": 0.188801899552345, + "fTy": 0.0019485397497192, + "fQp": 0.193691298365593, + "fCovMatrix": [ + 0.00175668124575168, + -0.00460470886901021, + -7.0030233473517e-5, + 3.18565325869713e-5, + 3.55471536749974e-4, + 0.040591511875391, + 2.57493113167584e-4, + -3.32050200086087e-4, + -0.00139040977228433, + 4.9586401473789e-6, + -9.23504728689295e-7, + -2.84806355921319e-5, + 4.88101841256139e-6, + 3.32723448082106e-6, + 1.75820154254325e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 42.284595489502, + "fY": 1.7777191400528, + "fZ": 217.451995849609, + "fTx": 0.251348227262497, + "fTy": 0.00114794040564448, + "fQp": 0.193487912416458, + "fCovMatrix": [ + 0.00140010926406831, + -0.0029458578210324, + 5.59846776013728e-5, + -1.63711501954822e-5, + 2.90705327643082e-4, + 0.0321751311421394, + -1.85875440365635e-4, + 2.63134745182469e-4, + -0.00103027222212404, + 4.47622051069629e-6, + -9.90499948727575e-9, + 2.62509583990322e-5, + 5.04389936395455e-6, + 2.64827554019575e-6, + 1.75261535332538e-4 + ] + }, + "fFlag": 0, + "fChi2": 12.7743577957153, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 173, + 256, + 450, + 764 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 16.3037147521973, + "fY": 8.18320560455322, + "fZ": 128.34700012207, + "fTx": 0.0485100857913494, + "fTy": 0.0269599035382271, + "fQp": -0.464794427156448, + "fCovMatrix": [ + 0.00144951173570007, + 0.00314678833819926, + -6.25289030722342e-5, + -1.83544307219563e-5, + 3.45025095157325e-4, + 0.0330061092972755, + -2.11471997317858e-4, + -2.74737540166825e-4, + 0.0012352877529338, + 5.42095585842617e-6, + 1.29005059079645e-7, + -3.29223839798942e-5, + 5.89166847930755e-6, + 2.42049827647861e-6, + 2.57838779361919e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 13.6117811203003, + "fY": 11.6619310379028, + "fZ": 253.266006469727, + "fTx": -0.0849352851510048, + "fTy": 0.0285291355103254, + "fQp": -0.465198427438736, + "fCovMatrix": [ + 0.00172228959854692, + 0.00445574428886175, + 6.58447606838308e-5, + 3.0620507459389e-5, + 3.84085607947782e-4, + 0.0399787276983261, + 2.39864952163771e-4, + 3.32715193508193e-4, + 0.00148236250970513, + 4.74132048111642e-6, + 7.53851111312542e-7, + 2.96433372568572e-5, + 6.02678755967645e-6, + 1.60450338171358e-6, + 2.58154206676409e-4 + ] + }, + "fFlag": 0, + "fChi2": 12.822455406189, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509945888, + "fStsHits": [ + 924, + 956, + 989, + 47, + 144 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -4.1777400970459, + "fY": -1.59111475944519, + "fZ": 16.4085006713867, + "fTx": -0.303603857755661, + "fTy": -0.146884217858315, + "fQp": -2.63142681121826, + "fCovMatrix": [ + 2.53685546340421e-4, + 0.00353788468055427, + -1.72874388226774e-5, + -7.87809622124769e-5, + 7.9515295510646e-5, + 0.158824130892754, + -1.12649591756053e-4, + -0.00375775853171945, + 0.00218742550350726, + 6.11713994658203e-6, + 1.87641842330777e-6, + -5.18201413797215e-5, + 1.49448547745124e-4, + 4.5176362618804e-5, + 0.00313072255812585 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -65.9978485107422, + "fY": -15.9892063140869, + "fZ": 97.1070022583008, + "fTx": -1.69931781291962, + "fTy": -0.28000882267952, + "fQp": -2.60817050933838, + "fCovMatrix": [ + 0.0023685097694397, + 0.0083130206912756, + 2.14044077438302e-4, + 2.21727692405693e-4, + 4.34383895481005e-4, + 0.0642749667167664, + 9.29289672058076e-4, + 0.00157989992294461, + 0.00178945402149111, + 2.0627336925827e-4, + 3.11331641569268e-5, + 5.96506637521088e-4, + 9.46382278925739e-5, + 6.35135511402041e-5, + 0.00276731047779322 + ] + }, + "fFlag": 0, + "fChi2": 26.2706127166748, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789827840, + "fStsHits": [ + 902, + 943, + 976, + 29 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.53912496566772, + "fY": -3.89659118652344, + "fZ": 16.2285003662109, + "fTx": 0.522825419902802, + "fTy": -0.288690507411957, + "fQp": 2.22434949874878, + "fCovMatrix": [ + 2.76199105428532e-4, + -0.00450697494670749, + -2.23749011638574e-5, + 1.09772387077101e-4, + 2.49009346589446e-4, + 0.206538245081902, + 1.02680598502047e-4, + -0.00498864334076643, + -0.00146092427894473, + 8.5196879808791e-6, + -3.43298597726971e-6, + -9.17924553505145e-5, + 1.66340614669025e-4, + 2.30491968977731e-5, + 0.00361455837264657 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 39.5060920715332, + "fY": -18.5408248901367, + "fZ": 60.9249992370605, + "fTx": 0.971311092376709, + "fTy": -0.388391822576523, + "fQp": 2.23315715789795, + "fCovMatrix": [ + 0.00245717912912369, + -0.00909164734184742, + 1.58361988724209e-4, + -2.69030395429581e-4, + 6.81250647176057e-4, + 0.070623591542244, + -5.55392180103809e-4, + 0.00196365104056895, + -0.00189403316471726, + 2.47496318479534e-5, + -2.33925493375864e-5, + 8.39190033730119e-5, + 1.84656732017174e-4, + -5.43450478289742e-5, + 0.00324276322498918 + ] + }, + "fFlag": 0, + "fChi2": 0.0160078462213278, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789827792, + "fStsHits": [ + 900, + 942, + 975, + 36 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 8.39200782775879, + "fY": -3.32475161552429, + "fZ": 16.2285003662109, + "fTx": 0.564900398254395, + "fTy": -0.282062292098999, + "fQp": 1.66170346736908, + "fCovMatrix": [ + 2.7359023806639e-4, + -0.00449520535767078, + -2.11336046049837e-5, + 1.08181659015827e-4, + 2.12581900996156e-4, + 0.206206426024437, + 9.8862117738463e-5, + -0.00494109373539686, + -8.965625311248e-4, + 6.43738349026535e-6, + -2.70707801064418e-6, + -6.69419459882192e-5, + 1.58320981427096e-4, + -8.06868501967983e-6, + 0.00214459444396198 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 40.114372253418, + "fY": -17.2033081054688, + "fZ": 60.9249992370605, + "fTx": 0.89084392786026, + "fTy": -0.348761737346649, + "fQp": 1.6664445400238, + "fCovMatrix": [ + 0.00244997604750097, + -0.0090667437762022, + 1.51414395077154e-4, + -2.62064364505932e-4, + 7.42975214961916e-4, + 0.0705385282635689, + -5.31124067492783e-4, + 0.00194119138177484, + -0.002225091913715, + 1.75859604496509e-5, + -1.97827012016205e-5, + 6.81519377394579e-5, + 1.69458886375651e-4, + -5.7736957387533e-5, + 0.00198274431750178 + ] + }, + "fFlag": 0, + "fChi2": 0.132077515125275, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789827936, + "fStsHits": [ + 100, + 167, + 248, + 343 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -9.1610107421875, + "fY": 9.85746097564697, + "fZ": 92.3769989013672, + "fTx": 0.480140268802643, + "fTy": 0.0600208789110184, + "fQp": 1.93609797954559, + "fCovMatrix": [ + 0.00200024293735623, + -0.00600277772173285, + -8.04242372396402e-5, + 1.13586029328872e-4, + 1.76585090230219e-4, + 0.0491588152945042, + 3.09234921587631e-4, + -8.73124052304775e-4, + -6.78855925798416e-4, + 1.28341525851283e-5, + -3.947150617023e-6, + -2.85571586573496e-5, + 3.27500929415692e-5, + 1.43330807986786e-5, + 5.38995489478111e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 86.7152557373047, + "fY": 17.499963760376, + "fZ": 190.85400390625, + "fTx": 1.84347748756409, + "fTy": 0.138669148087502, + "fQp": 1.97133362293243, + "fCovMatrix": [ + 0.00211035180836916, + 0.00650257663801312, + 1.25869875773787e-4, + 1.28308791317977e-4, + 1.88947567949072e-4, + 0.05129624158144, + 5.15072897542268e-4, + 9.42497921641916e-4, + 7.66049546655267e-4, + 4.11660621466581e-5, + 9.57041356741684e-6, + 5.5888343922561e-5, + 3.89481283491477e-5, + 1.91698745766189e-5, + 3.72251815861091e-4 + ] + }, + "fFlag": 0, + "fChi2": 5.01583194732666, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 0, + "fStsHits": [ + 892, + 932, + 966, + 995 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.163538798689842, + "fY": 6.58575916290283, + "fZ": 20.4885005950928, + "fTx": 0.0469133891165257, + "fTy": 0.296761155128479, + "fQp": 2.95029425621033, + "fCovMatrix": [ + 3.33037634845823e-4, + 0.00646359380334616, + -3.08881171804387e-5, + -3.15742305247113e-4, + 7.95795174781233e-4, + 0.296464592218399, + -3.12631047563627e-4, + -0.0144908409565687, + 0.0118488008156419, + 1.09513002826134e-5, + 2.37099629885051e-5, + -2.41712361457758e-4, + 0.00110194727312773, + -8.97166435606778e-4, + 0.0108545478433371 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 3.45915913581848, + "fY": 14.4354619979858, + "fZ": 46.7879981994629, + "fTx": 0.234864756464958, + "fTy": 0.301912605762482, + "fQp": 2.95631885528564, + "fCovMatrix": [ + 3.31636285409331e-4, + 0.00638530729338527, + 3.2258660212392e-5, + 3.13805445330217e-4, + 3.01188760204241e-4, + 0.292764902114868, + 3.11581214191392e-4, + 0.0143494522199035, + -0.0112698068842292, + 1.21231414595968e-5, + 2.43910999415675e-5, + 2.18840417801403e-4, + 0.0011020228266716, + -8.5128570208326e-4, + 0.0106315473094583 + ] + }, + "fFlag": 0, + "fChi2": 7.6029896736145, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789827936, + "fStsHits": [ + 187, + 312, + 454, + 776 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -5.29122018814087, + "fY": 1.11909639835358, + "fZ": 128.34700012207, + "fTx": 0.0679009631276131, + "fTy": 0.0531249344348907, + "fQp": 1.1774697303772, + "fCovMatrix": [ + 0.00155779195483774, + 0.0037622582167387, + -7.18135343049653e-5, + -4.57157075288706e-5, + 3.0329727451317e-4, + 0.0367696546018124, + -2.54258746281266e-4, + -4.71434817882255e-4, + 0.0010841793846339, + 8.51774257171201e-6, + 8.95118319022004e-7, + -5.39621942152735e-5, + 2.08546880458016e-5, + 2.92173058369372e-6, + 0.00107021443545818 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 26.9697799682617, + "fY": 8.39235782623291, + "fZ": 253.266006469727, + "fTx": 0.444779872894287, + "fTy": 0.0642979964613914, + "fQp": 1.18556535243988, + "fCovMatrix": [ + 0.00186509417835623, + 0.00526912836357951, + 8.09190751169808e-5, + 6.40154685243033e-5, + 3.54248360963538e-4, + 0.0448441095650196, + 3.1117265461944e-4, + 5.57739695068449e-4, + 0.0013737817062065, + 9.65948038356146e-6, + 1.98274415197375e-6, + 5.237402729108e-5, + 2.17948781937594e-5, + 2.6742793579615e-6, + 0.00105986534617841 + ] + }, + "fFlag": 0, + "fChi2": 9.60446739196777, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 909258038, + "fStsHits": [ + 181, + 281, + 443, + 758 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -8.51529216766357, + "fY": 7.83456087112427, + "fZ": 128.34700012207, + "fTx": 0.274531573057175, + "fTy": 0.0677979364991188, + "fQp": 1.72251999378204, + "fCovMatrix": [ + 0.00165854278020561, + 0.00421632174402475, + -8.55470789247192e-5, + -5.39180073246825e-5, + 2.21038935706019e-4, + 0.0387094058096409, + -3.19518032483757e-4, + -5.00099617056549e-4, + 8.185034384951e-4, + 1.17226491056499e-5, + 2.25074427362415e-6, + -2.76636437774869e-5, + 2.41988582274644e-5, + -4.49401568403118e-7, + 4.98394307214767e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 74.2952423095703, + "fY": 17.0499019622803, + "fZ": 253.266006469727, + "fTx": 1.15265381336212, + "fTy": 0.0914041697978973, + "fQp": 1.72471988201141, + "fCovMatrix": [ + 0.00201824493706226, + 0.00598255405202508, + 1.08104322862346e-4, + 8.26826799311675e-5, + 2.03509247512557e-4, + 0.0480972304940224, + 4.38924587797374e-4, + 6.5469037508592e-4, + 7.57522066123784e-4, + 2.06035074370448e-5, + 4.59917828266043e-6, + 1.97731387743261e-5, + 3.33881689584814e-5, + 9.54037204792257e-8, + 4.49782353825867e-4 + ] + }, + "fFlag": 0, + "fChi2": 28.5026397705078, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + } + ], + [ + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.113743782043457, + "fY": 0.588733792304993, + "fZ": 0.446708500385284, + "fTx": -0.100411854684353, + "fTy": 0.0182576980441809, + "fQp": 0.171851590275764, + "fCovMatrix": [ + 0.00121915130876005, + -0.00157526461407542, + -3.12615520670079e-5, + 1.03501242847415e-5, + 5.74186706217006e-5, + 0.0378880277276039, + 2.97486585623119e-5, + -2.39057058934122e-4, + -9.22055405681022e-5, + 9.93395019577292e-7, + -2.10161957170385e-7, + -1.58497925895063e-6, + 2.19491153075069e-6, + 7.0918503070061e-7, + 7.72945895732846e-6 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -6.13197088241577, + "fY": 10.9124612808228, + "fZ": 635.900024414062, + "fTx": 0.0194431487470865, + "fTy": 0.0154860503971577, + "fQp": 0.172769650816917, + "fCovMatrix": [ + 0.135963916778564, + 0.0383486896753311, + 3.6564379115589e-4, + 7.20570096746087e-5, + 7.27493315935135e-4, + 0.275383651256561, + 9.25719941733405e-5, + 5.98086451645941e-4, + 2.11843798751943e-4, + 3.41494865097047e-6, + 1.7498560112017e-7, + 1.8765556433209e-6, + 3.78396589439944e-6, + 4.02894784201635e-7, + 7.05648108123569e-6 + ] + }, + "fFlag": -1, + "fChi2": 16.41866, + "fNDF": 13, + "fB": 0, + "fLength": 636.0023, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 0, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 12, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": 117, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": 1.2522908449173, + "fBeta400": -1000, + "fBeta700": 0.999027828449863, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.182159796357155, + "fPidTof400": [], + "fPidTof700": [ + 0.0278569855210373, + 0.479282876594885, + 0.125851408977037, + 0.337534256597142, + 0.00694136249661365, + 0.00333161721207416, + 0.012175674573752, + 0.00702581802745868 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0836195200681686, + "fY": 0.718462407588959, + "fZ": 0.446708500385284, + "fTx": 0.200664833188057, + "fTy": 0.0644500628113747, + "fQp": 0.205368593335152, + "fCovMatrix": [ + 0.00121043354738504, + 7.51231040339917e-4, + -3.17153790092561e-5, + -3.09064625980682e-6, + 5.77419123146683e-5, + 0.0402111560106277, + 8.61757598613622e-8, + -2.53807316767052e-4, + -2.52896461461205e-5, + 1.11059159735305e-6, + -3.05645642129093e-8, + -1.67501616488153e-6, + 2.38139682551264e-6, + 3.06331457977649e-7, + 8.24737344373716e-6 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 126.024215698242, + "fY": 28.6712455749512, + "fZ": 422.371002197266, + "fTx": 0.353906005620956, + "fTy": 0.068443663418293, + "fQp": 0.209955647587776, + "fCovMatrix": [ + 0.0325352735817432, + 0.00746848527342081, + 1.85367811354809e-4, + 2.30380119319307e-5, + 3.13971162540838e-4, + 0.063996858894825, + 3.6662670026999e-5, + 2.48965283390135e-4, + 5.83649198233616e-5, + 2.24442760554666e-6, + 1.39650239816547e-7, + 1.83472332082601e-6, + 2.17277943193039e-6, + 1.80570296492988e-7, + 7.70802853367059e-6 + ] + }, + "fFlag": -1, + "fChi2": 63.5185, + "fNDF": 13, + "fB": 0, + "fLength": 441.7529, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 1, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": 3, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": 1.02663626607586, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.297340214252472, + "fPidTof400": [ + 0.130598533122617, + 0.21583797800367, + 0.183943564412314, + 0.21916459893691, + 0.0624329814818454, + 0.0363794016608691, + 0.0886948999462895, + 0.0629480424354852 + ], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.30139833688736, + "fY": 0.1864023655653, + "fZ": 0.446708500385284, + "fTx": 0.134838849306107, + "fTy": -0.11217276006937, + "fQp": 0.562926828861237, + "fCovMatrix": [ + 0.00584008684381843, + -0.00123285257723182, + -1.75772758666426e-4, + 9.88045667327242e-6, + 1.67197795235552e-4, + 0.0616421885788441, + 3.57064072886715e-6, + -5.71430660784245e-4, + -1.45398344102432e-5, + 6.46936314296909e-6, + -8.85034836528575e-8, + -5.29768340129522e-6, + 9.37898039410356e-6, + 2.59945551306373e-7, + 3.53833565895911e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 78.3410491943359, + "fY": -30.1586742401123, + "fZ": 248.565994262695, + "fTx": 0.519947171211243, + "fTy": -0.138447120785713, + "fQp": 0.568591356277466, + "fCovMatrix": [ + 0.00111755426041782, + -0.00150139129254967, + 3.1857311114436e-5, + -1.81215455086203e-5, + 5.22565605933778e-5, + 0.0204639304429293, + -6.45808249828406e-5, + 2.0539241086226e-4, + -8.36852050269954e-5, + 2.64465393229329e-6, + -8.06947014098114e-7, + 2.75229331236915e-6, + 4.93603874929249e-6, + -1.25252370253293e-6, + 3.4731492633e-5 + ] + }, + "fFlag": -1, + "fChi2": 48.13725, + "fNDF": 11, + "fB": 0, + "fLength": 264.1259, + "fNhits": 8, + "fUsing": false, + "fGemTrack": 2, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.359468817710876, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0466443933546543, + "fY": -0.145162776112556, + "fZ": 0.446708500385284, + "fTx": -0.241355091333389, + "fTy": 0.0830243080854416, + "fQp": 1.87991809844971, + "fCovMatrix": [ + 0.0138168260455132, + -0.00339613761752844, + -0.00118863512761891, + 6.9206187617965e-5, + 3.14348202664405e-4, + 0.142328485846519, + 8.17291656858288e-5, + -0.00290396297350526, + 8.38347696117125e-5, + 1.19657546747476e-4, + -3.72808381143841e-6, + -2.29592878895346e-5, + 1.44215999171138e-4, + 1.12929251372407e-6, + 3.83465056074783e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 67.4413909912109, + "fY": 18.4549140930176, + "fZ": 217.451995849609, + "fTx": 1.14467430114746, + "fTy": 0.122764363884926, + "fQp": 1.95217978954315, + "fCovMatrix": [ + 0.00171380024403334, + -0.00418118108063936, + 1.0429337999085e-4, + -7.7113312727306e-5, + 1.41469237860292e-4, + 0.0365858227014542, + -3.63614817615598e-4, + 6.59077544696629e-4, + -4.98083070851862e-4, + 2.47048610617639e-5, + -2.76183914138528e-6, + 2.36326213780558e-5, + 3.55777374352328e-5, + -4.08496134696179e-6, + 3.6235831794329e-4 + ] + }, + "fFlag": -1, + "fChi2": 26.7675, + "fNDF": 15, + "fB": 0, + "fLength": 243.3695, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 3, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.57079815864563, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0722319558262825, + "fY": 0.354784071445465, + "fZ": 0.446708500385284, + "fTx": -0.155001595616341, + "fTy": 0.0933444499969482, + "fQp": 0.863337874412537, + "fCovMatrix": [ + 0.00248112971894443, + -0.0022091583814472, + -1.71584979398176e-4, + 2.0161514839856e-5, + 9.59185126703233e-5, + 0.0701298043131828, + 4.46569429186638e-5, + -7.85009935498238e-4, + -9.24255000427365e-5, + 1.4471720533038e-5, + -5.93432559981011e-7, + -5.66963035453227e-6, + 2.19426583498716e-5, + 8.22816389245418e-7, + 7.96381355030462e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 26.3584899902344, + "fY": 23.1596603393555, + "fZ": 253.266006469727, + "fTx": 0.386137813329697, + "fTy": 0.0894111171364784, + "fQp": 0.872905194759369, + "fCovMatrix": [ + 0.00141222530510277, + 0.00261890306137502, + 4.1884839447448e-5, + 3.52654060407076e-5, + 6.37184057268314e-5, + 0.026132557541132, + 1.03059472166933e-4, + 3.20465071126819e-4, + 1.36897549964488e-4, + 3.59388832293916e-6, + 1.2825257726945e-6, + 4.27736631536391e-6, + 8.88297381607117e-6, + 1.62169681061641e-6, + 7.93475410318933e-5 + ] + }, + "fFlag": -1, + "fChi2": 36.37777, + "fNDF": 15, + "fB": 0, + "fLength": 258.6746, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 4, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.0808681026101112, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0223507452756166, + "fY": 0.117746315896511, + "fZ": 0.446708500385284, + "fTx": -0.158949002623558, + "fTy": -0.108076266944408, + "fQp": 0.321490377187729, + "fCovMatrix": [ + 0.00110964721534401, + 0.0016296305693686, + -4.07910520152654e-5, + -1.11586468847236e-5, + 3.87022519134916e-5, + 0.0413209311664104, + -3.79046941816341e-5, + -3.13119031488895e-4, + 7.54496431909502e-5, + 1.99892588170769e-6, + 2.76388362863145e-7, + -1.59209389494208e-6, + 4.23597293774947e-6, + -5.77993034767132e-7, + 1.44496598295518e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 9.21086978912354, + "fY": -66.7490005493164, + "fZ": 627.099975585938, + "fTx": 0.0693006217479706, + "fTy": -0.106068350374699, + "fQp": 0.325574189424515, + "fCovMatrix": [ + 0.214608564972878, + -0.0352199971675873, + 5.92130701988935e-4, + -6.48957429802977e-5, + 9.30178386624902e-4, + 0.33765435218811, + -8.78709979588166e-5, + 7.95151281636208e-4, + -1.35593116283417e-4, + 4.50117113359738e-6, + -1.83297686362494e-7, + 2.47051798396569e-6, + 4.84003430756275e-6, + -2.35852496643929e-7, + 1.33578841996496e-5 + ] + }, + "fFlag": -1, + "fChi2": 23.4274, + "fNDF": 13, + "fB": 0, + "fLength": 631.7896, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 5, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 26, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": 0.955971454867903, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.307907283306122, + "fPidTof400": [], + "fPidTof700": [ + 0.849397820405311, + 0.0280379574723017, + 0.0380931545550009, + 0.0273978671350635, + 0.0121024510356469, + 0.00564051559051651, + 0.0270490304126194, + 0.01228120339354 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.106933452188969, + "fY": -0.370311707258224, + "fZ": 0.446708500385284, + "fTx": -0.235435292124748, + "fTy": 0.0907222703099251, + "fQp": 2.46053838729858, + "fCovMatrix": [ + 0.014126705005765, + -0.00404291227459908, + -7.56452966015786e-4, + 7.92645660112612e-5, + 7.98755150754005e-4, + 0.182829931378365, + 7.63797652325593e-5, + -0.00320534314960241, + 6.16679200902581e-4, + 4.36723821621854e-5, + -2.70802843260753e-6, + -6.14533710177056e-5, + 8.48018826218322e-5, + -3.15751526613894e-6, + 0.00108029355760664 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 35.9676246643066, + "fY": 14.2686767578125, + "fZ": 154.856994628906, + "fTx": 0.896000862121582, + "fTy": 0.118299603462219, + "fQp": 2.51388120651245, + "fCovMatrix": [ + 0.001817143172957, + -0.00485007045790553, + 1.14804308395833e-4, + -9.64944920269772e-5, + 2.9752537375316e-4, + 0.0413326025009155, + -4.27107122959569e-4, + 7.91111495345831e-4, + -0.00113374111242592, + 2.6783502107719e-5, + -3.85322800866561e-6, + 5.09271048940718e-5, + 4.6236724301707e-5, + -1.47345344885252e-5, + 0.00102324690669775 + ] + }, + "fFlag": -1, + "fChi2": 40.41425, + "fNDF": 11, + "fB": 0, + "fLength": 167.6239, + "fNhits": 8, + "fUsing": false, + "fGemTrack": 6, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.807983875274658, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.316711187362671, + "fY": 0.238925993442535, + "fZ": 0.446708500385284, + "fTx": -0.343945235013962, + "fTy": -0.0580112785100937, + "fQp": 0.409561008214951, + "fCovMatrix": [ + 0.00555423181504011, + 0.00246460200287402, + -1.38709059683606e-4, + -2.05631240532966e-5, + 1.15155235107522e-4, + 0.0547902584075928, + -5.04528798046522e-5, + -4.56332985777408e-4, + 4.36690097558312e-5, + 4.2953188312822e-6, + 4.69048217155432e-7, + -3.72575595974922e-6, + 6.47122760710772e-6, + -7.24516155514721e-7, + 2.43893591687083e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -53.5613479614258, + "fY": -13.3742799758911, + "fZ": 248.565994262695, + "fTx": -0.0919805094599724, + "fTy": -0.051100492477417, + "fQp": 0.409756720066071, + "fCovMatrix": [ + 0.00102374202106148, + -0.00121821509674191, + 2.25714866246562e-5, + -9.65455365076195e-6, + 5.50462027604226e-5, + 0.0189228896051645, + -3.68259061360732e-5, + 1.56089285155758e-4, + -8.76016565598547e-5, + 1.22756193832174e-6, + -2.51058338562871e-7, + 2.36619644056191e-6, + 2.87100806417584e-6, + -4.09444822935257e-7, + 2.46403506025672e-5 + ] + }, + "fFlag": -1, + "fChi2": 22.50924, + "fNDF": 9, + "fB": 0, + "fLength": 254.4599, + "fNhits": 7, + "fUsing": false, + "fGemTrack": 7, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.339586406946182, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.195573806762695, + "fY": -1.81441295146942, + "fZ": 0.446708500385284, + "fTx": -0.0233523342758417, + "fTy": -0.0799169391393661, + "fQp": 0.211819499731064, + "fCovMatrix": [ + 0.00239080400206149, + 1.70066123246215e-4, + -5.87307076784782e-5, + -9.92962213786086e-7, + 7.24626806913875e-5, + 0.0632314011454582, + -4.44729812443256e-5, + -3.873614477925e-4, + 1.19298085337505e-4, + 2.17506953958946e-6, + 2.37903734046085e-7, + -2.04682828552905e-6, + 3.95881806980469e-6, + -6.84297958741809e-7, + 1.02914364106255e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 57.9138565063477, + "fY": -54.6964263916016, + "fZ": 635.900024414062, + "fTx": 0.127945572137833, + "fTy": -0.0842056721448898, + "fQp": 0.215001165866852, + "fCovMatrix": [ + 0.178465560078621, + -0.0452135726809502, + 4.70553990453482e-4, + -9.18271689442918e-5, + 9.15236596483737e-4, + 0.334037303924561, + -1.1111512867501e-4, + 7.4203364783898e-4, + -1.988829462789e-4, + 2.43283329837141e-6, + -2.38534653362876e-7, + 2.3646659883525e-6, + 2.8837989702879e-6, + -4.04263175823871e-7, + 9.14934480533702e-6 + ] + }, + "fFlag": -1, + "fChi2": 39.02974, + "fNDF": 9, + "fB": 0, + "fLength": 640.8456, + "fNhits": 8, + "fUsing": false, + "fGemTrack": 8, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 25, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": 0.980564064138401, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.24577975273132, + "fPidTof400": [], + "fPidTof700": [ + 0.936496883123008, + 0.0124580799429877, + 0.0168911515414285, + 0.0121781551086254, + 0.00461783656238372, + 0.00195265796344994, + 0.0107138115963022, + 0.00469142416181431 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -2.5022611618042, + "fY": -0.48456397652626, + "fZ": 0.446708500385284, + "fTx": 0.09127426892519, + "fTy": -0.0951503813266754, + "fQp": -0.993796586990356, + "fCovMatrix": [ + 0.0420446656644344, + -0.0174753814935684, + -0.00113928818609565, + 1.40313539304771e-4, + 0.0010245005832985, + 0.118863306939602, + 2.32575504924171e-4, + -0.00162115576677024, + -3.16957710310817e-4, + 6.6767395765055e-5, + -2.39103087551484e-6, + -2.33741357078543e-5, + 6.86382845742628e-5, + 2.84903512692836e-6, + 1.34686910314485e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -58.270393371582, + "fY": -24.5115928649902, + "fZ": 248.565994262695, + "fTx": -0.582086145877838, + "fTy": -0.102219641208649, + "fQp": -1.00568675994873, + "fCovMatrix": [ + 0.00128551793750376, + -0.00207453384064138, + 4.9034886615118e-5, + -2.93046323349699e-5, + 8.9734407083597e-5, + 0.0242247544229031, + -1.19483127491549e-4, + 3.08274960843846e-4, + -2.00828450033441e-4, + 5.85356519877678e-6, + -1.18506238777627e-6, + 6.76520085107768e-6, + 1.06499564935802e-5, + -3.04863306155312e-6, + 1.18108830065466e-4 + ] + }, + "fFlag": -1, + "fChi2": 32.46508, + "fNDF": 9, + "fB": 0, + "fLength": 260.707, + "fNhits": 7, + "fUsing": false, + "fGemTrack": 9, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.63166427612305, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0710224881768227, + "fY": 0.05183345079422, + "fZ": 0.446708500385284, + "fTx": 0.360555469989777, + "fTy": -0.100696377456188, + "fQp": 0.868661105632782, + "fCovMatrix": [ + 0.00175835390109569, + -0.00117000739555806, + -1.18933327030391e-4, + 1.62687065312639e-5, + 2.11807171581313e-4, + 0.138006910681725, + -6.73187387292273e-5, + -0.00164641381707042, + 6.95851165801287e-4, + 1.04335795185762e-5, + 4.73094388553363e-7, + -1.58148668560898e-5, + 2.91128362732707e-5, + -9.29293946683174e-6, + 2.2163889661897e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 64.4297180175781, + "fY": -13.9177446365356, + "fZ": 123.677001953125, + "fTx": 0.72672039270401, + "fTy": -0.134330794215202, + "fQp": 0.878399670124054, + "fCovMatrix": [ + 0.00160757114645094, + -0.00398816168308258, + 7.29574530851096e-5, + -8.36182516650297e-5, + 2.40785084315576e-4, + 0.0378738828003407, + -2.46375158894807e-4, + 6.83184887748212e-4, + -7.99094792455435e-4, + 7.44503131500096e-6, + -5.03312639921205e-6, + 2.31208141485695e-5, + 2.11625283554895e-5, + -1.67757134477142e-5, + 2.12662940612063e-4 + ] + }, + "fFlag": -1, + "fChi2": 4.796133, + "fNDF": 7, + "fB": 0, + "fLength": 141.1552, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 10, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.375572264194489, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.34116351604462, + "fY": -1.36811017990112, + "fZ": 0.446708500385284, + "fTx": 0.0989279821515083, + "fTy": 0.0329475291073322, + "fQp": 0.173811748623848, + "fCovMatrix": [ + 0.046872902661562, + -0.0271047055721283, + -6.04064960498363e-4, + 1.53399203554727e-4, + 9.83070000074804e-4, + 0.107374183833599, + 3.17508354783058e-4, + -7.07785424310714e-4, + -7.41539755836129e-4, + 8.14452778286068e-6, + -1.82926487468649e-6, + -1.25158912851475e-5, + 6.05001014264417e-6, + 4.36901927969302e-6, + 3.17835838359315e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 36.9998054504395, + "fY": 6.80868768692017, + "fZ": 253.266006469727, + "fTx": 0.204165861010551, + "fTy": 0.0321086347103119, + "fQp": 0.174466639757156, + "fCovMatrix": [ + 0.00132604071404785, + 0.00240976945497096, + 3.02924581774278e-5, + 2.5230410756194e-5, + 1.25503007438965e-4, + 0.025324797257781, + 6.86817729729228e-5, + 2.36949999816716e-4, + 3.32722527673468e-4, + 1.11861686491466e-6, + 7.92246112268913e-7, + 5.05562411490246e-6, + 3.14955241265125e-6, + 4.21537333750166e-6, + 3.16932710120454e-5 + ] + }, + "fFlag": -1, + "fChi2": 8.981709, + "fNDF": 7, + "fB": 0, + "fLength": 256.0445, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 11, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.21998953819275, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.472078382968903, + "fY": -0.11114527285099, + "fZ": 0.446708500385284, + "fTx": -0.047980472445488, + "fTy": -0.0546752586960793, + "fQp": 0.264409244060516, + "fCovMatrix": [ + 0.0632011517882347, + 0.0241218619048595, + -8.60568252392113e-4, + -1.34613204863854e-4, + 0.00126098853070289, + 0.11348532885313, + -2.8231434407644e-4, + -8.57013161294162e-4, + 6.5651984186843e-4, + 1.27156299640774e-5, + 1.60285753736389e-6, + -1.63434997375589e-5, + 9.33580122364219e-6, + -3.73514421880827e-6, + 4.36296577390749e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.82009363174438, + "fY": -13.8860502243042, + "fZ": 248.565994262695, + "fTx": 0.107870183885098, + "fTy": -0.0562192648649216, + "fQp": 0.266337841749191, + "fCovMatrix": [ + 0.00115839694626629, + -0.00171898689586669, + 2.91786582238274e-5, + -1.94178428500891e-5, + 1.24229423818178e-4, + 0.0224172528833151, + -5.91218558838591e-5, + 2.1739570365753e-4, + -2.88082315819338e-4, + 1.38089103529637e-6, + -7.26864755051793e-7, + 5.93746290178387e-6, + 3.33536263497081e-6, + -3.93559366784757e-6, + 4.36123991676141e-5 + ] + }, + "fFlag": -1, + "fChi2": 13.15495, + "fNDF": 7, + "fB": 0, + "fLength": 248.9029, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 12, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.73689329624176, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0597548820078373, + "fY": 0.644053101539612, + "fZ": 0.446708500385284, + "fTx": -0.107609897851944, + "fTy": -0.200291991233826, + "fQp": -0.562099874019623, + "fCovMatrix": [ + 0.00382377323694527, + 0.00269884592853487, + -1.30351749248803e-4, + -1.71071842487436e-5, + 3.48907429724932e-4, + 0.0906038582324982, + -4.06905928684864e-5, + -8.86596040800214e-4, + -3.42734019795898e-5, + 5.48633215657901e-6, + 1.50057630321498e-7, + -1.26574777823407e-5, + 1.21654602480703e-5, + 1.77455467564869e-6, + 9.3246424512472e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -34.5075836181641, + "fY": -31.8353710174561, + "fZ": 159.557006835938, + "fTx": -0.346722215414047, + "fTy": -0.21097306907177, + "fQp": -0.572068274021149, + "fCovMatrix": [ + 0.00153660564683378, + 0.00338289677165449, + 4.58140784758143e-5, + 4.59371112810913e-5, + 1.61742660566233e-4, + 0.0334698744118214, + 1.14889880933333e-4, + 4.34220593888313e-4, + 3.44392232364044e-4, + 2.73831551567127e-6, + 1.49882725963835e-6, + 1.05627932498464e-5, + 8.82463154994184e-6, + 3.68091014024685e-6, + 9.21655009733513e-5 + ] + }, + "fFlag": -1, + "fChi2": 50.0075, + "fNDF": 7, + "fB": 0, + "fLength": 166.6362, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 13, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.237428858876228, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0644420459866524, + "fY": 0.28891995549202, + "fZ": 0.446708500385284, + "fTx": -0.109520241618156, + "fTy": -0.264354079961777, + "fQp": 2.00249004364014, + "fCovMatrix": [ + 0.0148330349475145, + -0.00361188943497837, + -0.00138078932650387, + -7.04352669345099e-6, + 5.40123030077666e-4, + 0.204159691929817, + -8.48091167426901e-6, + -0.00359647208824754, + -6.31751259788871e-4, + 1.36617629323155e-4, + 5.07185995957116e-6, + -4.58278191217687e-5, + 1.77940702997148e-4, + 3.13839137788818e-7, + 9.79271368123591e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 24.8955745697021, + "fY": -33.7819709777832, + "fZ": 123.677001953125, + "fTx": 0.604310631752014, + "fTy": -0.315734297037125, + "fQp": 2.09776401519775, + "fCovMatrix": [ + 0.00176150107290596, + -0.00480693858116865, + 1.03912498161662e-4, + -1.12679801532067e-4, + 2.87616538116708e-4, + 0.042500589042902, + -4.01500758016482e-4, + 8.34156293421984e-4, + -9.35784832108766e-4, + 1.83507636393188e-5, + -7.35896674086689e-6, + 5.00350506627001e-5, + 4.53848879260477e-5, + -1.4240275049815e-5, + 9.32074501179159e-4 + ] + }, + "fFlag": -1, + "fChi2": 66.72202, + "fNDF": 7, + "fB": 0, + "fLength": 133.3012, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 14, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.167724788188934, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.54710507392883, + "fY": -0.58077609539032, + "fZ": 0.446708500385284, + "fTx": 0.0338729247450829, + "fTy": -0.0313976965844631, + "fQp": 0.202479869127274, + "fCovMatrix": [ + 0.160711407661438, + -0.0383793190121651, + -0.00174940226133913, + 1.56199675984681e-4, + 0.0031978590413928, + 0.206317380070686, + 3.42362414812669e-4, + -0.00121129816398025, + -6.0384685639292e-4, + 2.00798640435096e-5, + -1.31709532524837e-6, + -3.56181517418008e-5, + 9.03579257283127e-6, + 2.11933797800157e-6, + 8.1467951531522e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 24.739673614502, + "fY": -8.64188003540039, + "fZ": 248.565994262695, + "fTx": 0.153393998742104, + "fTy": -0.0334637500345707, + "fQp": 0.203488066792488, + "fCovMatrix": [ + 0.00120611628517509, + -0.00176589959301054, + 3.30342554661911e-5, + -1.81667473952984e-5, + 1.64499200764112e-4, + 0.0246628411114216, + -4.92055478389375e-5, + 2.77021696092561e-4, + -1.80929011548869e-4, + 1.72334603121271e-6, + -2.53595430876885e-7, + 1.0244283657812e-5, + 4.93520428790362e-6, + 1.19064839054772e-6, + 8.14808299764991e-5 + ] + }, + "fFlag": -1, + "fChi2": 2.793974, + "fNDF": 5, + "fB": 0, + "fLength": 249.5455, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 15, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.87326192855835, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0134795252233744, + "fY": 0.487246483564377, + "fZ": 0.446708500385284, + "fTx": -0.0687238201498985, + "fTy": -0.264258414506912, + "fQp": 0.469837635755539, + "fCovMatrix": [ + 0.00256364024244249, + 0.00289767188951373, + -1.15898430522066e-4, + -4.13587767980061e-5, + 5.24579489137977e-4, + 0.172234535217285, + -2.6559637626633e-4, + -0.0018809080356732, + 0.00192667171359062, + 6.12427538726479e-6, + 3.29693284584209e-6, + -2.57115116255591e-5, + 2.43352551478893e-5, + -2.42432324739639e-5, + 2.14631159906276e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.12681382894516, + "fY": -32.1258316040039, + "fZ": 123.677001953125, + "fTx": 0.0742319375276566, + "fTy": -0.26606622338295, + "fQp": 0.47090420126915, + "fCovMatrix": [ + 0.00158424722030759, + -0.00395862851291895, + 6.28770649200305e-5, + -8.84528126334772e-5, + 3.37789009790868e-4, + 0.0385282747447491, + -2.04121737624519e-4, + 7.34325964003801e-4, + -0.00110242667142302, + 4.39162113252678e-6, + -4.81559709442081e-6, + 2.59254975389922e-5, + 2.14575829886599e-5, + -2.56246821663808e-5, + 2.14337997022085e-4 + ] + }, + "fFlag": -1, + "fChi2": 3.557666, + "fNDF": 5, + "fB": 0, + "fLength": 127.5816, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 16, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.077278658747673, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -12.1896190643311, + "fY": 2.49409508705139, + "fZ": 0.446708500385284, + "fTx": -0.00102446682285517, + "fTy": 0.0395563989877701, + "fQp": 0.380936354398727, + "fCovMatrix": [ + 0.0611070431768894, + -0.0354166217148304, + -0.00119458755943924, + 2.26294883759692e-4, + 0.00155877380166203, + 0.120648585259914, + 4.24436875618994e-4, + -0.00121659121941775, + -0.0010009107645601, + 1.22825935250148e-4, + -2.79522691926104e-6, + -2.12772811210016e-5, + 1.19090829684865e-4, + 6.7240457610751e-6, + 6.08225964242592e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 16.5165977478027, + "fY": 12.2913675308228, + "fZ": 253.266006469727, + "fTx": 0.229917138814926, + "fTy": 0.0385008491575718, + "fQp": 0.383702665567398, + "fCovMatrix": [ + 0.00140638451557606, + 0.0031376676633954, + 3.78932563762646e-5, + 3.06943329633214e-5, + 1.49175975820981e-4, + 0.0336156375706196, + 1.34585134219378e-4, + 2.975782554131e-4, + 6.11140800174326e-4, + 2.04978573492554e-6, + 1.21983202916454e-6, + 7.85819793236442e-6, + 4.30095087722293e-6, + 5.96624204263208e-6, + 6.05825152888428e-5 + ] + }, + "fFlag": -1, + "fChi2": 4.295112, + "fNDF": 5, + "fB": 0, + "fLength": 255.3587, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 17, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 12.3314142227173, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0444554686546326, + "fY": 0.348040878772736, + "fZ": 0.446708500385284, + "fTx": -0.0752754285931587, + "fTy": -0.266079545021057, + "fQp": 0.319220513105392, + "fCovMatrix": [ + 0.00225992104969919, + 0.00305393501184881, + -9.69212924246676e-5, + -4.40127951151226e-5, + 5.14772429596633e-4, + 0.170411959290504, + -2.71132768830284e-4, + -0.00182572042103857, + 0.0019931229762733, + 4.74177841169876e-6, + 3.36953053192701e-6, + -2.44284583459375e-5, + 2.2066391466069e-5, + -2.48597789322957e-5, + 1.80513045052066e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.65879273414612, + "fY": -32.4332733154297, + "fZ": 123.677001953125, + "fTx": 0.021767932921648, + "fTy": -0.266411513090134, + "fQp": 0.319602519273758, + "fCovMatrix": [ + 0.00156673660967499, + -0.00387575500644743, + 6.05840032221749e-5, + -8.63880923134275e-5, + 3.30092705553398e-4, + 0.0381363146007061, + -1.93470521480776e-4, + 7.24260287825018e-4, + -0.0010770196095109, + 3.9610790736333e-6, + -4.63677679363173e-6, + 2.43303911702242e-5, + 2.08122073672712e-5, + -2.54360911640106e-5, + 1.80816088686697e-4 + ] + }, + "fFlag": -1, + "fChi2": 5.044239, + "fNDF": 5, + "fB": 0, + "fLength": 127.6035, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 18, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.0782802104949951, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.10143184661865, + "fY": 0.943868219852448, + "fZ": 0.446708500385284, + "fTx": -0.0236356854438782, + "fTy": 0.0478610992431641, + "fQp": 0.106951728463173, + "fCovMatrix": [ + 0.14646415412426, + 0.0157565474510193, + -0.0015795404324308, + -1.41862719829078e-5, + 0.00332151097245514, + 0.175634920597076, + -1.01814752270002e-4, + -9.37131466343999e-4, + 8.13772203400731e-5, + 1.74941469595069e-5, + -2.12643570307591e-7, + -3.62929167749826e-5, + 5.82600614507101e-6, + 1.26183351767395e-6, + 8.15489547676407e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 17.9083042144775, + "fY": 28.0036888122559, + "fZ": 597.099975585938, + "fTx": 0.0445287711918354, + "fTy": 0.0445158071815968, + "fQp": 0.0825817957520485, + "fCovMatrix": [ + 0.364190697669983, + 0.0381823219358921, + 0.0010879811597988, + 5.49031028640456e-5, + 0.00419190991669893, + 0.441666811704636, + 9.56025323830545e-5, + 0.00107291282620281, + 3.79249722755048e-5, + 3.26988333654299e-6, + 1.19356840855289e-7, + 1.27025923575275e-5, + 2.66925280811847e-6, + -3.73543485920891e-7, + 5.37693849764764e-5 + ] + }, + "fFlag": -1, + "fChi2": 28.96204, + "fNDF": 5, + "fB": 0, + "fLength": 597.7899, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 19, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 9, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": 0.804089836905722, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.2472208738327, + "fPidTof400": [], + "fPidTof700": [ + 0.119469895061994, + 0.11648865799471, + 0.11725495135731, + 0.11642242444021, + 0.129323001966123, + 0.148480637199097, + 0.123413530982756, + 0.1291469009978 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.928329765796661, + "fY": -0.00530472630634904, + "fZ": 0.446708500385284, + "fTx": -0.0476474948227406, + "fTy": -0.108358539640903, + "fQp": 0.300448805093765, + "fCovMatrix": [ + 0.0205874796956778, + -0.0218283198773861, + -3.42761719366536e-4, + 1.31376218632795e-4, + 8.29507829621434e-4, + 0.0849663093686104, + 3.40031983796507e-4, + -5.73873636312783e-4, + -9.89176100119948e-4, + 6.53728420729749e-6, + -2.04609477805207e-6, + -1.43179122460424e-5, + 5.54201233171625e-6, + 6.14383043284761e-6, + 4.8235207941616e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.91399574279785, + "fY": -24.2552947998047, + "fZ": 222.151992797852, + "fTx": 0.11579817533493, + "fTy": -0.110671669244766, + "fQp": 0.300759524106979, + "fCovMatrix": [ + 0.00144522078335285, + 0.00259754969738424, + 3.88384942198172e-5, + 3.15018660330679e-5, + 1.55900037498213e-4, + 0.0258977226912975, + 8.17190230009146e-5, + 2.48358410317451e-4, + 3.75826784875244e-4, + 1.75587786088727e-6, + 1.22047936201852e-6, + 7.71112809161423e-6, + 3.81520703740534e-6, + 6.17916612100089e-6, + 4.81271272292361e-5 + ] + }, + "fFlag": -1, + "fChi2": 9.90101, + "fNDF": 5, + "fB": 0, + "fLength": 223.4231, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 20, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.05338907241821, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -9.13331127166748, + "fY": -1.12110900878906, + "fZ": 0.446708500385284, + "fTx": -0.0173953901976347, + "fTy": 0.0628743693232536, + "fQp": 0.320655584335327, + "fCovMatrix": [ + 0.0583643950521946, + -0.0429685451090336, + -0.00102648814208806, + 2.20086571061984e-4, + 0.00155384629033506, + 0.128345862030983, + 5.27929747477174e-4, + -0.00103958090767264, + -0.00124197418335825, + 8.71188894961961e-5, + -2.80641279459815e-6, + -2.08510009542806e-5, + 8.30017452244647e-5, + 6.46857915853616e-6, + 5.66176458960399e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 10.7545213699341, + "fY": 14.619312286377, + "fZ": 253.266006469727, + "fTx": 0.175300538539886, + "fTy": 0.0621379911899567, + "fQp": 0.323985666036606, + "fCovMatrix": [ + 0.00143892969936132, + 0.0025955606251955, + 3.82889738830272e-5, + 3.2501597161172e-5, + 1.61684947670437e-4, + 0.0259502083063126, + 8.20754066808149e-5, + 2.53723876085132e-4, + 3.79059580154717e-4, + 1.79275116352073e-6, + 1.24236237297737e-6, + 7.63735897635343e-6, + 4.16995817431598e-6, + 6.60814203001792e-6, + 5.67811584915034e-5 + ] + }, + "fFlag": -1, + "fChi2": 13.0799, + "fNDF": 5, + "fB": 0, + "fLength": 254.58, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 21, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 9.23084259033203, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.843642950057983, + "fY": -0.48146265745163, + "fZ": 0.446708500385284, + "fTx": 0.0686445757746696, + "fTy": -0.106640420854092, + "fQp": 0.209226995706558, + "fCovMatrix": [ + 0.13631746172905, + -0.0395477153360844, + -0.0014649648219347, + 1.68585451319814e-4, + 0.00297867809422314, + 0.187767058610916, + 3.53419251041487e-4, + -9.96352639049292e-4, + -6.25751563347876e-4, + 1.65008386829868e-5, + -1.45064245771209e-6, + -3.29569265886676e-5, + 6.30119484412717e-6, + 2.42129408434266e-6, + 7.3498253186699e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 33.516040802002, + "fY": -27.4323062896729, + "fZ": 248.565994262695, + "fTx": 0.196304440498352, + "fTy": -0.110583245754242, + "fQp": 0.210500478744507, + "fCovMatrix": [ + 0.00120895623695105, + -0.00177905173040926, + 3.32296367560048e-5, + -1.8623793948791e-5, + 1.56467198394239e-4, + 0.0247090216726065, + -5.03061746712774e-5, + 2.78040184639394e-4, + -1.6888887330424e-4, + 1.74129593233374e-6, + -2.8823438924519e-7, + 9.76290812104708e-6, + 4.95667654831777e-6, + 1.07869789189863e-6, + 7.42414413252845e-5 + ] + }, + "fFlag": -1, + "fChi2": 14.86593, + "fNDF": 5, + "fB": 0, + "fLength": 251.9622, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 22, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.26132702827454, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -19.2282829284668, + "fY": 4.06761169433594, + "fZ": 0.446708500385284, + "fTx": 0.0927537381649017, + "fTy": 0.0284985508769751, + "fQp": 0.193146929144859, + "fCovMatrix": [ + 0.0606342479586601, + -0.0221270453184843, + -8.87219503056258e-4, + 9.80075928964652e-5, + 0.00195298518519849, + 0.12959098815918, + 2.26609423407353e-4, + -8.89979652129114e-4, + -4.36870177509263e-4, + 3.75641611753963e-5, + -8.27293149541219e-7, + -2.66763308900408e-5, + 3.2165706215892e-5, + 1.34837273435551e-6, + 7.3485862230882e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 11.7369527816772, + "fY": 10.1584901809692, + "fZ": 217.451995849609, + "fTx": 0.195405215024948, + "fTy": 0.0278738830238581, + "fQp": 0.193810537457466, + "fCovMatrix": [ + 0.00122305878903717, + -0.00181355641689152, + 3.46680826623924e-5, + -1.83849115273915e-5, + 1.60300332936458e-4, + 0.0247811619192362, + -5.19911627634428e-5, + 2.76879087323323e-4, + -1.93408704944886e-4, + 1.84531995728321e-6, + -2.47711994916244e-7, + 1.04186356111313e-5, + 4.85624241264304e-6, + 9.14421434572432e-7, + 7.33600318199024e-5 + ] + }, + "fFlag": -1, + "fChi2": 15.94391, + "fNDF": 5, + "fB": 0, + "fLength": 219.4563, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 23, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 19.5378093719482, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.535743653774261, + "fY": 1.13074922561646, + "fZ": 0.446708500385284, + "fTx": 0.0088078249245882, + "fTy": 0.124283142387867, + "fQp": -1.08276271820068, + "fCovMatrix": [ + 0.0205681435763836, + -0.00946416705846786, + -6.27778354100883e-4, + 4.78475521958899e-5, + 9.43946302868426e-4, + 0.16974076628685, + 2.93887889711186e-4, + -0.00174504995811731, + -0.00100176921114326, + 2.82505607174244e-5, + -1.57591944116575e-6, + -3.04493350995472e-5, + 3.598545663408e-5, + 7.35173580324044e-6, + 2.16082407860085e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -45.8982467651367, + "fY": 26.5154438018799, + "fZ": 190.85400390625, + "fTx": -0.550392150878906, + "fTy": 0.153908878564835, + "fQp": -1.0933438539505, + "fCovMatrix": [ + 0.0016527270199731, + 0.00375722139142454, + 5.61533379368484e-5, + 5.73905490455218e-5, + 1.73844207893126e-4, + 0.0337851718068123, + 1.5984958736226e-4, + 4.66885743662715e-4, + 5.14892512001097e-4, + 5.31236173628713e-6, + 1.87523312433768e-6, + 1.50291079989984e-5, + 1.36366652441211e-5, + 7.82930146669969e-6, + 2.06039971089922e-4 + ] + }, + "fFlag": -1, + "fChi2": 17.98244, + "fNDF": 5, + "fB": 0, + "fLength": 200.5973, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 24, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.905997157096863, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.828063666820526, + "fY": 1.32057547569275, + "fZ": 0.446708500385284, + "fTx": 0.0525042191147804, + "fTy": 0.076543316245079, + "fQp": 0.260553300380707, + "fCovMatrix": [ + 0.157716661691666, + 0.0197686683386564, + -0.00170101039111614, + -3.8990743632894e-5, + 0.00344474543817341, + 0.18804831802845, + -1.40642136102542e-4, + -0.00103673757985234, + 1.59807517775334e-4, + 1.9831073586829e-5, + 3.73987134594245e-8, + -3.82388498110231e-5, + 7.60457533033332e-6, + 7.31151999389112e-7, + 8.72718810569495e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 33.9409980773926, + "fY": 20.5864219665527, + "fZ": 253.266006469727, + "fTx": 0.210582479834557, + "fTy": 0.0765761435031891, + "fQp": 0.26235419511795, + "fCovMatrix": [ + 0.00145445531234145, + 0.00275185145437717, + 3.95754941564519e-5, + 2.84991037915461e-5, + 1.90182065125555e-4, + 0.0289667211472988, + 7.69189500715584e-5, + 3.15010925987735e-4, + 3.13600699882954e-4, + 1.93685445992742e-6, + 5.99234567744134e-7, + 1.08821486719535e-5, + 5.13304030391737e-6, + 9.56498297455255e-7, + 8.76150515978225e-5 + ] + }, + "fFlag": -1, + "fChi2": 19.22278, + "fNDF": 5, + "fB": 0, + "fLength": 256.0777, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 25, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.24199759960175, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0512982718646526, + "fY": 1.06561839580536, + "fZ": 0.446708500385284, + "fTx": 0.0198498331010342, + "fTy": 0.110577538609505, + "fQp": -1.19012749195099, + "fCovMatrix": [ + 0.00603315327316523, + 0.00704765599220991, + -3.97437339415774e-4, + -1.23337362310849e-4, + 0.0015260394429788, + 0.280310779809952, + -1.66871061082929e-4, + -0.00403328100219369, + 0.00104829901829362, + 2.91554206341971e-5, + 3.98109477828257e-6, + -9.39659003051929e-5, + 7.87801909609698e-5, + -3.100903268205e-5, + 0.00134257483296096 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -9.37472343444824, + "fY": 11.430046081543, + "fZ": 92.4069976806641, + "fTx": -0.238975748419762, + "fTy": 0.116884142160416, + "fQp": -1.2022613286972, + "fCovMatrix": [ + 0.00181734294164926, + -0.00530816009268165, + 7.91477577877231e-5, + -1.48450635606423e-4, + 5.27066120412201e-4, + 0.047173984348774, + -2.73892597761005e-4, + 0.00118228862993419, + -0.00185405183583498, + 8.10304391052341e-6, + -5.2895188673574e-6, + 6.60147197777405e-5, + 5.66577327845152e-5, + -3.31722803821322e-5, + 0.00132040248718113 + ] + }, + "fFlag": -1, + "fChi2": 22.29893, + "fNDF": 5, + "fB": 0, + "fLength": 93.42108, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 26, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.640410184860229, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.700390338897705, + "fY": 0.90983772277832, + "fZ": 0.446708500385284, + "fTx": -0.548557937145233, + "fTy": -0.305793702602386, + "fQp": 2.18843913078308, + "fCovMatrix": [ + 0.0741067007184029, + 0.0273595526814461, + -0.00337378145195544, + -7.50150938984007e-4, + 0.0033147088252008, + 0.30476975440979, + -0.00107568292878568, + -0.00604549515992403, + 0.00265475339256227, + 2.26271324208938e-4, + 4.30196050729137e-5, + -1.69975362950936e-4, + 2.360731450608e-4, + -6.06054345553275e-5, + 0.00152116548269987 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -20.3196315765381, + "fY": -32.7212295532227, + "fZ": 123.677001953125, + "fTx": 0.20149177312851, + "fTy": -0.26336732506752, + "fQp": 2.23557496070862, + "fCovMatrix": [ + 0.00191347696818411, + -0.00565362721681595, + 1.08587002614513e-4, + -1.2761885591317e-4, + 5.17589738592505e-4, + 0.0476216077804565, + -4.27084742113948e-4, + 9.8123773932457e-4, + -0.00190889881923795, + 1.62221658683848e-5, + -8.1552079791436e-6, + 6.61053418298252e-5, + 4.30222571594641e-5, + -3.38782410835847e-5, + 0.00154678162652999 + ] + }, + "fFlag": -1, + "fChi2": 23.61363, + "fNDF": 5, + "fB": 0, + "fLength": 131.0269, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 27, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.878863215446472, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.430907219648361, + "fY": 0.819810748100281, + "fZ": 0.446708500385284, + "fTx": 0.354820370674133, + "fTy": -0.161246061325073, + "fQp": 0.664999186992645, + "fCovMatrix": [ + 0.00955541804432869, + -0.00530777126550674, + -2.87420203676447e-4, + 6.70724984956905e-5, + 5.19839581102133e-4, + 0.125300273299217, + 1.08587206341326e-4, + -0.0012696391204372, + -6.76059920806438e-4, + 1.10646278699278e-5, + -1.73058799646242e-6, + -1.68200404004892e-5, + 1.83946885954356e-5, + 8.74752367963083e-6, + 9.66972947935574e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 81.8046035766602, + "fY": -27.8622398376465, + "fZ": 159.557006835938, + "fTx": 0.712900757789612, + "fTy": -0.214687287807465, + "fQp": 0.6629798412323, + "fCovMatrix": [ + 0.00161223881877959, + 0.00377275561913848, + 5.2143404900562e-5, + 4.81264833069872e-5, + 1.53602843056433e-4, + 0.0361070893704891, + 1.45044105011038e-4, + 4.82708710478619e-4, + 4.52368607511744e-4, + 3.82798089049174e-6, + 1.44914736210922e-6, + 1.09584916572203e-5, + 1.07873020169791e-5, + 3.82571352020022e-6, + 9.4176190032158e-5 + ] + }, + "fFlag": -1, + "fChi2": 29.0788, + "fNDF": 5, + "fB": 0, + "fLength": 182.7927, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 28, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.560243666172028, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.08742094039917, + "fY": -0.293393194675446, + "fZ": 0.446708500385284, + "fTx": -0.0401604361832142, + "fTy": -0.0164600592106581, + "fQp": 0.10171927511692, + "fCovMatrix": [ + 1.59696066379547, + 0.660858631134033, + -0.0156218260526657, + -0.00313152791932225, + 0.0318597480654716, + 0.65833842754364, + -0.00644648913294077, + -0.00318792019970715, + 0.0132419569417834, + 1.5323277330026e-4, + 3.06120855384506e-5, + -3.1325820600614e-4, + 1.59172777784988e-5, + -6.30246649961919e-5, + 6.45809981506318e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 8.08927249908447, + "fY": -11.032865524292, + "fZ": 635.900024414062, + "fTx": 0.0233717299997807, + "fTy": -0.0169893242418766, + "fQp": 0.0680521056056023, + "fCovMatrix": [ + 0.720901787281036, + -0.158103734254837, + 0.00197278172709048, + -3.69012559531257e-4, + 0.00920373201370239, + 0.658935248851776, + -4.29656472988427e-4, + 0.00152434047777206, + -0.00211671344004571, + 5.74976684220019e-6, + -1.00950876458228e-6, + 2.54789156315383e-5, + 3.92320316677797e-6, + -5.14099565407378e-6, + 1.29324762383476e-4 + ] + }, + "fFlag": -1, + "fChi2": 5.530421, + "fNDF": 3, + "fB": 0, + "fLength": 635.7604, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 29, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 11, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": 0.982413048336234, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.23891544342041, + "fPidTof400": [], + "fPidTof700": [ + 0.00377830140596851, + 0.00282265424851867, + 0.00302278320239034, + 0.00280648252323255, + 0.352906208430629, + 0.00236113640578434, + 0.00655261886666298, + 0.625749814916814 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.94281661510468, + "fY": 1.05254948139191, + "fZ": 0.446708500385284, + "fTx": -0.0460996776819229, + "fTy": 0.0232866797596216, + "fQp": 0.157823503017426, + "fCovMatrix": [ + 0.86102294921875, + -0.457817822694778, + -0.00844337046146393, + 0.0022731083445251, + 0.0167319793254137, + 0.634925365447998, + 0.00446182582527399, + -0.0032517989166081, + -0.00919024553149939, + 8.3519124018494e-5, + -2.22535654756939e-5, + -1.65581965120509e-4, + 1.80169045052025e-5, + 4.60318733530585e-5, + 3.44207452144474e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.1041431427002, + "fY": 6.79212951660156, + "fZ": 253.266006469727, + "fTx": 0.0468702279031277, + "fTy": 0.0221596695482731, + "fQp": 0.158737048506737, + "fCovMatrix": [ + 0.00187287107110023, + 0.00517367757856846, + 6.87778447172605e-5, + 8.69970317580737e-5, + 5.25635492522269e-4, + 0.0436974242329597, + 2.40288529312238e-4, + 6.76476571243256e-4, + 0.00211965525522828, + 3.98110887545045e-6, + 4.53476877737558e-6, + 3.50696209352463e-5, + 1.39108415169176e-5, + 4.35302827099804e-5, + 3.44250904163346e-4 + ] + }, + "fFlag": -1, + "fChi2": 0.6264067, + "fNDF": 3, + "fB": 0, + "fLength": 252.9831, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 30, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.07289290428162, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -5.56726026535034, + "fY": 1.88980782032013, + "fZ": 0.446708500385284, + "fTx": -0.00756088923662901, + "fTy": -0.0327454805374146, + "fQp": 0.218929752707481, + "fCovMatrix": [ + 0.0281521212309599, + -0.0200254637748003, + -5.85395784582943e-4, + 1.46306061651558e-4, + 0.00123560742940754, + 0.115272685885429, + 2.61412293184549e-4, + -0.00110655347816646, + -5.40421751793474e-4, + 4.21449658460915e-5, + -1.78392735961097e-6, + -2.21715617954032e-5, + 4.38980569015257e-5, + 2.76233777185553e-6, + 7.98879918875173e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.81798672676086, + "fY": -4.31223726272583, + "fZ": 186.154006958008, + "fTx": 0.0906062945723534, + "fTy": -0.0340937301516533, + "fQp": 0.220142289996147, + "fCovMatrix": [ + 0.00228732591494918, + -0.00766046345233917, + 4.16833136114292e-5, + -7.82218339736573e-5, + 1.34086134494282e-4, + 0.0586880035698414, + -9.49596069403924e-5, + 6.17937359493226e-4, + -8.07608885224909e-5, + 1.95375764633354e-6, + -6.85975749092904e-7, + 1.08221520349616e-5, + 8.30812223284738e-6, + 2.07624725589994e-6, + 7.99878544057719e-5 + ] + }, + "fFlag": -1, + "fChi2": 9.890654, + "fNDF": 3, + "fB": 0, + "fLength": 186.0561, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 31, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 5.72475862503052, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.40435910224915, + "fY": -1.74788320064545, + "fZ": 0.446708500385284, + "fTx": 0.0159829445183277, + "fTy": 0.0666084289550781, + "fQp": -0.0630679279565811, + "fCovMatrix": [ + 0.359982132911682, + 0.0454927869141102, + -0.00394425308331847, + 7.40441828384064e-5, + 0.00865282118320465, + 0.177479684352875, + -4.34850342571735e-4, + -8.83849628735334e-4, + 8.17067746538669e-4, + 4.34577923442703e-5, + -1.18699938411737e-6, + -9.56689837039448e-5, + 5.04924128108541e-6, + 3.46451156474359e-6, + 2.13246297789738e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.728297472000122, + "fY": 15.1543607711792, + "fZ": 253.266006469727, + "fTx": -0.0212028790265322, + "fTy": 0.0670934021472931, + "fQp": -0.0630813986063004, + "fCovMatrix": [ + 0.00170980067923665, + 0.00438810000196099, + 6.43509774818085e-5, + 2.79260748357046e-5, + 3.84177605155855e-4, + 0.0395979657769203, + 2.32808495638892e-4, + 3.1552481232211e-4, + 0.00148620537947863, + 4.30931640948984e-6, + 6.17797468294157e-7, + 2.9539532988565e-5, + 4.65721086584381e-6, + 1.86477541319618e-6, + 2.11488266359083e-4 + ] + }, + "fFlag": -1, + "fChi2": 12.07215, + "fNDF": 3, + "fB": 0, + "fLength": 253.4007, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 32, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.6056342124939, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0225908625870943, + "fY": 2.4101722240448, + "fZ": 0.446708500385284, + "fTx": -0.0205847378820181, + "fTy": 0.0317823737859726, + "fQp": 0.262870192527771, + "fCovMatrix": [ + 0.410086780786514, + 0.0469960048794746, + -0.00456686085090041, + 6.65025654598139e-5, + 0.00882185809314251, + 0.229289501905441, + -4.43539873231202e-4, + -0.00149148085620254, + 8.27870098873973e-4, + 5.22158370586112e-5, + -1.14772262804763e-6, + -9.82185010798275e-5, + 1.33087651192909e-5, + 3.38607537742064e-6, + 2.22015733015724e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 14.576849937439, + "fY": 10.2098379135132, + "fZ": 253.266006469727, + "fTx": 0.135617300868034, + "fTy": 0.0301221162080765, + "fQp": 0.264727205038071, + "fCovMatrix": [ + 0.00171579921152443, + 0.00442134169861674, + 6.48677450953983e-5, + 2.92732129310025e-5, + 3.80714831408113e-4, + 0.0397795774042606, + 2.3569269978907e-4, + 3.22912295814604e-4, + 0.00147179246414453, + 4.43919816461857e-6, + 7.01510657563631e-7, + 2.92453114525415e-5, + 5.09910523760482e-6, + 1.95571692529484e-6, + 2.21771551878192e-4 + ] + }, + "fFlag": -1, + "fChi2": 12.6951, + "fNDF": 3, + "fB": 0, + "fLength": 253.6778, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 33, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.9854781627655, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.629141807556152, + "fY": 1.38312804698944, + "fZ": 0.446708500385284, + "fTx": 0.146586313843727, + "fTy": 0.00271266396157444, + "fQp": 0.192928344011307, + "fCovMatrix": [ + 0.149345919489861, + -0.0577854551374912, + -0.00205688877031207, + 1.69445615028962e-4, + 0.00482555339112878, + 0.153863877058029, + 7.25681020412594e-4, + -9.60102246608585e-4, + -0.00172866601496935, + 2.90175394184189e-5, + -1.89735999356344e-6, + -6.68615102767944e-5, + 8.06202206149464e-6, + 3.97035546484403e-6, + 1.75839726580307e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 42.284595489502, + "fY": 1.7777191400528, + "fZ": 217.451995849609, + "fTx": 0.251348227262497, + "fTy": 0.00114794040564448, + "fQp": 0.193487912416458, + "fCovMatrix": [ + 0.00140010926406831, + -0.0029458578210324, + 5.59846776013728e-5, + -1.63711501954822e-5, + 2.90705327643082e-4, + 0.0321751311421394, + -1.85875440365635e-4, + 2.63134745182469e-4, + -0.00103027222212404, + 4.47622051069629e-6, + -9.90499948727575e-9, + 2.62509583990322e-5, + 5.04389936395455e-6, + 2.64827554019575e-6, + 1.75261535332538e-4 + ] + }, + "fFlag": -1, + "fChi2": 12.77436, + "fNDF": 3, + "fB": 0, + "fLength": 221.4154, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 34, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.12807381153107, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.741546928882599, + "fY": 4.85820436477661, + "fZ": 0.446708500385284, + "fTx": 0.19030949473381, + "fTy": 0.0252211969345808, + "fQp": -0.462024539709091, + "fCovMatrix": [ + 0.420751214027405, + 0.0515755452215672, + -0.00470444280654192, + 4.05961691285484e-5, + 0.00976410880684853, + 0.224917396903038, + -4.92765102535486e-4, + -0.00132196012418717, + 8.68746836204082e-4, + 6.0438564105425e-5, + -8.71645795541554e-7, + -1.11932982690632e-4, + 1.63539098139154e-5, + 3.21649645229627e-6, + 2.60348548181355e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 13.6117811203003, + "fY": 11.6619310379028, + "fZ": 253.266006469727, + "fTx": -0.0849352851510048, + "fTy": 0.0285291355103254, + "fQp": -0.465198427438736, + "fCovMatrix": [ + 0.00172228959854692, + 0.00445574428886175, + 6.58447606838308e-5, + 3.0620507459389e-5, + 3.84085607947782e-4, + 0.0399787276983261, + 2.39864952163771e-4, + 3.32715193508193e-4, + 0.00148236250970513, + 4.74132048111642e-6, + 7.53851111312542e-7, + 2.96433372568572e-5, + 6.02678755967645e-6, + 1.60450338171358e-6, + 2.58154206676409e-4 + ] + }, + "fFlag": -1, + "fChi2": 12.82246, + "fNDF": 3, + "fB": 0, + "fLength": 254.0149, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 35, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 4.49988603591919, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0719772577285767, + "fY": 0.726722061634064, + "fZ": 0.446708500385284, + "fTx": -0.213506519794464, + "fTy": -0.143965721130371, + "fQp": -2.62076330184937, + "fCovMatrix": [ + 0.00797438062727451, + 0.00720387883484364, + -6.53111434075981e-4, + -9.67506784945726e-5, + 0.0017830478027463, + 0.321473628282547, + -1.51318730786443e-4, + -0.00658326270058751, + 0.00148632749915123, + 6.07886504440103e-5, + 9.80958958507472e-8, + -1.58694179845043e-4, + 1.94639462279156e-4, + 4.33506102126557e-5, + 0.00314619881100953 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -65.9978485107422, + "fY": -15.9892063140869, + "fZ": 97.1070022583008, + "fTx": -1.69931781291962, + "fTy": -0.28000882267952, + "fQp": -2.60817050933838, + "fCovMatrix": [ + 0.0023685097694397, + 0.0083130206912756, + 2.14044077438302e-4, + 2.21727692405693e-4, + 4.34383895481005e-4, + 0.0642749667167664, + 9.29289672058076e-4, + 0.00157989992294461, + 0.00178945402149111, + 2.0627336925827e-4, + 3.11331641569268e-5, + 5.96506637521088e-4, + 9.46382278925739e-5, + 6.35135511402041e-5, + 0.00276731047779322 + ] + }, + "fFlag": -1, + "fChi2": 26.27061, + "fNDF": 5, + "fB": 0, + "fLength": 130.3361, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 36, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.303768336772919, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0557866953313351, + "fY": 0.547424077987671, + "fZ": 0.446708500385284, + "fTx": 0.429236263036728, + "fTy": -0.275659441947937, + "fQp": 2.17269659042358, + "fCovMatrix": [ + 0.0197780951857567, + -0.00987072102725506, + -0.00182154367212206, + 2.94619821943343e-4, + 0.00291714025661349, + 0.418625175952911, + 2.52996629569679e-4, + -0.00894289463758469, + -0.00197083782404661, + 2.09425037610345e-4, + -1.89258062164299e-5, + -2.41016896325164e-4, + 3.31170595018193e-4, + 3.93724658351857e-5, + 0.00362231628969312 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 39.5060920715332, + "fY": -18.5408248901367, + "fZ": 60.9249992370605, + "fTx": 0.971311092376709, + "fTy": -0.388391822576523, + "fQp": 2.23315715789795, + "fCovMatrix": [ + 0.00245717912912369, + -0.00909164734184742, + 1.58361988724209e-4, + -2.69030395429581e-4, + 6.81250647176057e-4, + 0.070623591542244, + -5.55392180103809e-4, + 0.00196365104056895, + -0.00189403316471726, + 2.47496318479534e-5, + -2.33925493375864e-5, + 8.39190033730119e-5, + 1.84656732017174e-4, + -5.43450478289742e-5, + 0.00324276322498918 + ] + }, + "fFlag": -1, + "fChi2": 0.01600785, + "fNDF": 3, + "fB": 0, + "fLength": 76.87881, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 37, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.150820776820183, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0865775346755981, + "fY": 1.03615427017212, + "fZ": 0.446708500385284, + "fTx": 0.490233063697815, + "fTy": -0.271417737007141, + "fQp": 1.6378653049469, + "fCovMatrix": [ + 0.00971092842519283, + -0.00865449476987123, + -8.71058786287904e-4, + 2.03632385819219e-4, + 0.00204137898981571, + 0.406613826751709, + 1.50130203110166e-4, + -0.00797386933118105, + -8.66855261847377e-4, + 1.02072430308908e-4, + -9.47271746554179e-6, + -1.61702104378492e-4, + 2.30386460316367e-4, + 3.07723848891328e-6, + 0.00214667920954525 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 40.114372253418, + "fY": -17.2033081054688, + "fZ": 60.9249992370605, + "fTx": 0.89084392786026, + "fTy": -0.348761737346649, + "fQp": 1.6664445400238, + "fCovMatrix": [ + 0.00244997604750097, + -0.0090667437762022, + 1.51414395077154e-4, + -2.62064364505932e-4, + 7.42975214961916e-4, + 0.0705385282635689, + -5.31124067492783e-4, + 0.00194119138177484, + -0.002225091913715, + 1.75859604496509e-5, + -1.97827012016205e-5, + 6.81519377394579e-5, + 1.69458886375651e-4, + -5.7736957387533e-5, + 0.00198274431750178 + ] + }, + "fFlag": -1, + "fChi2": 0.1320775, + "fNDF": 3, + "fB": 0, + "fLength": 76.24169, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 38, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.622270882129669, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -30.9979572296143, + "fY": 4.43448543548584, + "fZ": 0.446708500385284, + "fTx": 0.0402201563119888, + "fTy": 0.0601904541254044, + "fQp": 1.87127530574799, + "fCovMatrix": [ + 1.32694137096405, + -0.106557555496693, + -0.0177334845066071, + 8.25475435703993e-4, + 0.00908469036221504, + 1.40546059608459, + 0.0013534432509914, + -0.0161437466740608, + -0.00204152660444379, + 2.49203236307949e-4, + -1.15576422103914e-5, + -1.53714412590489e-4, + 2.04331721761264e-4, + 1.62767955771415e-5, + 5.45246468391269e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 86.7152557373047, + "fY": 17.499963760376, + "fZ": 190.85400390625, + "fTx": 1.84347748756409, + "fTy": 0.138669148087502, + "fQp": 1.97133362293243, + "fCovMatrix": [ + 0.00211035180836916, + 0.00650257663801312, + 1.25869875773787e-4, + 1.28308791317977e-4, + 1.88947567949072e-4, + 0.05129624158144, + 5.15072897542268e-4, + 9.42497921641916e-4, + 7.66049546655267e-4, + 4.11660621466581e-5, + 9.57041356741684e-6, + 5.5888343922561e-5, + 3.89481283491477e-5, + 1.91698745766189e-5, + 3.72251815861091e-4 + ] + }, + "fFlag": -1, + "fChi2": 5.015832, + "fNDF": 3, + "fB": 0, + "fLength": 241.3628, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 39, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 31.2234497070312, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.142423272132874, + "fY": 0.623891711235046, + "fZ": 0.446708500385284, + "fTx": -0.0736589878797531, + "fTy": 0.298795640468597, + "fQp": 2.80417394638062, + "fCovMatrix": [ + 0.0445475578308105, + 0.0275441370904446, + -0.00331222778186202, + -6.77968375384808e-4, + 0.00995489209890366, + 1.3541864156723, + -6.81058096233755e-4, + -0.0393065959215164, + 0.0296369660645723, + 3.44947155099362e-4, + 1.09068150777603e-5, + -6.63490616716444e-4, + 0.00142230000346899, + -8.73721961397678e-4, + 0.0108823031187057 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 3.45915913581848, + "fY": 14.4354619979858, + "fZ": 46.7879981994629, + "fTx": 0.234864756464958, + "fTy": 0.301912605762482, + "fQp": 2.95631885528564, + "fCovMatrix": [ + 3.31636285409331e-4, + 0.00638530729338527, + 3.2258660212392e-5, + 3.13805445330217e-4, + 3.01188760204241e-4, + 0.292764902114868, + 3.11581214191392e-4, + 0.0143494522199035, + -0.0112698068842292, + 1.21231414595968e-5, + 2.43910999415675e-5, + 2.18840417801403e-4, + 0.0011020228266716, + -8.5128570208326e-4, + 0.0106315473094583 + ] + }, + "fFlag": -1, + "fChi2": 7.60299, + "fNDF": 3, + "fB": 0, + "fLength": 48.78945, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 40, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.264814794063568, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 8.30461597442627, + "fY": -5.9334716796875, + "fZ": 0.446708500385284, + "fTx": -0.265362769365311, + "fTy": 0.0571171008050442, + "fQp": 1.03822529315948, + "fCovMatrix": [ + 5.15337038040161, + -0.00919716153293848, + -0.0533259771764278, + 7.47839163523167e-4, + 0.029088081791997, + 4.7500114440918, + 8.3266239380464e-4, + -0.0450916662812233, + 3.28805443132296e-4, + 5.94176410231739e-4, + -1.50604137161281e-5, + -3.8828028482385e-4, + 4.67599922558293e-4, + 8.13724273029948e-6, + 0.00107832241337746 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 26.9697799682617, + "fY": 8.39235782623291, + "fZ": 253.266006469727, + "fTx": 0.444779872894287, + "fTy": 0.0642979964613914, + "fQp": 1.18556535243988, + "fCovMatrix": [ + 0.00186509417835623, + 0.00526912836357951, + 8.09190751169808e-5, + 6.40154685243033e-5, + 3.54248360963538e-4, + 0.0448441095650196, + 3.1117265461944e-4, + 5.57739695068449e-4, + 0.0013737817062065, + 9.65948038356146e-6, + 1.98274415197375e-6, + 5.237402729108e-5, + 2.17948781937594e-5, + 2.6742793579615e-6, + 0.00105986534617841 + ] + }, + "fFlag": -1, + "fChi2": 9.604467, + "fNDF": 3, + "fB": 0, + "fLength": 259.5284, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 41, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 10.4857606887817, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -8.67306518554688, + "fY": -0.893381178379059, + "fZ": 0.446708500385284, + "fTx": -0.244425937533379, + "fTy": 0.0710715800523758, + "fQp": 1.46282720565796, + "fCovMatrix": [ + 1.94970905780792, + 0.0666303187608719, + -0.0393972508609295, + 4.9722200492397e-4, + 0.0140476133674383, + 1.89005267620087, + 1.53647080878727e-4, + -0.0352988466620445, + 7.02263845596462e-4, + 0.00511521846055984, + -9.02606479940005e-5, + -1.82768955710344e-4, + 0.00483105797320604, + 3.06898095914221e-6, + 5.15780760906637e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 74.2952423095703, + "fY": 17.0499019622803, + "fZ": 253.266006469727, + "fTx": 1.15265381336212, + "fTy": 0.0914041697978973, + "fQp": 1.72471988201141, + "fCovMatrix": [ + 0.00201824493706226, + 0.00598255405202508, + 1.08104322862346e-4, + 8.26826799311675e-5, + 2.03509247512557e-4, + 0.0480972304940224, + 4.38924587797374e-4, + 6.5469037508592e-4, + 7.57522066123784e-4, + 2.06035074370448e-5, + 4.59917828266043e-6, + 1.97731387743261e-5, + 3.33881689584814e-5, + 9.54037204792257e-8, + 4.49782353825867e-4 + ] + }, + "fFlag": -1, + "fChi2": 28.50264, + "fNDF": 3, + "fB": 0, + "fLength": 284.762, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 42, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 8.74019145965576, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + } + ] +] diff --git a/demo/playground/src/jvmMain/resources/root/event_1.json b/demo/playground/src/jvmMain/resources/root/event_1.json new file mode 100644 index 00000000..ca057754 --- /dev/null +++ b/demo/playground/src/jvmMain/resources/root/event_1.json @@ -0,0 +1,215 @@ +[ +[{ + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 2112745000, + "fStsHits" : [216, 221, 5, 50, 63, 82, 133], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.79052305221558, + "fY" : 8.83165168762207, + "fZ" : 36.5065002441406, + "fTx" : -0.11185921728611, + "fTy" : 0.228091076016426, + "fQp" : 0.893607378005981, + "fCovMatrix" : [1.68777798535302e-4, -9.69577522482723e-4, -1.07744517663377e-5, 1.2614247680176e-5, 2.87587154161884e-5, 0.0403835587203503, 5.90448107686825e-5, -5.16064348630607e-4, -2.05383723368868e-4, 2.20405854634009e-6, -8.30146461794357e-7, -5.49759215573431e-6, 1.16227884063846e-5, 3.6013934732182e-6, 1.46196922287345e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.67626953125, + "fY" : 43.7959594726562, + "fZ" : 190.759826660156, + "fTx" : 0.240885242819786, + "fTy" : 0.230351597070694, + "fQp" : 0.896391570568085, + "fCovMatrix" : [0.00152156152762473, 0.00325645040720701, 4.73157851956785e-5, 4.51812447863631e-5, 1.32256536744535e-4, 0.0311740729957819, 1.29416745039634e-4, 3.94528120523319e-4, 3.28425812767819e-4, 3.75195077140233e-6, 1.75166894678114e-6, 9.62230569712119e-6, 9.89728778222343e-6, 4.38717188444571e-6, 1.46559861605056e-4] + }, + "fFlag" : 0, + "fChi2" : 3.59655165672302, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [79, 108, 136, 160], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 7.56474113464355, + "fY" : -6.31765508651733, + "fZ" : 123.474571228027, + "fTx" : 0.198165953159332, + "fTy" : -0.0599287338554859, + "fQp" : 0.826108694076538, + "fCovMatrix" : [0.00192060391418636, -0.00543995574116707, -7.47249359847046e-5, 9.40304598771036e-5, 4.32362634455785e-4, 0.0452092550694942, 2.69763870164752e-4, -7.19496863894165e-4, -0.00178805936593562, 5.47440777154407e-6, -4.97666542287334e-6, -3.32396593876183e-5, 1.67156704264926e-5, 3.69572808267549e-5, 3.62657097866759e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 38.4175720214844, + "fY" : -12.5351896286011, + "fZ" : 222.266052246094, + "fTx" : 0.428264498710632, + "fTy" : -0.0652719661593437, + "fQp" : 0.827384233474731, + "fCovMatrix" : [0.00191446917597204, 0.00539331184700131, 7.50113686081022e-5, 9.10265880520456e-5, 4.29905543569475e-4, 0.0449054278433323, 2.68147414317355e-4, 7.0479983696714e-4, 0.00177141127642244, 5.60895068701939e-6, 4.76898094348144e-6, 3.39166836056393e-5, 1.61108710017288e-5, 3.51894050254487e-5, 3.57192009687424e-4] + }, + "fFlag" : 0, + "fChi2" : 0.0889237225055695, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}] +, +[{ + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.514997541904449, + "fY" : 0.614071667194366, + "fZ" : 0.716018855571747, + "fTx" : -0.182437181472778, + "fTy" : 0.231170654296875, + "fQp" : 0.890645802021027, + "fCovMatrix" : [0.00640107085928321, -0.00549036636948586, -2.40077963098884e-4, 5.9050194977317e-5, 4.4034980237484e-4, 0.0939982086420059, 1.37060953420587e-4, -0.0010447750100866, -3.45796346664429e-4, 1.4494138667942e-5, -1.88720639471285e-6, -1.71545361808967e-5, 2.24065261136275e-5, 4.27886925535859e-6, 1.46344274980947e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.67626953125, + "fY" : 43.7959594726562, + "fZ" : 190.759826660156, + "fTx" : 0.240885242819786, + "fTy" : 0.230351597070694, + "fQp" : 0.896391570568085, + "fCovMatrix" : [0.00152156152762473, 0.00325645040720701, 4.73157851956785e-5, 4.51812447863631e-5, 1.32256536744535e-4, 0.0311740729957819, 1.29416745039634e-4, 3.94528120523319e-4, 3.28425812767819e-4, 3.75195077140233e-6, 1.75166894678114e-6, 9.62230569712119e-6, 9.89728778222343e-6, 4.38717188444571e-6, 1.46559861605056e-4] + }, + "fFlag" : -1, + "fChi2" : 3.596552, + "fNDF" : 9, + "fB" : 0, + "fLength" : 196.4224, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 0, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.169359803199768, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.30332088470459, + "fY" : 0.709633886814117, + "fZ" : 0.716018855571747, + "fTx" : -0.0394387505948544, + "fTy" : -0.0554707236588001, + "fQp" : 0.794627845287323, + "fCovMatrix" : [1.0362377166748, -0.242409482598305, -0.0120293609797955, 0.00132000644225627, 0.0113498065620661, 1.10034370422363, 0.0026963478885591, -0.0100266374647617, -0.00638964772224426, 1.71858730027452e-4, -1.46718830364989e-5, -1.39145020511933e-4, 1.31993641844019e-4, 3.72123940906022e-5, 3.64089268259704e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 153.443832397461, + "fY" : -27.7408638000488, + "fZ" : 422.371002197266, + "fTx" : 0.623147189617157, + "fTy" : -0.0757252722978592, + "fQp" : 0.879441320896149, + "fCovMatrix" : [0.210621446371078, 0.00677151698619127, 0.00126052019186318, -1.89192069228739e-5, 0.00233594398014247, 0.117487587034702, 1.90632126759738e-5, 5.61361608561128e-4, 3.66047053830698e-4, 5.4321233619703e-5, -1.38209452416049e-6, 1.40239317261148e-5, 3.86252722819336e-5, -2.07852266953523e-7, 1.6525064711459e-4] + }, + "fFlag" : -1, + "fChi2" : 28.54445, + "fNDF" : 3, + "fB" : 0, + "fLength" : 456.7299, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 1, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : 0, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : 0.813491527513362, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.82100653648376, + "fPidTof400" : [0.698706510566553, 0.0456706934329348, 0.070160747316434, 0.044178479600919, 0.0321317585690916, 0.0203602877603981, 0.0563498151154308, 0.0324417076382387], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}] +] diff --git a/demo/playground/src/jvmMain/resources/root/event_2.json b/demo/playground/src/jvmMain/resources/root/event_2.json new file mode 100644 index 00000000..22e6c5f8 --- /dev/null +++ b/demo/playground/src/jvmMain/resources/root/event_2.json @@ -0,0 +1,5150 @@ +[ +[{ + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1682, 1766, 1829, 464, 768, 972, 1137, 1393], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.63523077964783, + "fY" : -1.11952388286591, + "fZ" : 24.867000579834, + "fTx" : -0.166404068470001, + "fTy" : -0.0722663849592209, + "fQp" : -0.659868478775024, + "fCovMatrix" : [1.58311304403469e-4, 0.00105864810757339, -8.34709226182895e-6, -1.12343277578475e-5, 2.62966495938599e-5, 0.041155993938446, -4.28007515438367e-5, -4.41101816250011e-4, 2.18053421122022e-4, 1.02060232620715e-6, 4.78974982343061e-7, -3.52032748196507e-6, 7.39310189601383e-6, -2.87856505565287e-6, 7.60013062972575e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -53.3829460144043, + "fY" : -13.1547222137451, + "fZ" : 185.683853149414, + "fTx" : -0.468784332275391, + "fTy" : -0.0797551199793816, + "fQp" : -0.660838067531586, + "fCovMatrix" : [0.00121652521193027, -0.00194779026787728, 3.82801008527167e-5, -2.38575230468996e-5, 1.03297272289637e-4, 0.0245428644120693, -8.60174477566034e-5, 2.80060805380344e-4, -2.55426042713225e-4, 3.07012169287191e-6, -9.24756022868678e-7, 7.38780818210216e-6, 6.4618020587659e-6, -2.95916311188194e-6, 7.52489650039934e-5] + }, + "fFlag" : 0, + "fChi2" : 0.682691812515259, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1763, 1827, 467, 767, 973, 1153, 1413, 1483], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -5.50913715362549, + "fY" : -1.61793780326843, + "fZ" : 33.2939987182617, + "fTx" : -0.153988212347031, + "fTy" : -0.0633151158690453, + "fQp" : 0.356036454439163, + "fCovMatrix" : [1.35921887704171e-4, 5.25149109307677e-4, -5.04478293805732e-6, -4.25407552029355e-6, 1.32292962007341e-5, 0.028402591124177, -1.43782526720315e-5, -2.4180811305996e-4, -1.33881485453458e-5, 6.79417325955001e-7, 8.60398827740028e-8, -1.90996661331155e-6, 3.24026382259035e-6, 5.01784484185919e-7, 2.29810775635997e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -18.7020149230957, + "fY" : -13.5386352539062, + "fZ" : 221.990875244141, + "fTx" : 0.0132204964756966, + "fTy" : -0.0631681606173515, + "fQp" : 0.356655418872833, + "fCovMatrix" : [0.0011939414544031, 0.0018086233176291, 2.46283125306945e-5, 1.62282540259184e-5, 6.86891944496892e-5, 0.0225373078137636, 4.09956592193339e-5, 1.98697045561858e-4, 1.08902706415392e-4, 9.78696903075615e-7, 3.44910347394034e-7, 2.85334499494638e-6, 2.87495959128137e-6, 8.18456555862213e-7, 2.30724126595305e-5] + }, + "fFlag" : 0, + "fChi2" : 1.9497594833374, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -1737188256, + "fStsHits" : [183, 630, 804, 993, 1315, 1437, 1504], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.96963500976562, + "fY" : 3.22212386131287, + "fZ" : 65.8386535644531, + "fTx" : 0.120770797133446, + "fTy" : 0.0367443077266216, + "fQp" : 0.182414337992668, + "fCovMatrix" : [0.00101125857327133, 0.00100853201001883, -2.16253556573065e-5, -7.20290472600027e-6, 6.52337694191374e-5, 0.0182508211582899, -2.26020365516888e-5, -1.44205492688343e-4, 4.419145261636e-5, 9.44088810683752e-7, 1.08565920697856e-7, -2.68945814241306e-6, 1.99062742467504e-6, 1.17405193122977e-7, 1.55548805196304e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 37.679759979248, + "fY" : 10.0525703430176, + "fZ" : 253.266006469727, + "fTx" : 0.203942775726318, + "fTy" : 0.0364765599370003, + "fQp" : 0.182578787207603, + "fCovMatrix" : [0.0011457153595984, 0.00149737962055951, 2.23015576921171e-5, 1.09393286038539e-5, 7.10815002094023e-5, 0.0201594308018684, 2.97546375804814e-5, 1.54651876073331e-4, 7.5706047937274e-5, 7.75048363266251e-7, 1.82903008294488e-7, 2.54641827268642e-6, 1.86880970431957e-6, 2.43735712501802e-7, 1.55496582010528e-5] + }, + "fFlag" : 0, + "fChi2" : 2.22132515907288, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 1601148318, + "fStsHits" : [1718, 1796, 211, 693, 818, 1020, 1326], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -5.71760082244873, + "fY" : 0.689112067222595, + "fZ" : 36.5065002441406, + "fTx" : -0.151977360248566, + "fTy" : 0.00709940027445555, + "fQp" : 0.156383261084557, + "fCovMatrix" : [1.44718200317584e-4, -7.90981808677316e-4, -5.82021084483131e-6, 8.37171864986885e-6, 2.73877376457676e-5, 0.0344392620027065, 4.076426193933e-5, -3.35155404172838e-4, -2.47787014814094e-4, 6.88013926719577e-7, -5.29977342011989e-7, -3.60629746865015e-6, 4.35047195423977e-6, 3.54779081135348e-6, 3.01437412417727e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -24.49658203125, + "fY" : 1.74604022502899, + "fZ" : 190.759826660156, + "fTx" : -0.0914124399423599, + "fTy" : 0.00656518992036581, + "fQp" : 0.156333759427071, + "fCovMatrix" : [0.00133210537023842, 0.00254281889647245, 3.07717891701031e-5, 2.77981016552076e-5, 1.17731280624866e-4, 0.027555949985981, 6.91556560923345e-5, 2.83489149296656e-4, 2.94191704597324e-4, 1.14010765628336e-6, 7.86034036082128e-7, 5.11840653416584e-6, 4.08969299314776e-6, 3.48841217601148e-6, 3.02118824038189e-5] + }, + "fFlag" : 0, + "fChi2" : 2.61141204833984, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 1090165622, + "fStsHits" : [209, 694, 811, 1010, 1317, 1455, 1505], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -17.8449935913086, + "fY" : 9.73141670227051, + "fZ" : 65.8457717895508, + "fTx" : -0.215278327465057, + "fTy" : 0.148166984319687, + "fQp" : 0.661383807659149, + "fCovMatrix" : [0.00113124051131308, 0.00145179522223771, -3.19208447763231e-5, -1.5488221833948e-5, 8.24654853204265e-5, 0.0208098106086254, -5.58063184143975e-5, -2.12456070585176e-4, 1.1660285963444e-4, 2.40666872741713e-6, 4.76995353437815e-7, -5.59231239094515e-6, 5.07825825479813e-6, -6.84226563407719e-7, 6.93799593136646e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -28.8700866699219, + "fY" : 36.6349716186523, + "fZ" : 253.266006469727, + "fTx" : 0.0915517956018448, + "fTy" : 0.13888768851757, + "fQp" : 0.663964629173279, + "fCovMatrix" : [0.0013174363411963, 0.00216729799285531, 3.46993256243877e-5, 2.37835829466349e-5, 7.89249243098311e-5, 0.0238640792667866, 7.23723351256922e-5, 2.47721880441532e-4, 9.2910930106882e-5, 2.31840249398374e-6, 7.41987889796292e-7, 4.51600999440416e-6, 5.64657284485293e-6, 3.95186390278468e-7, 6.98939329595305e-5] + }, + "fFlag" : 0, + "fChi2" : 5.7842812538147, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -1550214659, + "fStsHits" : [1678, 1770, 1832, 468, 724, 968, 1126], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.61242008209229, + "fY" : -5.50625228881836, + "fZ" : 24.867000579834, + "fTx" : -0.153559222817421, + "fTy" : -0.204351961612701, + "fQp" : 0.915053844451904, + "fCovMatrix" : [1.71674299053848e-4, 0.00124005193356425, -9.80737422651146e-6, -1.48666276800213e-5, 2.9903852919233e-5, 0.0517979934811592, -3.81923309760168e-5, -6.50938018225133e-4, -1.95993605302647e-4, 1.43080853831634e-6, 4.31599147532324e-7, -6.17102477917797e-6, 1.24674479593523e-5, 4.02873274651938e-6, 1.74217610037886e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.8365318775177, + "fY" : -32.9046325683594, + "fZ" : 159.629043579102, + "fTx" : 0.167047187685966, + "fTy" : -0.20632404088974, + "fQp" : 0.914145052433014, + "fCovMatrix" : [0.00155416806228459, 0.00351027329452336, 4.78662987006828e-5, 4.80297567264643e-5, 1.67868478456512e-4, 0.034046433866024, 1.29982028738596e-4, 4.5236645382829e-4, 4.79995826026425e-4, 3.62696550837427e-6, 1.50596133607905e-6, 1.30671187434928e-5, 1.08145477497601e-5, 5.51082939637126e-6, 1.74894215888344e-4] + }, + "fFlag" : 0, + "fChi2" : 62.482234954834, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509938528, + "fStsHits" : [1636, 1707, 1794, 685, 814, 1008, 1321, 1454, 1506], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.70249974727631, + "fY" : 4.77476358413696, + "fZ" : 28.9860000610352, + "fTx" : -0.0554607696831226, + "fTy" : 0.148796871304512, + "fQp" : 0.119566723704338, + "fCovMatrix" : [9.98170871753246e-5, 3.74785478925332e-4, -3.02104444926954e-6, -2.04468597075902e-6, 9.24034793570172e-6, 0.0330311395227909, -1.56929090735503e-5, -2.07925797440112e-4, 3.61919737770222e-5, 2.56948766264031e-7, 5.6199063180884e-8, -8.75137914135848e-7, 1.69477459621703e-6, 1.6178902662034e-9, 5.08493167217239e-6] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.76850318908691, + "fY" : 38.0125923156738, + "fZ" : 253.266006469727, + "fTx" : 0.00997702591121197, + "fTy" : 0.147619038820267, + "fQp" : 0.119642995297909, + "fCovMatrix" : [0.00100874423515052, 0.00117198028601706, 1.63884978974238e-5, 7.29519751985208e-6, 4.17295595980249e-5, 0.0191394723951817, 1.79422495421022e-5, 1.43677883897908e-4, 3.47817585861776e-5, 4.42629755070811e-7, 7.17247630177553e-8, 1.18746982025186e-6, 1.66530287515343e-6, -7.33179161827024e-9, 5.09104575030506e-6] + }, + "fFlag" : 0, + "fChi2" : 3.65150594711304, + "fNDF" : 13, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1593, 1644, 1720, 1797, 212, 690, 812, 1009], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.09095358848572, + "fY" : 2.90811204910278, + "fZ" : 19.0084991455078, + "fTx" : -0.153810381889343, + "fTy" : 0.128865405917168, + "fQp" : 0.528272271156311, + "fCovMatrix" : [1.57698406837881e-4, -0.00116014084778726, -7.51515744923381e-6, 1.18563257274218e-5, 3.05232642858755e-5, 0.051769096404314, 1.7445650883019e-5, -5.60092157684267e-4, 1.36088274302892e-4, 8.43438726860768e-7, -1.54633866600307e-7, -3.94911512557883e-6, 8.30690532893641e-6, -2.50242283073021e-6, 8.02850117906928e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -12.1900281906128, + "fY" : 20.1586036682129, + "fZ" : 154.893341064453, + "fTx" : 0.0223866682499647, + "fTy" : 0.125468313694, + "fQp" : 0.52903938293457, + "fCovMatrix" : [0.00118864618707448, -0.00201725121587515, 3.29115355270915e-5, -2.80263557215221e-5, 1.24523183330894e-4, 0.0269913990050554, -7.08940933691338e-5, 3.47086053807288e-4, -2.71533383056521e-4, 2.06066397367977e-6, -9.20225318168377e-7, 7.71232225815766e-6, 7.54866641727858e-6, -3.4717002108664e-6, 8.07631731731817e-5] + }, + "fFlag" : 0, + "fChi2" : 0.560838520526886, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1672, 1775, 1838, 461, 770, 1155, 1411, 1485], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.87697601318359, + "fY" : 0.080434538424015, + "fZ" : 24.867000579834, + "fTx" : -0.262285262346268, + "fTy" : -0.0302867814898491, + "fQp" : 0.574987947940826, + "fCovMatrix" : [1.61355375894345e-4, 0.00101068778894842, -9.4217311925604e-6, -1.12355837700306e-5, 3.08064340970304e-6, 0.0403573177754879, -3.77155956812203e-5, -4.77352383313701e-4, -1.23886769870296e-4, 1.20324261843052e-6, 4.16166756167513e-7, -1.4757878261662e-6, 1.14798785944004e-5, 6.69174198719702e-7, 7.2559661930427e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -30.0807361602783, + "fY" : -5.78548860549927, + "fZ" : 221.928085327148, + "fTx" : 0.0210418067872524, + "fTy" : -0.0293070133775473, + "fQp" : 0.576870679855347, + "fCovMatrix" : [0.00132818543352187, 0.00221483828499913, 3.30795446643606e-5, 2.5192939574481e-5, 1.05427883681841e-4, 0.0246683564037085, 6.37786215520464e-5, 2.38898894167505e-4, 2.15005653444678e-4, 1.80109100256232e-6, 7.71973873270326e-7, 6.46460057396325e-6, 4.64114327769494e-6, 2.72861416306114e-6, 7.34642962925136e-5] + }, + "fFlag" : 0, + "fChi2" : 1.21061491966248, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1589, 1637, 1706, 1795, 246, 817, 1005, 1323], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.25973784923553, + "fY" : 4.75281524658203, + "fZ" : 20.1884994506836, + "fTx" : -0.0586002320051193, + "fTy" : 0.207550808787346, + "fQp" : 0.285871863365173, + "fCovMatrix" : [1.29143983940594e-4, 6.2837143195793e-4, -5.66779226573999e-6, -4.78541460324777e-6, 2.199209848186e-5, 0.0403592400252819, -4.04380534746451e-6, -3.29683098243549e-4, -4.71849853056483e-5, 4.89187698349269e-7, 8.88997586656615e-9, -2.14619285543449e-6, 3.7864051591896e-6, 8.07122034984786e-7, 2.28951030294411e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.11983871459961, + "fY" : 39.9874572753906, + "fZ" : 190.759826660156, + "fTx" : 0.0620537921786308, + "fTy" : 0.206056728959084, + "fQp" : 0.286139667034149, + "fCovMatrix" : [0.00119367893785238, 0.00193155149463564, 2.52228346653283e-5, 1.92373408935964e-5, 7.64093638281338e-5, 0.0246099624782801, 4.20779288106132e-5, 2.31990285101347e-4, 1.01877601991873e-4, 1.02140506896831e-6, 4.58338035969064e-7, 3.38780637321179e-6, 3.69359349861043e-6, 9.96966150523804e-7, 2.29560191655764e-5] + }, + "fFlag" : 0, + "fChi2" : 1.32319784164429, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1768, 1831, 471, 766, 974, 1414, 1480, 1578], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.36828136444092, + "fY" : -0.453498303890228, + "fZ" : 33.2939987182617, + "fTx" : -0.0959276705980301, + "fTy" : -0.0285605732351542, + "fQp" : 0.165866121649742, + "fCovMatrix" : [1.36803573695943e-4, 5.3773820400238e-4, -5.17474018124631e-6, -3.6998362702434e-6, 9.60905708780047e-6, 0.0247320514172316, -2.49111944867764e-5, -1.74587636138313e-4, 7.60740076657385e-5, 6.40066389223648e-7, 1.60146484518009e-7, -8.24300684598711e-7, 2.28267299462459e-6, -5.28317059433903e-7, 8.68895767780486e-6] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -14.5694913864136, + "fY" : -6.65738916397095, + "fZ" : 248.485992431641, + "fTx" : -0.0104469852522016, + "fTy" : -0.029131792485714, + "fQp" : 0.166121900081635, + "fCovMatrix" : [9.30208479985595e-4, -0.00101866282057017, 1.61596672114683e-5, -8.17098771221936e-6, 4.52994027000386e-5, 0.0186960771679878, -1.66406480275327e-5, 1.3092921290081e-4, -4.22760458604898e-5, 5.84355689170479e-7, -1.87937203577349e-7, 1.65296296472661e-6, 1.55595296291722e-6, -5.9433574506329e-7, 8.71440352057107e-6] + }, + "fFlag" : 0, + "fChi2" : 1.48762679100037, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1601, 1655, 1736, 1809, 699, 836, 1038, 1345], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 3.85181069374084, + "fY" : -2.45643901824951, + "fZ" : 15.9584999084473, + "fTx" : 0.241178929805756, + "fTy" : -0.163667619228363, + "fQp" : 0.25532478094101, + "fCovMatrix" : [1.48446240928024e-4, -0.00158200669102371, -5.49221476831008e-6, 1.17448435048573e-5, 1.96525179489981e-5, 0.0678103491663933, 2.29246252274606e-5, -5.2765931468457e-4, -2.77748713415349e-5, 4.39525621231951e-7, -1.38289337314745e-7, -1.79930907506787e-6, 4.96373559144558e-6, -6.69981119472141e-8, 1.58070597535698e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 55.0374336242676, + "fY" : -31.1423664093018, + "fZ" : 186.27587890625, + "fTx" : 0.366489827632904, + "fTy" : -0.175483256578445, + "fQp" : 0.255306541919708, + "fCovMatrix" : [0.00105818000156432, -0.00150494289118797, 2.36668620345881e-5, -1.8978571461048e-5, 6.11486830166541e-5, 0.023076020181179, -3.95588904211763e-5, 2.58579704677686e-4, -8.41691216919571e-5, 1.04949799606402e-6, -4.62299027503832e-7, 2.83598228634219e-6, 4.9294499149255e-6, -7.70337180711067e-7, 1.57309768837877e-5] + }, + "fFlag" : 0, + "fChi2" : 5.11094665527344, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1616, 1695, 1773, 460, 771, 969, 1154, 1412], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.44671630859375, + "fY" : -1.43176901340485, + "fZ" : 16.1784992218018, + "fTx" : -0.372697472572327, + "fTy" : -0.0688439831137657, + "fQp" : 1.17891657352448, + "fCovMatrix" : [1.88983511179686e-4, 0.0015832909848541, -1.23509471450234e-5, -2.19342946365941e-5, 1.75969016709132e-5, 0.0622915513813496, -5.95990131841972e-5, -9.39551973715425e-4, 2.01952090719715e-4, 2.23867687054735e-6, 8.13113956610323e-7, -5.18520164405345e-6, 2.46821564360289e-5, -3.19497144118941e-6, 2.40546825807542e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -26.1258335113525, + "fY" : -11.6612462997437, + "fZ" : 185.833938598633, + "fTx" : 0.142297178506851, + "fTy" : -0.054171446710825, + "fQp" : 1.1889933347702, + "fCovMatrix" : [0.00134163885377347, -0.00245691742748022, 5.10454046889208e-5, -3.7505309592234e-5, 1.53668865095824e-4, 0.0273020192980766, -1.37132912641391e-4, 3.72970214812085e-4, -3.93421592889354e-4, 5.40775272384053e-6, -1.81297491508303e-6, 1.40981837830623e-5, 1.20690865514916e-5, -4.63336573375273e-6, 2.43694987148046e-4] + }, + "fFlag" : 0, + "fChi2" : 24.6987056732178, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [1656, 1737, 1815, 308, 704, 833, 1343], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.57648801803589, + "fY" : -3.68273878097534, + "fZ" : 24.511999130249, + "fTx" : 0.195369839668274, + "fTy" : -0.178091257810593, + "fQp" : 0.371276766061783, + "fCovMatrix" : [1.40133095555939e-4, -9.54277405980974e-4, -5.58432475372683e-6, 9.50169487623498e-6, 1.68482984008733e-5, 0.0459047444164753, -6.16809393250151e-6, -4.74974774988368e-4, 1.03478741948493e-4, 6.33763249879848e-7, 7.57914335736132e-8, -2.27954933507135e-6, 6.80246739648283e-6, -1.7073256231015e-6, 2.84394482150674e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 49.4424476623535, + "fY" : -33.5017509460449, + "fZ" : 186.244964599609, + "fTx" : 0.368892908096313, + "fTy" : -0.193302035331726, + "fQp" : 0.372141301631927, + "fCovMatrix" : [0.00215255655348301, -0.00685461703687906, 3.92403235309757e-5, -6.76833660691045e-5, 9.6430660050828e-5, 0.0515968352556229, -1.1207955685677e-4, 5.03702322021127e-4, -2.41851797909476e-4, 1.51022993577499e-6, -1.23772463211935e-6, 4.18293348047882e-6, 6.72852365823928e-6, -2.80614221992437e-6, 2.82885594060645e-5] + }, + "fFlag" : 0, + "fChi2" : 0.71911495923996, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [1582, 1627, 1700, 1786, 190, 566, 797], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.91899347305298, + "fY" : 2.11925148963928, + "fZ" : 18.9384994506836, + "fTx" : 0.282313615083694, + "fTy" : 0.0963860377669334, + "fQp" : 1.24172008037567, + "fCovMatrix" : [1.8620268383529e-4, 0.00177033746149391, -1.06157103800797e-5, -2.47538027906558e-5, 4.88820041937288e-5, 0.0877573862671852, -1.10954943011166e-5, -0.00125766696874052, -1.21624769235495e-4, 2.3399172732752e-6, 1.71174647789485e-7, -1.06720299299923e-5, 2.53151047218125e-5, 6.96951656209421e-6, 3.55073425453156e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 58.0685119628906, + "fY" : 13.1218519210815, + "fZ" : 128.266860961914, + "fTx" : 0.735637307167053, + "fTy" : 0.110303997993469, + "fQp" : 1.2478494644165, + "fCovMatrix" : [0.00186582887545228, 0.00535924965515733, 7.37560476409271e-5, 9.87442472251132e-5, 2.09176956559531e-4, 0.0458656288683414, 2.62276356806979e-4, 7.90530757512897e-4, 7.02802964951843e-4, 8.63070454215631e-6, 4.20958849645103e-6, 2.75256006716518e-5, 2.33199843933107e-5, 9.57082284003263e-6, 3.41619132086635e-4] + }, + "fFlag" : 0, + "fChi2" : 2.624995470047, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [1581, 1624, 1699, 1779, 192, 801, 979], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 7.30123615264893, + "fY" : 3.61234211921692, + "fZ" : 18.9384994506836, + "fTx" : 0.400299787521362, + "fTy" : 0.171811938285828, + "fQp" : 0.586377561092377, + "fCovMatrix" : [1.71267107361928e-4, 0.00129874085541815, -8.0822110248846e-6, -1.52227730723098e-5, 3.39580110448878e-5, 0.0674368962645531, 3.79077096113178e-6, -6.51829701382667e-4, 5.75321028009057e-5, 9.65329036262119e-7, 3.30068502307768e-7, -4.19109483118518e-6, 9.42516362556489e-6, -3.72629028788651e-6, 6.94321570335887e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 79.3677291870117, + "fY" : 28.174129486084, + "fZ" : 154.960510253906, + "fTx" : 0.673740983009338, + "fTy" : 0.198277235031128, + "fQp" : 0.583659291267395, + "fCovMatrix" : [0.00126076629385352, -0.00243792682886124, 4.26691185566597e-5, -2.5351766453241e-5, 1.08721644210164e-4, 0.0306138880550861, -1.34073343360797e-4, 3.3120164880529e-4, -3.81166988518089e-4, 3.79051311938383e-6, -5.50403228771756e-7, 8.82440872373991e-6, 8.84583005245076e-6, -1.61029106493515e-6, 6.83862963342108e-5] + }, + "fFlag" : 0, + "fChi2" : 2.89603352546692, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [1693, 1777, 1839, 731, 956, 1142, 1389], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -14.4623870849609, + "fY" : -0.987330555915833, + "fZ" : 23.6770000457764, + "fTx" : -0.579053103923798, + "fTy" : -0.0570501871407032, + "fQp" : 0.863117575645447, + "fCovMatrix" : [1.97907516849227e-4, 0.00209042918868363, -1.04955170172616e-5, -2.81542670563795e-5, 2.24658724619076e-5, 0.101877294480801, -2.67292525677476e-5, -0.00128722749650478, 6.64381601382047e-4, 1.71738327026105e-6, 7.05982927229343e-7, -6.41472115603392e-6, 2.64421905740164e-5, -5.25053610545001e-6, 2.37592685152777e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -74.1618881225586, + "fY" : -8.63301086425781, + "fZ" : 185.569320678711, + "fTx" : -0.184854105114937, + "fTy" : -0.0359268859028816, + "fQp" : 0.860927820205688, + "fCovMatrix" : [0.00133630225900561, -0.00249010743573308, 4.98670633533038e-5, -3.79545454052277e-5, 1.97672576177865e-4, 0.0283685196191072, -1.33573688799515e-4, 3.96652292693034e-4, -5.11784397531301e-4, 4.70526947538019e-6, -1.85892827175849e-6, 1.6102258086903e-5, 1.1450300917204e-5, -7.41731901143794e-6, 2.47276970185339e-4] + }, + "fFlag" : 0, + "fChi2" : 8.69698905944824, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1605, 1662, 1753, 1819, 263, 705], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.962284207344055, + "fY" : -4.97440195083618, + "fZ" : 14.7185001373291, + "fTx" : 0.0764660537242889, + "fTy" : -0.379733800888062, + "fQp" : 0.857872784137726, + "fCovMatrix" : [2.0666402997449e-4, -0.00249408837407827, -1.17340641736519e-5, 4.41386764578056e-5, 1.09821899968665e-4, 0.116383440792561, 5.1216109568486e-5, -0.00188099266961217, -0.00108879338949919, 1.76009689312195e-6, -1.69761813140212e-6, -1.46356633194955e-5, 3.91918038076255e-5, 3.63967665180098e-5, 4.03767073294148e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 14.6517648696899, + "fY" : -36.9337005615234, + "fZ" : 97.2979049682617, + "fTx" : 0.267938584089279, + "fTy" : -0.39751985669136, + "fQp" : 0.858786880970001, + "fCovMatrix" : [0.0020041186362505, 0.0062880627810955, 7.17065486242063e-5, 1.29548876429908e-4, 4.24215395469218e-4, 0.0527210347354412, 2.48639262281358e-4, 0.00104399619158357, 0.00170484441332519, 5.03440105603659e-6, 3.60055105375068e-6, 3.17915582854766e-5, 3.6310881114332e-5, 2.93589273496764e-5, 4.00858378270641e-4] + }, + "fFlag" : 0, + "fChi2" : 0.89791738986969, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [721, 953, 1110, 1355, 1471, 1516], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.25988674163818, + "fY" : -6.55236673355103, + "fZ" : 97.2322540283203, + "fTx" : 0.112791605293751, + "fTy" : -0.0707813948392868, + "fQp" : 0.232450231909752, + "fCovMatrix" : [0.00117024907376617, 0.00171570701058954, -3.07101399812382e-5, -1.84520740731386e-5, 1.22394587378949e-4, 0.0223012287169695, -6.06233661528677e-5, -2.12679311516695e-4, 2.77405692031607e-4, 1.42863052587927e-6, 7.09916434971092e-7, -6.28078259978793e-6, 3.08710696117487e-6, -3.51495418726699e-6, 3.8643669540761e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 32.1994171142578, + "fY" : -17.4566535949707, + "fZ" : 248.743057250977, + "fTx" : 0.199927106499672, + "fTy" : -0.0728905349969864, + "fQp" : 0.232502847909927, + "fCovMatrix" : [0.00115935911890119, -0.0017235407140106, 2.88825049210573e-5, -1.94963467947673e-5, 1.19995631393977e-4, 0.0224260333925486, -5.84204062761273e-5, 2.16226137126796e-4, -2.78120045550168e-4, 1.31434103423089e-6, -7.26508289972116e-7, 5.67927645533928e-6, 3.21425773108786e-6, -3.81498466595076e-6, 3.85692983400077e-5] + }, + "fFlag" : 0, + "fChi2" : 0.997307777404785, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1666, 1746, 1823, 253, 710, 831], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.429752796888351, + "fY" : -5.56902074813843, + "fZ" : 23.511999130249, + "fTx" : 0.0281199067831039, + "fTy" : -0.262201458215714, + "fQp" : 0.450742155313492, + "fCovMatrix" : [1.71506268088706e-4, -0.00138802453875542, -9.07607409317279e-6, 1.67480648087803e-5, 5.69293915759772e-5, 0.0817670300602913, -4.9255042540608e-5, -0.00110312970355153, 7.15361966285855e-4, 1.35715686155891e-6, 8.7630496636848e-7, -1.01259338407544e-5, 1.81684117706027e-5, -1.32359300550888e-5, 1.45553101901896e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.8525915145874, + "fY" : -31.998348236084, + "fZ" : 123.511558532715, + "fTx" : 0.144777610898018, + "fTy" : -0.267102360725403, + "fQp" : 0.451087117195129, + "fCovMatrix" : [0.0014291099505499, -0.0032419697381556, 4.93956431455445e-5, -6.88998552504927e-5, 2.42930182139389e-4, 0.0350515246391296, -1.43318975460716e-4, 6.34233001619577e-4, -6.86827290337533e-4, 3.12987617689942e-6, -3.23209337693697e-6, 1.69907871168107e-5, 1.81877385330154e-5, -1.51279182318831e-5, 1.4542366261594e-4] + }, + "fFlag" : 0, + "fChi2" : 1.26801037788391, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1609, 1664, 1757, 1824, 447, 725], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.958474099636078, + "fY" : -4.00479793548584, + "fZ" : 14.7185001373291, + "fTx" : 0.0282110013067722, + "fTy" : -0.316333919763565, + "fQp" : -1.62459671497345, + "fCovMatrix" : [2.16376312891953e-4, -0.00255327112972736, -1.41942136906437e-5, 4.57001624454278e-5, 9.58225573413074e-5, 0.11887838691473, 5.26813673786819e-5, -0.00199402496218681, 1.80576505954377e-4, 3.50398408954788e-6, -1.71135047821735e-6, -2.37921722145984e-5, 4.77122339361813e-5, 1.63027780217817e-5, 0.00108523073140532] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.2619371414185, + "fY" : -30.3149681091309, + "fZ" : 97.207145690918, + "fTx" : -0.3241907954216, + "fTy" : -0.32882833480835, + "fQp" : -1.62593746185303, + "fCovMatrix" : [0.00208903150632977, 0.00674401968717575, 8.48563431645744e-5, 1.50043764733709e-4, 4.01053373934701e-4, 0.0551445372402668, 3.204517706763e-4, 0.00114413211122155, 0.00138048059307039, 1.01180758065311e-5, 5.6384528761555e-6, 6.00225175730884e-5, 4.38956740254071e-5, 1.84727196028689e-5, 0.00107722356915474] + }, + "fFlag" : 0, + "fChi2" : 2.50778245925903, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1657, 1743, 1816, 307, 701, 834], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.46813249588013, + "fY" : -4.90692043304443, + "fZ" : 24.511999130249, + "fTx" : 0.192595615983009, + "fTy" : -0.224652722477913, + "fQp" : 0.495586484670639, + "fCovMatrix" : [1.72917585587129e-4, -0.00137926626484841, -9.14703650778392e-6, 1.71005558513571e-5, 5.57157072762493e-5, 0.0805980414152145, -4.74049120384734e-5, -0.00109869404695928, 6.4483133610338e-4, 1.33415574055107e-6, 8.18372313915461e-7, -1.00341840152396e-5, 1.8302867829334e-5, -1.19414598884759e-5, 1.43495824886486e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 30.012149810791, + "fY" : -27.715295791626, + "fZ" : 123.628150939941, + "fTx" : 0.329684227705002, + "fTy" : -0.236884519457817, + "fQp" : 0.496926605701447, + "fCovMatrix" : [0.00145258323755115, -0.0033528795465827, 5.184545807424e-5, -7.23689227015711e-5, 2.35452040215023e-4, 0.0356061942875385, -1.54099107021466e-4, 6.50815549306571e-4, -6.81751174852252e-4, 3.47621858054481e-6, -3.51407697962713e-6, 1.70653893292183e-5, 1.8816896044882e-5, -1.5315948985517e-5, 1.42825228977017e-4] + }, + "fFlag" : 0, + "fChi2" : 5.73322486877441, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1604, 1662, 1754, 1820, 259, 707], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.00981318950653, + "fY" : -5.04285573959351, + "fZ" : 14.7185001373291, + "fTx" : 0.0774484053254128, + "fTy" : -0.38495859503746, + "fQp" : 0.491351902484894, + "fCovMatrix" : [2.02897266717628e-4, -0.00245960406027734, -1.08946769614704e-5, 4.33608802268282e-5, 1.04796490631998e-4, 0.115326032042503, 4.9168236728292e-5, -0.00183966604527086, -9.66426974628121e-4, 1.25384838156606e-6, -1.6737062651373e-6, -1.2068853720848e-5, 3.64447005267721e-5, 3.21440202242229e-5, 2.2832109243609e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 11.5724449157715, + "fY" : -37.1252288818359, + "fZ" : 97.2810516357422, + "fTx" : 0.184642106294632, + "fTy" : -0.393206566572189, + "fQp" : 0.491282910108566, + "fCovMatrix" : [0.0019843983463943, 0.00619267066940665, 6.76561103318818e-5, 1.29911699332297e-4, 4.06330276746303e-4, 0.0522433407604694, 2.30213481700048e-4, 0.00104126078076661, 0.00156744290143251, 3.52676556758524e-6, 3.81714471586747e-6, 2.33595692407107e-5, 3.48855210177135e-5, 2.8559716156451e-5, 2.27711803745478e-4] + }, + "fFlag" : 0, + "fChi2" : 7.03528499603271, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -1039371012, + "fStsHits" : [765, 975, 1149, 1417, 1577], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.75026273727417, + "fY" : -5.4413857460022, + "fZ" : 97.2235488891602, + "fTx" : 0.00724998163059354, + "fTy" : -0.0642959550023079, + "fQp" : 0.211119934916496, + "fCovMatrix" : [0.00117649475578219, 0.00176432740408927, -3.10638570226729e-5, -2.034405588347e-5, 1.29306718008593e-4, 0.0234715472906828, -6.32680676062591e-5, -2.56088271271437e-4, 3.33813339238986e-4, 1.4295483197202e-6, 8.16821227545006e-7, -6.65486368234269e-6, 4.64160257251933e-6, -5.36914512849762e-6, 4.19976058765315e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.39248609542847, + "fY" : -15.2550344467163, + "fZ" : 248.595626831055, + "fTx" : 0.0840076804161072, + "fTy" : -0.0652276128530502, + "fQp" : 0.211302027106285, + "fCovMatrix" : [0.00215878384187818, -0.00652850000187755, 4.08105552196503e-5, -5.81041713303421e-5, 1.60905838129111e-4, 0.0475969351828098, -1.20058350148611e-4, 4.1928852442652e-4, -4.92834951728582e-4, 1.36078983814514e-6, -1.21245784612256e-6, 6.16464149061358e-6, 4.7944809011824e-6, -5.55816268388298e-6, 4.20562355429865e-5] + }, + "fFlag" : 0, + "fChi2" : 0.207960084080696, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -2033030591, + "fStsHits" : [1590, 1646, 1726, 1803, 208], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.34458017349243, + "fY" : 2.0635199546814, + "fZ" : 19.0084991455078, + "fTx" : -0.369900912046432, + "fTy" : 0.0637445524334908, + "fQp" : -1.67988467216492, + "fCovMatrix" : [2.78333347523585e-4, -0.00444477424025536, -1.9564025933505e-5, 1.10813583887648e-4, 2.54579092143103e-4, 0.199755907058716, 1.42027798574418e-4, -0.00469854427501559, -0.00203349813818932, 4.77896810480161e-6, -6.82736936141737e-6, -6.56101910863072e-5, 1.42291624797508e-4, 1.47602855577134e-4, 0.00213012704625726] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -29.1511573791504, + "fY" : 5.16933584213257, + "fZ" : 65.8757781982422, + "fTx" : -0.621299684047699, + "fTy" : 0.0697667375206947, + "fQp" : -1.68280816078186, + "fCovMatrix" : [0.00207065301947296, 0.00739669566974044, 1.5232952137012e-4, 2.03452989808284e-4, 0.00115508679300547, 0.0626869574189186, 5.78183040488511e-4, 0.00173771800473332, 0.00466901436448097, 1.66032168635866e-5, 1.37709239425021e-5, 1.00848628790118e-4, 1.44337231176905e-4, 1.39568408485502e-4, 0.00202691182494164] + }, + "fFlag" : 0, + "fChi2" : 0.227177545428276, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 804756743, + "fStsHits" : [830, 1016, 1341, 1460, 1513], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.858320772647858, + "fY" : 6.28393602371216, + "fZ" : 128.181015014648, + "fTx" : 0.0218003634363413, + "fTy" : 0.0314105115830898, + "fQp" : 0.173579782247543, + "fCovMatrix" : [0.00124174356460571, 0.00186171405948699, -3.65540909115225e-5, -1.86703055078397e-5, 1.78873349796049e-4, 0.0248651541769505, -5.55277656530961e-5, -2.76516511803493e-4, 2.27594617172144e-4, 2.0022507669637e-6, 2.58518213058778e-7, -1.19733213068685e-5, 4.80156813864596e-6, 8.01276428319397e-7, 8.51308141136542e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.86859655380249, + "fY" : 10.1788835525513, + "fZ" : 253.266006469727, + "fTx" : 0.0719021633267403, + "fTy" : 0.030917601659894, + "fQp" : 0.17361880838871, + "fCovMatrix" : [0.00144070305395871, 0.00268978602252901, 3.8227914046729e-5, 2.6859030185733e-5, 1.96151857380755e-4, 0.0287036336958408, 7.1467540692538e-5, 3.07969428831711e-4, 3.20376071613282e-4, 1.76498826931493e-6, 4.9620382469584e-7, 1.0976058547385e-5, 4.83661369798938e-6, 7.20734192327654e-7, 8.51301738293841e-5] + }, + "fFlag" : 0, + "fChi2" : 0.441367298364639, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 1784436488, + "fStsHits" : [1633, 1705, 1792, 251, 684], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.196990102529526, + "fY" : 4.10607433319092, + "fZ" : 28.9860000610352, + "fTx" : 2.31513069593348e-4, + "fTy" : 0.118222609162331, + "fQp" : 0.258941113948822, + "fCovMatrix" : [2.31129874009639e-4, 0.00292214122600853, -1.58259845193243e-5, -6.40172074781731e-5, 2.03543633688241e-4, 0.140206709504128, -5.95078163314611e-5, -0.00282353395596147, 0.0014167760964483, 2.27871191782469e-6, 2.79866867458622e-6, -3.25443397741765e-5, 6.69783912599087e-5, -6.38097335468046e-5, 5.69196708966047e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.04422128200531, + "fY" : 11.5715970993042, + "fZ" : 92.2562408447266, + "fTx" : 0.0397122837603092, + "fTy" : 0.117785260081291, + "fQp" : 0.259079456329346, + "fCovMatrix" : [0.0019244517898187, -0.00591123849153519, 8.24297530925833e-5, -1.79509283043444e-4, 7.10876774974167e-4, 0.0508608967065811, -2.78832420008257e-4, 0.00141337746754289, -0.00265289493836462, 5.02301281812834e-6, -6.6773113758245e-6, 5.02329530718271e-5, 6.71694069751538e-5, -6.46529588266276e-5, 5.70721633266658e-4] + }, + "fFlag" : 0, + "fChi2" : 0.969777345657349, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 2111848766, + "fStsHits" : [1741, 1812, 303, 719, 954], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 3.863436460495, + "fY" : -2.1556568145752, + "fZ" : 33.2039985656738, + "fTx" : 0.129835516214371, + "fTy" : -0.0879562199115753, + "fQp" : 0.433623850345612, + "fCovMatrix" : [1.83617870789021e-4, -0.00140847999136895, -1.03897600638447e-5, 1.92811603483278e-5, 5.59829240955878e-5, 0.0814942494034767, -1.10115513962228e-4, -0.00126815272960812, 0.00147929741069674, 2.54401743404742e-6, 2.19742628360109e-6, -1.96452256204793e-5, 2.49728036578745e-5, -3.28479363815859e-5, 3.4016027348116e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 20.04958152771, + "fY" : -10.2683620452881, + "fZ" : 123.573219299316, + "fTx" : 0.231167927384377, + "fTy" : -0.0918390303850174, + "fQp" : 0.433601051568985, + "fCovMatrix" : [0.00166628626175225, -0.00440471712499857, 7.23644261597656e-5, -9.8583557701204e-5, 4.49243234470487e-4, 0.0411870628595352, -2.49812321271747e-4, 8.06081690825522e-4, -0.00164000503718853, 5.4716306294722e-6, -5.69700978303445e-6, 3.84218983526807e-5, 2.34642557188636e-5, -3.62011523975525e-5, 3.3855639048852e-4] + }, + "fFlag" : 0, + "fChi2" : 1.28278923034668, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -583166863, + "fStsHits" : [820, 1018, 1340, 1459, 1514], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.18088924884796, + "fY" : 7.13062906265259, + "fZ" : 128.181015014648, + "fTx" : 0.0525054931640625, + "fTy" : 0.0577929578721523, + "fQp" : 0.223693534731865, + "fCovMatrix" : [0.00124389829579741, 0.00187493627890944, -3.67922184523195e-5, -1.9085904568783e-5, 1.77849171450362e-4, 0.0249385163187981, -5.70193769817706e-5, -2.78742809314281e-4, 2.31804602663033e-4, 2.05450055545953e-6, 2.91427767251662e-7, -1.19767664727988e-5, 4.92232766191592e-6, 6.38823962617607e-7, 8.7709297076799e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 9.65340137481689, + "fY" : 14.3349628448486, + "fZ" : 253.266006469727, + "fTx" : 0.11790207028389, + "fTy" : 0.0574194453656673, + "fQp" : 0.22418674826622, + "fCovMatrix" : [0.00144579424522817, 0.00271411100402474, 3.87558866350446e-5, 2.74546582659241e-5, 1.94436361198314e-4, 0.0288186054676771, 7.36644433345646e-5, 3.11019335640594e-4, 3.17794881993905e-4, 1.83949623533408e-6, 5.32548142473388e-7, 1.09920383692952e-5, 4.97932387588662e-6, 7.55248663608654e-7, 8.79240033100359e-5] + }, + "fFlag" : 0, + "fChi2" : 7.09661912918091, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 2107400207, + "fStsHits" : [1592, 1640, 1710, 207, 681], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.00900554656982, + "fY" : 5.7161545753479, + "fZ" : 19.0084991455078, + "fTx" : -0.156598970293999, + "fTy" : 0.305210292339325, + "fQp" : 2.57373809814453, + "fCovMatrix" : [2.5570543948561e-4, -0.00347107835114002, -1.94583844859153e-5, 6.41185470158234e-5, 1.35626905830577e-4, 0.153904005885124, 7.85877928137779e-5, -0.0029579671099782, 0.00157759909052402, 7.68603149481351e-6, -2.09810787055176e-6, -7.30215760995634e-5, 8.75331534189172e-5, -5.53514037164859e-5, 0.00436392892152071] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.69932627677917, + "fY" : 27.9923896789551, + "fZ" : 92.2562408447266, + "fTx" : 0.326712906360626, + "fTy" : 0.314964473247528, + "fQp" : 2.5777063369751, + "fCovMatrix" : [0.0019453507848084, -0.00591527670621872, 1.0935653699562e-4, -1.62201758939773e-4, 7.15228088665754e-4, 0.0500840172171593, -4.09632222726941e-4, 0.00128573877736926, -0.00303747202269733, 2.28120879910421e-5, -3.43982901540585e-6, 1.61356016178615e-4, 7.76000015321188e-5, -4.8420228267787e-5, 0.00437125051394105] + }, + "fFlag" : 0, + "fChi2" : 12.9892539978027, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 1146774797, + "fStsHits" : [1639, 1722, 241, 686, 1006], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.33991861343384, + "fY" : 3.3494861125946, + "fZ" : 28.9860000610352, + "fTx" : -0.0734212100505829, + "fTy" : 0.18664975464344, + "fQp" : 0.457632958889008, + "fCovMatrix" : [1.37585622724146e-4, 3.231153532397e-4, -7.759179425193e-6, -4.15190743296989e-6, 3.29127615259495e-5, 0.0465634614229202, -3.26022345689125e-5, -6.06094661634415e-4, 3.92252404708415e-4, 1.48185415582702e-6, 4.88209195736999e-7, -5.9483263612492e-6, 1.23654426715802e-5, -7.32584976503858e-6, 1.02529127616435e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.85358667373657, + "fY" : 26.7497463226318, + "fZ" : 154.893341064453, + "fTx" : 0.0682987794280052, + "fTy" : 0.18551504611969, + "fQp" : 0.458666443824768, + "fCovMatrix" : [0.00234777061268687, -0.00808644108474255, 4.71720522909891e-5, -8.98432699614204e-5, 1.90876264241524e-4, 0.0612202808260918, -1.42043427331373e-4, 6.91099616233259e-4, -5.6737702107057e-4, 2.28793101086922e-6, -1.78430468622537e-6, 1.14754893729696e-5, 1.07599435068551e-5, -7.92009814176708e-6, 1.02951998997014e-4] + }, + "fFlag" : 0, + "fChi2" : 18.1715698242188, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [1002, 1300, 1449, 1497], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.73212194442749, + "fY" : 7.62100839614868, + "fZ" : 154.930511474609, + "fTx" : 0.0688236728310585, + "fTy" : 0.0455737896263599, + "fQp" : 0.193551555275917, + "fCovMatrix" : [0.00191372714471072, -0.00537101458758116, -7.67493256716989e-5, 8.98420912562869e-5, 5.31863130163401e-4, 0.0446399599313736, 2.74645746685565e-4, -6.9100089604035e-4, -0.00216327188536525, 4.91318405693164e-6, -5.14892190039973e-6, -3.9024405850796e-5, 1.41200571306399e-5, 4.36181217082776e-5, 3.39367223205045e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.7385778427124, + "fY" : 12.0891809463501, + "fZ" : 253.266006469727, + "fTx" : 0.112201519310474, + "fTy" : 0.0453274585306644, + "fQp" : 0.193596020340919, + "fCovMatrix" : [0.00188012362923473, 0.00521380174905062, 6.9455367338378e-5, 8.78330101841129e-5, 5.20087778568268e-4, 0.0439235866069794, 2.43776274146512e-4, 6.81218691170216e-4, 0.00210053799673915, 4.06200524594169e-6, 4.60243154520867e-6, 3.49099573213607e-5, 1.40494394145207e-5, 4.31489788752515e-5, 3.39114689268172e-4] + }, + "fFlag" : 0, + "fChi2" : 0.411130547523499, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [1019, 1337, 1466, 1510], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.7900447845459, + "fY" : 1.92675232887268, + "fZ" : 154.863342285156, + "fTx" : 0.0236554350703955, + "fTy" : 0.0151996146887541, + "fQp" : 0.308184832334518, + "fCovMatrix" : [0.00191863265354186, -0.00539835495874286, -7.74139843997546e-5, 9.04433109099045e-5, 5.40200329851359e-4, 0.0447931326925755, 2.78089544735849e-4, -6.94478861987591e-4, -0.00220557954162359, 5.05971138409222e-6, -5.19395143783186e-6, -4.01898687414359e-5, 1.43396091516479e-5, 4.43324133811984e-5, 3.64607170922682e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.0862729549408, + "fY" : 3.39191007614136, + "fZ" : 253.266006469727, + "fTx" : 0.0919949263334274, + "fTy" : 0.0146251767873764, + "fQp" : 0.308357298374176, + "fCovMatrix" : [0.00187728903256357, 0.00520153529942036, 6.91362147335894e-5, 8.78545251907781e-5, 5.24696835782379e-4, 0.0438745133578777, 2.42525129579008e-4, 6.81901117786765e-4, 0.00212102546356618, 4.1156172301271e-6, 4.55953340861015e-6, 3.50678055838216e-5, 1.42927547130967e-5, 4.36515038018115e-5, 3.64597100997344e-4] + }, + "fFlag" : 0, + "fChi2" : 0.453778833150864, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [999, 1303, 1448, 1498], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.75856113433838, + "fY" : 5.29568672180176, + "fZ" : 154.930511474609, + "fTx" : 0.0780638679862022, + "fTy" : 0.0281242504715919, + "fQp" : 0.0756367072463036, + "fCovMatrix" : [0.00191509409341961, -0.00537667190656066, -7.70171245676465e-5, 8.98398866411299e-5, 5.36072591785342e-4, 0.0446596220135689, 2.75755912298337e-4, -6.90656190272421e-4, -0.00218208692967892, 4.90661386720603e-6, -5.17673879585345e-6, -3.91841604141518e-5, 1.40340262078098e-5, 4.40198164142203e-5, 3.35204240400344e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 17.3073558807373, + "fY" : 8.05453491210938, + "fZ" : 253.266006469727, + "fTx" : 0.0948937758803368, + "fTy" : 0.0280081648379564, + "fQp" : 0.0756424963474274, + "fCovMatrix" : [0.00187675538472831, 0.00519617134705186, 6.89028020133264e-5, 8.74576508067548e-5, 5.23877679370344e-4, 0.0438308529555798, 2.41132453083992e-4, 6.78879441693425e-4, 0.00211673392914236, 3.9582828321727e-6, 4.5645338104805e-6, 3.49516412825324e-5, 1.38887553475797e-5, 4.35075889981817e-5, 3.35134332999587e-4] + }, + "fFlag" : 0, + "fChi2" : 0.495197772979736, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [1109, 1357, 1472, 1571], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 22.9461498260498, + "fY" : -2.31094193458557, + "fZ" : 159.739318847656, + "fTx" : 0.188223868608475, + "fTy" : -0.0197214782238007, + "fQp" : 0.227153733372688, + "fCovMatrix" : [0.00179139547981322, 0.00477984780445695, -9.2383568699006e-5, -9.00091908988543e-5, 7.05861079040915e-4, 0.0414791218936443, -3.37911857059225e-4, -6.96462811902165e-4, 0.00288166361860931, 7.74141426518327e-6, 6.99613701726776e-6, -6.60418736515567e-5, 1.56029600475449e-5, -6.25387256150134e-5, 6.03570078965276e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 41.9540824890137, + "fY" : -4.10293197631836, + "fZ" : 248.796600341797, + "fTx" : 0.235984206199646, + "fTy" : -0.0203404352068901, + "fQp" : 0.227200746536255, + "fCovMatrix" : [0.00174356333445758, -0.00458400696516037, 8.15501189208589e-5, -8.98631260497496e-5, 6.81965495459735e-4, 0.0407083556056023, -2.93669785605744e-4, 6.95800816174597e-4, -0.00278137647546828, 6.21894605501438e-6, -6.38650772089022e-6, 5.82726097491104e-5, 1.60044910444412e-5, -6.40857906546444e-5, 6.02325773797929e-4] + }, + "fFlag" : 0, + "fChi2" : 0.698075890541077, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [810, 992, 1291, 1423], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 22.281042098999, + "fY" : 11.1978244781494, + "fZ" : 128.236862182617, + "fTx" : 0.213279917836189, + "fTy" : 0.0798255801200867, + "fQp" : 0.304712682962418, + "fCovMatrix" : [0.0017848601564765, 0.00476990174502134, -8.87135829543695e-5, -9.23507905099541e-5, 6.37873541563749e-4, 0.0415498688817024, -3.24260152410716e-4, -7.0833828067407e-4, 0.00262450193986297, 7.20816069588182e-6, 6.92722278472502e-6, -5.76723614358343e-5, 1.62298274517525e-5, -5.90791678405367e-5, 5.1123951561749e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 44.484375, + "fY" : 18.3676624298096, + "fZ" : 217.384552001953, + "fTx" : 0.284152507781982, + "fTy" : 0.0814678445458412, + "fQp" : 0.305033385753632, + "fCovMatrix" : [0.00175817660056055, -0.00463350908830762, 8.5848179878667e-5, -8.76575941219926e-5, 6.27167988568544e-4, 0.0408595725893974, -3.1003967160359e-4, 6.86733517795801e-4, -0.00256027095019817, 6.89906937623164e-6, -6.45210820948705e-6, 5.61424931220245e-5, 1.5617781173205e-5, -5.63507528568152e-5, 5.09658188093454e-4] + }, + "fFlag" : 0, + "fChi2" : 1.08289587497711, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [819, 1004, 1324, 1489], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.48127460479736, + "fY" : 14.1055374145508, + "fZ" : 128.181015014648, + "fTx" : 0.0669111758470535, + "fTy" : 0.106525674462318, + "fQp" : 0.562852263450623, + "fCovMatrix" : [0.00135837646666914, 0.00231276173144579, -4.58314134448301e-5, -3.72795839211904e-5, 2.04240073799156e-4, 0.0267512481659651, -9.33977207751013e-5, -3.52231087163091e-4, 3.5840822965838e-4, 3.15209990731091e-6, 1.46359877817304e-6, -1.48442813951988e-5, 9.25817039387766e-6, -3.60681519850914e-6, 1.43416997161694e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 16.8721809387207, + "fY" : 27.4688682556152, + "fZ" : 253.266006469727, + "fTx" : 0.239092364907265, + "fTy" : 0.106934949755669, + "fQp" : 0.564698278903961, + "fCovMatrix" : [0.00229982333257794, 0.00780216185376048, 4.0141665522242e-5, 7.67691526561975e-5, 1.28212152048945e-4, 0.0601321943104267, 8.49204225232825e-5, 6.12380274105817e-4, 5.99656232225243e-6, 2.48483934228716e-6, 8.56475082855468e-7, 1.06208335637348e-5, 9.37485037866281e-6, -1.77873027951136e-6, 1.43166267662309e-4] + }, + "fFlag" : 0, + "fChi2" : 1.11068141460419, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [639, 803, 1001, 1339], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 9.4885950088501, + "fY" : 3.8629424571991, + "fZ" : 92.2331237792969, + "fTx" : -0.0242228172719479, + "fTy" : 0.0985142067074776, + "fQp" : -0.330903857946396, + "fCovMatrix" : [0.00190640171058476, -0.00534825166687369, -7.4283110734541e-5, 9.04774060472846e-5, 4.89153375383466e-4, 0.0446081645786762, 2.65156908426434e-4, -6.94628863129765e-4, -0.00199959939345717, 4.69204860564787e-6, -5.0137605285272e-6, -3.50844784406945e-5, 1.44616788020357e-5, 4.09551321354229e-5, 3.06548143271357e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 3.08387875556946, + "fY" : 13.6549243927002, + "fZ" : 190.759826660156, + "fTx" : -0.10558620095253, + "fTy" : 0.100344710052013, + "fQp" : -0.331057548522949, + "fCovMatrix" : [0.00188889005221426, 0.0052486308850348, 7.33881024643779e-5, 8.69609430083074e-5, 4.84872958622873e-4, 0.0440538413822651, 2.59661668678746e-4, 6.78094103932381e-4, 0.00196568109095097, 4.63806691186619e-6, 4.78684660265571e-6, 3.48159555869643e-5, 1.40232677949825e-5, 3.92855836253148e-5, 3.06403584545478e-4] + }, + "fFlag" : 0, + "fChi2" : 1.66834080219269, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [996, 1312, 1441, 1503], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 10.3489437103271, + "fY" : 4.70093584060669, + "fZ" : 154.930511474609, + "fTx" : 0.114422798156738, + "fTy" : 0.0214356426149607, + "fQp" : 0.205062597990036, + "fCovMatrix" : [0.00191554531920701, -0.00537964282557368, -7.71532868384384e-5, 8.9897439465858e-5, 5.28358912561089e-4, 0.0446815341711044, 2.76426231721416e-4, -6.91475346684456e-4, -0.00215133302845061, 4.97471410199068e-6, -5.17047965331585e-6, -3.88837579521351e-5, 1.41577957037953e-5, 4.33041859650984e-5, 3.3617319422774e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 24.005033493042, + "fY" : 6.79686689376831, + "fZ" : 253.266006469727, + "fTx" : 0.160805702209473, + "fTy" : 0.0212317742407322, + "fQp" : 0.205193266272545, + "fCovMatrix" : [0.00187896145507693, 0.00520860031247139, 6.91965979058295e-5, 8.78914870554581e-5, 5.16361207701266e-4, 0.0439009629189968, 2.42643247474916e-4, 6.81457633618265e-4, 0.00208820379339159, 4.03758804168319e-6, 4.58853901363909e-6, 3.45933949574828e-5, 1.40722304422525e-5, 4.29789324698504e-5, 3.36067983880639e-4] + }, + "fFlag" : 0, + "fChi2" : 4.17218637466431, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [823, 1014, 1301, 1440], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.209159761667252, + "fY" : 5.51541423797607, + "fZ" : 128.181015014648, + "fTx" : 0.0891838893294334, + "fTy" : 0.0620394684374332, + "fQp" : 1.02081644535065, + "fCovMatrix" : [0.00179648376069963, 0.00484131509438157, -9.11472598090768e-5, -9.4970477221068e-5, 6.41372753307223e-4, 0.0420113168656826, -3.36277502356097e-4, -7.32080370653421e-4, 0.00263895676471293, 8.72109558258671e-6, 6.75840738040279e-6, -5.9632020565914e-5, 2.0143908841419e-5, -5.86929418204818e-5, 7.53887987229973e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 18.6140308380127, + "fY" : 11.1579370498657, + "fZ" : 217.384552001953, + "fTx" : 0.324826687574387, + "fTy" : 0.0648133456707001, + "fQp" : 1.02351033687592, + "fCovMatrix" : [0.00179702998138964, -0.00483735324814916, 9.20187958399765e-5, -9.39793317229487e-5, 6.35934644378722e-4, 0.0419517792761326, -3.39350604917854e-4, 7.26883299648762e-4, -0.00259862025268376, 8.94437198439846e-6, -6.71676525598741e-6, 5.96006648265757e-5, 1.98985035240185e-5, -5.73953657294624e-5, 7.41470488719642e-4] + }, + "fFlag" : 0, + "fChi2" : 10.8240270614624, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [1586, 1629, 1703, 1784], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 2.08460211753845, + "fY" : 3.47573447227478, + "fZ" : 20.1884994506836, + "fTx" : 0.16789023578167, + "fTy" : 0.16056589782238, + "fQp" : 6.63444900512695, + "fCovMatrix" : [3.26649431372061e-4, 0.00607380550354719, -3.47558998328168e-5, -3.04218527162448e-4, 8.30986129585654e-4, 0.278783947229385, -2.87038332317024e-4, -0.0139748118817806, 0.0139984898269176, 4.31774933531415e-5, 2.40868921537185e-5, -6.08670234214514e-4, 0.00117100204806775, -0.00112597877159715, 0.0572077855467796] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 12.4197807312012, + "fY" : 7.84360790252686, + "fZ" : 46.3479995727539, + "fTx" : 0.674497842788696, + "fTy" : 0.180485606193542, + "fQp" : 6.65022325515747, + "fCovMatrix" : [3.4709763713181e-4, 0.00678978255018592, 3.63292347174138e-5, 3.32853232976049e-4, 9.68408057815395e-5, 0.311384648084641, 2.99614679533988e-4, 0.0151938563212752, -0.015667324885726, 8.55263933772221e-5, 2.96559246635297e-5, 8.48880503326654e-4, 0.00118385872337967, -0.00109430367592722, 0.0491611175239086] + }, + "fFlag" : 0, + "fChi2" : 0.00596811110153794, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223088, + "fStsHits" : [1665, 1748, 1836, 462], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.712063908576965, + "fY" : -3.38685655593872, + "fZ" : 23.511999130249, + "fTx" : -0.0905543118715286, + "fTy" : -0.213576912879944, + "fQp" : -4.52138519287109, + "fCovMatrix" : [3.10847914079204e-4, -0.00515546835958958, -3.06443726003636e-5, 1.49077081005089e-4, 3.62573016900569e-4, 0.222128584980965, 2.35367304412648e-4, -0.00670933164656162, 0.00310587813146412, 2.11121332540642e-5, -5.10366817252361e-6, -2.44588678469881e-4, 2.87801318336278e-4, -3.01768741337582e-4, 0.0212442204356194] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.7083158493042, + "fY" : -11.8248224258423, + "fZ" : 61.02734375, + "fTx" : -0.561766088008881, + "fTy" : -0.246598660945892, + "fQp" : -4.54282855987549, + "fCovMatrix" : [0.00231565581634641, -0.00833991821855307, 2.11953214602545e-4, -2.98762606689706e-4, 0.00200965511612594, 0.0665908977389336, -7.94334802776575e-4, 0.00232968013733625, -0.00770675344392657, 5.23287199030165e-5, -9.87282601272454e-6, 2.70730466581881e-4, 3.05086723528802e-4, -2.41832807660103e-4, 0.019675899296999] + }, + "fFlag" : 0, + "fChi2" : 0.126345127820969, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223248, + "fStsHits" : [1681, 1772, 1835, 469], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.88433885574341, + "fY" : -5.33419370651245, + "fZ" : 24.867000579834, + "fTx" : -0.148824334144592, + "fTy" : -0.153178632259369, + "fQp" : 0.323248863220215, + "fCovMatrix" : [2.95291596557945e-4, 0.00507724098861217, -2.48809756158153e-5, -1.57063564984128e-4, 4.58680733572692e-4, 0.230090022087097, -1.96246211999096e-4, -0.00679233251139522, 0.0024279688950628, 5.24611232322059e-6, 1.26538825497846e-5, -1.44563178764656e-4, 2.51001823926345e-4, -3.72937996871769e-4, 0.00492896279320121] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -8.76997375488281, + "fY" : -10.8661489486694, + "fZ" : 61.0379409790039, + "fTx" : -0.120636485517025, + "fTy" : -0.152578368782997, + "fQp" : 0.323388069868088, + "fCovMatrix" : [0.00224469392560422, -0.00816680397838354, 1.83035343070515e-4, -2.75593047263101e-4, 0.00273431115783751, 0.0664315596222878, -7.01152719557285e-4, 0.00225460040383041, -0.0107996184378862, 1.73376683960669e-5, -1.98681918845978e-5, 2.78609455563128e-4, 2.4982143077068e-4, -3.56033619027585e-4, 0.00484105106443167] + }, + "fFlag" : 0, + "fChi2" : 1.90603971481323, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223136, + "fStsHits" : [1739, 1811, 714, 840], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.09232807159424, + "fY" : -3.98210906982422, + "fZ" : 33.2039985656738, + "fTx" : 0.200135305523872, + "fTy" : -0.137657016515732, + "fQp" : 2.13950061798096, + "fCovMatrix" : [2.81723798252642e-4, -0.00458552315831184, -2.06011136469897e-5, 5.82041539018974e-5, 1.0711484355852e-4, 0.199366182088852, 1.29341031424701e-4, -0.00275158672593534, -0.00123315514065325, 6.10193319516839e-6, -7.06659307070368e-7, -2.98638224194292e-5, 5.66852613701485e-5, 1.94280801224522e-6, 0.00113400362897664] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 49.6317138671875, + "fY" : -18.7386264801025, + "fZ" : 123.735862731934, + "fTx" : 0.922451794147491, + "fTy" : -0.211355149745941, + "fQp" : 2.14829063415527, + "fCovMatrix" : [0.00199073599651456, -0.00600775657221675, 1.30909102153964e-4, -1.49604718899354e-4, 4.00048622395843e-4, 0.0492274090647697, -5.2100548055023e-4, 0.00109832175076008, -0.00148220511619002, 2.66304086835589e-5, -8.38927280710777e-6, 6.87345527694561e-5, 6.45601903670467e-5, -1.4814616406511e-5, 0.00107164145447314] + }, + "fFlag" : 0, + "fChi2" : 2.83805012702942, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223248, + "fStsHits" : [1714, 1793, 557, 786], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.01563191413879, + "fY" : 8.8020715713501, + "fZ" : 36.5065002441406, + "fTx" : 0.0238136984407902, + "fTy" : 0.229776665568352, + "fQp" : 3.00857210159302, + "fCovMatrix" : [2.64756876276806e-4, -0.00391674833372235, -2.09588379220804e-5, 6.66756313876249e-5, 1.23633171824622e-5, 0.183763533830643, 4.85840973851737e-5, -0.00292594847269356, 0.0015829544281587, 9.95756727206754e-6, -3.02706757793203e-6, -3.11150288325734e-5, 8.82402819115669e-5, 1.12403367893421e-5, 0.0023886754643172] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 36.9655494689941, + "fY" : 31.9299697875977, + "fZ" : 128.266860961914, + "fTx" : 1.03927612304688, + "fTy" : 0.324166595935822, + "fQp" : 3.00718474388123, + "fCovMatrix" : [0.00225362344644964, 0.0075716795399785, 1.34594927658327e-4, 1.78253525518812e-4, 3.82453668862581e-4, 0.0592034570872784, 5.54147001821548e-4, 0.00129310914780945, 0.00136285566259176, 4.59551192761865e-5, 1.16209812404122e-5, 1.57154776388779e-4, 7.96331441961229e-5, 1.55477555381367e-5, 0.00224633538164198] + }, + "fFlag" : 0, + "fChi2" : 2.90521001815796, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223248, + "fStsHits" : [1683, 1765, 1833, 769], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.49905848503113, + "fY" : -4.73205327987671, + "fZ" : 24.867000579834, + "fTx" : -0.182313904166222, + "fTy" : -0.12723571062088, + "fQp" : -0.796673059463501, + "fCovMatrix" : [2.58392479736358e-4, 0.00391368288546801, -1.59541250468465e-5, -5.6714841775829e-5, 1.36179805849679e-4, 0.179493710398674, -5.48938623978756e-5, -0.00261219637468457, -2.17309025174472e-5, 2.42193846133887e-6, 7.85031886607612e-7, -2.42338719544932e-5, 5.2817995310761e-5, 1.84369109774707e-5, 4.60917421150953e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -22.0228366851807, + "fY" : -14.0940723419189, + "fZ" : 97.1422271728516, + "fTx" : -0.338983148336411, + "fTy" : -0.132703423500061, + "fQp" : -0.786303102970123, + "fCovMatrix" : [0.00249015097506344, 0.00926257483661175, 8.01757778390311e-5, 1.46307735121809e-4, 4.15503891417757e-4, 0.071669764816761, 2.8469690005295e-4, 0.00112168665509671, 0.0013581917155534, 4.9180093810719e-6, 5.47497120351181e-6, 3.15871002385393e-5, 5.38857966603246e-5, 2.07644352485659e-5, 4.52636770205572e-4] + }, + "fFlag" : 0, + "fChi2" : 4.02894258499146, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [1600, 1654, 1805, 323], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.07217502593994, + "fY" : -2.39451503753662, + "fZ" : 15.9584999084473, + "fTx" : 0.420909732580185, + "fTy" : -0.201101765036583, + "fQp" : 2.85020518302917, + "fCovMatrix" : [2.82053020782769e-4, -0.004905772395432, -2.29373454203596e-5, 1.13983885967173e-4, 2.73937796009704e-4, 0.226012468338013, 1.02235942904372e-4, -0.00534120853990316, -0.00137035315856338, 1.03694828794687e-5, -2.33197056331846e-6, -1.0354309779359e-4, 1.69253908097744e-4, 1.42875364872452e-8, 0.00385891180485487] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 35.2132225036621, + "fY" : -12.9507713317871, + "fZ" : 61.2922630310059, + "fTx" : 0.945975542068481, + "fTy" : -0.284506976604462, + "fQp" : 2.88229727745056, + "fCovMatrix" : [0.00233683804981411, -0.00856001209467649, 1.85092372703366e-4, -2.543551963754e-4, 8.70178337208927e-4, 0.0678045079112053, -6.34722004178911e-4, 0.00189690559636801, -0.00251634069718421, 3.38984646077733e-5, -2.53437228820985e-5, 8.01854839664884e-5, 1.95868473383598e-4, -6.10732240602374e-5, 0.0034143861848861] + }, + "fFlag" : 0, + "fChi2" : 6.32332944869995, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886492624, + "fStsHits" : [688, 821, 997, 1163], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.210880279541, + "fY" : 9.14961528778076, + "fZ" : 92.2262420654297, + "fTx" : 0.268496483564377, + "fTy" : 0.0843126401305199, + "fQp" : 0.404653936624527, + "fCovMatrix" : [0.00189176446292549, -0.00527186086401343, -7.27753067621961e-5, 8.81685991771519e-5, 4.18113690102473e-4, 0.0442262329161167, 2.58130748989061e-4, -6.84046244714409e-4, -0.00168485485482961, 4.6416130317084e-6, -4.77597404824337e-6, -3.00879692076705e-5, 1.43454008139088e-5, 3.39827383868396e-5, 2.44524126173928e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 21.804407119751, + "fY" : 17.5602760314941, + "fZ" : 190.816345214844, + "fTx" : 0.382342100143433, + "fTy" : 0.0868466049432755, + "fQp" : 0.404914736747742, + "fCovMatrix" : [0.00190632219891995, 0.00534393405541778, 7.47169833630323e-5, 9.11921524675563e-5, 4.20524040237069e-4, 0.0445523224771023, 2.66797083895653e-4, 6.97484647389501e-4, 0.00170170434284955, 4.85355940327281e-6, 5.06681362821837e-6, 3.06623078358825e-5, 1.476433044445e-5, 3.50714653905015e-5, 2.42588197579607e-4] + }, + "fFlag" : 0, + "fChi2" : 8.00023555755615, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223136, + "fStsHits" : [1703, 1782, 194, 473], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.95647144317627, + "fY" : 7.19097709655762, + "fZ" : 36.4264984130859, + "fTx" : 0.488533347845078, + "fTy" : 0.16237935423851, + "fQp" : 3.89113664627075, + "fCovMatrix" : [2.71968718152493e-4, 0.00365265016444027, -2.19121720874682e-5, -1.0013045539381e-4, 9.04925327631645e-5, 0.17259469628334, -6.57515920465812e-5, -0.00457445345818996, 0.00113340897951275, 1.7093965652748e-5, 4.73313457405311e-6, -9.16516219149344e-5, 1.89009631867521e-4, -8.29447890282609e-5, 0.00527296680957079] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 75.0670471191406, + "fY" : 19.5143299102783, + "fZ" : 92.2631225585938, + "fTx" : 3.7820155620575, + "fTy" : 0.601390242576599, + "fQp" : 3.85533571243286, + "fCovMatrix" : [0.00235269544646144, -0.00818183925002813, 5.11665304657072e-4, -1.08604559500236e-4, 4.72164072562009e-4, 0.0635098516941071, -0.00206283130683005, 0.00135259691160172, -0.00227036792784929, 0.00325425225310028, 6.31853705272079e-4, 0.00235342606902122, 3.95051145460457e-4, 4.07467334298417e-4, 0.00299980654381216] + }, + "fFlag" : 0, + "fChi2" : 9.25080680847168, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}] +, +[{ + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0740007385611534, + "fY" : 0.677288472652435, + "fZ" : -0.029397277161479, + "fTx" : -0.132579430937767, + "fTy" : -0.0721291899681091, + "fQp" : -0.658152520656586, + "fCovMatrix" : [0.00221950025297701, 0.0028900564648211, -1.04220271168742e-4, -2.53592424996896e-5, 1.63976801559329e-4, 0.0685155019164085, -6.93701877025887e-5, -6.83764228597283e-4, 2.89757415885106e-4, 1.90980463230517e-5, 7.73996305269975e-7, -7.43909049560898e-6, 2.4674836822669e-5, -2.87492434836167e-6, 7.77224195189774e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -53.3829460144043, + "fY" : -13.1547222137451, + "fZ" : 185.683853149414, + "fTx" : -0.468784332275391, + "fTy" : -0.0797551199793816, + "fQp" : -0.660838067531586, + "fCovMatrix" : [0.00121652521193027, -0.00194779026787728, 3.82801008527167e-5, -2.38575230468996e-5, 1.03297272289637e-4, 0.0245428644120693, -8.60174477566034e-5, 2.80060805380344e-4, -2.55426042713225e-4, 3.07012169287191e-6, -9.24756022868678e-7, 7.38780818210216e-6, 6.4618020587659e-6, -2.95916311188194e-6, 7.52489650039934e-5] + }, + "fFlag" : -1, + "fChi2" : 0.6826918, + "fNDF" : 11, + "fB" : 0, + "fLength" : 195.034, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 0, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.210160583257675, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0565017387270927, + "fY" : 0.494460880756378, + "fZ" : -0.029397277161479, + "fTx" : -0.179241627454758, + "fTy" : -0.0634460225701332, + "fQp" : 0.355513691902161, + "fCovMatrix" : [0.00171372515615076, 0.00121204636525363, -5.64642687095329e-5, -6.87115743858158e-6, 1.0493984882487e-4, 0.0483764111995697, -1.55542984430213e-5, -3.68349603377283e-4, -2.98307495540939e-5, 6.93179117661202e-6, 1.21132771369048e-7, -3.54249959855224e-6, 8.94996264833026e-6, 4.8634649374435e-7, 2.29968627536437e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.34597206115723, + "fY" : -36.7444114685059, + "fZ" : 597.099975585938, + "fTx" : 0.0729218125343323, + "fTy" : -0.0618063695728779, + "fQp" : 0.358231991529465, + "fCovMatrix" : [0.331405907869339, 0.0342925935983658, 9.26587206777185e-4, 6.27643530606292e-5, 0.00156141619663686, 0.422792285680771, 7.94868537923321e-5, 0.00100473617203534, 1.76515794009902e-4, 5.05353909829864e-6, 1.32167642163949e-7, 4.4491644075606e-6, 4.93799279865925e-6, 3.2901203894653e-7, 1.93345149455126e-5] + }, + "fFlag" : -1, + "fChi2" : 2.345246, + "fNDF" : 11, + "fB" : 0, + "fLength" : 600.161, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 1, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 31, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.953495024098538, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0322453156113625, + "fPidTof400" : [], + "fPidTof700" : [0.644609602414643, 0.0694591290661035, 0.0999944691296863, 0.0676239011016339, 0.0258690273393539, 0.0127859635663681, 0.0534378617075987, 0.0262200456746122], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0555508695542812, + "fY" : 0.789763331413269, + "fZ" : -0.029397277161479, + "fTx" : 0.093839704990387, + "fTy" : 0.0370822511613369, + "fQp" : 0.182179391384125, + "fCovMatrix" : [0.0116515140980482, 0.00359308440238237, -1.67895312188193e-4, -1.30996895677526e-5, 3.21652245474979e-4, 0.0466934405267239, -3.43895189871546e-5, -2.97956197755411e-4, 3.54110343323555e-5, 3.85609973818646e-6, 8.41147453911617e-8, -4.98619874633732e-6, 3.75554623133212e-6, 1.46831339975506e-7, 1.55608831846621e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 115.492073059082, + "fY" : 23.1709060668945, + "fZ" : 605.900024414062, + "fTx" : 0.223378911614418, + "fTy" : 0.037110548466444, + "fQp" : 0.181536912918091, + "fCovMatrix" : [0.17296989262104, 0.0270088110119104, 4.87490324303508e-4, 4.76852655992843e-5, 0.00122358207590878, 0.272770643234253, 6.78752548992634e-5, 6.24767446424812e-4, 7.79907350079156e-5, 2.03847548618796e-6, 1.22276247793707e-7, 3.50633217749419e-6, 2.10773487197002e-6, 7.30451219510542e-8, 1.37240003823536e-5] + }, + "fFlag" : -1, + "fChi2" : 3.761668, + "fNDF" : 9, + "fB" : 0, + "fLength" : 617.8355, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 2, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 0, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.971411726424795, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.331369638442993, + "fPidTof400" : [], + "fPidTof700" : [0.106999403059693, 0.0541017738352127, 0.062242782061034, 0.0534903252441693, 0.0607867282988083, 0.0188247780843922, 0.581212027214649, 0.0623421822020417], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0666805133223534, + "fY" : 0.428164750337601, + "fZ" : -0.029397277161479, + "fTx" : -0.164223328232765, + "fTy" : 0.0071898540481925, + "fQp" : 0.156282559037209, + "fCovMatrix" : [0.00208490528166294, -0.00386034185066819, -5.61424240004271e-5, 3.31496303260792e-5, 2.03864430659451e-4, 0.0647998973727226, 9.00229279068299e-5, -4.98076085932553e-4, -3.77679069060832e-4, 2.48717469730764e-6, -8.14599786735926e-7, -5.97023336013081e-6, 5.37509959031013e-6, 3.56370742338186e-6, 3.01462678180542e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -52.7552871704102, + "fY" : 4.46160650253296, + "fZ" : 635.900024414062, + "fTx" : -0.0584225989878178, + "fTy" : 0.00611235853284597, + "fQp" : 0.14877887070179, + "fCovMatrix" : [0.489943891763687, 0.0843223929405212, 0.00122661679051816, 1.37403840199113e-4, 0.00245483871549368, 0.52642035484314, 1.8254027236253e-4, 0.00109178281854838, 4.23482531914487e-4, 5.18732576892944e-6, 2.97387003911354e-7, 5.68062205275055e-6, 4.51046071248129e-6, 6.98760686645983e-7, 1.69157738127979e-5] + }, + "fFlag" : -1, + "fChi2" : 9.146291, + "fNDF" : 9, + "fB" : 0, + "fLength" : 638.3365, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 3, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 43, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.941049282810426, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0534606203436852, + "fPidTof400" : [], + "fPidTof700" : [0.0839293680874064, 0.0691443786358444, 0.0725100750284162, 0.0688654569786821, 0.218816546462281, 0.159709845292051, 0.113744289889448, 0.21328003962587], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.00191991194151342, + "fY" : -0.182826071977615, + "fZ" : -0.029397277161479, + "fTx" : -0.323013454675674, + "fTy" : 0.15284352004528, + "fQp" : 0.659121811389923, + "fCovMatrix" : [0.0335149951279163, 0.00798405054956675, -5.71855984162539e-4, -2.68500389211113e-5, 8.36657825857401e-4, 0.080984078347683, -8.70597796165384e-5, -7.50974228139967e-4, 1.40999851282686e-4, 3.57154640369117e-5, -1.06207596672903e-6, -1.695135688351e-5, 3.26826593664009e-5, -3.52053177721245e-8, 6.94709597155452e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -28.8700866699219, + "fY" : 36.6349716186523, + "fZ" : 253.266006469727, + "fTx" : 0.0915517956018448, + "fTy" : 0.13888768851757, + "fQp" : 0.663964629173279, + "fCovMatrix" : [0.0013174363411963, 0.00216729799285531, 3.46993256243877e-5, 2.37835829466349e-5, 7.89249243098311e-5, 0.0238640792667866, 7.23723351256922e-5, 2.47721880441532e-4, 9.2910930106882e-5, 2.31840249398374e-6, 7.41987889796292e-7, 4.51600999440416e-6, 5.64657284485293e-6, 3.95186390278468e-7, 6.98939329595305e-5] + }, + "fFlag" : -1, + "fChi2" : 5.784281, + "fNDF" : 9, + "fB" : 0, + "fLength" : 259.1661, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 4, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.654710590839386, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.179565787315369, + "fY" : -0.399083405733109, + "fZ" : -0.029397277161479, + "fTx" : -0.201461151242256, + "fTy" : -0.205910712480545, + "fQp" : 0.910654604434967, + "fCovMatrix" : [0.00247417250648141, 0.00274470099247992, -1.29717140225694e-4, -2.78156312560895e-5, 2.99764738883823e-4, 0.0925460234284401, -4.29163264925592e-5, -0.00102607894223183, -2.91065400233492e-4, 5.89180563110858e-5, 2.62338539869234e-6, -1.5305888155126e-5, 6.89567896188237e-5, 3.5991758977616e-6, 1.74445245647803e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.8365318775177, + "fY" : -32.9046325683594, + "fZ" : 159.629043579102, + "fTx" : 0.167047187685966, + "fTy" : -0.20632404088974, + "fQp" : 0.914145052433014, + "fCovMatrix" : [0.00155416806228459, 0.00351027329452336, 4.78662987006828e-5, 4.80297567264643e-5, 1.67868478456512e-4, 0.034046433866024, 1.29982028738596e-4, 4.5236645382829e-4, 4.79995826026425e-4, 3.62696550837427e-6, 1.50596133607905e-6, 1.30671187434928e-5, 1.08145477497601e-5, 5.51082939637126e-6, 1.74894215888344e-4] + }, + "fFlag" : -1, + "fChi2" : 62.48223, + "fNDF" : 9, + "fB" : 0, + "fLength" : 163.8421, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 5, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.895907878875732, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0139392474666238, + "fY" : 0.455241650342941, + "fZ" : -0.029397277161479, + "fTx" : -0.062625527381897, + "fTy" : 0.148939579725266, + "fQp" : 0.119508534669876, + "fCovMatrix" : [5.78801264055073e-4, 9.634830057621e-4, -1.53702530951705e-5, -3.56837290382828e-6, 3.91939029213972e-5, 0.0465439446270466, -1.91397884918842e-5, -2.5883741909638e-4, 3.60415215254761e-5, 9.66233187682519e-7, 4.68406611275896e-8, -1.17995512027846e-6, 2.2916310626897e-6, 8.62989057992536e-9, 5.08634002471808e-6] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.76850318908691, + "fY" : 38.0125923156738, + "fZ" : 253.266006469727, + "fTx" : 0.00997702591121197, + "fTy" : 0.147619038820267, + "fQp" : 0.119642995297909, + "fCovMatrix" : [0.00100874423515052, 0.00117198028601706, 1.63884978974238e-5, 7.29519751985208e-6, 4.17295595980249e-5, 0.0191394723951817, 1.79422495421022e-5, 1.43677883897908e-4, 3.47817585861776e-5, 4.42629755070811e-7, 7.17247630177553e-8, 1.18746982025186e-6, 1.66530287515343e-6, -7.33179161827024e-9, 5.09104575030506e-6] + }, + "fFlag" : -1, + "fChi2" : 3.651506, + "fNDF" : 13, + "fB" : 0, + "fLength" : 256.2021, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 6, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0258415304124355, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0389177985489368, + "fY" : 0.448986709117889, + "fZ" : -0.029397277161479, + "fTx" : -0.174546033143997, + "fTy" : 0.129471302032471, + "fQp" : 0.527156710624695, + "fCovMatrix" : [0.0010258931433782, -0.0017312727868557, -5.28234850207809e-5, 1.48109857036616e-5, 1.36350776301697e-4, 0.0762835368514061, 1.59505343617639e-5, -7.40130781196058e-4, 1.82737523573451e-4, 1.48886438182672e-5, -3.93580336321975e-7, -7.10239601175999e-6, 2.17374108615331e-5, -2.39764813159127e-6, 8.03250004537404e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -12.1900281906128, + "fY" : 20.1586036682129, + "fZ" : 154.893341064453, + "fTx" : 0.0223866682499647, + "fTy" : 0.125468313694, + "fQp" : 0.52903938293457, + "fCovMatrix" : [0.00118864618707448, -0.00201725121587515, 3.29115355270915e-5, -2.80263557215221e-5, 1.24523183330894e-4, 0.0269913990050554, -7.08940933691338e-5, 3.47086053807288e-4, -2.71533383056521e-4, 2.06066397367977e-6, -9.20225318168377e-7, 7.71232225815766e-6, 7.54866641727858e-6, -3.4717002108664e-6, 8.07631731731817e-5] + }, + "fFlag" : -1, + "fChi2" : 0.5608385, + "fNDF" : 11, + "fB" : 0, + "fLength" : 156.83, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 7, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0223205760121346, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0595742650330067, + "fY" : 0.836916446685791, + "fZ" : -0.029397277161479, + "fTx" : -0.294198930263519, + "fTy" : -0.0304462239146233, + "fQp" : 0.573667526245117, + "fCovMatrix" : [0.00174248847179115, 0.00238847779110074, -7.30393221601844e-5, -2.14202755159931e-5, 9.12808754947037e-5, 0.0714968591928482, -4.04166348744184e-5, -7.88744306191802e-4, -1.40165313496254e-4, 1.99451569642406e-5, 5.33542049652169e-7, -5.51650691704708e-6, 2.84034485957818e-5, 6.42699262698443e-7, 7.26091820979491e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 12.1114253997803, + "fY" : -17.3297557830811, + "fZ" : 627.099975585938, + "fTx" : 0.117817349731922, + "fTy" : -0.028366457670927, + "fQp" : 0.584481775760651, + "fCovMatrix" : [0.591495037078857, 0.0372841954231262, 0.00177296262700111, 4.17713163187727e-5, 0.00279141054488719, 0.607945024967194, 5.95685487496667e-5, 0.00164023577235639, 2.83282657619566e-4, 3.05342837236822e-5, -1.90274089817422e-8, 6.21156414126744e-6, 2.97543447231874e-5, 3.70998293419689e-7, 5.38747299287934e-5] + }, + "fFlag" : -1, + "fChi2" : 1.322424, + "fNDF" : 11, + "fB" : 0, + "fLength" : 632.3667, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 8, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 32, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.66598499103137, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.366903215646744, + "fPidTof400" : [], + "fPidTof700" : [0.0296857656813575, 0.0192531548640818, 0.021505703857677, 0.0190692797998261, 0.433669813466485, 0.0459036074703152, 0.0565353274279246, 0.374377347432333], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0465898849070072, + "fY" : 0.553586721420288, + "fZ" : -0.029397277161479, + "fTx" : -0.0703434571623802, + "fTy" : 0.207842886447906, + "fQp" : 0.285599648952484, + "fCovMatrix" : [6.56671356409788e-4, 7.71137769334018e-4, -2.46595536737004e-5, -4.32917977377656e-6, 7.51452389522456e-5, 0.0552795119583607, -4.64672382349818e-7, -4.11612389143556e-4, -6.38001729384996e-5, 4.0657282625034e-6, -8.79117152408071e-8, -3.08945914184733e-6, 7.27768338038004e-6, 8.36427375361382e-7, 2.29028191824909e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.11983871459961, + "fY" : 39.9874572753906, + "fZ" : 190.759826660156, + "fTx" : 0.0620537921786308, + "fTy" : 0.206056728959084, + "fQp" : 0.286139667034149, + "fCovMatrix" : [0.00119367893785238, 0.00193155149463564, 2.52228346653283e-5, 1.92373408935964e-5, 7.64093638281338e-5, 0.0246099624782801, 4.20779288106132e-5, 2.31990285101347e-4, 1.01877601991873e-4, 1.02140506896831e-6, 4.58338035969064e-7, 3.38780637321179e-6, 3.69359349861043e-6, 9.96966150523804e-7, 2.29560191655764e-5] + }, + "fFlag" : -1, + "fChi2" : 1.323198, + "fNDF" : 11, + "fB" : 0, + "fLength" : 194.9633, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 9, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0835930556058884, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0259277746081352, + "fY" : 0.497226029634476, + "fZ" : -0.029397277161479, + "fTx" : -0.107399627566338, + "fTy" : -0.0284976586699486, + "fQp" : 0.165723696351051, + "fCovMatrix" : [0.00143562606535852, 0.00178038876038045, -3.84828381356783e-5, -9.68738731899066e-6, 4.74320513603743e-5, 0.0390435010194778, -3.6724977690028e-5, -2.58285814197734e-4, 9.36405267566442e-5, 2.05063588509802e-6, 2.00309884235139e-7, -1.42571036576555e-6, 3.52463871422515e-6, -5.25847838162008e-7, 8.69256200530799e-6] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -12.2916278839111, + "fY" : -17.5992946624756, + "fZ" : 627.099975585938, + "fTx" : 0.00854089763015509, + "fTy" : -0.0289660077542067, + "fQp" : 0.166625663638115, + "fCovMatrix" : [0.148046761751175, -0.0303253699094057, 4.45078534539789e-4, -6.29990681773052e-5, 8.43557121697813e-4, 0.261670053005219, -7.34995119273663e-5, 6.11280789598823e-4, -1.67856240295805e-4, 4.74621310786461e-6, -1.55629805931312e-7, 2.18870354729006e-6, 4.95414224133128e-6, -3.70353092193909e-7, 7.84113217378035e-6] + }, + "fFlag" : -1, + "fChi2" : 1.703628, + "fNDF" : 11, + "fB" : 0, + "fLength" : 627.9094, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 10, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 36, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.981190015078161, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0277214013040066, + "fPidTof400" : [], + "fPidTof700" : [0.264831582444079, 0.099058080392236, 0.118656458213957, 0.0976499434722578, 0.0698905569127598, 0.0246110081281543, 0.253963106951953, 0.0713392634846027], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0660625994205475, + "fY" : 0.156047880649567, + "fZ" : -0.029397277161479, + "fTx" : 0.232560113072395, + "fTy" : -0.163165777921677, + "fQp" : 0.255133837461472, + "fCovMatrix" : [5.06653159391135e-4, -0.00217646267265081, -1.92137031262973e-5, 1.41351611091522e-5, 5.27632182638627e-5, 0.0859930515289307, 2.56181083386764e-5, -6.11333991400898e-4, -2.69352440227522e-5, 3.37526330440596e-6, -2.34994359971097e-7, -2.33265086535539e-6, 7.68585505284136e-6, -3.95814048204102e-8, 1.58123348228401e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 55.0374336242676, + "fY" : -31.1423664093018, + "fZ" : 186.27587890625, + "fTx" : 0.366489827632904, + "fTy" : -0.175483256578445, + "fQp" : 0.255306541919708, + "fCovMatrix" : [0.00105818000156432, -0.00150494289118797, 2.36668620345881e-5, -1.8978571461048e-5, 6.11486830166541e-5, 0.023076020181179, -3.95588904211763e-5, 2.58579704677686e-4, -8.41691216919571e-5, 1.04949799606402e-6, -4.62299027503832e-7, 2.83598228634219e-6, 4.9294499149255e-6, -7.70337180711067e-7, 1.57309768837877e-5] + }, + "fFlag" : -1, + "fChi2" : 5.110947, + "fNDF" : 11, + "fB" : 0, + "fLength" : 197.0814, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 11, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.316398054361343, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.029531504958868, + "fY" : -0.30577677488327, + "fZ" : -0.029397277161479, + "fTx" : -0.418623745441437, + "fTy" : -0.0700498446822166, + "fQp" : 1.17042815685272, + "fCovMatrix" : [0.0015906278276816, 0.00322215468622744, -1.27519058878534e-4, -3.8563332054764e-5, 1.79388167452998e-4, 0.099520243704319, -8.62178494571708e-5, -0.00140073359943926, 2.56149884080514e-4, 1.46425547427498e-4, 4.58337945019593e-6, -1.46780648719869e-5, 1.47418890264817e-4, -3.48796061189205e-6, 2.41092668147758e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -26.1258335113525, + "fY" : -11.6612462997437, + "fZ" : 185.833938598633, + "fTx" : 0.142297178506851, + "fTy" : -0.054171446710825, + "fQp" : 1.1889933347702, + "fCovMatrix" : [0.00134163885377347, -0.00245691742748022, 5.10454046889208e-5, -3.7505309592234e-5, 1.53668865095824e-4, 0.0273020192980766, -1.37132912641391e-4, 3.72970214812085e-4, -3.93421592889354e-4, 5.40775272384053e-6, -1.81297491508303e-6, 1.40981837830623e-5, 1.20690865514916e-5, -4.63336573375273e-6, 2.43694987148046e-4] + }, + "fFlag" : -1, + "fChi2" : 24.69871, + "fNDF" : 11, + "fB" : 0, + "fLength" : 189.8812, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 12, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.779283165931702, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0240551009774208, + "fY" : 0.674277245998383, + "fZ" : -0.029397277161479, + "fTx" : 0.176159054040909, + "fTy" : -0.177063018083572, + "fQp" : 0.37081640958786, + "fCovMatrix" : [0.0010780377779156, -8.84766515810043e-4, -4.12856061302591e-5, 6.88902537149261e-6, 9.13657931960188e-5, 0.0734804943203926, -1.65775963978376e-5, -6.55427982565016e-4, 1.44494799314998e-4, 7.058639312163e-6, -9.47400913275942e-9, -3.75339618585713e-6, 1.29052205011249e-5, -1.64153811965662e-6, 2.84535872197011e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 49.4424476623535, + "fY" : -33.5017509460449, + "fZ" : 186.244964599609, + "fTx" : 0.368892908096313, + "fTy" : -0.193302035331726, + "fQp" : 0.372141301631927, + "fCovMatrix" : [0.00215255655348301, -0.00685461703687906, 3.92403235309757e-5, -6.76833660691045e-5, 9.6430660050828e-5, 0.0515968352556229, -1.1207955685677e-4, 5.03702322021127e-4, -2.41851797909476e-4, 1.51022993577499e-6, -1.23772463211935e-6, 4.18293348047882e-6, 6.72852365823928e-6, -2.80614221992437e-6, 2.82885594060645e-5] + }, + "fFlag" : -1, + "fChi2" : 0.719115, + "fNDF" : 9, + "fB" : 0, + "fLength" : 196.2505, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 13, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.20367656648159, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0617795810103416, + "fY" : 0.293817669153214, + "fZ" : -0.029397277161479, + "fTx" : 0.231379643082619, + "fTy" : 0.096101388335228, + "fQp" : 1.22818338871002, + "fCovMatrix" : [0.00403393572196364, 0.00236393650993705, -3.13459051540121e-4, -2.8485423172242e-5, 3.93314432585612e-4, 0.146797671914101, 9.8125246950076e-7, -0.00196340912953019, -2.53541278652847e-4, 1.44722478580661e-4, 2.66153642769495e-6, -2.52219087997219e-5, 1.60045368829742e-4, 6.95107792125782e-6, 3.55977565050125e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 58.0685119628906, + "fY" : 13.1218519210815, + "fZ" : 128.266860961914, + "fTx" : 0.735637307167053, + "fTy" : 0.110303997993469, + "fQp" : 1.2478494644165, + "fCovMatrix" : [0.00186582887545228, 0.00535924965515733, 7.37560476409271e-5, 9.87442472251132e-5, 2.09176956559531e-4, 0.0458656288683414, 2.62276356806979e-4, 7.90530757512897e-4, 7.02802964951843e-4, 8.63070454215631e-6, 4.20958849645103e-6, 2.75256006716518e-5, 2.33199843933107e-5, 9.57082284003263e-6, 3.41619132086635e-4] + }, + "fFlag" : -1, + "fChi2" : 2.624995, + "fNDF" : 9, + "fB" : 0, + "fLength" : 143.5484, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 14, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.179138273000717, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0260817781090736, + "fY" : 0.36417630314827, + "fZ" : -0.029397277161479, + "fTx" : 0.373044222593307, + "fTy" : 0.170719236135483, + "fQp" : 0.585384905338287, + "fCovMatrix" : [0.00100781524088234, 0.00166274583898485, -4.68139005533885e-5, -2.35737807088299e-5, 1.44563353387639e-4, 0.095621332526207, -5.58875171918771e-6, -8.41636268887669e-4, 1.29279447719455e-4, 2.1956511773169e-5, 1.61192679115629e-6, -7.38532344257692e-6, 2.79109026450897e-5, -3.83259930458735e-6, 6.94699774612673e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 79.3677291870117, + "fY" : 28.174129486084, + "fZ" : 154.960510253906, + "fTx" : 0.673740983009338, + "fTy" : 0.198277235031128, + "fQp" : 0.583659291267395, + "fCovMatrix" : [0.00126076629385352, -0.00243792682886124, 4.26691185566597e-5, -2.5351766453241e-5, 1.08721644210164e-4, 0.0306138880550861, -1.34073343360797e-4, 3.3120164880529e-4, -3.81166988518089e-4, 3.79051311938383e-6, -5.50403228771756e-7, 8.82440872373991e-6, 8.84583005245076e-6, -1.61029106493515e-6, 6.83862963342108e-5] + }, + "fFlag" : -1, + "fChi2" : 2.896034, + "fNDF" : 9, + "fB" : 0, + "fLength" : 177.5232, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 15, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.12270288169384, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0483073107898235, + "fY" : 0.393165171146393, + "fZ" : -0.029397277161479, + "fTx" : -0.644379854202271, + "fTy" : -0.0592610761523247, + "fQp" : 0.85918128490448, + "fCovMatrix" : [0.00376315508037806, 0.00458553526550531, -3.42107960022986e-4, -5.83488363190554e-5, 3.93477501347661e-4, 0.178966328501701, -1.13283669634257e-4, -0.00210009817965329, 7.97470158431679e-4, 1.28874045913108e-4, 4.61120998807019e-6, -2.46611161855981e-5, 1.15384376840666e-4, -5.94538005316281e-6, 2.37791973631829e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -94.1140823364258, + "fY" : -19.8559474945068, + "fZ" : 605.900024414062, + "fTx" : -0.0226183347404003, + "fTy" : -0.0160221420228481, + "fQp" : 0.912991106510162, + "fCovMatrix" : [0.733367383480072, 1.0477769683348e-4, 0.00341560994274914, 2.05661308427807e-6, 3.92372399801388e-4, 0.702567219734192, -5.40282280780957e-6, 0.00354262278415263, 1.75905952346511e-4, 4.54554756288417e-5, -1.43423610765581e-8, 6.49140361019818e-7, 4.53696411568671e-5, 1.24108589716343e-6, 2.2716514649801e-4] + }, + "fFlag" : -1, + "fChi2" : 19.51908, + "fNDF" : 9, + "fB" : 0, + "fLength" : 621.7869, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 16, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : 5, + "fTof2Hit" : 51, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : 0.824839869161684, + "fBeta700" : 0.78413891117737, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0789182558655739, + "fPidTof400" : [0.371941016941938, 0.102499799654331, 0.179855863574656, 0.0983373147844284, 0.0578651987152106, 0.0389610684070502, 0.0921986281773345, 0.0583411097450511], + "fPidTof700" : [0.840198601123537, 0.0225780273705623, 0.0345356921530953, 0.0218340212657471, 0.01834113077067, 0.011741656473423, 0.0322547736695629, 0.018516097173403], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0270361006259918, + "fY" : 0.617177248001099, + "fZ" : -0.029397277161479, + "fTx" : 0.0507588386535645, + "fTy" : -0.378645896911621, + "fQp" : 0.854494571685791, + "fCovMatrix" : [0.00147134403232485, -0.00451167533174157, -1.01672383607365e-4, 7.60751572670415e-5, 4.14297945098951e-4, 0.180836632847786, 1.07913074316457e-4, -0.00251592299900949, -0.00162807607557625, 5.15010979142971e-5, -3.40793894793023e-6, -2.64719310507644e-5, 9.45847568800673e-5, 3.66812273568939e-5, 4.03933663619682e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 14.6517648696899, + "fY" : -36.9337005615234, + "fZ" : 97.2979049682617, + "fTx" : 0.267938584089279, + "fTy" : -0.39751985669136, + "fQp" : 0.858786880970001, + "fCovMatrix" : [0.0020041186362505, 0.0062880627810955, 7.17065486242063e-5, 1.29548876429908e-4, 4.24215395469218e-4, 0.0527210347354412, 2.48639262281358e-4, 0.00104399619158357, 0.00170484441332519, 5.03440105603659e-6, 3.60055105375068e-6, 3.17915582854766e-5, 3.6310881114332e-5, 2.93589273496764e-5, 4.00858378270641e-4] + }, + "fFlag" : -1, + "fChi2" : 0.8979174, + "fNDF" : 7, + "fB" : 0, + "fLength" : 105.7154, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 17, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.146498799324036, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0211788676679134, + "fY" : 0.264890640974045, + "fZ" : -0.029397277161479, + "fTx" : 0.0602984353899956, + "fTy" : -0.0695310831069946, + "fQp" : 0.231331944465637, + "fCovMatrix" : [0.0574447922408581, 0.0230465475469828, -7.54404463805258e-4, -1.2372930359561e-4, 0.00118127150926739, 0.107154481112957, -2.66663468210027e-4, -7.53610976971686e-4, 6.10624963883311e-4, 1.22538394862204e-5, 1.43956913234433e-6, -1.50341811604449e-5, 9.04982425709022e-6, -3.36638117914845e-6, 3.8673428207403e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 32.1994171142578, + "fY" : -17.4566535949707, + "fZ" : 248.743057250977, + "fTx" : 0.199927106499672, + "fTy" : -0.0728905349969864, + "fQp" : 0.232502847909927, + "fCovMatrix" : [0.00115935911890119, -0.0017235407140106, 2.88825049210573e-5, -1.94963467947673e-5, 1.19995631393977e-4, 0.0224260333925486, -5.84204062761273e-5, 2.16226137126796e-4, -2.78120045550168e-4, 1.31434103423089e-6, -7.26508289972116e-7, 5.67927645533928e-6, 3.21425773108786e-6, -3.81498466595076e-6, 3.85692983400077e-5] + }, + "fFlag" : -1, + "fChi2" : 0.9973078, + "fNDF" : 7, + "fB" : 0, + "fLength" : 251.7808, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 18, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.213376849889755, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0265165511518717, + "fY" : 0.598047256469727, + "fZ" : -0.029397277161479, + "fTx" : 0.00665936945006251, + "fTy" : -0.261780083179474, + "fQp" : 0.45001232624054, + "fCovMatrix" : [0.00199006428010762, 5.24522620253265e-4, -8.60151048982516e-5, -1.23626432468882e-5, 3.79494274966419e-4, 0.144032061100006, -1.25099832075648e-4, -0.00155290775001049, 0.00102622515987605, 1.2004950804112e-5, 1.56970281750546e-6, -1.71131014212733e-5, 2.81398060906213e-5, -1.31918177430634e-5, 1.45577345392667e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.8525915145874, + "fY" : -31.998348236084, + "fZ" : 123.511558532715, + "fTx" : 0.144777610898018, + "fTy" : -0.267102360725403, + "fQp" : 0.451087117195129, + "fCovMatrix" : [0.0014291099505499, -0.0032419697381556, 4.93956431455445e-5, -6.88998552504927e-5, 2.42930182139389e-4, 0.0350515246391296, -1.43318975460716e-4, 6.34233001619577e-4, -6.86827290337533e-4, 3.12987617689942e-6, -3.23209337693697e-6, 1.69907871168107e-5, 1.81877385330154e-5, -1.51279182318831e-5, 1.4542366261594e-4] + }, + "fFlag" : -1, + "fChi2" : 1.26801, + "fNDF" : 7, + "fB" : 0, + "fLength" : 128.2301, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 19, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.127429127693176, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.184611901640892, + "fY" : 0.671454608440399, + "fZ" : -0.029397277161479, + "fTx" : 0.0760625302791595, + "fTy" : -0.317902356386185, + "fQp" : -1.61735594272614, + "fCovMatrix" : [0.00308883422985673, -0.00466789305210114, -2.43805014179088e-4, 8.51078075356781e-5, 6.88052852638066e-4, 0.189663529396057, 1.16647715913132e-4, -0.00286581763066351, -7.18182127457112e-5, 1.14074267912656e-4, -5.64381707590655e-6, -5.61336091777775e-5, 1.66277313837782e-4, 1.80466577148763e-5, 0.00109390704892576] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.2619371414185, + "fY" : -30.3149681091309, + "fZ" : 97.207145690918, + "fTx" : -0.3241907954216, + "fTy" : -0.32882833480835, + "fQp" : -1.62593746185303, + "fCovMatrix" : [0.00208903150632977, 0.00674401968717575, 8.48563431645744e-5, 1.50043764733709e-4, 4.01053373934701e-4, 0.0551445372402668, 3.204517706763e-4, 0.00114413211122155, 0.00138048059307039, 1.01180758065311e-5, 5.6384528761555e-6, 6.00225175730884e-5, 4.38956740254071e-5, 1.84727196028689e-5, 0.00107722356915474] + }, + "fFlag" : -1, + "fChi2" : 2.507782, + "fNDF" : 7, + "fB" : 0, + "fLength" : 103.4519, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 20, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.25052347779274, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0657527521252632, + "fY" : 0.585246980190277, + "fZ" : -0.029397277161479, + "fTx" : 0.166888251900673, + "fTy" : -0.223062187433243, + "fQp" : 0.494734257459641, + "fCovMatrix" : [0.00211634044535458, 5.25640149135143e-4, -9.03631007531658e-5, -1.00845736596966e-5, 3.96233925130218e-4, 0.145723015069962, -1.21151497296523e-4, -0.0015668214764446, 9.32940165512264e-4, 1.45359554153401e-5, 1.05100161817973e-6, -1.75148707057815e-5, 3.0253077056841e-5, -1.15782904686057e-5, 1.43525379826315e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 30.012149810791, + "fY" : -27.715295791626, + "fZ" : 123.628150939941, + "fTx" : 0.329684227705002, + "fTy" : -0.236884519457817, + "fQp" : 0.496926605701447, + "fCovMatrix" : [0.00145258323755115, -0.0033528795465827, 5.184545807424e-5, -7.23689227015711e-5, 2.35452040215023e-4, 0.0356061942875385, -1.54099107021466e-4, 6.50815549306571e-4, -6.81751174852252e-4, 3.47621858054481e-6, -3.51407697962713e-6, 1.70653893292183e-5, 1.8816896044882e-5, -1.5315948985517e-5, 1.42825228977017e-4] + }, + "fFlag" : -1, + "fChi2" : 5.733225, + "fNDF" : 7, + "fB" : 0, + "fLength" : 130.673, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 21, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.11856509745121, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0218580476939678, + "fY" : 0.629203677177429, + "fZ" : -0.029397277161479, + "fTx" : 0.0626749098300934, + "fTy" : -0.38428658246994, + "fQp" : 0.490630775690079, + "fCovMatrix" : [0.00101967749651521, -0.00444304011762142, -5.33855709363706e-5, 7.46301666367799e-5, 3.33140487782657e-4, 0.177638679742813, 1.07444931927603e-4, -0.00239206408150494, -0.00144222122617066, 1.40433867272804e-5, -2.7796868380392e-6, -1.87960813491372e-5, 5.00846144859679e-5, 3.23565327562392e-5, 2.28346092626452e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 11.5724449157715, + "fY" : -37.1252288818359, + "fZ" : 97.2810516357422, + "fTx" : 0.184642106294632, + "fTy" : -0.393206566572189, + "fQp" : 0.491282910108566, + "fCovMatrix" : [0.0019843983463943, 0.00619267066940665, 6.76561103318818e-5, 1.29911699332297e-4, 4.06330276746303e-4, 0.0522433407604694, 2.30213481700048e-4, 0.00104126078076661, 0.00156744290143251, 3.52676556758524e-6, 3.81714471586747e-6, 2.33595692407107e-5, 3.48855210177135e-5, 2.8559716156451e-5, 2.27711803745478e-4] + }, + "fFlag" : -1, + "fChi2" : 7.035285, + "fNDF" : 7, + "fB" : 0, + "fLength" : 105.1616, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 22, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.168071672320366, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0474835783243179, + "fY" : 0.78285539150238, + "fZ" : -0.029397277161479, + "fTx" : -0.039885189384222, + "fTy" : -0.0637722164392471, + "fQp" : 0.210131198167801, + "fCovMatrix" : [0.0561482682824135, 0.0274022594094276, -7.35882786102593e-4, -1.61013696924783e-4, 0.00125679664779454, 0.129250317811966, -3.34718672093004e-4, -9.15000098757446e-4, 8.5243140347302e-4, 1.16585915748146e-5, 2.02640694624279e-6, -1.6065296222223e-5, 9.78590742306551e-6, -5.31669820702518e-6, 4.20234391640406e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 42.9485397338867, + "fY" : -39.0178604125977, + "fZ" : 597.099975585938, + "fTx" : 0.111159361898899, + "fTy" : -0.0674694031476974, + "fQp" : 0.220070779323578, + "fCovMatrix" : [0.27581062912941, -0.113243870437145, 7.99520348664373e-4, -2.47204530751333e-4, 0.00246219406835735, 0.466205537319183, -3.06058267597109e-4, 0.00106651033274829, -8.55989404954016e-4, 3.14367594000942e-6, -6.80913501582836e-7, 7.30455985831213e-6, 3.31925457430771e-6, -1.96429277821153e-6, 3.07057962345425e-5] + }, + "fFlag" : -1, + "fChi2" : 6.698724, + "fNDF" : 5, + "fB" : 0, + "fLength" : 600.5325, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 23, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 25, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.978990160074654, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.322582691907883, + "fPidTof400" : [], + "fPidTof700" : [0.644231726842223, 0.0664468963396918, 0.0872551431364887, 0.0650876397940315, 0.0280942881718885, 0.011603313325726, 0.0687209491232589, 0.028560043266692], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0269705541431904, + "fY" : 0.86626672744751, + "fZ" : -0.029397277161479, + "fTx" : -0.296288967132568, + "fTy" : 0.0620612986385822, + "fQp" : -1.67327976226807, + "fCovMatrix" : [0.00480414787307382, -0.013381153345108, -3.17799451295286e-4, 2.98244412988424e-4, 0.0024010946508497, 0.430685579776764, 4.40666102804244e-4, -0.00748321134597063, -0.0048612505197525, 1.33756286231801e-4, -1.45052717925864e-5, -1.56944210175425e-4, 2.52640224061906e-4, 1.49373343447223e-4, 0.00213810801506042] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -29.1511573791504, + "fY" : 5.16933584213257, + "fZ" : 65.8757781982422, + "fTx" : -0.621299684047699, + "fTy" : 0.0697667375206947, + "fQp" : -1.68280816078186, + "fCovMatrix" : [0.00207065301947296, 0.00739669566974044, 1.5232952137012e-4, 2.03452989808284e-4, 0.00115508679300547, 0.0626869574189186, 5.78183040488511e-4, 0.00173771800473332, 0.00466901436448097, 1.66032168635866e-5, 1.37709239425021e-5, 1.00848628790118e-4, 1.44337231176905e-4, 1.39568408485502e-4, 0.00202691182494164] + }, + "fFlag" : -1, + "fChi2" : 0.2271775, + "fNDF" : 5, + "fB" : 0, + "fLength" : 73.08131, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 24, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.400149792432785, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.53253877162933, + "fY" : 2.21172761917114, + "fZ" : -0.029397277161479, + "fTx" : -0.0300991535186768, + "fTy" : 0.0320842824876308, + "fQp" : 0.172622725367546, + "fCovMatrix" : [0.16963754594326, 0.017030593007803, -0.00184271612670273, -2.05997530429158e-5, 0.00341897248290479, 0.197976991534233, -1.13096597488038e-4, -0.00117654190398753, 1.00956378446426e-4, 2.07278790185228e-5, -1.55807782675765e-7, -3.75098570657428e-5, 8.69890664034756e-6, 1.15531929623103e-6, 8.51549120852724e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 37.985050201416, + "fY" : 20.02707862854, + "fZ" : 597.099975585938, + "fTx" : 0.0948549509048462, + "fTy" : 0.0276641175150871, + "fQp" : 0.183003291487694, + "fCovMatrix" : [0.444777190685272, 0.0305360313504934, 0.0021095525007695, -2.7875737487193e-6, 0.00371088227257133, 0.507221102714539, 3.36427910951898e-5, 0.00198251358233392, 5.01687463838607e-5, 1.77293622982688e-5, 1.26534516198262e-8, 6.10570623393869e-6, 1.72857144207228e-5, -4.63965051267223e-7, 6.02575310040265e-5] + }, + "fFlag" : -1, + "fChi2" : 3.748917, + "fNDF" : 5, + "fB" : 0, + "fLength" : 598.9304, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 25, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 28, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.94725859496145, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 2.29666018486023, + "fPidTof400" : [], + "fPidTof700" : [0.0415304638190809, 0.031574482504858, 0.0337090888263306, 0.0314008064952473, 0.404591798136961, 0.0348745042397562, 0.0673819225101498, 0.354936933467617], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0261322315782309, + "fY" : 0.672808051109314, + "fZ" : -0.029397277161479, + "fTx" : -0.015124392695725, + "fTy" : 0.11842468380928, + "fQp" : 0.258600860834122, + "fCovMatrix" : [0.00573420384898782, 0.0115867666900158, -2.22130765905604e-4, -1.98144538444467e-4, 0.00165110838133842, 0.360558211803436, -3.23505606502295e-4, -0.00477726384997368, 0.00326071726158261, 1.12036650534719e-5, 6.37417360849213e-6, -6.61796366330236e-5, 6.99954543961212e-5, -6.32923911325634e-5, 5.69206080399454e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.04422128200531, + "fY" : 11.5715970993042, + "fZ" : 92.2562408447266, + "fTx" : 0.0397122837603092, + "fTy" : 0.117785260081291, + "fQp" : 0.259079456329346, + "fCovMatrix" : [0.0019244517898187, -0.00591123849153519, 8.24297530925833e-5, -1.79509283043444e-4, 7.10876774974167e-4, 0.0508608967065811, -2.78832420008257e-4, 0.00141337746754289, -0.00265289493836462, 5.02301281812834e-6, -6.6773113758245e-6, 5.02329530718271e-5, 6.71694069751538e-5, -6.46529588266276e-5, 5.70721633266658e-4] + }, + "fFlag" : -1, + "fChi2" : 0.9697773, + "fNDF" : 5, + "fB" : 0, + "fLength" : 92.94762, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 26, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.202112466096878, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0650663748383522, + "fY" : 0.752111494541168, + "fZ" : -0.029397277161479, + "fTx" : 0.0998178720474243, + "fTy" : -0.0871179550886154, + "fQp" : 0.432712346315384, + "fCovMatrix" : [0.0072921933606267, 0.00709884241223335, -2.55254155490547e-4, -9.13754774956033e-5, 0.00111449335236102, 0.194643661379814, -3.62266961019486e-4, -0.00215245992876589, 0.0025608807336539, 1.59097653522622e-5, 4.36912660006783e-6, -4.32320339314174e-5, 3.38455211021937e-5, -3.23116764775477e-5, 3.40189901180565e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 130.623626708984, + "fY" : -40.7317199707031, + "fZ" : 418.510986328125, + "fTx" : 0.435034066438675, + "fTy" : -0.10467367619276, + "fQp" : 0.449056595563889, + "fCovMatrix" : [0.237828284502029, -0.00405357731506228, 0.0010494802845642, 9.03557884157635e-6, 0.00171555520500988, 0.122831404209137, -1.28254732771893e-5, 3.97770665585995e-4, 9.06293371372158e-6, 1.19462147267768e-5, -2.69630845650681e-7, 8.22162201075116e-6, 8.13378301245393e-6, 1.14923835781156e-7, 3.84919003408868e-5] + }, + "fFlag" : -1, + "fChi2" : 2.270605, + "fNDF" : 5, + "fB" : 0, + "fLength" : 441.7074, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 27, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : 3, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : 0.944945620734558, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.282895892858505, + "fPidTof400" : [0.367648475365766, 0.127063850850765, 0.205042066366208, 0.122866346238009, 0.0401267387508722, 0.0218435322333356, 0.0748099160462014, 0.0405990741488423], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.42327404022217, + "fY" : -0.326961070299149, + "fZ" : -0.029397277161479, + "fTx" : -0.0146566452458501, + "fTy" : 0.0585484281182289, + "fQp" : 0.223260626196861, + "fCovMatrix" : [0.158489212393761, 0.0182309299707413, -0.00171128590591252, -2.75821930699749e-5, 0.00347473053261638, 0.187137201428413, -1.24398502521217e-4, -0.00103616446722299, 1.26505750813521e-4, 1.89588517969241e-5, -8.85600570654788e-8, -3.83404294552747e-5, 6.71664110996062e-6, 1.00011595804972e-6, 8.77205238793977e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 57.5408630371094, + "fY" : 34.4138870239258, + "fZ" : 605.900024414062, + "fTx" : 0.139108642935753, + "fTy" : 0.0569998435676098, + "fQp" : 0.210490927100182, + "fCovMatrix" : [0.393921136856079, 0.0393110178411007, 0.00115129828918725, 5.51040066056885e-5, 0.00425325985997915, 0.467863172292709, 9.65387298492715e-5, 0.00112714653369039, -8.35825812828261e-6, 4.31362559538684e-6, 1.26172437830974e-7, 1.26203412946779e-5, 3.70305133401416e-6, -4.76045869390873e-7, 5.79466977796983e-5] + }, + "fFlag" : -1, + "fChi2" : 13.67719, + "fNDF" : 5, + "fB" : 0, + "fLength" : 610.8903, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 28, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 18, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.961042344437543, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 3.5486433506012, + "fPidTof400" : [], + "fPidTof700" : [0.163541824372634, 0.0752980829855243, 0.0879493177328712, 0.0743604180735853, 0.0748810563531657, 0.0254346008230213, 0.421924078710961, 0.076610620948237], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.00911172479391098, + "fY" : -0.164421364665031, + "fZ" : -0.029397277161479, + "fTx" : -0.263669341802597, + "fTy" : 0.312872141599655, + "fQp" : 2.44544816017151, + "fCovMatrix" : [0.0111502641811967, -0.00783455837517977, -0.00132511043921113, 2.06394455744885e-4, 0.00329444627277553, 0.303729832172394, 2.42670794250444e-4, -0.00564314238727093, 0.0024704618845135, 0.00162572483532131, -1.28985644550994e-4, -2.56872037425637e-4, 0.00173591135535389, -3.69936387869529e-5, 0.00438861642032862] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.69932627677917, + "fY" : 27.9923896789551, + "fZ" : 92.2562408447266, + "fTx" : 0.326712906360626, + "fTy" : 0.314964473247528, + "fQp" : 2.5777063369751, + "fCovMatrix" : [0.0019453507848084, -0.00591527670621872, 1.0935653699562e-4, -1.62201758939773e-4, 7.15228088665754e-4, 0.0500840172171593, -4.09632222726941e-4, 0.00128573877736926, -0.00303747202269733, 2.28120879910421e-5, -3.43982901540585e-6, 1.61356016178615e-4, 7.76000015321188e-5, -4.8420228267787e-5, 0.00437125051394105] + }, + "fFlag" : -1, + "fChi2" : 12.98925, + "fNDF" : 5, + "fB" : 0, + "fLength" : 97.86718, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 29, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.635798931121826, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.205629661679268, + "fY" : -2.07671427726746, + "fZ" : -0.029397277161479, + "fTx" : -0.101186849176884, + "fTy" : 0.187364757061005, + "fQp" : 0.457021623849869, + "fCovMatrix" : [0.00312046287581325, 0.00223815767094493, -1.17492134450004e-4, -2.22616636165185e-5, 2.98019789624959e-4, 0.0929653644561768, -7.64726355555467e-5, -0.00100807147100568, 6.01950858253986e-4, 4.9029290494218e-6, 7.80315247084218e-7, -1.21380680866423e-5, 1.47311247928883e-5, -7.12718838258297e-6, 1.02549296570942e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.85358667373657, + "fY" : 26.7497463226318, + "fZ" : 154.893341064453, + "fTx" : 0.0682987794280052, + "fTy" : 0.18551504611969, + "fQp" : 0.458666443824768, + "fCovMatrix" : [0.00234777061268687, -0.00808644108474255, 4.71720522909891e-5, -8.98432699614204e-5, 1.90876264241524e-4, 0.0612202808260918, -1.42043427331373e-4, 6.91099616233259e-4, -5.6737702107057e-4, 2.28793101086922e-6, -1.78430468622537e-6, 1.14754893729696e-5, 1.07599435068551e-5, -7.92009814176708e-6, 1.02951998997014e-4] + }, + "fFlag" : -1, + "fChi2" : 18.17157, + "fNDF" : 5, + "fB" : 0, + "fLength" : 157.7993, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 30, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 2.55332398414612, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.220339760184288, + "fY" : 0.496376216411591, + "fZ" : -0.029397277161479, + "fTx" : -0.00211817072704434, + "fTy" : 0.0463929995894432, + "fQp" : 0.192528858780861, + "fCovMatrix" : [0.856019198894501, -0.456166356801987, -0.00840072520077229, 0.00226182793267071, 0.0166160743683577, 0.631114602088928, 0.00442369421944022, -0.00323805911466479, -0.00905261561274529, 8.46254843054339e-5, -2.20356432691915e-5, -1.63838849402964e-4, 1.9668965251185e-5, 4.52888671134133e-5, 3.39393533067778e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 59.8817138671875, + "fY" : 27.3704490661621, + "fZ" : 605.900024414062, + "fTx" : 0.133832946419716, + "fTy" : 0.0435036905109882, + "fQp" : 0.194726914167404, + "fCovMatrix" : [0.571133196353912, 0.166687563061714, 0.00170184893067926, 4.04814578359947e-4, 0.00755761843174696, 0.629211246967316, 4.91408747620881e-4, 0.00156522076576948, 0.00230193347670138, 5.77202399654198e-6, 1.20644983780949e-6, 2.28702065214748e-5, 4.64329423266463e-6, 5.85072166359168e-6, 1.16228613478597e-4] + }, + "fFlag" : -1, + "fChi2" : 1.136688, + "fNDF" : 3, + "fB" : 0, + "fLength" : 610.1001, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 31, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 17, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.959020259347422, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.256132513284683, + "fPidTof400" : [], + "fPidTof700" : [0.100323871326863, 0.0618762176814875, 0.0688716803211751, 0.0613313895791886, 0.135889689500624, 0.0316363397150543, 0.398927631656923, 0.141143180218685], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.594629168510437, + "fY" : -0.528902053833008, + "fZ" : -0.029397277161479, + "fTx" : -0.088595800101757, + "fTy" : 0.0164505969733, + "fQp" : 0.301856219768524, + "fCovMatrix" : [1.06943094730377, -0.462121158838272, -0.0106638744473457, 0.00227981200441718, 0.0175477415323257, 0.81369423866272, 0.00450004823505878, -0.00511496514081955, -0.00920255575329065, 1.12717963929754e-4, -2.23288261622656e-5, -1.74585802596994e-4, 4.31654116255231e-5, 4.5806937123416e-5, 3.64787119906396e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.0862729549408, + "fY" : 3.39191007614136, + "fZ" : 253.266006469727, + "fTx" : 0.0919949263334274, + "fTy" : 0.0146251767873764, + "fQp" : 0.308357298374176, + "fCovMatrix" : [0.00187728903256357, 0.00520153529942036, 6.91362147335894e-5, 8.78545251907781e-5, 5.24696835782379e-4, 0.0438745133578777, 2.42525129579008e-4, 6.81901117786765e-4, 0.00212102546356618, 4.1156172301271e-6, 4.55953340861015e-6, 3.50678055838216e-5, 1.42927547130967e-5, 4.36515038018115e-5, 3.64597100997344e-4] + }, + "fFlag" : -1, + "fChi2" : 0.4537788, + "fNDF" : 3, + "fB" : 0, + "fLength" : 253.7004, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 32, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.14597833156586, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.09693610668182, + "fY" : 0.910544335842133, + "fZ" : -0.029397277161479, + "fTx" : 0.0502183735370636, + "fTy" : 0.0284693744033575, + "fQp" : 0.075424924492836, + "fCovMatrix" : [0.838427007198334, -0.459652572870255, -0.00817697867751122, 0.00227581011131406, 0.0165521930903196, 0.610160529613495, 0.00446027610450983, -0.00299714901484549, -0.00912789348512888, 8.03524162620306e-5, -2.21804511966184e-5, -1.62804528372362e-4, 1.54056233441224e-5, 4.55905319540761e-5, 3.35209013428539e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 54.5434494018555, + "fY" : 18.9760284423828, + "fZ" : 605.900024414062, + "fTx" : 0.107005573809147, + "fTy" : 0.0305983368307352, + "fQp" : 0.0930930972099304, + "fCovMatrix" : [0.56563675403595, 0.16722559928894, 0.00174596754368395, 3.85296909371391e-4, 0.00747825298458338, 0.630052626132965, 4.69339312985539e-4, 0.00162073923274875, 0.00243019312620163, 6.25193024461623e-6, 1.09307734419417e-6, 2.14953815884655e-5, 5.22690470461384e-6, 5.85555244470015e-6, 1.14141497761011e-4] + }, + "fFlag" : -1, + "fChi2" : 1.849876, + "fNDF" : 3, + "fB" : 0, + "fLength" : 608.6982, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 33, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 16, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.964560714384518, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.21388041973114, + "fPidTof400" : [], + "fPidTof700" : [0.10117938835824, 0.0942040931723345, 0.0959314236723074, 0.0940568189165485, 0.130333869166391, 0.243004121015255, 0.111581046200226, 0.129709239498698], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.246271401643753, + "fY" : 0.686478555202484, + "fZ" : -0.029397277161479, + "fTx" : 0.100004196166992, + "fTy" : -0.0179095789790154, + "fQp" : 0.224228218197823, + "fCovMatrix" : [1.69934582710266, 0.65160471200943, -0.0165731161832809, -0.00302895391359925, 0.0309155844151974, 0.740846633911133, -0.00629291869699955, -0.00405672565102577, 0.0124902306124568, 1.65061966981739e-4, 2.93027151201386e-5, -3.01817432045937e-4, 2.81286993413232e-5, -5.82969296374358e-5, 6.03647727984935e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 142.015197753906, + "fY" : -11.789249420166, + "fZ" : 635.900024414062, + "fTx" : 0.261783063411713, + "fTy" : -0.019876891747117, + "fQp" : 0.226378262042999, + "fCovMatrix" : [0.730842769145966, -0.143765032291412, 0.00208974187262356, -2.76358332484961e-4, 0.00865746289491653, 0.679372608661652, -3.38425335939974e-4, 0.00169669126626104, -0.00208298489451408, 1.00880961326766e-5, -6.78339972637332e-7, 2.09066220122622e-5, 8.40418761072215e-6, -4.18415947933681e-6, 1.39396972372197e-4] + }, + "fFlag" : -1, + "fChi2" : 0.7122054, + "fNDF" : 3, + "fB" : 0, + "fLength" : 652.5759, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 34, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 11, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.961074312249346, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.302201956510544, + "fPidTof400" : [], + "fPidTof700" : [0.16953417865818, 0.0772015667756544, 0.0903175448300243, 0.0762310570567533, 0.0754740336517106, 0.0258108121152269, 0.408230231610065, 0.0772005753023855], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.31043136119843, + "fY" : 0.955302178859711, + "fZ" : -0.029397277161479, + "fTx" : 0.118221916258335, + "fTy" : 0.080058217048645, + "fQp" : 0.304001986980438, + "fCovMatrix" : [0.71472954750061, 0.382430553436279, -0.0081872995942831, -0.00216610520146787, 0.0187111124396324, 0.500702857971191, -0.00434806989505887, -0.00290845660492778, 0.0101454136893153, 9.55057694227435e-5, 2.47198422584916e-5, -2.16604617889971e-4, 1.89319252967834e-5, -5.7865894632414e-5, 5.11259189806879e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 182.258880615234, + "fY" : 54.7707633972168, + "fZ" : 635.900024414062, + "fTx" : 0.336056143045425, + "fTy" : 0.0871101394295692, + "fQp" : 0.289522975683212, + "fCovMatrix" : [0.853387951850891, -0.0890597105026245, 0.00231860484927893, -9.03638356248848e-5, 0.0064244456589222, 0.737602531909943, -1.39394192956388e-4, 0.00185612577479333, -0.00130663730669767, 1.10044711618684e-5, -1.21694503363301e-8, 1.13985988718923e-5, 9.43024042499019e-6, -1.70210228134238e-6, 9.79300020844676e-5] + }, + "fFlag" : -1, + "fChi2" : 1.942739, + "fNDF" : 3, + "fB" : 0, + "fLength" : 665.3834, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 35, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 44, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.943914470571102, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.36478054523468, + "fPidTof400" : [], + "fPidTof700" : [0.299908382087893, 0.0963566464599368, 0.118141380702889, 0.0948122947218994, 0.0706504221956119, 0.028977843999243, 0.21920849937744, 0.0719445304550872], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.252122759819031, + "fY" : 0.321497887372971, + "fZ" : -0.029397277161479, + "fTx" : -0.102842479944229, + "fTy" : 0.108841717243195, + "fQp" : 0.559573948383331, + "fCovMatrix" : [0.256441533565521, 0.0546441897749901, -0.00284473551437259, -2.32375226914883e-4, 0.00498967245221138, 0.317853808403015, -4.59515140391886e-4, -0.00212748255580664, 7.54551903810352e-4, 4.81743991258554e-5, 1.53570385919011e-6, -5.81435924686957e-5, 3.23050117003731e-5, -2.43649560616177e-6, 1.43535420647822e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 126.55753326416, + "fY" : 66.642333984375, + "fZ" : 627.099975585938, + "fTx" : 0.301141917705536, + "fTy" : 0.104078777134418, + "fQp" : 0.552973508834839, + "fCovMatrix" : [0.532510101795197, 0.0278261322528124, 0.00150426605250686, 2.44738821493229e-5, 0.00452664634212852, 0.669826984405518, 4.28096900577657e-5, 0.00156850682105869, -6.47904933430254e-4, 1.31127917484264e-5, 2.68308809836526e-7, 1.29740210468299e-5, 1.20586528282729e-5, -1.80539052507811e-6, 9.89683685475029e-5] + }, + "fFlag" : -1, + "fChi2" : 5.43474, + "fNDF" : 3, + "fB" : 0, + "fLength" : 648.571, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 36, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 46, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.87911074165808, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.263937652111053, + "fPidTof400" : [], + "fPidTof700" : [0.750915369238995, 0.0399837095214084, 0.0555775724630657, 0.0389796081023081, 0.0248800841573318, 0.0137625154800943, 0.0507148910696421, 0.0251862499671541], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.35125255584717, + "fY" : -5.16963291168213, + "fZ" : -0.029397277161479, + "fTx" : 0.0455385223031044, + "fTy" : 0.0973970219492912, + "fQp" : -0.328985333442688, + "fCovMatrix" : [0.191143482923508, -0.139769360423088, -0.00275204074569046, 9.80156473815441e-4, 0.00684849871322513, 0.325831949710846, 0.00194071175064892, -0.00250163651071489, -0.0058176857419312, 4.03635312977713e-5, -1.37330607685726e-5, -9.97970928438008e-5, 2.20568235818064e-5, 4.17378359998111e-5, 3.08208429487422e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 3.08387875556946, + "fY" : 13.6549243927002, + "fZ" : 190.759826660156, + "fTx" : -0.10558620095253, + "fTy" : 0.100344710052013, + "fQp" : -0.331057548522949, + "fCovMatrix" : [0.00188889005221426, 0.0052486308850348, 7.33881024643779e-5, 8.69609430083074e-5, 4.84872958622873e-4, 0.0440538413822651, 2.59661668678746e-4, 6.78094103932381e-4, 0.00196568109095097, 4.63806691186619e-6, 4.78684660265571e-6, 3.48159555869643e-5, 1.40232677949825e-5, 3.92855836253148e-5, 3.06403584545478e-4] + }, + "fFlag" : -1, + "fChi2" : 1.668341, + "fNDF" : 3, + "fB" : 0, + "fLength" : 192.0008, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 37, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 10.0490455627441, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.28303253650665, + "fY" : 1.30700790882111, + "fZ" : -0.029397277161479, + "fTx" : 0.0388444475829601, + "fTy" : 0.022368460893631, + "fQp" : 0.203636944293976, + "fCovMatrix" : [0.885250806808472, -0.456907033920288, -0.00862818583846092, 0.00226107379421592, 0.0165749415755272, 0.655868411064148, 0.00442192470654845, -0.00343009643256664, -0.00898995902389288, 8.562996663386e-5, -2.19829889829271e-5, -1.63257514941506e-4, 2.04157349799061e-5, 4.4899989006808e-5, 3.36210272507742e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 92.9929122924805, + "fY" : 15.0256376266479, + "fZ" : 627.099975585938, + "fTx" : 0.187706679105759, + "fTy" : 0.0218684803694487, + "fQp" : 0.224675580859184, + "fCovMatrix" : [0.594597280025482, 0.162580519914627, 0.00167092029005289, 3.75143717974424e-4, 0.00739389378577471, 0.651716470718384, 4.48378792498261e-4, 0.00154582876712084, 0.00215009367093444, 5.87892918701982e-6, 1.04710966297716e-6, 2.09640384127852e-5, 4.87662600789918e-6, 5.20957382832421e-6, 1.08788466604892e-4] + }, + "fFlag" : -1, + "fChi2" : 7.156267, + "fNDF" : 3, + "fB" : 0, + "fLength" : 634.7792, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 38, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 13, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.952927221992502, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.56047129631042, + "fPidTof400" : [], + "fPidTof700" : [0.100793094280577, 0.0632901473876582, 0.0702298936320627, 0.0627474411774333, 0.157275123535341, 0.0347752208236058, 0.347029417332214, 0.163859661831108], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 9.04722690582275, + "fY" : -2.69119024276733, + "fZ" : -0.029397277161479, + "fTx" : -0.214173540472984, + "fTy" : 0.066271185874939, + "fQp" : 0.973324179649353, + "fCovMatrix" : [1.90959751605988, 0.345857620239258, -0.0221297480165958, -0.00174162059556693, 0.0235025100409985, 1.65526366233826, -0.00379488314501941, -0.0158087480813265, 0.00983281247317791, 2.70639488007873e-4, 1.81523137143813e-5, -2.8962770011276e-4, 1.7496311920695e-4, -5.34687205799855e-5, 7.56440567784011e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 18.6140308380127, + "fY" : 11.1579370498657, + "fZ" : 217.384552001953, + "fTx" : 0.324826687574387, + "fTy" : 0.0648133456707001, + "fQp" : 1.02351033687592, + "fCovMatrix" : [0.00179702998138964, -0.00483735324814916, 9.20187958399765e-5, -9.39793317229487e-5, 6.35934644378722e-4, 0.0419517792761326, -3.39350604917854e-4, 7.26883299648762e-4, -0.00259862025268376, 8.94437198439846e-6, -6.71676525598741e-6, 5.96006648265757e-5, 1.98985035240185e-5, -5.73953657294624e-5, 7.41470488719642e-4] + }, + "fFlag" : -1, + "fChi2" : 10.82403, + "fNDF" : 3, + "fB" : 0, + "fLength" : 220.8732, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 39, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 9.55130958557129, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.91946142911911, + "fY" : 0.232333868741989, + "fZ" : -0.029397277161479, + "fTx" : -0.0127219893038273, + "fTy" : 0.160901710391045, + "fQp" : 2.90746116638184, + "fCovMatrix" : [0.177920520305634, 0.0281006842851639, -0.013226586394012, -6.87061459757388e-4, 0.0368262194097042, 1.46299779415131, -9.60385252255946e-4, -0.0484406352043152, 0.0363761745393276, 0.00313101150095463, 1.39051771839149e-5, -0.00289830728434026, 0.00418889243155718, -0.00107791973277926, 0.0573726929724216] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 12.4197807312012, + "fY" : 7.84360790252686, + "fZ" : 46.3479995727539, + "fTx" : 0.674497842788696, + "fTy" : 0.180485606193542, + "fQp" : 6.65022325515747, + "fCovMatrix" : [3.4709763713181e-4, 0.00678978255018592, 3.63292347174138e-5, 3.32853232976049e-4, 9.68408057815395e-5, 0.311384648084641, 2.99614679533988e-4, 0.0151938563212752, -0.015667324885726, 8.55263933772221e-5, 2.96559246635297e-5, 8.48880503326654e-4, 0.00118385872337967, -0.00109430367592722, 0.0491611175239086] + }, + "fFlag" : -1, + "fChi2" : 0.005968111, + "fNDF" : 3, + "fB" : 0, + "fLength" : 50.51086, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 40, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.916526854038239, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.275234311819077, + "fY" : 1.66185438632965, + "fZ" : -0.029397277161479, + "fTx" : 0.122508220374584, + "fTy" : -0.217079237103462, + "fQp" : -4.45832967758179, + "fCovMatrix" : [0.114827856421471, -0.0195787586271763, -0.00612082332372665, 4.99484944157302e-4, 0.0182293485850096, 0.788843810558319, 5.74966601561755e-4, -0.0182638317346573, 0.00971878785640001, 3.3414555946365e-4, -2.01960465346929e-5, -0.00125481258146465, 5.39348344318569e-4, -2.4483390734531e-4, 0.0213687140494585] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.7083158493042, + "fY" : -11.8248224258423, + "fZ" : 61.02734375, + "fTx" : -0.561766088008881, + "fTy" : -0.246598660945892, + "fQp" : -4.54282855987549, + "fCovMatrix" : [0.00231565581634641, -0.00833991821855307, 2.11953214602545e-4, -2.98762606689706e-4, 0.00200965511612594, 0.0665908977389336, -7.94334802776575e-4, 0.00232968013733625, -0.00770675344392657, 5.23287199030165e-5, -9.87282601272454e-6, 2.70730466581881e-4, 3.05086723528802e-4, -2.41832807660103e-4, 0.019675899296999] + }, + "fFlag" : -1, + "fChi2" : 0.1263451, + "fNDF" : 3, + "fB" : 0, + "fLength" : 65.30978, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 41, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.21506714820862, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0335058271884918, + "fY" : -1.51622080802917, + "fZ" : -0.029397277161479, + "fTx" : -0.165475994348526, + "fTy" : -0.153514385223389, + "fQp" : 0.322940051555634, + "fCovMatrix" : [0.0123558649793267, 0.0297732409089804, -6.35048025287688e-4, -7.31324544176459e-4, 0.00731065683066845, 0.72432404756546, -0.00114081020001322, -0.0130683984607458, 0.0117901284247637, 3.77267788280733e-5, 3.2857740734471e-5, -3.99347540223971e-4, 2.5628472212702e-4, -3.79003584384918e-4, 0.00492897210642695] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -8.76997375488281, + "fY" : -10.8661489486694, + "fZ" : 61.0379409790039, + "fTx" : -0.120636485517025, + "fTy" : -0.152578368782997, + "fQp" : 0.323388069868088, + "fCovMatrix" : [0.00224469392560422, -0.00816680397838354, 1.83035343070515e-4, -2.75593047263101e-4, 0.00273431115783751, 0.0664315596222878, -7.01152719557285e-4, 0.00225460040383041, -0.0107996184378862, 1.73376683960669e-5, -1.98681918845978e-5, 2.78609455563128e-4, 2.4982143077068e-4, -3.56033619027585e-4, 0.00484105106443167] + }, + "fFlag" : -1, + "fChi2" : 1.90604, + "fNDF" : 3, + "fB" : 0, + "fLength" : 62.37534, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 42, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.98709070682526, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.00213396013714373, + "fY" : 0.48422384262085, + "fZ" : -0.029397277161479, + "fTx" : 0.0537827350199223, + "fTy" : -0.132247969508171, + "fQp" : 2.03384852409363, + "fCovMatrix" : [0.101356752216816, -0.0128131154924631, -0.00456118118017912, 6.7466105974745e-5, 0.00246793427504599, 0.533158957958221, 1.97527144337073e-4, -0.00875409226864576, -0.0013283061562106, 7.86647957284003e-4, -3.3255462312809e-6, -1.09059757960495e-4, 8.35597806144506e-4, 3.04340073853382e-6, 0.00114914972800761] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 49.6317138671875, + "fY" : -18.7386264801025, + "fZ" : 123.735862731934, + "fTx" : 0.922451794147491, + "fTy" : -0.211355149745941, + "fQp" : 2.14829063415527, + "fCovMatrix" : [0.00199073599651456, -0.00600775657221675, 1.30909102153964e-4, -1.49604718899354e-4, 4.00048622395843e-4, 0.0492274090647697, -5.2100548055023e-4, 0.00109832175076008, -0.00148220511619002, 2.66304086835589e-5, -8.38927280710777e-6, 6.87345527694561e-5, 6.45601903670467e-5, -1.4814616406511e-5, 0.00107164145447314] + }, + "fFlag" : -1, + "fChi2" : 2.83805, + "fNDF" : 3, + "fB" : 0, + "fLength" : 139.7365, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 43, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0390104465186596, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.563175976276398, + "fY" : 0.295070111751556, + "fZ" : -0.029397277161479, + "fTx" : -0.210707888007164, + "fTy" : 0.237468779087067, + "fQp" : 2.66978096961975, + "fCovMatrix" : [0.119420446455479, -0.0222559794783592, -0.00668415892869234, 6.79671531543136e-4, 0.00474497023969889, 0.61498498916626, 7.88265897426754e-4, -0.0122374352067709, 9.89413587376475e-4, 0.00234816665761173, -1.29664302221499e-4, -2.24227813305333e-4, 0.00244257412850857, 2.40578519878909e-5, 0.00245440984144807] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 36.9655494689941, + "fY" : 31.9299697875977, + "fZ" : 128.266860961914, + "fTx" : 1.03927612304688, + "fTy" : 0.324166595935822, + "fQp" : 3.00718474388123, + "fCovMatrix" : [0.00225362344644964, 0.0075716795399785, 1.34594927658327e-4, 1.78253525518812e-4, 3.82453668862581e-4, 0.0592034570872784, 5.54147001821548e-4, 0.00129310914780945, 0.00136285566259176, 4.59551192761865e-5, 1.16209812404122e-5, 1.57154776388779e-4, 7.96331441961229e-5, 1.55477555381367e-5, 0.00224633538164198] + }, + "fFlag" : -1, + "fChi2" : 2.90521, + "fNDF" : 3, + "fB" : 0, + "fLength" : 145.9663, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 44, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.557120323181152, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.513113439083099, + "fY" : -1.57424020767212, + "fZ" : -0.029397277161479, + "fTx" : -0.141265794634819, + "fTy" : -0.126548111438751, + "fQp" : -0.795029163360596, + "fCovMatrix" : [0.00408678036183119, 0.00675002112984657, -1.90156177268364e-4, -6.32357405265793e-5, 0.00104396394453943, 0.342634350061417, -4.0326027374249e-5, -0.00397018203511834, -4.78200527140871e-4, 1.22749943329836e-5, -1.96956435161155e-7, -4.79923328384757e-5, 5.88821931160055e-5, 1.83065239980351e-5, 4.62605647044256e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -22.0228366851807, + "fY" : -14.0940723419189, + "fZ" : 97.1422271728516, + "fTx" : -0.338983148336411, + "fTy" : -0.132703423500061, + "fQp" : -0.786303102970123, + "fCovMatrix" : [0.00249015097506344, 0.00926257483661175, 8.01757778390311e-5, 1.46307735121809e-4, 4.15503891417757e-4, 0.071669764816761, 2.8469690005295e-4, 0.00112168665509671, 0.0013581917155534, 4.9180093810719e-6, 5.47497120351181e-6, 3.15871002385393e-5, 5.38857966603246e-5, 2.07644352485659e-5, 4.52636770205572e-4] + }, + "fFlag" : -1, + "fChi2" : 4.028943, + "fNDF" : 3, + "fB" : 0, + "fLength" : 100.9747, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 45, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 2.1003634929657, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.225736543536186, + "fY" : 0.73824143409729, + "fZ" : -0.029397277161479, + "fTx" : 0.315195262432098, + "fTy" : -0.191795274615288, + "fQp" : 2.64431071281433, + "fCovMatrix" : [0.0222062785178423, -0.0094115762040019, -0.002589798765257, 2.46618670644239e-4, 0.0031125124078244, 0.455695301294327, 1.93938249140047e-4, -0.0101200696080923, -0.00145055854227394, 0.00224911631084979, -1.20157463243231e-4, -2.46833777055144e-4, 0.00226118532009423, 8.53220899443841e-6, 0.00390081130899489] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 35.2132225036621, + "fY" : -12.9507713317871, + "fZ" : 61.2922630310059, + "fTx" : 0.945975542068481, + "fTy" : -0.284506976604462, + "fQp" : 2.88229727745056, + "fCovMatrix" : [0.00233683804981411, -0.00856001209467649, 1.85092372703366e-4, -2.543551963754e-4, 8.70178337208927e-4, 0.0678045079112053, -6.34722004178911e-4, 0.00189690559636801, -0.00251634069718421, 3.38984646077733e-5, -2.53437228820985e-5, 8.01854839664884e-5, 1.95868473383598e-4, -6.10732240602374e-5, 0.0034143861848861] + }, + "fFlag" : -1, + "fChi2" : 6.323329, + "fNDF" : 3, + "fB" : 0, + "fLength" : 74.54071, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 46, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.32871201634407, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -30.5383033752441, + "fY" : 1.39664745330811, + "fZ" : -0.029397277161479, + "fTx" : 0.177466601133347, + "fTy" : 0.0839891508221626, + "fQp" : 0.404217898845673, + "fCovMatrix" : [0.165444180369377, -0.131337389349937, -0.00230440474115312, 9.09044698346406e-4, 0.00588673027232289, 0.302562415599823, 0.00179641973227262, -0.00214587501250207, -0.00481910118833184, 3.27145353367086e-5, -1.25628876048722e-5, -8.52862722240388e-5, 1.63093718583696e-5, 3.41204977303278e-5, 2.44537193793803e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 21.804407119751, + "fY" : 17.5602760314941, + "fZ" : 190.816345214844, + "fTx" : 0.382342100143433, + "fTy" : 0.0868466049432755, + "fQp" : 0.404914736747742, + "fCovMatrix" : [0.00190632219891995, 0.00534393405541778, 7.47169833630323e-5, 9.11921524675563e-5, 4.20524040237069e-4, 0.0445523224771023, 2.66797083895653e-4, 6.97484647389501e-4, 0.00170170434284955, 4.85355940327281e-6, 5.06681362821837e-6, 3.06623078358825e-5, 1.476433044445e-5, 3.50714653905015e-5, 2.42588197579607e-4] + }, + "fFlag" : -1, + "fChi2" : 8.000236, + "fNDF" : 3, + "fB" : 0, + "fLength" : 199.1183, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 47, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 30.5868377685547, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.15788125991821, + "fY" : 1.49865877628326, + "fZ" : -0.029397277161479, + "fTx" : 0.165132060647011, + "fTy" : 0.152950182557106, + "fQp" : 2.11752772331238, + "fCovMatrix" : [0.803330659866333, 0.0291136298328638, -0.104805134236813, -0.00241396785713732, 0.0123779531568289, 1.47373652458191, -0.00225822115316987, -0.112295806407928, 0.00424707541242242, 0.0190371759235859, 3.99815151467919e-4, -5.48746669664979e-4, 0.0189147349447012, -8.27027688501403e-5, 0.00546088628470898] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 75.0670471191406, + "fY" : 19.5143299102783, + "fZ" : 92.2631225585938, + "fTx" : 3.7820155620575, + "fTy" : 0.601390242576599, + "fQp" : 3.85533571243286, + "fCovMatrix" : [0.00235269544646144, -0.00818183925002813, 5.11665304657072e-4, -1.08604559500236e-4, 4.72164072562009e-4, 0.0635098516941071, -0.00206283130683005, 0.00135259691160172, -0.00227036792784929, 0.00325425225310028, 6.31853705272079e-4, 0.00235342606902122, 3.95051145460457e-4, 4.07467334298417e-4, 0.00299980654381216] + }, + "fFlag" : -1, + "fChi2" : 9.250807, + "fNDF" : 3, + "fB" : 0, + "fLength" : 158.3051, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 48, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 4.31654691696167, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}] +] diff --git a/demo/playground/src/jvmMain/resources/root/event_3.json b/demo/playground/src/jvmMain/resources/root/event_3.json new file mode 100644 index 00000000..f464037f --- /dev/null +++ b/demo/playground/src/jvmMain/resources/root/event_3.json @@ -0,0 +1,1370 @@ +[ +[{ + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 296852409, + "fStsHits" : [34, 58, 92, 111, 171, 294, 404], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.57000637054443, + "fY" : -9.91232872009277, + "fZ" : 61.1045799255371, + "fTx" : 0.114455692470074, + "fTy" : -0.1505176872015, + "fQp" : 0.338748455047607, + "fCovMatrix" : [0.00120294780936092, -0.00171040813438594, -2.56735456787283e-5, 1.45627755046007e-5, 6.92404646542855e-5, 0.0211342666298151, 4.00367316615302e-5, -1.75163280800916e-4, -9.87588136922568e-5, 1.06791651433014e-6, -3.21843600659122e-7, -2.9935415568616e-6, 2.51033725362504e-6, 6.99544045801304e-7, 2.2037434973754e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 44.1752090454102, + "fY" : -38.9115219116211, + "fZ" : 248.808853149414, + "fTx" : 0.279569119215012, + "fTy" : -0.157896891236305, + "fQp" : 0.340472787618637, + "fCovMatrix" : [0.00104028766509145, -0.00114251440390944, 2.29178640438477e-5, -1.0253203981847e-5, 6.06082467129454e-5, 0.0189696997404099, -3.21910156344529e-5, 1.621104311198e-4, -3.92368820030242e-5, 1.24302925996744e-6, -2.82433489928735e-7, 2.32914885600621e-6, 2.77825802186271e-6, -2.97843882890447e-8, 2.20006022573216e-5] + }, + "fFlag" : 0, + "fChi2" : 4.72594213485718, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509938528, + "fStsHits" : [495, 502, 509, 6, 36, 88, 149, 274, 362], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.46920967102051, + "fY" : 4.42782402038574, + "fZ" : 27.8159999847412, + "fTx" : 0.100209705531597, + "fTy" : 0.168729975819588, + "fQp" : -0.836885154247284, + "fCovMatrix" : [1.54722292791121e-4, 8.1766297807917e-4, -8.44947771838633e-6, -9.4166016424424e-6, 1.2599280125869e-5, 0.0388076938688755, -1.58085754264903e-6, -4.45390585809946e-4, -5.80995438212994e-5, 1.41129896746861e-6, 1.41468447623083e-7, -2.47726916313695e-6, 9.47681564866798e-6, 4.38638409150371e-7, 7.41747935535386e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -26.2282524108887, + "fY" : 43.8057022094727, + "fZ" : 253.266006469727, + "fTx" : -0.393378973007202, + "fTy" : 0.183965146541595, + "fQp" : -0.841169774532318, + "fCovMatrix" : [0.00138695456553251, 0.00245250947773457, 4.07528132200241e-5, 3.07277732645161e-5, 6.74965558573604e-5, 0.0257465783506632, 9.16569624678232e-5, 2.88728624582291e-4, 1.5688432904426e-4, 3.51272797161073e-6, 7.95116307017452e-7, 4.9578438847675e-6, 8.48969284561463e-6, 1.90970308722171e-6, 7.40295581636019e-5] + }, + "fFlag" : 0, + "fChi2" : 4.60224008560181, + "fNDF" : 13, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [500, 505, 511, 40, 91, 110, 148], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.1521635055542, + "fY" : 4.84085178375244, + "fZ" : 28.9860000610352, + "fTx" : -0.146197408437729, + "fTy" : 0.17111112177372, + "fQp" : -1.1365875005722, + "fCovMatrix" : [1.54369670781307e-4, 8.92427342478186e-4, -1.27299881569343e-5, -9.00611303222831e-6, 1.47260780067882e-5, 0.0776186287403107, -1.79295893758535e-4, -8.92429146915674e-4, -1.04104001366068e-4, 2.71486078418093e-6, 1.70441876434779e-6, -4.23068786403746e-6, 1.92049847100861e-5, 1.56831117692491e-6, 1.90227205166593e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -69.8452606201172, + "fY" : 35.5888671875, + "fZ" : 190.759826660156, + "fTx" : -0.755924940109253, + "fTy" : 0.234108626842499, + "fQp" : -1.1410653591156, + "fCovMatrix" : [0.0016210189787671, 0.00367055041715503, 5.95567980781198e-5, 4.92073886562139e-5, 1.30036598420702e-4, 0.0339352935552597, 1.72936561284587e-4, 4.68151818495244e-4, 3.72272508684546e-4, 7.08813240635209e-6, 1.15282068691158e-6, 1.59920909936773e-5, 1.43599054354127e-5, 8.06203615866252e-7, 1.84375589014962e-4] + }, + "fFlag" : 0, + "fChi2" : 8.86424922943115, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -1067520869, + "fStsHits" : [93, 113, 213, 302, 437], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 12.5838489532471, + "fY" : -2.74226856231689, + "fZ" : 123.501998901367, + "fTx" : 0.125694692134857, + "fTy" : -0.0128870774060488, + "fQp" : 0.235099822282791, + "fCovMatrix" : [0.00148753076791763, -0.00286372099071741, -4.24543140979949e-5, 2.97241167572793e-5, 1.96587119717151e-4, 0.0292670801281929, 8.35246173664927e-5, -3.15573968691751e-4, -3.55950993252918e-4, 2.13228327083925e-6, -6.59350348541921e-7, -1.18663283501519e-5, 4.95868243888253e-6, 1.70585974501591e-6, 8.24067028588615e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 32.9461936950684, + "fY" : -4.42597818374634, + "fZ" : 248.747436523438, + "fTx" : 0.196269676089287, + "fTy" : -0.0137906949967146, + "fQp" : 0.234843328595161, + "fCovMatrix" : [0.00120935030281544, -0.00178178038913757, 3.31491100951098e-5, -1.84210657607764e-5, 1.62665004609153e-4, 0.0247486550360918, -5.01800968777388e-5, 2.78292311122641e-4, -1.82114410563372e-4, 1.74688352672092e-6, -2.68147317683542e-7, 1.01446121334448e-5, 4.99256657349179e-6, 1.13328542283853e-6, 8.19254855741747e-5] + }, + "fFlag" : 0, + "fChi2" : 20.5910758972168, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [89, 106, 141, 239], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 10.9574069976807, + "fY" : 10.8984527587891, + "fZ" : 128.236862182617, + "fTx" : 0.13301394879818, + "fTy" : 0.0904059484601021, + "fQp" : 0.308079034090042, + "fCovMatrix" : [0.0017817176412791, 0.00475242547690868, -8.85804984136485e-5, -9.14301272132434e-5, 6.59521669149399e-4, 0.0414591357111931, -3.23259591823444e-4, -7.04148609656841e-4, 0.00271017011255026, 7.20695197742316e-6, 6.85740587869077e-6, -5.9744681493612e-5, 1.60877989401342e-5, -6.05789900873788e-5, 5.47787582036108e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 25.9320220947266, + "fY" : 18.9775524139404, + "fZ" : 217.384552001953, + "fTx" : 0.202286452054977, + "fTy" : 0.091080442070961, + "fQp" : 0.30821368098259, + "fCovMatrix" : [0.00176186766475439, -0.00465359771624207, 8.62092056195252e-5, -8.90066658030264e-5, 6.51401758659631e-4, 0.0409622117877007, -3.11948562739417e-4, 6.92703877575696e-4, -0.00266375578939915, 6.9299348979257e-6, -6.57674172543921e-6, 5.83395376452245e-5, 1.5830855772947e-5, -5.93766999372747e-5, 5.46319701243192e-4] + }, + "fFlag" : 0, + "fChi2" : 0.100665181875229, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [109, 150, 268, 370], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.04536199569702, + "fY" : 22.8184032440186, + "fZ" : 154.863342285156, + "fTx" : -0.00300517166033387, + "fTy" : 0.152006968855858, + "fQp" : 0.124095372855663, + "fCovMatrix" : [0.00190175464376807, -0.00531620439141989, -7.45397337595932e-5, 8.9641755039338e-5, 5.00830821692944e-4, 0.0443901121616364, 2.65212351223454e-4, -6.89060485456139e-4, -0.00202822429127991, 4.62873231299454e-6, -5.03400860907277e-6, -3.58479737769812e-5, 1.40884512802586e-5, 4.14812056988012e-5, 2.99814593745396e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.87017381191254, + "fY" : 37.7572059631348, + "fZ" : 253.266006469727, + "fTx" : 0.0264327693730593, + "fTy" : 0.151600807905197, + "fQp" : 0.124097675085068, + "fCovMatrix" : [0.00188965618144721, 0.0052546733058989, 7.22920085536316e-5, 8.74364632181823e-5, 4.96948370710015e-4, 0.044090673327446, 2.55633989581838e-4, 6.79159304127097e-4, 0.00200395938009024, 4.36992058894248e-6, 4.77146477351198e-6, 3.46658707712777e-5, 1.38237774081063e-5, 4.04370002797805e-5, 2.99695821013302e-4] + }, + "fFlag" : 0, + "fChi2" : 0.226910412311554, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [97, 136, 222, 314], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.58799624443054, + "fY" : -8.976881980896, + "fZ" : 123.397521972656, + "fTx" : -0.0131417205557227, + "fTy" : -0.0661567151546478, + "fQp" : 0.162161365151405, + "fCovMatrix" : [0.00190816225949675, -0.00534867076203227, -7.42775955586694e-5, 8.95381745067425e-5, 4.84511750983074e-4, 0.0445656515657902, 2.64561153016984e-4, -6.88906409777701e-4, -0.00197574705816805, 4.58586055174237e-6, -4.97963310408522e-6, -3.43889660143759e-5, 1.40434758577612e-5, 4.01280922233127e-5, 2.8115973691456e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.89048075675964, + "fY" : -15.52707862854, + "fZ" : 222.077667236328, + "fTx" : 0.0265315920114517, + "fTy" : -0.0665754824876785, + "fQp" : 0.162168383598328, + "fCovMatrix" : [0.00189096131362021, 0.00525919208303094, 7.12687469786033e-5, 8.75819096108899e-5, 4.80103975860402e-4, 0.0441058911383152, 2.50725541263819e-4, 6.79370888974518e-4, 0.00194779096636921, 4.24357494921423e-6, 4.68637608719291e-6, 3.30064540321473e-5, 1.38364857775741e-5, 3.94360940845218e-5, 2.81097542028874e-4] + }, + "fFlag" : 0, + "fChi2" : 0.451097756624222, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [123, 186, 329, 449], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.5336303710938, + "fY" : -3.46899247169495, + "fZ" : 159.687271118164, + "fTx" : -0.124593898653984, + "fTy" : -0.0750735253095627, + "fQp" : 0.354338347911835, + "fCovMatrix" : [0.00179788842797279, 0.00481476075947285, -9.4004011771176e-5, -9.17777142603882e-5, 7.1522785583511e-4, 0.0416768379509449, -3.45318461768329e-4, -7.08897190634161e-4, 0.00290325935930014, 8.33640388009371e-6, 7.05097045283765e-6, -6.65459374431521e-5, 1.7228041542694e-5, -6.33006930002011e-5, 6.9790770066902e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.85834217071533, + "fY" : -10.2067451477051, + "fZ" : 248.59846496582, + "fTx" : -0.0520231463015079, + "fTy" : -0.0764518603682518, + "fQp" : 0.354904860258102, + "fCovMatrix" : [0.00174834718927741, -0.004612120334059, 8.24026938062161e-5, -9.13782932912e-5, 7.04309437423944e-4, 0.0408704169094563, -2.97947903163731e-4, 7.05018232110888e-4, -0.00286549958400428, 6.46585021968349e-6, -6.47028218736523e-6, 6.13997981417924e-5, 1.67413891176693e-5, -6.62249440210871e-5, 7.03481142409146e-4] + }, + "fFlag" : 0, + "fChi2" : 3.45493102073669, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [126, 180, 312, 408], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.11370420455933, + "fY" : -6.19081974029541, + "fZ" : 159.640716552734, + "fTx" : 0.0766926929354668, + "fTy" : -0.0279160887002945, + "fQp" : 0.13067901134491, + "fCovMatrix" : [0.00179118709638715, 0.00477873161435127, -9.22102408367209e-5, -9.02009705896489e-5, 7.27188482414931e-4, 0.0414711087942123, -3.37155506713316e-4, -6.97095936629921e-4, 0.00297126267105341, 7.66818720876472e-6, 7.01760245647165e-6, -6.78419237374328e-5, 1.55325342348078e-5, -6.47546985419467e-5, 6.31099799647927e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.1892690658569, + "fY" : -8.69165992736816, + "fZ" : 248.638809204102, + "fTx" : 0.10332266241312, + "fTy" : -0.0282121077179909, + "fQp" : 0.130729869008064, + "fCovMatrix" : [0.0017405046382919, -0.00456876307725906, 8.11685167718679e-5, -8.95584089448676e-5, 7.05139013007283e-4, 0.0406320914626122, -2.91850272333249e-4, 6.9410540163517e-4, -0.0028778335545212, 6.1214336710691e-6, -6.37108087175875e-6, 6.03011758357752e-5, 1.58327566168737e-5, -6.63357495795935e-5, 6.34717929642648e-4] + }, + "fFlag" : 0, + "fChi2" : 8.80130481719971, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [118, 182, 331, 447], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.6413908004761, + "fY" : -6.14414262771606, + "fZ" : 159.68798828125, + "fTx" : -0.137811452150345, + "fTy" : -0.0411436446011066, + "fQp" : -0.970387399196625, + "fCovMatrix" : [0.00180307461414486, 0.00485242856666446, -9.49772147578187e-5, -9.2729547759518e-5, 6.89088425133377e-4, 0.0419448800384998, -3.51462047547102e-4, -7.19539937563241e-4, 0.0028468556702137, 9.27071050682571e-6, 6.83604685036698e-6, -6.56809643260203e-5, 1.94475542230066e-5, -5.98876467847731e-5, 7.98660155851394e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -8.4837646484375, + "fY" : -9.48062133789062, + "fZ" : 248.519302368164, + "fTx" : -0.352763444185257, + "fTy" : -0.0339179635047913, + "fQp" : -0.972050666809082, + "fCovMatrix" : [0.00178857066202909, -0.00480817910283804, 9.02258398127742e-5, -9.74497888819315e-5, 6.59170967992395e-4, 0.0418470054864883, -3.33041214616969e-4, 7.43029173463583e-4, -0.00274206721223891, 8.91559921001317e-6, -6.74819648338598e-6, 5.53193567611743e-5, 2.14663104998181e-5, -6.56304910080507e-5, 7.88591278251261e-4] + }, + "fFlag" : 0, + "fChi2" : 11.6502780914307, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [125, 201, 301, 438], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 9.01333904266357, + "fY" : -4.94230794906616, + "fZ" : 159.662322998047, + "fTx" : 0.266647726297379, + "fTy" : -0.0456439964473248, + "fQp" : 0.358276426792145, + "fCovMatrix" : [0.00179056881461293, 0.00477772951126099, -9.21343598747626e-5, -9.01032763067633e-5, 6.40454236418009e-4, 0.0414822958409786, -3.37014178512618e-4, -6.97992625646293e-4, 0.00260217650793493, 7.85415795689914e-6, 6.90964134264505e-6, -5.95282181166112e-5, 1.60820218297886e-5, -5.63795147172641e-5, 5.22615504451096e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 36.6136207580566, + "fY" : -9.08453845977783, + "fZ" : 248.767608642578, + "fTx" : 0.348794728517532, + "fTy" : -0.0466611199080944, + "fQp" : 0.357887446880341, + "fCovMatrix" : [0.00174852868076414, -0.00460646999999881, 8.27661424409598e-5, -8.9719491370488e-5, 6.22440304141492e-4, 0.0408178381621838, -2.99103499855846e-4, 6.9653894752264e-4, -0.00252968561835587, 6.56514612273895e-6, -6.37573566564242e-6, 5.31558325747028e-5, 1.64152570505394e-5, -5.77251703361981e-5, 5.26623975019902e-4] + }, + "fFlag" : 0, + "fChi2" : 13.0512256622314, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509947728, + "fStsHits" : [134, 236, 326, 418], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.37234425544739, + "fY" : -3.36550641059875, + "fZ" : 159.607604980469, + "fTx" : 0.0546356178820133, + "fTy" : -0.0443619750440121, + "fQp" : 1.37652194499969, + "fCovMatrix" : [0.00182872219011188, 0.00499599240720272, -9.81753037194721e-5, -9.82725541689433e-5, 6.9363642251119e-4, 0.0427631102502346, -3.67360975360498e-4, -7.55574263166636e-4, 0.002793526975438, 1.06962861536886e-5, 6.94656819177908e-6, -7.06074861227535e-5, 2.33454065892147e-5, -5.84443005209323e-5, 0.00108496204484254] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 16.0822811126709, + "fY" : -7.50871706008911, + "fZ" : 248.654602050781, + "fTx" : 0.35296493768692, + "fTy" : -0.0471868738532066, + "fQp" : 1.38267636299133, + "fCovMatrix" : [0.00181278993841261, -0.00494082737714052, 9.53344424488023e-5, -1.00094614026602e-4, 6.32787239737809e-4, 0.0426238588988781, -3.58232791768387e-4, 7.70228973124176e-4, -0.00252008717507124, 1.11789231596049e-5, -6.73666454531485e-6, 5.27514894201886e-5, 2.64508908003336e-5, -5.84950903430581e-5, 0.00108214910142124] + }, + "fFlag" : 0, + "fChi2" : 7.96521520614624, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509947728, + "fStsHits" : [115, 197, 303, 409], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 15.0809373855591, + "fY" : -6.98929262161255, + "fZ" : 159.695938110352, + "fTx" : 0.0689177364110947, + "fTy" : -0.00790996197611094, + "fQp" : -0.841446995735168, + "fCovMatrix" : [0.00180781364906579, 0.00486746476963162, -9.56724179559387e-5, -9.2438880528789e-5, 7.55298184230924e-4, 0.0419658273458481, -3.5373936407268e-4, -7.14505207724869e-4, 0.00312060676515102, 8.95912853593472e-6, 7.02754232406733e-6, -7.28257728042081e-5, 1.81177365448093e-5, -6.62021557218395e-5, 8.50404088851064e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.2809133529663, + "fY" : -7.53941249847412, + "fZ" : 248.638809204102, + "fTx" : -0.100862711668015, + "fTy" : -0.00437753833830357, + "fQp" : -0.844026267528534, + "fCovMatrix" : [0.00176415592432022, -0.00469323294237256, 8.53097735671327e-5, -9.46945510804653e-5, 7.16785027179867e-4, 0.0412978753447533, -3.11316456645727e-4, 7.260687998496e-4, -0.00294898869469762, 7.65372715250123e-6, -6.52985136184725e-6, 5.96674617554527e-5, 1.96662622329313e-5, -7.00035234331153e-5, 8.53373727295548e-4] + }, + "fFlag" : 0, + "fChi2" : 16.2323703765869, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}] +, +[{ + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.0553092956543, + "fY" : -0.759159684181213, + "fZ" : -0.0741752609610558, + "fTx" : 0.0682807937264442, + "fTy" : -0.148917526006699, + "fQp" : 0.33812740445137, + "fCovMatrix" : [0.0126965418457985, -0.00686986232176423, -1.94974621990696e-4, 3.77058713638689e-5, 3.4901627805084e-4, 0.0537109524011612, 7.84804724389687e-5, -3.72759677702561e-4, -1.43871977343224e-4, 8.03290822659619e-6, -4.70490732595863e-7, -5.99395752942655e-6, 8.34861111798091e-6, 7.59855993237579e-7, 2.20557340071537e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 44.1752090454102, + "fY" : -38.9115219116211, + "fZ" : 248.808853149414, + "fTx" : 0.279569119215012, + "fTy" : -0.157896891236305, + "fQp" : 0.340472787618637, + "fCovMatrix" : [0.00104028766509145, -0.00114251440390944, 2.29178640438477e-5, -1.0253203981847e-5, 6.06082467129454e-5, 0.0189696997404099, -3.21910156344529e-5, 1.621104311198e-4, -3.92368820030242e-5, 1.24302925996744e-6, -2.82433489928735e-7, 2.32914885600621e-6, 2.77825802186271e-6, -2.97843882890447e-8, 2.20006022573216e-5] + }, + "fFlag" : -1, + "fChi2" : 4.725942, + "fNDF" : 9, + "fB" : 0, + "fLength" : 256.1725, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 0, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.236941069364548, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.972045302391052, + "fY" : -0.280813157558441, + "fZ" : -0.0741752609610558, + "fTx" : 0.149191468954086, + "fTy" : 0.168982222676277, + "fQp" : -0.834105968475342, + "fCovMatrix" : [0.0029536911752075, 0.00129893212579191, -1.44318444654346e-4, -1.68929509527516e-5, 1.44262303365394e-4, 0.072073370218277, -1.02829853858566e-5, -7.96541280578822e-4, -6.96946008247323e-5, 3.18914135277737e-5, 9.77228637566441e-7, -6.86927978676977e-6, 3.9630860555917e-5, 3.83387657620915e-7, 7.7078329923097e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -26.2282524108887, + "fY" : 43.8057022094727, + "fZ" : 253.266006469727, + "fTx" : -0.393378973007202, + "fTy" : 0.183965146541595, + "fQp" : -0.841169774532318, + "fCovMatrix" : [0.00138695456553251, 0.00245250947773457, 4.07528132200241e-5, 3.07277732645161e-5, 6.74965558573604e-5, 0.0257465783506632, 9.16569624678232e-5, 2.88728624582291e-4, 1.5688432904426e-4, 3.51272797161073e-6, 7.95116307017452e-7, 4.9578438847675e-6, 8.48969284561463e-6, 1.90970308722171e-6, 7.40295581636019e-5] + }, + "fFlag" : -1, + "fChi2" : 4.60224, + "fNDF" : 13, + "fB" : 0, + "fLength" : 261.9332, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 1, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.250558197498322, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.05267107486725, + "fY" : -0.100232698023319, + "fZ" : -0.0741752609610558, + "fTx" : -0.0768801420927048, + "fTy" : 0.169134110212326, + "fQp" : -1.13182425498962, + "fCovMatrix" : [0.0067399088293314, 0.00791787542402744, -3.10500880004838e-4, -5.94121775066014e-5, 3.12555144773796e-4, 0.148948058485985, -2.36758729442954e-4, -0.00165140617173165, -1.53704575495794e-4, 5.67395400139503e-5, 1.25742951695429e-6, -1.59005121531663e-5, 7.31128166080453e-5, 1.79939468125667e-6, 1.9548847922124e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -69.8452606201172, + "fY" : 35.5888671875, + "fZ" : 190.759826660156, + "fTx" : -0.755924940109253, + "fTy" : 0.234108626842499, + "fQp" : -1.1410653591156, + "fCovMatrix" : [0.0016210189787671, 0.00367055041715503, 5.95567980781198e-5, 4.92073886562139e-5, 1.30036598420702e-4, 0.0339352935552597, 1.72936561284587e-4, 4.68151818495244e-4, 3.72272508684546e-4, 7.08813240635209e-6, 1.15282068691158e-6, 1.59920909936773e-5, 1.43599054354127e-5, 8.06203615866252e-7, 1.84375589014962e-4] + }, + "fFlag" : -1, + "fChi2" : 8.864249, + "fNDF" : 9, + "fB" : 0, + "fLength" : 210.9485, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 2, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.434302598237991, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.49803411960602, + "fY" : -1.23369157314301, + "fZ" : -0.0741752609610558, + "fTx" : 0.0571040958166122, + "fTy" : -0.0116128865629435, + "fQp" : 0.233414620161057, + "fCovMatrix" : [0.16058374941349, -0.0386939495801926, -0.00183908792678267, 1.57955844770186e-4, 0.00322318007238209, 0.20668363571167, 3.43304360285401e-4, -0.00129437737632543, -5.93546603340656e-4, 2.30489913519705e-5, -1.32737147851003e-6, -3.59687473974191e-5, 1.18543348435196e-5, 2.08487495001464e-6, 8.24516027932987e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 32.9461936950684, + "fY" : -4.42597818374634, + "fZ" : 248.747436523438, + "fTx" : 0.196269676089287, + "fTy" : -0.0137906949967146, + "fQp" : 0.234843328595161, + "fCovMatrix" : [0.00120935030281544, -0.00178178038913757, 3.31491100951098e-5, -1.84210657607764e-5, 1.62665004609153e-4, 0.0247486550360918, -5.01800968777388e-5, 2.78292311122641e-4, -1.82114410563372e-4, 1.74688352672092e-6, -2.68147317683542e-7, 1.01446121334448e-5, 4.99256657349179e-6, 1.13328542283853e-6, 8.19254855741747e-5] + }, + "fFlag" : -1, + "fChi2" : 20.59108, + "fNDF" : 5, + "fB" : 0, + "fLength" : 251.1237, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 3, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.865585923194885, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.168660625815392, + "fY" : -0.732907712459564, + "fZ" : -0.0741752609610558, + "fTx" : 0.0394175723195076, + "fTy" : 0.0910284221172333, + "fQp" : 0.306645959615707, + "fCovMatrix" : [0.730717658996582, 0.378915369510651, -0.00844841357320547, -0.00212396425195038, 0.0194573123008013, 0.505575299263, -0.00431815348565578, -0.00303975376300514, 0.0103680109605193, 1.0205547005171e-4, 2.42906644416507e-5, -2.25800249609165e-4, 2.3960954422364e-5, -5.85240559303202e-5, 5.47828210983425e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 25.9320220947266, + "fY" : 18.9775524139404, + "fZ" : 217.384552001953, + "fTx" : 0.202286452054977, + "fTy" : 0.091080442070961, + "fQp" : 0.30821368098259, + "fCovMatrix" : [0.00176186766475439, -0.00465359771624207, 8.62092056195252e-5, -8.90066658030264e-5, 6.51401758659631e-4, 0.0409622117877007, -3.11948562739417e-4, 6.92703877575696e-4, -0.00266375578939915, 6.9299348979257e-6, -6.57674172543921e-6, 5.83395376452245e-5, 1.5830855772947e-5, -5.93766999372747e-5, 5.46319701243192e-4] + }, + "fFlag" : -1, + "fChi2" : 0.1006652, + "fNDF" : 3, + "fB" : 0, + "fLength" : 220.2086, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 4, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.849169433116913, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.09552073478699, + "fY" : -0.791672945022583, + "fZ" : -0.0741752609610558, + "fTx" : -0.0488560423254967, + "fTy" : 0.152769893407822, + "fQp" : 0.123951099812984, + "fCovMatrix" : [0.764037489891052, -0.442365646362305, -0.00743837049230933, 0.00222868844866753, 0.0149596650153399, 0.610441923141479, 0.00428155763074756, -0.00300545059144497, -0.00863859802484512, 7.33681226847693e-5, -2.16770458791871e-5, -1.46979771670885e-4, 1.57766862685094e-5, 4.39250106865074e-5, 2.99817853374407e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.87017381191254, + "fY" : 37.7572059631348, + "fZ" : 253.266006469727, + "fTx" : 0.0264327693730593, + "fTy" : 0.151600807905197, + "fQp" : 0.124097675085068, + "fCovMatrix" : [0.00188965618144721, 0.0052546733058989, 7.22920085536316e-5, 8.74364632181823e-5, 4.96948370710015e-4, 0.044090673327446, 2.55633989581838e-4, 6.79159304127097e-4, 0.00200395938009024, 4.36992058894248e-6, 4.77146477351198e-6, 3.46658707712777e-5, 1.38237774081063e-5, 4.04370002797805e-5, 2.99695821013302e-4] + }, + "fFlag" : -1, + "fChi2" : 0.2269104, + "fNDF" : 3, + "fB" : 0, + "fLength" : 256.3305, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 5, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.280481159687042, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.08058607578278, + "fY" : -0.838285148143768, + "fZ" : -0.0741752609610558, + "fTx" : -0.0602659471333027, + "fTy" : -0.0657347366213799, + "fQp" : 0.161692976951599, + "fCovMatrix" : [0.373369604349136, -0.256095170974731, -0.00429155910387635, 0.00146932841744274, 0.0100092217326164, 0.437035441398621, 0.00290561700239778, -0.00253340043127537, -0.00696604512631893, 5.08210650878027e-5, -1.67745038197609e-5, -1.16124640044291e-4, 1.66389145306312e-5, 4.05125792894978e-5, 2.81171407550573e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.89048075675964, + "fY" : -15.52707862854, + "fZ" : 222.077667236328, + "fTx" : 0.0265315920114517, + "fTy" : -0.0665754824876785, + "fQp" : 0.162168383598328, + "fCovMatrix" : [0.00189096131362021, 0.00525919208303094, 7.12687469786033e-5, 8.75819096108899e-5, 4.80103975860402e-4, 0.0441058911383152, 2.50725541263819e-4, 6.79370888974518e-4, 0.00194779096636921, 4.24357494921423e-6, 4.68637608719291e-6, 3.30064540321473e-5, 1.38364857775741e-5, 3.94360940845218e-5, 2.81097542028874e-4] + }, + "fFlag" : -1, + "fChi2" : 0.4510978, + "fNDF" : 3, + "fB" : 0, + "fLength" : 222.739, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 6, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.319944620132446, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 44.9544410705566, + "fY" : 8.4261474609375, + "fZ" : -0.0741752609610558, + "fTx" : -0.263924449682236, + "fTy" : -0.0746458247303963, + "fQp" : 0.349957019090652, + "fCovMatrix" : [1.98384606838226, 0.685470521450043, -0.0193782690912485, -0.00341549632139504, 0.0342621468007565, 0.942128956317902, -0.00669290637597442, -0.00555382901802659, 0.0129474010318518, 1.91260362043977e-4, 3.34627511620056e-5, -3.44516127370298e-4, 3.62282080459408e-5, -6.4479245338589e-5, 6.98037445545197e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.85834217071533, + "fY" : -10.2067451477051, + "fZ" : 248.59846496582, + "fTx" : -0.0520231463015079, + "fTy" : -0.0764518603682518, + "fQp" : 0.354904860258102, + "fCovMatrix" : [0.00174834718927741, -0.004612120334059, 8.24026938062161e-5, -9.13782932912e-5, 7.04309437423944e-4, 0.0408704169094563, -2.97947903163731e-4, 7.05018232110888e-4, -0.00286549958400428, 6.46585021968349e-6, -6.47028218736523e-6, 6.13997981417924e-5, 1.67413891176693e-5, -6.62249440210871e-5, 7.03481142409146e-4] + }, + "fFlag" : -1, + "fChi2" : 3.454931, + "fNDF" : 3, + "fB" : 0, + "fLength" : 252.7396, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 7, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 44.8642272949219, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.98815751075745, + "fY" : -1.79677057266235, + "fZ" : -0.0741752609610558, + "fTx" : 0.0268787071108818, + "fTy" : -0.0271434132009745, + "fQp" : 0.129942655563354, + "fCovMatrix" : [1.62950122356415, 0.661146819591522, -0.0158530920743942, -0.00310880900360644, 0.0316362045705318, 0.676753103733063, -0.00640787184238434, -0.00336016505025327, 0.0130223669111729, 1.54828841914423e-4, 3.01927830150817e-5, -3.09189374092966e-4, 1.78518203028943e-5, -6.14967430010438e-5, 6.31117378361523e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.1892690658569, + "fY" : -8.69165992736816, + "fZ" : 248.638809204102, + "fTx" : 0.10332266241312, + "fTy" : -0.0282121077179909, + "fQp" : 0.130729869008064, + "fCovMatrix" : [0.0017405046382919, -0.00456876307725906, 8.11685167718679e-5, -8.95584089448676e-5, 7.05139013007283e-4, 0.0406320914626122, -2.91850272333249e-4, 6.9410540163517e-4, -0.0028778335545212, 6.1214336710691e-6, -6.37108087175875e-6, 6.03011758357752e-5, 1.58327566168737e-5, -6.63357495795935e-5, 6.34717929642648e-4] + }, + "fFlag" : -1, + "fChi2" : 8.801305, + "fNDF" : 3, + "fB" : 0, + "fLength" : 249.424, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 8, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 4.17802572250366, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.81049203872681, + "fY" : 1.1469452381134, + "fZ" : -0.0741752609610558, + "fTx" : 0.236087128520012, + "fTy" : -0.050562396645546, + "fQp" : -0.957896947860718, + "fCovMatrix" : [2.08753252029419, 0.596874952316284, -0.0210686512291431, -0.0023795876186341, 0.0366438962519169, 1.04195284843445, -0.00575345195829868, -0.00679782964289188, 0.0115563711151481, 2.30263074627146e-4, 2.25388430408202e-5, -3.76431678887457e-4, 6.72532478347421e-5, -4.65640514448751e-5, 8.11638543382287e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -8.4837646484375, + "fY" : -9.48062133789062, + "fZ" : 248.519302368164, + "fTx" : -0.352763444185257, + "fTy" : -0.0339179635047913, + "fQp" : -0.972050666809082, + "fCovMatrix" : [0.00178857066202909, -0.00480817910283804, 9.02258398127742e-5, -9.74497888819315e-5, 6.59170967992395e-4, 0.0418470054864883, -3.33041214616969e-4, 7.43029173463583e-4, -0.00274206721223891, 8.91559921001317e-6, -6.74819648338598e-6, 5.53193567611743e-5, 2.14663104998181e-5, -6.56304910080507e-5, 7.88591278251261e-4] + }, + "fFlag" : -1, + "fChi2" : 11.65028, + "fNDF" : 3, + "fB" : 0, + "fLength" : 253.0336, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 9, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 4.16944980621338, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -21.5212783813477, + "fY" : 2.11670660972595, + "fZ" : -0.0741752609610558, + "fTx" : 0.123838409781456, + "fTy" : -0.0428293310105801, + "fQp" : 0.350397825241089, + "fCovMatrix" : [1.76534926891327, 0.628246784210205, -0.0174159202724695, -0.00295637990348041, 0.0278382040560246, 0.900808334350586, -0.00597109459340572, -0.00593680469319224, 0.0113444663584232, 2.63705820543692e-4, 2.76864393526921e-5, -2.69689393462613e-4, 1.36653063236736e-4, -5.36378138349392e-5, 5.22854039445519e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 36.6136207580566, + "fY" : -9.08453845977783, + "fZ" : 248.767608642578, + "fTx" : 0.348794728517532, + "fTy" : -0.0466611199080944, + "fQp" : 0.357887446880341, + "fCovMatrix" : [0.00174852868076414, -0.00460646999999881, 8.27661424409598e-5, -8.9719491370488e-5, 6.22440304141492e-4, 0.0408178381621838, -2.99103499855846e-4, 6.9653894752264e-4, -0.00252968561835587, 6.56514612273895e-6, -6.37573566564242e-6, 5.31558325747028e-5, 1.64152570505394e-5, -5.77251703361981e-5, 5.26623975019902e-4] + }, + "fFlag" : -1, + "fChi2" : 13.05123, + "fNDF" : 3, + "fB" : 0, + "fLength" : 256.5815, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 10, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 22.6697101593018, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 31.6281032562256, + "fY" : 3.4384138584137, + "fZ" : -0.0741752609610558, + "fTx" : -0.467039108276367, + "fTy" : -0.0435147099196911, + "fQp" : 1.1711448431015, + "fCovMatrix" : [7.91541337966919, 0.779726445674896, -0.0805382579565048, -0.0050742132589221, 0.0481211170554161, 6.39190053939819, -0.00789854489266872, -0.0591910779476166, 0.012303021736443, 8.90450435690582e-4, 5.3377567382995e-5, -5.28921955265105e-4, 6.28222827799618e-4, -6.57707278151065e-5, 0.0010983272222802] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 16.0822811126709, + "fY" : -7.50871706008911, + "fZ" : 248.654602050781, + "fTx" : 0.35296493768692, + "fTy" : -0.0471868738532066, + "fQp" : 1.38267636299133, + "fCovMatrix" : [0.00181278993841261, -0.00494082737714052, 9.53344424488023e-5, -1.00094614026602e-4, 6.32787239737809e-4, 0.0426238588988781, -3.58232791768387e-4, 7.70228973124176e-4, -0.00252008717507124, 1.11789231596049e-5, -6.73666454531485e-6, 5.27514894201886e-5, 2.64508908003336e-5, -5.84950903430581e-5, 0.00108214910142124] + }, + "fFlag" : -1, + "fChi2" : 7.965215, + "fNDF" : 3, + "fB" : 0, + "fLength" : 256.0514, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 11, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 30.8907814025879, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -24.1479740142822, + "fY" : -5.13045358657837, + "fZ" : -0.0741752609610558, + "fTx" : 0.4214788377285, + "fTy" : -0.0166378784924746, + "fQp" : -0.825638711452484, + "fCovMatrix" : [2.25483560562134, 0.679172396659851, -0.0261307191103697, -0.00274870544672012, 0.0411236099898815, 0.892340660095215, -0.00686908280476928, -0.0075940815731883, 0.0129511076956987, 9.46337939240038e-4, 2.36712530750083e-5, -4.33476088801399e-4, 6.35952048469335e-4, -5.28009732079227e-5, 8.67289258167148e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.2809133529663, + "fY" : -7.53941249847412, + "fZ" : 248.638809204102, + "fTx" : -0.100862711668015, + "fTy" : -0.00437753833830357, + "fQp" : -0.844026267528534, + "fCovMatrix" : [0.00176415592432022, -0.00469323294237256, 8.53097735671327e-5, -9.46945510804653e-5, 7.16785027179867e-4, 0.0412978753447533, -3.11316456645727e-4, 7.260687998496e-4, -0.00294898869469762, 7.65372715250123e-6, -6.52985136184725e-6, 5.96674617554527e-5, 1.96662622329313e-5, -7.00035234331153e-5, 8.53373727295548e-4] + }, + "fFlag" : -1, + "fChi2" : 16.23237, + "fNDF" : 3, + "fB" : 0, + "fLength" : 253.9741, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 12, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 25.5586757659912, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}] +] diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 014db562..46430b30 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -34,20 +34,27 @@ public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { } } +/** + * A layer for extruded shape + */ @Serializable public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) +/** + * An extruded shape with the same number of points on each layer. + */ @Serializable @SerialName("solid.extrude") public class Extruded( - public val shape: List, + public val shape: Shape2D, public val layers: List, ) : SolidBase(), GeometrySolid { - override fun toGeometry(geometryBuilder: GeometryBuilder) { - val shape: Shape2D = shape + init { + require(shape.size > 2) { "Extruded shape requires more than 2 points per layer" } + } - if (shape.size < 3) error("Extruded shape requires more than 2 points per layer") + override fun toGeometry(geometryBuilder: GeometryBuilder) { /** * Expand the shape for specific layers @@ -90,31 +97,31 @@ public class Extruded( geometryBuilder.cap(layers.last()) } - public companion object { - public const val TYPE: String = "solid.extruded" - } -} + public class Builder( + public var shape: List = emptyList(), + public var layers: MutableList = ArrayList(), + public val properties: MutableMeta = MutableMeta(), + ) { + public fun shape(block: Shape2DBuilder.() -> Unit) { + this.shape = Shape2DBuilder().apply(block).build() + } -public class ExtrudeBuilder( - public var shape: List = emptyList(), - public var layers: MutableList = ArrayList(), - public val properties: MutableMeta = MutableMeta(), -) { - public fun shape(block: Shape2DBuilder.() -> Unit) { - this.shape = Shape2DBuilder().apply(block).build() - } + public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { + layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat())) + } - public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { - layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat())) + internal fun build(): Extruded = Extruded(shape, layers).apply { + this.properties.setProperty(Name.EMPTY, this@Builder.properties) + } } - internal fun build(): Extruded = Extruded(shape, layers).apply { - this.properties.setProperty(Name.EMPTY, this@ExtrudeBuilder.properties) + public companion object { + public const val TYPE: String = "solid.extruded" } } @VisionBuilder public fun MutableVisionContainer.extruded( name: String? = null, - action: ExtrudeBuilder.() -> Unit = {}, -): Extruded = ExtrudeBuilder().apply(action).build().also { setChild(name, it) } \ No newline at end of file + action: Extruded.Builder.() -> Unit = {}, +): Extruded = Extruded.Builder().apply(action).build().also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt index b9a2fdba..08c00d51 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt @@ -15,7 +15,6 @@ import kotlin.math.sqrt @Serializable(Float32Euclidean2DSpace.VectorSerializer::class) public interface Float32Vector2D: Vector2D - public object Float32Euclidean2DSpace : GeometrySpace, ScaleOperations { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LayersSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LayersSurface.kt new file mode 100644 index 00000000..4a637762 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LayersSurface.kt @@ -0,0 +1,136 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.kmath.geometry.component1 +import space.kscience.kmath.geometry.component2 +import space.kscience.kmath.structures.Float32 + + +private inline fun Iterable.sumOf(selector: (T) -> Float32): Float32 { + var sum = 0f + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * A layered solid with a hole inside + */ +@Serializable +@SerialName("solid.surface") +public class LayersSurface( + public val layers: List, +) : SolidBase(), GeometrySolid { + + @Serializable + public data class Layer(val z: Float32, val outer: Shape2D, val inner: Shape2D?) { + init { + require(outer.size >= 3) { "Extruded shape requires more than 2 points per layer" } + require(inner == null || inner.size == outer.size) { "Outer shape size is ${outer.size}, but inner is ${inner?.size}" } + } + + public fun outerPoints(): List = outer.map { (x, y) -> Float32Vector3D(x, y, z) } + + public fun innerPoints(): List? = inner?.map { (x, y) -> Float32Vector3D(x, y, z) } + + public val center: Float32Vector3D by lazy { + Float32Vector3D( + outer.sumOf { it.x } / size, + outer.sumOf { it.y } / size, + z + ) + } + + + val size: Int get() = outer.size + } + + init { + require(layers.size > 1) { "Number of layers must be 2 or more" } + require(layers.all { it.size == layers.first().size }) { "All layers must have the same size" } + } + + override fun toGeometry(geometryBuilder: GeometryBuilder) { + + geometryBuilder.apply { + //outer and inner + for (i in 0 until layers.size - 1) { + val bottom = layers[i] + val top = layers[i+1] + + //creating shape in x-y plane with z = 0 + val bottomOuterPoints = bottom.outerPoints() + val topOuterPoints = top.outerPoints() + + for (it in 1 until bottomOuterPoints.size) { + //outer face + face4( + bottomOuterPoints[it - 1], + bottomOuterPoints[it], + topOuterPoints[it], + topOuterPoints[it - 1] + ) + } + + //outer face last segment + face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last()) + + val bottomInnerPoints = bottom.innerPoints() ?: bottom.outerPoints().map { bottom.center } + val topInnerPoints = top.innerPoints() ?: top.outerPoints().map { top.center } + + for (it in 1 until bottomInnerPoints.size) { + //inner face + face4( + bottomInnerPoints[it], + bottomInnerPoints[it - 1], + topInnerPoints[it - 1], + topInnerPoints[it] + ) + } + + //inner face last segment + face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0]) + } + + val bottom = layers.first() + val top = layers.last() + val bottomOuterPoints = bottom.outerPoints() + val topOuterPoints = top.outerPoints() + val bottomInnerPoints = bottom.innerPoints() ?: bottom.outerPoints().map { bottom.center } + val topInnerPoints = top.innerPoints() ?: top.outerPoints().map { top.center } + + (1 until bottom.size).forEach { + + //bottom cup + face4( + bottomInnerPoints[it - 1], + bottomInnerPoints[it], + bottomOuterPoints[it], + bottomOuterPoints[it - 1] + ) + //upper cup + face4( + topInnerPoints[it], + topInnerPoints[it - 1], + topOuterPoints[it - 1], + topOuterPoints[it] + ) + + + face4( + bottomInnerPoints.last(), + bottomInnerPoints[0], + bottomOuterPoints[0], + bottomOuterPoints.last() + ) + face4(topInnerPoints[0], topInnerPoints.last(), topOuterPoints.last(), topOuterPoints[0]) + } + } + } + + public companion object { + public const val TYPE: String = "solid.surface" + } +} From af2539eed2333cf438ab3caddb09de5cf4093b9f Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 30 Sep 2023 20:13:08 +0300 Subject: [PATCH 088/112] BM@N and fixes --- .../commonMain/kotlin/ru/mipt/npm/root/BMN.kt | 3 ++ .../kotlin/{rootParser.kt => BmnDemo.kt} | 30 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) rename demo/playground/src/jvmMain/kotlin/{rootParser.kt => BmnDemo.kt} (64%) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt index 78053d1d..5ae1671c 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt @@ -4,6 +4,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray +import space.kscience.visionforge.solid.Float32Vector3D @Serializable @@ -16,6 +17,8 @@ public data class FairTrackParam( val fQp: Double, ) +public fun FairTrackParam.toVector(): Float32Vector3D = Float32Vector3D(fX,fY,fZ) + @Serializable public data class CbmStsTrack( val fParamFirst: FairTrackParam, diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/BmnDemo.kt similarity index 64% rename from demo/playground/src/jvmMain/kotlin/rootParser.kt rename to demo/playground/src/jvmMain/kotlin/BmnDemo.kt index 04aa71f7..8f38af59 100644 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ b/demo/playground/src/jvmMain/kotlin/BmnDemo.kt @@ -4,16 +4,14 @@ import ru.mipt.npm.root.BMN import ru.mipt.npm.root.DGeoManager import ru.mipt.npm.root.rootGeo import ru.mipt.npm.root.serialization.TGeoManager +import ru.mipt.npm.root.toVector import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.isLeaf import space.kscience.dataforge.meta.string import space.kscience.visionforge.Colors import space.kscience.visionforge.html.ResourceLocation -import space.kscience.visionforge.solid.Solids -import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.invoke -import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.solid.* import java.util.zip.ZipInputStream import kotlin.io.path.Path import kotlin.io.path.writeText @@ -52,6 +50,30 @@ fun main() { rootGeo(geo,"BM@N", ignoreRootColors = true).also { Path("data/BM@N.vf.json").writeText(Solids.encodeToString(it)) } + + solidGroup("cbmStsTracks") { + events.cbmTracks.forEach { track -> + polyline( + track.fParamFirst.toVector(), + track.fParamLast.toVector() + ) { + thickness = 2.0 + color(Colors.blue) + } + } + } + + solidGroup("bmnGlobalTracks") { + events.bmnGlobalTracks.forEach { track -> + polyline( + track.fParamFirst.toVector(), + track.fParamLast.toVector() + ) { + thickness = 2.0 + color(Colors.red) + } + } + } } } } From 9356e34328a44a9e52d2191c4104c65c1dba62fd Mon Sep 17 00:00:00 2001 From: Igor Dunaev Date: Wed, 4 Oct 2023 13:43:38 +0300 Subject: [PATCH 089/112] Add CutTube class --- .../kscience/visionforge/solid/CutTube.kt | 154 ++++++++++++++++++ .../kscience/visionforge/solid/Solids.kt | 1 + 2 files changed, 155 insertions(+) create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt new file mode 100644 index 00000000..e98f07bc --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt @@ -0,0 +1,154 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild +import kotlin.math.abs +import kotlin.math.cos +import kotlin.math.sin + +/** + * A tube section cut with two planes. + * The centers of the two sections are positioned + * along the central axis of the tube, at the top + * and at the bottom. + * + * The default segment number is 32. + */ +@Serializable +@SerialName("solid.cutTube") +public class CutTube( + public val outerRadius: Float, + public val innerRadius: Float, + public val height: Float, + public val phiStart: Float = 0f, + public val phi: Float = PI2, + public val nTop: Float32Vector3D, + public val nBottom: Float32Vector3D, +) : SolidBase(), GeometrySolid { + + init { + require(innerRadius >= 0) { "Tube inner radius must be non-negative" } + require(outerRadius >= 0) { "Tube outer radius must not be less than its inner radius" } + require(height >= 0) { "Tube height must be non-negative" } + //TODO implement more "subtle" section checks + require(abs(nTop.z) > 1e-5) { "Top section is almost vertical" } + require(abs(nBottom.z) > 1e-5) { "Bottom section is almost vertical" } + //require(phiStart >= 0) + require(phi in (0f..(PI2))) + } + + override fun toGeometry(geometryBuilder: GeometryBuilder) { + val segments = detail ?: 32 + require(segments >= 4) { "The number of segments in the tube is too small" } + val angleStep = phi / (segments - 1) + + fun section(r: Float, z: Float, n: Float32Vector3D): List = (0 until segments).map { i -> + val x = r * cos(phiStart + angleStep * i) + val y = r * sin(phiStart + angleStep * i) + Float32Vector3D(x, y, (n.z * z - n.x * x - n.y * y) / n.z) + } + + geometryBuilder.apply { + //creating top and bottom sections of the tube: + //shapes in planes defined with (0, 0, +-z) points and normal vectors + //TODO check for an intersection of the sections + val topOuterPoints = section(outerRadius, height / 2, nTop) + val bottomOuterPoints = section(outerRadius, -height / 2, nBottom) + + + //outer face + for (it in 1 until segments) { + face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1]) + } + if (phi == PI2) { + face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last()) + } + + if (innerRadius == 0f) { + val zeroBottom = Float32Vector3D(0f, 0f, -height / 2) + val zeroTop = Float32Vector3D(0f, 0f, height / 2) + (1 until segments).forEach { + face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) + face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop) + } + if (phi == PI2) { + face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) + face(topOuterPoints.last(), topOuterPoints[0], zeroTop) + } else { + face4(zeroTop, zeroBottom, bottomOuterPoints[0], topOuterPoints[0]) + face4(zeroTop, zeroBottom, bottomOuterPoints.last(), topOuterPoints.last()) + } + } else { + val topInnerPoints = section(innerRadius, height / 2, nTop) + val bottomInnerPoints = section(innerRadius, -height / 2, nBottom) + // inner face + (1 until segments).forEach { + // inner surface + face4( + bottomInnerPoints[it], + bottomInnerPoints[it - 1], + topInnerPoints[it - 1], + topInnerPoints[it] + ) + //bottom cup + face4( + bottomInnerPoints[it - 1], + bottomInnerPoints[it], + bottomOuterPoints[it], + bottomOuterPoints[it - 1] + ) + //upper cup + face4( + topInnerPoints[it], + topInnerPoints[it - 1], + topOuterPoints[it - 1], + topOuterPoints[it] + ) + } + if (phi == PI2) { + face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0]) + face4( + bottomInnerPoints.last(), + bottomInnerPoints[0], + bottomOuterPoints[0], + bottomOuterPoints.last() + ) + face4(topInnerPoints[0], topInnerPoints.last(), topOuterPoints.last(), topOuterPoints[0]) + } else { + face4(bottomInnerPoints[0], bottomOuterPoints[0], topOuterPoints[0], topInnerPoints[0]) + face4( + bottomOuterPoints.last(), + bottomInnerPoints.last(), + topInnerPoints.last(), + topOuterPoints.last() + ) + } + } + } + } +} + + +@VisionBuilder +public inline fun MutableVisionContainer.cutTube( + outerRadius: Number, + innerRadius: Number, + height: Number, + startAngle: Number = 0f, + angle: Number = PI2, + topNormal: Float32Vector3D, + bottomNormal: Float32Vector3D, + name: String? = null, + block: CutTube.() -> Unit = {}, +): CutTube = CutTube( + outerRadius = outerRadius.toFloat(), + innerRadius = innerRadius.toFloat(), + height = height.toFloat(), + phiStart = startAngle.toFloat(), + phi = angle.toFloat(), + nTop = topNormal, + nBottom = bottomNormal +).apply(block).also { setChild(name, it) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 1477c2a0..0ad9bdeb 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -45,6 +45,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer Date: Sat, 7 Oct 2023 14:53:04 +0300 Subject: [PATCH 090/112] Name unification in Vision properties manipulation --- CHANGELOG.md | 1 + .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 2 +- .../mipt/npm/root/serialization/jsonToRoot.kt | 3 +- .../visionforge/gdml/GDMLVisionTest.kt | 2 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 2 +- demo/playground/src/jvmMain/kotlin/antenna.kt | 2 +- .../playground/src/jvmMain/kotlin/extruded.kt | 11 ++- demo/playground/src/jvmMain/kotlin/surface.kt | 16 ++++ gradle.properties | 2 +- .../kscience/visionforge/AbstractVision.kt | 2 +- .../space/kscience/visionforge/StyleSheet.kt | 4 +- .../space/kscience/visionforge/Vision.kt | 5 +- ...VisionChange.kt => VisionChangeBuilder.kt} | 34 +------- .../space/kscience/visionforge/VisionEvent.kt | 52 +++++++++++ .../space/kscience/visionforge/VisionGroup.kt | 32 +++++-- .../kscience/visionforge/VisionProperties.kt | 87 +++++++++++-------- .../kscience/visionforge/flowProperty.kt | 4 +- .../visionforge/html/HtmlVisionRenderer.kt | 1 - .../visionforge/html/VisionOfHtmlInput.kt | 5 +- .../space/kscience/visionforge/useProperty.kt | 4 +- .../kscience/visionforge/html/HtmlTagTest.kt | 1 + .../visionforge/meta/VisionPropertyTest.kt | 6 +- .../kscience/visionforge/VisionClient.kt | 60 ++++++++----- .../kscience/visionforge/inputRenderers.kt | 6 +- .../visionforge/plotly/VisionOfPlotly.kt | 5 +- .../visionforge/server/VisionServer.kt | 18 ++-- .../kscience/visionforge/solid/Composite.kt | 7 +- .../kscience/visionforge/solid/Extruded.kt | 2 +- .../kscience/visionforge/solid/PolyLine.kt | 5 +- .../space/kscience/visionforge/solid/Solid.kt | 6 +- .../visionforge/solid/SolidMaterial.kt | 8 +- .../visionforge/solid/SolidReference.kt | 19 +--- .../solid/{LayersSurface.kt => Surface.kt} | 4 +- .../solid/transform/RemoveSingleChild.kt | 2 +- .../visionforge/solid/SolidPropertyTest.kt | 1 + .../solid/three/ThreeLineFactory.kt | 2 +- .../visionforge/solid/three/ThreeMaterials.kt | 12 +-- .../solid/three/ThreeMeshFactory.kt | 2 +- 38 files changed, 262 insertions(+), 175 deletions(-) create mode 100644 demo/playground/src/jvmMain/kotlin/surface.kt rename visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/{VisionChange.kt => VisionChangeBuilder.kt} (84%) create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt rename visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/{LayersSurface.kt => Surface.kt} (98%) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbb44a80..87fe2343 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added - Context receivers flag - MeshLine for thick lines +- Custom client-side events and thier processing in VisionServer ### Changed - Color accessor property is now `colorProperty`. Color uses `invoke` instead of `set` diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index c81ca577..d6b7b4ce 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -3,6 +3,7 @@ package ru.mipt.npm.root import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus @@ -12,7 +13,6 @@ import space.kscience.kmath.geometry.fromRotationMatrix import space.kscience.kmath.linear.VirtualMatrix import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.isEmpty -import space.kscience.visionforge.set import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY import kotlin.math.PI diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt index c443f646..e3cf446c 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt @@ -12,6 +12,7 @@ import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.subclass +@Suppress("UNUSED_PARAMETER") private fun jsonRootDeserializer( tSerializer: KSerializer, builder: (JsonElement) -> T, @@ -83,7 +84,7 @@ private object RootDecoder { return ref.getOrPutValue { // println("Decoding $it") - val actualTypeName = it.jsonObject["_typename"]?.jsonPrimitive?.content +// val actualTypeName = it.jsonObject["_typename"]?.jsonPrimitive?.content input.json.decodeFromJsonElement(tSerializer, it) } } diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index 294af3ee..ba9cb333 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -34,6 +34,6 @@ class GDMLVisionTest { val child = cubes[Name.of("composite-000","segment-0")] assertNotNull(child) child.properties.setValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) - assertEquals("red", child.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string) + assertEquals("red", child.properties.getMeta(SolidMaterial.MATERIAL_COLOR_KEY).string) } } \ No newline at end of file diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index f11c9e01..2cc8e9a5 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -69,7 +69,7 @@ class Model(val manager: VisionManager) { fun reset() { map.values.forEach { - it.properties.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, null) + it.properties.setMeta(SolidMaterial.MATERIAL_COLOR_KEY, null) } tracks.children.clear() } diff --git a/demo/playground/src/jvmMain/kotlin/antenna.kt b/demo/playground/src/jvmMain/kotlin/antenna.kt index 5ec997f7..5080e939 100644 --- a/demo/playground/src/jvmMain/kotlin/antenna.kt +++ b/demo/playground/src/jvmMain/kotlin/antenna.kt @@ -75,7 +75,7 @@ fun main() = serve { val incRot = Quaternion.fromRotation(30.degrees, Euclidean3DSpace.zAxis) - val rotationJob = context.launch { + context.launch { var time: Long = 0L while (isActive) { with(QuaternionField) { diff --git a/demo/playground/src/jvmMain/kotlin/extruded.kt b/demo/playground/src/jvmMain/kotlin/extruded.kt index 8a25549f..fb4707eb 100644 --- a/demo/playground/src/jvmMain/kotlin/extruded.kt +++ b/demo/playground/src/jvmMain/kotlin/extruded.kt @@ -1,9 +1,6 @@ package space.kscience.visionforge.examples -import space.kscience.visionforge.solid.ambientLight -import space.kscience.visionforge.solid.extruded -import space.kscience.visionforge.solid.polygon -import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.solid.* fun main() = makeVisionFile { vision("canvas") { @@ -12,9 +9,11 @@ fun main() = makeVisionFile { extruded("extruded") { shape{ polygon(8, 100) - layer(-30) - layer(30) } + layer(-30) + layer(30) + }.apply { + edges(false) } } } diff --git a/demo/playground/src/jvmMain/kotlin/surface.kt b/demo/playground/src/jvmMain/kotlin/surface.kt new file mode 100644 index 00000000..a13644bf --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/surface.kt @@ -0,0 +1,16 @@ +package space.kscience.visionforge.examples + +//fun main() = makeVisionFile { +// vision("canvas") { +// solid { +// ambientLight() +// surface("surface") { +// shape{ +// polygon(8, 100) +// layer(-30) +// layer(30) +// } +// } +// } +// } +//} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index e3a218ba..063d38a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.js.compiler=ir -kotlin.incremental.js.ir=true +#kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt index e7df2198..0cba6a37 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt @@ -3,7 +3,7 @@ package space.kscience.visionforge import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 7320839d..00213644 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline @JvmInline public value class StyleSheet(private val owner: Vision) { - private val styleNode: Meta get() = owner.properties.getProperty(STYLESHEET_KEY) + private val styleNode: Meta get() = owner.properties.getMeta(STYLESHEET_KEY) public val items: Map get() = styleNode.items @@ -23,7 +23,7 @@ public value class StyleSheet(private val owner: Vision) { * Define a style without notifying owner */ public fun define(key: String, style: Meta?) { - owner.properties.setProperty(STYLESHEET_KEY + key, style) + owner.properties.setMeta(STYLESHEET_KEY + key, style) } /** diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index ce5f588f..31ff307e 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -37,6 +37,9 @@ public interface Vision : Described { * Update this vision using a dif represented by [VisionChange]. */ public fun update(change: VisionChange) { + if (change.children?.isNotEmpty() == true) { + error("Vision is not a group") + } change.properties?.let { updateProperties(it, Name.EMPTY) } @@ -67,7 +70,7 @@ public var Vision.visible: Boolean? */ public fun Vision.onPropertyChange( scope: CoroutineScope? = manager?.context, - callback: suspend (Name) -> Unit + callback: suspend (Name) -> Unit, ): Job = properties.changes.onEach { callback(it) }.launchIn(scope ?: error("Orphan Vision can't observe properties")) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChangeBuilder.kt similarity index 84% rename from visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt rename to visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChangeBuilder.kt index 847368f3..5b143023 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChangeBuilder.kt @@ -1,15 +1,15 @@ package space.kscience.visionforge -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* -import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.plus @@ -27,22 +27,6 @@ private fun Vision.deepCopy(manager: VisionManager): Vision { return manager.decodeFromJson(json) } -/** - * A vision used only in change propagation and showing that the target should be removed - */ -@Serializable -public object NullVision : Vision { - override var parent: Vision? - get() = null - set(_) { - error("Can't set parent for null vision") - } - - override val properties: MutableVisionProperties get() = error("Can't get properties of `NullVision`") - - override val descriptor: MetaDescriptor? = null -} - /** * An update for a [Vision] @@ -111,18 +95,6 @@ public class VisionChangeBuilder : MutableVisionContainer { ) } -/** - * @param vision a new value for vision content. If the Vision is to be removed should be [NullVision] - * @param properties updated properties - * @param children a map of children changed in ths [VisionChange]. If a child to be removed, set [delete] flag to true. - */ -@Serializable -public data class VisionChange( - public val vision: Vision? = null, - public val properties: Meta? = null, - public val children: Map? = null, -) - public inline fun VisionManager.VisionChange(block: VisionChangeBuilder.() -> Unit): VisionChange = VisionChangeBuilder().apply(block).deepCopy(this) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt new file mode 100644 index 00000000..3f86a2c0 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt @@ -0,0 +1,52 @@ +package space.kscience.visionforge + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.names.Name + +/** + * An event propagated from client to a server + */ +@Serializable +public sealed interface VisionEvent + +/** + * An event that consists of custom meta + */ +@Serializable +@SerialName("meta") +public class VisionMetaEvent(public val targetName: Name, public val meta: Meta) : VisionEvent + + +/** + * A vision used only in change propagation and showing that the target should be removed + */ +@Serializable +@SerialName("null") +public object NullVision : Vision { + override var parent: Vision? + get() = null + set(_) { + error("Can't set parent for null vision") + } + + override val properties: MutableVisionProperties get() = error("Can't get properties of `NullVision`") + + override val descriptor: MetaDescriptor? = null +} + + +/** + * @param vision a new value for vision content. If the Vision is to be removed should be [NullVision] + * @param properties updated properties + * @param children a map of children changed in ths [VisionChange]. + */ +@Serializable +@SerialName("change") +public data class VisionChange( + public val vision: Vision? = null, + public val properties: Meta? = null, + public val children: Map? = null, +) : VisionEvent \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index 8a651ffc..fd8aaa16 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -10,11 +10,25 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus +import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.STYLE_KEY public interface VisionGroup : Vision { public val children: VisionChildren + + override fun update(change: VisionChange) { + change.children?.forEach { (name, change) -> + if (change.vision != null || change.vision == NullVision) { + error("VisionGroup is read-only") + } else { + children.getChild(name)?.update(change) + } + } + change.properties?.let { + updateProperties(it, Name.EMPTY) + } + } } public interface MutableVisionGroup : VisionGroup { @@ -22,15 +36,6 @@ public interface MutableVisionGroup : VisionGroup { override val children: MutableVisionChildren public fun createGroup(): MutableVisionGroup -} - -public val Vision.children: VisionChildren? get() = (this as? VisionGroup)?.children - -/** - * A full base implementation for a [Vision] - */ -@Serializable -public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { override fun update(change: VisionChange) { change.children?.forEach { (name, change) -> @@ -44,6 +49,15 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup updateProperties(it, Name.EMPTY) } } +} + +public val Vision.children: VisionChildren? get() = (this as? VisionGroup)?.children + +/** + * A full base implementation for a [Vision] + */ +@Serializable +public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { @SerialName("children") protected var childrenInternal: MutableMap? = null diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 2fa88248..dfb06b50 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -12,7 +12,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.names.* -public interface VisionProperties { +public interface VisionProperties : MetaProvider { /** * Raw Visions own properties without styles, defaults, etc. @@ -23,21 +23,26 @@ public interface VisionProperties { public fun getValue( name: Name, - inherit: Boolean? = null, + inherit: Boolean?, includeStyles: Boolean? = null, ): Value? + override fun getValue(name: Name): Value? = getValue(name, null, null) + /** * Get property with given layer flags. * @param inherit toggles parent node property lookup. Null means inference from descriptor. * @param includeStyles toggles inclusion of properties from styles. */ - public fun getProperty( + public fun getMeta( name: Name, - inherit: Boolean? = null, + inherit: Boolean?, includeStyles: Boolean? = null, ): Meta + override fun getMeta(name: Name): Meta? = getMeta(name, null, null) + + public val changes: Flow /** @@ -47,9 +52,9 @@ public interface VisionProperties { public fun invalidate(propertyName: Name) } -public interface MutableVisionProperties : VisionProperties { +public interface MutableVisionProperties : VisionProperties, MutableMetaProvider { - override fun getProperty( + override fun getMeta( name: Name, inherit: Boolean?, includeStyles: Boolean?, @@ -60,21 +65,31 @@ public interface MutableVisionProperties : VisionProperties { includeStyles, ) - public fun setProperty( + public fun setMeta( name: Name, node: Meta?, - notify: Boolean = true, + notify: Boolean, ) public fun setValue( name: Name, value: Value?, - notify: Boolean = true, + notify: Boolean, ) + + override fun getMeta(name: Name): MutableMeta = getMeta(name, null, null) + + override fun setMeta(name: Name, node: Meta?) { + setMeta(name, node, true) + } + + override fun setValue(name: Name, value: Value?) { + setValue(name, value, true) + } } public fun MutableVisionProperties.remove(name: Name) { - setProperty(name, null) + setMeta(name, null) } public fun MutableVisionProperties.remove(name: String) { @@ -134,7 +149,7 @@ private class VisionPropertiesItem( ) override fun setMeta(name: Name, node: Meta?) { - properties.setProperty(nodeName + name, node) + properties.setMeta(nodeName + name, node) } override fun toString(): String = Meta.toString(this) @@ -187,7 +202,7 @@ public abstract class AbstractVisionProperties( return descriptor?.defaultValue } - override fun setProperty(name: Name, node: Meta?, notify: Boolean) { + override fun setMeta(name: Name, node: Meta?, notify: Boolean) { //ignore if the value is the same as existing if (own?.getMeta(name) == node) return @@ -257,11 +272,11 @@ public fun VisionProperties.getValue( /** * Get [Vision] property using key as a String */ -public fun VisionProperties.getProperty( +public fun VisionProperties.getMeta( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, -): Meta = getProperty(name.parseAsName(), inherit, includeStyles) +): Meta = getMeta(name.parseAsName(), inherit, includeStyles) /** * The root property node with given inheritance and style flags @@ -271,33 +286,33 @@ public fun VisionProperties.getProperty( public fun MutableVisionProperties.root( inherit: Boolean? = null, includeStyles: Boolean? = null, -): MutableMeta = getProperty(Name.EMPTY, inherit, includeStyles) +): MutableMeta = getMeta(Name.EMPTY, inherit, includeStyles) /** * Get [Vision] property using key as a String */ -public fun MutableVisionProperties.getProperty( +public fun MutableVisionProperties.getMeta( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, -): MutableMeta = getProperty(name.parseAsName(), inherit, includeStyles) - - -public operator fun MutableVisionProperties.set(name: Name, value: Number): Unit = - setValue(name, value.asValue()) - -public operator fun MutableVisionProperties.set(name: String, value: Number): Unit = - set(name.parseAsName(), value) - -public operator fun MutableVisionProperties.set(name: Name, value: Boolean): Unit = - setValue(name, value.asValue()) - -public operator fun MutableVisionProperties.set(name: String, value: Boolean): Unit = - set(name.parseAsName(), value) - -public operator fun MutableVisionProperties.set(name: Name, value: String): Unit = - setValue(name, value.asValue()) - -public operator fun MutableVisionProperties.set(name: String, value: String): Unit = - set(name.parseAsName(), value) \ No newline at end of file +): MutableMeta = getMeta(name.parseAsName(), inherit, includeStyles) + +// +//public operator fun MutableVisionProperties.set(name: Name, value: Number): Unit = +// setValue(name, value.asValue()) +// +//public operator fun MutableVisionProperties.set(name: String, value: Number): Unit = +// set(name.parseAsName(), value) +// +//public operator fun MutableVisionProperties.set(name: Name, value: Boolean): Unit = +// setValue(name, value.asValue()) +// +//public operator fun MutableVisionProperties.set(name: String, value: Boolean): Unit = +// set(name.parseAsName(), value) +// +//public operator fun MutableVisionProperties.set(name: Name, value: String): Unit = +// setValue(name, value.asValue()) +// +//public operator fun MutableVisionProperties.set(name: String, value: String): Unit = +// set(name.parseAsName(), value) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt index c8f14ae3..f8d128e1 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt @@ -17,10 +17,10 @@ public fun Vision.flowProperty( includeStyles: Boolean? = null, ): Flow = flow { //Pass initial value. - emit(properties.getProperty(propertyName, inherit, includeStyles)) + emit(properties.getMeta(propertyName, inherit, includeStyles)) properties.changes.collect { name -> if (name.startsWith(propertyName)) { - emit(properties.getProperty(propertyName, inherit, includeStyles)) + emit(properties.getMeta(propertyName, inherit, includeStyles)) } } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt index c02b6e64..d71e848a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt @@ -93,7 +93,6 @@ public fun FlowContent.visionFragment( updatesUrl: String? = null, onVisionRendered: (Name, Vision) -> Unit = { _, _ -> }, idPrefix: String? = null, - fragment: HtmlVisionFragment, ): Unit = consumer.visionFragment( visionManager = visionManager, diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt index 3a818b08..d2bb2c52 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt @@ -6,10 +6,11 @@ import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.number import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name -import space.kscience.visionforge.* +import space.kscience.visionforge.AbstractVision +import space.kscience.visionforge.Vision //TODO replace by something -internal val Vision.mutableProperties get() = properties.getProperty(Name.EMPTY, false, false) +internal val Vision.mutableProperties get() = properties.getMeta(Name.EMPTY, false, false) @Serializable public abstract class VisionOfHtmlInput : AbstractVision() { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt index 87312f6f..f6f95a6f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt @@ -23,10 +23,10 @@ public fun Vision.useProperty( callback: (Meta) -> Unit, ): Job { //Pass initial value. - callback(properties.getProperty(propertyName, inherit, includeStyles)) + callback(properties.getMeta(propertyName, inherit, includeStyles)) return properties.changes.onEach { name -> if (name.startsWith(propertyName)) { - callback(properties.getProperty(propertyName, inherit, includeStyles)) + callback(properties.getMeta(propertyName, inherit, includeStyles)) } }.launchIn(scope ?: error("Orphan Vision can't observe properties")) } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index eaea0a4e..20868b96 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -4,6 +4,7 @@ import kotlinx.html.* import kotlinx.html.stream.createHTML import space.kscience.dataforge.context.Global import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.set import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.visionforge.* diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index e9a0685e..a6ea86a2 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -42,7 +42,7 @@ internal class VisionPropertyTest { @Test fun testPropertyEdit() { val vision = manager.group() - vision.properties.getProperty("fff.ddd").apply { + vision.properties.getMeta("fff.ddd").apply { value = 2.asValue() } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) @@ -52,7 +52,7 @@ internal class VisionPropertyTest { @Test fun testPropertyUpdate() { val vision = manager.group() - vision.properties.getProperty("fff").updateWith(TestScheme) { + vision.properties.getMeta("fff").updateWith(TestScheme) { ddd = 2 } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) @@ -87,7 +87,7 @@ internal class VisionPropertyTest { child.properties.remove("test") - assertEquals(11, child.properties.getProperty("test", inherit = true).int) + assertEquals(11, child.properties.getMeta("test", inherit = true).int) // assertEquals(11, deferred.await()?.int) // assertEquals(2, callCounter) subscription.cancel() diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index c9146efd..91e4f1bc 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -4,6 +4,7 @@ import kotlinx.browser.document import kotlinx.browser.window import kotlinx.coroutines.Job import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex @@ -11,10 +12,7 @@ import kotlinx.coroutines.sync.withLock import org.w3c.dom.* import org.w3c.dom.url.URL import space.kscience.dataforge.context.* -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MetaSerializer -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.parseAsName import space.kscience.visionforge.html.VisionTagConsumer @@ -68,7 +66,7 @@ public class VisionClient : AbstractPlugin() { /** * Communicate vision property changed from rendering engine to model */ - public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { + public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { context.launch { mutex.withLock { changeCollector.propertyChanged(visionName, propertyName, item) @@ -76,9 +74,17 @@ public class VisionClient : AbstractPlugin() { } } -// public fun visionChanged(name: Name?, child: Vision?) { -// changeCollector.setChild(name, child) -// } + private val eventCollector by lazy { + MutableSharedFlow(meta["feedback.eventCache"].int ?: 100) + } + + + /** + * Send a custom feedback event + */ + public suspend fun sendEvent(event: VisionEvent) { + eventCollector.emit(event) + } private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) { vision.setAsRoot(visionManager) @@ -103,7 +109,7 @@ public class VisionClient : AbstractPlugin() { logger.info { "Updating vision data from $wsUrl" } - //Individual websocket for this element + //Individual websocket for this vision WebSocket(wsUrl.toString()).apply { onmessage = { messageEvent -> val stringData: String? = messageEvent.data as? String @@ -131,7 +137,7 @@ public class VisionClient : AbstractPlugin() { var feedbackJob: Job? = null //Feedback changes aggregation time in milliseconds - val feedbackAggregationTime = meta["aggregationTime"]?.int ?: 300 + val feedbackAggregationTime = meta["feedback.aggregationTime"]?.int ?: 300 onopen = { feedbackJob = visionManager.context.launch { @@ -144,18 +150,24 @@ public class VisionClient : AbstractPlugin() { change.reset() } } +// // take channel for given vision name +// eventCollector[name]?.let { channel -> +// for (e in channel) { +// send(visionManager.jsonFormat.encodeToString(VisionEvent.serializer(), e)) +// } +// } } } - logger.info { "WebSocket update channel established for output '$name'" } + logger.info { "WebSocket feedback channel established for output '$name'" } } onclose = { feedbackJob?.cancel() - logger.info { "WebSocket update channel closed for output '$name'" } + logger.info { "WebSocket feedback channel closed for output '$name'" } } onerror = { feedbackJob?.cancel() - logger.error { "WebSocket update channel error for output '$name'" } + logger.error { "WebSocket feedback channel error for output '$name'" } } } } @@ -248,20 +260,26 @@ public class VisionClient : AbstractPlugin() { } } -public fun VisionClient.visionPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { - visionPropertyChanged(visionName, propertyName.parseAsName(true), item) +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) +} + +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Number) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) } -public fun VisionClient.visionPropertyChanged(visionName: Name, propertyName: String, item: Number) { - visionPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: String) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) } -public fun VisionClient.visionPropertyChanged(visionName: Name, propertyName: String, item: String) { - visionPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) } -public fun VisionClient.visionPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { - visionPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +public fun VisionClient.sendEvent(visionName: Name, event: MetaRepr): Unit { + context.launch { + sendEvent(VisionMetaEvent(visionName, event.toMeta())) + } } private fun whenDocumentLoaded(block: Document.() -> Unit): Unit { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index 390058ea..faf82d13 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -36,7 +36,7 @@ internal fun textVisionRenderer( value = it ?: "" } onChangeFunction = { - client.visionPropertyChanged(name, VisionOfTextField::text.name, value) + client.notifyPropertyChanged(name, VisionOfTextField::text.name, value) } } } @@ -58,7 +58,7 @@ internal fun numberVisionRenderer( value = it?.toDouble() ?: 0.0 } onChangeFunction = { - client.visionPropertyChanged(name, VisionOfNumberField::value.name, value) + client.notifyPropertyChanged(name, VisionOfNumberField::value.name, value) } } } @@ -106,7 +106,7 @@ internal fun formVisionRenderer( form.onsubmit = { event -> event.preventDefault() val formData = FormData(form).toMeta() - client.visionPropertyChanged(name, VisionOfHtmlForm::values.name, formData) + client.notifyPropertyChanged(name, VisionOfHtmlForm::values.name, formData) console.info("Sent: ${formData.toMap()}") false } diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index f92e7d4d..d5333dda 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -10,7 +10,6 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.plotly.Plot import space.kscience.plotly.Plotly @@ -34,7 +33,7 @@ public class VisionOfPlotly private constructor( @Transient override val properties: MutableVisionProperties = object : MutableVisionProperties { - override fun setProperty(name: Name, node: Meta?, notify: Boolean) { + override fun setMeta(name: Name, node: Meta?, notify: Boolean) { meta.setMeta(name, node) } @@ -46,7 +45,7 @@ public class VisionOfPlotly private constructor( override val descriptor: MetaDescriptor? get() = this@VisionOfPlotly.descriptor - override fun getProperty( + override fun getMeta( name: Name, inherit: Boolean?, includeStyles: Boolean?, diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 61952497..873a52c9 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -23,10 +23,7 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name -import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionChange -import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.flowChanges +import space.kscience.visionforge.* import space.kscience.visionforge.html.* import kotlin.time.Duration.Companion.milliseconds @@ -77,6 +74,11 @@ public class VisionRoute( */ public fun Application.serveVisionData( configuration: VisionRoute, + onEvent: suspend Vision.(VisionEvent) -> Unit = { event -> + if (event is VisionChange) { + update(event) + } + }, resolveVision: (Name) -> Vision?, ) { require(WebSockets) @@ -96,11 +98,11 @@ public fun Application.serveVisionData( launch { for (frame in incoming) { val data = frame.data.decodeToString() - application.log.debug("Received update for $name: \n$data") - val change = configuration.visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(), data + application.log.debug("Received event for $name: \n$data") + val event = configuration.visionManager.jsonFormat.decodeFromString( + VisionEvent.serializer(), data ) - vision.update(change) + vision.onEvent(event) } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index 7c6ab3ec..65a1bcd5 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -3,7 +3,10 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.names.Name -import space.kscience.visionforge.* +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild +import space.kscience.visionforge.static public enum class CompositeType { GROUP, // Dumb sum of meshes @@ -33,7 +36,7 @@ public inline fun MutableVisionContainer.composite( } val res = Composite(type, children[0], children[1]) - res.properties.setProperty(Name.EMPTY, group.properties.own) + res.properties.setMeta(Name.EMPTY, group.properties.own) setChild(name, res) return res diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 46430b30..70de06db 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -111,7 +111,7 @@ public class Extruded( } internal fun build(): Extruded = Extruded(shape, layers).apply { - this.properties.setProperty(Name.EMPTY, this@Builder.properties) + this.properties.setMeta(Name.EMPTY, this@Builder.properties) } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt index 1681f44a..0ead1642 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt @@ -13,7 +13,10 @@ import space.kscience.visionforge.setChild public class PolyLine(public val points: List) : SolidBase() { //var lineType by string() - public var thickness: Number by properties.root(inherit = false, includeStyles = true).number { DEFAULT_THICKNESS } + public var thickness: Number by properties.root( + inherit = false, + includeStyles = true + ).number { DEFAULT_THICKNESS } public companion object { public const val DEFAULT_THICKNESS: Double = 1.0 diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index f33573d7..3972de83 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -11,8 +11,10 @@ import space.kscience.dataforge.names.plus import space.kscience.kmath.complex.Quaternion import space.kscience.kmath.complex.QuaternionField import space.kscience.kmath.geometry.* -import space.kscience.visionforge.* +import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY +import space.kscience.visionforge.hide +import space.kscience.visionforge.inherited import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY import space.kscience.visionforge.solid.Solid.Companion.IGNORE_KEY import space.kscience.visionforge.solid.Solid.Companion.LAYER_KEY @@ -182,7 +184,7 @@ internal fun point( override fun setValue(thisRef: Solid, property: KProperty<*>, value: Float32Vector3D?) { if (value == null) { - thisRef.properties.setProperty(name, null) + thisRef.properties.setMeta(name, null) } else { thisRef.properties[name + X_KEY] = value.x thisRef.properties[name + Y_KEY] = value.y diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index df720e6c..14784065 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -107,12 +107,12 @@ public val Solid.color: ColorAccessor get() = ColorAccessor(properties.root(true), MATERIAL_COLOR_KEY) public var Solid.material: SolidMaterial? - get() = SolidMaterial.read(properties.getProperty(MATERIAL_KEY)) - set(value) = properties.setProperty(MATERIAL_KEY, value?.meta) + get() = SolidMaterial.read(properties.getMeta(MATERIAL_KEY)) + set(value) = properties.setMeta(MATERIAL_KEY, value?.meta) @VisionBuilder public fun Solid.material(builder: SolidMaterial.() -> Unit) { - properties.getProperty(MATERIAL_KEY).updateWith(SolidMaterial, builder) + properties.getMeta(MATERIAL_KEY).updateWith(SolidMaterial, builder) } public var Solid.opacity: Number? @@ -125,5 +125,5 @@ public var Solid.opacity: Number? @VisionBuilder public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { properties[SolidMaterial.EDGES_ENABLED_KEY] = enabled - SolidMaterial.write(properties.getProperty(SolidMaterial.EDGES_MATERIAL_KEY)).apply(block) + SolidMaterial.write(properties.getMeta(SolidMaterial.EDGES_MATERIAL_KEY)).apply(block) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 2770a7aa..a6aabe67 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -14,7 +14,6 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.names.* import space.kscience.visionforge.* -import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX @@ -162,7 +161,7 @@ internal class SolidReferenceChild( override val properties: MutableVisionProperties = object : MutableVisionProperties { override val descriptor: MetaDescriptor get() = this@SolidReferenceChild.descriptor - override val own: MutableMeta by lazy { owner.properties.getProperty(childToken(childName).asName()) } + override val own: MutableMeta by lazy { owner.properties.getMeta(childToken(childName).asName()) } override fun getValue( name: Name, @@ -170,7 +169,7 @@ internal class SolidReferenceChild( includeStyles: Boolean?, ): Value? = own.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) - override fun setProperty(name: Name, node: Meta?, notify: Boolean) { + override fun setMeta(name: Name, node: Meta?, notify: Boolean) { own.setMeta(name, node) } @@ -185,20 +184,6 @@ internal class SolidReferenceChild( } } - override fun update(change: VisionChange) { - change.children?.forEach { (name, change) -> - when { - change.vision == NullVision -> error("Deleting children inside ref is not allowed.") - change.vision != null -> error("Updating content of the ref is not allowed") - else -> children.getChild(name)?.update(change) - } - } - change.properties?.let { - updateProperties(it, Name.EMPTY) - } - } - - override val children: VisionChildren = object : VisionChildren { override val parent: Vision get() = this@SolidReferenceChild diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LayersSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt similarity index 98% rename from visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LayersSurface.kt rename to visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt index 4a637762..a871d9af 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LayersSurface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt @@ -20,9 +20,9 @@ private inline fun Iterable.sumOf(selector: (T) -> Float32): Float32 { */ @Serializable @SerialName("solid.surface") -public class LayersSurface( +public class Surface( public val layers: List, -) : SolidBase(), GeometrySolid { +) : SolidBase(), GeometrySolid { @Serializable public data class Layer(val z: Float32, val outer: Shape2D, val inner: Shape2D?) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index d2667e76..cdc9caaf 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -19,7 +19,7 @@ internal fun Solid.updateFrom(other: Solid): Solid { scaleX *= other.scaleX scaleY *= other.scaleY scaleZ *= other.scaleZ - properties.setProperty(Name.EMPTY, other.properties.root()) + properties.setMeta(Name.EMPTY, other.properties.root()) return this } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index 87ba368c..e4b0619d 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.set import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.asName import space.kscience.visionforge.* diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index 45325430..42722254 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -24,7 +24,7 @@ public object ThreeLineFactory : ThreeFactory { } val material = ThreeMaterials.getLineMaterial( - vision.properties.getProperty(SolidMaterial.MATERIAL_KEY), + vision.properties.getMeta(SolidMaterial.MATERIAL_KEY), false ) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index f5ac5c2b..49667c8e 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -83,7 +83,7 @@ public object ThreeMaterials { private val visionMaterialCache = HashMap() internal fun cacheMaterial(vision: Vision): Material = visionMaterialCache.getOrPut(vision) { - buildMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)).apply { + buildMaterial(vision.properties.getMeta(SolidMaterial.MATERIAL_KEY)).apply { cached = true } } @@ -133,11 +133,11 @@ public fun Mesh.setMaterial(vision: Vision) { } else { material = vision.parent?.let { parent -> //TODO cache parent material - ThreeMaterials.buildMaterial(parent.properties.getProperty(SolidMaterial.MATERIAL_KEY)) + ThreeMaterials.buildMaterial(parent.properties.getMeta(SolidMaterial.MATERIAL_KEY)) } ?: ThreeMaterials.cacheMaterial(vision) } } else { - material = ThreeMaterials.buildMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)) + material = ThreeMaterials.buildMaterial(vision.properties.getMeta(SolidMaterial.MATERIAL_KEY)) } } @@ -153,18 +153,18 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { when (propertyName) { SolidMaterial.MATERIAL_COLOR_KEY -> { material.asDynamic().color = - vision.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).threeColor() + vision.properties.getMeta(SolidMaterial.MATERIAL_COLOR_KEY).threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.SPECULAR_COLOR_KEY -> { material.asDynamic().specular = - vision.properties.getProperty(SolidMaterial.SPECULAR_COLOR_KEY).threeColor() + vision.properties.getMeta(SolidMaterial.SPECULAR_COLOR_KEY).threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { - material.asDynamic().emissive = vision.properties.getProperty(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY) + material.asDynamic().emissive = vision.properties.getMeta(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY) .threeColor() ?: ThreeMaterials.BLACK_COLOR } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index 06224bbb..4ba19998 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -76,7 +76,7 @@ public fun Mesh.applyEdges(vision: Solid) { val edges = children.find { it.name == EDGES_OBJECT_NAME } as? LineSegments //inherited edges definition, enabled by default if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = false)?.boolean != false) { - val material = ThreeMaterials.getLineMaterial(vision.properties.getProperty(EDGES_MATERIAL_KEY), true) + val material = ThreeMaterials.getLineMaterial(vision.properties.getMeta(EDGES_MATERIAL_KEY), true) if (edges == null) { add( LineSegments( From c7640a686a2b0a2b4eea4c24c95b4b90506d290f Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 7 Oct 2023 15:27:28 +0300 Subject: [PATCH 091/112] Add surface geometry --- .../playground/src/jvmMain/kotlin/extruded.kt | 7 ++-- demo/playground/src/jvmMain/kotlin/surface.kt | 31 +++++++------- .../kscience/visionforge/solid/Extruded.kt | 41 +++++-------------- .../kscience/visionforge/solid/Shape2D.kt | 26 ++++++++++++ .../kscience/visionforge/solid/Solids.kt | 1 + .../kscience/visionforge/solid/Surface.kt | 39 +++++++++++++++++- 6 files changed, 97 insertions(+), 48 deletions(-) create mode 100644 visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt diff --git a/demo/playground/src/jvmMain/kotlin/extruded.kt b/demo/playground/src/jvmMain/kotlin/extruded.kt index fb4707eb..af8fe6d0 100644 --- a/demo/playground/src/jvmMain/kotlin/extruded.kt +++ b/demo/playground/src/jvmMain/kotlin/extruded.kt @@ -1,6 +1,9 @@ package space.kscience.visionforge.examples -import space.kscience.visionforge.solid.* +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.extruded +import space.kscience.visionforge.solid.polygon +import space.kscience.visionforge.solid.solid fun main() = makeVisionFile { vision("canvas") { @@ -12,8 +15,6 @@ fun main() = makeVisionFile { } layer(-30) layer(30) - }.apply { - edges(false) } } } diff --git a/demo/playground/src/jvmMain/kotlin/surface.kt b/demo/playground/src/jvmMain/kotlin/surface.kt index a13644bf..9bcc9e2f 100644 --- a/demo/playground/src/jvmMain/kotlin/surface.kt +++ b/demo/playground/src/jvmMain/kotlin/surface.kt @@ -1,16 +1,19 @@ package space.kscience.visionforge.examples -//fun main() = makeVisionFile { -// vision("canvas") { -// solid { -// ambientLight() -// surface("surface") { -// shape{ -// polygon(8, 100) -// layer(-30) -// layer(30) -// } -// } -// } -// } -//} \ No newline at end of file +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.polygon +import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.solid.surface + +fun main() = makeVisionFile { + vision("canvas") { + solid { + ambientLight() + surface("surface") { + layer(0, {polygon(8,10)}, {polygon(8,20)}) + layer(10, {polygon(8,10)}, {polygon(8,30)}) + + } + } + } +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 70de06db..8276722e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -9,37 +9,8 @@ import space.kscience.kmath.geometry.component2 import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder import space.kscience.visionforge.setChild -import kotlin.math.PI -import kotlin.math.cos -import kotlin.math.sin -public typealias Shape2D = List - -@Serializable -public class Shape2DBuilder(private val points: ArrayList = ArrayList()) { - - public fun point(x: Number, y: Number) { - points.add(Float32Vector2D(x, y)) - } - - public fun build(): Shape2D = points -} - -public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { - require(vertices > 2) { "Polygon must have more than 2 vertices" } - val angle = 2 * PI / vertices - for (i in 0 until vertices) { - point(radius.toDouble() * cos(angle * i), radius.toDouble() * sin(angle * i)) - } -} - -/** - * A layer for extruded shape - */ -@Serializable -public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) - /** * An extruded shape with the same number of points on each layer. */ @@ -50,6 +21,12 @@ public class Extruded( public val layers: List, ) : SolidBase(), GeometrySolid { + /** + * A layer for extruded shape + */ + @Serializable + public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) + init { require(shape.size > 2) { "Extruded shape requires more than 2 points per layer" } } @@ -72,6 +49,8 @@ public class Extruded( var lowerLayer = layers.first() var upperLayer: List + geometryBuilder.cap(layers.first().reversed()) + for (i in (1 until layers.size)) { upperLayer = layers[i] for (j in (0 until shape.size - 1)) { @@ -93,7 +72,7 @@ public class Extruded( ) lowerLayer = upperLayer } - geometryBuilder.cap(layers.first().reversed()) + geometryBuilder.cap(layers.last()) } @@ -102,10 +81,12 @@ public class Extruded( public var layers: MutableList = ArrayList(), public val properties: MutableMeta = MutableMeta(), ) { + @VisionBuilder public fun shape(block: Shape2DBuilder.() -> Unit) { this.shape = Shape2DBuilder().apply(block).build() } + @VisionBuilder public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat())) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt new file mode 100644 index 00000000..4f5d48a4 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt @@ -0,0 +1,26 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.Serializable +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin + +public typealias Shape2D = List + +@Serializable +public class Shape2DBuilder(private val points: ArrayList = ArrayList()) { + + public fun point(x: Number, y: Number) { + points.add(Float32Vector2D(x, y)) + } + + public fun build(): Shape2D = points +} + +public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { + require(vertices > 2) { "Polygon must have more than 2 vertices" } + val angle = 2 * PI / vertices + for (i in 0 until vertices) { + point(radius.toDouble() * cos(angle * i), radius.toDouble() * sin(angle * i)) + } +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 1477c2a0..2a2e86fc 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -41,6 +41,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer Iterable.sumOf(selector: (T) -> Float32): Float32 { @@ -58,7 +63,7 @@ public class Surface( //outer and inner for (i in 0 until layers.size - 1) { val bottom = layers[i] - val top = layers[i+1] + val top = layers[i + 1] //creating shape in x-y plane with z = 0 val bottomOuterPoints = bottom.outerPoints() @@ -130,7 +135,39 @@ public class Surface( } } + public class Builder( + public var layers: MutableList = ArrayList(), + public val properties: MutableMeta = MutableMeta(), + ) { + + public fun layer( + z: Number, + innerBuilder: (Shape2DBuilder.() -> Unit)? = null, + outerBuilder: Shape2DBuilder.() -> Unit, + ) { + layers.add( + Layer( + z.toFloat(), + outer = Shape2DBuilder().apply(outerBuilder).build(), + inner = innerBuilder?.let { Shape2DBuilder().apply(innerBuilder).build() } + ) + ) + } + + internal fun build(): Surface = Surface(layers).apply { + properties.setMeta(Name.EMPTY, this@Builder.properties) + } + } + + public companion object { public const val TYPE: String = "solid.surface" } } + + +@VisionBuilder +public fun MutableVisionContainer.surface( + name: String? = null, + action: Surface.Builder.() -> Unit = {}, +): Surface = Surface.Builder().apply(action).build().also { setChild(name, it) } From 52d346453c14ab1a6b815c9e12ade0dda7b85562 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 7 Oct 2023 15:42:03 +0300 Subject: [PATCH 092/112] Added polygone with a hole to Root converter --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 31 ++++++++++++------- .../playground/src/jvmMain/kotlin/extruded.kt | 1 + demo/playground/src/jvmMain/kotlin/surface.kt | 6 ++-- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index d6b7b4ce..ba3e4616 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -188,7 +188,7 @@ private fun SolidGroup.addShape( } "TGeoPgon" -> { - //TODO add a inner polygone layer + val fDphi by shape.meta.double(0.0) val fNz by shape.meta.int(2) val fPhi1 by shape.meta.double(360.0) @@ -201,19 +201,26 @@ private fun SolidGroup.addShape( val startphi = degToRad(fPhi1) val deltaphi = degToRad(fDphi) - extruded(name) { + fun Shape2DBuilder.pGon(radius: Double){ + (0.. 1) { "The polyhedron geometry requires at least two planes" } - val baseRadius = fRmax[0] - shape { - (0.. - //scaling all radii relative to first layer radius - layer(fZ[index], scale = fRmax[index] / baseRadius) + for (index in 0 until fNz){ + layer( + fZ[index], + innerBuilder = { + pGon(fRmin[index]) + }, + outerBuilder = { + pGon(fRmax[index]) + } + ) } }.apply(block) } diff --git a/demo/playground/src/jvmMain/kotlin/extruded.kt b/demo/playground/src/jvmMain/kotlin/extruded.kt index af8fe6d0..c45b2564 100644 --- a/demo/playground/src/jvmMain/kotlin/extruded.kt +++ b/demo/playground/src/jvmMain/kotlin/extruded.kt @@ -14,6 +14,7 @@ fun main() = makeVisionFile { polygon(8, 100) } layer(-30) + layer(0, x = 10, y = 10) layer(30) } } diff --git a/demo/playground/src/jvmMain/kotlin/surface.kt b/demo/playground/src/jvmMain/kotlin/surface.kt index 9bcc9e2f..01fbfb50 100644 --- a/demo/playground/src/jvmMain/kotlin/surface.kt +++ b/demo/playground/src/jvmMain/kotlin/surface.kt @@ -10,9 +10,9 @@ fun main() = makeVisionFile { solid { ambientLight() surface("surface") { - layer(0, {polygon(8,10)}, {polygon(8,20)}) - layer(10, {polygon(8,10)}, {polygon(8,30)}) - + layer(0, { polygon(8, 10) }, { polygon(8, 20) }) + layer(10, { polygon(8, 20) }, { polygon(8, 30) }) + layer(20, { polygon(8, 10) }, { polygon(8, 20) }) } } } From cf4743b6007060d284c13c1d519dec7a2cef2471 Mon Sep 17 00:00:00 2001 From: Igor Dunaev Date: Sun, 8 Oct 2023 15:16:32 +0300 Subject: [PATCH 093/112] Add ROOT to Solid conversion for TGeoCone and TGeoCTub shapes --- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index c81ca577..e19b2786 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -269,6 +269,44 @@ private fun SolidGroup.addShape( } } + "TGeoCone" -> { + val fDz by shape.meta.double(0.0) + val fRmin1 by shape.meta.double(0.0) + val fRmax1 by shape.meta.double(0.0) + val fRmin2 by shape.meta.double(0.0) + val fRmax2 by shape.meta.double(0.0) + + coneSurface( + bottomOuterRadius = fRmax1, + bottomInnerRadius = fRmin1, + height = fDz * 2.0, + topOuterRadius = fRmax2, + topInnerRadius = fRmin2, + name = name, + ) + } + + "TGeoCtub" -> { + val fRmin by shape.meta.double(0.0) + val fRmax by shape.meta.double(0.0) + val fDz by shape.meta.double(0.0) + val fPhi1 by shape.meta.double(0.0) + val fPhi2 by shape.meta.double(PI2.toDouble()) + val fNlow by shape.meta.doubleArray() + val fNhigh by shape.meta.doubleArray() + + cutTube( + outerRadius = fRmax, + innerRadius = fRmin, + height = fDz * 2.0, + startAngle = degToRad(fPhi1), + angle = degToRad(fPhi2 - fPhi1), + topNormal = Float32Vector3D(fNhigh[0], fNhigh[1], fNhigh[2]), + bottomNormal = Float32Vector3D(fNlow[0], fNlow[1], fNlow[2]), + name = name, + ) + } + else -> { TODO("A shape with type ${shape.typename} not implemented") } From 15b7dbd057cd5e16931145739813b9369a712a21 Mon Sep 17 00:00:00 2001 From: Igor Dunaev Date: Sun, 8 Oct 2023 17:09:18 +0300 Subject: [PATCH 094/112] Add documentation for parameters --- .../space/kscience/visionforge/solid/CutTube.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt index e98f07bc..cc0ef614 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt @@ -132,6 +132,20 @@ public class CutTube( } +/** + * Create a cut tube - a hollow cylinder (or a segment) cut with two planes. The axis of the cylinder + * is the Z axis. Each section is define by a center and a normal vector. The centers of the two sections + * are the points (0, 0, height / 2) and (0, 0, -height / 2). + * + * @param outerRadius outer radius of the tube + * @param innerRadius inner radius if the tube + * @param height height (length) of the tube. Essentially this is the length of the Z axis segment, + * contained between the top and bottom sections of the tube + * @param startAngle start angle of the segment (if this is a segment) + * @param angle angular magnitude of the segment + * @param topNormal normal vector of the top section + * @param bottomNormal normal vector of the bottom section + */ @VisionBuilder public inline fun MutableVisionContainer.cutTube( outerRadius: Number, From 8fac827acb49c122e961a714b83dcb2e57c116cd Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 9 Oct 2023 16:17:08 +0300 Subject: [PATCH 095/112] Update versions --- build.gradle.kts | 2 +- demo/playground/src/jvmMain/kotlin/BmnDemo.kt | 3 +++ gradle.properties | 2 +- visionforge-plotly/build.gradle.kts | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 775fd191..56dda332 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { // id("org.jetbrains.kotlinx.kover") version "0.5.0" } -val dataforgeVersion by extra("0.6.1") +val dataforgeVersion by extra("0.6.2") val fxVersion by extra("11") allprojects { diff --git a/demo/playground/src/jvmMain/kotlin/BmnDemo.kt b/demo/playground/src/jvmMain/kotlin/BmnDemo.kt index 8f38af59..295701fa 100644 --- a/demo/playground/src/jvmMain/kotlin/BmnDemo.kt +++ b/demo/playground/src/jvmMain/kotlin/BmnDemo.kt @@ -14,6 +14,7 @@ import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.* import java.util.zip.ZipInputStream import kotlin.io.path.Path +import kotlin.io.path.createDirectories import kotlin.io.path.writeText @@ -25,6 +26,8 @@ private fun Meta.countTypes(): Sequence = sequence { } fun main() { + Path("data").createDirectories() + val string = ZipInputStream(TGeoManager::class.java.getResourceAsStream("/root/geometry_run_7-2076.zip")!!).use { it.nextEntry it.readAllBytes().decodeToString() diff --git a/gradle.properties b/gradle.properties index dc7d1342..279f6491 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,5 +9,5 @@ org.gradle.jvmargs=-Xmx4G org.jetbrains.compose.experimental.jscanvas.enabled=true toolsVersion=0.15.0-kotlin-1.9.20-Beta2 -kotlin.experimental.tryK2=true +#kotlin.experimental.tryK2=true #kscience.wasm.disabled=true diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index 8b0a99d1..9d313266 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -val plotlyVersion = "0.5.3" +val plotlyVersion = "0.6.0" kscience { jvm() From 001efa711a67dbd741894cc41ad84fa0bbfbd973 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 18 Oct 2023 11:30:27 +0300 Subject: [PATCH 096/112] update version --- demo/playground/build.gradle.kts | 2 +- gradle.properties | 2 +- visionforge-markdown/build.gradle.kts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index 36bd6b7b..c51f6691 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -17,7 +17,7 @@ kotlin { useCommonJs() browser { webpackTask { - outputFileName = "js/visionforge-playground.js" + mainOutputFileName.set("js/visionforge-playground.js") } commonWebpackConfig { sourceMaps = true diff --git a/gradle.properties b/gradle.properties index 279f6491..900cd1b7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ org.gradle.jvmargs=-Xmx4G org.jetbrains.compose.experimental.jscanvas.enabled=true -toolsVersion=0.15.0-kotlin-1.9.20-Beta2 +toolsVersion=0.15.0-kotlin-1.9.20-RC #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true diff --git a/visionforge-markdown/build.gradle.kts b/visionforge-markdown/build.gradle.kts index 36559a09..eb856d75 100644 --- a/visionforge-markdown/build.gradle.kts +++ b/visionforge-markdown/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -val markdownVersion = "0.4.1" +val markdownVersion = "0.5.2" kscience { jvm() From 2578fd6f77faa33080e644a6beb54a251c60aa79 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 18 Oct 2023 11:31:11 +0300 Subject: [PATCH 097/112] Replace external enum with external sealed object --- demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt | 26 +++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt b/demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt index 635c4580..5116155b 100644 --- a/demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt +++ b/demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt @@ -9,30 +9,38 @@ import react.Component import react.Props import react.State -external enum class DropEffects { - copy, - move, - link, - none +sealed external class DropEffects { + @JsName("copy") + object Copy : DropEffects + + @JsName("move") + object Move : DropEffects + + @JsName("link") + object Link : DropEffects + + @JsName("none") + object None : DropEffects } -external interface FileDropProps: Props { +external interface FileDropProps : Props { var className: String? var targetClassName: String? var draggingOverFrameClassName: String? var draggingOverTargetClassName: String? -// var frame?: Exclude | HTMLDocument; + // var frame?: Exclude | HTMLDocument; var onFrameDragEnter: ((event: DragEvent) -> Unit)? var onFrameDragLeave: ((event: DragEvent) -> Unit)? var onFrameDrop: ((event: DragEvent) -> Unit)? -// var onDragOver: ReactDragEventHandler? + + // var onDragOver: ReactDragEventHandler? // var onDragLeave: ReactDragEventHandler? var onDrop: ((files: FileList?, event: dynamic) -> Unit)?//event:DragEvent) var dropEffect: DropEffects? } -external interface FileDropState: State { +external interface FileDropState : State { var draggingOverFrame: Boolean var draggingOverTarget: Boolean } From cf6d73305bf372fe730e3dc66e91faf5110da5e9 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 18 Oct 2023 13:52:42 +0300 Subject: [PATCH 098/112] Add vision client-side events --- ...VisionChangeBuilder.kt => VisionChange.kt} | 38 +++++++++++++++++++ .../space/kscience/visionforge/VisionEvent.kt | 37 +++--------------- .../kscience/visionforge/VisionClient.kt | 15 ++++---- .../visionforge/server/VisionServer.kt | 4 +- 4 files changed, 53 insertions(+), 41 deletions(-) rename visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/{VisionChangeBuilder.kt => VisionChange.kt} (83%) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChangeBuilder.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt similarity index 83% rename from visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChangeBuilder.kt rename to visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 5b143023..9915c035 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChangeBuilder.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -9,12 +9,34 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.plus import kotlin.time.Duration + + +/** + * A vision used only in change propagation and showing that the target should be removed + */ +@Serializable +@SerialName("null") +public object NullVision : Vision { + override var parent: Vision? + get() = null + set(_) { + error("Can't set parent for null vision") + } + + override val properties: MutableVisionProperties get() = error("Can't get properties of `NullVision`") + + override val descriptor: MetaDescriptor? = null +} + /** * Create a deep copy of given Vision without external connections. */ @@ -28,6 +50,22 @@ private fun Vision.deepCopy(manager: VisionManager): Vision { } +/** + * An event that contains changes made to a vision. + * + * @param vision a new value for vision content. If the Vision is to be removed should be [NullVision] + * @param properties updated properties + * @param children a map of children changed in ths [VisionChange]. + */ +@Serializable +@SerialName("change") +public data class VisionChange( + public val vision: Vision? = null, + public val properties: Meta? = null, + public val children: Map? = null, +) + + /** * An update for a [Vision] */ diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt index 3f86a2c0..6b85156a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt @@ -3,50 +3,23 @@ package space.kscience.visionforge import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name /** * An event propagated from client to a server */ @Serializable -public sealed interface VisionEvent +public sealed interface VisionEvent{ + public val targetName: Name +} /** * An event that consists of custom meta */ @Serializable @SerialName("meta") -public class VisionMetaEvent(public val targetName: Name, public val meta: Meta) : VisionEvent - - -/** - * A vision used only in change propagation and showing that the target should be removed - */ -@Serializable -@SerialName("null") -public object NullVision : Vision { - override var parent: Vision? - get() = null - set(_) { - error("Can't set parent for null vision") - } +public class VisionMetaEvent(override val targetName: Name, public val meta: Meta) : VisionEvent - override val properties: MutableVisionProperties get() = error("Can't get properties of `NullVision`") - - override val descriptor: MetaDescriptor? = null -} - - -/** - * @param vision a new value for vision content. If the Vision is to be removed should be [NullVision] - * @param properties updated properties - * @param children a map of children changed in ths [VisionChange]. - */ @Serializable @SerialName("change") -public data class VisionChange( - public val vision: Vision? = null, - public val properties: Meta? = null, - public val children: Map? = null, -) : VisionEvent \ No newline at end of file +public class VisionChangeEvent(override val targetName: Name, public val change: VisionChange) : VisionEvent \ No newline at end of file diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index 91e4f1bc..81493a6e 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -5,6 +5,9 @@ import kotlinx.browser.window import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex @@ -141,21 +144,19 @@ public class VisionClient : AbstractPlugin() { onopen = { feedbackJob = visionManager.context.launch { + eventCollector.filter { it.targetName == name }.onEach { + send(visionManager.jsonFormat.encodeToString(VisionEvent.serializer(), it)) + }.launchIn(this) + while (isActive) { delay(feedbackAggregationTime.milliseconds) val change = changeCollector[name] ?: continue if (!change.isEmpty()) { mutex.withLock { - send(change.toJsonString(visionManager)) + eventCollector.emit(VisionChangeEvent(name, change.deepCopy(visionManager))) change.reset() } } -// // take channel for given vision name -// eventCollector[name]?.let { channel -> -// for (e in channel) { -// send(visionManager.jsonFormat.encodeToString(VisionEvent.serializer(), e)) -// } -// } } } logger.info { "WebSocket feedback channel established for output '$name'" } diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 873a52c9..cf2f068d 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -75,8 +75,8 @@ public class VisionRoute( public fun Application.serveVisionData( configuration: VisionRoute, onEvent: suspend Vision.(VisionEvent) -> Unit = { event -> - if (event is VisionChange) { - update(event) + if (event is VisionChangeEvent) { + update(event.change) } }, resolveVision: (Name) -> Vision?, From 9c1246fb26d7fa052b95a05f8bfc81ec7a2e6d98 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 18 Oct 2023 21:48:50 +0300 Subject: [PATCH 099/112] Fix CME in solid children clearing. Add documentation. Splic client --- .../src/jsMain/kotlin/JsPlaygroundApp.kt | 4 +- demo/muon-monitor/build.gradle.kts | 1 + .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 6 +- .../kscience/visionforge/VisionClient.kt | 42 +++++++++ .../kscience/visionforge/VisionContainer.kt | 30 +----- .../space/kscience/visionforge/VisionEvent.kt | 17 +++- .../{VisionClient.kt => JsVisionClient.kt} | 51 ++++------ .../kscience/visionforge/inputRenderers.kt | 6 +- .../src/jsMain/kotlin/VFNotebookClient.kt | 4 +- .../visionforge/markup/MarkupPlugin.kt | 2 +- .../kscience/visionforge/plotly/plotlyJs.kt | 4 +- .../kscience/visionforge/solid/Composite.kt | 3 + .../kscience/visionforge/solid/Convex.kt | 3 + .../kscience/visionforge/solid/LightSource.kt | 2 +- .../kscience/visionforge/solid/MiscSolid.kt | 8 +- .../kscience/visionforge/solid/Shape2D.kt | 3 + .../space/kscience/visionforge/solid/Solid.kt | 34 ++++--- .../kscience/visionforge/solid/SolidBase.kt | 3 + .../visionforge/solid/SolidMaterial.kt | 3 + .../visionforge/solid/SolidReference.kt | 94 +------------------ .../visionforge/tables/TableVisionJsPlugin.kt | 4 +- .../visionforge/solid/three/ThreeCanvas.kt | 16 ++-- .../visionforge/solid/three/ThreePlugin.kt | 10 +- 23 files changed, 155 insertions(+), 195 deletions(-) create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt rename visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/{VisionClient.kt => JsVisionClient.kt} (88%) diff --git a/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt index 0bdee628..dd0d0b26 100644 --- a/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt @@ -8,7 +8,7 @@ import space.kscience.plotly.models.Trace import space.kscience.plotly.scatter import space.kscience.visionforge.Application import space.kscience.visionforge.Colors -import space.kscience.visionforge.VisionClient +import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.react.createRoot import space.kscience.visionforge.react.render @@ -34,7 +34,7 @@ private class JsPlaygroundApp : Application { val playgroundContext = Context { plugin(ThreeWithControlsPlugin) - plugin(VisionClient) + plugin(JsVisionClient) plugin(PlotlyPlugin) } diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index c8f26b2c..7023e1cc 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -13,6 +13,7 @@ kscience { useKtor() fullStack( "muon-monitor.js", + development = true, jvmConfig = { withJava() }, jsConfig = { useCommonJs() } ) { diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 2cc8e9a5..7f7958b9 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -3,6 +3,7 @@ package ru.mipt.npm.muon.monitor import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.LOWER_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.UPPER_LAYER_Z +import space.kscience.dataforge.names.asName import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionManager import space.kscience.visionforge.setAsRoot @@ -34,7 +35,7 @@ class Model(val manager: VisionManager) { } } - var tracks: SolidGroup + val tracks: SolidGroup = SolidGroup() val root: SolidGroup = SolidGroup().apply { setAsRoot(this@Model.manager) @@ -59,7 +60,8 @@ class Model(val manager: VisionManager) { detector(it) } } - tracks = solidGroup("tracks") + + setChild("tracks".asName(), tracks) } private fun highlight(pixel: String) { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt new file mode 100644 index 00000000..cc1c38b8 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -0,0 +1,42 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.launch +import space.kscience.dataforge.context.Plugin +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MetaRepr +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.parseAsName + +/** + * A feedback client that communicates with a server and provides ability to propagate events and changes back to the model + */ +public interface VisionClient: Plugin { + public val visionManager: VisionManager + + public suspend fun sendEvent(event: VisionEvent) + + public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) +} + + +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) +} + +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Number) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} + +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: String) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} + +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} + +public fun VisionClient.sendEvent(visionName: Name, event: MetaRepr): Unit { + context.launch { + sendEvent(VisionMetaEvent(visionName, event.toMeta())) + } +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index 77f989f4..c74f027d 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -187,30 +187,10 @@ internal abstract class VisionChildrenImpl( } override fun clear() { - items?.forEach { set(it.key, null) } -// if (!items.isNullOrEmpty()) { -// updateJobs.values.forEach { -// it.cancel() -// } -// updateJobs.clear() -// items?.clear() -// } + items?.clear() + updateJobs.values.forEach { it.cancel() } + updateJobs.clear() + onChange(Name.EMPTY) } } -// -//internal object VisionChildrenContainerSerializer : KSerializer { -// private val mapSerializer = serializer>() -// -// override val descriptor: SerialDescriptor = mapSerializer.descriptor -// -// override fun deserialize(decoder: Decoder): MutableVisionChildren { -// val map = decoder.decodeSerializableValue(mapSerializer) -// return VisionChildrenImpl(map) -// } -// -// override fun serialize(encoder: Encoder, value: MutableVisionChildren) { -// val map = value.keys.associateWith { value[it]!! } -// encoder.encodeSerializableValue(mapSerializer, map) -// } -// -//} + diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt index 6b85156a..f123cf46 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt @@ -3,6 +3,8 @@ package space.kscience.visionforge import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name /** @@ -11,6 +13,10 @@ import space.kscience.dataforge.names.Name @Serializable public sealed interface VisionEvent{ public val targetName: Name + + public companion object{ + public val CLICK_EVENT_KEY: Name get() = Name.of("events", "click", "payload") + } } /** @@ -22,4 +28,13 @@ public class VisionMetaEvent(override val targetName: Name, public val meta: Met @Serializable @SerialName("change") -public class VisionChangeEvent(override val targetName: Name, public val change: VisionChange) : VisionEvent \ No newline at end of file +public class VisionChangeEvent(override val targetName: Name, public val change: VisionChange) : VisionEvent + +public val Vision.Companion.CLICK_EVENT_KEY: Name get() = Name.of("events", "click", "payload") + +/** + * Set the payload to be sent to server on click + */ +public fun Vision.onClickPayload(payloadBuilder: MutableMeta.() -> Unit){ + properties[VisionEvent.CLICK_EVENT_KEY] = Meta(payloadBuilder) +} \ No newline at end of file diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt similarity index 88% rename from visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt rename to visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index 81493a6e..44d07309 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -15,7 +15,10 @@ import kotlinx.coroutines.sync.withLock import org.w3c.dom.* import org.w3c.dom.url.URL import space.kscience.dataforge.context.* -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MetaSerializer +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.parseAsName import space.kscience.visionforge.html.VisionTagConsumer @@ -29,9 +32,9 @@ import kotlin.time.Duration.Companion.milliseconds /** * A Kotlin-browser plugin that renders visions based on provided renderers and governs communication with the server. */ -public class VisionClient : AbstractPlugin() { +public class JsVisionClient : AbstractPlugin(), VisionClient { override val tag: PluginTag get() = Companion.tag - private val visionManager: VisionManager by require(VisionManager) + override val visionManager: VisionManager by require(VisionManager) /** * Up-going tree traversal in search for endpoint attribute. If element is null, return window URL @@ -69,7 +72,7 @@ public class VisionClient : AbstractPlugin() { /** * Communicate vision property changed from rendering engine to model */ - public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { + override fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { context.launch { mutex.withLock { changeCollector.propertyChanged(visionName, propertyName, item) @@ -85,7 +88,7 @@ public class VisionClient : AbstractPlugin() { /** * Send a custom feedback event */ - public suspend fun sendEvent(event: VisionEvent) { + override suspend fun sendEvent(event: VisionEvent) { eventCollector.emit(event) } @@ -252,37 +255,15 @@ public class VisionClient : AbstractPlugin() { textVisionRenderer(this), formVisionRenderer(this) ).associateByName() - } else super.content(target) + } else super.content(target) - public companion object : PluginFactory { - override fun build(context: Context, meta: Meta): VisionClient = VisionClient() + public companion object : PluginFactory { + override fun build(context: Context, meta: Meta): JsVisionClient = JsVisionClient() override val tag: PluginTag = PluginTag(name = "vision.client.js", group = PluginTag.DATAFORGE_GROUP) } } -public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { - notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) -} - -public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Number) { - notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -} - -public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: String) { - notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -} - -public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { - notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -} - -public fun VisionClient.sendEvent(visionName: Name, event: MetaRepr): Unit { - context.launch { - sendEvent(VisionMetaEvent(visionName, event.toMeta())) - } -} - private fun whenDocumentLoaded(block: Document.() -> Unit): Unit { if (document.body != null) { block(document) @@ -294,7 +275,7 @@ private fun whenDocumentLoaded(block: Document.() -> Unit): Unit { /** * Fetch and render visions for all elements with [VisionTagConsumer.OUTPUT_CLASS] class inside given [element]. */ -public fun VisionClient.renderAllVisionsIn(element: Element) { +public fun JsVisionClient.renderAllVisionsIn(element: Element) { val elements = element.getElementsByClassName(VisionTagConsumer.OUTPUT_CLASS) logger.info { "Finished search for outputs. Found ${elements.length} items" } elements.asList().forEach { child -> @@ -305,7 +286,7 @@ public fun VisionClient.renderAllVisionsIn(element: Element) { /** * Render all visions in an element with a given [id] */ -public fun VisionClient.renderAllVisionsById(document: Document, id: String): Unit { +public fun JsVisionClient.renderAllVisionsById(document: Document, id: String): Unit { val element = document.getElementById(id) if (element != null) { renderAllVisionsIn(element) @@ -318,13 +299,13 @@ public fun VisionClient.renderAllVisionsById(document: Document, id: String): Un /** * Fetch visions from the server for all elements with [VisionTagConsumer.OUTPUT_CLASS] class in the document body */ -public fun VisionClient.renderAllVisions(): Unit = whenDocumentLoaded { +public fun JsVisionClient.renderAllVisions(): Unit = whenDocumentLoaded { val element = body ?: error("Document does not have a body") renderAllVisionsIn(element) } public class VisionClientApplication(public val context: Context) : Application { - private val client = context.request(VisionClient) + private val client = context.request(JsVisionClient) override fun start(document: Document, state: Map) { context.logger.info { @@ -348,7 +329,7 @@ public fun runVisionClient(contextBuilder: ContextBuilder.() -> Unit) { Global.logger.info { "Starting VisionForge context" } val context = Context("VisionForge") { - plugin(VisionClient) + plugin(JsVisionClient) contextBuilder() } diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index faf82d13..ff84c403 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -20,7 +20,7 @@ import space.kscience.visionforge.html.VisionOfNumberField import space.kscience.visionforge.html.VisionOfTextField internal fun textVisionRenderer( - client: VisionClient, + client: JsVisionClient, ): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> val fieldName = vision.name ?: "input[${vision.hashCode().toUInt()}]" vision.label?.let { @@ -42,7 +42,7 @@ internal fun textVisionRenderer( } internal fun numberVisionRenderer( - client: VisionClient, + client: JsVisionClient, ): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> val fieldName = vision.name ?: "input[${vision.hashCode().toUInt()}]" vision.label?.let { @@ -87,7 +87,7 @@ internal fun FormData.toMeta(): Meta { } internal fun formVisionRenderer( - client: VisionClient, + client: JsVisionClient, ): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> val form = document.getElementById(vision.formId) as? HTMLFormElement diff --git a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt index 7f06c6ac..e095485c 100644 --- a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt +++ b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt @@ -8,14 +8,14 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta -import space.kscience.visionforge.VisionClient +import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.renderAllVisions import space.kscience.visionforge.renderAllVisionsById import space.kscience.visionforge.renderAllVisionsIn @JsExport public class VFNotebookClient : AbstractPlugin() { - private val client by require(VisionClient) + private val client by require(JsVisionClient) public fun renderAllVisionsIn(element: Element) { client.renderAllVisionsIn(element) diff --git a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index aad66f3f..ef700466 100644 --- a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -18,7 +18,7 @@ import space.kscience.visionforge.markup.VisionOfMarkup.Companion.COMMONMARK_FOR import space.kscience.visionforge.markup.VisionOfMarkup.Companion.GFM_FORMAT public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { - public val visionClient: VisionClient by require(VisionClient) + public val visionClient: JsVisionClient by require(JsVisionClient) override val tag: PluginTag get() = Companion.tag override val visionSerializersModule: SerializersModule get() = markupSerializersModule diff --git a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt index 91518f34..074be6dc 100644 --- a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt +++ b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt @@ -11,12 +11,12 @@ import space.kscience.dataforge.names.asName import space.kscience.plotly.PlotlyConfig import space.kscience.plotly.plot import space.kscience.visionforge.ElementVisionRenderer +import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionClient import space.kscience.visionforge.VisionPlugin public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { - public val visionClient: VisionClient by require(VisionClient) + public val visionClient: JsVisionClient by require(JsVisionClient) override val tag: PluginTag get() = Companion.tag diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index 65a1bcd5..3cc6ff61 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -15,6 +15,9 @@ public enum class CompositeType { SUBTRACT } +/** + * A CSG-based composite solid + */ @Serializable @SerialName("solid.composite") public class Composite( diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt index 4fa174ac..bd449ce8 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt @@ -5,6 +5,9 @@ import kotlinx.serialization.Serializable import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.setChild +/** + * A convex hull shape + */ @Serializable @SerialName("solid.convex") public class Convex(public val points: List) : SolidBase() diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt index 6064e6ed..9f970bf0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -12,7 +12,7 @@ import space.kscience.dataforge.names.asName import space.kscience.visionforge.* @Serializable -public abstract class LightSource : SolidBase() { +public abstract class LightSource : MiscSolid() { override val descriptor: MetaDescriptor get() = LightSource.descriptor public val color: ColorAccessor by colorProperty(SolidMaterial.COLOR_KEY) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt index f83f6cb9..99462802 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt @@ -6,13 +6,19 @@ import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder import space.kscience.visionforge.setChild +/** + * Utility solids + */ public abstract class MiscSolid: SolidBase() +/** + * X-Y-Z axes + */ @Serializable @SerialName("solid.axes") public class AxesSolid(public val size: Double): MiscSolid(){ public companion object{ - public const val AXES_NAME: String = "@xes" + public const val AXES_NAME: String = "@axes" } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt index 4f5d48a4..a73b97e0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt @@ -7,6 +7,9 @@ import kotlin.math.sin public typealias Shape2D = List +/** + * A builder for 2D shapes + */ @Serializable public class Shape2DBuilder(private val points: ArrayList = ArrayList()) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 3972de83..a42427da 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -152,7 +152,10 @@ public var Vision.ignore: Boolean? // get() = getProperty(SELECTED_KEY).boolean // set(value) = setProperty(SELECTED_KEY, value) -internal fun float(name: Name, default: Number): ReadWriteProperty = +/** + *A [Float] solid property delegate + */ +internal fun float32(name: Name, default: Number): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Number { return thisRef.properties.getValue(name)?.number ?: default @@ -163,7 +166,10 @@ internal fun float(name: Name, default: Number): ReadWriteProperty : AbstractVision(), Solid { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index 14784065..40857b14 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -12,6 +12,9 @@ import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_K import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY +/** + * A scheme for vision material + */ @VisionBuilder public class SolidMaterial : Scheme() { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index a6aabe67..32e69520 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -21,6 +21,7 @@ import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD * Get a vision prototype if it is a [SolidReference] or vision itself if it is not. * Unref is recursive, so it always returns a non-reference. */ +@Suppress("RecursivePropertyAccessor") public val Vision.prototype: Solid get() = when (this) { is SolidReference -> prototype.prototype @@ -239,95 +240,4 @@ public fun SolidGroup.newRef( error("Can't add different prototype on top of existing one") } return children.ref(prototypeName, name?.parseAsName()) -} - - -// -// -///** -// * A reference [Solid] to reuse a template object -// */ -//@Serializable -//@SerialName("solid.ref") -//public class SolidReferenceGroup( -// public val refName: Name, -//) : VisionGroup(), SolidReference, VisionGroup, Solid { -// -// /** -// * Recursively search for defined template in the parent -// */ -// override val prototype: Solid by lazy { -// if (parent == null) error("No parent is present for SolidReferenceGroup") -// if (parent !is PrototypeHolder) error("Parent does not hold prototypes") -// (parent as? PrototypeHolder)?.getPrototype(refName) ?: error("Prototype with name $refName not found") -// } -// -// override val items: Map> -// get() = (prototype as? VisionGroup<*>)?.items -// ?.filter { it.key != SolidGroup.PROTOTYPES_TOKEN } -// ?.mapValues { -// VisionGroupItem.Node(ReferenceChild(this, it.key.asName())) -// } ?: emptyMap() -// -// override val descriptor: MetaDescriptor get() = prototype.descriptor -// -// -// /** -// * A ProxyChild is created temporarily only to interact with properties, it does not store any values -// * (properties are stored in external cache) and created and destroyed on-demand). -// */ -// private class ReferenceChild( -// val owner: SolidReferenceGroup, -// private val refName: Name, -// ) : SolidReference, VisionGroup, Solid { -// -// override val prototype: Solid by lazy { -// if (refName.isEmpty()) { -// owner.prototype -// } else { -// val proto = (owner.prototype).children.get(refName) -// ?: error("Prototype with name $refName not found in SolidReferenceGroup ${owner.refName}") -// proto as? Solid ?: error("Prototype with name $refName is ${proto::class} but expected Solid") -//// proto.unref as? Solid -//// ?: error("Prototype with name $refName is ${proto::class} but expected Solid") -// } -// } -// -// override val meta: ObservableMutableMeta by lazy { -// owner.meta.getOrCreate(childToken(refName).asName()) -// } -// -// override val items: Map> -// get() = (prototype as? VisionGroup<*>)?.items -// ?.filter { it.key != SolidGroup.PROTOTYPES_TOKEN } -// ?.mapValues { (key, _) -> -// VisionGroupItem.Node(ReferenceChild(owner, refName + key.asName())) -// } ?: emptyMap() -// -// override var parent: VisionGroup<*>? -// get() { -// val parentName = refName.cutLast() -// return if (parentName.isEmpty()) owner else ReferenceChild(owner, parentName) -// } -// set(_) { -// error("Setting a parent for a reference child is not possible") -// } -// -// override fun invalidateProperty(propertyName: Name) { -// owner.invalidateProperty(childPropertyName(refName, propertyName)) -// } -// -// override fun update(change: VisionChange) { -// change.properties?.let { -// updateProperties(it, Name.EMPTY) -// } -// } -// -// override val descriptor: MetaDescriptor get() = prototype.descriptor -// -// } -// -// public companion object { -// public const val REFERENCE_CHILD_PROPERTY_PREFIX: String = "@child" -// } -//} +} \ No newline at end of file diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index 469d4af8..75977d79 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -12,13 +12,13 @@ import space.kscience.dataforge.meta.toDynamic import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.visionforge.ElementVisionRenderer +import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionClient import tabulator.Tabulator import tabulator.TabulatorFull public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { - public val visionClient: VisionClient by require(VisionClient) + public val visionClient: JsVisionClient by require(JsVisionClient) public val tablesBase: TableVisionPlugin by require(TableVisionPlugin) override val tag: PluginTag get() = Companion.tag diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index c692b88d..b65d1fce 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -123,8 +123,8 @@ public class ThreeCanvas( element.appendChild(canvas) updateSize() canvas.addEventListener("pointerdown", { - val picked = pick() - options.onSelect?.invoke(picked?.fullName()) + val newPicked = pick() + options.onSelect?.invoke(newPicked?.fullName()) }, false) //Attach listener to track mouse changes @@ -143,12 +143,12 @@ public class ThreeCanvas( addControls(canvas, options.controls) renderer.setAnimationLoop { - val picked = pick() + val newPicked = pick() - if (picked != null && this.picked != picked) { - this.picked?.toggleHighlight(false, HIGHLIGHT_NAME, HIGHLIGHT_MATERIAL) - picked.toggleHighlight(true, HIGHLIGHT_NAME, HIGHLIGHT_MATERIAL) - this.picked = picked + if (newPicked != null && picked !== newPicked) { + picked?.toggleHighlight(false, HIGHLIGHT_NAME, HIGHLIGHT_MATERIAL) + newPicked.toggleHighlight(true, HIGHLIGHT_NAME, HIGHLIGHT_MATERIAL) + picked = newPicked } renderer.render(scene, camera) @@ -326,7 +326,7 @@ public class ThreeCanvas( public val HIGHLIGHT_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply { color.set(Colors.blue) - thickness = 2f + thickness = 1f cached = true } // diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index c1c2cf4d..7051f887 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -7,12 +7,10 @@ import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.* -import space.kscience.visionforge.ElementVisionRenderer -import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionChildren +import space.kscience.visionforge.* import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.visible +import space.kscience.visionforge.solid.three.set import three.core.Object3D import kotlin.collections.set import kotlin.reflect.KClass @@ -23,6 +21,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public val solids: Solids by require(Solids) + public val client: VisionClient? get() = context.plugins.get() + private val objectFactories = HashMap, ThreeFactory<*>>() private val compositeFactory = ThreeCompositeFactory(this) @@ -90,6 +90,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { val child = vision.children.getChild(childName) + logger.debug { "Changing vision $childName to $child" } + //removing old object findChild(childName)?.let { oldChild -> oldChild.parent?.remove(oldChild) From 64c447a37b9b63dd83ba2e6a8c3efcf246d96120 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 25 Oct 2023 18:49:36 +0300 Subject: [PATCH 100/112] Version updates and bugfixes --- build.gradle.kts | 2 +- demo/muon-monitor/build.gradle.kts | 2 ++ gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../kotlin/space/kscience/visionforge/solid/MiscSolid.kt | 1 + 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 56dda332..4e97dbe6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-13" + version = "0.3.0-dev-14" } subprojects { diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index 7023e1cc..e453492b 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -47,6 +47,8 @@ application { mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt") } +//TODO ??? +tasks.getByName("jsBrowserProductionWebpack").dependsOn("jsDevelopmentExecutableCompileSync") //distributions { // main { diff --git a/gradle.properties b/gradle.properties index 900cd1b7..c8070279 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ org.gradle.jvmargs=-Xmx4G org.jetbrains.compose.experimental.jscanvas.enabled=true -toolsVersion=0.15.0-kotlin-1.9.20-RC +toolsVersion=0.15.0-kotlin-1.9.20-RC2 #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index db9a6b82..e411586a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt index 99462802..6a2fdb08 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt @@ -9,6 +9,7 @@ import space.kscience.visionforge.setChild /** * Utility solids */ +@Serializable public abstract class MiscSolid: SolidBase() /** From 399be206be9e2c455db4895aacc770efd0ff7a86 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 13 Nov 2023 21:45:37 +0300 Subject: [PATCH 101/112] Non-nullable accessor for colors --- CHANGELOG.md | 2 +- build.gradle.kts | 2 +- demo/muon-monitor/build.gradle.kts | 4 - gradle.properties | 2 +- ui/compose/build.gradle.kts | 41 ++++++ .../visionforge/compose/MetaViewer.kt | 130 ++++++++++++++++++ .../visionforge/compose/TreeStyles.kt | 71 ++++++++++ .../kscience/visionforge/compose/layouts.kt | 41 ++++++ .../visionforge/solid/ColorAccessor.kt | 22 +-- .../visionforge/solid/SolidPropertyTest.kt | 2 +- .../visionforge/solid/SolidReferenceTest.kt | 2 +- visionforge-tables/build.gradle.kts | 6 +- 12 files changed, 302 insertions(+), 23 deletions(-) create mode 100644 ui/compose/build.gradle.kts create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 87fe2343..bf2c3478 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - Custom client-side events and thier processing in VisionServer ### Changed -- Color accessor property is now `colorProperty`. Color uses `invoke` instead of `set` +- Color accessor property is now `colorProperty`. Color uses non-nullable `invoke` instead of `set`. - API update for server and pages - Edges moved to solids module for easier construction - Visions **must** be rooted in order to subscribe to updates. diff --git a/build.gradle.kts b/build.gradle.kts index 4e97dbe6..9f982d94 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-14" + version = "0.3.0-dev-15" } subprojects { diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index e453492b..d01b9dc9 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -13,7 +13,6 @@ kscience { useKtor() fullStack( "muon-monitor.js", - development = true, jvmConfig = { withJava() }, jsConfig = { useCommonJs() } ) { @@ -47,9 +46,6 @@ application { mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt") } -//TODO ??? -tasks.getByName("jsBrowserProductionWebpack").dependsOn("jsDevelopmentExecutableCompileSync") - //distributions { // main { // contents { diff --git a/gradle.properties b/gradle.properties index c8070279..9413b93e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ org.gradle.jvmargs=-Xmx4G org.jetbrains.compose.experimental.jscanvas.enabled=true -toolsVersion=0.15.0-kotlin-1.9.20-RC2 +toolsVersion=0.15.0-kotlin-1.9.20 #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true diff --git a/ui/compose/build.gradle.kts b/ui/compose/build.gradle.kts new file mode 100644 index 00000000..a2f2c4a7 --- /dev/null +++ b/ui/compose/build.gradle.kts @@ -0,0 +1,41 @@ + +plugins { + id("space.kscience.gradle.mpp") + id("org.jetbrains.compose") version "1.5.10" +// id("com.android.library") +} + +kscience{ + jvm() + js() +// wasm() +} + +kotlin { +// android() + sourceSets { + val commonMain by getting { + dependencies { + + } + } + + val jvmMain by getting { + dependencies { + api(compose.runtime) + api(compose.foundation) + api(compose.material) + api(compose.preview) + } + } + + val jsMain by getting{ + dependencies { + api(compose.html.core) + api("app.softwork:bootstrap-compose:0.1.15") + api("app.softwork:bootstrap-compose-icons:0.1.15") + api(projects.visionforge.visionforgeThreejs) + } + } + } +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt new file mode 100644 index 00000000..93cbddfc --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt @@ -0,0 +1,130 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import kotlinx.html.js.onClickFunction +import org.jetbrains.compose.web.css.AlignItems +import org.jetbrains.compose.web.css.alignItems +import org.jetbrains.compose.web.dom.Span +import org.w3c.dom.events.Event +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.isLeaf +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.lastOrNull +import space.kscience.dataforge.names.plus + + +private val MetaViewerItem: FC = fc("MetaViewerItem") { props -> + metaViewerItem(props) +} + +@Composable +private fun MetaViewerItem(root: Meta, name: Name, rootDescriptor: MetaDescriptor? = null) { + var expanded: Boolean by remember { mutableStateOf(true) } + val item: Meta? = root[name] + val descriptorItem: MetaDescriptor? = rootDescriptor?.get(name) + val actualValue = item?.value ?: descriptorItem?.defaultValue + val actualMeta = item ?: descriptorItem?.defaultNode + + val token = name.lastOrNull()?.toString() ?: props.rootName ?: "" + + val expanderClick: (Event) -> Unit = { + expanded = !expanded + } + + FlexRow(attrs = { + classes("metaItem") + style { + alignItems(AlignItems.Center) + } + }) { + if (actualMeta?.isLeaf == false) { + Span(attrs = { + + }) + styledSpan { + css { + +TreeStyles.treeCaret + if (expanded) { + +TreeStyles.treeCaredDown + } + } + attrs { + onClickFunction = expanderClick + } + } + } + + styledSpan { + css { + +TreeStyles.treeLabel + if (item == null) { + +TreeStyles.treeLabelInactive + } + } + +token + } + styledDiv { + a { + +actualValue.toString() + } + } + } + if (expanded) { + flexColumn { + css { + +TreeStyles.tree + } + val keys = buildSet { + descriptorItem?.children?.keys?.forEach { + add(NameToken(it)) + } + actualMeta!!.items.keys.let { addAll(it) } + } + + keys.filter { !it.body.startsWith("@") }.forEach { token -> + styledDiv { + css { + +TreeStyles.treeItem + } + child(MetaViewerItem) { + attrs { + this.key = props.name.toString() + this.root = props.root + this.name = props.name + token + this.descriptor = props.descriptor + } + } + //configEditor(props.root, props.name + token, props.descriptor, props.default) + } + } + } + } + + +} + +@JsExport +public val MetaViewer: FC = fc("MetaViewer") { props -> + child(MetaViewerItem) { + attrs { + this.key = "" + this.root = props.root + this.name = Name.EMPTY + this.descriptor = props.descriptor + } + } +} + +public fun RBuilder.metaViewer(meta: Meta, descriptor: MetaDescriptor? = null, key: Any? = null) { + child(MetaViewer) { + attrs { + this.key = key?.toString() ?: "" + this.root = meta + this.descriptor = descriptor + } + } +} diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt new file mode 100644 index 00000000..29074464 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt @@ -0,0 +1,71 @@ +package space.kscience.visionforge.compose + +import kotlinx.css.* +import org.jetbrains.compose.web.css.* + +public object TreeStyles : StyleSheet() { + /** + * Remove default bullets + */ + public val tree: String by style { + paddingLeft(5.px) + marginLeft(0.px) + listStyleType("none") + } + + /** + * Style the caret/arrow + */ + public val treeCaret by style { + cursor("pointer") + userSelect = UserSelect.none + /* Create the caret/arrow with a unicode, and style it */ + before { + content = "\u25B6".quoted + color(Color.black) + display(DisplayStyle.InlineBlock) + marginRight(6.px) + } + } + + /** + * Rotate the caret/arrow icon when clicked on (using JavaScript) + */ + public val treeCaredDown by style { + before { + content = "\u25B6".quoted + color(Color.black) + display(DisplayStyle.InlineBlock) + marginRight(6.px) + transform { rotate(90.deg) } + } + } + + public val treeItem: String by style { + alignItems(AlignItems.Center) + paddingLeft(10.px) + border { + left{ + width(1.px) + color(Color.lightgray) + style = LineStyle.Dashed + } + } + } + + public val treeLabel by style { + border(style = LineStyle.None) + padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) + textAlign("left") + flex(1) + } + + public val treeLabelInactive: RuleSet by css { + color = Color.lightGray + } + + public val treeLabelSelected: RuleSet by css { + backgroundColor = Color.lightBlue + } + +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt new file mode 100644 index 00000000..882f1f1c --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt @@ -0,0 +1,41 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.css.DisplayStyle +import org.jetbrains.compose.web.css.FlexDirection +import org.jetbrains.compose.web.css.display +import org.jetbrains.compose.web.css.flexDirection +import org.jetbrains.compose.web.dom.AttrBuilderContext +import org.jetbrains.compose.web.dom.Div +import org.jetbrains.compose.web.dom.ElementScope +import org.w3c.dom.HTMLDivElement + +@Composable +public fun FlexColumn( + attrs: AttrBuilderContext? = null, + content: @Composable ElementScope.() -> Unit, +): Unit = Div( + attrs = { + style { + display(DisplayStyle.Flex) + flexDirection(FlexDirection.Column) + } + attrs?.invoke(this) + }, + content +) + +@Composable +public fun FlexRow( + attrs: AttrBuilderContext? = null, + content: @Composable ElementScope.() -> Unit, +): Unit = Div( + attrs = { + style { + display(DisplayStyle.Flex) + flexDirection(FlexDirection.Row) + } + attrs?.invoke(this) + }, + content +) \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index 60789027..14a22797 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -34,33 +34,33 @@ public fun Vision.colorProperty( ColorAccessor(properties.root(true), propertyName ?: property.name.asName()) } -public var ColorAccessor?.string: String? - get() = this?.value?.let { if (it == Null) null else it.string } +public var ColorAccessor.string: String? + get() = value?.let { if (it == Null) null else it.string } set(value) { - this?.value = value?.asValue() + this.value = value?.asValue() } /** * Set [webcolor](https://en.wikipedia.org/wiki/Web_colors) as string */ -public operator fun ColorAccessor?.invoke(webColor: String) { - this?.value = webColor.asValue() +public operator fun ColorAccessor.invoke(webColor: String) { + value = webColor.asValue() } /** * Set color as RGB integer */ -public operator fun ColorAccessor?.invoke(rgb: Int) { - this?.value = Colors.rgbToString(rgb).asValue() +public operator fun ColorAccessor.invoke(rgb: Int) { + value = Colors.rgbToString(rgb).asValue() } /** * Set color as RGB */ -public operator fun ColorAccessor?.invoke(r: UByte, g: UByte, b: UByte) { - this?.value = Colors.rgbToString(r, g, b).asValue() +public operator fun ColorAccessor.invoke(r: UByte, g: UByte, b: UByte) { + value = Colors.rgbToString(r, g, b).asValue() } -public fun ColorAccessor?.clear() { - this?.value = null +public fun ColorAccessor.clear() { + value = null } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index e4b0619d..4991c12d 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -94,7 +94,7 @@ class SolidPropertyTest { } } } - assertEquals("#555555", box?.color.string) + assertEquals("#555555", box?.color?.string) } @Test diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt index d8d971bb..512f3807 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt @@ -31,7 +31,7 @@ class SolidReferenceTest { fun testReferenceSerialization(){ val serialized = Solids.jsonForSolids.encodeToJsonElement(groupWithReference) val deserialized = Solids.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized) - assertEquals(groupWithReference.items["test"]?.color.string, deserialized.items["test"]?.color.string) + assertEquals(groupWithReference.items["test"]?.color?.string, deserialized.items["test"]?.color?.string) assertEquals("blue", (deserialized.children.getChild("test") as Solid).color.string) } } \ No newline at end of file diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index cf813e6e..33988cf0 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -val tablesVersion = "0.2.0-dev-4" +val tablesVersion = "0.2.1" kscience { jvm() @@ -22,8 +22,8 @@ kscience { api("space.kscience:tables-kt:${tablesVersion}") } dependencies(jsMain) { - implementation(npm("tabulator-tables", "5.4.4")) - implementation(npm("@types/tabulator-tables", "5.4.8")) + implementation(npm("tabulator-tables", "5.5.2")) + implementation(npm("@types/tabulator-tables", "5.5.3")) } useSerialization() } From 1ea5ef86e66abb12198847288f9c689e61ace89c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 15 Nov 2023 10:26:37 +0300 Subject: [PATCH 102/112] Add direct event processing to Vision --- build.gradle.kts | 2 +- settings.gradle.kts | 2 +- .../space/kscience/visionforge/Vision.kt | 17 +++++++++++++- .../space/kscience/visionforge/VisionEvent.kt | 19 +++++++++++----- .../space/kscience/visionforge/VisionGroup.kt | 22 ++++++++++++------- .../kscience/visionforge/JsVisionClient.kt | 15 ++++++++----- .../visionforge/server/VisionServer.kt | 20 +++++++++-------- .../visionforge/solid/VisionUpdateTest.kt | 2 +- 8 files changed, 67 insertions(+), 32 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9f982d94..2da86b96 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-15" + version = "0.3.0-dev-16" } subprojects { diff --git a/settings.gradle.kts b/settings.gradle.kts index 31119a06..8611d0aa 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -45,7 +45,7 @@ include( ":ui:ring", // ":ui:material", ":ui:bootstrap", -// ":ui:compose", + ":ui:compose", ":visionforge-core", ":visionforge-solid", // ":visionforge-fx", diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 31ff307e..8cfe7a27 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -11,6 +11,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.isEmpty import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.TYPE @@ -36,7 +37,7 @@ public interface Vision : Described { /** * Update this vision using a dif represented by [VisionChange]. */ - public fun update(change: VisionChange) { + public fun receiveChange(change: VisionChange) { if (change.children?.isNotEmpty() == true) { error("Vision is not a group") } @@ -45,6 +46,20 @@ public interface Vision : Described { } } + /** + * Receive and process a generic [VisionEvent]. + */ + public fun receiveEvent(event: VisionEvent) { + if(event.targetName.isEmpty()) { + when (event) { + is VisionChangeEvent -> receiveChange(event.change) + else -> TODO() + } + } else { + error("Vision is not a group and can't process an event with non-empty target") + } + } + override val descriptor: MetaDescriptor? public companion object { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt index f123cf46..f1d8d3ed 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt @@ -11,10 +11,15 @@ import space.kscience.dataforge.names.Name * An event propagated from client to a server */ @Serializable -public sealed interface VisionEvent{ +public sealed interface VisionEvent { public val targetName: Name - public companion object{ + /** + * Create a copy of this event with the same type and content, but different [targetName] + */ + public fun changeTarget(newTarget: Name): VisionEvent + + public companion object { public val CLICK_EVENT_KEY: Name get() = Name.of("events", "click", "payload") } } @@ -24,17 +29,21 @@ public sealed interface VisionEvent{ */ @Serializable @SerialName("meta") -public class VisionMetaEvent(override val targetName: Name, public val meta: Meta) : VisionEvent +public data class VisionMetaEvent(override val targetName: Name, public val meta: Meta) : VisionEvent { + override fun changeTarget(newTarget: Name): VisionMetaEvent = VisionMetaEvent(newTarget, meta) +} @Serializable @SerialName("change") -public class VisionChangeEvent(override val targetName: Name, public val change: VisionChange) : VisionEvent +public data class VisionChangeEvent(override val targetName: Name, public val change: VisionChange) : VisionEvent { + override fun changeTarget(newTarget: Name): VisionChangeEvent = VisionChangeEvent(newTarget, change) +} public val Vision.Companion.CLICK_EVENT_KEY: Name get() = Name.of("events", "click", "payload") /** * Set the payload to be sent to server on click */ -public fun Vision.onClickPayload(payloadBuilder: MutableMeta.() -> Unit){ +public fun Vision.onClickPayload(payloadBuilder: MutableMeta.() -> Unit) { properties[VisionEvent.CLICK_EVENT_KEY] = Meta(payloadBuilder) } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index fd8aaa16..ca3d6338 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -6,10 +6,7 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.ValueType import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.NameToken -import space.kscience.dataforge.names.parseAsName -import space.kscience.dataforge.names.plus +import space.kscience.dataforge.names.* import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.STYLE_KEY @@ -17,18 +14,27 @@ import space.kscience.visionforge.Vision.Companion.STYLE_KEY public interface VisionGroup : Vision { public val children: VisionChildren - override fun update(change: VisionChange) { + override fun receiveChange(change: VisionChange) { change.children?.forEach { (name, change) -> if (change.vision != null || change.vision == NullVision) { error("VisionGroup is read-only") } else { - children.getChild(name)?.update(change) + children.getChild(name)?.receiveChange(change) } } change.properties?.let { updateProperties(it, Name.EMPTY) } } + + override fun receiveEvent(event: VisionEvent) { + if (event.targetName.isEmpty()) { + super.receiveEvent(event) + } else { + val target = children[event.targetName] ?: error("Child vision with name ${event.targetName} not found") + target.receiveEvent(event.changeTarget(Name.EMPTY)) + } + } } public interface MutableVisionGroup : VisionGroup { @@ -37,12 +43,12 @@ public interface MutableVisionGroup : VisionGroup { public fun createGroup(): MutableVisionGroup - override fun update(change: VisionChange) { + override fun receiveChange(change: VisionChange) { change.children?.forEach { (name, change) -> when { change.vision == NullVision -> children.setChild(name, null) change.vision != null -> children.setChild(name, change.vision) - else -> children.getChild(name)?.update(change) + else -> children.getChild(name)?.receiveChange(change) } } change.properties?.let { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index 44d07309..3042be5a 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -20,6 +20,7 @@ import space.kscience.dataforge.meta.MetaSerializer import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.parseAsName import space.kscience.visionforge.html.VisionTagConsumer import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_CONNECT_ATTRIBUTE @@ -120,19 +121,21 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { onmessage = { messageEvent -> val stringData: String? = messageEvent.data as? String if (stringData != null) { - val change: VisionChange = visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(), + val event: VisionEvent = visionManager.jsonFormat.decodeFromString( + VisionEvent.serializer(), stringData ) // If change contains root vision replacement, do it - change.vision?.let { vision -> - renderVision(element, name, vision, outputMeta) + if(event is VisionChangeEvent && event.targetName.isEmpty()) { + event.change.vision?.let { vision -> + renderVision(element, name, vision, outputMeta) + } } - logger.debug { "Got update $change for output with name $name" } + logger.debug { "Got $event for output with name $name" } if (vision == null) error("Can't update vision because it is not loaded.") - vision.update(change) + vision.receiveEvent(event) } else { logger.error { "WebSocket message data is not a string" } } diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index cf2f068d..1831d641 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -14,6 +14,7 @@ import io.ktor.server.util.* import io.ktor.server.websocket.* import io.ktor.util.pipeline.* import io.ktor.websocket.* +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -71,14 +72,11 @@ public class VisionRoute( /** * Serve visions in a given [route] without providing a page template. * [visions] could be changed during the service. + * + * @return a [Flow] of backward events, including vision change events */ public fun Application.serveVisionData( configuration: VisionRoute, - onEvent: suspend Vision.(VisionEvent) -> Unit = { event -> - if (event is VisionChangeEvent) { - update(event.change) - } - }, resolveVision: (Name) -> Vision?, ) { require(WebSockets) @@ -102,16 +100,18 @@ public fun Application.serveVisionData( val event = configuration.visionManager.jsonFormat.decodeFromString( VisionEvent.serializer(), data ) - vision.onEvent(event) + + vision.receiveEvent(event) } } try { withContext(configuration.context.coroutineContext) { vision.flowChanges(configuration.updateInterval.milliseconds).onEach { update -> + val event = VisionChangeEvent(Name.EMPTY, update) val json = configuration.visionManager.jsonFormat.encodeToString( - VisionChange.serializer(), - update + VisionEvent.serializer(), + event ) application.log.debug("Sending update for $name: \n$json") outgoing.send(Frame.Text(json)) @@ -147,6 +147,8 @@ public fun Application.serveVisionData( /** * Serve a page, potentially containing any number of visions at a given [route] with given [header]. + * + * @return a [Flow] containing backward propagated events, including vision change events */ public fun Application.visionPage( route: String, @@ -154,7 +156,7 @@ public fun Application.visionPage( headers: Collection, connector: EngineConnectorConfig? = null, visionFragment: HtmlVisionFragment, -) { +){ require(WebSockets) val collector: MutableMap = mutableMapOf() diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 0e495aaa..898fae11 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -28,7 +28,7 @@ internal class VisionUpdateTest { propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) } - targetVision.update(dif) + targetVision.receiveChange(dif) assertTrue { targetVision.children.getChild("top") is SolidGroup } assertEquals("red", (targetVision.children.getChild("origin") as Solid).color.string) // Should work assertEquals( From c7d4bdfa5f989c320412bca67ab90e8be2b0e17c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 15 Nov 2023 10:42:56 +0300 Subject: [PATCH 103/112] Add direct event processing to Vision --- settings.gradle.kts | 2 +- .../space/kscience/visionforge/Vision.kt | 11 +++-------- .../space/kscience/visionforge/VisionChange.kt | 3 +-- .../space/kscience/visionforge/VisionClient.kt | 6 +++--- .../space/kscience/visionforge/VisionEvent.kt | 16 +--------------- .../space/kscience/visionforge/VisionGroup.kt | 14 ++++---------- .../kscience/visionforge/JsVisionClient.kt | 18 ++++++++---------- .../visionforge/server/VisionServer.kt | 3 +-- 8 files changed, 22 insertions(+), 51 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 8611d0aa..31119a06 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -45,7 +45,7 @@ include( ":ui:ring", // ":ui:material", ":ui:bootstrap", - ":ui:compose", +// ":ui:compose", ":visionforge-core", ":visionforge-solid", // ":visionforge-fx", diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 8cfe7a27..06cd6d8f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -11,7 +11,6 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.isEmpty import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.TYPE @@ -50,13 +49,9 @@ public interface Vision : Described { * Receive and process a generic [VisionEvent]. */ public fun receiveEvent(event: VisionEvent) { - if(event.targetName.isEmpty()) { - when (event) { - is VisionChangeEvent -> receiveChange(event.change) - else -> TODO() - } - } else { - error("Vision is not a group and can't process an event with non-empty target") + when (event) { + is VisionChange -> receiveChange(event) + else -> TODO() } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 9915c035..87bff794 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -63,8 +63,7 @@ public data class VisionChange( public val vision: Vision? = null, public val properties: Meta? = null, public val children: Map? = null, -) - +) : VisionEvent /** * An update for a [Vision] diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt index cc1c38b8..76d8aa80 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -13,7 +13,7 @@ import space.kscience.dataforge.names.parseAsName public interface VisionClient: Plugin { public val visionManager: VisionManager - public suspend fun sendEvent(event: VisionEvent) + public suspend fun sendEvent(targetName: Name, event: VisionEvent) public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) } @@ -35,8 +35,8 @@ public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: St notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) } -public fun VisionClient.sendEvent(visionName: Name, event: MetaRepr): Unit { +public fun VisionClient.sendEvent(targetName: Name, payload: MetaRepr): Unit { context.launch { - sendEvent(VisionMetaEvent(visionName, event.toMeta())) + sendEvent(targetName, VisionMetaEvent(payload.toMeta())) } } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt index f1d8d3ed..84d36217 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt @@ -12,13 +12,6 @@ import space.kscience.dataforge.names.Name */ @Serializable public sealed interface VisionEvent { - public val targetName: Name - - /** - * Create a copy of this event with the same type and content, but different [targetName] - */ - public fun changeTarget(newTarget: Name): VisionEvent - public companion object { public val CLICK_EVENT_KEY: Name get() = Name.of("events", "click", "payload") } @@ -29,15 +22,8 @@ public sealed interface VisionEvent { */ @Serializable @SerialName("meta") -public data class VisionMetaEvent(override val targetName: Name, public val meta: Meta) : VisionEvent { - override fun changeTarget(newTarget: Name): VisionMetaEvent = VisionMetaEvent(newTarget, meta) -} +public class VisionMetaEvent(public val meta: Meta) : VisionEvent -@Serializable -@SerialName("change") -public data class VisionChangeEvent(override val targetName: Name, public val change: VisionChange) : VisionEvent { - override fun changeTarget(newTarget: Name): VisionChangeEvent = VisionChangeEvent(newTarget, change) -} public val Vision.Companion.CLICK_EVENT_KEY: Name get() = Name.of("events", "click", "payload") diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index ca3d6338..1edfa40a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -6,7 +6,10 @@ import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.ValueType import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value -import space.kscience.dataforge.names.* +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.parseAsName +import space.kscience.dataforge.names.plus import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.STYLE_KEY @@ -26,15 +29,6 @@ public interface VisionGroup : Vision { updateProperties(it, Name.EMPTY) } } - - override fun receiveEvent(event: VisionEvent) { - if (event.targetName.isEmpty()) { - super.receiveEvent(event) - } else { - val target = children[event.targetName] ?: error("Child vision with name ${event.targetName} not found") - target.receiveEvent(event.changeTarget(Name.EMPTY)) - } - } } public interface MutableVisionGroup : VisionGroup { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index 3042be5a..b9e0ef93 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -20,7 +20,6 @@ import space.kscience.dataforge.meta.MetaSerializer import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.parseAsName import space.kscience.visionforge.html.VisionTagConsumer import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_CONNECT_ATTRIBUTE @@ -82,15 +81,14 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { } private val eventCollector by lazy { - MutableSharedFlow(meta["feedback.eventCache"].int ?: 100) + MutableSharedFlow>(meta["feedback.eventCache"].int ?: 100) } - /** * Send a custom feedback event */ - override suspend fun sendEvent(event: VisionEvent) { - eventCollector.emit(event) + override suspend fun sendEvent(targetName: Name, event: VisionEvent) { + eventCollector.emit(targetName to event) } private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) { @@ -127,8 +125,8 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { ) // If change contains root vision replacement, do it - if(event is VisionChangeEvent && event.targetName.isEmpty()) { - event.change.vision?.let { vision -> + if(event is VisionChange) { + event.vision?.let { vision -> renderVision(element, name, vision, outputMeta) } } @@ -150,8 +148,8 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { onopen = { feedbackJob = visionManager.context.launch { - eventCollector.filter { it.targetName == name }.onEach { - send(visionManager.jsonFormat.encodeToString(VisionEvent.serializer(), it)) + eventCollector.filter { it.first == name }.onEach { + send(visionManager.jsonFormat.encodeToString(VisionEvent.serializer(), it.second)) }.launchIn(this) while (isActive) { @@ -159,7 +157,7 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { val change = changeCollector[name] ?: continue if (!change.isEmpty()) { mutex.withLock { - eventCollector.emit(VisionChangeEvent(name, change.deepCopy(visionManager))) + eventCollector.emit(name to change.deepCopy(visionManager)) change.reset() } } diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 1831d641..4c5e093a 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -107,8 +107,7 @@ public fun Application.serveVisionData( try { withContext(configuration.context.coroutineContext) { - vision.flowChanges(configuration.updateInterval.milliseconds).onEach { update -> - val event = VisionChangeEvent(Name.EMPTY, update) + vision.flowChanges(configuration.updateInterval.milliseconds).onEach { event -> val json = configuration.visionManager.jsonFormat.encodeToString( VisionEvent.serializer(), event From f0048a4d46c433e14ad0558dd3014120396983a3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 15 Nov 2023 10:49:19 +0300 Subject: [PATCH 104/112] Add direct event processing to Vision --- .../commonMain/kotlin/space/kscience/visionforge/Vision.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 06cd6d8f..55d1391b 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.descriptors.Described @@ -45,13 +46,17 @@ public interface Vision : Described { } } + public fun onMetaEvent(meta: Meta){ + + } + /** * Receive and process a generic [VisionEvent]. */ public fun receiveEvent(event: VisionEvent) { when (event) { is VisionChange -> receiveChange(event) - else -> TODO() + is VisionMetaEvent -> onMetaEvent(event.meta) } } From ed71ba9ccbf42e03779f480b2407c99ab8712046 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 20 Nov 2023 10:03:44 +0300 Subject: [PATCH 105/112] Add compose-html --- settings.gradle.kts | 2 +- .../visionforge/compose/MetaViewer.kt | 103 ++----- .../visionforge/compose/PropertyEditor.kt | 189 ++++++++++++ .../visionforge/compose/ThreeCanvas.kt | 52 ++++ .../kscience/visionforge/compose/ThreeJS.kt | 11 - .../visionforge/compose/TreeStyles.kt | 49 +++- .../space/kscience/visionforge/compose/css.kt | 35 +++ .../visionforge/compose/valueChooser.kt | 268 ++++++++++++++++++ .../space/kscience/visionforge/Vision.kt | 2 +- 9 files changed, 612 insertions(+), 99 deletions(-) create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeCanvas.kt delete mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeJS.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt diff --git a/settings.gradle.kts b/settings.gradle.kts index 31119a06..8611d0aa 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -45,7 +45,7 @@ include( ":ui:ring", // ":ui:material", ":ui:bootstrap", -// ":ui:compose", + ":ui:compose", ":visionforge-core", ":visionforge-solid", // ":visionforge-fx", diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt index 93cbddfc..5aaf4140 100644 --- a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt @@ -1,11 +1,12 @@ package space.kscience.visionforge.compose import androidx.compose.runtime.* -import kotlinx.html.js.onClickFunction import org.jetbrains.compose.web.css.AlignItems import org.jetbrains.compose.web.css.alignItems +import org.jetbrains.compose.web.dom.A +import org.jetbrains.compose.web.dom.Div import org.jetbrains.compose.web.dom.Span -import org.w3c.dom.events.Event +import org.jetbrains.compose.web.dom.Text import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get @@ -17,10 +18,6 @@ import space.kscience.dataforge.names.lastOrNull import space.kscience.dataforge.names.plus -private val MetaViewerItem: FC = fc("MetaViewerItem") { props -> - metaViewerItem(props) -} - @Composable private fun MetaViewerItem(root: Meta, name: Name, rootDescriptor: MetaDescriptor? = null) { var expanded: Boolean by remember { mutableStateOf(true) } @@ -29,11 +26,7 @@ private fun MetaViewerItem(root: Meta, name: Name, rootDescriptor: MetaDescripto val actualValue = item?.value ?: descriptorItem?.defaultValue val actualMeta = item ?: descriptorItem?.defaultNode - val token = name.lastOrNull()?.toString() ?: props.rootName ?: "" - - val expanderClick: (Event) -> Unit = { - expanded = !expanded - } + val token = name.lastOrNull()?.toString() ?: "" FlexRow(attrs = { classes("metaItem") @@ -42,42 +35,34 @@ private fun MetaViewerItem(root: Meta, name: Name, rootDescriptor: MetaDescripto } }) { if (actualMeta?.isLeaf == false) { - Span(attrs = { - - }) - styledSpan { - css { - +TreeStyles.treeCaret - if (expanded) { - +TreeStyles.treeCaredDown - } + Span({ + classes(TreeStyles.treeCaret) + if (expanded) { + classes(TreeStyles.treeCaretDown) } - attrs { - onClickFunction = expanderClick - } - } + onClick { expanded = !expanded } + }) } - styledSpan { - css { - +TreeStyles.treeLabel - if (item == null) { - +TreeStyles.treeLabelInactive - } + Span({ + classes(TreeStyles.treeLabel) + if (item == null) { + classes(TreeStyles.treeLabelInactive) } - +token + }) { + Text(token) } - styledDiv { - a { - +actualValue.toString() + + Div { + A { + Text(actualValue.toString()) } } } if (expanded) { - flexColumn { - css { - +TreeStyles.tree - } + FlexColumn({ + classes(TreeStyles.tree) + }) { val keys = buildSet { descriptorItem?.children?.keys?.forEach { add(NameToken(it)) @@ -86,45 +71,17 @@ private fun MetaViewerItem(root: Meta, name: Name, rootDescriptor: MetaDescripto } keys.filter { !it.body.startsWith("@") }.forEach { token -> - styledDiv { - css { - +TreeStyles.treeItem - } - child(MetaViewerItem) { - attrs { - this.key = props.name.toString() - this.root = props.root - this.name = props.name + token - this.descriptor = props.descriptor - } - } - //configEditor(props.root, props.name + token, props.descriptor, props.default) + Div({ + classes(TreeStyles.treeItem) + }) { + MetaViewerItem(root, name + token, rootDescriptor) } } } } - - -} - -@JsExport -public val MetaViewer: FC = fc("MetaViewer") { props -> - child(MetaViewerItem) { - attrs { - this.key = "" - this.root = props.root - this.name = Name.EMPTY - this.descriptor = props.descriptor - } - } } -public fun RBuilder.metaViewer(meta: Meta, descriptor: MetaDescriptor? = null, key: Any? = null) { - child(MetaViewer) { - attrs { - this.key = key?.toString() ?: "" - this.root = meta - this.descriptor = descriptor - } - } +@Composable +public fun MetaViewer(meta: Meta, descriptor: MetaDescriptor? = null) { + MetaViewerItem(meta, Name.EMPTY, descriptor) } diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt new file mode 100644 index 00000000..f82b9e05 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt @@ -0,0 +1,189 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.launch +import org.jetbrains.compose.web.attributes.disabled +import org.jetbrains.compose.web.css.AlignItems +import org.jetbrains.compose.web.css.alignItems +import org.jetbrains.compose.web.css.px +import org.jetbrains.compose.web.css.width +import org.jetbrains.compose.web.dom.Button +import org.jetbrains.compose.web.dom.Div +import org.jetbrains.compose.web.dom.Span +import org.jetbrains.compose.web.dom.Text +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.ObservableMutableMeta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.ValueRequirement +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.remove +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.isEmpty +import space.kscience.dataforge.names.lastOrNull +import space.kscience.visionforge.hidden + + +/** + * The display state of a property + */ +public sealed class EditorPropertyState { + public object Defined : EditorPropertyState() + public class Default(public val source: String = "unknown") : EditorPropertyState() + public object Undefined : EditorPropertyState() + +} + +/** + * @param rootDescriptor Full path to the displayed node in [meta]. Could be empty + */ +@Composable +private fun PropertyEditorItem( + /** + * Root config object - always non-null + */ + meta: MutableMeta, + getPropertyState: (Name) -> EditorPropertyState, + scope: CoroutineScope, + updates: Flow, + name: Name, + rootDescriptor: MetaDescriptor?, + initialExpanded: Boolean? = null, +) { + var expanded: Boolean by remember { mutableStateOf(initialExpanded ?: true) } + val descriptor: MetaDescriptor? = remember(rootDescriptor, name) { rootDescriptor?.get(name) } + var property: MutableMeta by remember { mutableStateOf(meta.getOrCreate(name)) } + var editorPropertyState: EditorPropertyState by remember { mutableStateOf(getPropertyState(name)) } + + + val keys = remember(descriptor) { + buildSet { + descriptor?.children?.filterNot { + it.key.startsWith("@") || it.value.hidden + }?.forEach { + add(NameToken(it.key)) + } + //ownProperty?.items?.keys?.filterNot { it.body.startsWith("@") }?.let { addAll(it) } + } + } + + val token = name.lastOrNull()?.toString() ?: "Properties" + + fun update() { + property = meta.getOrCreate(name) + editorPropertyState = getPropertyState(name) + } + + LaunchedEffect(meta) { + updates.collect { updatedName -> + if (updatedName == name) { + update() + } + } + } + + FlexRow({ + style { + alignItems(AlignItems.Center) + } + }) { + if (keys.isNotEmpty()) { + Span({ + classes(TreeStyles.treeCaret) + if (expanded) { + classes(TreeStyles.treeCaretDown) + } + onClick { expanded = !expanded } + }) + } + Span({ + classes(TreeStyles.treeLabel) + if (editorPropertyState != EditorPropertyState.Defined) { + classes(TreeStyles.treeLabelInactive) + } + }) { + Text(token) + } + + if (!name.isEmpty() && descriptor?.valueRequirement != ValueRequirement.ABSENT) { + Div({ + style { + width(160.px) + marginAll(1.px, 5.px) + } + }) { + ValueChooser(descriptor, editorPropertyState, property.value) { + property.value = it + editorPropertyState = getPropertyState(name) + } + } + + Button({ + classes(TreeStyles.propertyEditorButton) + if (editorPropertyState != EditorPropertyState.Defined) { + disabled() + } else { + onClick { + meta.remove(name) + update() + } + } + }) { + Text("\u00D7") + } + } + } + if (expanded) { + FlexColumn({ + classes(TreeStyles.tree) + }) { + keys.forEach { token -> + Div({ + classes(TreeStyles.treeItem) + }) { + PropertyEditorItem(meta, getPropertyState, scope, updates, name, descriptor, expanded) + } + } + } + } +} + +@Composable +public fun PropertyEditor( + scope: CoroutineScope, + properties: ObservableMutableMeta, + descriptor: MetaDescriptor? = null, + expanded: Boolean? = null, +) { + PropertyEditorItem( + meta = properties, + getPropertyState = { name -> + if (properties[name] != null) { + EditorPropertyState.Defined + } else if (descriptor?.get(name)?.defaultValue != null) { + EditorPropertyState.Default("descriptor") + } else { + EditorPropertyState.Undefined + } + }, + scope = scope, + updates = callbackFlow { + properties.onChange(scope) { name -> + scope.launch { + send(name) + } + } + + invokeOnClose { + properties.removeListener(scope) + } + }, + name = Name.EMPTY, + rootDescriptor = descriptor, + initialExpanded = expanded, + ) +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeCanvas.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeCanvas.kt new file mode 100644 index 00000000..9816b5c2 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeCanvas.kt @@ -0,0 +1,52 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import kotlinx.dom.clear +import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.dom.Div +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.request +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.specifications.Canvas3DOptions +import space.kscience.visionforge.solid.three.ThreeCanvas +import space.kscience.visionforge.solid.three.ThreePlugin + +@Composable +public fun ThreeCanvas( + context: Context, + options: Canvas3DOptions?, + solid: Solid?, + selected: Name?, +) { + + val three: ThreePlugin by derivedStateOf { context.request(ThreePlugin) } + + Div({ + style { + maxWidth(100.vw) + maxHeight(100.vh) + width(100.percent) + height(100.percent) + } + }) { + var canvas: ThreeCanvas? = null + DisposableEffect(options) { + canvas = ThreeCanvas(three, scopeElement, options ?: Canvas3DOptions()) + onDispose { + scopeElement.clear() + canvas = null + } + } + LaunchedEffect(solid) { + if (solid != null) { + canvas?.render(solid) + } else { + canvas?.clear() + } + } + LaunchedEffect(selected) { + canvas?.select(selected) + } + } +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeJS.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeJS.kt deleted file mode 100644 index 6033c712..00000000 --- a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeJS.kt +++ /dev/null @@ -1,11 +0,0 @@ -package space.kscience.visionforge.compose - -import androidx.compose.material.Surface -import androidx.compose.runtime.Composable - -@Composable -public fun ThreeJs(){ - Surface { - - } -} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt index 29074464..de9001ba 100644 --- a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt @@ -1,8 +1,10 @@ package space.kscience.visionforge.compose -import kotlinx.css.* +import org.jetbrains.compose.web.ExperimentalComposeWebApi import org.jetbrains.compose.web.css.* + +@OptIn(ExperimentalComposeWebApi::class) public object TreeStyles : StyleSheet() { /** * Remove default bullets @@ -16,12 +18,12 @@ public object TreeStyles : StyleSheet() { /** * Style the caret/arrow */ - public val treeCaret by style { + public val treeCaret: String by style { cursor("pointer") - userSelect = UserSelect.none + userSelect(UserSelect.none) /* Create the caret/arrow with a unicode, and style it */ before { - content = "\u25B6".quoted + content("\u25B6") color(Color.black) display(DisplayStyle.InlineBlock) marginRight(6.px) @@ -31,9 +33,9 @@ public object TreeStyles : StyleSheet() { /** * Rotate the caret/arrow icon when clicked on (using JavaScript) */ - public val treeCaredDown by style { + public val treeCaretDown: String by style { before { - content = "\u25B6".quoted + content("\u25B6") color(Color.black) display(DisplayStyle.InlineBlock) marginRight(6.px) @@ -45,7 +47,7 @@ public object TreeStyles : StyleSheet() { alignItems(AlignItems.Center) paddingLeft(10.px) border { - left{ + left { width(1.px) color(Color.lightgray) style = LineStyle.Dashed @@ -53,19 +55,40 @@ public object TreeStyles : StyleSheet() { } } - public val treeLabel by style { + public val treeLabel: String by style { border(style = LineStyle.None) - padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) + paddingAll(left = 4.pt, right = 4.pt) textAlign("left") flex(1) } - public val treeLabelInactive: RuleSet by css { - color = Color.lightGray + public val treeLabelInactive: String by style { + color(Color.lightgray) + } + + public val treeLabelSelected: String by style { + backgroundColor(Color.lightblue) } - public val treeLabelSelected: RuleSet by css { - backgroundColor = Color.lightBlue + public val propertyEditorButton: String by style { + width(24.px) + alignSelf(AlignSelf.Stretch) + marginAll(1.px, 5.px) + backgroundColor(Color.white) + border{ + style(LineStyle.Solid) + } + borderRadius(2.px) + textAlign("center") + textDecoration("none") + cursor("pointer") + disabled { + cursor("auto") + border{ + style(LineStyle.Dashed) + } + color(Color.lightgray) + } } } \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt new file mode 100644 index 00000000..9f6eb3e4 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt @@ -0,0 +1,35 @@ +package space.kscience.visionforge.compose + +import org.jetbrains.compose.web.css.* + +public enum class UserSelect { + inherit, initial, revert, revertLayer, unset, + + none, auto, text, contain, all; +} + +public fun StyleScope.userSelect(value: UserSelect) { + property("user-select", value.name) +} + +public fun StyleScope.content(value: String) { + property("content", "'$value'") +} + +public fun StyleScope.paddingAll( + top: CSSNumeric = 0.pt, + right: CSSNumeric = top, + bottom: CSSNumeric = top, + left: CSSNumeric = right, +) { + padding(top, right, bottom, left) +} + +public fun StyleScope.marginAll( + top: CSSNumeric = 0.pt, + right: CSSNumeric = top, + bottom: CSSNumeric = top, + left: CSSNumeric = right, +) { + margin(top, right, bottom, left) +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt new file mode 100644 index 00000000..0be879ad --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt @@ -0,0 +1,268 @@ +@file:Suppress("UNUSED_PARAMETER") + +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import org.jetbrains.compose.web.attributes.* +import org.jetbrains.compose.web.css.percent +import org.jetbrains.compose.web.css.px +import org.jetbrains.compose.web.css.width +import org.jetbrains.compose.web.dom.Input +import org.jetbrains.compose.web.dom.Option +import org.jetbrains.compose.web.dom.Select +import org.jetbrains.compose.web.dom.Text +import org.w3c.dom.HTMLInputElement +import org.w3c.dom.HTMLOptionElement +import org.w3c.dom.asList +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.ValueRequirement +import space.kscience.dataforge.meta.descriptors.allowedValues +import space.kscience.visionforge.Colors +import space.kscience.visionforge.widgetType +import three.math.Color + + +@Composable +public fun StringValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var stringValue by remember { mutableStateOf(value?.string ?: "") } + Input(type = InputType.Text) { + style { + width(100.percent) + } + value(stringValue) + onKeyDown { event -> + if (event.type == "keydown" && event.asDynamic().key == "Enter") { + stringValue = (event.target as HTMLInputElement).value + onValueChange(stringValue.asValue()) + } + } + onChange { + stringValue = it.target.value + } + } +} + + +@Composable +public fun BooleanValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + Input(type = InputType.Checkbox) { + style { + width(100.percent) + } + //this.attributes["indeterminate"] = (props.item == null).toString() + checked(value?.boolean ?: false) + + onChange { + val newValue = it.target.checked + onValueChange(newValue.asValue()) + } + } +} + +@Composable +public fun NumberValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var innerValue by remember { mutableStateOf(value?.string ?: "") } + Input(type = InputType.Number) { + style { + width(100.percent) + } + value(innerValue) + onKeyDown { event -> + if (event.type == "keydown" && event.asDynamic().key == "Enter") { + innerValue = (event.target as HTMLInputElement).value + val number = innerValue.toDoubleOrNull() + if (number == null) { + console.error("The input value $innerValue is not a number") + } else { + onValueChange(number.asValue()) + } + } + } + onChange { + innerValue = it.target.value + } + descriptor?.attributes?.get("step").number?.let { + step(it) + } + descriptor?.attributes?.get("min").string?.let { + min(it) + } + descriptor?.attributes?.get("max").string?.let { + max(it) + } + } +} + + +@Composable +public fun ComboValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var selected by remember { mutableStateOf(value?.string ?: "") } + Select({ + style { + width(100.percent) + } + onChange { + selected = it.target.value + onValueChange(selected.asValue()) + } + }, multiple = false) { + descriptor?.allowedValues?.forEach { + Option(it.string, { if (it == value) selected() }) { + Text(it.string) + } + } + + } +} + +@Composable +public fun ColorValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + Input(type = InputType.Color) { + style { + width(100.percent) + marginAll(0.px) + } + value( + value?.let { value -> + if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) + else "#" + Color(value.string).getHexString() + } ?: "#000000" + ) + onChange { + onValueChange(it.target.value.asValue()) + } + } +} + + +@Composable +public fun MultiSelectChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + Select({ + onChange { event -> + val newSelected = event.target.selectedOptions.asList() + .map { (it as HTMLOptionElement).value.asValue() } + onValueChange(newSelected.asValue()) + + } + }, multiple = true) { + descriptor?.allowedValues?.forEach { optionValue -> + Option(optionValue.string, { + value?.list?.let { if (optionValue in it) selected() } + }) { + Text(optionValue.string) + } + } + + } +} + +@Composable +public fun RangeValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var innerValue by remember { mutableStateOf(value?.double) } + var rangeDisabled: Boolean by remember { mutableStateOf(state != EditorPropertyState.Defined) } + + + FlexRow { + if (descriptor?.valueRequirement != ValueRequirement.REQUIRED) { + Input(type = InputType.Checkbox) { + if (!rangeDisabled) defaultChecked() + + onChange { + val checkBoxValue = it.target.checked + rangeDisabled = !checkBoxValue + onValueChange( + if (!checkBoxValue) { + null + } else { + innerValue?.asValue() + } + ) + } + } + } + } + + Input(type = InputType.Range) { + style { + width(100.percent) + } + if (rangeDisabled) disabled() + value(innerValue?.toString() ?: "") + onChange { + val newValue = it.target.value + onValueChange(newValue.toDoubleOrNull()?.asValue()) + innerValue = newValue.toDoubleOrNull() + } + descriptor?.attributes?.get("min").string?.let { + min(it) + } + descriptor?.attributes?.get("max").string?.let { + max(it) + } + descriptor?.attributes?.get("step").number?.let { + step(it) + } + + } + +} + +@Composable +public fun ValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + val rawInput by remember { mutableStateOf(false) } + + val type = descriptor?.valueTypes?.firstOrNull() + + when { + rawInput -> StringValueChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "color" -> ColorValueChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "multiSelect" -> MultiSelectChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "range" -> RangeValueChooser(descriptor, state, value, onValueChange) + type == ValueType.BOOLEAN -> BooleanValueChooser(descriptor, state, value, onValueChange) + type == ValueType.NUMBER -> NumberValueChooser(descriptor, state, value, onValueChange) + descriptor?.allowedValues?.isNotEmpty() ?: false -> ComboValueChooser(descriptor, state, value, onValueChange) + //TODO handle lists + else -> StringValueChooser(descriptor, state, value, onValueChange) + } +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 55d1391b..b4e6cba7 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -47,7 +47,7 @@ public interface Vision : Described { } public fun onMetaEvent(meta: Meta){ - + //Do nothing by default } /** From e6bdb67262f74ec9fd1c69045ad3be2a2d3d4202 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 21 Nov 2023 13:32:02 +0300 Subject: [PATCH 106/112] Add compose-html --- .../visionforge/compose/NameCrumbs.kt | 44 +++++ .../visionforge/compose/PropertyEditor.kt | 23 +-- .../kscience/visionforge/compose/Tabs.kt | 102 +++++++++++ .../visionforge/compose/ThreeControls.kt | 80 +++++++++ .../compose/ThreeViewWithControls.kt | 169 ++++++++++++++++++ .../visionforge/compose/VisionTree.kt | 96 ++++++++++ .../kscience/visionforge/compose/bootstrap.kt | 8 + .../space/kscience/visionforge/compose/css.kt | 9 + 8 files changed, 517 insertions(+), 14 deletions(-) create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeControls.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeViewWithControls.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt create mode 100644 ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt new file mode 100644 index 00000000..2becdbb6 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt @@ -0,0 +1,44 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.dom.Li +import org.jetbrains.compose.web.dom.Nav +import org.jetbrains.compose.web.dom.Ol +import org.jetbrains.compose.web.dom.Text +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.length + +@Composable +public fun NameCrumbs(name: Name?, link: (Name) -> Unit): Unit = Nav({ + attr("aria-label","breadcrumb") +}) { + Ol({classes("breadcrumb")}) { + Li({ + classes("breadcrumb-item") + onClick { + link(Name.EMPTY) + } + }) { + Text("\u2302") + } + + if (name != null) { + val tokens = ArrayList(name.length) + name.tokens.forEach { token -> + tokens.add(token) + val fullName = Name(tokens.toList()) + Text(".") + Li({ + classes("breadcrumb-item") + if(tokens.size == name.length) classes("active") + onClick { + link(fullName) + } + }) { + Text(token.toString()) + } + } + } + } +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt index f82b9e05..d919cd77 100644 --- a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt @@ -21,10 +21,7 @@ import space.kscience.dataforge.meta.descriptors.ValueRequirement import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.remove -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.NameToken -import space.kscience.dataforge.names.isEmpty -import space.kscience.dataforge.names.lastOrNull +import space.kscience.dataforge.names.* import space.kscience.visionforge.hidden @@ -39,19 +36,17 @@ public sealed class EditorPropertyState { } /** + * @param meta Root config object - always non-null * @param rootDescriptor Full path to the displayed node in [meta]. Could be empty */ @Composable -private fun PropertyEditorItem( - /** - * Root config object - always non-null - */ +public fun PropertyEditor( + scope: CoroutineScope, meta: MutableMeta, getPropertyState: (Name) -> EditorPropertyState, - scope: CoroutineScope, updates: Flow, - name: Name, - rootDescriptor: MetaDescriptor?, + name: Name = Name.EMPTY, + rootDescriptor: MetaDescriptor? = null, initialExpanded: Boolean? = null, ) { var expanded: Boolean by remember { mutableStateOf(initialExpanded ?: true) } @@ -145,7 +140,7 @@ private fun PropertyEditorItem( Div({ classes(TreeStyles.treeItem) }) { - PropertyEditorItem(meta, getPropertyState, scope, updates, name, descriptor, expanded) + PropertyEditor(scope, meta, getPropertyState, updates, name + token, descriptor, expanded) } } } @@ -159,7 +154,8 @@ public fun PropertyEditor( descriptor: MetaDescriptor? = null, expanded: Boolean? = null, ) { - PropertyEditorItem( + PropertyEditor( + scope = scope, meta = properties, getPropertyState = { name -> if (properties[name] != null) { @@ -170,7 +166,6 @@ public fun PropertyEditor( EditorPropertyState.Undefined } }, - scope = scope, updates = callbackFlow { properties.onChange(scope) { name -> scope.launch { diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt new file mode 100644 index 00000000..cae4e797 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt @@ -0,0 +1,102 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import org.jetbrains.compose.web.dom.* +import org.w3c.dom.HTMLDivElement +import org.w3c.dom.HTMLLIElement + + +public class ComposeTab( + public val key: String, + public val title: String, + public val content: ContentBuilder, + public val disabled: Boolean, + public val titleExt: ContentBuilder, +) + +@Composable +public fun Tabs(tabs: List, activeKey: String) { + var active by remember(activeKey) { mutableStateOf(activeKey) } + + Div({ classes("card", "text-center") }) { + Div({ classes("card-header") }) { + + Ul({ classes("nav", "nav-tabs", "card-header-tabs") }) { + tabs.forEach { tab -> + Li({ + classes("nav-item") + }) { + A(attrs = { + classes("nav-link") + if (active == tab.key) { + classes("active") + } + if (tab.disabled) { + classes("disabled") + } + onClick { + active = tab.key + } + }) { + Text(tab.title) + } + tab.titleExt.invoke(this) + } + } + } + } + tabs.find { it.key == active }?.let { tab -> + Div({ classes("card-body") }) { + tab.content.invoke(this) + } + } + } + + +} + +public class TabBuilder internal constructor(public val key: String) { + private var title: String = key + public var disabled: Boolean = false + private var content: ContentBuilder = {} + private var titleExt: ContentBuilder = {} + + @Composable + public fun Content(content: ContentBuilder) { + this.content = content + } + + @Composable + public fun Title(title: String, titleExt: ContentBuilder = {}) { + this.title = title + this.titleExt = titleExt + } + + internal fun build(): ComposeTab = ComposeTab( + key, + title, + content, + disabled, + titleExt + ) +} + +public class TabsBuilder { + public var active: String = "" + internal val tabs: MutableList = mutableListOf() + + @Composable + public fun Tab(key: String, builder: @Composable TabBuilder.() -> Unit) { + tabs.add(TabBuilder(key).apply { builder() }.build()) + } + + public fun addTab(tab: ComposeTab) { + tabs.add(tab) + } +} + +@Composable +public fun Tabs(builder: @Composable TabsBuilder.() -> Unit) { + val result = TabsBuilder().apply { builder() } + Tabs(result.tabs, result.active) +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeControls.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeControls.kt new file mode 100644 index 00000000..c559b946 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeControls.kt @@ -0,0 +1,80 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.dom.Button +import org.jetbrains.compose.web.dom.Text +import org.w3c.files.Blob +import org.w3c.files.BlobPropertyBag +import space.kscience.dataforge.context.Global +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Vision +import space.kscience.visionforge.encodeToString +import space.kscience.visionforge.solid.specifications.Canvas3DOptions + +@Composable +internal fun CanvasControls( + vision: Vision?, + options: Canvas3DOptions, +) { + FlexColumn { + FlexRow({ + style { + border { + width(1.px) + style(LineStyle.Solid) + color(Color("blue")) + } + padding(4.px) + } + }) { + vision?.let { vision -> + Button({ + onClick { event -> + val json = vision.encodeToString() + event.stopPropagation(); + event.preventDefault(); + + val fileSaver = kotlinext.js.require("file-saver") + val blob = Blob(arrayOf(json), BlobPropertyBag("text/json;charset=utf-8")) + fileSaver.saveAs(blob, "object.json") as Unit + } + }) { + Text("Export") + } + } + } + PropertyEditor( + scope = vision?.manager?.context ?: Global, + properties = options.meta, + descriptor = Canvas3DOptions.descriptor, + expanded = false + ) + + } +} + + +@Composable +public fun ThreeControls( + vision: Vision?, + canvasOptions: Canvas3DOptions, + selected: Name?, + onSelect: (Name?) -> Unit, + tabBuilder: @Composable TabsBuilder.() -> Unit = {}, +) { + Tabs { + active = "Tree" + vision?.let { vision -> + Tab("Tree") { + CardTitle("Vision tree") + VisionTree(vision, Name.EMPTY, selected, onSelect) + } + } + Tab("Settings") { + CardTitle("Canvas configuration") + CanvasControls(vision, canvasOptions) + } + tabBuilder() + } +} diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeViewWithControls.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeViewWithControls.kt new file mode 100644 index 00000000..7a347110 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeViewWithControls.kt @@ -0,0 +1,169 @@ +@file:OptIn(ExperimentalComposeWebApi::class) + +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import app.softwork.bootstrapcompose.Card +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.launch +import org.jetbrains.compose.web.ExperimentalComposeWebApi +import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.dom.* +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.isEmpty +import space.kscience.visionforge.* +import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.SolidGroup +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.specifications.Canvas3DOptions + +@Composable +public fun ThreeCanvasWithControls( + solids: Solids, + builderOfSolid: Deferred, + initialSelected: Name?, + options: Canvas3DOptions?, + tabBuilder: @Composable TabsBuilder.() -> Unit = {}, +) { + var selected: Name? by remember { mutableStateOf(initialSelected) } + var solid: Solid? by remember { mutableStateOf(null) } + + LaunchedEffect(builderOfSolid) { + solids.context.launch { + solid = builderOfSolid.await() + //ensure that the solid is properly rooted + if (solid?.parent == null) { + solid?.setAsRoot(solids.context.visionManager) + } + } + } + + val optionsWithSelector = remember(options) { + (options ?: Canvas3DOptions()).apply { + this.onSelect = { + selected = it + } + } + } + + val selectedVision: Vision? = remember(builderOfSolid, selected) { + selected?.let { + when { + it.isEmpty() -> solid + else -> (solid as? SolidGroup)?.get(it) + } + } + } + + + FlexRow({ + style { + height(100.percent) + width(100.percent) + flexWrap(FlexWrap.Wrap) + alignItems(AlignItems.Stretch) + alignContent(AlignContent.Stretch) + } + }) { + FlexColumn({ + style { + height(100.percent) + minWidth(600.px) + flex(10, 1, 600.px) + position(Position.Relative) + } + }) { + if (solid == null) { + Div({ + style { + position(Position.Fixed) + width(100.percent) + height(100.percent) + zIndex(1000) + top(40.percent) + left(0.px) + opacity(0.5) + filter { + opacity(50.percent) + } + } + }) { + Div({ classes("d-flex", " justify-content-center") }) { + Div({ + classes("spinner-grow", "text-primary") + style { + width(3.cssRem) + height(3.cssRem) + zIndex(20) + } + attr("role", "status") + }) { + Span({ classes("sr-only") }) { Text("Loading 3D vision") } + } + } + } + } else { + ThreeCanvas(solids.context, optionsWithSelector, solid, selected) + } + + selectedVision?.let { vision -> + Div({ + style { + position(Position.Absolute) + top(5.px) + right(5.px) + width(450.px) + } + }) { + Card( + headerAttrs = { + // border = true + }, + header = { + NameCrumbs(selected) { selected = it } + } + ) { + PropertyEditor( + scope = solids.context, + meta = vision.properties.root(), + getPropertyState = { name -> + if (vision.properties.own?.get(name) != null) { + EditorPropertyState.Defined + } else if (vision.properties.root()[name] != null) { + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + }, + updates = vision.properties.changes, + rootDescriptor = vision.descriptor + ) + + } + + vision.styles.takeIf { it.isNotEmpty() }?.let { styles -> + P { + B { Text("Styles: ") } + Text(styles.joinToString(separator = ", ")) + } + } + } + } + } + } + FlexColumn({ + style { + paddingAll(4.px) + minWidth(400.px) + height(100.percent) + overflowY("auto") + flex(1, 10, 300.px) + } + }) { + ThreeControls(solid, optionsWithSelector, selected, onSelect = { selected = it }, tabBuilder = tabBuilder) + } +} + + diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt new file mode 100644 index 00000000..2de59f90 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt @@ -0,0 +1,96 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import org.jetbrains.compose.web.css.Color +import org.jetbrains.compose.web.css.color +import org.jetbrains.compose.web.css.cursor +import org.jetbrains.compose.web.css.textDecorationLine +import org.jetbrains.compose.web.dom.Div +import org.jetbrains.compose.web.dom.Span +import org.jetbrains.compose.web.dom.Text +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.lastOrNull +import space.kscience.dataforge.names.plus +import space.kscience.dataforge.names.startsWith +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.asSequence +import space.kscience.visionforge.compose.TreeStyles.hover +import space.kscience.visionforge.compose.TreeStyles.invoke +import space.kscience.visionforge.isEmpty + + +@Composable +private fun TreeLabel( + vision: Vision, + name: Name, + selected: Name?, + clickCallback: (Name) -> Unit, +) { + Span({ + classes(TreeStyles.treeLabel) + if (name == selected) { + classes(TreeStyles.treeLabelSelected) + } + style { + color(Color("#069")) + cursor("pointer") + hover.invoke { + textDecorationLine("underline") + } + + } + onClick { clickCallback(name) } + }) { + Text(name.lastOrNull()?.toString() ?: "World") + } +} + +@Composable +public fun VisionTree( + vision: Vision, + name: Name = Name.EMPTY, + selected: Name? = null, + clickCallback: (Name) -> Unit, +): Unit { + var expanded: Boolean by remember { mutableStateOf(selected?.startsWith(name) ?: false) } + + //display as node if any child is visible + if (vision is VisionGroup) { + FlexRow { + if (vision.children.keys.any { !it.body.startsWith("@") }) { + Span({ + classes(TreeStyles.treeCaret) + if (expanded) { + classes(TreeStyles.treeCaretDown) + } + onClick { + expanded = !expanded + } + }) + } + TreeLabel(vision, name, selected, clickCallback) + } + if (expanded) { + FlexColumn({ + classes(TreeStyles.tree) + }) { + vision.children.asSequence() + .filter { !it.first.toString().startsWith("@") } // ignore statics and other hidden children + .sortedBy { (it.second as? VisionGroup)?.children?.isEmpty() ?: true } // ignore empty groups + .forEach { (childToken, child) -> + Div({ classes(TreeStyles.treeItem) }) { + VisionTree( + child, + name + childToken, + selected, + clickCallback + ) + } + } + } + } + } else { + TreeLabel(vision, name, selected, clickCallback) + } +} diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt new file mode 100644 index 00000000..8b0ee5b5 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt @@ -0,0 +1,8 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.dom.H5 +import org.jetbrains.compose.web.dom.Text + +@Composable +public fun CardTitle(title: String): Unit = H5({ classes("card-title") }) { Text(title) } \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt index 9f6eb3e4..0bf8f7c2 100644 --- a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt @@ -1,6 +1,7 @@ package space.kscience.visionforge.compose import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.css.keywords.CSSAutoKeyword public enum class UserSelect { inherit, initial, revert, revertLayer, unset, @@ -32,4 +33,12 @@ public fun StyleScope.marginAll( left: CSSNumeric = right, ) { margin(top, right, bottom, left) +} + +public fun StyleScope.zIndex(value: Int) { + property("z-index", "$value") +} + +public fun StyleScope.zIndex(value: CSSAutoKeyword) { + property("z-index", value) } \ No newline at end of file From 80284a99ef7b7e4c79aa510e27f6a03b03a20225 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 24 Nov 2023 10:02:25 +0300 Subject: [PATCH 107/112] Add click handlers --- .../kscience/visionforge/ControlVision.kt | 52 +++++++++++++++++++ .../space/kscience/visionforge/Vision.kt | 15 ++---- .../space/kscience/visionforge/VisionEvent.kt | 14 +---- .../space/kscience/visionforge/VisionGroup.kt | 8 +-- .../visionforge/solid/VisionUpdateTest.kt | 2 +- 5 files changed, 63 insertions(+), 28 deletions(-) create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt new file mode 100644 index 00000000..38ee4d7f --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt @@ -0,0 +1,52 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MetaRepr +import space.kscience.dataforge.meta.MutableMeta + +@Serializable +@SerialName("control") +public abstract class VisionControlEvent : VisionEvent, MetaRepr { + public abstract val meta: Meta + + override fun toMeta(): Meta = meta +} + +public interface ControlVision : Vision { + public val controlEventFlow: Flow + + public fun dispatchControlEvent(event: VisionControlEvent) + + override fun receiveEvent(event: VisionEvent) { + if (event is VisionControlEvent) { + dispatchControlEvent(event) + } else super.receiveEvent(event) + } +} + +@Serializable +@SerialName("control.click") +public class VisionClickEvent(override val meta: Meta) : VisionControlEvent() + + +public interface ClickControl : ControlVision { + public fun click(builder: MutableMeta.() -> Unit = {}) { + dispatchControlEvent(VisionClickEvent(Meta(builder))) + } + + public fun onClick(scope: CoroutineScope, block: suspend VisionClickEvent.() -> Unit): Job { + return controlEventFlow.filterIsInstance().onEach(block).launchIn(scope) + } + + public companion object { + + } +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index b4e6cba7..29965944 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -4,7 +4,8 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.context.logger +import space.kscience.dataforge.context.warn import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.descriptors.Described @@ -37,7 +38,7 @@ public interface Vision : Described { /** * Update this vision using a dif represented by [VisionChange]. */ - public fun receiveChange(change: VisionChange) { + public fun update(change: VisionChange) { if (change.children?.isNotEmpty() == true) { error("Vision is not a group") } @@ -46,18 +47,12 @@ public interface Vision : Described { } } - public fun onMetaEvent(meta: Meta){ - //Do nothing by default - } - /** * Receive and process a generic [VisionEvent]. */ public fun receiveEvent(event: VisionEvent) { - when (event) { - is VisionChange -> receiveChange(event) - is VisionMetaEvent -> onMetaEvent(event.meta) - } + if(event is VisionChange) update(event) + else manager?.logger?.warn { "Undispatched event: $event" } } override val descriptor: MetaDescriptor? diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt index 84d36217..de0b2643 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt @@ -3,8 +3,6 @@ package space.kscience.visionforge import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name /** @@ -22,14 +20,4 @@ public sealed interface VisionEvent { */ @Serializable @SerialName("meta") -public class VisionMetaEvent(public val meta: Meta) : VisionEvent - - -public val Vision.Companion.CLICK_EVENT_KEY: Name get() = Name.of("events", "click", "payload") - -/** - * Set the payload to be sent to server on click - */ -public fun Vision.onClickPayload(payloadBuilder: MutableMeta.() -> Unit) { - properties[VisionEvent.CLICK_EVENT_KEY] = Meta(payloadBuilder) -} \ No newline at end of file +public class VisionMetaEvent(public val meta: Meta) : VisionEvent \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index 1edfa40a..fd8aaa16 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -17,12 +17,12 @@ import space.kscience.visionforge.Vision.Companion.STYLE_KEY public interface VisionGroup : Vision { public val children: VisionChildren - override fun receiveChange(change: VisionChange) { + override fun update(change: VisionChange) { change.children?.forEach { (name, change) -> if (change.vision != null || change.vision == NullVision) { error("VisionGroup is read-only") } else { - children.getChild(name)?.receiveChange(change) + children.getChild(name)?.update(change) } } change.properties?.let { @@ -37,12 +37,12 @@ public interface MutableVisionGroup : VisionGroup { public fun createGroup(): MutableVisionGroup - override fun receiveChange(change: VisionChange) { + override fun update(change: VisionChange) { change.children?.forEach { (name, change) -> when { change.vision == NullVision -> children.setChild(name, null) change.vision != null -> children.setChild(name, change.vision) - else -> children.getChild(name)?.receiveChange(change) + else -> children.getChild(name)?.update(change) } } change.properties?.let { diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 898fae11..0e495aaa 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -28,7 +28,7 @@ internal class VisionUpdateTest { propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) } - targetVision.receiveChange(dif) + targetVision.update(dif) assertTrue { targetVision.children.getChild("top") is SolidGroup } assertEquals("red", (targetVision.children.getChild("origin") as Solid).color.string) // Should work assertEquals( From 469655092e8c7f871dfb610f1c34555d82da0d81 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 29 Nov 2023 09:41:22 +0300 Subject: [PATCH 108/112] Change controls API --- demo/playground/notebooks/common-demo.ipynb | 9 +- demo/playground/notebooks/controls.ipynb | 45 +++++++ demo/playground/notebooks/dynamic-demo.ipynb | 7 +- .../src/jvmMain/kotlin/formServer.kt | 2 +- .../kscience/visionforge/ControlVision.kt | 29 ++-- .../kscience/visionforge/html/VisionOfHtml.kt | 54 ++++++++ .../visionforge/html/VisionOfHtmlForm.kt | 7 +- .../visionforge/html/VisionOfHtmlInput.kt | 58 -------- .../kscience/visionforge/JsVisionClient.kt | 6 +- .../kscience/visionforge/inputRenderers.kt | 124 +++++++++--------- .../jvmMain/kotlin/VisionForgeIntegration.kt | 2 - .../kotlin/JupyterCommonIntegration.kt | 7 +- 12 files changed, 197 insertions(+), 153 deletions(-) create mode 100644 demo/playground/notebooks/controls.ipynb create mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt delete mode 100644 visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt diff --git a/demo/playground/notebooks/common-demo.ipynb b/demo/playground/notebooks/common-demo.ipynb index 78797545..caa7306f 100644 --- a/demo/playground/notebooks/common-demo.ipynb +++ b/demo/playground/notebooks/common-demo.ipynb @@ -54,9 +54,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "jupyter": { - "outputs_hidden": false - }, "tags": [] }, "outputs": [], @@ -83,9 +80,6 @@ "language": "kotlin", "name": "kotlin" }, - "ktnbPluginMetadata": { - "isAddProjectLibrariesToClasspath": false - }, "language_info": { "codemirror_mode": "text/x-kotlin", "file_extension": ".kt", @@ -94,6 +88,9 @@ "nbconvert_exporter": "", "pygments_lexer": "kotlin", "version": "1.8.20" + }, + "ktnbPluginMetadata": { + "projectLibraries": [] } }, "nbformat": 4, diff --git a/demo/playground/notebooks/controls.ipynb b/demo/playground/notebooks/controls.ipynb new file mode 100644 index 00000000..8552a178 --- /dev/null +++ b/demo/playground/notebooks/controls.ipynb @@ -0,0 +1,45 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "USE(JupyterCommonIntegration())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + } + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "language_info": { + "name": "kotlin", + "version": "1.9.0", + "mimetype": "text/x-kotlin", + "file_extension": ".kt", + "pygments_lexer": "kotlin", + "codemirror_mode": "text/x-kotlin", + "nbconvert_exporter": "" + }, + "ktnbPluginMetadata": { + "projectDependencies": true + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/demo/playground/notebooks/dynamic-demo.ipynb b/demo/playground/notebooks/dynamic-demo.ipynb index ac70b4c2..3fcd31e3 100644 --- a/demo/playground/notebooks/dynamic-demo.ipynb +++ b/demo/playground/notebooks/dynamic-demo.ipynb @@ -25,10 +25,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "collapsed": false }, "outputs": [], "source": [ @@ -84,7 +81,7 @@ "version": "1.8.0-dev-3517" }, "ktnbPluginMetadata": { - "isAddProjectLibrariesToClasspath": false + "projectLibraries": [] } }, "nbformat": 4, diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index d832d85a..21d2d4a7 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -75,7 +75,7 @@ fun main() { server.openInBrowser() - while (readln() != "exit") { + while (readlnOrNull() != "exit") { } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt index 38ee4d7f..e0d44930 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt @@ -2,7 +2,7 @@ package space.kscience.visionforge import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -21,7 +21,7 @@ public abstract class VisionControlEvent : VisionEvent, MetaRepr { } public interface ControlVision : Vision { - public val controlEventFlow: Flow + public val controlEventFlow: SharedFlow public fun dispatchControlEvent(event: VisionControlEvent) @@ -32,21 +32,32 @@ public interface ControlVision : Vision { } } +/** + * @param payload The optional payload associated with the click event. + */ @Serializable @SerialName("control.click") -public class VisionClickEvent(override val meta: Meta) : VisionControlEvent() +public class VisionClickEvent(public val payload: Meta = Meta.EMPTY) : VisionControlEvent() { + override val meta: Meta get() = Meta { ::payload.name put payload } +} public interface ClickControl : ControlVision { + /** + * Create and dispatch a click event + */ public fun click(builder: MutableMeta.() -> Unit = {}) { dispatchControlEvent(VisionClickEvent(Meta(builder))) } +} - public fun onClick(scope: CoroutineScope, block: suspend VisionClickEvent.() -> Unit): Job { - return controlEventFlow.filterIsInstance().onEach(block).launchIn(scope) - } +/** + * Register listener + */ +public fun ClickControl.onClick(scope: CoroutineScope, block: suspend VisionClickEvent.() -> Unit): Job = + controlEventFlow.filterIsInstance().onEach(block).launchIn(scope) - public companion object { - } -} \ No newline at end of file +@Serializable +@SerialName("control.valueChange") +public class VisionValueChangeEvent(override val meta: Meta) : VisionControlEvent() \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt new file mode 100644 index 00000000..d9f09ec1 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt @@ -0,0 +1,54 @@ +package space.kscience.visionforge.html + +import kotlinx.html.InputType +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.names.asName +import space.kscience.visionforge.AbstractVision + + +@Serializable +public abstract class VisionOfHtml: AbstractVision(){ + public var classes: List by properties.stringList(*emptyArray()) +} + +@Serializable +@SerialName("html.input") +public open class VisionOfHtmlInput( + public val inputType: String, +) : VisionOfHtml() { + public var value : Value? by properties.value() + public var disabled: Boolean by properties.boolean { false } + public var fieldName: String? by properties.string() +} + + +@Serializable +@SerialName("html.text") +public class VisionOfTextField : VisionOfHtmlInput(InputType.text.realValue) { + public var text: String? by properties.string(key = VisionOfHtmlInput::value.name.asName()) +} + +@Serializable +@SerialName("html.checkbox") +public class VisionOfCheckbox : VisionOfHtmlInput(InputType.checkBox.realValue) { + public var checked: Boolean? by properties.boolean(key = VisionOfHtmlInput::value.name.asName()) +} + +@Serializable +@SerialName("html.number") +public class VisionOfNumberField : VisionOfHtmlInput(InputType.number.realValue) { + public var number: Number? by properties.number(key = VisionOfHtmlInput::value.name.asName()) +} + +@Serializable +@SerialName("html.range") +public class VisionOfRangeField( + public val min: Double, + public val max: Double, + public val step: Double = 1.0, +) : VisionOfHtmlInput(InputType.range.realValue) { + public var number: Number? by properties.number(key = VisionOfHtmlInput::value.name.asName()) +} + diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt index d9c0347d..e56af874 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt @@ -9,12 +9,15 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.node +/** + * @param formId an id of the element in rendered DOM, this form is bound to + */ @Serializable @SerialName("html.form") public class VisionOfHtmlForm( public val formId: String, -) : VisionOfHtmlInput() { - public var values: Meta? by mutableProperties.node() +) : VisionOfHtml() { + public var values: Meta? by properties.node() } public fun TagConsumer.bindForm( diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt deleted file mode 100644 index d2bb2c52..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt +++ /dev/null @@ -1,58 +0,0 @@ -package space.kscience.visionforge.html - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.boolean -import space.kscience.dataforge.meta.number -import space.kscience.dataforge.meta.string -import space.kscience.dataforge.names.Name -import space.kscience.visionforge.AbstractVision -import space.kscience.visionforge.Vision - -//TODO replace by something -internal val Vision.mutableProperties get() = properties.getMeta(Name.EMPTY, false, false) - -@Serializable -public abstract class VisionOfHtmlInput : AbstractVision() { - public var disabled: Boolean by mutableProperties.boolean { false } -} - -@Serializable -@SerialName("html.text") -public class VisionOfTextField( - public val label: String? = null, - public val name: String? = null, -) : VisionOfHtmlInput() { - public var text: String? by mutableProperties.string() -} - -@Serializable -@SerialName("html.checkbox") -public class VisionOfCheckbox( - public val label: String? = null, - public val name: String? = null, -) : VisionOfHtmlInput() { - public var checked: Boolean? by mutableProperties.boolean() -} - -@Serializable -@SerialName("html.number") -public class VisionOfNumberField( - public val label: String? = null, - public val name: String? = null, -) : VisionOfHtmlInput() { - public var value: Number? by mutableProperties.number() -} - -@Serializable -@SerialName("html.range") -public class VisionOfRangeField( - public val min: Double, - public val max: Double, - public val step: Double = 1.0, - public val label: String? = null, - public val name: String? = null, -) : VisionOfHtmlInput() { - public var value: Number? by mutableProperties.number() -} - diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index b9e0ef93..d164e5ea 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -252,9 +252,9 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { override fun content(target: String): Map = if (target == ElementVisionRenderer.TYPE) { listOf( - numberVisionRenderer(this), - textVisionRenderer(this), - formVisionRenderer(this) + numberVisionRenderer(), + textVisionRenderer(), + formVisionRenderer() ).associateByName() } else super.content(target) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index ff84c403..8b07e177 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -3,65 +3,62 @@ package space.kscience.visionforge import kotlinx.browser.document import kotlinx.html.InputType import kotlinx.html.js.input -import kotlinx.html.js.label import kotlinx.html.js.onChangeFunction +import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLFormElement import org.w3c.dom.HTMLInputElement import org.w3c.dom.get import org.w3c.xhr.FormData import space.kscience.dataforge.context.debug import space.kscience.dataforge.context.logger -import space.kscience.dataforge.meta.DynamicMeta -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.toMap -import space.kscience.dataforge.meta.valueSequence -import space.kscience.visionforge.html.VisionOfHtmlForm -import space.kscience.visionforge.html.VisionOfNumberField -import space.kscience.visionforge.html.VisionOfTextField +import space.kscience.dataforge.meta.* +import space.kscience.visionforge.html.* -internal fun textVisionRenderer( - client: JsVisionClient, -): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> - val fieldName = vision.name ?: "input[${vision.hashCode().toUInt()}]" - vision.label?.let { - label { - htmlFor = fieldName - +it - } + +private fun HTMLElement.subscribeToVision(vision: VisionOfHtml) { + vision.useProperty(VisionOfHtml::classes) { + classList.value = classes.joinToString(separator = " ") } - input { - type = InputType.text - this.name = fieldName - vision.useProperty(VisionOfTextField::text) { - value = it ?: "" - } - onChangeFunction = { - client.notifyPropertyChanged(name, VisionOfTextField::text.name, value) - } +} + + +private fun HTMLInputElement.subscribeToInput(inputVision: VisionOfHtmlInput) { + subscribeToVision(inputVision) + inputVision.useProperty(VisionOfHtmlInput::disabled) { + disabled = it } } -internal fun numberVisionRenderer( - client: JsVisionClient, -): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> - val fieldName = vision.name ?: "input[${vision.hashCode().toUInt()}]" - vision.label?.let { - label { - htmlFor = fieldName - +it + +internal fun JsVisionClient.textVisionRenderer(): ElementVisionRenderer = + ElementVisionRenderer { visionName, vision, _ -> + input { + type = InputType.text + onChangeFunction = { + notifyPropertyChanged(visionName, VisionOfTextField::text.name, value) + } + }.apply { + subscribeToInput(vision) + vision.useProperty(VisionOfTextField::text) { + value = (it ?: "").asValue() + } } } - input { - type = InputType.text - this.name = fieldName - vision.useProperty(VisionOfNumberField::value) { - value = it?.toDouble() ?: 0.0 - } - onChangeFunction = { - client.notifyPropertyChanged(name, VisionOfNumberField::value.name, value) + +internal fun JsVisionClient.numberVisionRenderer(): ElementVisionRenderer = + ElementVisionRenderer { visionName, vision, _ -> + input { + type = InputType.text + onChangeFunction = { + notifyPropertyChanged(visionName, VisionOfNumberField::value.name, value) + } + }.apply { + subscribeToInput(vision) + vision.useProperty(VisionOfNumberField::value) { + value = (it?.double ?: 0.0).asValue() + } } } -} internal fun FormData.toMeta(): Meta { @Suppress("UNUSED_VARIABLE") val formData = this @@ -86,28 +83,29 @@ internal fun FormData.toMeta(): Meta { return DynamicMeta(`object`) } -internal fun formVisionRenderer( - client: JsVisionClient, -): ElementVisionRenderer = ElementVisionRenderer { name, vision, _ -> +internal fun JsVisionClient.formVisionRenderer(): ElementVisionRenderer = + ElementVisionRenderer { visionName, vision, _ -> + + val form = document.getElementById(vision.formId) as? HTMLFormElement + ?: error("An element with id = '${vision.formId} is not a form") - val form = document.getElementById(vision.formId) as? HTMLFormElement - ?: error("An element with id = '${vision.formId} is not a form") + form.subscribeToVision(vision) - client.logger.debug{"Adding hooks to form with id = '$vision.formId'"} + logger.debug { "Adding hooks to form with id = '$vision.formId'" } - vision.useProperty(VisionOfHtmlForm::values) { values -> - client.logger.debug{"Updating form '${vision.formId}' with values $values"} - val inputs = form.getElementsByTagName("input") - values?.valueSequence()?.forEach { (token, value) -> - (inputs[token.toString()] as? HTMLInputElement)?.value = value.toString() + vision.useProperty(VisionOfHtmlForm::values) { values -> + logger.debug { "Updating form '${vision.formId}' with values $values" } + val inputs = form.getElementsByTagName("input") + values?.valueSequence()?.forEach { (token, value) -> + (inputs[token.toString()] as? HTMLInputElement)?.value = value.toString() + } } - } - form.onsubmit = { event -> - event.preventDefault() - val formData = FormData(form).toMeta() - client.notifyPropertyChanged(name, VisionOfHtmlForm::values.name, formData) - console.info("Sent: ${formData.toMap()}") - false - } -} \ No newline at end of file + form.onsubmit = { event -> + event.preventDefault() + val formData = FormData(form).toMeta() + notifyPropertyChanged(visionName, VisionOfHtmlForm::values.name, formData) + console.info("Sent: ${formData.toMap()}") + false + } + } \ No newline at end of file diff --git a/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt index afc2ecc2..935f183c 100644 --- a/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt @@ -7,7 +7,6 @@ import org.jetbrains.kotlinx.jupyter.api.declare import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.ContextAware -import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager import space.kscience.visionforge.html.* @@ -17,7 +16,6 @@ import kotlin.random.nextUInt /** * A base class for different Jupyter VF integrations */ -@DFExperimental public abstract class VisionForgeIntegration( public val visionManager: VisionManager, ) : JupyterIntegration(), ContextAware { diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt index 6200bd5d..2f7988f8 100644 --- a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt @@ -1,14 +1,14 @@ package space.kscience.visionforge.jupyter -import kotlinx.html.* +import kotlinx.html.div +import kotlinx.html.p import org.jetbrains.kotlinx.jupyter.api.libraries.resources import space.kscience.dataforge.context.Context -import space.kscience.dataforge.misc.DFExperimental import space.kscience.gdml.Gdml import space.kscience.plotly.Plot import space.kscience.plotly.PlotlyPage import space.kscience.plotly.StaticPlotlyRenderer -import space.kscience.tables.* +import space.kscience.tables.Table import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.html.HtmlFragment import space.kscience.visionforge.html.VisionPage @@ -21,7 +21,6 @@ import space.kscience.visionforge.tables.toVision import space.kscience.visionforge.visionManager -@DFExperimental public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionManager) { override fun Builder.afterLoaded(vf: VisionForge) { From 7561ddad364527cfc1ccfc63aa43781c5949c599 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 2 Dec 2023 23:01:15 +0300 Subject: [PATCH 109/112] Fix html input renderers --- .../kscience/visionforge/VisionClient.kt | 34 +++-- .../kscience/visionforge/VisionManager.kt | 7 +- .../kscience/visionforge/html/VisionOfHtml.kt | 35 ++++- .../space/kscience/visionforge/useProperty.kt | 17 ++- .../visionforge/ElementVisionRenderer.kt | 2 +- .../kscience/visionforge/JsVisionClient.kt | 79 +++++----- .../kscience/visionforge/inputRenderers.kt | 135 +++++++++++++++--- 7 files changed, 232 insertions(+), 77 deletions(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt index 76d8aa80..9d6a5561 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -2,10 +2,8 @@ package space.kscience.visionforge import kotlinx.coroutines.launch import space.kscience.dataforge.context.Plugin -import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaRepr import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.parseAsName /** * A feedback client that communicates with a server and provides ability to propagate events and changes back to the model @@ -15,25 +13,25 @@ public interface VisionClient: Plugin { public suspend fun sendEvent(targetName: Name, event: VisionEvent) - public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) +// public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) } -public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { - notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) -} - -public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Number) { - notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -} - -public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: String) { - notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -} - -public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { - notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -} +//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { +// notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) +//} +// +//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Number) { +// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +//} +// +//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: String) { +// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +//} +// +//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { +// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +//} public fun VisionClient.sendEvent(targetName: Name, payload: MetaRepr): Unit { context.launch { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index e4ca1cdb..8799a73f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -13,10 +13,7 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.toJson import space.kscience.dataforge.meta.toMeta import space.kscience.dataforge.names.Name -import space.kscience.visionforge.html.VisionOfCheckbox -import space.kscience.visionforge.html.VisionOfHtmlForm -import space.kscience.visionforge.html.VisionOfNumberField -import space.kscience.visionforge.html.VisionOfTextField +import space.kscience.visionforge.html.* public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionContainer { override val tag: PluginTag get() = Companion.tag @@ -72,9 +69,11 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont defaultDeserializer { SimpleVisionGroup.serializer() } subclass(NullVision.serializer()) subclass(SimpleVisionGroup.serializer()) + subclass(VisionOfHtmlInput.serializer()) subclass(VisionOfNumberField.serializer()) subclass(VisionOfTextField.serializer()) subclass(VisionOfCheckbox.serializer()) + subclass(VisionOfRangeField.serializer()) subclass(VisionOfHtmlForm.serializer()) } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt index d9f09ec1..51458047 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt @@ -1,6 +1,8 @@ package space.kscience.visionforge.html import kotlinx.html.InputType +import kotlinx.html.TagConsumer +import kotlinx.html.stream.createHTML import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* @@ -9,16 +11,45 @@ import space.kscience.visionforge.AbstractVision @Serializable -public abstract class VisionOfHtml: AbstractVision(){ +public abstract class VisionOfHtml : AbstractVision() { public var classes: List by properties.stringList(*emptyArray()) } +@Serializable +@SerialName("html.plain") +public class VisionOfPlainHtml : VisionOfHtml() { + public var content: String? by properties.string() +} + +public inline fun VisionOfPlainHtml.content(block: TagConsumer<*>.() -> Unit) { + content = createHTML().apply(block).finalize() +} + +@Serializable +public enum class InputFeedbackMode{ + /** + * Fire feedback event on `onchange` event + */ + ONCHANGE, + + /** + * Fire feedback event on `oninput` event + */ + ONINPUT, + + /** + * provide only manual feedback + */ + NONE +} + @Serializable @SerialName("html.input") public open class VisionOfHtmlInput( public val inputType: String, + public val feedbackMode: InputFeedbackMode = InputFeedbackMode.ONCHANGE ) : VisionOfHtml() { - public var value : Value? by properties.value() + public var value: Value? by properties.value() public var disabled: Boolean by properties.boolean { false } public var fieldName: String? by properties.string() } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt index f6f95a6f..cee3a002 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt @@ -39,9 +39,22 @@ public fun Vision.useProperty( callback: (Meta) -> Unit, ): Job = useProperty(propertyName.parseAsName(), inherit, includeStyles, scope, callback) +/** + * Observe changes to the specific property without passing the initial value. + */ +public fun V.onPropertyChange( + property: KProperty1, + scope: CoroutineScope = manager?.context ?: error("Orphan Vision can't observe properties"), + callback: suspend V.(T) -> Unit, +): Job = properties.changes.onEach { name -> + if (name.startsWith(property.name.asName())) { + callback(property.get(this)) + } +}.launchIn(scope) + public fun V.useProperty( property: KProperty1, - scope: CoroutineScope? = manager?.context, + scope: CoroutineScope = manager?.context ?: error("Orphan Vision can't observe properties"), callback: V.(T) -> Unit, ): Job { //Pass initial value. @@ -50,5 +63,5 @@ public fun V.useProperty( if (name.startsWith(property.name.asName())) { callback(property.get(this@useProperty)) } - }.launchIn(scope ?: error("Orphan Vision can't observe properties")) + }.launchIn(scope) } \ No newline at end of file diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt index 75ec785a..8842e08e 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt @@ -26,7 +26,7 @@ public interface ElementVisionRenderer : Named { /** * Give a [vision] integer rating based on this renderer capabilities. [ZERO_RATING] or negative values means that this renderer * can't process a vision. The value of [DEFAULT_RATING] used for default renderer. Specialized renderers could specify - * higher value in order to "steal" rendering job + * higher value to "steal" rendering job */ public fun rateVision(vision: Vision): Int diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index d164e5ea..388ed2af 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -65,20 +65,20 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { private fun Element.getFlag(attribute: String): Boolean = attributes[attribute]?.value != null - private val mutex = Mutex() +// private val mutex = Mutex() - private val changeCollector = VisionChangeBuilder() - /** - * Communicate vision property changed from rendering engine to model - */ - override fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { - context.launch { - mutex.withLock { - changeCollector.propertyChanged(visionName, propertyName, item) - } - } - } + +// /** +// * Communicate vision property changed from rendering engine to model +// */ +// private fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { +// context.launch { +// mutex.withLock { +// changeCollector.propertyChanged(visionName, propertyName, item) +// } +// } +// } private val eventCollector by lazy { MutableSharedFlow>(meta["feedback.eventCache"].int ?: 100) @@ -97,7 +97,7 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { renderer.render(element, name, vision, outputMeta) } - private fun startVisionUpdate(element: Element, name: Name, vision: Vision?, outputMeta: Meta) { + private fun startVisionUpdate(element: Element, visionName: Name, vision: Vision, outputMeta: Meta) { element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { val endpoint = resolveEndpoint(element) @@ -109,9 +109,10 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { URL(attr.value) }.apply { protocol = "ws" - searchParams.append("name", name.toString()) + searchParams.append("name", visionName.toString()) } + logger.info { "Updating vision data from $wsUrl" } //Individual websocket for this vision @@ -125,14 +126,13 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { ) // If change contains root vision replacement, do it - if(event is VisionChange) { + if (event is VisionChange) { event.vision?.let { vision -> - renderVision(element, name, vision, outputMeta) + renderVision(element, visionName, vision, outputMeta) } } - logger.debug { "Got $event for output with name $name" } - if (vision == null) error("Can't update vision because it is not loaded.") + logger.debug { "Got $event for output with name $visionName" } vision.receiveEvent(event) } else { logger.error { "WebSocket message data is not a string" } @@ -147,32 +147,44 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { val feedbackAggregationTime = meta["feedback.aggregationTime"]?.int ?: 300 onopen = { + + + val mutex = Mutex() + + val changeCollector = VisionChangeBuilder() + feedbackJob = visionManager.context.launch { - eventCollector.filter { it.first == name }.onEach { + //launch a separate coroutine to send events to the backend + eventCollector.filter { it.first == visionName }.onEach { send(visionManager.jsonFormat.encodeToString(VisionEvent.serializer(), it.second)) }.launchIn(this) + //launch backward property propagation + vision.properties.changes.onEach { propertyName: Name -> + changeCollector.propertyChanged(visionName, propertyName, vision.properties.getMeta(propertyName)) + }.launchIn(this) + + //aggregate atomic changes while (isActive) { delay(feedbackAggregationTime.milliseconds) - val change = changeCollector[name] ?: continue - if (!change.isEmpty()) { + if (!changeCollector.isEmpty()) { mutex.withLock { - eventCollector.emit(name to change.deepCopy(visionManager)) - change.reset() + eventCollector.emit(visionName to changeCollector.deepCopy(visionManager)) + changeCollector.reset() } } } } - logger.info { "WebSocket feedback channel established for output '$name'" } + logger.info { "WebSocket feedback channel established for output '$visionName'" } } onclose = { feedbackJob?.cancel() - logger.info { "WebSocket feedback channel closed for output '$name'" } + logger.info { "WebSocket feedback channel closed for output '$visionName'" } } onerror = { feedbackJob?.cancel() - logger.error { "WebSocket feedback channel error for output '$name'" } + logger.error { "WebSocket feedback channel error for output '$visionName'" } } } } @@ -241,9 +253,9 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { } //Try to load vision via websocket - element.attributes[OUTPUT_CONNECT_ATTRIBUTE] != null -> { - startVisionUpdate(element, name, null, outputMeta) - } +// element.attributes[OUTPUT_CONNECT_ATTRIBUTE] != null -> { +// startVisionUpdate(element, name, null, outputMeta) +// } else -> error("No embedded vision data / fetch url for $name") } @@ -252,9 +264,12 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { override fun content(target: String): Map = if (target == ElementVisionRenderer.TYPE) { listOf( - numberVisionRenderer(), - textVisionRenderer(), - formVisionRenderer() + inputVisionRenderer, + checkboxVisionRenderer, + numberVisionRenderer, + textVisionRenderer, + rangeVisionRenderer, + formVisionRenderer ).associateByName() } else super.content(target) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index 8b07e177..4e984cb0 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -3,10 +3,10 @@ package space.kscience.visionforge import kotlinx.browser.document import kotlinx.html.InputType import kotlinx.html.js.input -import kotlinx.html.js.onChangeFunction import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLFormElement import org.w3c.dom.HTMLInputElement +import org.w3c.dom.events.Event import org.w3c.dom.get import org.w3c.xhr.FormData import space.kscience.dataforge.context.debug @@ -14,7 +14,11 @@ import space.kscience.dataforge.context.logger import space.kscience.dataforge.meta.* import space.kscience.visionforge.html.* - +/** + * Subscribes the HTML element to a given vision. + * + * @param vision The vision to subscribe to. + */ private fun HTMLElement.subscribeToVision(vision: VisionOfHtml) { vision.useProperty(VisionOfHtml::classes) { classList.value = classes.joinToString(separator = " ") @@ -22,6 +26,11 @@ private fun HTMLElement.subscribeToVision(vision: VisionOfHtml) { } +/** + * Subscribes the HTML input element to a given vision. + * + * @param inputVision The input vision to subscribe to. + */ private fun HTMLInputElement.subscribeToInput(inputVision: VisionOfHtmlInput) { subscribeToVision(inputVision) inputVision.useProperty(VisionOfHtmlInput::disabled) { @@ -29,33 +38,123 @@ private fun HTMLInputElement.subscribeToInput(inputVision: VisionOfHtmlInput) { } } - -internal fun JsVisionClient.textVisionRenderer(): ElementVisionRenderer = - ElementVisionRenderer { visionName, vision, _ -> +internal val inputVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer(acceptRating = ElementVisionRenderer.DEFAULT_RATING - 1) { _, vision, _ -> input { type = InputType.text - onChangeFunction = { - notifyPropertyChanged(visionName, VisionOfTextField::text.name, value) + }.apply { + val onEvent: (Event) -> Unit = { + vision.value = value.asValue() + } + + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> onchange = onEvent + + InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.NONE -> {} } + + subscribeToInput(vision) + vision.useProperty(VisionOfHtmlInput::value) { + this@apply.value = it?.string ?: "" + } + } + } + +internal val checkboxVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + input { + type = InputType.checkBox }.apply { + val onEvent: (Event) -> Unit = { + vision.checked = checked + } + + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> onchange = onEvent + + InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.NONE -> {} + } + subscribeToInput(vision) - vision.useProperty(VisionOfTextField::text) { - value = (it ?: "").asValue() + vision.useProperty(VisionOfCheckbox::checked) { + this@apply.checked = it ?: false } } } -internal fun JsVisionClient.numberVisionRenderer(): ElementVisionRenderer = - ElementVisionRenderer { visionName, vision, _ -> +internal val textVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> input { type = InputType.text - onChangeFunction = { - notifyPropertyChanged(visionName, VisionOfNumberField::value.name, value) + }.apply { + val onEvent: (Event) -> Unit = { + vision.text = value + } + + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> onchange = onEvent + + InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.NONE -> {} } + + subscribeToInput(vision) + vision.useProperty(VisionOfTextField::text) { + this@apply.value = it ?: "" + } + } + } + +internal val numberVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + input { + type = InputType.text }.apply { + + val onEvent: (Event) -> Unit = { + value.toDoubleOrNull()?.let { vision.number = it } + } + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> onchange = onEvent + + InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.NONE -> {} + } subscribeToInput(vision) vision.useProperty(VisionOfNumberField::value) { - value = (it?.double ?: 0.0).asValue() + this@apply.valueAsNumber = it?.double ?: 0.0 + } + } + } + +internal val rangeVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + input { + type = InputType.text + min = vision.min.toString() + max = vision.max.toString() + step = vision.step.toString() + }.apply { + + val onEvent: (Event) -> Unit = { + value.toDoubleOrNull()?.let { vision.number = it } + } + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> onchange = onEvent + + InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.NONE -> {} + } + subscribeToInput(vision) + vision.useProperty(VisionOfRangeField::value) { + this@apply.valueAsNumber = it?.double ?: 0.0 } } } @@ -83,7 +182,7 @@ internal fun FormData.toMeta(): Meta { return DynamicMeta(`object`) } -internal fun JsVisionClient.formVisionRenderer(): ElementVisionRenderer = +internal val formVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { visionName, vision, _ -> val form = document.getElementById(vision.formId) as? HTMLFormElement @@ -91,10 +190,10 @@ internal fun JsVisionClient.formVisionRenderer(): ElementVisionRenderer = form.subscribeToVision(vision) - logger.debug { "Adding hooks to form with id = '$vision.formId'" } + vision.manager?.logger?.debug { "Adding hooks to form with id = '$vision.formId'" } vision.useProperty(VisionOfHtmlForm::values) { values -> - logger.debug { "Updating form '${vision.formId}' with values $values" } + vision.manager?.logger?.debug { "Updating form '${vision.formId}' with values $values" } val inputs = form.getElementsByTagName("input") values?.valueSequence()?.forEach { (token, value) -> (inputs[token.toString()] as? HTMLInputElement)?.value = value.toString() @@ -104,7 +203,7 @@ internal fun JsVisionClient.formVisionRenderer(): ElementVisionRenderer = form.onsubmit = { event -> event.preventDefault() val formData = FormData(form).toMeta() - notifyPropertyChanged(visionName, VisionOfHtmlForm::values.name, formData) + vision.values = formData console.info("Sent: ${formData.toMap()}") false } From c877fcbce37cc6a4f1049a5a8ed7a2762445d739 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 2 Dec 2023 23:07:00 +0300 Subject: [PATCH 110/112] Add plain html input renderer --- .../kscience/visionforge/JsVisionClient.kt | 1 + .../kscience/visionforge/inputRenderers.kt | 71 +++++++++++-------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index 388ed2af..6ae70280 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -264,6 +264,7 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { override fun content(target: String): Map = if (target == ElementVisionRenderer.TYPE) { listOf( + htmlVisionRenderer, inputVisionRenderer, checkboxVisionRenderer, numberVisionRenderer, diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index 4e984cb0..af54bd75 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge import kotlinx.browser.document import kotlinx.html.InputType +import kotlinx.html.div import kotlinx.html.js.input import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLFormElement @@ -38,26 +39,36 @@ private fun HTMLInputElement.subscribeToInput(inputVision: VisionOfHtmlInput) { } } +internal val htmlVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + div {}.also { div -> + div.subscribeToVision(vision) + vision.useProperty(VisionOfPlainHtml::content) { + div.textContent = it + } + } + } + internal val inputVisionRenderer: ElementVisionRenderer = ElementVisionRenderer(acceptRating = ElementVisionRenderer.DEFAULT_RATING - 1) { _, vision, _ -> input { type = InputType.text - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - vision.value = value.asValue() + vision.value = htmlInputElement.value.asValue() } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfHtmlInput::value) { - this@apply.value = it?.string ?: "" + htmlInputElement.value = it?.string ?: "" } } } @@ -66,22 +77,22 @@ internal val checkboxVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { _, vision, _ -> input { type = InputType.checkBox - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - vision.checked = checked + vision.checked = htmlInputElement.checked } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfCheckbox::checked) { - this@apply.checked = it ?: false + htmlInputElement.checked = it ?: false } } } @@ -90,22 +101,22 @@ internal val textVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { _, vision, _ -> input { type = InputType.text - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - vision.text = value + vision.text = htmlInputElement.value } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfTextField::text) { - this@apply.value = it ?: "" + htmlInputElement.value = it ?: "" } } } @@ -114,21 +125,21 @@ internal val numberVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { _, vision, _ -> input { type = InputType.text - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - value.toDoubleOrNull()?.let { vision.number = it } + htmlInputElement.value.toDoubleOrNull()?.let { vision.number = it } } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfNumberField::value) { - this@apply.valueAsNumber = it?.double ?: 0.0 + htmlInputElement.valueAsNumber = it?.double ?: 0.0 } } } @@ -140,21 +151,21 @@ internal val rangeVisionRenderer: ElementVisionRenderer = min = vision.min.toString() max = vision.max.toString() step = vision.step.toString() - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - value.toDoubleOrNull()?.let { vision.number = it } + htmlInputElement.value.toDoubleOrNull()?.let { vision.number = it } } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfRangeField::value) { - this@apply.valueAsNumber = it?.double ?: 0.0 + htmlInputElement.valueAsNumber = it?.double ?: 0.0 } } } From fbb402de90463f893d016e72329958c067e87ce8 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 3 Dec 2023 20:17:48 +0300 Subject: [PATCH 111/112] add builders for html field --- .../kscience/visionforge/html/VisionOfHtml.kt | 38 ++++++++++++++++++- .../visionforge/meta/VisionPropertyTest.kt | 2 - .../kscience/visionforge/inputRenderers.kt | 2 +- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt index 51458047..9cc223e5 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt @@ -25,8 +25,13 @@ public inline fun VisionOfPlainHtml.content(block: TagConsumer<*>.() -> Unit) { content = createHTML().apply(block).finalize() } +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.html( + block: VisionOfPlainHtml.() -> Unit, +): VisionOfPlainHtml = VisionOfPlainHtml().apply(block) + @Serializable -public enum class InputFeedbackMode{ +public enum class InputFeedbackMode { /** * Fire feedback event on `onchange` event */ @@ -47,13 +52,18 @@ public enum class InputFeedbackMode{ @SerialName("html.input") public open class VisionOfHtmlInput( public val inputType: String, - public val feedbackMode: InputFeedbackMode = InputFeedbackMode.ONCHANGE + public val feedbackMode: InputFeedbackMode = InputFeedbackMode.ONCHANGE, ) : VisionOfHtml() { public var value: Value? by properties.value() public var disabled: Boolean by properties.boolean { false } public var fieldName: String? by properties.string() } +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlInput( + inputType: String, + block: VisionOfHtmlInput.() -> Unit = {}, +): VisionOfHtmlInput = VisionOfHtmlInput(inputType).apply(block) @Serializable @SerialName("html.text") @@ -61,18 +71,34 @@ public class VisionOfTextField : VisionOfHtmlInput(InputType.text.realValue) { public var text: String? by properties.string(key = VisionOfHtmlInput::value.name.asName()) } +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlTextField( + block: VisionOfTextField.() -> Unit = {}, +): VisionOfTextField = VisionOfTextField().apply(block) + + @Serializable @SerialName("html.checkbox") public class VisionOfCheckbox : VisionOfHtmlInput(InputType.checkBox.realValue) { public var checked: Boolean? by properties.boolean(key = VisionOfHtmlInput::value.name.asName()) } +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlCheckBox( + block: VisionOfCheckbox.() -> Unit = {}, +): VisionOfCheckbox = VisionOfCheckbox().apply(block) + @Serializable @SerialName("html.number") public class VisionOfNumberField : VisionOfHtmlInput(InputType.number.realValue) { public var number: Number? by properties.number(key = VisionOfHtmlInput::value.name.asName()) } +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlNumberField( + block: VisionOfNumberField.() -> Unit = {}, +): VisionOfNumberField = VisionOfNumberField().apply(block) + @Serializable @SerialName("html.range") public class VisionOfRangeField( @@ -83,3 +109,11 @@ public class VisionOfRangeField( public var number: Number? by properties.number(key = VisionOfHtmlInput::value.name.asName()) } +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlRangeField( + min: Double, + max: Double, + step: Double = 1.0, + block: VisionOfRangeField.() -> Unit = {}, +): VisionOfRangeField = VisionOfRangeField(min, max, step).apply(block) + diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index a6ea86a2..38abe34c 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -1,7 +1,6 @@ package space.kscience.visionforge.meta import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.take @@ -24,7 +23,6 @@ private class TestScheme : Scheme() { companion object : SchemeSpec(::TestScheme) } -@OptIn(ExperimentalCoroutinesApi::class) internal class VisionPropertyTest { private val manager = Global.request(VisionManager) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index af54bd75..e1410752 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -194,7 +194,7 @@ internal fun FormData.toMeta(): Meta { } internal val formVisionRenderer: ElementVisionRenderer = - ElementVisionRenderer { visionName, vision, _ -> + ElementVisionRenderer { _, vision, _ -> val form = document.getElementById(vision.formId) as? HTMLFormElement ?: error("An element with id = '${vision.formId} is not a form") From 595512959c4e358a0eb86d11f24f104bd0284013 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 5 Dec 2023 16:39:15 +0300 Subject: [PATCH 112/112] DataForge 0.7.1 and other version updates --- build.gradle.kts | 4 +- .../visionforge/gdml/GDMLVisionTest.kt | 2 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 2 +- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../bootstrap/visionPropertyEditor.kt | 2 +- ui/compose/build.gradle.kts | 3 +- .../visionforge/compose/PropertyEditor.kt | 5 +-- .../visionforge/compose/valueChooser.kt | 4 +- .../visionforge/react/PropertyEditor.kt | 7 ++-- .../visionforge/react/RangeValueChooser.kt | 4 +- .../space/kscience/visionforge/StyleSheet.kt | 6 +-- .../space/kscience/visionforge/Vision.kt | 4 +- .../kscience/visionforge/VisionProperties.kt | 42 +++++++++---------- .../kscience/visionforge/flowProperty.kt | 4 +- .../space/kscience/visionforge/useProperty.kt | 4 +- .../visionforge/meta/VisionPropertyTest.kt | 6 +-- .../visionforge/ElementVisionRenderer.kt | 4 +- .../kscience/visionforge/JsVisionClient.kt | 2 +- visionforge-plotly/build.gradle.kts | 2 +- .../visionforge/plotly/VisionOfPlotly.kt | 8 ++-- .../visionforge/server/VisionServer.kt | 2 +- .../kscience/visionforge/solid/Composite.kt | 2 +- .../kscience/visionforge/solid/Extruded.kt | 2 +- .../space/kscience/visionforge/solid/Solid.kt | 2 +- .../visionforge/solid/SolidMaterial.kt | 8 ++-- .../visionforge/solid/SolidReference.kt | 6 +-- .../kscience/visionforge/solid/Surface.kt | 2 +- .../kscience/visionforge/solid/geometry.kt | 6 +-- .../solid/transform/RemoveSingleChild.kt | 2 +- visionforge-tables/build.gradle.kts | 2 +- .../visionforge/tables/VisionOfTableTest.kt | 3 +- .../visionforge/solid/three/ThreeFactory.kt | 4 +- .../solid/three/ThreeLineFactory.kt | 2 +- .../visionforge/solid/three/ThreeMaterials.kt | 12 +++--- .../solid/three/ThreeMeshFactory.kt | 2 +- 36 files changed, 88 insertions(+), 88 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 2da86b96..b578696d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,12 +7,12 @@ plugins { // id("org.jetbrains.kotlinx.kover") version "0.5.0" } -val dataforgeVersion by extra("0.6.2") +val dataforgeVersion by extra("0.7.1") val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-16" + version = "0.3.0-dev-17" } subprojects { diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index ba9cb333..6ade4ec8 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -34,6 +34,6 @@ class GDMLVisionTest { val child = cubes[Name.of("composite-000","segment-0")] assertNotNull(child) child.properties.setValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) - assertEquals("red", child.properties.getMeta(SolidMaterial.MATERIAL_COLOR_KEY).string) + assertEquals("red", child.properties[SolidMaterial.MATERIAL_COLOR_KEY].string) } } \ No newline at end of file diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 7f7958b9..34b750e9 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -71,7 +71,7 @@ class Model(val manager: VisionManager) { fun reset() { map.values.forEach { - it.properties.setMeta(SolidMaterial.MATERIAL_COLOR_KEY, null) + it.properties[SolidMaterial.MATERIAL_COLOR_KEY] = null } tracks.children.clear() } diff --git a/gradle.properties b/gradle.properties index 9413b93e..4e33feb5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ org.gradle.jvmargs=-Xmx4G org.jetbrains.compose.experimental.jscanvas.enabled=true -toolsVersion=0.15.0-kotlin-1.9.20 +toolsVersion=0.15.2-kotlin-1.9.21 #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e411586a..a5952066 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index 8e7e1208..8264ae43 100644 --- a/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -29,7 +29,7 @@ public fun RBuilder.visionPropertyEditor( this.descriptor = descriptor this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") this.getPropertyState = { name -> - val ownMeta = vision.properties.own?.getMeta(name) + val ownMeta = vision.properties.own?.get(name) if (ownMeta != null && !ownMeta.isEmpty()) { EditorPropertyState.Defined } else if (vision.properties.root().getValue(name) != null) { diff --git a/ui/compose/build.gradle.kts b/ui/compose/build.gradle.kts index a2f2c4a7..f77c8e26 100644 --- a/ui/compose/build.gradle.kts +++ b/ui/compose/build.gradle.kts @@ -1,7 +1,8 @@ plugins { id("space.kscience.gradle.mpp") - id("org.jetbrains.compose") version "1.5.10" + alias(spclibs.plugins.compose) +// id("org.jetbrains.compose") version "1.5.11" // id("com.android.library") } diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt index d919cd77..0892b9af 100644 --- a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt @@ -17,9 +17,8 @@ import org.jetbrains.compose.web.dom.Text import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.ObservableMutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.ValueRequirement +import space.kscience.dataforge.meta.descriptors.ValueRestriction import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.remove import space.kscience.dataforge.names.* import space.kscience.visionforge.hidden @@ -104,7 +103,7 @@ public fun PropertyEditor( Text(token) } - if (!name.isEmpty() && descriptor?.valueRequirement != ValueRequirement.ABSENT) { + if (!name.isEmpty() && descriptor?.valueRestriction != ValueRestriction.ABSENT) { Div({ style { width(160.px) diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt index 0be879ad..b6aefee7 100644 --- a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt @@ -16,7 +16,7 @@ import org.w3c.dom.HTMLOptionElement import org.w3c.dom.asList import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.ValueRequirement +import space.kscience.dataforge.meta.descriptors.ValueRestriction import space.kscience.dataforge.meta.descriptors.allowedValues import space.kscience.visionforge.Colors import space.kscience.visionforge.widgetType @@ -199,7 +199,7 @@ public fun RangeValueChooser( FlexRow { - if (descriptor?.valueRequirement != ValueRequirement.REQUIRED) { + if (descriptor?.valueRestriction != ValueRestriction.REQUIRED) { Input(type = InputType.Checkbox) { if (!rangeDisabled) defaultChecked() diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index 58986076..b13e7304 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -16,9 +16,8 @@ import react.dom.attrs import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.ObservableMutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.ValueRequirement +import space.kscience.dataforge.meta.descriptors.ValueRestriction import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.remove import space.kscience.dataforge.names.* import space.kscience.visionforge.hidden @@ -146,7 +145,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } +token } - if (!props.name.isEmpty() && descriptor?.valueRequirement != ValueRequirement.ABSENT) { + if (!props.name.isEmpty() && descriptor?.valueRestriction != ValueRestriction.ABSENT) { styledDiv { css { //+TreeStyles.resizeableInput @@ -185,7 +184,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } +"\u00D7" attrs { - if (editorPropertyState!= EditorPropertyState.Defined) { + if (editorPropertyState != EditorPropertyState.Defined) { disabled = true } else { onClickFunction = removeClick diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index 4a82a6e9..bec34fc1 100644 --- a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -12,7 +12,7 @@ import react.dom.attrs import react.fc import react.useState import space.kscience.dataforge.meta.asValue -import space.kscience.dataforge.meta.descriptors.ValueRequirement +import space.kscience.dataforge.meta.descriptors.ValueRestriction import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.string @@ -43,7 +43,7 @@ public val RangeValueChooser: FC = fc("RangeValueChooser") { } flexRow { - if (props.descriptor?.valueRequirement != ValueRequirement.REQUIRED) { + if (props.descriptor?.valueRestriction != ValueRestriction.REQUIRED) { styledInput(type = InputType.checkBox) { attrs { defaultChecked = rangeDisabled.not() diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 00213644..ed893162 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline @JvmInline public value class StyleSheet(private val owner: Vision) { - private val styleNode: Meta get() = owner.properties.getMeta(STYLESHEET_KEY) + private val styleNode: Meta get() = owner.properties[STYLESHEET_KEY] public val items: Map get() = styleNode.items @@ -23,7 +23,7 @@ public value class StyleSheet(private val owner: Vision) { * Define a style without notifying owner */ public fun define(key: String, style: Meta?) { - owner.properties.setMeta(STYLESHEET_KEY + key, style) + owner.properties[STYLESHEET_KEY + key] = style } /** @@ -92,7 +92,7 @@ public fun Vision.useStyle(name: String, notify: Boolean = true) { * Resolve a style with given name for given [Vision]. The style is not necessarily applied to this [Vision]. */ public fun Vision.getStyle(name: String): Meta? = - properties.own?.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) + properties.own?.get(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) /** * Resolve a property from all styles diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 29965944..78f917a9 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -10,7 +10,7 @@ import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.descriptors.Described import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.misc.Type +import space.kscience.dataforge.misc.DfType import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties @@ -19,7 +19,7 @@ import space.kscience.visionforge.Vision.Companion.TYPE /** * A root type for display hierarchy */ -@Type(TYPE) +@DfType(TYPE) public interface Vision : Described { /** diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index dfb06b50..3c375c62 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -34,13 +34,13 @@ public interface VisionProperties : MetaProvider { * @param inherit toggles parent node property lookup. Null means inference from descriptor. * @param includeStyles toggles inclusion of properties from styles. */ - public fun getMeta( + public fun get( name: Name, inherit: Boolean?, includeStyles: Boolean? = null, ): Meta - override fun getMeta(name: Name): Meta? = getMeta(name, null, null) + override fun get(name: Name): Meta? = get(name, null, null) public val changes: Flow @@ -54,7 +54,7 @@ public interface VisionProperties : MetaProvider { public interface MutableVisionProperties : VisionProperties, MutableMetaProvider { - override fun getMeta( + override fun get( name: Name, inherit: Boolean?, includeStyles: Boolean?, @@ -65,7 +65,7 @@ public interface MutableVisionProperties : VisionProperties, MutableMetaProvider includeStyles, ) - public fun setMeta( + public fun set( name: Name, node: Meta?, notify: Boolean, @@ -77,10 +77,10 @@ public interface MutableVisionProperties : VisionProperties, MutableMetaProvider notify: Boolean, ) - override fun getMeta(name: Name): MutableMeta = getMeta(name, null, null) + override fun get(name: Name): MutableMeta = get(name, null, null) - override fun setMeta(name: Name, node: Meta?) { - setMeta(name, node, true) + override fun set(name: Name, node: Meta?) { + set(name, node, true) } override fun setValue(name: Name, value: Value?) { @@ -89,7 +89,7 @@ public interface MutableVisionProperties : VisionProperties, MutableMetaProvider } public fun MutableVisionProperties.remove(name: Name) { - setMeta(name, null) + set(name, null) } public fun MutableVisionProperties.remove(name: String) { @@ -114,7 +114,7 @@ private class VisionPropertiesItem( override val items: Map get() { - val metaKeys = properties.own?.getMeta(nodeName)?.items?.keys ?: emptySet() + val metaKeys = properties.own?.get(nodeName)?.items?.keys ?: emptySet() val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet() val defaultKeys = default?.get(nodeName)?.items?.keys ?: emptySet() val inheritFlag = descriptor?.inherited ?: inherit @@ -148,8 +148,8 @@ private class VisionPropertiesItem( default ) - override fun setMeta(name: Name, node: Meta?) { - properties.setMeta(nodeName + name, node) + override fun set(name: Name, node: Meta?) { + properties[nodeName + name] = node } override fun toString(): String = Meta.toString(this) @@ -202,16 +202,16 @@ public abstract class AbstractVisionProperties( return descriptor?.defaultValue } - override fun setMeta(name: Name, node: Meta?, notify: Boolean) { + override fun set(name: Name, node: Meta?, notify: Boolean) { //ignore if the value is the same as existing - if (own?.getMeta(name) == node) return + if (own?.get(name) == node) return if (name.isEmpty()) { properties = node?.asMutableMeta() } else if (node == null) { - properties?.setMeta(name, node) + properties?.set(name, node) } else { - getOrCreateProperties().setMeta(name, node) + getOrCreateProperties()[name] = node } if (notify) { invalidate(name) @@ -223,7 +223,7 @@ public abstract class AbstractVisionProperties( if (own?.getValue(name) == value) return if (value == null) { - properties?.getMeta(name)?.value = null + properties?.get(name)?.value = null } else { getOrCreateProperties().setValue(name, value) } @@ -272,11 +272,11 @@ public fun VisionProperties.getValue( /** * Get [Vision] property using key as a String */ -public fun VisionProperties.getMeta( +public fun VisionProperties.get( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, -): Meta = getMeta(name.parseAsName(), inherit, includeStyles) +): Meta = get(name.parseAsName(), inherit, includeStyles) /** * The root property node with given inheritance and style flags @@ -286,17 +286,17 @@ public fun VisionProperties.getMeta( public fun MutableVisionProperties.root( inherit: Boolean? = null, includeStyles: Boolean? = null, -): MutableMeta = getMeta(Name.EMPTY, inherit, includeStyles) +): MutableMeta = get(Name.EMPTY, inherit, includeStyles) /** * Get [Vision] property using key as a String */ -public fun MutableVisionProperties.getMeta( +public fun MutableVisionProperties.get( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, -): MutableMeta = getMeta(name.parseAsName(), inherit, includeStyles) +): MutableMeta = get(name.parseAsName(), inherit, includeStyles) // //public operator fun MutableVisionProperties.set(name: Name, value: Number): Unit = diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt index f8d128e1..60c39c20 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt @@ -17,10 +17,10 @@ public fun Vision.flowProperty( includeStyles: Boolean? = null, ): Flow = flow { //Pass initial value. - emit(properties.getMeta(propertyName, inherit, includeStyles)) + emit(properties.get(propertyName, inherit, includeStyles)) properties.changes.collect { name -> if (name.startsWith(propertyName)) { - emit(properties.getMeta(propertyName, inherit, includeStyles)) + emit(properties.get(propertyName, inherit, includeStyles)) } } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt index cee3a002..8ffb272a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt @@ -23,10 +23,10 @@ public fun Vision.useProperty( callback: (Meta) -> Unit, ): Job { //Pass initial value. - callback(properties.getMeta(propertyName, inherit, includeStyles)) + callback(properties.get(propertyName, inherit, includeStyles)) return properties.changes.onEach { name -> if (name.startsWith(propertyName)) { - callback(properties.getMeta(propertyName, inherit, includeStyles)) + callback(properties.get(propertyName, inherit, includeStyles)) } }.launchIn(scope ?: error("Orphan Vision can't observe properties")) } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 38abe34c..b1ca970a 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -40,7 +40,7 @@ internal class VisionPropertyTest { @Test fun testPropertyEdit() { val vision = manager.group() - vision.properties.getMeta("fff.ddd").apply { + vision.properties.get("fff.ddd").apply { value = 2.asValue() } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) @@ -50,7 +50,7 @@ internal class VisionPropertyTest { @Test fun testPropertyUpdate() { val vision = manager.group() - vision.properties.getMeta("fff").updateWith(TestScheme) { + vision.properties.get("fff").updateWith(TestScheme) { ddd = 2 } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) @@ -85,7 +85,7 @@ internal class VisionPropertyTest { child.properties.remove("test") - assertEquals(11, child.properties.getMeta("test", inherit = true).int) + assertEquals(11, child.properties.get("test", inherit = true).int) // assertEquals(11, deferred.await()?.int) // assertEquals(2, callCounter) subscription.cancel() diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt index 8842e08e..8e1254d9 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt @@ -9,8 +9,8 @@ import kotlinx.serialization.serializerOrNull import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.misc.DfType import space.kscience.dataforge.misc.Named -import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.parseAsName @@ -20,7 +20,7 @@ import kotlin.reflect.cast /** * A browser renderer for a [Vision]. */ -@Type(ElementVisionRenderer.TYPE) +@DfType(ElementVisionRenderer.TYPE) public interface ElementVisionRenderer : Named { /** diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index 6ae70280..17958f97 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -161,7 +161,7 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { //launch backward property propagation vision.properties.changes.onEach { propertyName: Name -> - changeCollector.propertyChanged(visionName, propertyName, vision.properties.getMeta(propertyName)) + changeCollector.propertyChanged(visionName, propertyName, vision.properties[propertyName]) }.launchIn(this) //aggregate atomic changes diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index 9d313266..c4df8593 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -val plotlyVersion = "0.6.0" +val plotlyVersion = "0.6.1" kscience { jvm() diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index d5333dda..19d98171 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -33,8 +33,8 @@ public class VisionOfPlotly private constructor( @Transient override val properties: MutableVisionProperties = object : MutableVisionProperties { - override fun setMeta(name: Name, node: Meta?, notify: Boolean) { - meta.setMeta(name, node) + override fun set(name: Name, node: Meta?, notify: Boolean) { + meta[name] = node } override fun setValue(name: Name, value: Value?, notify: Boolean) { @@ -45,11 +45,11 @@ public class VisionOfPlotly private constructor( override val descriptor: MetaDescriptor? get() = this@VisionOfPlotly.descriptor - override fun getMeta( + override fun get( name: Name, inherit: Boolean?, includeStyles: Boolean?, - ): MutableMeta = meta.getMeta(name) ?: MutableMeta() + ): MutableMeta = meta[name] ?: MutableMeta() override fun getValue( name: Name, diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 4c5e093a..3c5e397a 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -32,7 +32,7 @@ import kotlin.time.Duration.Companion.milliseconds public class VisionRoute( public val route: String, public val visionManager: VisionManager, - override val meta: ObservableMutableMeta = MutableMeta(), + override val meta: ObservableMutableMeta = ObservableMutableMeta(), ) : Configurable, ContextAware { public enum class Mode { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index 3cc6ff61..3ae6a681 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -39,7 +39,7 @@ public inline fun MutableVisionContainer.composite( } val res = Composite(type, children[0], children[1]) - res.properties.setMeta(Name.EMPTY, group.properties.own) + res.properties[Name.EMPTY] = group.properties.own setChild(name, res) return res diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 8276722e..c2157480 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -92,7 +92,7 @@ public class Extruded( } internal fun build(): Extruded = Extruded(shape, layers).apply { - this.properties.setMeta(Name.EMPTY, this@Builder.properties) + this.properties[Name.EMPTY] = this@Builder.properties } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index a42427da..aab583a0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -190,7 +190,7 @@ internal fun float32Vector( override fun setValue(thisRef: Solid, property: KProperty<*>, value: Float32Vector3D?) { if (value == null) { - thisRef.properties.setMeta(name, null) + thisRef.properties[name] = null } else { thisRef.properties[name + X_KEY] = value.x thisRef.properties[name + Y_KEY] = value.y diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index 40857b14..c411cf4c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -110,12 +110,12 @@ public val Solid.color: ColorAccessor get() = ColorAccessor(properties.root(true), MATERIAL_COLOR_KEY) public var Solid.material: SolidMaterial? - get() = SolidMaterial.read(properties.getMeta(MATERIAL_KEY)) - set(value) = properties.setMeta(MATERIAL_KEY, value?.meta) + get() = SolidMaterial.read(properties[MATERIAL_KEY]) + set(value) = properties.set(MATERIAL_KEY, value?.meta) @VisionBuilder public fun Solid.material(builder: SolidMaterial.() -> Unit) { - properties.getMeta(MATERIAL_KEY).updateWith(SolidMaterial, builder) + properties[MATERIAL_KEY].updateWith(SolidMaterial, builder) } public var Solid.opacity: Number? @@ -128,5 +128,5 @@ public var Solid.opacity: Number? @VisionBuilder public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { properties[SolidMaterial.EDGES_ENABLED_KEY] = enabled - SolidMaterial.write(properties.getMeta(SolidMaterial.EDGES_MATERIAL_KEY)).apply(block) + SolidMaterial.write(properties[SolidMaterial.EDGES_MATERIAL_KEY]).apply(block) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 32e69520..b832865c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -162,7 +162,7 @@ internal class SolidReferenceChild( override val properties: MutableVisionProperties = object : MutableVisionProperties { override val descriptor: MetaDescriptor get() = this@SolidReferenceChild.descriptor - override val own: MutableMeta by lazy { owner.properties.getMeta(childToken(childName).asName()) } + override val own: MutableMeta by lazy { owner.properties[childToken(childName).asName()] } override fun getValue( name: Name, @@ -170,8 +170,8 @@ internal class SolidReferenceChild( includeStyles: Boolean?, ): Value? = own.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) - override fun setMeta(name: Name, node: Meta?, notify: Boolean) { - own.setMeta(name, node) + override fun set(name: Name, node: Meta?, notify: Boolean) { + own[name] = node } override fun setValue(name: Name, value: Value?, notify: Boolean) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt index 35f9b75f..cf442c62 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt @@ -155,7 +155,7 @@ public class Surface( } internal fun build(): Surface = Surface(layers).apply { - properties.setMeta(Name.EMPTY, this@Builder.properties) + properties[Name.EMPTY] = this@Builder.properties } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt index 58c3021d..8f799f2e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt @@ -36,9 +36,9 @@ internal fun Meta.toVector2D(): Float32Vector2D = //} internal fun MetaProvider.point3D(default: Float = 0f) = Float32Euclidean3DSpace.vector( - getMeta(X_KEY).float ?: default, - getMeta(Y_KEY).float ?: default, - getMeta(Z_KEY).float ?: default + get(X_KEY).float ?: default, + get(Y_KEY).float ?: default, + get(Z_KEY).float ?: default ) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index cdc9caaf..bcf3baa9 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -19,7 +19,7 @@ internal fun Solid.updateFrom(other: Solid): Solid { scaleX *= other.scaleX scaleY *= other.scaleY scaleZ *= other.scaleZ - properties.setMeta(Name.EMPTY, other.properties.root()) + properties[Name.EMPTY] = other.properties.root() return this } diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index 33988cf0..f4197864 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -val tablesVersion = "0.2.1" +val tablesVersion = "0.3.0" kscience { jvm() diff --git a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt index e1210ffa..def7017b 100644 --- a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt +++ b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt @@ -6,6 +6,7 @@ import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.int import space.kscience.tables.ColumnHeader import space.kscience.tables.ColumnTable +import space.kscience.tables.fill import space.kscience.tables.get import kotlin.math.pow import kotlin.test.Test @@ -18,7 +19,7 @@ internal class VisionOfTableTest { val y by ColumnHeader.typed() val table = ColumnTable(100) { - x.fill { it.asValue() } + fill(x, null) { it.asValue() } y.values = x.values.map { it?.double?.pow(2)?.asValue() } } diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index 122a2c30..09b81053 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -1,6 +1,6 @@ package space.kscience.visionforge.solid.three -import space.kscience.dataforge.misc.Type +import space.kscience.dataforge.misc.DfType import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.Vision @@ -17,7 +17,7 @@ import kotlin.reflect.KClass /** * Builder and updater for three.js object */ -@Type(TYPE) +@DfType(TYPE) public interface ThreeFactory { public val type: KClass diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index 42722254..68bfd7b2 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -24,7 +24,7 @@ public object ThreeLineFactory : ThreeFactory { } val material = ThreeMaterials.getLineMaterial( - vision.properties.getMeta(SolidMaterial.MATERIAL_KEY), + vision.properties[SolidMaterial.MATERIAL_KEY], false ) diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 49667c8e..8e1b2e3f 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -83,7 +83,7 @@ public object ThreeMaterials { private val visionMaterialCache = HashMap() internal fun cacheMaterial(vision: Vision): Material = visionMaterialCache.getOrPut(vision) { - buildMaterial(vision.properties.getMeta(SolidMaterial.MATERIAL_KEY)).apply { + buildMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]).apply { cached = true } } @@ -133,11 +133,11 @@ public fun Mesh.setMaterial(vision: Vision) { } else { material = vision.parent?.let { parent -> //TODO cache parent material - ThreeMaterials.buildMaterial(parent.properties.getMeta(SolidMaterial.MATERIAL_KEY)) + ThreeMaterials.buildMaterial(parent.properties[SolidMaterial.MATERIAL_KEY]) } ?: ThreeMaterials.cacheMaterial(vision) } } else { - material = ThreeMaterials.buildMaterial(vision.properties.getMeta(SolidMaterial.MATERIAL_KEY)) + material = ThreeMaterials.buildMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]) } } @@ -153,18 +153,18 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { when (propertyName) { SolidMaterial.MATERIAL_COLOR_KEY -> { material.asDynamic().color = - vision.properties.getMeta(SolidMaterial.MATERIAL_COLOR_KEY).threeColor() + vision.properties[SolidMaterial.MATERIAL_COLOR_KEY].threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.SPECULAR_COLOR_KEY -> { material.asDynamic().specular = - vision.properties.getMeta(SolidMaterial.SPECULAR_COLOR_KEY).threeColor() + vision.properties[SolidMaterial.SPECULAR_COLOR_KEY].threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { - material.asDynamic().emissive = vision.properties.getMeta(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY) + material.asDynamic().emissive = vision.properties[SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY] .threeColor() ?: ThreeMaterials.BLACK_COLOR } diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index 4ba19998..2e5fc0ca 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -76,7 +76,7 @@ public fun Mesh.applyEdges(vision: Solid) { val edges = children.find { it.name == EDGES_OBJECT_NAME } as? LineSegments //inherited edges definition, enabled by default if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = false)?.boolean != false) { - val material = ThreeMaterials.getLineMaterial(vision.properties.getMeta(EDGES_MATERIAL_KEY), true) + val material = ThreeMaterials.getLineMaterial(vision.properties[EDGES_MATERIAL_KEY], true) if (edges == null) { add( LineSegments(