Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typescript issues #8898

Closed
jony89 opened this issue Jun 2, 2020 · 3 comments · Fixed by #8904
Closed

typescript issues #8898

jony89 opened this issue Jun 2, 2020 · 3 comments · Fixed by #8904

Comments

@jony89
Copy link
Contributor

jony89 commented Jun 2, 2020

Regard the new version 1.70 which should officially support TypeScript,

all results properties should be optional

example, if geodesic is instance of EllipsoidGeodesic the following :

geodesic.interpolateUsingSurfaceDistance(distance);

yields error :

error TS2554: Expected 2 arguments, but got 1.

we should be able to pass Color to prop that is a Property

new PolylineDashMaterialProperty({
  color: Color.WHITE,
});

yields the error :

error TS2322: Type 'Color' is not assignable to type 'Property'.

should not we support direct assign ?

if polyline is instance of PolylineGraphic the following :

polyline.width = 12;

yields the error :

error TS2322: Type '12' is not assignable to type 'Property'.

There are many examples of this.

There are now two cesium Typescript definitions

TypeScript community is using https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/cesium. why wouldn't we update the definition there instead of creating two definitions for cesium?

ATM, cesium 1.70 could break projects TypeScript definition, since cesium lib definition takes over the @types/cesium

@mramato

@OmarShehata
Copy link
Contributor

Thanks for bringing up these issues @jony89. For this:

ATM, cesium 1.70 could break projects TypeScript definition, since cesium lib definition takes over the @types/cesium

You can continue to use your own as Matt mentions in this blog post:

If you’re using your own custom definitions or @types/cesium and you’re not yet ready to switch, you can delete Source/Cesium.d.ts after install. TypeScript tooling will then fall back to the next set of CesiumJS type definitions that it finds.

@jony89
Copy link
Contributor Author

jony89 commented Jun 2, 2020

switch, you can delete Source/Cesium.d.ts after install.

I really should not touch node_modules at all. it's generally bad and will make me write some script for the CI process.

@mramato
Copy link
Contributor

mramato commented Jun 2, 2020

@jony89 thank you for taking the time to write up this issue and provide feedback and bug reports!

all results properties should be optional

For EllipsoidGeodesic.interpolateUsingSurfaceDistance, this is true and a bug in our code (technically in the JSDoc annotations). I will open a PR to fix it. However, this is not true for Cesium's API in general, we have a lot of required result parameters.

we should be able to pass Color to prop that is a Property

Absolutely. This is another issue that I will open a PR to fix. We did this for all of the XXXGraphics types, but missed it for these properties.

should not we support direct assign ?

This is an unfortunate limitation of TypeScript.

polyline.width = 12;

needs to be

polyline.width = new ConstantProperty(12);

Here's why: Cesium mimics a capability from C# known as implicit conversion. Basically the internal type of all Entity API properties is Property, but CesiumJS allows you to assign a primitive type and internally it will automatically turn this into a ConstantProperty (for constant values). Even if plain JavaScript where polyline.width = 12 works, typeof polyline.width will not be a number because polyline.width is actually instanceof ConstantProperty. We would love to be able to make the TypeScript type of the setter to be Property|number and the getter to be Property, but TypeScript specifically disallows this. Lots of people have complained about this and I think the closest issue on the TS side is here: microsoft/TypeScript#2521

We want to play by the TS rules as much as possible and make the definition match whatever we would have done if we were writing TS directly. We are looking at ways of turning Property into a generic, but I don't think we'll even be able to make polyline.width = 12 work without the TS compiler adding new features.

TypeScript community is using https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/cesium. why wouldn't we update the definition there instead of creating two definitions for cesium?

At least some of the developers that support @types/cesium also contribute to Cesium and they are all part of the cesium community. Since TypeScript is now officially supported and maintained, it is much easier to keep everything in the cesium repository. It allows us to maintain high quality definitions with as little friction as possible and make sure as Cesium changes, the TS types change in lock step. We also reached out to some of the maintainers of @types/cesium to make sure they could provide feedback to the process and they are welcome to contribute to the new definitions. We did not want to try to "take over" the existing project, but our goal is to make the official TypeScript definitions the best ones available and we fully expect that at some point @types/cesium will be deprecated.

