@loaders.gl/3d-tiles 3.3.0-alpha.3 → 3.3.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.min.js +60 -33
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/lib/parsers/helpers/parse-3d-implicit-tiles.js +2 -0
- package/dist/es5/lib/parsers/helpers/parse-3d-implicit-tiles.js.map +1 -1
- package/dist/es5/lib/parsers/helpers/parse-3d-tile-subtree.js +47 -18
- package/dist/es5/lib/parsers/helpers/parse-3d-tile-subtree.js.map +1 -1
- package/dist/es5/lib/parsers/parse-3d-tile-header.js +153 -69
- package/dist/es5/lib/parsers/parse-3d-tile-header.js.map +1 -1
- package/dist/es5/lib/utils/version.js +1 -1
- package/dist/es5/tiles-3d-loader.js +5 -26
- package/dist/es5/tiles-3d-loader.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/parsers/helpers/parse-3d-implicit-tiles.js +2 -0
- package/dist/esm/lib/parsers/helpers/parse-3d-implicit-tiles.js.map +1 -1
- package/dist/esm/lib/parsers/helpers/parse-3d-tile-subtree.js +28 -7
- package/dist/esm/lib/parsers/helpers/parse-3d-tile-subtree.js.map +1 -1
- package/dist/esm/lib/parsers/parse-3d-tile-header.js +38 -20
- package/dist/esm/lib/parsers/parse-3d-tile-header.js.map +1 -1
- package/dist/esm/lib/utils/version.js +1 -1
- package/dist/esm/tiles-3d-loader.js +2 -9
- package/dist/esm/tiles-3d-loader.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.d.ts.map +1 -1
- package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.js +2 -13
- package/dist/lib/parsers/helpers/parse-3d-tile-subtree.d.ts +2 -1
- package/dist/lib/parsers/helpers/parse-3d-tile-subtree.d.ts.map +1 -1
- package/dist/lib/parsers/helpers/parse-3d-tile-subtree.js +36 -7
- package/dist/lib/parsers/parse-3d-tile-header.d.ts +5 -4
- package/dist/lib/parsers/parse-3d-tile-header.d.ts.map +1 -1
- package/dist/lib/parsers/parse-3d-tile-header.js +37 -18
- package/dist/tiles-3d-loader.d.ts.map +1 -1
- package/dist/tiles-3d-loader.js +1 -8
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +1 -1
- package/src/lib/parsers/helpers/parse-3d-implicit-tiles.ts +2 -14
- package/src/lib/parsers/helpers/parse-3d-tile-subtree.ts +50 -7
- package/src/lib/parsers/parse-3d-tile-header.ts +59 -21
- package/src/tiles-3d-loader.ts +2 -16
- package/src/types.ts +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loaders.gl/3d-tiles",
|
|
3
|
-
"version": "3.3.0-alpha.
|
|
3
|
+
"version": "3.3.0-alpha.5",
|
|
4
4
|
"description": "3D Tiles, an open standard for streaming massive heterogeneous 3D geospatial datasets.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -34,16 +34,16 @@
|
|
|
34
34
|
"build-bundle": "esbuild src/bundle.ts --bundle --outfile=dist/dist.min.js"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@loaders.gl/draco": "3.3.0-alpha.
|
|
38
|
-
"@loaders.gl/gltf": "3.3.0-alpha.
|
|
39
|
-
"@loaders.gl/loader-utils": "3.3.0-alpha.
|
|
40
|
-
"@loaders.gl/math": "3.3.0-alpha.
|
|
41
|
-
"@loaders.gl/tiles": "3.3.0-alpha.
|
|
37
|
+
"@loaders.gl/draco": "3.3.0-alpha.5",
|
|
38
|
+
"@loaders.gl/gltf": "3.3.0-alpha.5",
|
|
39
|
+
"@loaders.gl/loader-utils": "3.3.0-alpha.5",
|
|
40
|
+
"@loaders.gl/math": "3.3.0-alpha.5",
|
|
41
|
+
"@loaders.gl/tiles": "3.3.0-alpha.5",
|
|
42
42
|
"@math.gl/core": "^3.5.1",
|
|
43
43
|
"@math.gl/geospatial": "^3.5.1"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@loaders.gl/core": "^3.2.0"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "d2df3bead97710c45fd2974cd51ecd7d5f7f5ea4"
|
|
49
49
|
}
|
package/src/index.ts
CHANGED
|
@@ -13,4 +13,4 @@ export {default as Tile3DBatchTable} from './lib/classes/tile-3d-batch-table';
|
|
|
13
13
|
// EXPERIMENTAL
|
|
14
14
|
export {TILE3D_TYPE} from './lib/constants';
|
|
15
15
|
export {getIonTilesetMetadata as _getIonTilesetMetadata} from './lib/ion/ion';
|
|
16
|
-
export type {FeatureTableJson, B3DMContent, Node3D} from './types';
|
|
16
|
+
export type {FeatureTableJson, B3DMContent, Node3D, ImplicitTilingExtension} from './types';
|
|
@@ -75,15 +75,6 @@ export async function parseImplicitTiles(params: {
|
|
|
75
75
|
let childTileY = concatBits(parentData.y, childY);
|
|
76
76
|
let childTileZ = concatBits(parentData.z, childZ);
|
|
77
77
|
|
|
78
|
-
// TODO Remove after real implicit tileset will be tested.
|
|
79
|
-
// Degug data
|
|
80
|
-
// tile.level = level + globalData.level;
|
|
81
|
-
// tile.x = concatBits(globalData.x, childTileX);
|
|
82
|
-
// tile.y = concatBits(globalData.y, childTileY);
|
|
83
|
-
// tile.z = concatBits(globalData.z, childTileZ);
|
|
84
|
-
// tile.mortonIndex = childTileMortonIndex;
|
|
85
|
-
// End of debug data
|
|
86
|
-
|
|
87
78
|
let isChildSubtreeAvailable = false;
|
|
88
79
|
|
|
89
80
|
if (level + 1 > subtreeLevels) {
|
|
@@ -211,12 +202,9 @@ function formatTileData(
|
|
|
211
202
|
type: getTileType(tile),
|
|
212
203
|
lodMetricType,
|
|
213
204
|
lodMetricValue,
|
|
205
|
+
geometricError: lodMetricValue,
|
|
206
|
+
transform: tile.transform,
|
|
214
207
|
boundingVolume
|
|
215
|
-
// Temp debug values. Remove when real implicit tileset will be tested.
|
|
216
|
-
// x: tile.x,
|
|
217
|
-
// y: tile.y,
|
|
218
|
-
// z: tile.z,
|
|
219
|
-
// level: tile.level
|
|
220
208
|
};
|
|
221
209
|
}
|
|
222
210
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {Subtree, ExplicitBitstream} from '../../../types';
|
|
2
|
-
import {
|
|
2
|
+
import type {LoaderContext, LoaderOptions} from '@loaders.gl/loader-utils';
|
|
3
3
|
|
|
4
4
|
const SUBTREE_FILE_MAGIC = 0x74627573;
|
|
5
5
|
const SUBTREE_FILE_VERSION = 1;
|
|
@@ -11,7 +11,11 @@ const SUBTREE_FILE_VERSION = 1;
|
|
|
11
11
|
* @returns
|
|
12
12
|
*/
|
|
13
13
|
// eslint-disable-next-line max-statements
|
|
14
|
-
export default async function parse3DTilesSubtree(
|
|
14
|
+
export default async function parse3DTilesSubtree(
|
|
15
|
+
data: ArrayBuffer,
|
|
16
|
+
options: LoaderOptions | undefined,
|
|
17
|
+
context: LoaderContext | undefined
|
|
18
|
+
): Promise<Subtree> {
|
|
15
19
|
const magic = new Uint32Array(data.slice(0, 4));
|
|
16
20
|
|
|
17
21
|
if (magic[0] !== SUBTREE_FILE_MAGIC) {
|
|
@@ -42,7 +46,8 @@ export default async function parse3DTilesSubtree(data: ArrayBuffer): Promise<Su
|
|
|
42
46
|
subtree.tileAvailability.explicitBitstream = await getExplicitBitstream(
|
|
43
47
|
subtree,
|
|
44
48
|
'tileAvailability',
|
|
45
|
-
internalBinaryBuffer
|
|
49
|
+
internalBinaryBuffer,
|
|
50
|
+
context
|
|
46
51
|
);
|
|
47
52
|
}
|
|
48
53
|
|
|
@@ -50,7 +55,8 @@ export default async function parse3DTilesSubtree(data: ArrayBuffer): Promise<Su
|
|
|
50
55
|
subtree.contentAvailability.explicitBitstream = await getExplicitBitstream(
|
|
51
56
|
subtree,
|
|
52
57
|
'contentAvailability',
|
|
53
|
-
internalBinaryBuffer
|
|
58
|
+
internalBinaryBuffer,
|
|
59
|
+
context
|
|
54
60
|
);
|
|
55
61
|
}
|
|
56
62
|
|
|
@@ -58,13 +64,40 @@ export default async function parse3DTilesSubtree(data: ArrayBuffer): Promise<Su
|
|
|
58
64
|
subtree.childSubtreeAvailability.explicitBitstream = await getExplicitBitstream(
|
|
59
65
|
subtree,
|
|
60
66
|
'childSubtreeAvailability',
|
|
61
|
-
internalBinaryBuffer
|
|
67
|
+
internalBinaryBuffer,
|
|
68
|
+
context
|
|
62
69
|
);
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
return subtree;
|
|
66
73
|
}
|
|
67
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Get url for bitstream downloading
|
|
77
|
+
* @param bitstreamRelativeUri
|
|
78
|
+
* @param baseUri
|
|
79
|
+
* @returns
|
|
80
|
+
*/
|
|
81
|
+
function resolveBufferUri(bitstreamRelativeUri: string, basePath: string): string {
|
|
82
|
+
const hasProtocol = basePath.startsWith('http');
|
|
83
|
+
|
|
84
|
+
if (hasProtocol) {
|
|
85
|
+
const resolvedUri = new URL(bitstreamRelativeUri, basePath);
|
|
86
|
+
return decodeURI(resolvedUri.toString());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Adding http protocol only for new URL constructor usage.
|
|
91
|
+
* It allows to resolve relative paths like ../../example with basePath.
|
|
92
|
+
*/
|
|
93
|
+
const basePathWithProtocol = `http://${basePath}`;
|
|
94
|
+
const resolvedUri = new URL(bitstreamRelativeUri, basePathWithProtocol);
|
|
95
|
+
/**
|
|
96
|
+
* Drop protocol and use just relative path.
|
|
97
|
+
*/
|
|
98
|
+
return `/${resolvedUri.host}${resolvedUri.pathname}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
68
101
|
/**
|
|
69
102
|
* Get explicit bitstream for subtree availability data.
|
|
70
103
|
* @param subtree
|
|
@@ -74,15 +107,25 @@ export default async function parse3DTilesSubtree(data: ArrayBuffer): Promise<Su
|
|
|
74
107
|
async function getExplicitBitstream(
|
|
75
108
|
subtree: Subtree,
|
|
76
109
|
name: string,
|
|
77
|
-
internalBinaryBuffer: ArrayBuffer
|
|
110
|
+
internalBinaryBuffer: ArrayBuffer,
|
|
111
|
+
context: LoaderContext | undefined
|
|
78
112
|
): Promise<ExplicitBitstream> {
|
|
79
113
|
const bufferViewIndex = subtree[name].bufferView;
|
|
80
114
|
const bufferView = subtree.bufferViews[bufferViewIndex];
|
|
81
115
|
const buffer = subtree.buffers[bufferView.buffer];
|
|
82
116
|
|
|
117
|
+
if (!context?.url || !context.fetch) {
|
|
118
|
+
throw new Error('Url is not provided');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!context.fetch) {
|
|
122
|
+
throw new Error('fetch is not provided');
|
|
123
|
+
}
|
|
124
|
+
|
|
83
125
|
// External bitstream loading
|
|
84
126
|
if (buffer.uri) {
|
|
85
|
-
const
|
|
127
|
+
const bufferUri = resolveBufferUri(buffer.uri, context?.url);
|
|
128
|
+
const response = await context.fetch(bufferUri);
|
|
86
129
|
const data = await response.arrayBuffer();
|
|
87
130
|
// Return view of bitstream.
|
|
88
131
|
return new Uint8Array(data, bufferView.byteOffset, bufferView.byteLength);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type {LoaderOptions} from '@loaders.gl/loader-utils';
|
|
1
2
|
import {Tile3DSubtreeLoader} from '../../tile-3d-subtree-loader';
|
|
2
3
|
import {load} from '@loaders.gl/core';
|
|
3
|
-
import {Tileset3D, LOD_METRIC_TYPE, TILE_REFINEMENT, TILE_TYPE} from '@loaders.gl/tiles';
|
|
4
|
-
import {Subtree} from '../../types';
|
|
4
|
+
import {Tileset3D, LOD_METRIC_TYPE, TILE_REFINEMENT, TILE_TYPE, Tile3D} from '@loaders.gl/tiles';
|
|
5
|
+
import {ImplicitTilingExtension, Subtree} from '../../types';
|
|
5
6
|
import {parseImplicitTiles, replaceContentUrlTemplate} from './helpers/parse-3d-implicit-tiles';
|
|
6
7
|
|
|
7
8
|
function getTileType(tile) {
|
|
@@ -70,9 +71,24 @@ export function normalizeTileData(tile, options) {
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
// normalize tile headers
|
|
73
|
-
export function normalizeTileHeaders(
|
|
74
|
+
export async function normalizeTileHeaders(
|
|
75
|
+
tileset: Tileset3D,
|
|
76
|
+
options: LoaderOptions
|
|
77
|
+
): Promise<Tileset3D> {
|
|
74
78
|
const basePath = tileset.basePath;
|
|
75
|
-
|
|
79
|
+
let root: Tileset3D;
|
|
80
|
+
|
|
81
|
+
const rootImplicitTilingExtension = getImplicitTilingExtensionData(tileset?.root);
|
|
82
|
+
if (rootImplicitTilingExtension && tileset.root) {
|
|
83
|
+
root = await normalizeImplicitTileHeaders(
|
|
84
|
+
tileset.root,
|
|
85
|
+
tileset,
|
|
86
|
+
rootImplicitTilingExtension,
|
|
87
|
+
options
|
|
88
|
+
);
|
|
89
|
+
} else {
|
|
90
|
+
root = normalizeTileData(tileset.root, tileset);
|
|
91
|
+
}
|
|
76
92
|
|
|
77
93
|
const stack: any[] = [];
|
|
78
94
|
stack.push(root);
|
|
@@ -80,8 +96,19 @@ export function normalizeTileHeaders(tileset) {
|
|
|
80
96
|
while (stack.length > 0) {
|
|
81
97
|
const tile = stack.pop() || {};
|
|
82
98
|
const children = tile.children || [];
|
|
83
|
-
for (
|
|
84
|
-
|
|
99
|
+
for (let childHeader of children) {
|
|
100
|
+
const childImplicitTilingExtension = getImplicitTilingExtensionData(childHeader);
|
|
101
|
+
if (childImplicitTilingExtension) {
|
|
102
|
+
childHeader = await normalizeImplicitTileHeaders(
|
|
103
|
+
childHeader,
|
|
104
|
+
tileset,
|
|
105
|
+
childImplicitTilingExtension,
|
|
106
|
+
options
|
|
107
|
+
);
|
|
108
|
+
} else {
|
|
109
|
+
normalizeTileData(childHeader, {basePath});
|
|
110
|
+
}
|
|
111
|
+
|
|
85
112
|
stack.push(childHeader);
|
|
86
113
|
}
|
|
87
114
|
}
|
|
@@ -94,29 +121,29 @@ export function normalizeTileHeaders(tileset) {
|
|
|
94
121
|
* TODO Check if Tile3D class can be a return type here.
|
|
95
122
|
* @param tileset
|
|
96
123
|
*/
|
|
97
|
-
export async function normalizeImplicitTileHeaders(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
124
|
+
export async function normalizeImplicitTileHeaders(
|
|
125
|
+
tile: Tile3D,
|
|
126
|
+
tileset: Tileset3D,
|
|
127
|
+
implicitTilingExtension: ImplicitTilingExtension,
|
|
128
|
+
options: LoaderOptions
|
|
129
|
+
) {
|
|
102
130
|
const basePath = tileset.basePath;
|
|
103
|
-
const implicitTilingExtension = tileset.root.extensions['3DTILES_implicit_tiling'];
|
|
104
131
|
const {
|
|
105
132
|
subdivisionScheme,
|
|
106
133
|
maximumLevel,
|
|
107
134
|
subtreeLevels,
|
|
108
135
|
subtrees: {uri: subtreesUriTemplate}
|
|
109
136
|
} = implicitTilingExtension;
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
const contentUrlTemplate = resolveUri(
|
|
114
|
-
const refine = tileset
|
|
137
|
+
const replacedUrlTemplate = replaceContentUrlTemplate(subtreesUriTemplate, 0, 0, 0, 0);
|
|
138
|
+
const subtreeUrl = resolveUri(replacedUrlTemplate, basePath);
|
|
139
|
+
const subtree = await load(subtreeUrl, Tile3DSubtreeLoader, options);
|
|
140
|
+
const contentUrlTemplate = resolveUri(tile.content.uri, basePath);
|
|
141
|
+
const refine = tileset?.root?.refine;
|
|
115
142
|
// @ts-ignore
|
|
116
|
-
const rootLodMetricValue =
|
|
117
|
-
const rootBoundingVolume =
|
|
143
|
+
const rootLodMetricValue = tile.geometricError;
|
|
144
|
+
const rootBoundingVolume = tile.boundingVolume;
|
|
118
145
|
|
|
119
|
-
const
|
|
146
|
+
const implicitOptions = {
|
|
120
147
|
contentUrlTemplate,
|
|
121
148
|
subtreesUriTemplate,
|
|
122
149
|
subdivisionScheme,
|
|
@@ -131,7 +158,7 @@ export async function normalizeImplicitTileHeaders(tileset: Tileset3D) {
|
|
|
131
158
|
getRefine
|
|
132
159
|
};
|
|
133
160
|
|
|
134
|
-
return await normalizeImplicitTileData(
|
|
161
|
+
return await normalizeImplicitTileData(tile, subtree, implicitOptions);
|
|
135
162
|
}
|
|
136
163
|
|
|
137
164
|
/**
|
|
@@ -164,3 +191,14 @@ export async function normalizeImplicitTileData(tile, rootSubtree: Subtree, opti
|
|
|
164
191
|
|
|
165
192
|
return tile;
|
|
166
193
|
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Implicit Tiling data can be in 3DTILES_implicit_tiling for 3DTiles v.Next or directly in implicitTiling object for 3DTiles v1.1.
|
|
197
|
+
* Spec 3DTiles v.Next - https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_implicit_tiling
|
|
198
|
+
* Spec 3DTiles v.1.1 - https://github.com/CesiumGS/3d-tiles/tree/draft-1.1/specification/ImplicitTiling
|
|
199
|
+
* @param tile
|
|
200
|
+
* @returns
|
|
201
|
+
*/
|
|
202
|
+
function getImplicitTilingExtensionData(tile: Tile3D | null): ImplicitTilingExtension {
|
|
203
|
+
return tile?.extensions?.['3DTILES_implicit_tiling'] || tile?.implicitTiling;
|
|
204
|
+
}
|
package/src/tiles-3d-loader.ts
CHANGED
|
@@ -3,12 +3,7 @@ import {path} from '@loaders.gl/loader-utils';
|
|
|
3
3
|
import {TILESET_TYPE, LOD_METRIC_TYPE} from '@loaders.gl/tiles';
|
|
4
4
|
import {VERSION} from './lib/utils/version';
|
|
5
5
|
import {parse3DTile} from './lib/parsers/parse-3d-tile';
|
|
6
|
-
import {
|
|
7
|
-
normalizeTileHeaders,
|
|
8
|
-
normalizeImplicitTileHeaders
|
|
9
|
-
} from './lib/parsers/parse-3d-tile-header';
|
|
10
|
-
|
|
11
|
-
const IMPLICIT_TILING_EXTENSION_NAME = '3DTILES_implicit_tiling';
|
|
6
|
+
import {normalizeTileHeaders} from './lib/parsers/parse-3d-tile-header';
|
|
12
7
|
|
|
13
8
|
/**
|
|
14
9
|
* Loader for 3D Tiles
|
|
@@ -54,9 +49,7 @@ async function parseTileset(data, options, context) {
|
|
|
54
49
|
tilesetJson.url = context.url;
|
|
55
50
|
// base path that non-absolute paths in tileset are relative to.
|
|
56
51
|
tilesetJson.basePath = getBaseUri(tilesetJson);
|
|
57
|
-
tilesetJson.root =
|
|
58
|
-
? await normalizeImplicitTileHeaders(tilesetJson)
|
|
59
|
-
: normalizeTileHeaders(tilesetJson);
|
|
52
|
+
tilesetJson.root = await normalizeTileHeaders(tilesetJson, options);
|
|
60
53
|
|
|
61
54
|
tilesetJson.type = TILESET_TYPE.TILES3D;
|
|
62
55
|
|
|
@@ -84,10 +77,3 @@ async function parse(data, options, context) {
|
|
|
84
77
|
|
|
85
78
|
return data;
|
|
86
79
|
}
|
|
87
|
-
|
|
88
|
-
function hasImplicitTilingExtension(tilesetJson) {
|
|
89
|
-
return (
|
|
90
|
-
tilesetJson?.extensionsRequired?.includes(IMPLICIT_TILING_EXTENSION_NAME) &&
|
|
91
|
-
tilesetJson?.extensionsUsed?.includes(IMPLICIT_TILING_EXTENSION_NAME)
|
|
92
|
-
);
|
|
93
|
-
}
|
package/src/types.ts
CHANGED
|
@@ -88,3 +88,18 @@ type BufferView = {
|
|
|
88
88
|
byteOffset: number;
|
|
89
89
|
byteLength: number;
|
|
90
90
|
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Spec - https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_implicit_tiling
|
|
94
|
+
*/
|
|
95
|
+
export type ImplicitTilingExtension = {
|
|
96
|
+
subdivisionScheme: 'QUADTREE' | 'OCTREE';
|
|
97
|
+
maximumLevel?: number;
|
|
98
|
+
availableLevels: number;
|
|
99
|
+
subtreeLevels: number;
|
|
100
|
+
subtrees: SubtreeUri;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
type SubtreeUri = {
|
|
104
|
+
uri: string;
|
|
105
|
+
};
|