From 9d17f0da7dae9a6d4fcc2d3af8512e634361d210 Mon Sep 17 00:00:00 2001 From: mrmaxm Date: Thu, 7 Mar 2024 13:20:21 +0200 Subject: [PATCH] Bundles Refactor (#5675) * wip * Bundles refactor * fix jsdoc * @internal > @ignore * PR comments * engine-only example for bundle loading * update bundle example to new examples format * edits based on PR review comments * lint, fix * events docs * lazy initialize TextDecoder * example update * linter --------- Co-authored-by: KPal <48248865+kpal81xd@users.noreply.github.com> --- examples/assets/bundles/bundle.tar | Bin 0 -> 88576 bytes examples/bundle.tar | Bin 0 -> 88576 bytes .../src/examples/loaders/bundle/config.mjs | 6 + .../src/examples/loaders/bundle/example.mjs | 116 +++++ src/core/event-handle.js | 2 +- src/framework/asset/asset-registry.js | 84 +++- src/framework/asset/asset.js | 9 +- src/framework/bundle/bundle-registry.js | 340 +++++++------ src/framework/bundle/bundle.js | 95 +++- src/framework/handlers/binary.js | 11 +- src/framework/handlers/bundle.js | 81 ++- src/framework/handlers/css.js | 20 +- src/framework/handlers/html.js | 20 +- src/framework/handlers/json.js | 20 +- src/framework/handlers/loader.js | 54 +- src/framework/handlers/shader.js | 20 +- src/framework/handlers/template.js | 21 +- src/framework/handlers/text.js | 20 +- src/framework/handlers/untar.js | 472 ++++++------------ tests/framework/bundles/test_bundle_loader.js | 280 +++++++---- .../framework/bundles/test_bundle_registry.js | 161 +----- tests/test-assets/bundles/bundle.tar | Bin 0 -> 216576 bytes tests/test-assets/bundles/bundle.tar.gz | Bin 32636 -> 0 bytes tests/test-assets/bundles/css.css | 3 + 24 files changed, 998 insertions(+), 837 deletions(-) create mode 100644 examples/assets/bundles/bundle.tar create mode 100644 examples/bundle.tar create mode 100644 examples/src/examples/loaders/bundle/config.mjs create mode 100644 examples/src/examples/loaders/bundle/example.mjs create mode 100644 tests/test-assets/bundles/bundle.tar delete mode 100644 tests/test-assets/bundles/bundle.tar.gz create mode 100644 tests/test-assets/bundles/css.css diff --git a/examples/assets/bundles/bundle.tar b/examples/assets/bundles/bundle.tar new file mode 100644 index 0000000000000000000000000000000000000000..99b1d1d53eb3e2619bb5c70631cf286cb5d4536f GIT binary patch literal 88576 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 app.resizeCanvas(); +window.addEventListener('resize', resize); +app.on('destroy', () => { + window.removeEventListener('resize', resize); +}); + +// load assets +// notice that scene and torus are loaded as blob's and only tar file is downloaded +const assetListLoader = new pc.AssetListLoader(Object.values(assets), app.assets); +assetListLoader.load(() => { + + app.start(); + + /** + * the array will store loaded cameras + * @type {pc.CameraComponent[]} + */ + let camerasComponents = null; + + // glb lights use physical units + app.scene.physicalUnits = true; + + // create an instance using render component + const entity = assets.scene.resource.instantiateRenderEntity(); + app.root.addChild(entity); + + // create an instance using render component + const entityTorus = assets.torus.resource.instantiateRenderEntity(); + app.root.addChild(entityTorus); + entityTorus.setLocalPosition(0, 0, 2); + + // find all cameras - by default they are disabled + camerasComponents = entity.findComponents("camera"); + camerasComponents.forEach((component) => { + + // set the aspect ratio to automatic to work with any window size + component.aspectRatioMode = pc.ASPECT_AUTO; + + // set up exposure for physical units + component.aperture = 4; + component.shutter = 1 / 100; + component.sensitivity = 500; + }); + + /** @type {pc.LightComponent[]} */ + const lightComponents = entity.findComponents("light"); + lightComponents.forEach((component) => { + component.enabled = true; + }); + + let time = 0; + let activeCamera = 0; + app.on("update", function (dt) { + time -= dt; + + entityTorus.rotateLocal(360 * dt, 0, 0); + + // change the camera every few seconds + if (time <= 0) { + time = 2; + + // disable current camera + camerasComponents[activeCamera].enabled = false; + + // activate next camera + activeCamera = (activeCamera + 1) % camerasComponents.length; + camerasComponents[activeCamera].enabled = true; + } + }); +}); + +export { app }; diff --git a/src/core/event-handle.js b/src/core/event-handle.js index 1f5ce4068fa..a2a07cb6bdc 100644 --- a/src/core/event-handle.js +++ b/src/core/event-handle.js @@ -97,7 +97,7 @@ class EventHandle { /** * Mark if event has been removed. * @type {boolean} - * @internal + * @ignore */ set removed(value) { if (!value) return; diff --git a/src/framework/asset/asset-registry.js b/src/framework/asset/asset-registry.js index 0fcddca94e9..3383cbcb471 100644 --- a/src/framework/asset/asset-registry.js +++ b/src/framework/asset/asset-registry.js @@ -26,6 +26,14 @@ import { Asset } from './asset.js'; * @param {Asset} [asset] - The loaded asset if no errors were encountered. */ +/** + * Callback used by {@link ResourceLoader#load} and called when an asset is choosing a bundle + * to load from. Return a single bundle to ensure asset is loaded from it. + * + * @callback BundlesFilterCallback + * @param {import('../bundle/bundle.js').Bundle[]} bundles - List of bundles which contain the asset. + */ + /** * Container for all assets that are available to this application. Note that PlayCanvas scripts * are provided with an AssetRegistry instance as `app.assets`. @@ -189,6 +197,13 @@ class AssetRegistry extends EventHandler { */ prefix = null; + /** + * BundleRegistry + * + * @type {import('../bundle/bundle-registry.js').BundleRegistry|null} + */ + bundles = null; + /** * Create an instance of an AssetRegistry. * @@ -335,6 +350,15 @@ class AssetRegistry extends EventHandler { * out when it is loaded. * * @param {Asset} asset - The asset to load. + * @param {object} [options] - Options for asset loading. + * @param {boolean} [options.bundlesIgnore] - If set to true, then asset will not try to load + * from a bundle. Defaults to false. + * @param {boolean} [options.force] - If set to true, then the check of asset being loaded or + * is already loaded is bypassed, which forces loading of asset regardless. + * @param {BundlesFilterCallback} [options.bundlesFilter] - A callback that will be called + * when loading an asset that is contained in any of the bundles. It provides an array of + * bundles and will ensure asset is loaded from bundle returned from a callback. By default + * smallest filesize bundle is choosen. * @example * // load some assets * const assetsToLoad = [ @@ -352,16 +376,24 @@ class AssetRegistry extends EventHandler { * app.assets.load(assetToLoad); * }); */ - load(asset) { + load(asset, options) { // do nothing if asset is already loaded // note: lots of code calls assets.load() assuming this check is present // don't remove it without updating calls to assets.load() with checks for the asset.loaded state - if (asset.loading || asset.loaded) { + if ((asset.loading || asset.loaded) && !options?.force) { return; } const file = asset.file; + const _fireLoad = () => { + this.fire('load', asset); + this.fire('load:' + asset.id, asset); + if (file && file.url) + this.fire('load:url:' + file.url, asset); + asset.fire('load', asset); + }; + // open has completed on the resource const _opened = (resource) => { if (resource instanceof Array) { @@ -373,11 +405,28 @@ class AssetRegistry extends EventHandler { // let handler patch the resource this._loader.patch(asset, this); - this.fire('load', asset); - this.fire('load:' + asset.id, asset); - if (file && file.url) - this.fire('load:url:' + file.url, asset); - asset.fire('load', asset); + if (asset.type === 'bundle') { + const assetIds = asset.data.assets; + for (let i = 0; i < assetIds.length; i++) { + const assetInBundle = this._idToAsset.get(assetIds[i]); + if (assetInBundle && !assetInBundle.loaded) { + this.load(assetInBundle, { force: true }); + } + } + + if (asset.resource.loaded) { + _fireLoad(); + } else { + this.fire('load:start', asset); + this.fire('load:start:' + asset.id, asset); + if (file && file.url) + this.fire('load:start:url:' + file.url, asset); + asset.fire('load:start', asset); + asset.resource.on('load', _fireLoad); + } + } else { + _fireLoad(); + } }; // load has completed on the resource @@ -409,7 +458,26 @@ class AssetRegistry extends EventHandler { this.fire('load:' + asset.id + ':start', asset); asset.loading = true; - this._loader.load(asset.getFileUrl(), asset.type, _loaded, asset); + + const fileUrl = asset.getFileUrl(); + + // mark bundle assets as loading + if (asset.type === 'bundle') { + const assetIds = asset.data.assets; + for (let i = 0; i < assetIds.length; i++) { + const assetInBundle = this._idToAsset.get(assetIds[i]); + if (!assetInBundle) + continue; + + if (assetInBundle.loaded || assetInBundle.resource || assetInBundle.loading) + continue; + + assetInBundle.loading = true; + } + } + + + this._loader.load(fileUrl, asset.type, _loaded, asset, options); } else { // asset has no file to load, open it directly const resource = this._loader.open(asset.type, asset.data); diff --git a/src/framework/asset/asset.js b/src/framework/asset/asset.js index 37a360d7652..a68d7fe192e 100644 --- a/src/framework/asset/asset.js +++ b/src/framework/asset/asset.js @@ -133,7 +133,7 @@ class Asset extends EventHandler { * * @param {string} name - A non-unique but human-readable name which can be later used to * retrieve the asset. - * @param {string} type - Type of asset. One of ["animation", "audio", "binary", "container", + * @param {string} type - Type of asset. One of ["animation", "audio", "binary", "bundle", "container", * "cubemap", "css", "font", "json", "html", "material", "model", "script", "shader", "sprite", * "template", text", "texture", "textureatlas"] * @param {object} [file] - Details about the file the asset is made from. At the least must @@ -197,6 +197,8 @@ class Asset extends EventHandler { // This is where the loaded resource(s) will be this._resources = []; + this.urlObject = null; + // a string-assetId dictionary that maps // locale to asset id this._i18n = {}; @@ -533,6 +535,11 @@ class Asset extends EventHandler { const old = this._resources; + if (this.urlObject) { + URL.revokeObjectURL(this.urlObject); + this.urlObject = null; + } + // clear resources on the asset this.resources = []; this.loaded = false; diff --git a/src/framework/bundle/bundle-registry.js b/src/framework/bundle/bundle-registry.js index 6b7d5b7df0d..f215db2f5d9 100644 --- a/src/framework/bundle/bundle-registry.js +++ b/src/framework/bundle/bundle-registry.js @@ -4,6 +4,34 @@ * @ignore */ class BundleRegistry { + /** + * Index of bundle assets. + * @type {Map} + * @private + */ + _idToBundle = new Map(); + + /** + * Index of asset id to set of bundle assets. + * @type {Map>} + * @private + */ + _assetToBundles = new Map(); + + /** + * Index of file url to set of bundle assets. + * @type {Map>} + * @private + */ + _urlsToBundles = new Map(); + + /** + * Index of file request to load callbacks. + * @type {Map} + * @private + */ + _fileRequests = new Map(); + /** * Create a new BundleRegistry instance. * @@ -11,67 +39,58 @@ class BundleRegistry { */ constructor(assets) { this._assets = assets; - - // index of bundle assets - this._bundleAssets = {}; - // index asset id to one more bundle assets - this._assetsInBundles = {}; - // index file urls to one or more bundle assets - this._urlsInBundles = {}; - // contains requests to load file URLs indexed by URL - this._fileRequests = {}; - - this._assets.on('add', this._onAssetAdded, this); - this._assets.on('remove', this._onAssetRemoved, this); + this._assets.bundles = this; + this._assets.on('add', this._onAssetAdd, this); + this._assets.on('remove', this._onAssetRemove, this); } - // Add asset in internal indexes - _onAssetAdded(asset) { + /** + * Called when asset is added to AssetRegistry. + * + * @param {import('../asset/asset.js').Asset} asset - The asset that has been added. + * @private + */ + _onAssetAdd(asset) { // if this is a bundle asset then add it and // index its referenced assets if (asset.type === 'bundle') { - this._bundleAssets[asset.id] = asset; - - this._registerBundleEventListeners(asset.id); - - for (let i = 0, len = asset.data.assets.length; i < len; i++) { - this._indexAssetInBundle(asset.data.assets[i], asset); + this._idToBundle.set(asset.id, asset); + this._assets.on(`load:start:${asset.id}`, this._onBundleLoadStart, this); + this._assets.on(`load:${asset.id}`, this._onBundleLoad, this); + this._assets.on(`error:${asset.id}`, this._onBundleError, this); + + const assetIds = asset.data.assets; + for (let i = 0; i < assetIds.length; i++) { + this._indexAssetInBundle(assetIds[i], asset); } } else { // if this is not a bundle then index its URLs - if (this._assetsInBundles[asset.id]) { + if (this._assetToBundles.has(asset.id)) { this._indexAssetFileUrls(asset); } } } - _registerBundleEventListeners(bundleAssetId) { - this._assets.on('load:' + bundleAssetId, this._onBundleLoaded, this); - this._assets.on('error:' + bundleAssetId, this._onBundleError, this); - } - - _unregisterBundleEventListeners(bundleAssetId) { - this._assets.off('load:' + bundleAssetId, this._onBundleLoaded, this); - this._assets.off('error:' + bundleAssetId, this._onBundleError, this); + _unbindAssetEvents(id) { + this._assets.off('load:start:' + id, this._onBundleLoadStart, this); + this._assets.off('load:' + id, this._onBundleLoad, this); + this._assets.off('error:' + id, this._onBundleError, this); } // Index the specified asset id and its file URLs so that // the registry knows that the asset is in that bundle - _indexAssetInBundle(assetId, bundleAsset) { - if (!this._assetsInBundles[assetId]) { - this._assetsInBundles[assetId] = [bundleAsset]; - } else { - const bundles = this._assetsInBundles[assetId]; - const idx = bundles.indexOf(bundleAsset); - if (idx === -1) { - bundles.push(bundleAsset); - } - } + _indexAssetInBundle(id, bundle) { + let bundles = this._assetToBundles.get(id); - const asset = this._assets.get(assetId); - if (asset) { - this._indexAssetFileUrls(asset); + if (!bundles) { + bundles = new Set(); + this._assetToBundles.set(id, bundles); } + + bundles.add(bundle); + + const asset = this._assets.get(id); + if (asset) this._indexAssetFileUrls(asset); } // Index the file URLs of the specified asset @@ -79,14 +98,10 @@ class BundleRegistry { const urls = this._getAssetFileUrls(asset); if (!urls) return; - for (let i = 0, len = urls.length; i < len; i++) { - const url = urls[i]; - // Just set the URL to point to the same bundles as the asset does. - // This is a performance/memory optimization and it assumes that - // the URL will not exist in any other asset. If that does happen then - // this will not work as expected if the asset is removed, as the URL will - // be removed too. - this._urlsInBundles[url] = this._assetsInBundles[asset.id]; + for (let i = 0; i < urls.length; i++) { + const bundles = this._assetToBundles.get(asset.id); + if (!bundles) continue; + this._urlsToBundles.set(urls[i], bundles); } } @@ -95,7 +110,7 @@ class BundleRegistry { let url = asset.getFileUrl(); if (!url) return null; - url = this._normalizeUrl(url); + url = url.split('?')[0]; const urls = [url]; // a font might have additional files @@ -110,97 +125,96 @@ class BundleRegistry { return urls; } - // Removes query parameters from a URL - _normalizeUrl(url) { - return url && url.split('?')[0]; - } - // Remove asset from internal indexes - _onAssetRemoved(asset) { + _onAssetRemove(asset) { if (asset.type === 'bundle') { // remove bundle from index - delete this._bundleAssets[asset.id]; + this._idToBundle.delete(asset.id); // remove event listeners - this._unregisterBundleEventListeners(asset.id); - - // remove bundle from _assetsInBundles and _urlInBundles indexes - for (const id in this._assetsInBundles) { - const array = this._assetsInBundles[id]; - const idx = array.indexOf(asset); - if (idx !== -1) { - array.splice(idx, 1); - if (!array.length) { - delete this._assetsInBundles[id]; - - // make sure we do not leave that array in - // any _urlInBundles entries - for (const url in this._urlsInBundles) { - if (this._urlsInBundles[url] === array) { - delete this._urlsInBundles[url]; - } - } + this._unbindAssetEvents(asset.id); + + // remove bundle from _assetToBundles and _urlInBundles indexes + const assetIds = asset.data.assets; + for (let i = 0; i < assetIds.length; i++) { + const bundles = this._assetToBundles.get(assetIds[i]); + if (!bundles) continue; + bundles.delete(asset); + + if (bundles.size === 0) { + this._assetToBundles.delete(assetIds[i]); + for (const [url, otherBundles] of this._urlsToBundles) { + if (otherBundles !== bundles) + continue; + this._urlsToBundles.delete(url); } } } // fail any pending requests for this bundle - this._onBundleError(`Bundle ${asset.id} was removed`, asset); + this._onBundleError(`Bundle ${asset.id} was removed`); + } else { + const bundles = this._assetToBundles.get(asset.id); + if (!bundles) return; - } else if (this._assetsInBundles[asset.id]) { - // remove asset from _assetInBundles - delete this._assetsInBundles[asset.id]; + this._assetToBundles.delete(asset.id); - // remove asset urls from _urlsInBundles + // remove asset urls from _urlsToBundles const urls = this._getAssetFileUrls(asset); - for (let i = 0, len = urls.length; i < len; i++) { - delete this._urlsInBundles[urls[i]]; + if (!urls) return; + for (let i = 0; i < urls.length; i++) { + this._urlsToBundles.delete(urls[i]); } } } + _onBundleLoadStart(asset) { + asset.resource.on('add', (url, data) => { + const callbacks = this._fileRequests.get(url); + if (!callbacks) return; + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, data); + } + this._fileRequests.delete(url); + }); + } + // If we have any pending file requests // that can be satisfied by the specified bundle // then resolve them - _onBundleLoaded(bundleAsset) { - // this can happen if the bundleAsset failed + _onBundleLoad(asset) { + // this can happen if the asset failed // to create its resource - if (!bundleAsset.resource) { - this._onBundleError(`Bundle ${bundleAsset.id} failed to load`, bundleAsset); + if (!asset.resource) { + this._onBundleError(`Bundle ${asset.id} failed to load`); return; } - // on next tick resolve the pending asset requests - // don't do it on the same tick because that ties the loading - // of the bundle to the loading of all the assets - requestAnimationFrame(() => { - // make sure the registry hasn't been destroyed already - if (!this._fileRequests) { - return; - } + // make sure the registry hasn't been destroyed already + if (!this._fileRequests) + return; - for (const url in this._fileRequests) { - const bundles = this._urlsInBundles[url]; - if (!bundles || bundles.indexOf(bundleAsset) === -1) continue; + for (const [url, requests] of this._fileRequests) { + const bundles = this._urlsToBundles.get(url); + if (!bundles || !bundles.has(asset)) continue; - const decodedUrl = decodeURIComponent(url); - let err = null; - if (!bundleAsset.resource.hasBlobUrl(decodedUrl)) { - err = `Bundle ${bundleAsset.id} does not contain URL ${url}`; - } + const decodedUrl = decodeURIComponent(url); - const requests = this._fileRequests[url]; - for (let i = 0, len = requests.length; i < len; i++) { - if (err) { - requests[i](err); - } else { - requests[i](null, bundleAsset.resource.getBlobUrl(decodedUrl)); - } - } + let err, data; - delete this._fileRequests[url]; + if (asset.resource.has(decodedUrl)) { + data = asset.resource.get(decodedUrl); + } else if (asset.resource.loaded) { + err = `Bundle ${asset.id} does not contain URL ${url}`; + } else { + continue; } - }); + + for (let i = 0; i < requests.length; i++) { + requests[i](err, err || data); + } + this._fileRequests.delete(url); + } } // If we have outstanding file requests for any @@ -208,17 +222,14 @@ class BundleRegistry { // other bundles that can satisfy these requests. // If we do not find any other bundles then fail // those pending file requests with the specified error. - _onBundleError(err, bundleAsset) { - for (const url in this._fileRequests) { + _onBundleError(err) { + for (const [url, requests] of this._fileRequests) { const bundle = this._findLoadedOrLoadingBundleForUrl(url); if (!bundle) { - const requests = this._fileRequests[url]; - for (let i = 0, len = requests.length; i < len; i++) { + for (let i = 0; i < requests.length; i++) requests[i](err); - } - - delete this._fileRequests[url]; + this._fileRequests.delete(url); } } } @@ -226,52 +237,42 @@ class BundleRegistry { // Finds a bundle that contains the specified URL but // only returns the bundle if it's either loaded or being loaded _findLoadedOrLoadingBundleForUrl(url) { - const bundles = this._urlsInBundles[url]; + const bundles = this._urlsToBundles.get(url); if (!bundles) return null; - // look for loaded bundle first... - const len = bundles.length; - for (let i = 0; i < len; i++) { - // 'loaded' can be true but if there was an error - // then 'resource' would be null - if (bundles[i].loaded && bundles[i].resource) { - return bundles[i]; - } - } + let candidate = null; - // ...then look for loading bundles - for (let i = 0; i < len; i++) { - if (bundles[i].loading) { - return bundles[i]; + for (const bundle of bundles) { + if (bundle.loaded && bundle.resource) { + return bundle; + } else if (bundle.loading) { + candidate = bundle; } } - return null; + return candidate; } /** - * Lists all of the available bundles that reference the specified asset id. + * Lists all of the available bundles that reference the specified asset. * - * @param {import('../asset/asset.js').Asset} asset - The asset. - * @returns {import('../asset/asset.js').Asset[]} An array of bundle assets or null if the + * @param {import('../asset/asset.js').Asset} asset - The asset to search by. + * @returns {import('../asset/asset.js').Asset[]|null} An array of bundle assets or null if the * asset is not in any bundle. */ listBundlesForAsset(asset) { - return this._assetsInBundles[asset.id] || null; + const bundles = this._assetToBundles.get(asset.id); + if (bundles) return Array.from(bundles); + return null; } /** - * Lists all of the available bundles. This includes bundles that are not loaded. + * Lists all bundle assets. * * @returns {import('../asset/asset.js').Asset[]} An array of bundle assets. */ list() { - const result = []; - for (const id in this._bundleAssets) { - result.push(this._bundleAssets[id]); - } - - return result; + return Array.from(this._idToBundle.values()); } /** @@ -281,7 +282,7 @@ class BundleRegistry { * @returns {boolean} True or false. */ hasUrl(url) { - return !!this._urlsInBundles[url]; + return this._urlsToBundles.has(url); } /** @@ -291,7 +292,7 @@ class BundleRegistry { * @param {string} url - The url. * @returns {boolean} True or false. */ - canLoadUrl(url) { + urlIsLoadedOrLoading(url) { return !!this._findLoadedOrLoadingBundleForUrl(url); } @@ -305,8 +306,8 @@ class BundleRegistry { * the second argument is the file blob URL. * @example * const url = asset.getFileUrl().split('?')[0]; // get normalized asset URL - * this.app.bundles.loadFile(url, function (err, blobUrl) { - * // do something with the blob URL + * this.app.bundles.loadFile(url, function (err, data) { + * // do something with the data * }); */ loadUrl(url, callback) { @@ -319,17 +320,22 @@ class BundleRegistry { // Only load files from bundles that're explicitly requested to be loaded. if (bundle.loaded) { const decodedUrl = decodeURIComponent(url); - if (!bundle.resource.hasBlobUrl(decodedUrl)) { + + if (bundle.resource.has(decodedUrl)) { + callback(null, bundle.resource.get(decodedUrl)); + return; + } else if (bundle.resource.loaded) { callback(`Bundle ${bundle.id} does not contain URL ${url}`); return; } + } - callback(null, bundle.resource.getBlobUrl(decodedUrl)); - } else if (this._fileRequests.hasOwnProperty(url)) { - this._fileRequests[url].push(callback); - } else { - this._fileRequests[url] = [callback]; + let callbacks = this._fileRequests.get(url); + if (!callbacks) { + callbacks = []; + this._fileRequests.set(url, callbacks); } + callbacks.push(callback); } /** @@ -337,17 +343,25 @@ class BundleRegistry { * should be unloaded by the {@link AssetRegistry}. */ destroy() { - this._assets.off('add', this._onAssetAdded, this); - this._assets.off('remove', this._onAssetRemoved, this); + this._assets.off('add', this._onAssetAdd, this); + this._assets.off('remove', this._onAssetRemove, this); - for (const id in this._bundleAssets) { - this._unregisterBundleEventListeners(id); + for (const id of this._idToBundle.keys()) { + this._unbindAssetEvents(id); } this._assets = null; - this._bundleAssets = null; - this._assetsInBundles = null; - this._urlsInBundles = null; + + this._idToBundle.clear(); + this._idToBundle = null; + + this._assetToBundles.clear(); + this._assetToBundles = null; + + this._urlsToBundles.clear(); + this._urlsToBundles = null; + + this._fileRequests.clear(); this._fileRequests = null; } } diff --git a/src/framework/bundle/bundle.js b/src/framework/bundle/bundle.js index 0ea05798213..475e3bdc72a 100644 --- a/src/framework/bundle/bundle.js +++ b/src/framework/bundle/bundle.js @@ -1,23 +1,59 @@ +import { EventHandler } from '../../core/event-handler.js'; + /** - * Represents the resource of a Bundle Asset, which contains an index that maps URLs to blob URLs. + * Represents the resource of a Bundle Asset, which contains an index that maps URLs to DataViews. * * @ignore */ -class Bundle { +class Bundle extends EventHandler { + /** + * Index of file url to to DataView. + * @type {Map} + * @private + */ + _index = new Map(); + + /** + * If Bundle has all files loaded. + * @type {boolean} + * @private + */ + _loaded = false; + + /** + * Fired when a file has been added to a Bundle. + * + * @event + * @example + * bundle.on("add", function (url, data) { + * console.log("file added: " + url); + * }); + */ + static EVENT_ADD = 'add'; + /** - * Create a new Bundle instance. + * Fired when all files of a Bundle has been loaded. * - * @param {object[]} files - An array of objects that have a name field and contain a - * getBlobUrl() function. + * @event + * @example + * bundle.on("load", function () { + * console.log("All Bundle files has been loaded"); + * }); */ - constructor(files) { - this._blobUrls = {}; + static EVENT_LOAD = 'load'; - for (let i = 0, len = files.length; i < len; i++) { - if (files[i].url) { - this._blobUrls[files[i].name] = files[i].url; - } - } + /** + * Add file to a Bundle. + * + * @param {string} url - A url of a file. + * @param {DataView} data - A DataView of a file. + * @ignore + */ + addFile(url, data) { + if (this._index.has(url)) + return; + this._index.set(url, data); + this.fire('add', url, data); } /** @@ -27,29 +63,42 @@ class Bundle { * the URL first. * @returns {boolean} True of false. */ - hasBlobUrl(url) { - return !!this._blobUrls[url]; + has(url) { + return this._index.has(url); } /** - * Returns a blob URL for the specified URL. + * Returns a DataView for the specified URL. * * @param {string} url - The original file URL. Make sure you have called decodeURIComponent on * the URL first. - * @returns {string} A blob URL. + * @returns {DataView|null} A DataView. */ - getBlobUrl(url) { - return this._blobUrls[url]; + get(url) { + return this._index.get(url) || null; } /** - * Destroys the bundle and frees up blob URLs. + * Destroys the bundle. */ destroy() { - for (const key in this._blobUrls) { - URL.revokeObjectURL(this._blobUrls[key]); - } - this._blobUrls = null; + this._index.clear(); + } + + /** + * True if all files of a Bundle are loaded. + * @type {boolean} + */ + set loaded(value) { + if (!value || this._loaded) + return; + + this._loaded = true; + this.fire('load'); + } + + get loaded() { + return this._loaded; } } diff --git a/src/framework/handlers/binary.js b/src/framework/handlers/binary.js index ce726608692..9031046e3c7 100644 --- a/src/framework/handlers/binary.js +++ b/src/framework/handlers/binary.js @@ -1,5 +1,4 @@ import { http, Http } from '../../platform/net/http.js'; - import { ResourceHandler } from './handler.js'; class BinaryHandler extends ResourceHandler { @@ -27,6 +26,16 @@ class BinaryHandler extends ResourceHandler { } }); } + + /** + * Parses raw DataView and returns ArrayBuffer. + * + * @param {DataView} data - The raw data as a DataView + * @returns {ArrayBuffer} The parsed resource data. + */ + openBinary(data) { + return data.buffer; + } } export { BinaryHandler }; diff --git a/src/framework/handlers/bundle.js b/src/framework/handlers/bundle.js index 752670360fd..8208f340ee0 100644 --- a/src/framework/handlers/bundle.js +++ b/src/framework/handlers/bundle.js @@ -1,10 +1,6 @@ -import { platform } from '../../core/platform.js'; - -import { http, Http } from '../../platform/net/http.js'; - import { Bundle } from '../bundle/bundle.js'; -import { Untar, UntarWorker } from './untar.js'; - +import { Debug } from '../../core/debug.js'; +import { Untar } from './untar.js'; import { ResourceHandler } from './handler.js'; /** @@ -22,7 +18,7 @@ class BundleHandler extends ResourceHandler { super(app, 'bundle'); this._assets = app.assets; - this._worker = null; + this.maxRetries = 0; } load(url, callback) { @@ -33,55 +29,42 @@ class BundleHandler extends ResourceHandler { }; } - const self = this; + fetch(url.load, { + mode: 'cors', + credentials: 'include' + }).then((res) => { + const bundle = new Bundle(); + callback(null, bundle); - http.get(url.load, { - responseType: Http.ResponseType.ARRAY_BUFFER, - retry: this.maxRetries > 0, - maxRetries: this.maxRetries - }, function (err, response) { - if (!err) { - try { - self._untar(response, callback); - } catch (ex) { - callback('Error loading bundle resource ' + url.original + ': ' + ex); - } - } else { - callback('Error loading bundle resource ' + url.original + ': ' + err); - } - }); - } - - _untar(response, callback) { - const self = this; + const untar = new Untar(res, this._assets.prefix); - // use web workers if available otherwise - // fallback to untar'ing in the main thread - if (platform.workers) { - // create web worker if necessary - if (!self._worker) { - self._worker = new UntarWorker(self._assets.prefix); - } + untar.on('file', (file) => { + bundle.addFile(file.name, file.data); + }); - self._worker.untar(response, function (err, files) { - callback(err, files); + untar.on('done', () => { + bundle.loaded = true; + }); - // if we have no more requests for this worker then - // destroy it - if (!self._worker.hasPendingRequests()) { - self._worker.destroy(); - self._worker = null; - } + untar.on('error', (err) => { + Debug.error(err); + callback(err); }); - } else { - const archive = new Untar(response); - const files = archive.untar(self._assets.prefix); - callback(null, files); - } + }).catch((err) => { + Debug.error(err); + callback(err); + }); } - open(url, data) { - return new Bundle(data); + /** + * Open the bundle. + * + * @param {string} url - The URL of the resource to open. + * @param {Bundle} bundle - Bundle to open. + * @returns {Bundle} The bundle. + */ + open(url, bundle) { + return bundle; } } diff --git a/src/framework/handlers/css.js b/src/framework/handlers/css.js index 4477ec53660..b555e3e7c47 100644 --- a/src/framework/handlers/css.js +++ b/src/framework/handlers/css.js @@ -1,8 +1,15 @@ import { http } from '../../platform/net/http.js'; - import { ResourceHandler } from './handler.js'; class CssHandler extends ResourceHandler { + /** + * TextDecoder for decoding binary data. + * + * @type {TextDecoder|null} + * @private + */ + decoder = null; + constructor(app) { super(app, 'css'); } @@ -26,6 +33,17 @@ class CssHandler extends ResourceHandler { } }); } + + /** + * Parses raw DataView and returns string. + * + * @param {DataView} data - The raw data as a DataView + * @returns {string} The parsed resource data. + */ + openBinary(data) { + this.decoder ??= new TextDecoder('utf-8'); + return this.decoder.decode(data); + } } export { CssHandler }; diff --git a/src/framework/handlers/html.js b/src/framework/handlers/html.js index 0a05fc709b8..e6b24653e53 100644 --- a/src/framework/handlers/html.js +++ b/src/framework/handlers/html.js @@ -1,8 +1,15 @@ import { http } from '../../platform/net/http.js'; - import { ResourceHandler } from './handler.js'; class HtmlHandler extends ResourceHandler { + /** + * TextDecoder for decoding binary data. + * + * @type {TextDecoder|null} + * @private + */ + decoder = null; + constructor(app) { super(app, 'html'); } @@ -26,6 +33,17 @@ class HtmlHandler extends ResourceHandler { } }); } + + /** + * Parses raw DataView and returns string. + * + * @param {DataView} data - The raw data as a DataView + * @returns {string} The parsed resource data. + */ + openBinary(data) { + this.decoder ??= new TextDecoder('utf-8'); + return this.decoder.decode(data); + } } export { HtmlHandler }; diff --git a/src/framework/handlers/json.js b/src/framework/handlers/json.js index b56d116fc26..7b16ed16228 100644 --- a/src/framework/handlers/json.js +++ b/src/framework/handlers/json.js @@ -1,8 +1,15 @@ import { http, Http } from '../../platform/net/http.js'; - import { ResourceHandler } from './handler.js'; class JsonHandler extends ResourceHandler { + /** + * TextDecoder for decoding binary data. + * + * @type {TextDecoder|null} + * @private + */ + decoder = null; + constructor(app) { super(app, 'json'); } @@ -33,6 +40,17 @@ class JsonHandler extends ResourceHandler { } }); } + + /** + * Parses raw DataView and returns string. + * + * @param {DataView} data - The raw data as a DataView + * @returns {object} The parsed resource data. + */ + openBinary(data) { + this.decoder ??= new TextDecoder('utf-8'); + return JSON.parse(this.decoder.decode(data)); + } } export { JsonHandler }; diff --git a/src/framework/handlers/loader.js b/src/framework/handlers/loader.js index b58b6fd03bd..6ca1929b878 100644 --- a/src/framework/handlers/loader.js +++ b/src/framework/handlers/loader.js @@ -94,12 +94,19 @@ class ResourceLoader { * an error occurs. Passed (err, resource) where err is null if there are no errors. * @param {import('../asset/asset.js').Asset} [asset] - Optional asset that is passed into * handler. + * @param {object} [options] - Additional options for loading. + * @param {boolean} [options.bundlesIgnore] - If set to true, then asset will not try to load + * from a bundle. Defaults to false. + * @param {import('../asset/asset-registry.js').BundlesFilterCallback} [options.bundlesFilter] - A callback that will be called + * when loading an asset that is contained in any of the bundles. It provides an array of + * bundles and will ensure asset is loaded from bundle returned from a callback. By default + * smallest filesize bundle is choosen. * @example * app.loader.load("../path/to/texture.png", "texture", function (err, texture) { * // use texture here * }); */ - load(url, type, callback, asset) { + load(url, type, callback, asset, options) { const handler = this._handlers[type]; if (!handler) { const err = `No resource handler for asset type: '${type}' when loading [${url}]`; @@ -134,6 +141,28 @@ class ResourceLoader { return; } + if (urlObj.load instanceof DataView) { + if (handler.openBinary) { + if (!self._requests[key]) + return; + + try { + const data = handler.openBinary(urlObj.load); + self._onSuccess(key, data); + } catch (err) { + self._onFailure(key, err); + } + return; + } + + urlObj.load = URL.createObjectURL(new Blob([urlObj.load])); + if (asset) { + if (asset.urlObject) + URL.revokeObjectURL(asset.urlObject); + asset.urlObject = urlObj.load; + } + } + handler.load(urlObj, function (err, data, extra) { // make sure key exists because loader // might have been destroyed by now @@ -155,10 +184,25 @@ class ResourceLoader { }; const normalizedUrl = url.split('?')[0]; - if (this._app.enableBundles && this._app.bundles.hasUrl(normalizedUrl)) { - if (!this._app.bundles.canLoadUrl(normalizedUrl)) { - handleLoad(`Bundle for ${url} not loaded yet`); - return; + if (this._app.enableBundles && this._app.bundles.hasUrl(normalizedUrl) && !(options && options.bundlesIgnore)) { + // if there is no loaded bundle with asset, then start loading a bundle + if (!this._app.bundles.urlIsLoadedOrLoading(normalizedUrl)) { + const bundles = this._app.bundles.listBundlesForAsset(asset); + let bundle; + + if (options && options.bundlesFilter) { + bundle = options.bundlesFilter(bundles); + } + + if (!bundle) { + // prioritize smallest bundle + bundles?.sort((a, b) => { + return a.file.size - b.file.size; + }); + bundle = bundles?.[0]; + } + + if (bundle) this._app.assets?.load(bundle); } this._app.bundles.loadUrl(normalizedUrl, function (err, fileUrlFromBundle) { diff --git a/src/framework/handlers/shader.js b/src/framework/handlers/shader.js index c3186152c56..c5a8840548b 100644 --- a/src/framework/handlers/shader.js +++ b/src/framework/handlers/shader.js @@ -1,8 +1,15 @@ import { http } from '../../platform/net/http.js'; - import { ResourceHandler } from './handler.js'; class ShaderHandler extends ResourceHandler { + /** + * TextDecoder for decoding binary data. + * + * @type {TextDecoder|null} + * @private + */ + decoder = null; + constructor(app) { super(app, 'shader'); } @@ -26,6 +33,17 @@ class ShaderHandler extends ResourceHandler { } }); } + + /** + * Parses raw DataView and returns string. + * + * @param {DataView} data - The raw data as a DataView + * @returns {string} The parsed resource data. + */ + openBinary(data) { + this.decoder ??= new TextDecoder('utf-8'); + return this.decoder.decode(data); + } } export { ShaderHandler }; diff --git a/src/framework/handlers/template.js b/src/framework/handlers/template.js index ad3a05d5ff7..4ec1fc005ee 100644 --- a/src/framework/handlers/template.js +++ b/src/framework/handlers/template.js @@ -1,10 +1,16 @@ import { http } from '../../platform/net/http.js'; - import { Template } from '../template.js'; - import { ResourceHandler } from './handler.js'; class TemplateHandler extends ResourceHandler { + /** + * TextDecoder for decoding binary data. + * + * @type {TextDecoder|null} + * @private + */ + decoder = null; + constructor(app) { super(app, 'template'); } @@ -35,6 +41,17 @@ class TemplateHandler extends ResourceHandler { open(url, data) { return new Template(this._app, data); } + + /** + * Parses raw DataView and returns string. + * + * @param {DataView} data - The raw data as a DataView + * @returns {Template} The parsed resource data. + */ + openBinary(data) { + this.decoder ??= new TextDecoder('utf-8'); + return new Template(this._app, JSON.parse(this.decoder.decode(data))); + } } export { TemplateHandler }; diff --git a/src/framework/handlers/text.js b/src/framework/handlers/text.js index 054fde79b67..0e2698a6c40 100644 --- a/src/framework/handlers/text.js +++ b/src/framework/handlers/text.js @@ -1,8 +1,15 @@ import { http } from '../../platform/net/http.js'; - import { ResourceHandler } from './handler.js'; class TextHandler extends ResourceHandler { + /** + * TextDecoder for decoding binary data. + * + * @type {TextDecoder|null} + * @private + */ + decoder = null; + constructor(app) { super(app, 'text'); } @@ -26,6 +33,17 @@ class TextHandler extends ResourceHandler { } }); } + + /** + * Parses raw DataView and returns string. + * + * @param {DataView} data - The raw data as a DataView + * @returns {string} The parsed resource data. + */ + openBinary(data) { + this.decoder ??= new TextDecoder('utf-8'); + return this.decoder.decode(data); + } } export { TextHandler }; diff --git a/src/framework/handlers/untar.js b/src/framework/handlers/untar.js index 8fcc479a76a..2e0c8f6088f 100644 --- a/src/framework/handlers/untar.js +++ b/src/framework/handlers/untar.js @@ -1,369 +1,201 @@ -let Untar; // see below why we declare this here - -// The UntarScope function is going to be used -// as the code that ends up in a Web Worker. -// The Untar variable is declared outside the scope so that -// we do not have to add a 'return' statement to the UntarScope function. -// We also have to make sure that we do not mangle 'Untar' variable otherwise -// the Worker will not work. -function UntarScope(isWorker) { - let utfDecoder; - let asciiDecoder; - - if (typeof TextDecoder !== 'undefined') { - try { - utfDecoder = new TextDecoder('utf-8'); - asciiDecoder = new TextDecoder('windows-1252'); - } catch (e) { - console.warn('TextDecoder not supported - pc.Untar module will not work'); - } - } else { - console.warn('TextDecoder not supported - pc.Untar module will not work'); - } - - function PaxHeader(fields) { - this._fields = fields; - } - - PaxHeader.parse = function (buffer, start, length) { - const paxArray = new Uint8Array(buffer, start, length); - let bytesRead = 0; - const fields = []; - - while (bytesRead < length) { - let spaceIndex; - for (spaceIndex = bytesRead; spaceIndex < length; spaceIndex++) { - if (paxArray[spaceIndex] === 0x20) - break; - } - - if (spaceIndex >= length) { - throw new Error('Invalid PAX header data format.'); - } - - const fieldLength = parseInt(utfDecoder.decode(new Uint8Array(buffer, start + bytesRead, spaceIndex - bytesRead)), 10); - const fieldText = utfDecoder.decode(new Uint8Array(buffer, start + spaceIndex + 1, fieldLength - (spaceIndex - bytesRead) - 2)); - const field = fieldText.split('='); - - if (field.length !== 2) { - throw new Error('Invalid PAX header data format.'); - } - - if (field[1].length === 0) { - field[1] = null; - } - - fields.push({ - name: field[0], - value: field[1] - }); - - bytesRead += fieldLength; - } - - return new PaxHeader(fields); - }; - - PaxHeader.prototype.applyHeader = function (file) { - for (let i = 0; i < this._fields.length; i++) { - let fieldName = this._fields[i].name; - const fieldValue = this._fields[i].value; - - if (fieldName === 'path') { - fieldName = 'name'; - } - - if (fieldValue === null) { - delete file[fieldName]; - } else { - file[fieldName] = fieldValue; - } - } - }; +import { EventHandler } from '../../core/event-handler.js'; +/** + * A utility class for untaring archives from a fetch request. It processes files from a tar file + * in a streamed manner, so asset parsing can happen in parallel instead of all at once at the end. + * + * @augments EventHandler + * @ignore + */ +class Untar extends EventHandler { /** + * @type {number} * @private - * @name Untar - * @classdesc Untars a tar archive in the form of an array buffer. - * @param {ArrayBuffer} arrayBuffer - The array buffer that holds the tar archive. - * @description Creates a new instance of Untar. */ - function UntarInternal(arrayBuffer) { - this._arrayBuffer = arrayBuffer || new ArrayBuffer(0); - this._bufferView = new DataView(this._arrayBuffer); - this._globalPaxHeader = null; - this._paxHeader = null; - this._bytesRead = 0; - } - - if (!isWorker) { - Untar = UntarInternal; - } + headerSize = 512; /** + * @type {number} * @private - * @function - * @name Untar#_hasNext - * @description Whether we have more files to untar. - * @returns {boolean} Returns true or false. */ - UntarInternal.prototype._hasNext = function () { - return this._bytesRead + 4 < this._arrayBuffer.byteLength && this._bufferView.getUint32(this._bytesRead) !== 0; - }; + paddingSize = 512; /** + * @type {number} * @private - * @function - * @name Untar#_readNextFile - * @description Untars the next file in the archive. - * @returns {object} Returns a file descriptor in the following format: - * {name, size, start, url}. */ - UntarInternal.prototype._readNextFile = function () { - const headersDataView = new DataView(this._arrayBuffer, this._bytesRead, 512); - const headers = asciiDecoder.decode(headersDataView); - this._bytesRead += 512; - - let name = headers.substring(0, 100).replace(/\0/g, ''); - const ustarFormat = headers.substring(257, 263); - const size = parseInt(headers.substring(124, 136), 8); - const type = headers.substring(156, 157); - const start = this._bytesRead; - let url = null; - - let normalFile = false; - switch (type) { - case '0': case '': // Normal file - // do not create blob URL if we are in a worker - // because if the worker is destroyed it will also destroy the blob URLs - normalFile = true; - if (!isWorker) { - const blob = new Blob([this._arrayBuffer.slice(this._bytesRead, this._bytesRead + size)]); - url = URL.createObjectURL(blob); - } - break; - case 'g': // Global PAX header - this._globalPaxHeader = PaxHeader.parse(this._arrayBuffer, this._bytesRead, size); - break; - case 'x': // PAX header - this._paxHeader = PaxHeader.parse(this._arrayBuffer, this._bytesRead, size); - break; - case '1': // Link to another file already archived - case '2': // Symbolic link - case '3': // Character special device - case '4': // Block special device - case '5': // Directory - case '6': // FIFO special file - case '7': // Reserved - default: // Unknown file type - } - - this._bytesRead += size; - - // File data is padded to reach a 512 byte boundary; skip the padded bytes too. - const remainder = size % 512; - if (remainder !== 0) { - this._bytesRead += (512 - remainder); - } - - if (!normalFile) { - return null; - } - - if (ustarFormat.indexOf('ustar') !== -1) { - const namePrefix = headers.substring(345, 500).replace(/\0/g, ''); - - if (namePrefix.length > 0) { - name = namePrefix.trim() + name.trim(); - } - } - - const file = { - name: name, - start: start, - size: size, - url: url - }; + bytesRead = 0; - if (this._globalPaxHeader) { - this._globalPaxHeader.applyHeader(file); - } + /** + * @type {number} + * @private + */ + bytesReceived = 0; - if (this._paxHeader) { - this._paxHeader.applyHeader(file); - this._paxHeader = null; - } + /** + * @type {boolean} + * @private + */ + headerRead = false; - return file; - }; + /** + * @type {ReadableStream|null} + * @private + */ + reader = null; /** + * @type {Uint8Array} * @private - * @function - * @name Untar#untar - * @description Untars the array buffer provided in the constructor. - * @param {string} [filenamePrefix] - The prefix for each filename in the tar archive. This is usually the {@link AssetRegistry} prefix. - * @returns {object[]} An array of files in this format {name, start, size, url}. */ - UntarInternal.prototype.untar = function (filenamePrefix) { - if (!utfDecoder) { - console.error('Cannot untar because TextDecoder interface is not available for this platform.'); - return []; - } + data = new Uint8Array(0); - const files = []; - while (this._hasNext()) { - const file = this._readNextFile(); - if (!file) continue; - if (filenamePrefix && file.name) { - file.name = filenamePrefix + file.name; - } - files.push(file); - } + /** + * @type {TextDecoder|null} + * @private + */ + decoder = null; - return files; - }; - - // if we are in a worker then create the onmessage handler using worker.self - if (isWorker) { - self.onmessage = function (e) { - const id = e.data.id; - - try { - const archive = new UntarInternal(e.data.arrayBuffer); - const files = archive.untar(e.data.prefix); - // The worker is done so send a message to the main thread. - // Notice we are sending the array buffer back as a Transferrable object - // so that the main thread can re-assume control of the array buffer. - postMessage({ - id: id, - files: files, - arrayBuffer: e.data.arrayBuffer - }, [e.data.arrayBuffer]); - } catch (err) { - postMessage({ - id: id, - error: err.toString() - }); - } - }; - } -} + /** + * @type {string} + * @private + */ + prefix = ''; -// this is the URL that is going to be used for workers -let workerUrl = null; + /** + * @type {string} + * @private + */ + fileName = ''; -// Convert the UntarScope function to a string and add -// the onmessage handler for the worker to untar archives -function getWorkerUrl() { - if (!workerUrl) { - // execute UntarScope function in the worker - const code = '(' + UntarScope.toString() + ')(true)\n\n'; + /** + * @type {number} + * @private + */ + fileSize = 0; - // create blob URL for the code above to be used for the worker - const blob = new Blob([code], { type: 'application/javascript' }); + /** + * @type {string} + * @private + */ + fileType = ''; - workerUrl = URL.createObjectURL(blob); - } - return workerUrl; -} + /** + * @type {string} + * @private + */ + ustarFormat = ''; -/** - * Wraps untar'ing a tar archive with a Web Worker. - * - * @ignore - */ -class UntarWorker { /** - * Creates new instance of an UntarWorker. + * Create an instance of an Untar. * - * @param {string} [filenamePrefix] - The prefix that should be added to each file name in the - * archive. This is usually the {@link AssetRegistry} prefix. + * @param {Promise} fetchPromise - A Promise object returned from a fetch request. + * @param {string} assetsPrefix - Assets registry files prefix. + * @ignore */ - constructor(filenamePrefix) { - this._requestId = 0; - this._pendingRequests = {}; - this._filenamePrefix = filenamePrefix; - this._worker = new Worker(getWorkerUrl()); - this._worker.addEventListener('message', this._onMessage.bind(this)); + constructor(fetchPromise, assetsPrefix = '') { + super(); + this.prefix = assetsPrefix || ''; + this.reader = fetchPromise.body.getReader(); + + this.reader.read().then((res) => { + this.pump(res.done, res.value); + }).catch((err) => { + this.fire('error', err); + }); } /** - * @param {MessageEvent} e - The message event from the worker. - * @private + * This method is called multiple times when the stream provides data. + * + * @param {boolean} done - True when reading data is complete. + * @param {Uint8Array} value - Chunk of data read from a stream. + * @returns {Promise|null} Return new pump Promise or null when no more data is available. + * @ignore */ - _onMessage(e) { - const id = e.data.id; - if (!this._pendingRequests[id]) return; - - const callback = this._pendingRequests[id]; + pump(done, value) { + if (done) { + this.fire('done'); + return null; + } - delete this._pendingRequests[id]; + this.bytesReceived += value.byteLength; - if (e.data.error) { - callback(e.data.error); - } else { - const arrayBuffer = e.data.arrayBuffer; + const data = new Uint8Array(this.data.length + value.length); + data.set(this.data); + data.set(value, this.data.length); + this.data = data; - // create blob URLs for each file. We are creating the URLs - // here - outside of the worker - so that the main thread owns them - for (let i = 0, len = e.data.files.length; i < len; i++) { - const file = e.data.files[i]; - const blob = new Blob([arrayBuffer.slice(file.start, file.start + file.size)]); - file.url = URL.createObjectURL(blob); - } + while (this.readFile()); - callback(null, e.data.files); - } + return this.reader.read().then((res) => { + this.pump(res.done, res.value); + }).catch((err) => { + this.fire('error', err); + }); } /** - * Untars the specified array buffer using a Web Worker and returns the result in the callback. + * Attempt to read file from an available data buffer * - * @param {ArrayBuffer} arrayBuffer - The array buffer that holds the tar archive. - * @param {Function} callback - The callback function called when the worker is finished or if - * there is an error. The callback has the following arguments: {error, files}, where error is - * a string if any, and files is an array of file descriptors. + * @returns {boolean} True if file was successfully read and more data is potentially available for + * processing. + * @ignore */ - untar(arrayBuffer, callback) { - const id = this._requestId++; - this._pendingRequests[id] = callback; - - // send data to the worker - notice the last argument - // converts the arrayBuffer to a Transferrable object - // to avoid copying the array buffer which would cause a stall. - // However this causes the worker to assume control of the array - // buffer so we cannot access this buffer until the worker is done with it. - this._worker.postMessage({ - id: id, - prefix: this._filenamePrefix, - arrayBuffer: arrayBuffer - }, [arrayBuffer]); - } + readFile() { + if (!this.headerRead && this.bytesReceived > (this.bytesRead + this.headerSize)) { + this.headerRead = true; + const view = new DataView(this.data.buffer, this.bytesRead, this.headerSize); + this.decoder ??= new TextDecoder('windows-1252'); + const headers = this.decoder.decode(view); + + this.fileName = headers.substring(0, 100).replace(/\0/g, ''); + this.fileSize = parseInt(headers.substring(124, 136), 8); + this.fileType = headers.substring(156, 157); + this.ustarFormat = headers.substring(257, 263); + + if (this.ustarFormat.indexOf('ustar') !== -1) { + const prefix = headers.substring(345, 500).replace(/\0/g, ''); + if (prefix.length > 0) { + this.fileName = prefix.trim() + this.fileName.trim(); + } + } - /** - * Returns whether the worker has pending requests to untar array buffers. - * - * @returns {boolean} Returns true if there are pending requests and false otherwise. - */ - hasPendingRequests() { - return Object.keys(this._pendingRequests).length > 0; - } + this.bytesRead += 512; + } - /** - * Destroys the internal Web Worker. - */ - destroy() { - if (this._worker) { - this._worker.terminate(); - this._worker = null; + if (this.headerRead) { + // buffer might be not long enough + if (this.bytesReceived < (this.bytesRead + this.fileSize)) { + return false; + } + + // normal file + if (this.fileType === '' || this.fileType === '0') { + const dataView = new DataView(this.data.buffer, this.bytesRead, this.fileSize); + + const file = { + name: this.prefix + this.fileName, + size: this.fileSize, + data: dataView + }; - this._pendingRequests = null; + this.fire('file', file); + } + + this.bytesRead += this.fileSize; + this.headerRead = false; + + // bytes padding + const bytesRemained = this.bytesRead % this.paddingSize; + if (bytesRemained !== 0) + this.bytesRead += this.paddingSize - bytesRemained; + + return true; } + + return false; } } -// execute the UntarScope function in order to declare the Untar constructor -UntarScope(); - -export { Untar, UntarWorker }; +export { Untar }; diff --git a/tests/framework/bundles/test_bundle_loader.js b/tests/framework/bundles/test_bundle_loader.js index 723c61e6515..f674cb45739 100644 --- a/tests/framework/bundles/test_bundle_loader.js +++ b/tests/framework/bundles/test_bundle_loader.js @@ -1,7 +1,5 @@ describe('Test Bundle Loader', function () { beforeEach(function () { - this._workers = pc.platform.workers; - // create app this.app = new pc.Application(document.createElement('canvas')); @@ -11,7 +9,7 @@ describe('Test Bundle Loader', function () { this.assets = [ new pc.Asset('css', 'css', { filename: 'css.css', - url: 'files/css/css.css' + url: 'base/tests/test-assets/bundles/css.css' }), new pc.Asset('html', 'html', { filename: 'html.html', @@ -33,22 +31,26 @@ describe('Test Bundle Loader', function () { // filename: 'cubemap.dds', // url: 'files/cubemap/cubemap.dds' // }), - new pc.Asset('model', 'model', { - filename: 'model.json', - url: 'files/model/model.json' + new pc.Asset('container', 'container', { + filename: 'container.glb', + url: 'files/container/container.glb' }), new pc.Asset('texture', 'texture', { filename: 'texture.jpg', url: 'files/texture/texture.jpg' }), new pc.Asset('atlas', 'textureatlas', { - filename: 'atlas.jpg', - url: 'files/textureatlas/atlas.jpg' + filename: 'texture.jpg', + url: 'files/textureatlas/texture.jpg' }), new pc.Asset('animation', 'animation', { filename: 'animation.json', url: 'files/animation/animation.json' }), + new pc.Asset('template', 'template', { + filename: 'template.json', + url: 'files/template/template.json' + }), new pc.Asset('font', 'font', { filename: 'font.png', url: 'files/font/font.png' @@ -89,6 +91,9 @@ describe('Test Bundle Loader', function () { cubemap: { instanceof: pc.Texture }, + template: { + instanceof: pc.Template + }, texture: { instanceof: pc.Texture }, @@ -98,6 +103,12 @@ describe('Test Bundle Loader', function () { model: { instanceof: pc.Model }, + render: { + instanceof: pc.Render + }, + container: { + instanceof: pc.Container + }, animation: { instanceof: pc.Animation }, @@ -111,7 +122,8 @@ describe('Test Bundle Loader', function () { // the bundle asset this.bundleAsset = new pc.Asset('bundle asset', 'bundle', { - url: 'base/tests/test-assets/bundles/bundle.tar.gz' + url: 'base/tests/test-assets/bundles/bundle.tar', + size: 133632 }, { assets: this.assets.map(function (asset) { return asset.id; @@ -120,143 +132,199 @@ describe('Test Bundle Loader', function () { }); afterEach(function () { - pc.platform.workers = this._workers; this.app.destroy(); }); - it('should load bundle asset', function (done) { - expect(pc.platform.workers).to.equal(true); - - var self = this; - self.app.assets.add(this.bundleAsset); - self.assets.forEach(function (asset) { - self.app.assets.add(asset); + it('should load bundle asset and its assets', function (done) { + this.app.assets.add(this.bundleAsset); + this.assets.forEach((asset) => { + this.app.assets.add(asset); }); - self.app.assets.load(this.bundleAsset); + this.app.assets.load(this.bundleAsset); - self.app.assets.on('load:' + self.bundleAsset.id, function () { - expect(self.bundleAsset.resource instanceof pc.Bundle).to.equal(true); - self.assets.forEach(function (asset) { - expect(self.bundleAsset.resource.hasBlobUrl(asset.file.url)).to.equal(true); + this.app.assets.on('load:' + this.bundleAsset.id, () => { + expect(this.bundleAsset.resource instanceof pc.Bundle).to.equal(true); + this.assets.forEach((asset) => { + const url = (this.app.assets.prefix || '') + asset.file.url; + expect(this.bundleAsset.resource.has(url)).to.equal(true); }); done(); }); }); - it('should load bundle asset without using web workers', function (done) { - pc.platform.workers = false; + it('should load assets from bundle', function (done) { + const self = this; + let loaded = 0; - var self = this; - self.app.assets.add(this.bundleAsset); - self.assets.forEach(function (asset) { - self.app.assets.add(asset); + this.app.assets.add(this.bundleAsset); + this.assets.forEach((asset) => { + this.app.assets.add(asset); }); - self.app.assets.load(this.bundleAsset); + this.app.assets.load(this.bundleAsset); - self.app.assets.on('load:' + self.bundleAsset.id, function () { - expect(self.bundleAsset.resource instanceof pc.Bundle).to.equal(true); - self.assets.forEach(function (asset) { - expect(self.bundleAsset.resource.hasBlobUrl(asset.file.url)).to.equal(true); - }); - done(); - }); - }); + const onLoad = function() { + loaded++; + var resource = this.type === 'cubemap' ? this.resources[1] : this.resource; + expect(resource).to.not.equal(null); + var expected = self.expectedTypes[this.type]; - it('should load assets from bundle', function (done) { - expect(pc.platform.workers).to.equal(true); - - var self = this; - var todo = 0; - - var onLoad = function () { - todo--; - if (todo === 0) { - self.assets.forEach(function (asset, index) { - var resource = asset.type === 'cubemap' ? asset.resources[1] : asset.resource; - expect(resource).to.not.equal(null); - var expected = self.expectedTypes[asset.type]; - - if (expected.typeof) { - expect(typeof resource).to.equal(expected.typeof); - } - - if (expected.instanceof) { - expect(resource instanceof expected.instanceof).to.equal(true); - } - - if (asset.type === 'font') { - expect(resource.textures.length).to.equal(2); - } - }); + if (expected.typeof) { + expect(typeof resource).to.equal(expected.typeof); + } + + if (expected.instanceof) { + expect(resource instanceof expected.instanceof).to.equal(true); + } + + if (this.type === 'font') { + expect(resource.textures.length).to.equal(2); + } + + if ((self.assets.length + 1) === loaded) { done(); } }; + this.assets.forEach((asset, index) => { + asset.on('load', onLoad); + }); this.bundleAsset.on('load', onLoad); - self.app.assets.add(this.bundleAsset); - self.app.assets.load(this.bundleAsset); - todo++; + }); - self.assets.forEach(function (asset) { - asset.on('load', onLoad); - self.app.assets.add(asset); - self.app.assets.load(asset); - todo++; + it('asset should load if bundle with that asset has loaded', function(done) { + this.app.assets.add(this.bundleAsset); + this.app.assets.add(this.assets[0]); + + expect(this.assets[0].loading).to.equal(false); + this.app.assets.load(this.bundleAsset); + expect(this.assets[0].loading).to.equal(true); + + this.assets[0].ready(() => { + done(); }); }); - it('should load assets from bundle without using web workers', function (done) { - pc.platform.workers = false; + it('bundle should load if asset from it has loaded', function(done) { + this.app.assets.add(this.bundleAsset); + this.app.assets.add(this.assets[0]); + + expect(this.bundleAsset.loading).to.equal(false); + this.app.assets.load(this.assets[0]); + expect(this.bundleAsset.loading).to.equal(true); - var self = this; - var todo = 0; + this.bundleAsset.ready(() => { + done(); + }); + }); - var onLoad = function () { - todo--; - if (todo === 0) { - self.assets.forEach(function (asset, index) { - var resource = asset.type === 'cubemap' ? asset.resources[1] : asset.resource; - expect(resource).to.not.equal(null); - var expected = self.expectedTypes[asset.type]; + it('bundle should load if asset from it has loaded', function(done) { + this.app.assets.add(this.bundleAsset); + this.app.assets.add(this.assets[0]); - if (expected.typeof) { - expect(typeof resource).to.equal(expected.typeof); - } + expect(this.bundleAsset.loading).to.equal(false); + this.app.assets.load(this.assets[0]); + expect(this.bundleAsset.loading).to.equal(true); - if (expected.instanceof) { - expect(resource instanceof expected.instanceof).to.equal(true); - } + this.bundleAsset.ready(() => { + done(); + }); + }); - if (asset.type === 'font') { - expect(resource.textures.length).to.equal(2); - } - }); - done(); + it('asset loading with bundlesIgnore option should not load bundle', function(done) { + this.app.assets.add(this.bundleAsset); + this.app.assets.add(this.assets[0]); + + let filterCalled = false; + + expect(this.bundleAsset.loading).to.equal(false); + this.app.assets.load(this.assets[0], { + bundlesIgnore: true, + bundlesFilter: (bundles) => { + filterCalled = true; } - }; + }); + expect(filterCalled).to.equal(false); + expect(this.bundleAsset.loading).to.equal(false); - this.bundleAsset.on('load', onLoad); - self.app.assets.add(this.bundleAsset); - self.app.assets.load(this.bundleAsset); - todo++; + this.assets[0].ready(() => { + done(); + }); + }); - self.assets.forEach(function (asset) { - asset.on('load', onLoad); - self.app.assets.add(asset); - self.app.assets.load(asset); - todo++; + it('asset loading should prefer smallest bundle', function(done) { + const bundleAsset2 = new pc.Asset('bundle asset 2', 'bundle', { + url: 'base/tests/test-assets/bundles/bundle.tar', + size: 133632 + 1 + }, { + assets: this.assets.map(function (asset) { + return asset.id; + }) + }); + + this.app.assets.add(bundleAsset2); + this.app.assets.add(this.bundleAsset); + this.app.assets.add(this.assets[0]); + + expect(this.bundleAsset.loading).to.equal(false); + this.app.assets.load(this.assets[0]); + expect(this.bundleAsset.loading).to.equal(true); + expect(bundleAsset2.loading).to.equal(false); + + this.assets[0].ready(() => { + done(); }); }); - it('should fail loading assets if the bundle has not started loading', function (done) { + it('asset loading with bundlesFilter', function(done) { + const bundleAsset2 = new pc.Asset('bundle asset 2', 'bundle', { + url: 'base/tests/test-assets/bundles/bundle.tar', + size: 133632 + 1 + }, { + assets: this.assets.map(function (asset) { + return asset.id; + }) + }); + + this.app.assets.add(bundleAsset2); this.app.assets.add(this.bundleAsset); + this.app.assets.add(this.assets[0]); + + let filterCalled = false; + + expect(bundleAsset2.loading).to.equal(false); + + this.app.assets.load(this.assets[0], { + bundlesFilter: (bundles) => { + filterCalled = true; + expect(bundles.length).to.equal(2); - this.app.assets.on('error:' + this.assets[0].id, function (err) { + if (bundles[0].name === 'bundle asset 2') { + return bundles[0]; + } else { + return bundles[1]; + } + } + }); + expect(filterCalled).to.equal(true); + expect(bundleAsset2.loading).to.equal(true); + expect(this.bundleAsset.loading).to.equal(false); + + this.assets[0].ready(() => { done(); }); + }); + + it('loadUrl() calls callback if bundle loaded', function (done) { + this.app.assets.add(this.bundleAsset); this.app.assets.add(this.assets[0]); - this.app.assets.load(this.assets[0]); + this.app.assets.load(this.bundleAsset); + + this.app.assets.bundles.loadUrl(this.assets[0].file.url, function (err, dataView) { + expect(err).to.equal(null); + expect(dataView instanceof DataView).to.equal(true); + done(); + }); }); }); diff --git a/tests/framework/bundles/test_bundle_registry.js b/tests/framework/bundles/test_bundle_registry.js index 434491109b1..98de7882a50 100644 --- a/tests/framework/bundles/test_bundle_registry.js +++ b/tests/framework/bundles/test_bundle_registry.js @@ -192,7 +192,7 @@ describe('pc.BundleRegistry', function () { expect(this.bundles.hasUrl('text.txt')).to.equal(false); }); - it('canLoadUrl() returns false if bundle not loaded', function () { + it('urlIsLoadedOrLoading() returns false if bundle not loaded', function () { var asset = new pc.Asset('asset', 'text', { url: 'text.txt' }); @@ -203,10 +203,10 @@ describe('pc.BundleRegistry', function () { }); this.assets.add(bundleAsset); - expect(this.bundles.canLoadUrl('text.txt')).to.equal(false); + expect(this.bundles.urlIsLoadedOrLoading('text.txt')).to.equal(false); }); - it('canLoadUrl() returns false if bundle loaded without a resource', function () { + it('urlIsLoadedOrLoading() returns false if bundle loaded without a resource', function () { var asset = new pc.Asset('asset', 'text', { url: 'text.txt' }); @@ -218,10 +218,10 @@ describe('pc.BundleRegistry', function () { this.assets.add(bundleAsset); bundleAsset.loaded = true; - expect(this.bundles.canLoadUrl('text.txt')).to.equal(false); + expect(this.bundles.urlIsLoadedOrLoading('text.txt')).to.equal(false); }); - it('canLoadUrl() returns true if bundle loaded', function () { + it('urlIsLoadedOrLoading() returns true if bundle loaded', function () { var asset = new pc.Asset('asset', 'text', { url: 'text.txt' }); @@ -235,10 +235,10 @@ describe('pc.BundleRegistry', function () { bundleAsset.loaded = true; bundleAsset.resource = sinon.fake(); - expect(this.bundles.canLoadUrl('text.txt')).to.equal(true); + expect(this.bundles.urlIsLoadedOrLoading('text.txt')).to.equal(true); }); - it('canLoadUrl() returns true if bundle being loaded', function () { + it('urlIsLoadedOrLoading() returns true if bundle being loaded', function () { var asset = new pc.Asset('asset', 'text', { url: 'text.txt' }); @@ -250,152 +250,7 @@ describe('pc.BundleRegistry', function () { this.assets.add(bundleAsset); bundleAsset.loading = true; - expect(this.bundles.canLoadUrl('text.txt')).to.equal(true); - }); - - it('loadUrl() calls callback if bundle loaded', function (done) { - var asset = new pc.Asset('asset', 'text', { - url: 'text.txt' - }); - this.assets.add(asset); - - var bundleAsset = new pc.Asset('bundle', 'bundle', null, { - assets: [asset.id] - }); - this.assets.add(bundleAsset); - bundleAsset.loaded = true; - bundleAsset.resource = sinon.fake(); - bundleAsset.resource.hasBlobUrl = sinon.fake.returns(true); - bundleAsset.resource.getBlobUrl = sinon.fake.returns('blob url'); - - this.bundles.loadUrl('text.txt', function (err, blobUrl) { - expect(err).to.equal(null); - expect(blobUrl).to.equal('blob url'); - done(); - }); - }); - - it('loadUrl() calls callback if bundle is loaded later', function (done) { - var asset = new pc.Asset('asset', 'text', { - url: 'text.txt' - }); - this.assets.add(asset); - - var bundleAsset = new pc.Asset('bundle', 'bundle', null, { - assets: [asset.id] - }); - this.assets.add(bundleAsset); - bundleAsset.loading = true; - - this.bundles.loadUrl('text.txt', function (err, blobUrl) { - expect(err).to.equal(null); - expect(blobUrl).to.equal('blob url'); - done(); - }); - - setTimeout(function () { - bundleAsset.loading = false; - bundleAsset.loaded = true; - bundleAsset.resource = sinon.fake(); - bundleAsset.resource.hasBlobUrl = sinon.fake.returns(true); - bundleAsset.resource.getBlobUrl = sinon.fake.returns('blob url'); - this.assets.fire('load:' + bundleAsset.id, bundleAsset); - }.bind(this)); - }); - - it('loadUrl() calls callback if other bundle that contains the asset is loaded later', function (done) { - var asset = new pc.Asset('asset', 'text', { - url: 'text.txt' - }); - this.assets.add(asset); - - var bundleAsset = new pc.Asset('bundle', 'bundle', null, { - assets: [asset.id] - }); - this.assets.add(bundleAsset); - bundleAsset.loading = true; - - var bundleAsset2 = new pc.Asset('bundle2', 'bundle', null, { - assets: [asset.id] - }); - this.assets.add(bundleAsset2); - bundleAsset2.loading = true; - - this.bundles.loadUrl('text.txt', function (err, blobUrl) { - expect(err).to.equal(null); - expect(blobUrl).to.equal('blob url'); - done(); - }); - - setTimeout(function () { - this.assets.remove(bundleAsset); - bundleAsset2.loading = false; - bundleAsset2.loaded = true; - bundleAsset2.resource = sinon.fake(); - bundleAsset2.resource.hasBlobUrl = sinon.fake.returns(true); - bundleAsset2.resource.getBlobUrl = sinon.fake.returns('blob url'); - this.assets.fire('load:' + bundleAsset2.id, bundleAsset2); - }.bind(this)); - }); - - it('loadUrl() calls callback with error if bundle that contains the asset is removed', function (done) { - var asset = new pc.Asset('asset', 'text', { - url: 'text.txt' - }); - this.assets.add(asset); - - var bundleAsset = new pc.Asset('bundle', 'bundle', null, { - assets: [asset.id] - }); - this.assets.add(bundleAsset); - bundleAsset.loading = true; - - this.bundles.loadUrl('text.txt', function (err, blobUrl) { - expect(err).to.be.a('string'); - done(); - }); - - setTimeout(function () { - this.assets.remove(bundleAsset); - }.bind(this)); - }); - - it('loadUrl() calls callback if bundle fails to load but another bundle that contains the asset is loaded later', function (done) { - var asset = new pc.Asset('asset', 'text', { - url: 'text.txt' - }); - this.assets.add(asset); - - var bundleAsset = new pc.Asset('bundle', 'bundle', null, { - assets: [asset.id] - }); - this.assets.add(bundleAsset); - bundleAsset.loading = true; - - var bundleAsset2 = new pc.Asset('bundle2', 'bundle', null, { - assets: [asset.id] - }); - this.assets.add(bundleAsset2); - bundleAsset2.loading = true; - - this.bundles.loadUrl('text.txt', function (err, blobUrl) { - expect(err).to.equal(null); - expect(blobUrl).to.equal('blob url'); - done(); - }); - - setTimeout(function () { - bundleAsset.loading = false; - bundleAsset.loaded = true; - this.assets.fire('error:' + bundleAsset.id, 'error'); - - bundleAsset2.loading = false; - bundleAsset2.loaded = true; - bundleAsset2.resource = sinon.fake(); - bundleAsset2.resource.hasBlobUrl = sinon.fake.returns(true); - bundleAsset2.resource.getBlobUrl = sinon.fake.returns('blob url'); - this.assets.fire('load:' + bundleAsset2.id, bundleAsset2); - }.bind(this)); + expect(this.bundles.urlIsLoadedOrLoading('text.txt')).to.equal(true); }); it('loadUrl() calls callback with error if bundle fails to load', function (done) { diff --git a/tests/test-assets/bundles/bundle.tar b/tests/test-assets/bundles/bundle.tar new file mode 100644 index 0000000000000000000000000000000000000000..f916062e191fe1d0d80f36d6b21c37c87fea46d0 GIT binary patch literal 216576 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 z zID``u#zdMO^$wOq5IViOr!7yw)?r1>{{TyA8#p(+wNEF>M@;#S%M_~m+!{O#i9DX* zR~dm(TpYp>0GsG;XMGF{>W9CxZ)5cMq)GVaQ4DM~aIKa4c1)DkXx3-TGLsnPJj;Ch z`1-PRuefeO{2tZi@=>zIg<8(EINFX>dxOPE?c(m9fGWM$r{w+w*9h?>!x7S24yBpL zH>|;$hiwB^f#|po-n|}C@xh3c(vM&+0aCY&$;PEEBJmilMH22MO-2EmoV;Cca6)O& zy9#2OtF=CcPmivpBkG1z@x`oXN0(pT_ZU54CQq~F*+K^ZYv$%e-- z%2ivv1AA<-FVCMolc>QE!U#l2(IWj)@-n*O@O-*&G76vkQwVLB8)ehI!C`=z9U7~n zfft1Aw&*Zc)F28}+ZA05apda!wc$D8>?V2c?`yv=z-v4m`eTDa~}H%uD$4MHe` z4x)xv-{_vuks^WEx$dEpnZYlJxCd-!87J~T%HjO7{k4fiQJPG?6*~q$QAhywHJeh9 z6LhMp175kWmQO`hUrIiSstaI%HiZ#I-suE&Ct5w_-4Xy{;zm#m}J;B69_FP@W5e~%~O}zjdxYIJ=P`#;iciL z>fbAtsU+NCuTsN@pQma^Es_%nTG&^??n-=>P_eLc;eKy>!N-rT8h9HWnKnX5045Ql zyvCc|$~A`_E7T^(N|TL0a#Pxsf3XFf1PDuz&>s1D&tLqli#rAjZ&s$+ZJB)5Gga`)7QrvesF)d73-+MO$>8 zVhLS@m=r?G4xQ_sF^fZ?agRF}Yd&(lT`^P_Uul~i_h`b~dfD*t02pCE_DEe7SmQ@X zZJuN*ff_}r+S~_QV|bz)G_yfu6c4*}jDWY;uz z#!!s}Y0E*?r0ULl&~7Frq6vINfMKI&r34IgqjJ_ui2QodG;S6B`6C-E5JGByp_*|y zo?41(Z%p$bqWrca+soMG5D1>tx_ngzWK^Gxp~+MYiCGx^^R0ZOgoO>bf{T-320zxg z70_SwP;+tMFFg6#4?orn8}8xBNdp4Hz<)r?kUty~OSym_&myvP5K0bK_mZ5GLe_*c zxwMsDYJMun=N|j##YR}Fg1DT}6One?$klr$v4@_|_5l<&mi#Wizc4)gILAZt>XL_> z&kz#Vs7HLGmmol1&FTHBOY2v0N5^W9hJIdyV@faHaw)@vbEvi8(WfZx@9_--R`7Eg z<9XyDjiZ}Yon?oB$iXs=oXzapucuCpr=MTf4x}3H;VEIjB0dyYnp$6r_%LCn2H>@6 zJjLgXJ6k+iQzg<*k(OY`B5HD16mn)JqZij(iWYm{;B2L@?S++}N+;It+VJ4eeayCX z&rMa{%2^k2m#hIE?Gn9cC|2mp?wO( z1kTn*|8hByN!-m@Apf>WPeJYrD{LVDYW_F~sHtZCP0xj3v#{lxw!!c?aS|0k( zfwhJ>-eE8MzsQ|z*l0J@ze7rGY)8fd=CspdE2lyNV*XN)Pu{U+;NB=T?l|Q%e0uq@ zqu$TVIJ}08!V+TQPUKy`#bn$J9~+=BG2By)RX?=*HF5a!Y-L;eg6C zHB1&PFRv#CCgwAon}Sg`@qwxljnvXhte#VN4Yj2cKNS)zu;L7tUc#I2;^SESiZMJ) z=qk(cP94Uem{W#51+8fWqmJ=W5Qai_zT|369X4w9AK6njab4-m9y7?2^m+kle22_< zEDUY>N@@@;wa0|oIt3IzMNk5S%`E~A8-J>{Jni%kp{W=U0(7NYvb;c-khN5@^pFEV zjz0Qs%CNjn+=)kY4)kTu%THp_Zg~|j3jbBlrWwMa`*c`+Q!__OS*pr=r`-_*wK;HR zZgVeq-hO<@fQL53U(CaX1c7Dz7jjfwFOu_%07Xb>HAne_j!#v$)QGr@kHLwd{8QvJ zHHeD^pz9+UF(1ReF!|KjWS9%96i4a{@{eFVP}q=~gFv0esuQe0c7Si2OTh(wbASvw zm9#vr#Dq`mvFzA*vX-uMp0QSDe_dX5{Y0F?kgJRJjq5^ZJ}P49Cq8?atJQ86V|`4l z)~bH_lnq=aU4HdGomL2^iR|ZVo#Zd+7w1a}DpQzlu@^0of zvWJYaZy!Ca`fWIS|6Nq8!BL)$xneRvK-p-yOo}AS>n9u?kHMlsJ3e@T!CoMt?CpO= z94(2-g44F20x@ivr=mpBk$ssEowQq)Z0mfbR-b^#^!U&1&3{E^bIS&KgDoa(l6V5F zq@k73P#{1(!*8+ zP4;T&%#2X+gnu}6iDzHJDCxgpO<;%hAa&|ySuFwqZivyoBuk6FzHE=Omp3H$biQM} zWGn1oc2-?Ch3?c|56pvZxM+g8xc@*cAO!<2HBzq%a=MBCWG~xQyR*s!b1G_xO%I42 ze!m{VT4ra2t_dCs^}VvxHH;-G;0bu$)0i5%K^( zCTpZg)1q}q5Tvw7Gbj91*lYttF9tN6_J{+YZFPRm(dx#;*LL)q)*p<_gQB-DRgT2KdBKp8gdbH_n=u0 zZG(`k5ugh}idJ!#Qe2HnMy=C_rUjns|3a0TgVoIUUtDOO4d{=glVW^lzaFy?Ei(b< zY9l-wMz0F{8m&p&cJju#9PyRpbkaACgMMc5l_aRBjn90zYqWLQzAW8>utBdF8%0Zi zr>$b2<0`L{WPe!+3OKyBxUh16R+LXjV6Xnp$2+c!7+@;vf6ZUnp%yE7UAkLrx)~d3 z$wx0jfPj>|pz7^jlv10CK;s#adOB5nPnYhru&xEpBFwfsbm`bA!wNDJ=JE%t@!UH{ zJz!O{?{t>g4u`PdB6#Oq?W<`97$o)Sij_)5Ey*Q|z(Koei+f7jgXNV(Yu!6P6Zodj z*I;I5C%o+j+0gqgy@3$^b1CaDXQ=}}+9OGFwCl%J z3cosL2zzEkv#A76;^o%l_$Y58YT$AJgVZonDdG}XPRRf&p@My|Fn;u{x)&IWJB*;n z=Tn5@V0TbgDOV{)JPk!;gNH~G*@{aopM9K;@BY6U8Up~M>9h|ZbXxjl^s;CiI)1%A znv7*Hk4ULTgM$6d`1Gs!;P+$qZq~VXv1OU7FiJd{9ZokJYm9*=a;;bLq6aok%tk1R z0(1XIcUN9;!~)Kzw>@B>0?r@5REkNcD`dWC_n8ypE_Ml~Fg^!ioYbGU@1Fmi`>gV} z={T+whQmK&&r@$XESV${n2F8g9oso;#g0c=wa#&UAZLZppIo8qr5<* zPo?H5>B{E>x&)=~XFy!Tld$k{7saZY2>RSrL;l+pPMl<1u< z3kDzws}q6UZpGUT0uCcg>up{eW1j10G6@NM=*FHtUA^C^wG2nn3hGnvuG*Y7)t1?f zM9naYXk&1Yx1qo+R(XPUHlU>HZ$+uR=e8!BY))ix^?kKFq)Oqxgl%?hUC7l2k7eOUEdR>E=0je8mg!|#TSEFz&P7uJ@SV^A3w+3fS zZunCu(PB|evXl!Z3K8)QVL9uYAKu;O9-bE$etL6Ha`TRBVhE_Er1-nw&3j7e7`aS= zMNb1acGS3^i~lY0a$iL-amlU|rdAFWD0gdDo3!c=(~ZEmiQ7UWTN2uwh-Zy69helu zJhAUjrdXC^&1Upc3yBw1-osK!p{<}OW=V@{7Ks<+Jix;Z)t=>2kWk~dxL=K;+EPY# z?Ys-D_diy6!$W3xTYNp=>Q|&GdCpOX>tL}WN>G3I?H>1$_`Eh%1tqofh|CiO74VM{ zdUguJaMdlb5In}8AzPZCxM)Oz*W2HgAw#VbWG~2|HsS-A??}NZ#{x=##TPDg#ir~) zG<1or_A-KaPojQ(SIq!{fm4w2`^#`_6I`{*RT)-NNYvdkcrq0M*GLRFt`la^WQmpX z+g}osRyroUS9G;`jWRcKS9)*kx%H~w&sghU4V`0R;zH(4(ELA(%C4`rXoUdna5Nb! zG$euBqk{;%@Qitv99vQ0n52MWY|Hr^MmCBwws5)Xvh$xt^o+!=VGLGeEO$LHuNh}B z=;lLo3D`LC$nhaA+yP%BM;a^0F=lL>G*ra!x$ZPQ=df6VJ#7=KUB;K(;L+3!qB1md}D@&B9w$?+5R=TDHnHG30L%cJ{0s*Oz}Reaf$hLQq2j`#;)0K}uk~ZTD>4OZBvcjtoPw`$nbQCLr;Ltr&MJ0R79v8eZgR`L3Tdqow>w@6$8!|@ zd*x5nbOWRRW%pkO{C!S`b?J$ zfKLBZN_W<`B?=>Q{gL^|h88*G6oIIf9%p6EZgL_Jc zII5OOiWgpPC?Sn>^;jBze$8E)3iHYvdhS%W1v4D{Np! zs*yc^TIkb^1^(A(B0M-(|q#W0`X&Uvp!wK*b|73V)T}2$buM6&@}RO{5;~BXuUZ z>2m%Cj=?M;dcA{c&c)-DGA2q)JyIRYx-Fr0A~E+!W=&lf>;#CGc;PB%8oHb)nD>Mz zT+oYccHUoMa<~${M{F_gsWKSz6mGfvpBXb7hN<*yk&Tl9=2}O9z9T6Ba*sqNLT!;j zsV6_96C?tU6hm0JM+?UBbGw|s5_*>gg)px(8+`6aoo7)VVmE$g9#Y5Yk$p+c&-iD9 z(aHDcmm~e_*_)FfWZ#F?O}nUXt&)-Yifq&0zmDB&PBhLG-*y6WjWfCTVlU-NcV^on z166d`@{AXAG+{|%qvl{)J`Rj|h>;vAM)8GYVG);MZm-9t@+<<}@Iqc$YKp_CDX!et zCRm?4|IAzO>^SvNz{anDsKn0U>l)JqJ%VYaspvybl3E767i(H8<#01RJF0PVLGFv!n%Xh?$u|! z8qDG2_h7^d;<-6(?#G|jufKQ*Q^v=W^oRT)4>OgIt14&5aUh)dt)+PzCC&Isd#>xL zDj<5($V;Xcdz?lIFo5xMD4{i5vPfw1UK%A4b4B){Y+%F#vFPIpE}mlzd+w*l_Np~@ zIC;~eR&}Fpd|frw^j!M!d(5At4TOz-dhWj(>JP)@f@yDYGJJEy`9+BC6f~5$6r=Dw zF{&!6(MFP8%W-m3%0Lx0ymXinNr2Hb31QM8j(dDK&mO~hSe7i#u-K>H2_Fm+DtYOaNHxFv{Z3~qD@E;Imo7zq znJtteONKQyf0II-8!u)U`>=-Bv`29i@pOk7xOQ%I`yMQkAy-xL;DO@t##%T1-bv-P z#L*UZeOQnejjn@GVNj`41Uy@d1=V@jNZ~TV(uI8VT;BFXbkydT$37ienH3jSwQsB} ztH%pz8aP?v0`C3tdqRJUkaPVHVCvWqd}TkyHEB!z@b^LP5zB}N1pvg8aI#($Go?b^ z@pYAj3YybcDmAb@Vqq_LTD72f+O!S0MJ&w#9WH#r^giEaKz+9pHa^|VD1p`GY>jx` zDtlLmP{$=3uqF6o1f{uMaoVZL6^*Lu14+MX@Av@VZfs$dkoX;GaSb0P_FXmWrf^6TAH0HaDX3@K}yFVud_q5&*+_MS%r~hlZ$IFTF(M z9nj#prrQz!Fi1aS52+6b!$RNi4d<_s?=alXdd6qP_aCcNAZ7VBjyq>`^%WCaGr8z< zQHI@Dya;SUHfhrY&l_xj{A`~%UXAzDDjktNp44cg-$8X5F{+Hw0&^8VKhjmZ*hJueVbC4|h5Xp$I}2NJN8WmDN%hjvFB;8?4LdGvIr{3s zu`yy^4`s!TxznqjqavGNy-Z>8R1py#|K~1chhdMa>1;h0*&nH+mv)FcRK1=47sfgm zo#=EI1?u#nqJGLrmt4M&QX&gilQdfN)dYDDIy#6qkhg32w>%1Cl5XPHT$w+n*D)W( zL@NcTb+)<92tGaZOfN8jN)XD zSE`{RF4hhZn9XKww)y+zGSteDlR_O!otinXUvVsP-7Q!9SJRbRm-@%@F}0hYjYM(H zi3#sYhdQsnM5;%b1wPsMqeqyol}U|FT8nWzmH*BQKR zh*x6Bi*eOWQ?%GAL9s_h5u(_$d(JM5`!pqrRF_B(70;qNE445r@3P)%{oXLE4fJ5J zIaJlPB1!i!Mbv*wD|oG!OGcIaS5i_9x`u3?;b3-gtQ;Vfz%p>PCzhN9#OtkEGf>Zo z-6-B~_w0C?>;&{B7?cid=$`MaG8mFXP%p(x7z40v-9h3?r>f~{I+`@ZB4T_O?yNCglI5NbwSzGKGA5y}s> zHW+-PtPPp(<|L%xwP{n0;0`F1Uh;X+$FnVy#~`=Cd71aXGXWPK(Z`5e>V(p!WoLn`R$o6=+D4>#;36eAYAWWwgb4 z-pxfHDbvDn{KXrp&YG%Aq>c<3{V!JK-%}2~d}wBT;e}6+&{BwNM9&lmc0IJ6r3XW8 zDII=Rg8ZeQ>TG&G+`gV^h%t-mKs6(beAjAP*jy;e0U)_n0`ldss+nfnz@XCaLG`u4wlyil5f$)eNr4t73iAwH! z`ElRot(TI2mKXcb=qG1IFeX5yIRA-9MsUlY_=Y5oo0MgwzD`Zt{p9=i(DY5A0eE=Q z{ZU2jn5XGI<$3P$4ojEQQ7u&s4R@Jkd5*j-|5*Z~XQ@;{rreY5a>sH16RLM<@Fz}e zfRIf8tV_Jm5C#E~c%_kjR8E@^W-&y961!$l7V{G&^&z@-zg-^1f1Xc+g%^TZHeSI= z8F+7?M<1{_LfUdfrS-Z^FxIoQN++VPFnsl??#~Jb<@5e_paugNK&eckHJXOGD2KjD z^Q(qffUAr*W>RE17MpRg1dki%?LZG$UNdmIrZf&1T|^Q^X&E_GIhsn~pzCUdA7X0A z&7K-G*y<$d*LDA2*-LSsxHoCfe3w+w%ZD^YlMvt*l|DN4!NRz-*4g2Rm~gLx!Ym{Eyk3oZGvGAM6Xy+n z7LGIo-8x-M$F~cf&K zlF{{!b7_h@T&akR3>rC=WgH^-og}Fd@jBqb`=h6}3fnJ7IssG~O6CnT)3zH6yX+=YGv9}6eQWM@wc{(jp!OB^Q+ zcZ@>DUlzfqrNQ36a4T`_x8dR*9_Pe9|0iQvg#g>w4bXIJ8fYuasx!}pOv;lse>;m*xGI3I_D(u_@9cV@Y|Br z!Pj5|qRj;ZHEdmNAVe{ z>C(|L0z@LI26Qun^o%J5^U^d#v74#ZgC3j=!A{7?=sYTXD);LN6P2$13;MV`md&W@ z(wg`856aE=CjbDJSD2Do`EDYM!T|X885c>+l-0Qa+%>F9Ady&?*VfnAhq~m6nwOsh zIHB2-^C-9coe>lF9hQm|g!_1cf<*H8Uk&*KfZ4*!*QfLY23DKuF5w^o^{(fMQ0q`+ zJR~>@RL>#u_08jduk!jYVNJ?PW=CpnK1r$&X9F?yh1u^%MD}CJbRoOdgt%J0yi&w* z*e!Nkm+LYaVeRjq;2vS?2>mDU)W>RmpsT$8hvn|>(N7V)`O(i77B0)eZZ~h1uE>=r z5Uc?06I13V`7t)3yT%5ggTLjI*cqhiLx%|GH&DCW#hSd`)tu#YV?x-9%|@b}vi4s2 zIG*=qOc>Y-uu1Ddu2f!DX+pn0Pi`$&LXzne-troUwQjnI2Xng5%v36Y>Xc4&-TjBvQUd^T@(s7*j=9aw@p!WC$a=o`SR3uM(7)!$>R(({ zgKu(O>W^?asWo>nal^aqgz9LBNLOn&66GU9qb2X!r&+O|QX1nDNMAB$71Y*mtrvBp z3_TU=z_=w-2Wq)(VsmCynVT_F`$;!uuKyHD0RRuUmk-dH0tS^+uVuoO2{HoIK+>b3 zW&{o%_3XQe5Jq{Iu(Tv@*5~@)Ft!DJRiBEWwu*F}w%oyB#+ve2j8Ls8URzHrI6f%y5!)1 zSxp5Yqo3IgK_{xHS~zEj__$vti(chAG^3ncq~I(&+MuXhr_tZ{P2=lqnBbN$+B^~B zDuOYhZsTPDK2r=b=dpq6gP>hXU3_KnU%9yooK9zvmlZ>aX)Gm}yZww= zD40diVCC~_1N_b7<{G;T`DpsMY-vhT)0YSv=L=urA^7^Z8F@;avm89(L?~aVJA;7z zLwsu3Q$b=KcMLgG@LGM`A zh%WA;h?up=aT)pl{(1B~TRVN>`bU(Pz+fE=00VLsYAWD?(86A>DLZQqcTUS2N-~#|KYd|AugI(PiO!6h|$ED-5UcqmnUF@Hxb@@6Ko3CJ{9f z9%&w-*}zLGV_V}-V;m-TTKMh!0(`WyhaRoVH#)t@#0w^8QHDB4vXM06_ z!T5p`;Xs2uJdyxu_N|kb*Xrq$sVKK15f+-Xbnx({$z`pcVP_r*O(A?MMT_}?#=>k> zrlZrWrl&{SXQB1+(NO7&+4A(Cj)o~UeYH0BUJwf`hb1ej>}waOx?<){ad50&QN|2` zEy^_&TG%+cuRSM3U7ZRBboq$~F%$QKTgF#{AR%tP(Z8&cLciZ~l`CG|>f_A5AB#jC zAgVBf>EQnI(g#Cnpt8Z+OV3p|7xfs3|PgyXmrW|(`Dm@I7ER6M3U8J(6((& zBB$PaP_LV}pOT10_yLz;7#T`v!nAq!M3%Ri{$SM%JBgcL2-U-kS9166vN@0H?)H=Y zW#TG{c&onV>K2=4nAt|K5`jke%AtELCWQj?+SCk}2dT*$-7b2T5mG_u5O@mn@XBfS zQ|gH%C%t7X7F8f;@c>NTQ}gkq(>#9xRkiK=mybKE19jc8dWuNWRK44ULrWU+6Hfad zEoIiBXd91a0JxMXt*+G$y|)x;CzK}4$766B^t?Z?ii4rTGg$IKO+S*nX?%al-QJ!4 z_SW(*`UmeE(^eRN*mYQ!Ayf6A#Wj2TwQM2a0l@9#S_5$A*%j!mL~|Dg;j z;(#@ZVQ8`5H!05>S$c9;enW4n3h}0=7V<8mT6&aa(Ok}Gy>$`4TBbko%eH~WvZv$4 zQa!EHQoDl=u*x6!uvx^U80y(zK#7yICj-+a+T33upoUGO5sA3Nhtv=lg(sYAK$jJR zfRQRFD$K(A`(X_9A>y)u!pTfi^smc5h2}zlZ|K$o+@OZqrBhcjXfu}0^Owiv_LfNe zv!78Q>1stBM@4OYZm-7LN^_90DiR-dqv4BL;lmu<3*i_Jz0?_4jLqiNJSN_a`Y&hb zdn*r7gYJW!q@pbFHns0#Ukf?in?gQfudesrk#agBYxKlOD8p#xGfcEN6o zv&mKP`G@mO*qhdSAwcqh{$MOjARR1(5eY_PoT0LYvTVa&A;xERJ3`vAu0ffc)C=yl z2*s81*erZ!$bgG85xXHge|5Cvs9Y)MI;06tBBlldDi6>$DLPKn#6djqbo8*-H3_`M z=Nx(xfNnliHN z$N%nbbf1m!$I>pMOs9VTy)Z{s(Eluae0ukZI8W2%NRp~O?r;C(3e9;X0uK*L!9~ZT zo&DX>GnegJlah2qN6kq|u{yT#hLLEjhpc#A$9tKQ&Cjmw&OEg<(J7r%MfGFU=`>Es z&=-}ch%$_@yDdBJqPD)<_730LoVI@oodGauNDLl8f(Y{?M+WENKoH1MI{|7N>dwZ~ zh2F7x4oTe!+`TKOs#u}I1aR^@UaH$Ob{^EW=8XV{S#m{`#W7Vm6cx)vy{)Es+zhfD z`YN1-{iW7s-dzc8}Wo_-W&tauC(wBxPl#zV*OQ)rAK7^%Po5<+7 zbzm|Q$)sjaylQ1QDuG`npKNe8nN(4Mkb+gZDiPVzaDSD?O8uftjupVmt&758;ztN` z6>9XX(bzPEUZcRzh{QBmDUhyNdQG9fb5EKxJ;AQ(?XMqS|8tnyH-}YUTK82$O_kuIHxGc_B>tJ1M@g)@BsS8_ zc9z21NKGVRv1^Yn?FCDEtf;r{(f$ZiO&-5|IgL0UB7eyItOS`zEsLrljYBqZqEjKh zAOKuNP0}}Wq;Qjt>_FL_a0bNkKZQ<1$dCASEHCJxM%H;Cn_*wj_PM+>Iv>h0`M5cY zw)klMcUY*Z)Pd?E>l<~Ep+P}XsG=-p7^$WZY5eK9(9G-Cqv|_l9tnr#Y0}y>jCRX~ zYGAd4(s+Zju)XwWHdXM)iA8vm-2zo#zwK+_gZZDbmiNEh3I203I4qFb`R{dqLU3~L z@7BVvyR9Zx7yyjewqK&FU&aG+o5qeU&m#KI)*oU(CokS$d;00qS_}wMpIO!3#+@3S zvtPiqDl1;TdRr)+@S{%?kM%2ImxhuCdAYR|EbE;bv1n__emnm5Ku#1vU-nMgjuLEI zx>>m3`4mpgGU@ty*e93#KpONiW*gyu(peBSw$LZgv^>;IStF(D+#yBrZT>SLsg^Jg)Ihrs@yk6d%#sVcbqRX%GWf#v3Wmx1}t(My;S3c4%+01h7# z=_P>azW8+xXYqIeMk{KYZ9g~L#6YeRQ|-m$9F_A4Z?J7c`& zs%j`tOqpaCW(fU(kBN|7NhmYx1~~AfVPI?l%6igvMJqjmdwssVllJ)C_%N)wWHLwm zIt)&hK&rs_jou?NUFIYVw^^AqDR_`#sdsK@hQ}clX%JW$EXkDt$^RCvTt2KNud-Av zkqvQLY#FFAuW8KMT0cCfsL2m*O8_rAyhV@e2I9E^#C-Xav2B-W{S9L+GJO0-+Nigbo^-^eP}AUIPS02pT}Tdg-Eq21G$AR+=D! z0*a0QUFV!VXHN;3EBE=o=lkS7_qn;5nRnJ+``v53d#!zT+P0}%x9`sb2mX3s=d>cn zcb58YYyFmqJ5FRRDRN~(`12|4*TnaJ#B^c!u!@^cMk*(>iHP?VF9mR|zi-C={Gn zKIHwV`HkYXO^n?(*72wri|`YxBC0rD%2bM%aHvA8l^Yvcwx@| z602J^YdR%FT~f4K!^7P&wGvq=!RkYY(;my6AjXy6^ktF7^A<{xhn-WBn=B|^G49Bz zgpogt9r@0?6&gM_X=vLQziqepje&Pt6uEJDLD0gm<{Opm?}xqAYRJBnoW{3rG|s74 zw$u}~vR_!+xy!UQ!JErJQdNm8T_rrN^&tdk3|F31zF-$UJl+rc6fR zM>kF1dNHJ0mtBo&%sZnuuU)F@kU4!n==z;7b5!Vp=MEH$i!U$9=6_)yOCP3OHkdt2hcc;RPR)>*t-qp))=z)Xjb2^ z4$K|%QTUjIN?o)fYcGZUSgOnZ!^)!O6_e^jCfwTj-LbBp7i!vLZ~c(*XFE44m;K|` z)WRv9#&&e#PKn}cu7CVkZ8=VyI{fofb4E>FzxcyyMMKjjfBVW9T-!TBOW4x*Vc7oWZR$DezO z&G{@6S5bHCw0hyqMVX^36>42>--Nm|QnqBrXD>Lqeq~PFpSd%aJ7)A;^7yIY^Sg{{ z_2&F;1ktupII_e_2Gry&(m=ZqZiR?SlrZjIdDHmS8dkQ+b_GdYxwfl*E_as-+$)Fyn(-eRC(y--3O*mtGD2E z$N698be)$qv%%Ogqn9S0KDX|h$M&45Jnp^DyJv>}KHk-J$DOTP*Z=YPuN&8--aJ~T zOt*})CF3uYcMY%p?wZ>>>*66->!1D8-Hk&^#e}wd>1e5@2ZAOY-xR;5S@o`EX$_ss zD0sbM!g*X+->uO==c~&KbWaO?a`~$nh0^3F8fe#p+8s}Ow3n2$Be+6Eoo5<_HvhDHr|j+9&n14bEi(6O+0pc^o2e}xJJvUCaEAu1 znbM>7!0FYpuN|9zWAx7%x2}#$y}Io{Mz0)t7_Ags;?pVtyt$&@n<)ha>yHdAupHbbesHrP& zAGsVg{kc`Q)sV)cA9IvE5IIK3T@-dGr}ymV>+4Grx{a)5{PCeKD4fPN zzkG37f#L_wH=a{r@ZPB`jJBrbh$`iN?=^pXo$$hg_IxqxgGx8ohm7v>V#ZhM zdzEjc_AHU`e3Plc-M?#JVN3bolgTBgb=f+0<;S<81;y}0Bxc9 zF;xn${&MBmdD3rn+I%cu-#5uQw?vtZ!Rx054?l9Q?Kc}ce)|2kO}{0E?wNJsn0P3( z#^%b2KOPV59r0eX;k|20kM!)eBL2jxzTKjmUF!79v=fEr%v}(aS@>pL+b-LiSJ#is zNIdx3SM>c!H#$3$I^|EbctZ;p6THbz~di%)3Rc2@|w%pLoQS(k@(w_ zgR=${ST(;EmF2pvYqlB|U2{6C^B36}1!w9i5)Fx>wUq&c_o6 z@4j5R+-HmSZ7q6fa#E?}*$ty+)UKqw@YSsNoL{C8pPk))cK4a#F7iad}J*a(p_mf@5J+)&%)pApk zuV+7#+j3jYeVyCf(z?a;3|U+`w6rth^UM~LI~CnqBs{L$tiso~_F0yD<=et34Zn)% z5m%_hMsZJOV#%p9%U2!w_*SR$-KgU0KmBOYp!h=9wDGmK-5B)wV<)p(#coWvxg)#v zmY&J2H=Mhq#mVund~$Mn%%+%?m-Z=5+a_PA&@rxUwN!EE8=syZG5EtH*Tj-#^lrl@ ze)V-y=NF5=J?ygr?e`XWD}2vu)p{5Hw$0l^;)`*zH>4s-Pm1)_Vs zRj2EQp0D;1PERWQWa>}Kq_Za{em}5Pl^qSPi{HOAVRLlIk>cmSedFNvny*fHa);Y%@}Y#CMUm4r35D9W|RoiSB&zX>iA)35Po*-2BTmPi=g;0TmLzj+rnJy&9w zKCtqzUm8^|y5N<^PUiGHIje5_6DPKANUl`*wTq)`>pU1 zaO&WY#Rm%Bxl`5P_t46Q78nZXOc-Yb!Wix|LjGXbp zfc4cMdN;HG$gtoyGE#PhJz65+R*!vqJ9jBlrPKQT>XF^gR2%hL#-h3PCfw-#Y3781 zm4^M&Gj8v`psTSddwzQLhaalc4f%dS>ysV!em&>)4{xVl89zSk@$g>j)I(n{dBiEN zxcteR0~Z!cYuG3#W$St6+vDRt{Cs@sodT88me-I%f{urk8(V6?-bKxNbsttLX-!P1 zuzWzdw=b73S7X2{Eq?vET!1 z7Uc?&>uH7(G7283_|a!5ZFl^7>|4F|_X+tnuED!GdmFYbNi(FkjQe0<{2R~ijv0RT z->ZU-I^SQHRIFgb^G6C5{W5l0aIroaca8-`XPl@}wnCRaZ)bl0^q>_h3-xXFVujnq zKB`cr*6PsoYK2B;Zu?}$ijo!U-KyI5a!5$_^X(>I-1Y3!ZJNEA^!UQ^KRnSlBjw!c zhf4=NdQ@K!lsoI;*hyDoDi&LnGdH;R#B~XmU+KE}lU`TXpI^2n`SybOA8g6k*Ko^M zg#1U$J2XiSEmg4O%wi2s zq`%YYrB*Xmj+~NQW>r=#ZT0K3{{8Qp7uLQ%u3U>N^-H}U|6$aIKU=K)bM(LVEqz$b zoTFu(e)W}uSAM?z?3ou*uU#$VN*N=UiwxBVoJa|EJu~fY-?+BIfvd|NEj_eAjh71T zs`LDmweLz&NJ8Srar-;x)c*3)wPh^_T-*L=rNn{n?Pwhu_FcuSuep5 zIie$1gd}dS8M$=Lkp`D1o;`e};?b>}ZuMI*cu9*>IUP2J|JXNT%J3+0rsG=6D1GCp z(q&7OyQGYmow#I%t7o$t+4Da>dSh?HuNOY|bfdFry+54#{jfbbIn!cG*4?UZy4&ye z>;|WAeG)rr@lvVw)R0F%KHP9_+VC2SN|lUTQzK$kaEXg6Ug#x81vkx3Y~SUDubURF z^jhV*7f+pjtn0Eq87tHD+SO;RdvnYFZD-$Hu=u;xFTeBDQ}ri*{MLwa5pC|I6#3W7 z@fW{bkSb}7m(9X)=vn`Ys#qm#`i7Xx`{H6xOj*}Ex@MuC{d;^GmN{icSY(6Xs>+xd zqpk*T-}Po>$i*6!%4r+koukBPn>((ke`ZHq&9+B|zt{QojZr~G%RHe+w-Nij-DPxW z=_S*H)^*KZx@+6fLtAEim-$Vlq5a16TUfC5ir~`GkzolZm`EHLf)wX-Zh| zj+DC7m$fR;J|yc#(F&1I^jlT?X2Iq!EWd@=6uT+?&vG5NbyCOGh`k;fle}lomn(`K zRgV`uxTInC1v_8tT>jziAwSi-z2o!uB9|w0jD5b#sZK{nKk;*iprY|HeapaKL8*`Jk|9K{)X1m*6w>Dbb_mA~2Tq&fK9Y6ST z+sqA9)^<<)srrixhqiT&KmSZ((51`*GgA-tANSnRqajV+IoUSaowBDx%d#hSP467i zU7C|~_>Z|eo;}s=nXxZ#QJ?-}g*>r9CFOGO535HvKU-%)^U^bWB#w@L?15nV*d-LRo)PT3_7O$*BEb~$)XHm^}qQ`hvz>i9a3Q2;i(JCK9f^>!I9Wtp;hK~wb~QYVq&MyD$w+$4@wt} z3og>~&!ca*>QXAVlcUJKn0EWxHJRM>tAx<`Tnn}DK0r&R1{T_WJwg|a6wch zK@18P9?aL@8)f8(^rSSHcJFuH|5e|?-TxE+Bi=DS!ZY^~(c>dVrKF7j4I-iyM?`AU zkd%n%hz?1EQo;p6jBrHs8JT9VBqCaHYBK%9yN32j84(fPZ9IE_LL+)-O5dcBgVXWC z_y~Gcbl^WdCORSprHnP-oemI3#4x-jI3$--am%7Z=;4S+!*68SDF|-O5#>^xic7-} zq9i*Ne13cceaI=r(1Nn2ugG68s6a6fi225 zmc+0mMQ}+PLFo#8x!{yURa7JkDN59ws^(S=C`H0Mqg=96Qbo6o1%DVLaw@v6t1=Bt z78Ms^sj4P>pk&eM#v6Cw zf-LE<*+R{e7Y3}w*Mvsl2`Pg|4H)4=Lz8NPL9%;Mk_Z^3YfcT10y&~|SRv7*OHPHz zW)A=yG~eoWDwt{_m?Eh<`9hO4%(nejP|SF%TXf>_A~)VEVYWrd0g6eoOXX0(AoHz~ zQ*s$g0Plfo@m57wB*B{@?5zUc0#pGrkHvtuO0q6;Zv_R+x8fzYgjIlrr5Y5*TEeuc z99=NU#(Q-a2qh9nb*CvMu{ku~pSR0=rl5>=goj&F2GP8pF1!9a7$ z^j)54WCi}WkG@y1n|Ixg=!ckxI{t0f;QPAg2<9; z#9v)?NfO+Tz@!RXY_x(0Jf=%JOvgmJRSCl+hlvmYEM&tDw?KSD>`+}u3ltt)y5_Py z#)ub)8OD4PGw|h>ad}fC5HpQTmyi7ALO8{&m|oEk=yYR_-7eXsAfl<36_hfuf=!0# zvW&b0pJRR`Zt+{8r- zL9D?dBPL=CnZ?oa)7LwDvI8S2!lF}74LKFh%E4=g0pZ5Vqln6;Lp{Kl2Mkd|5*BsI3z(QBa!fK^YA`7fqosTX zTe3qVdeQ)08vbidGGZN)p=VuT(d%ZMl69~K1|dbL3O@}Tp`m{~h>GDcYzriwe8^6! zCXsGH(nGjMq{C0Dj_>5w2*+p5nlUm`)>MmqGT!cqzF;3Dn#n#56g9jix)9)P_HlgH zEVl|S6$(u^5iv@)ht87I^o)q8PJThuL>}R0l;g5yhE2nXA`~O}Q;j8%x}p7R{|YWGD*IjAIA+PL-kb3@<`_VKLJOkXo?0vIotPS!2-) zZj>xJhYw(7VJcaG7m^z*bUJQO>B@(#6MFMAcM)YOj)`i-(U$tyCM~0!6W2Aw$nV>zOq}w&Ir90i&hj4JlA{0fC&E%R4hGKi;s~&uz zAce4H@ENOt1r_4L9j^#)Q2!8ke#Th@_C-W=&jV3%>nhd?rF@At7>4_}(OUfV1tfhU zIz=~fi_d%ri0QO{fZ~u;7ohn8Tg3H6qm=`RMS;-=4Z2K2?1hRj_lmye@x1jzH67*S zN5&b|WpT#X>Y1GJ;ce5Dq(1rNt*Bz7smoZ~(6JPQEMg%Qhyp?l5}2rKv=}9i!K#NNxTa-qv2s6QC=EUj&k#TP6lSrKWkKyrg9 zDv_wvxTS4z(-%uYl$T^$)+|n7?C7h{49 zYPx7|rDGu=z&J$s$i?e1i=cqQE*dJyG)z%M6AO8tWo_EVqr?PtjDip;N0e@my*O22 zX#l(rNf3KY3k&JWuuGCP7T?{d`asPYn`l{w>d-)0x5C9ci=V*K1W`xk!%rg0RM;5M z7-dyqW7MGs!69I&#(H#Us6M%%UOWrO;wSkF`hc0`GG+mLQpK~sfE8{xNlYC~h2ll^ zM)Xp|7CQ+EJ2PlX(=04MYlw=_f|?Nw1IgbZ@H;BE<9d<_HS!vPDR78tj5 zk(p5wP?20b;YASZcAlclEQoa(`vJo&(%BFTgvsKUH#>l7vBQs}@k7&6lJZYcI2O{Lr=`a^ z0x=h5Jl$X`;x~Dm-vlsbS{PI$L50#BiAhbJqb3ID!ZJ5s=YNipF>}}*_|wz^=6MAa zRC;A_USg9->j!lm<9lsfM0^#h1%(P5m(ewV!T6Q;vb2#v3(6sqHAk2Ml!k0j####$ zi^P*#dABmgp8o?lef)3DyGOE5bgNPc4EVf}5X_;X*7pS@eY2yN>XMqu-j2%27x@7cBFjOES z>T)#(i>?gOrYmKCqftbiGpepq+X^C>kBerMWuJxLJ)t#^nbgqupqZo^FZ@7-V(hH# z@$r$CgY`sL%4NPBy%$3aWS*Vz15*2?qzU;|1kjDvP67o<+Wn(901eNC91=EkklP`n z_oid1Q0EWzAA4MO$o+dbObB?{L*>hS+G9sl&K?`blf~{gE<1>FIRAlv?4Zfv*!KKo zKih$m!?Aif`I#@Chlmaw7*xFF?E5+?FY@KLEr4vUQrVu*r}oNc8zuxFv<%EVAfT_K zph<%O!!0h0gf<+uFOs1`u@VvJQQhD|KcX2n8X~DC4W)AhApoyZw6yhrO>m2t7B-5v z2+*(vYXQGfpwW0_YznA$jbD-egE&Ra%*=$wPQ&O-aCTc{Wp>*`_edUy3r}`NNWm7$ zfHSk9j~6V;T4+dWR3kIfoB0!SC=Y7oYXb@!V~-%R9bhro1IuKI$3`yYBeEma1%$B( zY`{<%+$;5P@zoAs zRc~T=8|Upbe_rIp&HR!Rt#<{@W$gCRw<7J&DK|s5+S*v;Tw>AD{4^9a8Xf{dA%L)g zSoCE92Vze_iJA*tv_GJdi5+GvPFjF`oaIEX1xSKj*Ufzji7DL(4vH6^#Y+nhGp^wL z0!3!zn?Q(yiu#igVyKJ*6>C__TWGPDUI zFMH9Hh^pEa4!Q5T(<4S z%;v$+{B~L)&dtI()-D~K5WzMTeOy+Eqtco}T?@0fsp{yssh~3s`0!hJ7C(73D!*80 ztYpH_XceHh05r5<{J>ZM{fl7tF^z>#9xd;I;@FbMG&IBfY-2%`N6UMl92z)mp>e5| zg;5@jv(3kCGKzDS+cfA&KigO!<E z$;v|BIw_A;=#jD>96PciZefc^iqdloi(kxm*(2Y)VueS-nwXqv_=rc(vS7`l!r`;(mOcchfbAjl!pprxd z6z}eo8zn#mL&E7tbZ{IhG5}W>vDj%uT*zc2Mgj?E156~YH5H}PXCot~ zBv;$ASV;jFttmR{i=P0d(^*(Di|b8Ap{P!WK~XY8T_3^$r~Gh|(N+%@9|;V-DKxlE zFdUx4zK+1S<`n)fj-I+5)VM)&3OvM$kU7gNG7=b?Q}B{un0b1Ku(;+FksarMp&8NW zq|xF;2-1;ln8iavuv=3QwAK*q-V~jbmf=YUYFjh{hYMW?L}weyA|(w`70kZ0(K5rX z!5pI9oQgsNj%=rCMB`ec{+o^o=fJo#RX`+S7(FgR6wFiNe}xzZpk0P)7ybY{Q!H+x zPlH+^NTFa5bbyZPb;!)zXjpO&&_?nvle$UY(G1}44CA2-G++@CkmqgZu=F0F@52Rl z7BJD`!g)=sC0U_!h3InO7ii1ccr3vOFb|;v%{9`co>YoOyexhZDdI;AkVHw^8yZ0`f zCe}F0MiYw@jK;)b0dW({2T<0ax<67Y@g5^anUAR-5vC^j}4H2*M*Y>lm$g!(TfGHTjj8;BD&_Hb~L82ozQnMWY@US~idsTo$m183@nAe2eV>!}L;-MxrACgoP6_{xZOW6^Kgk z7tVuWKZ=u<#z{u3Dp}wRviQhAOiEL9p_!s{g$9vW9x-}kSSM(aq2@)WiK#_~ZjS9S zo{|iew+yHPPF_)VVm*PpIpW932hov&=JRdcl4y#;q z1DzXR9Gs-49d8s`TP{4!My)MW>;38J-6in{QV;@UIvfb)hsVw&2R?waPu#rOag(=5 z^|c7+P+YR1b8sNVIOZygIIU+-mmMiN9DffXo8rt9!lwcOLG55S%Fj4LY6IE9kpl`a zGJGEAUjYPP!8Z;Zn4>+94P-~iKtPN$G-o)dVN97$j{>28Pt@aZI5q0+Z~x)tNdNDSh(cGSyHA}1s9s65zGl=FADQDUk+JmtONZAw3EebQ{@ha{|7B)O* zCFqc>0ugDJ<@id0jcbKV3m0(Rb{&(Xq6RAza>A_k=s^d${hU^;^8$L5v* zr)!LEonL{qUARg3{PNwq3t_c2ygMZDp4pxvNt^%vlnKT<8h-(d3D`glmwQ{rx;GpJ zS@_LASb#Phi@^^BjK$#x0>)yo517%2yY~bH@EOloZ+=)^s=qu7#sc$?%3^+5%32cK z!eP3VTh2IX6>tSwG1&mY!yz09makvGiU;K55chjKZdhEk?Bfcmkb!m}wH7vhWyfV6 z+J&Bm%Q%n5sYZ*r0fufCSDV|j^vJ9`8$%wfHT;c5F{9!==MEl!L!+a z@L&KQho&Tgj+GOv~tlf7Q86+915 zIocl$zNMm}fflg0!XmI29JR{=!=dkUPdFBX{~8=Mei)orn}#J+7KQVIW4%Gsb=2cx zZ~+I);xG?qG`Ru~R>uhf%Xd^?HoIKhE}2DQ9xm^RrJfmsgA5MPG~>lFk9iLhIZQN7 zZ4-^v<{yov{6=He%rH&}FoDZr2ft$IaTMH7LJFC7;cT7StKOrQxmF8=553(#ieQUI z&(s^D7opTvbeJg5D>k-AF`L+U6Yd>w869ln)GY+Gfn^!at!`c?)AQna2WRF9E}CMC zfag~!p0FJdonXQt3q#Mr3ld$WKrd5@@C?GX+asFEZm`2sZs2~jY^J>?3bE9bCoq!9 zW_c_iutzeR4ha~kd6Pg)R5m?lkUSFE<4-pAp86;EwTQ*&3DT2mwsJN0P#hpf?EsEs z3Es;jJHpdBcrMx-ur{|_hIi;cpkM!d9*D)<;mKXvsL<2yI!Zb?9>c;3p2^2Pn2z_N zsb%bFRZI=;!LUbU(HStfmjNtN(OOUl1qZ3wSugMm4>W<`xL*LJeXsx}f3%gj4Y9>s zFc$SUGkl5ktRHpg@kq7j>0r|1X!{sgsMX;pFAg{2!F{f3V1-^l;eH6?q9AN8aPtL_ zD1fl1ez1=ON$D{=bnDQ^z$26x8)YHS^jow967FwM&0|zJhC_XR^Z=NX=rI}`0XIyd zqclLIx*s|jHj>3d+DoGqXVj?BM!+#{3KI3(->ep{Te3??we2c zfnXXvb;ju(&&uMsPUSxCKo16m%Okjs4$}e_8a_!kMVL|3Kd54L1=gf=tqryh{LnARu{;Gx71Cwgqe>590;od;Wq2rWh=H`BX(i_0&(8D|n0Pb)2L! zD@Z66qcEv)>y@d808}vDVgytMjJzkKT5rTyuP>o4BC>()3!dW4A)N9JFoC=actwn$ zgKiyN_2b9+_@P77^T~NEdE6*~b3-1cgWY&~m>vRC>A_e;5In7er(3z5k;QQKS)MQc z-lv1p#&rx3PYTX$qtS*#1h!|aU>gW5z+95gaD1Fnv0KpbcsM;Hfj+X0XOWrVAztDJ z8ngLet^=>F7TS7Xb92?-4ep1(}jGq(c&w^GrO23A!+1z9G_$l<10OKjcz%H zNykBOTAm(G6!2)WZ6HrnhKdk{g-wkJu)^O=lQEQY48~BFME{D4vIZ<4l{*Yg$?rol z7(32H&~swA>jzmT!1v>MXFLXNNgdD^&(auD$KmGWlSNv8INZ5HpOx5-kB@2a4t8l& z{?i>e)qzOv&s-DHXdM{_2J#T*jej%&hf$12PhAc-9->9kwEb_<*VoLzpzNqDPQG9{ z;F(n;8DP?(c)0ayarmzo%DWPE3>{)a_ouI~bsnk6f1FR5Zd4#Ji}o-r-ujwEqK7== zp)8FHMSf#kSo63+O`@rFJ8)GU+C7}(c;fon=g%2x5keK3>X`pOL>V92w)@YtEF_;| zT*rtAh#CT|Ij9SW75maJa0_c1XN~A;GAKUpoWazr(dDMQNa*?@y7G~r+?-ScV{x*K zq#7RAr^^FyM3D}*a1>yYmV!H7$B5U_B87^CSi{{x%qY+dtIfFgM8~}dbTJ%*`iabG2ATJ-l3)w!t8G%aQx*U8bzRU9lZu7v^?v;-5{6djD~Hbr!e zjgxa|tEspR)3%DqTH4goRZob1ILu`@9rW`QhNx3!o`*tL)_h{0y0v-9T9Xaboz4#% zFoS+%{2R*F&hos3#YPm9jm-wPntVhotj4~F4whmQ1RaMXQux_(&w!WqK}80q11V-= z&Jo{mag8%EoWXR+|2RYJg7O;K-ZtGH<`lF+WEC4c*Gm zvL_3{LS!3^hh`Ehjt)I(To${Behrjo@p0^X5i7B1AZ$!T?DM&p;Ui)x%Hk77U5KL# z3yp}^ROO)R5iXyl1FkMy|Km?(TYoW@d8mQ-Eh3Parx;|2B0Ofv?_+#qE0&h$@fHd} zzMC(k797jP^#d@9Zg#@m4!G~uUIIR{mG@FWMF@J*y`w-gBRX!4!6^-n{yw^upGH3o zfV_`#4qasjzmlv5e{szY7p-`jGN*aj7+@0eB8eY6AAn}{Fq79uc%%qIP37g4mqxV} zWdQ3@8^E@TstQmLm|W3#?iH8nAl;!pWY3(%OkYLBIh?VQ%0=drSBTquw85!#1<&=^ znEBGEoX(=;Yf5vdY22xU(w)j*?v;mh4FF0qMxlZSFzL{ZWE7!M{6Im&TXJxfSU+P? z$i)#puk$55jrf`J5Q=2O#QzcZxBp!ul9NWH)cw04_xU{bc#wL&_x`j0k5}V0q@$jkr7@BcUEKRsnc`iTD?3-UGpl7PSeKz9lMGye~S-}eFG z=AT#)l{8{R%7f-Y{^no7{Nox)^`H5_&(uATm-CqaU(;2#hCukyhE15A4H A_5c6? literal 0 HcmV?d00001 diff --git a/tests/test-assets/bundles/bundle.tar.gz b/tests/test-assets/bundles/bundle.tar.gz deleted file mode 100644 index 851d84fc7d713bb90f1df0e5049757dfa6fca311..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32636 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