ATM, cesium 1.70 could break projects TypeScript definition, since cesium lib definition takes over the @types/cesium

As @OmarShehata mentioned, deleting the file is one easy way to ensure it isn't used, which you can do with a prepare or postinstall step as part of your build scripts. However, I looked up alternative ways as well. I should have been a little less lazy and included them in the blog and CHANGES.

If you want to continue to use @types/cesium or a custom typings file, you can add the below to your tsconfig.json's compilerOptions settings.

"paths": {
  "cesium": ["node_modules/@types/cesium"]
}

Basically this overrides the types field in the cesium module and points to whatever types you want to use.

Thanks again for your feedback. I'll keep this issue open until the actionable items (the definition issues you brought up) are fixed, hopefully later today.

mramato added a commit that referenced this issue Jun 3, 2020
All of the MaterialProperty constructors take primitive types in addition
to Property instances (and automatically wrap the primitive type in a
`ConstantProperty`).  The JSDoc was incorrect on this leading to sub-par
TS type definitions. Also fixed a missing optional result parameter in
the JSDoc for `EllipsoidGeodesic.interpolateUsingSurfaceDistance`.

Fixes #8898
katSchmid added a commit to PropellerAero/cesium that referenced this issue Jun 24, 2020
* Add translucency rectangle to sandcastle example [skip ci]

* Account for primitive restart value.

* No const in ES5.

* Simplify skinning to always expect VEC4 joint/weight accessors.

* Changed code mirror viewport margin to Infinity for improved search

* Moves changes to 1.70

* Remove unused imports.

* Fix variable and semantic names.

* Added frustumSplits option to DebugCameraPrimitive

* updated CHANGES.md

* Added GlobeTranslucencyState

* Fixed ground primitives in orthographic mode

* Changed czm_writeDepthClampedToFarPlane to czm_writeDepthClamp and czm_depthClampFarPlane to czm_depthClamp

* Add cjs extension to prettier configuration

I was modifying gulpfile in another branch and realized formatting was
not set up correctly.

* Fixed depth plane for orthographic

* updated CHANGES.md

* Made orthographic depth plane aligned to camera and fixed multifrustum ray ellipsoid intersection

* made common variable for camera

* Fixed derived commands

* Remove invisible translucency state to support classification on invisible surfaces

* Fix picking in 2D

* Use better image for sandcastle [skip ci]

* Don't do depth only shader if clipping planes are enabled [skip ci]

* Updated unit tests

* Fix a typo

* Fix a typo

* Render full sky atmosphere when globe is hidden

* Add per-fragment atmosphere, improve per-vertex atmosphere

* Update CHANGES.md

* Fix tests

* Add underground color

* Add getters/setters, Sandcastle, tests

* Update CHANGES.md

* Fix CHANGES.md [skip ci]

* Added nightAlpha and dayAlpha in the ImageryLayer

* Updated CONTRIBUTORS.md

* CHANGES.md updated

* Added night textures showcase to the Sandcastle

* typo

* Switch to two-pass classification

* Updates from review

* Tweak atmosphere under ellipsoid so it's less bright

* Fix tests

* removed old comment [skip ci]

* Distance relative to globe surface

* Rename undergroundColorByDistance to undergroundColorAlphaByDistance

* Updates from review

* Doc [skip ci]

* Render underground when clipping planes or cartographic limit are being used

* Add czm_backFacing

* Only render ground atmosphere for front faces

* Show back faces in cartogrphic limit rectangle sandcastle

* Fix camera height uniform

* Temp

* Align ellipsoid geometry to camera

* Default perFragmentAtmosphere to false

* Support #rgba and #rrggbbaa in Color.fromCssColorString

* Updates from review

* Same blueness everywhere

* Improve alpha

* Tweak brightness by fade distance

* Revert ground atmosphere change to fix issues when zoomed out really far

* Updates from review

* Remove old intersection code

* Fix lighting crash

* Tweak strength to prevent ring artifact in enableLighting mode

* Turn off globe lighting in demo

* Reorder ifdef's

* Reorder updateFrameState

* Added GlobeTranslucency to group translucency options

* Fix test

* Remove frameState from update function

* Premultiply alpha for ground polylines

* Fix tests

* Fix translucencyEnabled not applying when base color alpha is < 1.0

* Define constant once

* Add back translucency gradient to sky atmosphere

* Add define for globe translucency to SkyAtmosphereCommon

* Sky atmosphere fix to not use camera height when intersecting the ellipsoid

* some tweaks to day/night blending

* Generate official TypeScript type definitions

It's been a long requested feature for us to have official TypeScript type
definitions.  While the community has done a yeoman's job of manually
supporting various efforts, the most recent incarnation of which is
`@types/cesium`, the sheer scale and ever-evolving nature of Cesium's code
base makes manual maintenance a Sisyphean task.

Thankfully, our decision to maintain meticulous JSDoc API documentation
continues to pay dividends and is what makes automatically generating
TypeScript definitions possible. Using the excellent
https://github.com/englercj/tsd-jsdoc project we can now automatically
generate and even partially validate official definitions as part of the
build process. (Thanks to @bampakoa who contributed some early PRs to both
CesiumJS and tsd-jsdoc over a year ago and is how I learned about
tsd-jsdoc)

While tsd-jsdoc output is mostly where we need it to be, we do
post-processing on it as well. This lets us clean up the output and also
make sure these definitions work whether users include cesium via module,
i.e. `import { Cartesian3 } from 'cesium'`, or individual files, i.e.
`'import Cartesian3 from 'cesium/Source/Core/Cartesian3'`. There were also
some quirks of tsd-jsdoc output we fixed that may eventually turn into a PR
into that project from us. The post-processing is part typescript compiler
API, part string manipulation. It works and is straightforward but we might
want to go full TS api in the future if we decide we need to do more
complicated tasks. The output of tsd-jsdoc is currently a little noisy
because of some incorrect error reporting, but I'm talking with the
maintainer in englercj/tsd-jsdoc#133 to get them
fixed. No need to hold up this PR for it though.

The definition is generated as a single `Cesium.d.ts` file in Source, so it
lives alongside Cesium.js. It is ignored by git but generated by a separate
`build-ts` task as part of CI and makeZipFile. This task also validates the
file by compiling it with TypeScript, so if a developer does anything too
egregious, the build will fail. Definitions are automatically included in
our npm packages and release zips and will be automatically used by IDEs
thanks to the `types` setting in package.json. This means that IDEs such as
VS Code will prefer these types over the existing `@types/cesium` version
by default.

I didn't want to slow the `build` step down, so I made this a separate
step, but in the future we could consider running it by default and we
could also unignore this file in Git so that PR reviewers can see the
impact, if any, our code changes have on the generated definitions. This
might be a good idea as an additional sanity check and should only actually
change when the public API itself changes. But the issue would be
remembering to run it before submitting the code (or we could use git hooks
I suppose?) I just don't want to slow down devs so I'm hesitant to do
anything like this out of the gate. We can definitely revisit in the
future.

A particular exciting thing about this approach is that it exposed a ton of
badness in our current JSDoc markup, which is now fixed. Previously, our
only concern was "does the doc look right" and we didn't pay attention to
whether the meta information generated by JSDoc correctly captured type
information (because up until it didn't matter). We leaned particular hard
on `@exports` which acted as a catch-all but has now been completely
removed from the codebase. All this means is that our documentation as a
whole has now improved greatly and will continue to be maintained at this
new higher level thanks to incorporating TS definition creation into our
pipeline!

One minor caveat here is that obviously we changed our JSDoc usage to both
make it correct and also accommodate TypeScript. The main drawback to these
fixes is that enums are now generated as globals in the doc, rather than
modules. This means they no longer have their own dedicated page and are
instead on the globals page, but I changed the code to ensure they are
still in the table of contents that we generate. I think this trade-off is
perfectly fine, but I wanted to mention it since it does change the doc
some. We can certainly look into whether we can generate enums on their own
page if we think that makes sense. (I actually like this approach a little
better personally).

Last major piece, the actual code. 99% of the changes in this PR only
affect the JSDoc. There are two exceptions:

A few of our enums also have private functions tacked onto them. I had to
move these functions to be outside the initializer but otherwise they are
unchanged.  This ensures that a valid TS enum is generated from our code, since you can't have functions globbed onto enums in the TS world. If we were writing TS code by hand, we could use  declaration merging with a namespace, but the toolchain we are using doesn't have a way to express that right now.  There were two cases where these extra functions weren't private, `ComponentDataType` and `IndexDataType`. That means that as far as the TS definitions goes, the helper methods don't exist.  I consder this an edge case and we can write up issues to investigate later.  I'm actually not even sure if these functions are public on purposes, @lilleyse can you confirm?

We had a few places where we had method signatures with optional parameters
that came _before_ required parameters, which is silly. This is invalid
TypeScript (and not good API design no matter the language). In 99% of
cases this was `equalsEpsilon` style functions where the lhs/rhs were
optional but the epsilon was not. I remember the discussion around this
when we first did it because we were paranoid about defaulting to 0, but
it's an edge case and it's silly so I just changed the epsilon functions
to default to zero now, problem solved.

Here's a high level summary of the JS changes:

* Use proper `@enum` notation instead of `@exports` for enums.

* Use proper `@namespace` instead of `@exports` for static classes.

* Use proper `@function` instead of `@exports` for standalone functions.

* Fix `Promise` markup to actually include the type in all cases, i.e.
`Promise` => `Promise<void>` or `Promise<Cartesian3[]>`.

* Fix bad markup that referenced types that do not exist (or no longer
exist) at the spec level, `Image` => `HTMLImageElement`,
`Canvas` => `HTMLCanvasElement`, etc.. `TypedArray` in particular does not
exist and much be expressed as a lsit of all applicable types,
`Int8Array|Uint8Array|Int16Array|Uint16Array...`.

* Use dot notation instead of tilde in callbacks, to better support
TypeScript, i.e. `EasingFunction~Callback` becomes
`EasingFunction.Callback`. The only exception is when we had a callback
type that was i.e. `exportKml~ModelCallback` becomes
`exportKmlModelCallback` (a module global type rather than a type on
exportKml). This is because it's not possible to have exportKml be both a
function and a namespace in this current toolchain.  Not a big deal either
way since these are meta-types used for defining callbacks but I wanted to
mention it.

* There were some edge cases where private types that were referenced in
the public API but don't exist in the JSDoc. These were trivial to fix by
either tweaking the JSDoc to avoid leaking the type or in some cases, just
as `PixelDataType`, simply exposing the private type as public.  I also
found a few cases where things were accidentally public, I marked these as
private (these were extreme edge cases so I'm not concerned about breaking
changes). Appearances took an optional `RenderState` in their options, I
just changed the type to `Object` which we can clean up further later if
we need to.

* Lots of other little misc JSDoc issues that became obvious once we
started to generate definitions (duplicate parameters for example).

Thanks again to the community for helping generate ideas and discussions
around TS definitions over the last few years and a big thanks to @javagl
for helping behind the scenes on this specific effort by evaluating a few
different approaches and workaround before we settled on this one (I'm
working on a blog with all of the gory details for those interested).

Finally, while I'm thrilled with how this turned out (all ~41000 lines
and 1.9MB of it), I can guarantee we will uncover some issues with the
type definitions as more people use it. The good news is that improving it
is now just a matter of fixing the JSDoc, which will benefit the community
as a whole and not just TS users.


Fixes CesiumGS#2730
Fixes CesiumGS#5717

* Don't hardcode ./node_modules/tsd-jsdoc

It may be different in some environments. Instead, just use the normal module name, which will be resolved according to node's module resolution rules.

* Use tsconfig.json to avoid errors in some environments.

* Add new Sandcastle example.

* Add back a "Proxy" type.

Since master documented a `Proxy` base class, create it rather than using
`DefaultProxy` everywhere.

* Add missing `update` function to all DataSource implementations

Allows them to be assignable to `DataSource` in the TS definitions.

* Minor tweak to doc and Sandcastle

* JSDoc fixes to GregorianDate and TimeIntervalCollection

* Fix JSDoc for exportKml

* Additional JSDoc/TypeScript fixes.

* Make IonImageryProvider actually implement all ImageryProvider properties

* More TypeScript fixes

1. Make Matrix 2/3/4 ArrayLike objects

2. Make PropertyBag include a string indexor so that it is a dictionary
like object. We do this by making up a new private interface and defining
it only in the definition file. JSDoc ignores it in the HTML output.

* Update CHANGES

Fix bad commit.

* Number[] -> number[] in TS definition

Add workaround for englercj/tsd-jsdoc#117

* Fix Event.raiseEvent TS generation.

* Add missing availability property to TerrainProvider classes.

* Whoops

* More JSDoc fixes and TS improvements

1. Resource has incorrect return types.
2. Improve formatting of TS definition file.

* Don't abuse EllipsoidTerrainProvider.

* Lots of small changes to improve the typescript definitions.

* Give up on trying JSDoc tags for PropertyBag

* Example of exporting ConstructorOptions interface

* Break out constructor options: Entity and Graphics

* Various small type fixes

* Selected/tracked entity can be undefined

* First pass at generic Events

* Constructor interfaces for ImageryProviders

* Load-method option interfaces for some DataSources

* Options interfaces for Viewer, Resource

* CesiumGS#8843 Clear Request cancelFunction and deferred references to free up unintentional retained request data memory

* CesiumGS#8843 Add comments

* CesiumGS#8843 Update comment

* Add CONTRIBUTORS entry

* Use function overloading for exportKml

* Update CHANGES.md

* Update CesiumSandcastle.js

* Spell out docs for Resource.QueryParameter

* Undo some changes

* Add ConstructorOptions to the rest of the ImageryProviders

* Workaround CesiumMath -> Math documentation issue

* Fix doc links that include a hash.

* Improve camera controls when underground

* Update CHANGES, tweak doc, and add test.

* Fix UrlTemplateImageryProvider

Also opt-in tsd-jsdoc so we can use @template in the future.

* More fixes found by Kevin.

* Tweak CHANGES related to TypeScript

* Remove hardcoded node_modules in gulpfile.

1. Use `npx` to execute binaries rather than hardcoded `node_modules/.bin`,
which may not always be the right location.

2. Streamline generateDocumentation by calling it sync.

* Update CHANGES to make underground visualization more prominent

* Fix doc using @member instead of @memberof

* Removed duplicate CHANGES.md line

* Add Cesium OSM Buildings note in CHANGES

* Add Sandcastle link [ci skip]

* Fix typo [ci skip]

* fixed flipy issue

* updated CHANGES.md

* added myself to CONTRIBUTORS.md

* added tests for flipY function

* Fixed Bing Maps Road option in sandcastle example

* removed extra whitespace line

* fix gulp build error

* Added Navagis to CONTRIBUTORS.md

* updated tokens, version, and changes.md

* Fix variable naming in fog sandcastle

* Add toString method for Resource class

* Tests for Resource#toString

* Use explicit cast

* Improve JSDoc/TypeScript support for Material properties

All of the MaterialProperty constructors take primitive types in addition
to Property instances (and automatically wrap the primitive type in a
`ConstantProperty`).  The JSDoc was incorrect on this leading to sub-par
TS type definitions. Also fixed a missing optional result parameter in
the JSDoc for `EllipsoidGeodesic.interpolateUsingSurfaceDistance`.

Fixes CesiumGS#8898

* Update CHANGES

Add another missing optional result fix.

* Update CHANGES for cancelled request memory leak fix

* Add additional smokescreen to build-ts

1. Add a Specs/TypeScript directory with a minimal TS configuration that
uses the d.ts files generated by build-ts

2. Have `build-ts` compile index.ts from this directory which makes sure
various types actually conform to their expected interfaces.

3. Fix ImageryProvider interfaces which had issues exposed by this new
test.

In the future we can add any additional smokescreens that we think are
important to validate our definitions going forward, but this will never
be a fully exhaustive check.

We currently don't actually execute the output, it's just there for
compile-time checking.  We can revisit this if we ever feel that it's
needed.

* Update CHANGES

* Add missing property typs to TypeScript smokescreen

* Other minor TS improvements.

* Make sure all nullable Entity API properties are marked as such.

* Most ImageryProvider properties can be undefined.

* Fix missing HeadingPitchRoll/HeadingPitchRange JSDoc

* Missing `|undefined` in GoogleEarthEnterpriseMapsProvider

* Missing JSDoc

* change cesiumScriptRegex value

fixes Issue CesiumGS#8902

* Expose buildModuleUrl as part of the Cesium API

It's been used in Sandcastle examples forever, but has always been marked
as private in jsdoc. In order to make it available in TypeScript, we need
to expose it.

Also cleaned up the doc to be more inline with what the current version
actually does.

Fixes CesiumGS#8922

* add more test

add CesiumSomething test

* Correcting Navagis Corporate Link

* Two small JSDoc/TS fixes

1. `EllipsoidTangentPlane.fromPoints` takes an array.
2. `EntityCollection.getById` and `CompositeEntityCollection.getById` can
both return undefined.

* Fix whitespace

* Update CHANGES.

Also fix missing links from previous PRs

* Add some missing readonly documentation tags

* Add false as a possible value for skyBox and SkyAtmosphere

* CesiumGS#8927: Exposing Transforms.rotationMatrixFromPositionVelocity; Adding tests for Transforms.rotationMatrixFromPositionVelocity

* CesiumGS#8927: Adding message for exposing Transforms.rotationMatrixFromPositionVelocity to CHANGES.md

* CesiumGS#8927: Running prettier on new rotationMatrixFromPositionVelocity tests

* Only include Source folder in TypeScript smokescreen tests.

We were including all Cesium directories in the TypeScript smokescreen
configuration. This meant that multiple Cesium.d.ts files were included
if you did a full build and then ran `build-ts` afterwards. This updates
the config used by the smokescreen to only include Source.

* Improve base url regex, add additional test.

* CesiumGS#8927: Simplifed rotationMatrixFromPositionVelocity tests

* Fix geometry creation in TypeScript

None of the `XXXGeometry` classes are actually `Geometry` instances. They
are instead utility classes that create geometries via their
`createGeometry` implementation. `GeometryInstance` can take either "type"
but since JS doesn't have types we never really defined what the "utility"
type is, so the TypeScript definition for `GeometryInstance` specifies that
currently only specifies `Geometry`. This means that this valid JS code
is a compiler error in TypeScript

```
const geometryInstance = new GeometryInstance({
  geometry: new PolylineGeometry({
    positions: [],
  }),
});
```

To fix this, I introduced a `GeometryFactory` base class like we have
elsewhere in the code and changed `GeometryInstance` to take either type.
This is the only place where we actually base "non-geometry Geometry" in
the API.

Happy to consider other names, like `GeometryCreator` if we don't like
factory for some reason, but I want to get this in sooner rather than
later for 1.70.1 fixes.

Also fixed an issue with tsconfig.json I introduced in my last change
which was failing to actually catch TS compile errors because it wasn't
including the Cesium.d.ts.

* Update doc/CHANGES

* Bump version and cleanup CHANGES for 1.70.1 release.

* adding release 1.70.1

* add codeship

* make tests runable

* adding propeller code changes back

* more changes form diff

* Correcting ChANGES.md and index.d.ts

Co-authored-by: Matthew Amato <matt.amato@gmail.com>
Co-authored-by: Sean Lilley <lilleyse@gmail.com>
Co-authored-by: Kevin Ring <kevin@kotachrome.com>
Co-authored-by: Ed Mackey <elm19087@gmail.com>
Co-authored-by: Ian Lilley <ianlilleyt@gmail.com>
Co-authored-by: Sam Suhag <sanjeetsuhag@users.noreply.github.com>
Co-authored-by: Sanjeet Suhag <suhagsanjeet@gmail.com>
Co-authored-by: Jakub Vrána <jakub@vrana.cz>
Co-authored-by: Edvinas Pranka <epranka@develop.localhost>
Co-authored-by: Omar Shehata <omar@cesium.com>
Co-authored-by: Omar Shehata <oshehata@agi.com>
Co-authored-by: James Bromwell <943160+thw0rted@users.noreply.github.com>
Co-authored-by: Brandon Nguyen <bnguyen@dignitastechnologies.com>
Co-authored-by: Hannah <hannah@cesium.com>
Co-authored-by: Eli Bogomolny <ebogo@seas.upenn.edu>
Co-authored-by: Peter Gagliardi <ptrgags@gmail.com>
Co-authored-by: Jonathan Nogueira <jontnog@gmail.com>
Co-authored-by: xiaobaogeit <xiaobaogeit@163.com>
Co-authored-by: Jonathan Nogueira <LuminousPath@users.noreply.github.com>
Co-authored-by: Frederic Junod <frederic.junod@camptocamp.com>
Co-authored-by: John Remsberg <john.remsberg@comcast.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants