@plasius/gpu-shared 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -3
- package/README.md +55 -1
- package/assets/brigantine.gltf +549 -24
- package/assets/cutter.gltf +538 -0
- package/assets/harbor-dock.gltf +680 -0
- package/assets/lighthouse.gltf +604 -0
- package/dist/chunk-2FIFSBB4.js +74 -0
- package/dist/chunk-2FIFSBB4.js.map +1 -0
- package/dist/chunk-DABW627O.js +113 -0
- package/dist/chunk-DABW627O.js.map +1 -0
- package/dist/chunk-DQX4DXBR.js +369 -0
- package/dist/chunk-DQX4DXBR.js.map +1 -0
- package/dist/chunk-NCPJWLX3.js +17 -0
- package/dist/chunk-NCPJWLX3.js.map +1 -0
- package/dist/gltf-loader-WAM23F37.js +9 -0
- package/dist/index.cjs +1255 -279
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +19 -6
- package/dist/index.js.map +1 -1
- package/dist/showcase-inline-assets-B7U7VX5H.js +7 -0
- package/dist/{showcase-runtime-2ZNPKD7D.js → showcase-runtime-PN7N3FZY.js} +808 -237
- package/dist/showcase-runtime-PN7N3FZY.js.map +1 -0
- package/package.json +15 -1
- package/src/asset-url.js +62 -11
- package/src/feature-flags.js +1 -0
- package/src/gltf-loader.js +322 -32
- package/src/i18n.js +71 -0
- package/src/index.d.ts +115 -1
- package/src/index.js +9 -1
- package/src/showcase-inline-assets.js +3 -0
- package/src/showcase-runtime.js +912 -188
- package/src/translations/en-GB.js +55 -0
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-OTCJ3VOK.js +0 -35
- package/dist/chunk-OTCJ3VOK.js.map +0 -1
- package/dist/chunk-QBMXJ3V2.js +0 -142
- package/dist/chunk-QBMXJ3V2.js.map +0 -1
- package/dist/gltf-loader-LKALCZAV.js +0 -8
- package/dist/showcase-runtime-2ZNPKD7D.js.map +0 -1
- /package/dist/{chunk-DGUM43GV.js.map → gltf-loader-WAM23F37.js.map} +0 -0
- /package/dist/{gltf-loader-LKALCZAV.js.map → showcase-inline-assets-B7U7VX5H.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -19,9 +19,24 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
19
19
|
};
|
|
20
20
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
21
|
|
|
22
|
+
// src/showcase-inline-assets.js
|
|
23
|
+
var showcase_inline_assets_exports = {};
|
|
24
|
+
__export(showcase_inline_assets_exports, {
|
|
25
|
+
INLINE_SHOWCASE_ASSET_URLS: () => INLINE_SHOWCASE_ASSET_URLS
|
|
26
|
+
});
|
|
27
|
+
var INLINE_SHOWCASE_ASSET_URLS;
|
|
28
|
+
var init_showcase_inline_assets = __esm({
|
|
29
|
+
"src/showcase-inline-assets.js"() {
|
|
30
|
+
INLINE_SHOWCASE_ASSET_URLS = Object.freeze({
|
|
31
|
+
"brigantine": "data:application/json;base64,ewogICJhc3NldCI6IHsKICAgICJ2ZXJzaW9uIjogIjIuMCIsCiAgICAiZ2VuZXJhdG9yIjogIkBwbGFzaXVzL2dwdS1zaGFyZWQgc2hvd2Nhc2UgYXNzZXQgZ2VuZXJhdG9yIgogIH0sCiAgInNjZW5lIjogMCwKICAic2NlbmVzIjogWwogICAgewogICAgICAibm9kZXMiOiBbCiAgICAgICAgMAogICAgICBdCiAgICB9CiAgXSwKICAibm9kZXMiOiBbCiAgICB7CiAgICAgICJuYW1lIjogImJyaWdhbnRpbmUiLAogICAgICAiY2hpbGRyZW4iOiBbCiAgICAgICAgMSwKICAgICAgICAyLAogICAgICAgIDMKICAgICAgXSwKICAgICAgImV4dHJhcyI6IHsKICAgICAgICAicGh5c2ljcyI6IHsKICAgICAgICAgICJzaGFwZSI6ICJib3giLAogICAgICAgICAgImhhbGZFeHRlbnRzIjogWwogICAgICAgICAgICAxLjU4LAogICAgICAgICAgICAxLjEyLAogICAgICAgICAgICA0LjQKICAgICAgICAgIF0sCiAgICAgICAgICAibWFzcyI6IDQ3MDAsCiAgICAgICAgICAicmVzdGl0dXRpb24iOiAwLjIsCiAgICAgICAgICAibGluZWFyRGFtcGluZyI6IDAuMDM4LAogICAgICAgICAgImFuZ3VsYXJEYW1waW5nIjogMC4wNzYsCiAgICAgICAgICAid2F0ZXJsaW5lIjogMC40NAogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgIHsKICAgICAgIm5hbWUiOiAiYnJpZ2FudGluZS1odWxsIiwKICAgICAgIm1lc2giOiAwCiAgICB9LAogICAgewogICAgICAibmFtZSI6ICJicmlnYW50aW5lLXJpZyIsCiAgICAgICJtZXNoIjogMQogICAgfSwKICAgIHsKICAgICAgIm5hbWUiOiAiYnJpZ2FudGluZS1sYW50ZXJucyIsCiAgICAgICJtZXNoIjogMgogICAgfQogIF0sCiAgIm1lc2hlcyI6IFsKICAgIHsKICAgICAgIm5hbWUiOiAiYnJpZ2FudGluZS1odWxsIiwKICAgICAgInByaW1pdGl2ZXMiOiBbCiAgICAgICAgewogICAgICAgICAgImF0dHJpYnV0ZXMiOiB7CiAgICAgICAgICAgICJQT1NJVElPTiI6IDAsCiAgICAgICAgICAgICJOT1JNQUwiOiAxCiAgICAgICAgICB9LAogICAgICAgICAgImluZGljZXMiOiAyLAogICAgICAgICAgIm1hdGVyaWFsIjogMAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImF0dHJpYnV0ZXMiOiB7CiAgICAgICAgICAgICJQT1NJVElPTiI6IDMsCiAgICAgICAgICAgICJOT1JNQUwiOiA0CiAgICAgICAgICB9LAogICAgICAgICAgImluZGljZXMiOiA1LAogICAgICAgICAgIm1hdGVyaWFsIjogMQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImF0dHJpYnV0ZXMiOiB7CiAgICAgICAgICAgICJQT1NJVElPTiI6IDYsCiAgICAgICAgICAgICJOT1JNQUwiOiA3CiAgICAgICAgICB9LAogICAgICAgICAgImluZGljZXMiOiA4LAogICAgICAgICAgIm1hdGVyaWFsIjogMgogICAgICAgIH0KICAgICAgXQogICAgfSwKICAgIHsKICAgICAgIm5hbWUiOiAiYnJpZ2FudGluZS1yaWciLAogICAgICAicHJpbWl0aXZlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAiYXR0cmlidXRlcyI6IHsKICAgICAgICAgICAgIlBPU0lUSU9OIjogOSwKICAgICAgICAgICAgIk5PUk1BTCI6IDEwCiAgICAgICAgICB9LAogICAgICAgICAgImluZGljZXMiOiAxMSwKICAgICAgICAgICJtYXRlcmlhbCI6IDMKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJhdHRyaWJ1dGVzIjogewogICAgICAgICAgICAiUE9TSVRJT04iOiAxMiwKICAgICAgICAgICAgIk5PUk1BTCI6IDEzCiAgICAgICAgICB9LAogICAgICAgICAgImluZGljZXMiOiAxNCwKICAgICAgICAgICJtYXRlcmlhbCI6IDQKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJhdHRyaWJ1dGVzIjogewogICAgICAgICAgICAiUE9TSVRJT04iOiAxNSwKICAgICAgICAgICAgIk5PUk1BTCI6IDE2CiAgICAgICAgICB9LAogICAgICAgICAgImluZGljZXMiOiAxNywKICAgICAgICAgICJtYXRlcmlhbCI6IDUKICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJuYW1lIjogImJyaWdhbnRpbmUtbGFudGVybnMiLAogICAgICAicHJpbWl0aXZlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAiYXR0cmlidXRlcyI6IHsKICAgICAgICAgICAgIlBPU0lUSU9OIjogMTgsCiAgICAgICAgICAgICJOT1JNQUwiOiAxOQogICAgICAgICAgfSwKICAgICAgICAgICJpbmRpY2VzIjogMjAsCiAgICAgICAgICAibWF0ZXJpYWwiOiA2CiAgICAgICAgfQogICAgICBdCiAgICB9CiAgXSwKICAibWF0ZXJpYWxzIjogWwogICAgewogICAgICAibmFtZSI6ICJwYWludGVkLWh1bGwiLAogICAgICAicGJyTWV0YWxsaWNSb3VnaG5lc3MiOiB7CiAgICAgICAgImJhc2VDb2xvckZhY3RvciI6IFsKICAgICAgICAgIDAuNDIsCiAgICAgICAgICAwLjI0LAogICAgICAgICAgMC4xNiwKICAgICAgICAgIDEKICAgICAgICBdLAogICAgICAgICJtZXRhbGxpY0ZhY3RvciI6IDAuMDgsCiAgICAgICAgInJvdWdobmVzc0ZhY3RvciI6IDAuNzYKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgIm5hbWUiOiAiZGVjay1wbGFuayIsCiAgICAgICJwYnJNZXRhbGxpY1JvdWdobmVzcyI6IHsKICAgICAgICAiYmFzZUNvbG9yRmFjdG9yIjogWwogICAgICAgICAgMC41MywKICAgICAgICAgIDAuMzksCiAgICAgICAgICAwLjI2LAogICAgICAgICAgMQogICAgICAgIF0sCiAgICAgICAgIm1ldGFsbGljRmFjdG9yIjogMC4wMiwKICAgICAgICAicm91Z2huZXNzRmFjdG9yIjogMC45CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJuYW1lIjogImh1bGwtdHJpbSIsCiAgICAgICJwYnJNZXRhbGxpY1JvdWdobmVzcyI6IHsKICAgICAgICAiYmFzZUNvbG9yRmFjdG9yIjogWwogICAgICAgICAgMC43MiwKICAgICAgICAgIDAuNzEsCiAgICAgICAgICAwLjY2LAogICAgICAgICAgMQogICAgICAgIF0sCiAgICAgICAgIm1ldGFsbGljRmFjdG9yIjogMC4xOCwKICAgICAgICAicm91Z2huZXNzRmFjdG9yIjogMC40MgogICAgICB9CiAgICB9LAogICAgewogICAgICAibmFtZSI6ICJtYXN0LXdvb2QiLAogICAgICAicGJyTWV0YWxsaWNSb3VnaG5lc3MiOiB7CiAgICAgICAgImJhc2VDb2xvckZhY3RvciI6IFsKICAgICAgICAgIDAuMzcsCiAgICAgICAgICAwLjI3LAogICAgICAgICAgMC4xOCwKICAgICAgICAgIDEKICAgICAgICBdLAogICAgICAgICJtZXRhbGxpY0ZhY3RvciI6IDAuMDIsCiAgICAgICAgInJvdWdobmVzc0ZhY3RvciI6IDAuODIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgIm5hbWUiOiAic2FpbC1jYW52YXMiLAogICAgICAicGJyTWV0YWxsaWNSb3VnaG5lc3MiOiB7CiAgICAgICAgImJhc2VDb2xvckZhY3RvciI6IFsKICAgICAgICAgIDAuODIsCiAgICAgICAgICAwLjc5LAogICAgICAgICAgMC43MiwKICAgICAgICAgIDEKICAgICAgICBdLAogICAgICAgICJtZXRhbGxpY0ZhY3RvciI6IDAsCiAgICAgICAgInJvdWdobmVzc0ZhY3RvciI6IDAuOTYKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgIm5hbWUiOiAibWV0YWwtZGFyayIsCiAgICAgICJwYnJNZXRhbGxpY1JvdWdobmVzcyI6IHsKICAgICAgICAiYmFzZUNvbG9yRmFjdG9yIjogWwogICAgICAgICAgMC4yMSwKICAgICAgICAgIDAuMjIsCiAgICAgICAgICAwLjI0LAogICAgICAgICAgMQogICAgICAgIF0sCiAgICAgICAgIm1ldGFsbGljRmFjdG9yIjogMC44NCwKICAgICAgICAicm91Z2huZXNzRmFjdG9yIjogMC4zNAogICAgICB9CiAgICB9LAogICAgewogICAgICAibmFtZSI6ICJ3YXJtLWdsYXNzIiwKICAgICAgInBick1ldGFsbGljUm91Z2huZXNzIjogewogICAgICAgICJiYXNlQ29sb3JGYWN0b3IiOiBbCiAgICAgICAgICAwLjk1LAogICAgICAgICAgMC44MiwKICAgICAgICAgIDAuNTYsCiAgICAgICAgICAwLjg0CiAgICAgICAgXSwKICAgICAgICAibWV0YWxsaWNGYWN0b3IiOiAwLjAyLAogICAgICAgICJyb3VnaG5lc3NGYWN0b3IiOiAwLjE2CiAgICAgIH0sCiAgICAgICJlbWlzc2l2ZUZhY3RvciI6IFsKICAgICAgICAwLjkyLAogICAgICAgIDAuNywKICAgICAgICAwLjM0CiAgICAgIF0sCiAgICAgICJhbHBoYU1vZGUiOiAiQkxFTkQiCiAgICB9CiAgXSwKICAiYnVmZmVycyI6IFsKICAgIHsKICAgICAgInVyaSI6ICJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsQUFBQUFJWHJVYi9Oekl6QWZQS3dQc2U2dUw3TnpJekFsLzhRUDlQZTRMNEFBRkRBQUFBQUFJWHJVYi9Oekl6QWwvOFFQOVBlNEw0QUFGREFBQUFBQUkvQ2RiOEFBRkRBZlBLd1BzZTZ1TDdOekl6QW5ETWlQeHBSMmo3TnpJekFTK3FFUDBJKzZENEFBRkRBZlBLd1BzZTZ1TDdOekl6QVMrcUVQMEkrNkQ0QUFGREFsLzhRUDlQZTRMNEFBRkRBbkRNaVB4cFIyajdOekl6QTdGRTRQNFhyVVQvTnpJekFQUXFYUDJabVpqOEFBRkRBbkRNaVB4cFIyajdOekl6QVBRcVhQMlptWmo4QUFGREFTK3FFUDBJKzZENEFBRkRBN0ZFNHY0WHJVVC9Oekl6QW5ETWl2eHBSMmo3TnpJekFTK3FFdjBJKzZENEFBRkRBN0ZFNHY0WHJVVC9Oekl6QVMrcUV2MEkrNkQ0QUFGREFQUXFYdjJabVpqOEFBRkRBbkRNaXZ4cFIyajdOekl6QWZQS3d2c2U2dUw3TnpJekFsLzhRdjlQZTRMNEFBRkRBbkRNaXZ4cFIyajdOekl6QWwvOFF2OVBlNEw0QUFGREFTK3FFdjBJKzZENEFBRkRBZlBLd3ZzZTZ1TDdOekl6QUFBQUFBSVhyVWIvTnpJekFBQUFBQUkvQ2RiOEFBRkRBZlBLd3ZzZTZ1TDdOekl6QUFBQUFBSS9DZGI4QUFGREFsLzhRdjlQZTRMNEFBRkRBQUFBQUFJL0NkYjhBQUZEQWwvOFFQOVBlNEw0QUFGREFvV2N6UDQvazhyNW1aZ2JBQUFBQUFJL0NkYjhBQUZEQW9XY3pQNC9rOHI1bVpnYkFBQUFBQUxnZWhiOW1aZ2JBbC84UVA5UGU0TDRBQUZEQVMrcUVQMEkrNkQ0QUFGREFWSFNrUDl1Sy9UNW1aZ2JBbC84UVA5UGU0TDRBQUZEQVZIU2tQOXVLL1Q1bVpnYkFvV2N6UDQvazhyNW1aZ2JBUytxRVAwSSs2RDRBQUZEQVBRcVhQMlptWmo4QUFGREFTT0c2UDBqaGVqOW1aZ2JBUytxRVAwSSs2RDRBQUZEQVNPRzZQMGpoZWo5bVpnYkFWSFNrUDl1Sy9UNW1aZ2JBUFFxWHYyWm1aajhBQUZEQVMrcUV2MEkrNkQ0QUFGREFWSFNrdjl1Sy9UNW1aZ2JBUFFxWHYyWm1aajhBQUZEQVZIU2t2OXVLL1Q1bVpnYkFTT0c2djBqaGVqOW1aZ2JBUytxRXYwSSs2RDRBQUZEQWwvOFF2OVBlNEw0QUFGREFvV2N6djQvazhyNW1aZ2JBUytxRXYwSSs2RDRBQUZEQW9XY3p2NC9rOHI1bVpnYkFWSFNrdjl1Sy9UNW1aZ2JBbC84UXY5UGU0TDRBQUZEQUFBQUFBSS9DZGI4QUFGREFBQUFBQUxnZWhiOW1aZ2JBbC84UXY5UGU0TDRBQUZEQUFBQUFBTGdlaGI5bVpnYkFvV2N6djQvazhyNW1aZ2JBQUFBQUFMZ2VoYjltWmdiQW9XY3pQNC9rOHI1bVpnYkFnU1pDUDIzbis3NHpNek8vQUFBQUFMZ2VoYjltWmdiQWdTWkNQMjNuKzc0ek16Ty9BQUFBQUhFOWlyOHpNek8vb1djelA0L2s4cjVtWmdiQVZIU2tQOXVLL1Q1bVpnYkFvZml4UDVNWUJEOHpNek8vb1djelA0L2s4cjVtWmdiQW9maXhQNU1ZQkQ4ek16Ty9nU1pDUDIzbis3NHpNek8vVkhTa1A5dUsvVDVtWmdiQVNPRzZQMGpoZWo5bVpnYkFjVDNLUDF5UGdqOHpNek8vVkhTa1A5dUsvVDVtWmdiQWNUM0tQMXlQZ2o4ek16Ty9vZml4UDVNWUJEOHpNek8vU09HNnYwamhlajltWmdiQVZIU2t2OXVLL1Q1bVpnYkFvZml4djVNWUJEOHpNek8vU09HNnYwamhlajltWmdiQW9maXh2NU1ZQkQ4ek16Ty9jVDNLdjF5UGdqOHpNek8vVkhTa3Y5dUsvVDVtWmdiQW9XY3p2NC9rOHI1bVpnYkFnU1pDdjIzbis3NHpNek8vVkhTa3Y5dUsvVDVtWmdiQWdTWkN2MjNuKzc0ek16Ty9vZml4djVNWUJEOHpNek8vb1djenY0L2s4cjVtWmdiQUFBQUFBTGdlaGI5bVpnYkFBQUFBQUhFOWlyOHpNek8vb1djenY0L2s4cjVtWmdiQUFBQUFBSEU5aXI4ek16Ty9nU1pDdjIzbis3NHpNek8vQUFBQUFIRTlpcjh6TXpPL2dTWkNQMjNuKzc0ek16Ty9WbjB1UDBDazM3NW1ab1kvQUFBQUFIRTlpcjh6TXpPL1ZuMHVQMENrMzc1bVpvWS9BQUFBQUVqaGVyOW1ab1kvZ1NaQ1AyM24rNzR6TXpPL29maXhQNU1ZQkQ4ek16Ty81ZktmUC84aC9UNW1ab1kvZ1NaQ1AyM24rNzR6TXpPLzVmS2ZQLzhoL1Q1bVpvWS9WbjB1UDBDazM3NW1ab1kvb2ZpeFA1TVlCRDh6TXpPL2NUM0tQMXlQZ2o4ek16Ty9qOEsxUDQvQ2RUOW1ab1kvb2ZpeFA1TVlCRDh6TXpPL2o4SzFQNC9DZFQ5bVpvWS81ZktmUC84aC9UNW1ab1kvY1QzS3YxeVBnajh6TXpPL29maXh2NU1ZQkQ4ek16Ty81Zktmdi84aC9UNW1ab1kvY1QzS3YxeVBnajh6TXpPLzVmS2Z2LzhoL1Q1bVpvWS9qOEsxdjQvQ2RUOW1ab1kvb2ZpeHY1TVlCRDh6TXpPL2dTWkN2MjNuKzc0ek16Ty9WbjB1djBDazM3NW1ab1kvb2ZpeHY1TVlCRDh6TXpPL1ZuMHV2MENrMzc1bVpvWS81Zktmdi84aC9UNW1ab1kvZ1NaQ3YyM24rNzR6TXpPL0FBQUFBSEU5aXI4ek16Ty9BQUFBQUVqaGVyOW1ab1kvZ1NaQ3YyM24rNzR6TXpPL0FBQUFBRWpoZXI5bVpvWS9WbjB1djBDazM3NW1ab1kvQUFBQUFFamhlcjltWm9ZL1ZuMHVQMENrMzc1bVpvWS9zQVBuUGpTQXQ3NHpNeU5BQUFBQUFFamhlcjltWm9ZL3NBUG5QalNBdDc0ek15TkFBQUFBQUQwS1Y3OHpNeU5BVm4wdVAwQ2szNzVtWm9ZLzVmS2ZQLzhoL1Q1bVpvWS9ZY05UUDljMDd6NHpNeU5BVm4wdVAwQ2szNzVtWm9ZL1ljTlRQOWMwN3o0ek15TkFzQVBuUGpTQXQ3NHpNeU5BNWZLZlAvOGgvVDVtWm9ZL2o4SzFQNC9DZFQ5bVpvWS8xNk53UDY1SFlUOHpNeU5BNWZLZlAvOGgvVDVtWm9ZLzE2TndQNjVIWVQ4ek15TkFZY05UUDljMDd6NHpNeU5BajhLMXY0L0NkVDltWm9ZLzVmS2Z2LzhoL1Q1bVpvWS9ZY05UdjljMDd6NHpNeU5BajhLMXY0L0NkVDltWm9ZL1ljTlR2OWMwN3o0ek15TkExNk53djY1SFlUOHpNeU5BNWZLZnYvOGgvVDVtWm9ZL1ZuMHV2MENrMzc1bVpvWS9zQVBudmpTQXQ3NHpNeU5BNWZLZnYvOGgvVDVtWm9ZL3NBUG52alNBdDc0ek15TkFZY05UdjljMDd6NHpNeU5BVm4wdXYwQ2szNzVtWm9ZL0FBQUFBRWpoZXI5bVpvWS9BQUFBQUQwS1Y3OHpNeU5BVm4wdXYwQ2szNzVtWm9ZL0FBQUFBRDBLVjc4ek15TkFzQVBudmpTQXQ3NHpNeU5BQUFBQUFEMEtWNzh6TXlOQXNBUG5QalNBdDc0ek15TkErdTNyUGJyYWlyNmFtWGxBQUFBQUFEMEtWNzh6TXlOQSt1M3JQYnJhaXI2YW1YbEFBQUFBQUhzVUxyK2FtWGxBc0FQblBqU0F0NzR6TXlOQVljTlRQOWMwN3o0ek15TkEwRVJZUG9qMDJ6NmFtWGxBc0FQblBqU0F0NzR6TXlOQTBFUllQb2owMno2YW1YbEErdTNyUGJyYWlyNmFtWGxBWWNOVFA5YzA3ejR6TXlOQTE2TndQNjVIWVQ4ek15TkFqOEoxUGhTdVJ6K2FtWGxBWWNOVFA5YzA3ejR6TXlOQWo4SjFQaFN1UnorYW1YbEEwRVJZUG9qMDJ6NmFtWGxBMTZOd3Y2NUhZVDh6TXlOQVljTlR2OWMwN3o0ek15TkEwRVJZdm9qMDJ6NmFtWGxBMTZOd3Y2NUhZVDh6TXlOQTBFUll2b2owMno2YW1YbEFqOEoxdmhTdVJ6K2FtWGxBWWNOVHY5YzA3ejR6TXlOQXNBUG52alNBdDc0ek15TkErdTNydmJyYWlyNmFtWGxBWWNOVHY5YzA3ejR6TXlOQSt1M3J2YnJhaXI2YW1YbEEwRVJZdm9qMDJ6NmFtWGxBc0FQbnZqU0F0NzR6TXlOQUFBQUFBRDBLVjc4ek15TkFBQUFBQUhzVUxyK2FtWGxBc0FQbnZqU0F0NzR6TXlOQUFBQUFBSHNVTHIrYW1YbEErdTNydmJyYWlyNmFtWGxBajhKMVBoU3VSeithbVhsQUFBQUFBTTNNVEQrYW1YbEFqOEoxdmhTdVJ6K2FtWGxBajhKMVBoU3VSeithbVhsQWo4SjF2aFN1UnorYW1YbEEwRVJZdm9qMDJ6NmFtWGxBajhKMVBoU3VSeithbVhsQTBFUll2b2owMno2YW1YbEErdTNydmJyYWlyNmFtWGxBajhKMVBoU3VSeithbVhsQSt1M3J2YnJhaXI2YW1YbEFBQUFBQUhzVUxyK2FtWGxBajhKMVBoU3VSeithbVhsQUFBQUFBSHNVTHIrYW1YbEErdTNyUGJyYWlyNmFtWGxBajhKMVBoU3VSeithbVhsQSt1M3JQYnJhaXI2YW1YbEEwRVJZUG9qMDJ6NmFtWGxBN0ZFNHY0WHJVVC9Oekl6QUFBQUFBUFlvWEQvTnpJekE3RkU0UDRYclVUL056SXpBN0ZFNHY0WHJVVC9Oekl6QTdGRTRQNFhyVVQvTnpJekFuRE1pUHhwUjJqN056SXpBN0ZFNHY0WHJVVC9Oekl6QW5ETWlQeHBSMmo3TnpJekFmUEt3UHNlNnVMN056SXpBN0ZFNHY0WHJVVC9Oekl6QWZQS3dQc2U2dUw3TnpJekFBQUFBQUlYclViL056SXpBN0ZFNHY0WHJVVC9Oekl6QUFBQUFBSVhyVWIvTnpJekFmUEt3dnNlNnVMN056SXpBN0ZFNHY0WHJVVC9Oekl6QWZQS3d2c2U2dUw3TnpJekFuRE1pdnhwUjJqN056SXpBeHNoSVArY2NGNy8vYUVPK3hzaElQK2NjRjcvL2FFTyt4c2hJUCtjY0Y3Ly9hRU8rUHBVc1A2V3hPNzh0ekxhOVBwVXNQNld4Tzc4dHpMYTlQcFVzUDZXeE83OHR6TGE5aGRCa1A5OXNwNzRlSUoyK2hkQmtQOTlzcDc0ZUlKMitoZEJrUDk5c3A3NGVJSjIrN05wZFAvcVQ2cjUxWGtxKzdOcGRQL3FUNnI1MVhrcSs3TnBkUC9xVDZyNTFYa3ErekJCcVAyS0ZUYjZiR3JTK3pCQnFQMktGVGI2YkdyUyt6QkJxUDJLRlRiNmJHclMrbk5ablA0a1VrNzVEdkorK25OWm5QNGtVazc1RHZKKytuTlpuUDRrVWs3NUR2SisrN3ROc3YwanlUNzZDUktTKzd0TnN2MGp5VDc2Q1JLUys3dE5zdjBqeVQ3NkNSS1MrVDVObHZ3YWxrYjVPaDYyK1Q1Tmx2d2Fsa2I1T2g2MitUNU5sdndhbGtiNU9oNjIrZHBOcnYybGZyTDdQYkV5K2RwTnJ2Mmxmckw3UGJFeStkcE5ydjJsZnJMN1BiRXkrSE1SWXYzTXk1YjZxTHBPK0hNUll2M015NWI2cUxwTytITVJZdjNNeTViNnFMcE8rVFA5THYvS0hHYitnaHBXOVRQOUx2L0tIR2IrZ2hwVzlUUDlMdi9LSEdiK2docFc5b0ljcXZ3RjJPYitSaWpXK29JY3F2d0YyT2IrUmlqVytvSWNxdndGMk9iK1JpalcrOG1Jc1AvSjZPNzhFRmMrOThtSXNQL0o2Tzc4RUZjKzk4bUlzUC9KNk83OEVGYys5allzZ1ArbnJScitIYUYyOWpZc2dQK25yUnIrSGFGMjlqWXNnUCtuclJyK0hhRjI5UUFaZlAzblE2NzY2RkM2K1FBWmZQM25RNjc2NkZDNitRQVpmUDNuUTY3NjZGQzYrQjlaWlAzTTBBNytaeSt1OUI5WlpQM00wQTcrWnkrdTlCOVpaUDNNMEE3K1p5K3U5S01KdVAyeDRsNzZ2ZEZPK0tNSnVQMng0bDc2dmRGTytLTUp1UDJ4NGw3NnZkRk8rTXBCc1B6djdxcjc0WHo2K01wQnNQenY3cXI3NFh6NitNcEJzUHp2N3FyNzRYejYrUnBWdnYxditsNzQwVmtLK1JwVnZ2MXYrbDc0MFZrSytScFZ2djF2K2w3NDBWa0srQTlkcnYyTjFxcjY1K0UyK0E5ZHJ2Mk4xcXI2NStFMitBOWRydjJOMXFyNjUrRTIrNThSZ3Y3Mm83YjVFUCsrOTU4Umd2NzJvN2I1RVArKzk1OFJndjcybzdiNUVQKys5aGw5WXYrRlNBcjk3bFNhK2hsOVl2K0ZTQXI5N2xTYStobDlZditGU0FyOTdsU2ErUGd3dHZ4RXpQTDltZVZHOVBnd3R2eEV6UEw5bWVWRzlQZ3d0dnhFelBMOW1lVkc5bGdZZ3Z5cEhScjlhSzhhOWxnWWd2eXBIUnI5YUs4YTlsZ1lndnlwSFJyOWFLOGE5bzYwZ1B5VVdSNzhwMFJHOW82MGdQeVVXUjc4cDBSRzlvNjBnUHlVV1I3OHAwUkc5Z2RFY1A0RkRTcjlEN2JpOGdkRWNQNEZEU3I5RDdiaThnZEVjUDRGRFNyOUQ3Ymk4alBCYVA1M2VBNyt2NFdpOWpQQmFQNTNlQTcrdjRXaTlqUEJhUDUzZUE3K3Y0V2k5QTdWWVB6WGZCNzhlL0NtOUE3VllQelhmQjc4ZS9DbTlBN1ZZUHpYZkI3OGUvQ205WXlod1AxS1VyYjZMMTVDOVl5aHdQMUtVcmI2TDE1QzlZeWh3UDFLVXJiNkwxNUM5bWhodlB5L2tzNzQwbG9XOW1oaHZQeS9rczc0MGxvVzltaGh2UHkva3M3NDBsb1c5WGoxd3YzeWpyYjcvcFlhOVhqMXd2M3lqcmI3L3BZYTlYajF3djN5anJiNy9wWWE5eXdSdnYwalZzNzZnV0krOXl3UnZ2MGpWczc2Z1dJKzl5d1J2djBqVnM3NmdXSSs5aWhwYnYrajNBNy8reGlxOWlocGJ2K2ozQTcvK3hpcTlpaHBiditqM0E3Lyt4aXE5OG8xWXY3YkdCNzhKRTJXOThvMVl2N2JHQjc4SkUyVzk4bzFZdjdiR0I3OEpFMlc5ajcwZ3Y5OHBSNytvRjdhOGo3MGd2OThwUjcrb0Y3YThqNzBndjk4cFI3K29GN2E4OXNJY3Y4QXdTci94M0ErOTlzSWN2OEF3U3IveDNBKzk5c0ljdjhBd1NyL3gzQSs5NzZVY1AwOExTcjl5OWxNOTc2VWNQMDhMU3I5eTlsTTk3NlVjUDA4TFNyOXk5bE05MjJNZlB5QUFTTCtMMnpZOTIyTWZQeUFBU0wrTDJ6WTkyMk1mUHlBQVNMK0wyelk5eEh0WVAxQzdCNytQNEhzOXhIdFlQMUM3QjcrUDRIczl4SHRZUDFDN0I3K1A0SHM5R3p4YVA2QWRCYjk2YTF3OUd6eGFQNkFkQmI5NmExdzlHenhhUDZBZEJiOTZhMXc5TlBadVAwN0tzNzVpSUpZOU5QWnVQMDdLczc1aUlKWTlOUFp1UDA3S3M3NWlJSlk5OWN0dlAzU0ZyNzVlcnBFOTljdHZQM1NGcjc1ZXJwRTk5Y3R2UDNTRnI3NWVycEU5WWdGdnY3ZlNzNzZjOVpBOVlnRnZ2N2ZTczc2YzlaQTlZZ0Z2djdmU3M3NmM5WkE5czc5dnYzdDhyNzdlU3BjOXM3OXZ2M3Q4cjc3ZVNwYzlzNzl2djN0OHI3N2VTcGM5UVpSWXY2dktCNytZbTF3OVFaUll2NnZLQjcrWW0xdzlRWlJZdjZ2S0I3K1ltMXc5RFNGYXZ4OE5CYjlsaG40OURTRmF2eDhOQmI5bGhuNDlEU0Zhdng4TkJiOWxobjQ5MnJJY3Yva2JTcjhleVRnOTJySWN2L2tiU3I4ZXlUZzkyckljdi9rYlNyOGV5VGc5YlZVZnZ3WHVSNzhCeUZROWJWVWZ2d1h1Ujc4QnlGUTliVlVmdndYdVI3OEJ5RlE5dlJRZVA2QmJScjlTbUFvK3ZSUWVQNkJiUnI5U21Bbyt2UlFlUDZCYlJyOVNtQW8rdlhBNlAvYXJMci9yYTRJOXZYQTZQL2FyTHIvcmE0STl2WEE2UC9hckxyL3JhNEk5RC9KVVA3VGpBYi9IY0dZK0QvSlVQN1RqQWIvSGNHWStEL0pVUDdUakFiL0hjR1kraXY5bFA1WiswYjdHTlNNK2l2OWxQNVorMGI3R05TTStpdjlsUDVaKzBiN0dOU00rNjE1blA1ZGFxYjZMQzRzKzYxNW5QNWRhcWI2TEM0cys2MTVuUDVkYXFiNkxDNHMrdnBodVAxWmxncjVjQTRRK3ZwaHVQMVpsZ3I1Y0E0USt2cGh1UDFabGdyNWNBNFErWGNWb3YvVmdxcjdQQVlBK1hjVm92L1ZncXI3UEFZQStYY1Zvdi9WZ3FyN1BBWUErR2VGc3Z4RjFnYjdJc3BBK0dlRnN2eEYxZ2I3SXNwQStHZUZzdnhGMWdiN0lzcEErcU54WHZ4cXJBNzh1SnlBK3FOeFh2eHFyQTc4dUp5QStxTnhYdnhxckE3OHVKeUErRkJaaXYyanV6Yjd5TVhjK0ZCWml2Mmp1emI3eU1YYytGQlppdjJqdXpiN3lNWGMrTmlBZnZ6K3JSNzhORnBVOU5pQWZ2eityUjc4TkZwVTlOaUFmdnorclI3OE5GcFU5cXM4NHZ6Y2xMYjgydnhVK3FzODR2emNsTGI4MnZ4VStxczg0dnpjbExiODJ2eFUrWnpzMlA2RzZLcitRaUdFK1p6czJQNkc2S3IrUWlHRStaenMyUDZHNktyK1FpR0UrcTBaMlB5Zk5pcjZ4bWdNOXEwWjJQeWZOaXI2eG1nTTlxMFoyUHlmTmlyNnhtZ005Q3dsWVA4REd4TDd4cTc4K0N3bFlQOERHeEw3eHE3OCtDd2xZUDhER3hMN3hxNzgrOWI1MVA4S25Ccjc1V1gwKzliNTFQOEtuQnI3NVdYMCs5YjUxUDhLbkJyNzVXWDArSjVKZVAzSkdjNzdaemQwK0o1SmVQM0pHYzc3WnpkMCtKNUplUDNKR2M3N1p6ZDArZFhOb1B6SFltTDJkRWRNK2RYTm9QekhZbUwyZEVkTStkWE5vUHpIWW1MMmRFZE0rTXFGaXZ5UzJkNzcyWHNzK01xRml2eVMyZDc3MlhzcytNcUZpdnlTMmQ3NzJYc3MrNkRoanZ3eG9sYjBFMytnKzZEaGp2d3hvbGIwRTMrZys2RGhqdnd4b2xiMEUzK2crWGRoaHZ6RzJ6YjZVYW5zK1hkaGh2ekcyemI2VWFucytYZGhodnpHMnpiNlVhbnMrZW5CbnY5YWgvYjJlY2RFK2VuQm52OWFoL2IyZWNkRStlbkJudjlhaC9iMmVjZEUra2pVNnY0ZDBMci9NYUtVOWtqVTZ2NGQwTHIvTWFLVTlralU2djRkMExyL01hS1U5dmFSdXYrdC9ocjVQOVg0K3ZhUnV2K3QvaHI1UDlYNCt2YVJ1dit0L2hyNVA5WDQrQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQkFBSUFBd0FFQUFVQUJnQUhBQWdBQ1FBS0FBc0FEQUFOQUE0QUR3QVFBQkVBRWdBVEFCUUFGUUFXQUJjQUdBQVpBQm9BR3dBY0FCMEFIZ0FmQUNBQUlRQWlBQ01BSkFBbEFDWUFKd0FvQUNrQUtnQXJBQ3dBTFFBdUFDOEFNQUF4QURJQU13QTBBRFVBTmdBM0FEZ0FPUUE2QURzQVBBQTlBRDRBUHdCQUFFRUFRZ0JEQUVRQVJRQkdBRWNBU0FCSkFFb0FTd0JNQUUwQVRnQlBBRkFBVVFCU0FGTUFWQUJWQUZZQVZ3QllBRmtBV2dCYkFGd0FYUUJlQUY4QVlBQmhBR0lBWXdCa0FHVUFaZ0JuQUdnQWFRQnFBR3NBYkFCdEFHNEFid0J3QUhFQWNnQnpBSFFBZFFCMkFIY0FlQUI1QUhvQWV3QjhBSDBBZmdCL0FJQUFnUUNDQUlNQWhBQ0ZBSVlBaHdDSUFJa0FpZ0NMQUl3QWpRQ09BSThBa0FDUkFKSUFrd0NVQUpVQWxnQ1hBSmdBbVFDYUFKc0FuQUNkQUo0QW53Q2dBS0VBb2dDakFLUUFwUUNtQUtjQXFBQ3BBS29BcXdDc0FLMEFyZ0N2QUxBQXNRQ3lBTE1BdEFDMUFMWUF0d0M0QUxrQXVnQzdBTHdBdlFDK0FMOEF3QURCQU1JQXd3REVBTVVBeGdESEFNZ0F5UURLQU1zQXpBRE5BTTRBendEUUFORUEwZ0RUQU5RQTFRRFdBTmNBMkFEWkFOb0Eyd0RjQU4wQTNnRGZBT0FBNFFEaUFPTUE1QURsQU9ZQTV3RG9BT2tBNmdEckFPd0E3UUR1QU84QThBRHhBUElBOHdEMEFQVUE5Z0QzQVBnQStRRDZBUHNBQUFBQUFQWW9YRC9Oekl6QTdGRTRQNFhyVVQvTnpJekFQUXFYUDJabVpqOEFBRkRBQUFBQUFQWW9YRC9Oekl6QVBRcVhQMlptWmo4QUFGREFBQUFBQURNemN6OEFBRkRBN0ZFNHY0WHJVVC9Oekl6QUFBQUFBUFlvWEQvTnpJekFBQUFBQURNemN6OEFBRkRBN0ZFNHY0WHJVVC9Oekl6QUFBQUFBRE16Y3o4QUFGREFQUXFYdjJabVpqOEFBRkRBQUFBQUFETXpjejhBQUZEQVBRcVhQMlptWmo4QUFGREFTT0c2UDBqaGVqOW1aZ2JBQUFBQUFETXpjejhBQUZEQVNPRzZQMGpoZWo5bVpnYkFBQUFBQUFyWGd6OW1aZ2JBUFFxWHYyWm1aajhBQUZEQUFBQUFBRE16Y3o4QUFGREFBQUFBQUFyWGd6OW1aZ2JBUFFxWHYyWm1aajhBQUZEQUFBQUFBQXJYZ3o5bVpnYkFTT0c2djBqaGVqOW1aZ2JBQUFBQUFBclhnejltWmdiQVNPRzZQMGpoZWo5bVpnYkFjVDNLUDF5UGdqOHpNek8vQUFBQUFBclhnejltWmdiQWNUM0tQMXlQZ2o4ek16Ty9BQUFBQUhFOWlqOHpNek8vU09HNnYwamhlajltWmdiQUFBQUFBQXJYZ3o5bVpnYkFBQUFBQUhFOWlqOHpNek8vU09HNnYwamhlajltWmdiQUFBQUFBSEU5aWo4ek16Ty9jVDNLdjF5UGdqOHpNek8vQUFBQUFIRTlpajh6TXpPL2NUM0tQMXlQZ2o4ek16Ty9qOEsxUDQvQ2RUOW1ab1kvQUFBQUFIRTlpajh6TXpPL2o4SzFQNC9DZFQ5bVpvWS9BQUFBQUs1SGdUOW1ab1kvY1QzS3YxeVBnajh6TXpPL0FBQUFBSEU5aWo4ek16Ty9BQUFBQUs1SGdUOW1ab1kvY1QzS3YxeVBnajh6TXpPL0FBQUFBSzVIZ1Q5bVpvWS9qOEsxdjQvQ2RUOW1ab1kvQUFBQUFLNUhnVDltWm9ZL2o4SzFQNC9DZFQ5bVpvWS8xNk53UDY1SFlUOHpNeU5BQUFBQUFLNUhnVDltWm9ZLzE2TndQNjVIWVQ4ek15TkFBQUFBQUIrRmF6OHpNeU5BajhLMXY0L0NkVDltWm9ZL0FBQUFBSzVIZ1Q5bVpvWS9BQUFBQUIrRmF6OHpNeU5BajhLMXY0L0NkVDltWm9ZL0FBQUFBQitGYXo4ek15TkExNk53djY1SFlUOHpNeU5BQUFBQUFCK0Zhejh6TXlOQTE2TndQNjVIWVQ4ek15TkFqOEoxUGhTdVJ6K2FtWGxBQUFBQUFCK0Zhejh6TXlOQWo4SjFQaFN1UnorYW1YbEFBQUFBQU0zTVREK2FtWGxBMTZOd3Y2NUhZVDh6TXlOQUFBQUFBQitGYXo4ek15TkFBQUFBQU0zTVREK2FtWGxBMTZOd3Y2NUhZVDh6TXlOQUFBQUFBTTNNVEQrYW1YbEFqOEoxdmhTdVJ6K2FtWGxBZXhRdXZ3QUFnRCthbVJtL2V4UXVQd0FBZ0QrYW1SbS9leFF1UDdnZXhUK2FtUm0vZXhRdXZ3QUFnRCthbVJtL2V4UXVQN2dleFQrYW1SbS9leFF1djdnZXhUK2FtUm0vZXhRdVB3QUFnRDltWmhiQWV4UXV2d0FBZ0Q5bVpoYkFleFF1djdnZXhUOW1aaGJBZXhRdVB3QUFnRDltWmhiQWV4UXV2N2dleFQ5bVpoYkFleFF1UDdnZXhUOW1aaGJBZXhRdXZ3QUFnRDltWmhiQWV4UXV2d0FBZ0QrYW1SbS9leFF1djdnZXhUK2FtUm0vZXhRdXZ3QUFnRDltWmhiQWV4UXV2N2dleFQrYW1SbS9leFF1djdnZXhUOW1aaGJBZXhRdVB3QUFnRCthbVJtL2V4UXVQd0FBZ0Q5bVpoYkFleFF1UDdnZXhUOW1aaGJBZXhRdVB3QUFnRCthbVJtL2V4UXVQN2dleFQ5bVpoYkFleFF1UDdnZXhUK2FtUm0vZXhRdXY3Z2V4VCthbVJtL2V4UXVQN2dleFQrYW1SbS9leFF1UDdnZXhUOW1aaGJBZXhRdXY3Z2V4VCthbVJtL2V4UXVQN2dleFQ5bVpoYkFleFF1djdnZXhUOW1aaGJBZXhRdXZ3QUFnRDltWmhiQWV4UXVQd0FBZ0Q5bVpoYkFleFF1UHdBQWdEK2FtUm0vZXhRdXZ3QUFnRDltWmhiQWV4UXVQd0FBZ0QrYW1SbS9leFF1dndBQWdEK2FtUm0vcmtmaHZseVBnaithbWRrL3JrZmhQbHlQZ2orYW1kay9ya2ZoUHRlanNEK2FtZGsvcmtmaHZseVBnaithbWRrL3JrZmhQdGVqc0QrYW1kay9ya2ZodnRlanNEK2FtZGsvcmtmaFBseVBnajhBQUFBL3JrZmh2bHlQZ2o4QUFBQS9ya2ZodnRlanNEOEFBQUEvcmtmaFBseVBnajhBQUFBL3JrZmh2dGVqc0Q4QUFBQS9ya2ZoUHRlanNEOEFBQUEvcmtmaHZseVBnajhBQUFBL3JrZmh2bHlQZ2orYW1kay9ya2ZodnRlanNEK2FtZGsvcmtmaHZseVBnajhBQUFBL3JrZmh2dGVqc0QrYW1kay9ya2ZodnRlanNEOEFBQUEvcmtmaFBseVBnaithbWRrL3JrZmhQbHlQZ2o4QUFBQS9ya2ZoUHRlanNEOEFBQUEvcmtmaFBseVBnaithbWRrL3JrZmhQdGVqc0Q4QUFBQS9ya2ZoUHRlanNEK2FtZGsvcmtmaHZ0ZWpzRCthbWRrL3JrZmhQdGVqc0QrYW1kay9ya2ZoUHRlanNEOEFBQUEvcmtmaHZ0ZWpzRCthbWRrL3JrZmhQdGVqc0Q4QUFBQS9ya2ZodnRlanNEOEFBQUEvcmtmaHZseVBnajhBQUFBL3JrZmhQbHlQZ2o4QUFBQS9ya2ZoUGx5UGdqK2FtZGsvcmtmaHZseVBnajhBQUFBL3JrZmhQbHlQZ2orYW1kay9ya2Zodmx5UGdqK2FtZGsvekVGaXZRYUtmcjl4NkxvOXpFRml2UWFLZnI5eDZMbzl6RUZpdlFhS2ZyOXg2TG85UnVBc3ZRRCtmcisxcFo4OVJ1QXN2UUQrZnIrMXBaODlSdUFzdlFEK2ZyKzFwWjg5eElOaVBUM1VmcitQaTU4OXhJTmlQVDNVZnIrUGk1ODl4SU5pUFQzVWZyK1BpNTg5Y3NJc1BRTFNmcjl2WGJBOWNzSXNQUUxTZnI5dlhiQTljc0lzUFFMU2ZyOXZYYkE5cGRvc3ZiUDFmcjhMNzZJOXBkb3N2YlAxZnI4TDc2STlwZG9zdmJQMWZyOEw3Nkk5ck5vTHZlRTdmNzhRQzQ0OXJOb0x2ZUU3Zjc4UUM0NDlyTm9MdmVFN2Y3OFFDNDQ5aGZ3c1Bhc25mNy9SLzQwOWhmd3NQYXNuZjcvUi80MDloZndzUGFzbmY3L1IvNDA5ME1RTFBmc1RmNy9KK0o0OTBNUUxQZnNUZjcvSitKNDkwTVFMUGZzVGY3L0orSjQ5VVI4TXZTaTVmNytkNlFBOVVSOE12U2k1ZjcrZDZRQTlVUjhNdlNpNWY3K2Q2UUE5V0ZVYnZTS25mNzljRmhJOVdGVWJ2U0tuZjc5Y0ZoSTlXRlVidlNLbmY3OWNGaEk5UWhvTVBldXZmNzlpR3hJOVFob01QZXV2Zjc5aUd4STlRaG9NUGV1dmY3OWlHeEk5amxvYlBiU3ZmNytETXdJOWpsb2JQYlN2ZjcrRE13STlqbG9iUGJTdmY3K0RNd0k5WGxJYnZUdWlmNzhvYnhxOVhsSWJ2VHVpZjc4b2J4cTlYbElidlR1aWY3OG9ieHE5WUFVUXZTU2pmNytjbXlPOVlBVVF2U1NqZjcrY215TzlZQVVRdlNTamY3K2NteU85Nms0YlBZdWNmNzlqbHlPOTZrNGJQWXVjZjc5amx5Tzk2azRiUFl1Y2Y3OWpseU85N2dnUVBYU3BmNy93YWhtOTdnZ1FQWFNwZjcvd2FobTk3Z2dRUFhTcGY3L3dhaG05S3RZUHZWZFBmNzh6OG9POUt0WVB2VmRQZjc4ejhvTzlLdFlQdlZkUGY3OHo4b085QjlRdHZXdFBmNzhLR1hXOUI5UXR2V3RQZjc4S0dYVzlCOVF0dld0UGY3OEtHWFc5cXVBUFBmdGhmNy9kS25XOXF1QVBQZnRoZjcvZEtuVzlxdUFQUGZ0aGY3L2RLblc5aE1BdFBjRXlmNzlXcjRpOWhNQXRQY0V5Zjc5V3I0aTloTUF0UGNFeWY3OVdyNGk5cmxjdHZjZVlmcjhWME1POXJsY3R2Y2VZZnI4VjBNTzlybGN0dmNlWWZyOFYwTU85N1dtcHZlTWVmcjlCdGJTOTdXbXB2ZU1lZnI5QnRiUzk3V21wdmVNZWZyOUJ0YlM5SlhVdFBRN0VmcisxS3JXOUpYVXRQUTdFZnIrMUtyVzlKWFV0UFE3RWZyKzFLclc5WCsyb1BRNWtmYi9idisyOVgrMm9QUTVrZmIvYnYrMjlYKzJvUFE1a2ZiL2J2KzI5QUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBSUFBQUFBQUFBQ0FQd0FBQUlBQUFBQUFBQUNBUHdBQUFJQUFBQUFBQUFBQWdBQUFnRDhBQUFBQUFBQUFnQUFBZ0Q4QUFBQUFBQUFBZ0FBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBSUFBQUFBQUFBQ0FQd0FBQUlBQUFBQUFBQUNBUHdBQUFJQUFBQUFBQUFBQWdBQUFnRDhBQUFBQUFBQUFnQUFBZ0Q4QUFBQUFBQUFBZ0FBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQkFBSUFBd0FFQUFVQUJnQUhBQWdBQ1FBS0FBc0FEQUFOQUE0QUR3QVFBQkVBRWdBVEFCUUFGUUFXQUJjQUdBQVpBQm9BR3dBY0FCMEFIZ0FmQUNBQUlRQWlBQ01BSkFBbEFDWUFKd0FvQUNrQUtnQXJBQ3dBTFFBdUFDOEFNQUF4QURJQU13QTBBRFVBTmdBM0FEZ0FPUUE2QURzQVBBQTlBRDRBUHdCQUFFRUFRZ0JEQUVRQVJRQkdBRWNBU0FCSkFFb0FTd0JNQUUwQVRnQlBBRkFBVVFCU0FGTUFWQUJWQUZZQVZ3QllBRmtBV2dCYkFGd0FYUUJlQUY4QVlBQmhBR0lBWXdCa0FHVUFaZ0JuQUdnQWFRQnFBR3NBYkFCdEFHNEFid0J3QUhFQWNnQnpBSFFBZFFCMkFIY0FlQUI1QUhvQWV3QjhBSDBBZmdCL0FJQUFnUUNDQUlNQWhBQ0ZBSVlBaHdDSUFJa0FpZ0NMQUl3QWpRQ09BSThBcEhDOXZ6MEtWeithbVJsQXBIQzlQejBLVnorYW1SbEFwSEM5UHpNemN6K2FtUmxBcEhDOXZ6MEtWeithbVJsQXBIQzlQek16Y3orYW1SbEFwSEM5dnpNemN6K2FtUmxBcEhDOVB6MEtWei9OekF6QXBIQzl2ejBLVnovTnpBekFwSEM5dnpNemN6L056QXpBcEhDOVB6MEtWei9OekF6QXBIQzl2ek16Y3ovTnpBekFwSEM5UHpNemN6L056QXpBcEhDOXZ6MEtWei9OekF6QXBIQzl2ejBLVnorYW1SbEFwSEM5dnpNemN6K2FtUmxBcEhDOXZ6MEtWei9OekF6QXBIQzl2ek16Y3orYW1SbEFwSEM5dnpNemN6L056QXpBcEhDOVB6MEtWeithbVJsQXBIQzlQejBLVnovTnpBekFwSEM5UHpNemN6L056QXpBcEhDOVB6MEtWeithbVJsQXBIQzlQek16Y3ovTnpBekFwSEM5UHpNemN6K2FtUmxBcEhDOXZ6TXpjeithbVJsQXBIQzlQek16Y3orYW1SbEFwSEM5UHpNemN6L056QXpBcEhDOXZ6TXpjeithbVJsQXBIQzlQek16Y3ovTnpBekFwSEM5dnpNemN6L056QXpBcEhDOXZ6MEtWei9OekF6QXBIQzlQejBLVnovTnpBekFwSEM5UHowS1Z6K2FtUmxBcEhDOXZ6MEtWei9OekF6QXBIQzlQejBLVnorYW1SbEFwSEM5dnowS1Z6K2FtUmxBS1Z3UHZ4K0Zxejk3Rkc2L0tWd1BQeCtGcXo5N0ZHNi9oZXZSUGlsY3p6OTdGRzYvS1Z3UHZ4K0Zxejk3Rkc2L2hldlJQaWxjeno5N0ZHNi9oZXZSdmlsY3p6OTdGRzYvS1Z3UFB4K0ZxeitGNndIQUtWd1B2eCtGcXorRjZ3SEFoZXZSdmlsY3p6K0Y2d0hBS1Z3UFB4K0ZxeitGNndIQWhldlJ2aWxjenorRjZ3SEFoZXZSUGlsY3p6K0Y2d0hBS1Z3UHZ4K0ZxeitGNndIQUtWd1B2eCtGcXo5N0ZHNi9oZXZSdmlsY3p6OTdGRzYvS1Z3UHZ4K0ZxeitGNndIQWhldlJ2aWxjeno5N0ZHNi9oZXZSdmlsY3p6K0Y2d0hBS1Z3UFB4K0Zxejk3Rkc2L0tWd1BQeCtGcXorRjZ3SEFoZXZSUGlsY3p6K0Y2d0hBS1Z3UFB4K0Zxejk3Rkc2L2hldlJQaWxjenorRjZ3SEFoZXZSUGlsY3p6OTdGRzYvaGV2UnZpbGN6ejk3Rkc2L2hldlJQaWxjeno5N0ZHNi9oZXZSUGlsY3p6K0Y2d0hBaGV2UnZpbGN6ejk3Rkc2L2hldlJQaWxjenorRjZ3SEFoZXZSdmlsY3p6K0Y2d0hBS1Z3UHZ4K0ZxeitGNndIQUtWd1BQeCtGcXorRjZ3SEFLVndQUHgrRnF6OTdGRzYvS1Z3UHZ4K0ZxeitGNndIQUtWd1BQeCtGcXo5N0ZHNi9LVndQdngrRnF6OTdGRzYvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBSUFBQUFBQUFBQ0FQd0FBQUlBQUFBQUFBQUNBUHdBQUFJQUFBQUFBQUFBQWdBQUFnRDhBQUFBQUFBQUFnQUFBZ0Q4QUFBQUFBQUFBZ0FBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvcktoaHZ3SEg4VDRBQUFBQXJLaGh2d0hIOFQ0QUFBQUFyS2hodndISDhUNEFBQUFBcktoaHZ3SEg4VDRBQUFBQXJLaGh2d0hIOFQ0QUFBQUFyS2hodndISDhUNEFBQUFBcktoaFB3SEg4VDRBQUFBQXJLaGhQd0hIOFQ0QUFBQUFyS2hoUHdISDhUNEFBQUFBcktoaFB3SEg4VDRBQUFBQXJLaGhQd0hIOFQ0QUFBQUFyS2hoUHdISDhUNEFBQUFBQUFBQWdBQUFnRDhBQUFBQUFBQUFnQUFBZ0Q4QUFBQUFBQUFBZ0FBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQkFBSUFBd0FFQUFVQUJnQUhBQWdBQ1FBS0FBc0FEQUFOQUE0QUR3QVFBQkVBRWdBVEFCUUFGUUFXQUJjQUdBQVpBQm9BR3dBY0FCMEFIZ0FmQUNBQUlRQWlBQ01BSkFBbEFDWUFKd0FvQUNrQUtnQXJBQ3dBTFFBdUFDOEFNQUF4QURJQU13QTBBRFVBTmdBM0FEZ0FPUUE2QURzQVBBQTlBRDRBUHdCQUFFRUFRZ0JEQUVRQVJRQkdBRWNBemN6TVBacVpXVDhmaFd1L0tWeVBQUUFBeUVBZmhXdS8zN2FHUFFBQXlFQVpaR1cvemN6TVBacVpXVDhmaFd1LzM3YUdQUUFBeUVBWlpHVy85WExBUFpxWldUK293MksvOVhMQVBacVpXVCtvdzJLLzM3YUdQUUFBeUVBWlpHVy82S05iUFFBQXlFQlNBR0MvOVhMQVBacVpXVCtvdzJLLzZLTmJQUUFBeUVCU0FHQy95dUtjUFpxWldUK01FRnUveXVLY1BacVpXVCtNRUZ1LzZLTmJQUUFBeUVCU0FHQy9LVndQUFFBQXlFQTJBRnkveXVLY1BacVpXVCtNRUZ1L0tWd1BQUUFBeUVBMkFGeS96Y3hNUFpxWldUK0pXVlcvemN4TVBacVpXVCtKV1ZXL0tWd1BQUUFBeUVBMkFGeS9WQ2RIUEFBQXlFQkwzMW0vemN4TVBacVpXVCtKV1ZXL1ZDZEhQQUFBeUVCTDMxbS9xa0NPUEpxWldUOFZUMUsvcWtDT1BKcVpXVDhWVDFLL1ZDZEhQQUFBeUVCTDMxbS9WQ2RIdkFBQXlFQkwzMW0vcWtDT1BKcVpXVDhWVDFLL1ZDZEh2QUFBeUVCTDMxbS9xa0NPdkpxWldUOFZUMUsvcWtDT3ZKcVpXVDhWVDFLL1ZDZEh2QUFBeUVCTDMxbS9LVndQdlFBQXlFQTJBRnkvcWtDT3ZKcVpXVDhWVDFLL0tWd1B2UUFBeUVBMkFGeS96Y3hNdlpxWldUK0pXVlcvemN4TXZacVpXVCtKV1ZXL0tWd1B2UUFBeUVBMkFGeS82S05idlFBQXlFQlNBR0MvemN4TXZacVpXVCtKV1ZXLzZLTmJ2UUFBeUVCU0FHQy95dUtjdlpxWldUK01FRnUveXVLY3ZacVpXVCtNRUZ1LzZLTmJ2UUFBeUVCU0FHQy8zN2FHdlFBQXlFQVpaR1cveXVLY3ZacVpXVCtNRUZ1LzM3YUd2UUFBeUVBWlpHVy85WExBdlpxWldUK293MksvOVhMQXZacVpXVCtvdzJLLzM3YUd2UUFBeUVBWlpHVy9LVnlQdlFBQXlFQWZoV3UvOVhMQXZacVpXVCtvdzJLL0tWeVB2UUFBeUVBZmhXdS96Y3pNdlpxWldUOGZoV3UvemN6TXZacVpXVDhmaFd1L0tWeVB2UUFBeUVBZmhXdS8zN2FHdlFBQXlFQWxwbkcvemN6TXZacVpXVDhmaFd1LzM3YUd2UUFBeUVBbHBuRy85WExBdlpxWldUK1ZSblMvOVhMQXZacVpXVCtWUm5TLzM3YUd2UUFBeUVBbHBuRy82S05idlFBQXlFRHNDWGUvOVhMQXZacVpXVCtWUm5TLzZLTmJ2UUFBeUVEc0NYZS95dUtjdlpxWldUK3grWHUveXVLY3ZacVpXVCt4K1h1LzZLTmJ2UUFBeUVEc0NYZS9LVndQdlFBQXlFQUhDbnUveXVLY3ZacVpXVCt4K1h1L0tWd1B2UUFBeUVBSENudS96Y3hNdlpxWldUOWEySUMvemN4TXZacVpXVDlhMklDL0tWd1B2UUFBeUVBSENudS9WQ2RIdkFBQXlFRHlLbjIvemN4TXZacVpXVDlhMklDL1ZDZEh2QUFBeUVEeUtuMi9xa0NPdkpxWldUK1VYWUsvcWtDT3ZKcVpXVCtVWFlLL1ZDZEh2QUFBeUVEeUtuMi9WQ2RIUEFBQXlFRHlLbjIvcWtDT3ZKcVpXVCtVWFlLL1ZDZEhQQUFBeUVEeUtuMi9xa0NPUEpxWldUK1VYWUsvcWtDT1BKcVpXVCtVWFlLL1ZDZEhQQUFBeUVEeUtuMi9LVndQUFFBQXlFQUhDbnUvcWtDT1BKcVpXVCtVWFlLL0tWd1BQUUFBeUVBSENudS96Y3hNUFpxWldUOWEySUMvemN4TVBacVpXVDlhMklDL0tWd1BQUUFBeUVBSENudS82S05iUFFBQXlFRHNDWGUvemN4TVBacVpXVDlhMklDLzZLTmJQUUFBeUVEc0NYZS95dUtjUFpxWldUK3grWHUveXVLY1BacVpXVCt4K1h1LzZLTmJQUUFBeUVEc0NYZS8zN2FHUFFBQXlFQWxwbkcveXVLY1BacVpXVCt4K1h1LzM3YUdQUUFBeUVBbHBuRy85WExBUFpxWldUK1ZSblMvOVhMQVBacVpXVCtWUm5TLzM3YUdQUUFBeUVBbHBuRy9LVnlQUFFBQXlFQWZoV3UvOVhMQVBacVpXVCtWUm5TL0tWeVBQUUFBeUVBZmhXdS96Y3pNUFpxWldUOGZoV3UvMzdhR1BRQUF5RUFscG5HLzZLTmJQUUFBeUVEc0NYZS9LVndQUFFBQXlFQUhDbnUvMzdhR1BRQUF5RUFscG5HL0tWd1BQUUFBeUVBSENudS9WQ2RIUEFBQXlFRHlLbjIvMzdhR1BRQUF5RUFscG5HL1ZDZEhQQUFBeUVEeUtuMi9WQ2RIdkFBQXlFRHlLbjIvMzdhR1BRQUF5RUFscG5HL1ZDZEh2QUFBeUVEeUtuMi9LVndQdlFBQXlFQUhDbnUvMzdhR1BRQUF5RUFscG5HL0tWd1B2UUFBeUVBSENudS82S05idlFBQXlFRHNDWGUvMzdhR1BRQUF5RUFscG5HLzZLTmJ2UUFBeUVEc0NYZS8zN2FHdlFBQXlFQWxwbkcvMzdhR1BRQUF5RUFscG5HLzM3YUd2UUFBeUVBbHBuRy9LVnlQdlFBQXlFQWZoV3UvMzdhR1BRQUF5RUFscG5HL0tWeVB2UUFBeUVBZmhXdS8zN2FHdlFBQXlFQVpaR1cvMzdhR1BRQUF5RUFscG5HLzM3YUd2UUFBeUVBWlpHVy82S05idlFBQXlFQlNBR0MvMzdhR1BRQUF5RUFscG5HLzZLTmJ2UUFBeUVCU0FHQy9LVndQdlFBQXlFQTJBRnkvMzdhR1BRQUF5RUFscG5HL0tWd1B2UUFBeUVBMkFGeS9WQ2RIdkFBQXlFQkwzMW0vMzdhR1BRQUF5RUFscG5HL1ZDZEh2QUFBeUVCTDMxbS9WQ2RIUEFBQXlFQkwzMW0vMzdhR1BRQUF5RUFscG5HL1ZDZEhQQUFBeUVCTDMxbS9LVndQUFFBQXlFQTJBRnkvMzdhR1BRQUF5RUFscG5HL0tWd1BQUUFBeUVBMkFGeS82S05iUFFBQXlFQlNBR0MvMzdhR1BRQUF5RUFscG5HLzZLTmJQUUFBeUVCU0FHQy8zN2FHUFFBQXlFQVpaR1cvMzdhR1BRQUF5RUFscG5HLzM3YUdQUUFBeUVBWlpHVy9LVnlQUFFBQXlFQWZoV3UvemN6TVBacVpXVDhmaFd1LzlYTEFQWnFaV1Qrb3cySy95dUtjUFpxWldUK01FRnUvemN6TVBacVpXVDhmaFd1L3l1S2NQWnFaV1QrTUVGdS96Y3hNUFpxWldUK0pXVlcvemN6TVBacVpXVDhmaFd1L3pjeE1QWnFaV1QrSldWVy9xa0NPUEpxWldUOFZUMUsvemN6TVBacVpXVDhmaFd1L3FrQ09QSnFaV1Q4VlQxSy9xa0NPdkpxWldUOFZUMUsvemN6TVBacVpXVDhmaFd1L3FrQ092SnFaV1Q4VlQxSy96Y3hNdlpxWldUK0pXVlcvemN6TVBacVpXVDhmaFd1L3pjeE12WnFaV1QrSldWVy95dUtjdlpxWldUK01FRnUvemN6TVBacVpXVDhmaFd1L3l1S2N2WnFaV1QrTUVGdS85WExBdlpxWldUK293MksvemN6TVBacVpXVDhmaFd1LzlYTEF2WnFaV1Qrb3cySy96Y3pNdlpxWldUOGZoV3UvemN6TVBacVpXVDhmaFd1L3pjek12WnFaV1Q4ZmhXdS85WExBdlpxWldUK1ZSblMvemN6TVBacVpXVDhmaFd1LzlYTEF2WnFaV1QrVlJuUy95dUtjdlpxWldUK3grWHUvemN6TVBacVpXVDhmaFd1L3l1S2N2WnFaV1QreCtYdS96Y3hNdlpxWldUOWEySUMvemN6TVBacVpXVDhmaFd1L3pjeE12WnFaV1Q5YTJJQy9xa0NPdkpxWldUK1VYWUsvemN6TVBacVpXVDhmaFd1L3FrQ092SnFaV1QrVVhZSy9xa0NPUEpxWldUK1VYWUsvemN6TVBacVpXVDhmaFd1L3FrQ09QSnFaV1QrVVhZSy96Y3hNUFpxWldUOWEySUMvemN6TVBacVpXVDhmaFd1L3pjeE1QWnFaV1Q5YTJJQy95dUtjUFpxWldUK3grWHUvemN6TVBacVpXVDhmaFd1L3l1S2NQWnFaV1QreCtYdS85WExBUFpxWldUK1ZSblMvQUFBQUFJL0NkVDlJNFRyQWo4TDF2T3hSbUVCSTRUckFJRHNIdmV4Um1FQVp5VG5BQUFBQUFJL0NkVDlJNFRyQUlEc0h2ZXhSbUVBWnlUbkFtUmVldTQvQ2RULzlJRG5BbVJlZXU0L0NkVC85SURuQUlEc0h2ZXhSbUVBWnlUbkFTc3NxdmV4Um1FQzEwampBbVJlZXU0L0NkVC85SURuQVNzc3F2ZXhSbUVDMTBqakFPMU9adkkvQ2RUL0VsamZBTzFPWnZJL0NkVC9FbGpmQVNzc3F2ZXhSbUVDMTBqakFya2RodmV4Um1FRFZHempBTzFPWnZJL0NkVC9FbGpmQXJrZGh2ZXhSbUVEVkd6akFDdGNqdlkvQ2RUOHFjamJBQ3RjanZZL0NkVDhxY2piQXJrZGh2ZXhSbUVEVkd6akE5UTZTdmV4Um1FQ0h1amZBQ3RjanZZL0NkVDhxY2piQTlRNlN2ZXhSbUVDSHVqZkF0V09IdlkvQ2RUOTUxalhBdFdPSHZZL0NkVDk1MWpYQTlRNlN2ZXhSbUVDSHVqZkFINSsxdmV4Um1FQ0h1amZBdFdPSHZZL0NkVDk1MWpYQUg1KzF2ZXhSbUVDSHVqZkFYMHJBdlkvQ2RUOTUxalhBWDByQXZZL0NkVDk1MWpYQUg1KzF2ZXhSbUVDSHVqZkFQUXJYdmV4Um1FRFZHempBWDByQXZZL0NkVDk1MWpYQVBRclh2ZXhSbUVEVkd6akFqOEwxdlkvQ2RUOHFjamJBajhMMXZZL0NkVDhxY2piQVBRclh2ZXhSbUVEVkd6akFiMGp5dmV4Um1FQzEwampBajhMMXZZL0NkVDhxY2piQWIwanl2ZXhSbUVDMTBqakFvNndRdm8vQ2RUL0VsamZBbzZ3UXZvL0NkVC9FbGpmQWIwanl2ZXhSbUVDMTBqakFRZ2dDdnV4Um1FQVp5VG5BbzZ3UXZvL0NkVC9FbGpmQVFnZ0N2dXhSbUVBWnlUbkFUZVlldm8vQ2RULzlJRG5BVGVZZXZvL0NkVC85SURuQVFnZ0N2dXhSbUVBWnlUbkF1QjRGdnV4Um1FQkk0VHJBVGVZZXZvL0NkVC85SURuQXVCNEZ2dXhSbUVCSTRUckFDdGNqdm8vQ2RUOUk0VHJBQ3RjanZvL0NkVDlJNFRyQXVCNEZ2dXhSbUVCSTRUckFRZ2dDdnV4Um1FQjMrVHZBQ3RjanZvL0NkVDlJNFRyQVFnZ0N2dXhSbUVCMytUdkFUZVlldm8vQ2RUK1RvVHpBVGVZZXZvL0NkVCtUb1R6QVFnZ0N2dXhSbUVCMytUdkFiMGp5dmV4Um1FRGE3enpBVGVZZXZvL0NkVCtUb1R6QWIwanl2ZXhSbUVEYTd6ekFvNndRdm8vQ2RUL0xLejdBbzZ3UXZvL0NkVC9MS3o3QWIwanl2ZXhSbUVEYTd6ekFQUXJYdmV4Um1FQzZwajNBbzZ3UXZvL0NkVC9MS3o3QVBRclh2ZXhSbUVDNnBqM0FqOEwxdlkvQ2RUOW1VRC9BajhMMXZZL0NkVDltVUQvQVBRclh2ZXhSbUVDNnBqM0FINSsxdmV4Um1FQUpDRDdBajhMMXZZL0NkVDltVUQvQUg1KzF2ZXhSbUVBSkNEN0FYMHJBdlkvQ2RUOFc3RC9BWDByQXZZL0NkVDhXN0QvQUg1KzF2ZXhSbUVBSkNEN0E5UTZTdmV4Um1FQUpDRDdBWDByQXZZL0NkVDhXN0QvQTlRNlN2ZXhSbUVBSkNEN0F0V09IdlkvQ2RUOFc3RC9BdFdPSHZZL0NkVDhXN0QvQTlRNlN2ZXhSbUVBSkNEN0Fya2RodmV4Um1FQzZwajNBdFdPSHZZL0NkVDhXN0QvQXJrZGh2ZXhSbUVDNnBqM0FDdGNqdlkvQ2RUOW1VRC9BQ3RjanZZL0NkVDltVUQvQXJrZGh2ZXhSbUVDNnBqM0FTc3NxdmV4Um1FRGE3enpBQ3RjanZZL0NkVDltVUQvQVNzc3F2ZXhSbUVEYTd6ekFPMU9adkkvQ2RUL0xLejdBTzFPWnZJL0NkVC9MS3o3QVNzc3F2ZXhSbUVEYTd6ekFJRHNIdmV4Um1FQjMrVHZBTzFPWnZJL0NkVC9MS3o3QUlEc0h2ZXhSbUVCMytUdkFtUmVldTQvQ2RUK1RvVHpBbVJlZXU0L0NkVCtUb1R6QUlEc0h2ZXhSbUVCMytUdkFqOEwxdk94Um1FQkk0VHJBbVJlZXU0L0NkVCtUb1R6QWo4TDF2T3hSbUVCSTRUckFBQUFBQUkvQ2RUOUk0VHJBSURzSHZleFJtRUIzK1R2QVNzc3F2ZXhSbUVEYTd6ekFya2RodmV4Um1FQzZwajNBSURzSHZleFJtRUIzK1R2QXJrZGh2ZXhSbUVDNnBqM0E5UTZTdmV4Um1FQUpDRDdBSURzSHZleFJtRUIzK1R2QTlRNlN2ZXhSbUVBSkNEN0FINSsxdmV4Um1FQUpDRDdBSURzSHZleFJtRUIzK1R2QUg1KzF2ZXhSbUVBSkNEN0FQUXJYdmV4Um1FQzZwajNBSURzSHZleFJtRUIzK1R2QVBRclh2ZXhSbUVDNnBqM0FiMGp5dmV4Um1FRGE3enpBSURzSHZleFJtRUIzK1R2QWIwanl2ZXhSbUVEYTd6ekFRZ2dDdnV4Um1FQjMrVHZBSURzSHZleFJtRUIzK1R2QVFnZ0N2dXhSbUVCMytUdkF1QjRGdnV4Um1FQkk0VHJBSURzSHZleFJtRUIzK1R2QXVCNEZ2dXhSbUVCSTRUckFRZ2dDdnV4Um1FQVp5VG5BSURzSHZleFJtRUIzK1R2QVFnZ0N2dXhSbUVBWnlUbkFiMGp5dmV4Um1FQzEwampBSURzSHZleFJtRUIzK1R2QWIwanl2ZXhSbUVDMTBqakFQUXJYdmV4Um1FRFZHempBSURzSHZleFJtRUIzK1R2QVBRclh2ZXhSbUVEVkd6akFINSsxdmV4Um1FQ0h1amZBSURzSHZleFJtRUIzK1R2QUg1KzF2ZXhSbUVDSHVqZkE5UTZTdmV4Um1FQ0h1amZBSURzSHZleFJtRUIzK1R2QTlRNlN2ZXhSbUVDSHVqZkFya2RodmV4Um1FRFZHempBSURzSHZleFJtRUIzK1R2QXJrZGh2ZXhSbUVEVkd6akFTc3NxdmV4Um1FQzEwampBSURzSHZleFJtRUIzK1R2QVNzc3F2ZXhSbUVDMTBqakFJRHNIdmV4Um1FQVp5VG5BSURzSHZleFJtRUIzK1R2QUlEc0h2ZXhSbUVBWnlUbkFqOEwxdk94Um1FQkk0VHJBQUFBQUFJL0NkVDlJNFRyQW1SZWV1NC9DZFQvOUlEbkFPMU9adkkvQ2RUL0VsamZBQUFBQUFJL0NkVDlJNFRyQU8xT1p2SS9DZFQvRWxqZkFDdGNqdlkvQ2RUOHFjamJBQUFBQUFJL0NkVDlJNFRyQUN0Y2p2WS9DZFQ4cWNqYkF0V09IdlkvQ2RUOTUxalhBQUFBQUFJL0NkVDlJNFRyQXRXT0h2WS9DZFQ5NTFqWEFYMHJBdlkvQ2RUOTUxalhBQUFBQUFJL0NkVDlJNFRyQVgwckF2WS9DZFQ5NTFqWEFqOEwxdlkvQ2RUOHFjamJBQUFBQUFJL0NkVDlJNFRyQWo4TDF2WS9DZFQ4cWNqYkFvNndRdm8vQ2RUL0VsamZBQUFBQUFJL0NkVDlJNFRyQW82d1F2by9DZFQvRWxqZkFUZVlldm8vQ2RULzlJRG5BQUFBQUFJL0NkVDlJNFRyQVRlWWV2by9DZFQvOUlEbkFDdGNqdm8vQ2RUOUk0VHJBQUFBQUFJL0NkVDlJNFRyQUN0Y2p2by9DZFQ5STRUckFUZVlldm8vQ2RUK1RvVHpBQUFBQUFJL0NkVDlJNFRyQVRlWWV2by9DZFQrVG9UekFvNndRdm8vQ2RUL0xLejdBQUFBQUFJL0NkVDlJNFRyQW82d1F2by9DZFQvTEt6N0FqOEwxdlkvQ2RUOW1VRC9BQUFBQUFJL0NkVDlJNFRyQWo4TDF2WS9DZFQ5bVVEL0FYMHJBdlkvQ2RUOFc3RC9BQUFBQUFJL0NkVDlJNFRyQVgwckF2WS9DZFQ4VzdEL0F0V09IdlkvQ2RUOFc3RC9BQUFBQUFJL0NkVDlJNFRyQXRXT0h2WS9DZFQ4VzdEL0FDdGNqdlkvQ2RUOW1VRC9BQUFBQUFJL0NkVDlJNFRyQUN0Y2p2WS9DZFQ5bVVEL0FPMU9adkkvQ2RUL0xLejdBQUFBQUFJL0NkVDlJNFRyQU8xT1p2SS9DZFQvTEt6N0FtUmVldTQvQ2RUK1RvVHpBQ3RlanZUTXpVMEN1UjJHL0g0VUxRRE16VTBDdVIyRy9INFVMUU94UldFQ3VSMkcvQ3RlanZUTXpVMEN1UjJHL0g0VUxRT3hSV0VDdVIyRy9DdGVqdmV4UldFQ3VSMkcvSDRVTFFETXpVMEFBQUlDL0N0ZWp2VE16VTBBQUFJQy9DdGVqdmV4UldFQUFBSUMvSDRVTFFETXpVMEFBQUlDL0N0ZWp2ZXhSV0VBQUFJQy9INFVMUU94UldFQUFBSUMvQ3RlanZUTXpVMEFBQUlDL0N0ZWp2VE16VTBDdVIyRy9DdGVqdmV4UldFQ3VSMkcvQ3RlanZUTXpVMEFBQUlDL0N0ZWp2ZXhSV0VDdVIyRy9DdGVqdmV4UldFQUFBSUMvSDRVTFFETXpVMEN1UjJHL0g0VUxRRE16VTBBQUFJQy9INFVMUU94UldFQUFBSUMvSDRVTFFETXpVMEN1UjJHL0g0VUxRT3hSV0VBQUFJQy9INFVMUU94UldFQ3VSMkcvQ3RlanZleFJXRUN1UjJHL0g0VUxRT3hSV0VDdVIyRy9INFVMUU94UldFQUFBSUMvQ3RlanZleFJXRUN1UjJHL0g0VUxRT3hSV0VBQUFJQy9DdGVqdmV4UldFQUFBSUMvQ3RlanZUTXpVMEFBQUlDL0g0VUxRRE16VTBBQUFJQy9INFVMUURNelUwQ3VSMkcvQ3RlanZUTXpVMEFBQUlDL0g0VUxRRE16VTBDdVIyRy9DdGVqdlRNelUwQ3VSMkcvS1Z3UHZwcVpHVUNhbVRuQUN0ZWpQNXFaR1VDYW1UbkFDdGVqUDFLNEhrQ2FtVG5BS1Z3UHZwcVpHVUNhbVRuQUN0ZWpQMUs0SGtDYW1UbkFLVndQdmxLNEhrQ2FtVG5BQ3RlalA1cVpHVUFBQUVEQUtWd1B2cHFaR1VBQUFFREFLVndQdmxLNEhrQUFBRURBQ3RlalA1cVpHVUFBQUVEQUtWd1B2bEs0SGtBQUFFREFDdGVqUDFLNEhrQUFBRURBS1Z3UHZwcVpHVUFBQUVEQUtWd1B2cHFaR1VDYW1UbkFLVndQdmxLNEhrQ2FtVG5BS1Z3UHZwcVpHVUFBQUVEQUtWd1B2bEs0SGtDYW1UbkFLVndQdmxLNEhrQUFBRURBQ3RlalA1cVpHVUNhbVRuQUN0ZWpQNXFaR1VBQUFFREFDdGVqUDFLNEhrQUFBRURBQ3RlalA1cVpHVUNhbVRuQUN0ZWpQMUs0SGtBQUFFREFDdGVqUDFLNEhrQ2FtVG5BS1Z3UHZsSzRIa0NhbVRuQUN0ZWpQMUs0SGtDYW1UbkFDdGVqUDFLNEhrQUFBRURBS1Z3UHZsSzRIa0NhbVRuQUN0ZWpQMUs0SGtBQUFFREFLVndQdmxLNEhrQUFBRURBS1Z3UHZwcVpHVUFBQUVEQUN0ZWpQNXFaR1VBQUFFREFDdGVqUDVxWkdVQ2FtVG5BS1Z3UHZwcVpHVUFBQUVEQUN0ZWpQNXFaR1VDYW1UbkFLVndQdnBxWkdVQ2FtVG5BQ3RjanZZL0N0VCthbWFGQWo4SjFQWS9DdFQrYW1hRkFqOEoxUFFBQXdEK2FtYUZBQ3RjanZZL0N0VCthbWFGQWo4SjFQUUFBd0QrYW1hRkFDdGNqdlFBQXdEK2FtYUZBajhKMVBZL0N0VC9Oekd4QUN0Y2p2WS9DdFQvTnpHeEFDdGNqdlFBQXdEL056R3hBajhKMVBZL0N0VC9Oekd4QUN0Y2p2UUFBd0QvTnpHeEFqOEoxUFFBQXdEL056R3hBQ3RjanZZL0N0VC9Oekd4QUN0Y2p2WS9DdFQrYW1hRkFDdGNqdlFBQXdEK2FtYUZBQ3RjanZZL0N0VC9Oekd4QUN0Y2p2UUFBd0QrYW1hRkFDdGNqdlFBQXdEL056R3hBajhKMVBZL0N0VCthbWFGQWo4SjFQWS9DdFQvTnpHeEFqOEoxUFFBQXdEL056R3hBajhKMVBZL0N0VCthbWFGQWo4SjFQUUFBd0QvTnpHeEFqOEoxUFFBQXdEK2FtYUZBQ3RjanZRQUF3RCthbWFGQWo4SjFQUUFBd0QrYW1hRkFqOEoxUFFBQXdEL056R3hBQ3RjanZRQUF3RCthbWFGQWo4SjFQUUFBd0QvTnpHeEFDdGNqdlFBQXdEL056R3hBQ3RjanZZL0N0VC9Oekd4QWo4SjFQWS9DdFQvTnpHeEFqOEoxUFkvQ3RUK2FtYUZBQ3RjanZZL0N0VC9Oekd4QWo4SjFQWS9DdFQrYW1hRkFDdGNqdlkvQ3RUK2FtYUZBL2Y1L1A2a0t0anNBQUFBQS9mNS9QNmtLdGpzQUFBQUF2NDV3UDZrS3RqdVRISzgrL2Y1L1A2a0t0anNBQUFBQXY0NXdQNmtLdGp1VEhLOCt2NDV3UDZrS3RqdVRISzgrdjQ1d1A2a0t0anVUSEs4K3Y0NXdQNmtLdGp1VEhLOCt0eHBFUDZrS3Rqc1VqU1EvdjQ1d1A2a0t0anVUSEs4K3R4cEVQNmtLdGpzVWpTUS90eHBFUDZrS3Rqc1VqU1EvdHhwRVA2a0t0anNValNRL3R4cEVQNmtLdGpzVWpTUS8vZjcvUHFrS3RqdjNzbDAvdHhwRVA2a0t0anNValNRLy9mNy9QcWtLdGp2M3NsMC8vZjcvUHFrS3RqdjNzbDAvL2Y3L1Bxa0t0anYzc2wwLy9mNy9QcWtLdGp2M3NsMC9JTkF4UHFrS3RqdGRHM3cvL2Y3L1Bxa0t0anYzc2wwL0lOQXhQcWtLdGp0ZEczdy9JTkF4UHFrS3RqdGRHM3cvSU5BeFBxa0t0anRkRzN3L0lOQXhQcWtLdGp0ZEczdy9JTkF4dnFrS3RqdGRHM3cvSU5BeFBxa0t0anRkRzN3L0lOQXh2cWtLdGp0ZEczdy9JTkF4dnFrS3RqdGRHM3cvSU5BeHZxa0t0anRkRzN3L0lOQXh2cWtLdGp0ZEczdy8vZjcvdnFrS3RqdjNzbDAvSU5BeHZxa0t0anRkRzN3Ly9mNy92cWtLdGp2M3NsMC8vZjcvdnFrS3RqdjNzbDAvL2Y3L3Zxa0t0anYzc2wwLy9mNy92cWtLdGp2M3NsMC90eHBFdjZrS3Rqc1VqU1EvL2Y3L3Zxa0t0anYzc2wwL3R4cEV2NmtLdGpzVWpTUS90eHBFdjZrS3Rqc1VqU1EvdHhwRXY2a0t0anNValNRL3R4cEV2NmtLdGpzVWpTUS92NDV3djZrS3RqdVRISzgrdHhwRXY2a0t0anNValNRL3Y0NXd2NmtLdGp1VEhLOCt2NDV3djZrS3RqdVRISzgrdjQ1d3Y2a0t0anVUSEs4K3Y0NXd2NmtLdGp1VEhLOCsvZjUvdjZrS3RqdWpNQTBsdjQ1d3Y2a0t0anVUSEs4Ky9mNS92NmtLdGp1ak1BMGwvZjUvdjZrS3RqdWpNQTBsL2Y1L3Y2a0t0anVqTUEwbC9mNS92NmtLdGp1ak1BMGx2NDV3djZrS3RqdVRISysrL2Y1L3Y2a0t0anVqTUEwbHY0NXd2NmtLdGp1VEhLKyt2NDV3djZrS3RqdVRISysrdjQ1d3Y2a0t0anVUSEsrK3Y0NXd2NmtLdGp1VEhLKyt0eHBFdjZrS3Rqc1VqU1MvdjQ1d3Y2a0t0anVUSEsrK3R4cEV2NmtLdGpzVWpTUy90eHBFdjZrS3Rqc1VqU1MvdHhwRXY2a0t0anNValNTL3R4cEV2NmtLdGpzVWpTUy8vZjcvdnFrS3RqdjNzbDIvdHhwRXY2a0t0anNValNTLy9mNy92cWtLdGp2M3NsMi8vZjcvdnFrS3RqdjNzbDIvL2Y3L3Zxa0t0anYzc2wyLy9mNy92cWtLdGp2M3NsMi9JTkF4dnFrS3RqdGRHM3kvL2Y3L3Zxa0t0anYzc2wyL0lOQXh2cWtLdGp0ZEczeS9JTkF4dnFrS3RqdGRHM3kvSU5BeHZxa0t0anRkRzN5L0lOQXh2cWtLdGp0ZEczeS9JTkF4UHFrS3RqdGRHM3kvSU5BeHZxa0t0anRkRzN5L0lOQXhQcWtLdGp0ZEczeS9JTkF4UHFrS3RqdGRHM3kvSU5BeFBxa0t0anRkRzN5L0lOQXhQcWtLdGp0ZEczeS8vZjcvUHFrS3RqdjNzbDIvSU5BeFBxa0t0anRkRzN5Ly9mNy9QcWtLdGp2M3NsMi8vZjcvUHFrS3RqdjNzbDIvL2Y3L1Bxa0t0anYzc2wyLy9mNy9QcWtLdGp2M3NsMi90eHBFUDZrS3Rqc1VqU1MvL2Y3L1Bxa0t0anYzc2wyL3R4cEVQNmtLdGpzVWpTUy90eHBFUDZrS3Rqc1VqU1MvdHhwRVA2a0t0anNValNTL3R4cEVQNmtLdGpzVWpTUy92NDV3UDZrS3RqdVRISysrdHhwRVA2a0t0anNValNTL3Y0NXdQNmtLdGp1VEhLKyt2NDV3UDZrS3RqdVRISysrdjQ1d1A2a0t0anVUSEsrK3Y0NXdQNmtLdGp1VEhLKysvZjUvUDZrS3Rqc0FBQUFBdjQ1d1A2a0t0anVUSEsrKy9mNS9QNmtLdGpzQUFBQUEvZjUvUDZrS3Rqc0FBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFDQUFBQUFBQUFBZ0Q4QUFBQ0FBQUFBQUFBQWdEOEFBQUNBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQWdBQUFnTDhBQUFBQUFBQUFnQUFBZ0w4QUFBQUFBQUFBZ0FBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBOWYxL1ArVlhBVHdBQUFBQTlmMS9QK1ZYQVR3QUFBQUF4NDF3UCtWWEFUemVHNjgrOWYxL1ArVlhBVHdBQUFBQXg0MXdQK1ZYQVR6ZUc2OCt4NDF3UCtWWEFUemVHNjgreDQxd1ArVlhBVHplRzY4K3g0MXdQK1ZYQVR6ZUc2OCs3UmxFUCtWWEFUeHJqQ1EveDQxd1ArVlhBVHplRzY4KzdSbEVQK1ZYQVR4cmpDUS83UmxFUCtWWEFUeHJqQ1EvN1JsRVArVlhBVHhyakNRLzdSbEVQK1ZYQVR4cmpDUS85ZjMvUHVWWEFUd1NzbDAvN1JsRVArVlhBVHhyakNRLzlmMy9QdVZYQVR3U3NsMC85ZjMvUHVWWEFUd1NzbDAvOWYzL1B1VlhBVHdTc2wwLzlmMy9QdVZYQVR3U3NsMC9hYzh4UHVWWEFUeGFHbncvOWYzL1B1VlhBVHdTc2wwL2FjOHhQdVZYQVR4YUdudy9hYzh4UHVWWEFUeGFHbncvYWM4eFB1VlhBVHhhR253L2FjOHhQdVZYQVR4YUdudy9hYzh4dnVWWEFUeGFHbncvYWM4eFB1VlhBVHhhR253L2FjOHh2dVZYQVR4YUdudy9hYzh4dnVWWEFUeGFHbncvYWM4eHZ1VlhBVHhhR253L2FjOHh2dVZYQVR4YUdudy85ZjMvdnVWWEFUd1NzbDAvYWM4eHZ1VlhBVHhhR253LzlmMy92dVZYQVR3U3NsMC85ZjMvdnVWWEFUd1NzbDAvOWYzL3Z1VlhBVHdTc2wwLzlmMy92dVZYQVR3U3NsMC83UmxFditWWEFUeHJqQ1EvOWYzL3Z1VlhBVHdTc2wwLzdSbEV2K1ZYQVR4cmpDUS83UmxFditWWEFUeHJqQ1EvN1JsRXYrVlhBVHhyakNRLzdSbEV2K1ZYQVR4cmpDUS94NDF3ditWWEFUemVHNjgrN1JsRXYrVlhBVHhyakNRL3g0MXd2K1ZYQVR6ZUc2OCt4NDF3ditWWEFUemVHNjgreDQxd3YrVlhBVHplRzY4K3g0MXd2K1ZYQVR6ZUc2OCs5ZjEvditWWEFUd1JNQTBseDQxd3YrVlhBVHplRzY4KzlmMS92K1ZYQVR3Uk1BMGw5ZjEvditWWEFUd1JNQTBsOWYxL3YrVlhBVHdSTUEwbDlmMS92K1ZYQVR3Uk1BMGx4NDF3ditWWEFUemVHNisrOWYxL3YrVlhBVHdSTUEwbHg0MXd2K1ZYQVR6ZUc2Kyt4NDF3ditWWEFUemVHNisreDQxd3YrVlhBVHplRzYrK3g0MXd2K1ZYQVR6ZUc2Kys3UmxFditWWEFUeHJqQ1MveDQxd3YrVlhBVHplRzYrKzdSbEV2K1ZYQVR4cmpDUy83UmxFditWWEFUeHJqQ1MvN1JsRXYrVlhBVHhyakNTLzdSbEV2K1ZYQVR4cmpDUy85ZjMvdnVWWEFUd1NzbDIvN1JsRXYrVlhBVHhyakNTLzlmMy92dVZYQVR3U3NsMi85ZjMvdnVWWEFUd1NzbDIvOWYzL3Z1VlhBVHdTc2wyLzlmMy92dVZYQVR3U3NsMi9hYzh4dnVWWEFUeGFHbnkvOWYzL3Z1VlhBVHdTc2wyL2FjOHh2dVZYQVR4YUdueS9hYzh4dnVWWEFUeGFHbnkvYWM4eHZ1VlhBVHhhR255L2FjOHh2dVZYQVR4YUdueS9hYzh4UHVWWEFUeGFHbnkvYWM4eHZ1VlhBVHhhR255L2FjOHhQdVZYQVR4YUdueS9hYzh4UHVWWEFUeGFHbnkvYWM4eFB1VlhBVHhhR255L2FjOHhQdVZYQVR4YUdueS85ZjMvUHVWWEFUd1NzbDIvYWM4eFB1VlhBVHhhR255LzlmMy9QdVZYQVR3U3NsMi85ZjMvUHVWWEFUd1NzbDIvOWYzL1B1VlhBVHdTc2wyLzlmMy9QdVZYQVR3U3NsMi83UmxFUCtWWEFUeHJqQ1MvOWYzL1B1VlhBVHdTc2wyLzdSbEVQK1ZYQVR4cmpDUy83UmxFUCtWWEFUeHJqQ1MvN1JsRVArVlhBVHhyakNTLzdSbEVQK1ZYQVR4cmpDUy94NDF3UCtWWEFUemVHNisrN1JsRVArVlhBVHhyakNTL3g0MXdQK1ZYQVR6ZUc2Kyt4NDF3UCtWWEFUemVHNisreDQxd1ArVlhBVHplRzYrK3g0MXdQK1ZYQVR6ZUc2Kys5ZjEvUCtWWEFUd0FBQUFBeDQxd1ArVlhBVHplRzYrKzlmMS9QK1ZYQVR3QUFBQUE5ZjEvUCtWWEFUd0FBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFDQUFBQUFBQUFBZ0Q4QUFBQ0FBQUFBQUFBQWdEOEFBQUNBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQWdBQUFnTDhBQUFBQUFBQUFnQUFBZ0w4QUFBQUFBQUFBZ0FBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBSUFBQUFBQUFBQ0FQd0FBQUlBQUFBQUFBQUNBUHdBQUFJQUFBQUFBQUFBQWdBQUFnRDhBQUFBQUFBQUFnQUFBZ0Q4QUFBQUFBQUFBZ0FBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBSUFBQUFBQUFBQ0FQd0FBQUlBQUFBQUFBQUNBUHdBQUFJQUFBQUFBQUFBQWdBQUFnRDhBQUFBQUFBQUFnQUFBZ0Q4QUFBQUFBQUFBZ0FBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBSUFBQUFBQUFBQ0FQd0FBQUlBQUFBQUFBQUNBUHdBQUFJQUFBQUFBQUFBQWdBQUFnRDhBQUFBQUFBQUFnQUFBZ0Q4QUFBQUFBQUFBZ0FBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQkFBSUFBd0FFQUFVQUJnQUhBQWdBQ1FBS0FBc0FEQUFOQUE0QUR3QVFBQkVBRWdBVEFCUUFGUUFXQUJjQUdBQVpBQm9BR3dBY0FCMEFIZ0FmQUNBQUlRQWlBQ01BSkFBbEFDWUFKd0FvQUNrQUtnQXJBQ3dBTFFBdUFDOEFNQUF4QURJQU13QTBBRFVBTmdBM0FEZ0FPUUE2QURzQVBBQTlBRDRBUHdCQUFFRUFRZ0JEQUVRQVJRQkdBRWNBU0FCSkFFb0FTd0JNQUUwQVRnQlBBRkFBVVFCU0FGTUFWQUJWQUZZQVZ3QllBRmtBV2dCYkFGd0FYUUJlQUY4QVlBQmhBR0lBWXdCa0FHVUFaZ0JuQUdnQWFRQnFBR3NBYkFCdEFHNEFid0J3QUhFQWNnQnpBSFFBZFFCMkFIY0FlQUI1QUhvQWV3QjhBSDBBZmdCL0FJQUFnUUNDQUlNQWhBQ0ZBSVlBaHdDSUFJa0FpZ0NMQUl3QWpRQ09BSThBa0FDUkFKSUFrd0NVQUpVQWxnQ1hBSmdBbVFDYUFKc0FuQUNkQUo0QW53Q2dBS0VBb2dDakFLUUFwUUNtQUtjQXFBQ3BBS29BcXdDc0FLMEFyZ0N2QUxBQXNRQ3lBTE1BdEFDMUFMWUF0d0M0QUxrQXVnQzdBTHdBdlFDK0FMOEF3QURCQU1JQXd3REVBTVVBeGdESEFNZ0F5UURLQU1zQXpBRE5BTTRBendEUUFORUEwZ0RUQU5RQTFRRFdBTmNBMkFEWkFOb0Eyd0RjQU4wQTNnRGZBT0FBNFFEaUFPTUE1QURsQU9ZQTV3RG9BT2tBNmdEckFPd0E3UUR1QU84QThBRHhBUElBOHdEMEFQVUE5Z0QzQVBnQStRRDZBUHNBL0FEOUFQNEEvd0FBQVFFQkFnRURBUVFCQlFFR0FRY0JDQUVKQVFvQkN3RU1BUTBCRGdFUEFSQUJFUUVTQVJNQkZBRVZBUllCRndFWUFSa0JHZ0ViQVJ3QkhRRWVBUjhCSUFFaEFTSUJJd0VrQVNVQkpnRW5BU2dCS1FFcUFTc0JMQUV0QVM0Qkx3RXdBVEVCTWdFekFUUUJOUUUyQVRjQk9BRTVBVG9CT3dFOEFUMEJQZ0UvQVVBQlFRRkNBVU1CUkFGRkFVWUJSd0ZJQVVrQlNnRkxBVXdCVFFGT0FVOEJVQUZSQVZJQlV3RlVBVlVCVmdGWEFWZ0JXUUZhQVZzQlhBRmRBVjRCWHdGZ0FXRUJZZ0ZqQVdRQlpRRm1BV2NCYUFGcEFXb0Jhd0ZzQVcwQmJnRnZBWEFCY1FGeUFYTUJkQUYxQVhZQmR3RjRBWGtCZWdGN0FYd0JmUUYrQVg4QmdBR0JBWUlCZ3dHRUFZVUJoZ0dIQVlnQmlRR0tBWXNCakFHTkFZNEJqd0dRQVpFQmtnR1RBWlFCbFFHV0FaY0JtQUdaQVpvQm13R2NBWjBCbmdHZkFhQUJvUUdpQWFNQnBBR2xBYVlCcHdHb0Fha0JxZ0dyQWF3QnJRR3VBYThCc0FHeEFiSUJzd0cwQWJVQnRnRzNBYmdCdVFHNkFic0J2QUc5QWI0QnZ3SEFBY0VCd2dIREFjUUJ4UUhHQWNjQnlBSEpBY29CeXdITUFjMEJ6Z0hQQWRBQjBRSFNBZE1CMUFIVkFkWUIxd0hZQWRrQjJnSGJBZHdCM1FIZUFkOEI0QUhoQWVJQjR3SGtBZVVCNWdIbkFlZ0I2UUhxQWVzQjdBSHRBZTRCN3dId0FmRUI4Z0h6QWZRQjlRSDJBZmNCK0FINUFmb0Ird0g4QWYwQi9nSC9BUUFDQVFJQ0FnTUNDdGVqUFhFOW1rQWZoV3UvZXhUdVAwamhXa0E5Q2xlL3VCN0ZQeWxjenora2NEMi9DdGVqUFhFOW1rQWZoV3UvdUI3RlB5bGN6eitrY0QyL0N0ZWpQTGdlQlVEMktGeS96Y3hNdlQwS2QwQ2tjRDNBTXpPVFA2UndIVUE5Q2pmQWo4SjFQeWxjanorRjZ6SEF6Y3hNdlQwS2QwQ2tjRDNBajhKMVB5bGNqeitGNnpIQUN0ZWp2UlN1eHo5STRUckExMWFQT3JyL1k3MWFtbisvMTFhUE9yci9ZNzFhbW4rLzExYVBPcnIvWTcxYW1uKy8rYmVTUFZxNnY3eWNSWCsvK2JlU1BWcTZ2N3ljUlgrLytiZVNQVnE2djd5Y1JYKy9tdmMvUE1IZGVyMTJnSCsvbXZjL1BNSGRlcjEyZ0grL212Yy9QTUhkZXIxMmdIKy9TNHdBUGdtN21yekY3WDIvUzR3QVBnbTdtcnpGN1gyL1M0d0FQZ203bXJ6RjdYMi9BQUFCQUFJQUF3QUVBQVVBQmdBSEFBZ0FDUUFLQUFzQWo4SjF2eFN1Unovc1ViZy9qOEoxUHhTdVJ6L3NVYmcvajhKMVA2NUhZVC9zVWJnL2o4SjF2eFN1Unovc1ViZy9qOEoxUDY1SFlUL3NVYmcvajhKMXY2NUhZVC9zVWJnL2o4SjFQeFN1UnordVI2RS9qOEoxdnhTdVJ6K3VSNkUvajhKMXY2NUhZVCt1UjZFL2o4SjFQeFN1UnordVI2RS9qOEoxdjY1SFlUK3VSNkUvajhKMVA2NUhZVCt1UjZFL2o4SjF2eFN1UnordVI2RS9qOEoxdnhTdVJ6L3NVYmcvajhKMXY2NUhZVC9zVWJnL2o4SjF2eFN1UnordVI2RS9qOEoxdjY1SFlUL3NVYmcvajhKMXY2NUhZVCt1UjZFL2o4SjFQeFN1Unovc1ViZy9qOEoxUHhTdVJ6K3VSNkUvajhKMVA2NUhZVCt1UjZFL2o4SjFQeFN1Unovc1ViZy9qOEoxUDY1SFlUK3VSNkUvajhKMVA2NUhZVC9zVWJnL2o4SjF2NjVIWVQvc1ViZy9qOEoxUDY1SFlUL3NVYmcvajhKMVA2NUhZVCt1UjZFL2o4SjF2NjVIWVQvc1ViZy9qOEoxUDY1SFlUK3VSNkUvajhKMXY2NUhZVCt1UjZFL2o4SjF2eFN1UnordVI2RS9qOEoxUHhTdVJ6K3VSNkUvajhKMVB4U3VSei9zVWJnL2o4SjF2eFN1UnordVI2RS9qOEoxUHhTdVJ6L3NVYmcvajhKMXZ4U3VSei9zVWJnL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFBQUFBQUlBL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFBQUFBQUlDL0FBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0F2d0FBQUFBQUFBQUFBQUNBdndBQUFBQUFBQUFBQUFDQXZ3QUFBQUFBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQ0FQd0FBQUlBQUFBQUFBQUNBUHdBQUFJQUFBQUFBQUFDQVB3QUFBSUFBQUFBQUFBQUFnQUFBZ0Q4QUFBQUFBQUFBZ0FBQWdEOEFBQUFBQUFBQWdBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUJBQUlBQXdBRUFBVUFCZ0FIQUFnQUNRQUtBQXNBREFBTkFBNEFEd0FRQUJFQUVnQVRBQlFBRlFBV0FCY0FHQUFaQUJvQUd3QWNBQjBBSGdBZkFDQUFJUUFpQUNNQXpjeE1QeWxjanorUHduVS96Y3hNUDNzVXJqK1B3blUvdGoxTFAzc1Vyai9zbUgwL3pjeE1QeWxjanorUHduVS90ajFMUDNzVXJqL3NtSDAvdGoxTFB5bGNqei9zbUgwL3RqMUxQeWxjanovc21IMC90ajFMUDNzVXJqL3NtSDAvTXMxR1Azc1Vyai9ySG9JL3RqMUxQeWxjanovc21IMC9NczFHUDNzVXJqL3JIb0kvTXMxR1B5bGNqei9ySG9JL01zMUdQeWxjanovckhvSS9NczFHUDNzVXJqL3JIb0kvU1NoQVAzc1Vyajh0VjRRL01zMUdQeWxjanovckhvSS9TU2hBUDNzVXJqOHRWNFEvU1NoQVB5bGNqejh0VjRRL1NTaEFQeWxjano4dFY0US9TU2hBUDNzVXJqOHRWNFEvN0ZFNFAzc1Vyais0SG9VL1NTaEFQeWxjano4dFY0US83RkU0UDNzVXJqKzRIb1UvN0ZFNFB5bGNqeis0SG9VLzdGRTRQeWxjanorNEhvVS83RkU0UDNzVXJqKzRIb1UvajNzd1Azc1Vyajh0VjRRLzdGRTRQeWxjanorNEhvVS9qM3N3UDNzVXJqOHRWNFEvajNzd1B5bGNqejh0VjRRL2ozc3dQeWxjano4dFY0US9qM3N3UDNzVXJqOHRWNFEvcGRZcFAzc1Vyai9ySG9JL2ozc3dQeWxjano4dFY0US9wZFlwUDNzVXJqL3JIb0kvcGRZcFB5bGNqei9ySG9JL3BkWXBQeWxjanovckhvSS9wZFlwUDNzVXJqL3JIb0kvSVdZbFAzc1Vyai9zbUgwL3BkWXBQeWxjanovckhvSS9JV1lsUDNzVXJqL3NtSDAvSVdZbFB5bGNqei9zbUgwL0lXWWxQeWxjanovc21IMC9JV1lsUDNzVXJqL3NtSDAvQ3RjalAzc1VyaitQd25VL0lXWWxQeWxjanovc21IMC9DdGNqUDNzVXJqK1B3blUvQ3RjalB5bGNqeitQd25VL0N0Y2pQeWxjanorUHduVS9DdGNqUDNzVXJqK1B3blUvSVdZbFAzc1Vyajh5N0cwL0N0Y2pQeWxjanorUHduVS9JV1lsUDNzVXJqOHk3RzAvSVdZbFB5bGNqejh5N0cwL0lXWWxQeWxjano4eTdHMC9JV1lsUDNzVXJqOHk3RzAvcGRZcFAzc1VyajlKUjJjL0lXWWxQeWxjano4eTdHMC9wZFlwUDNzVXJqOUpSMmMvcGRZcFB5bGNqejlKUjJjL3BkWXBQeWxjano5SlIyYy9wZFlwUDNzVXJqOUpSMmMvajNzd1Azc1Vyai9GMW1JL3BkWXBQeWxjano5SlIyYy9qM3N3UDNzVXJqL0YxbUkvajNzd1B5bGNqei9GMW1JL2ozc3dQeWxjanovRjFtSS9qM3N3UDNzVXJqL0YxbUkvN0ZFNFAzc1Vyait1UjJFL2ozc3dQeWxjanovRjFtSS83RkU0UDNzVXJqK3VSMkUvN0ZFNFB5bGNqeit1UjJFLzdGRTRQeWxjanordVIyRS83RkU0UDNzVXJqK3VSMkUvU1NoQVAzc1Vyai9GMW1JLzdGRTRQeWxjanordVIyRS9TU2hBUDNzVXJqL0YxbUkvU1NoQVB5bGNqei9GMW1JL1NTaEFQeWxjanovRjFtSS9TU2hBUDNzVXJqL0YxbUkvTXMxR1Azc1VyajlKUjJjL1NTaEFQeWxjanovRjFtSS9NczFHUDNzVXJqOUpSMmMvTXMxR1B5bGNqejlKUjJjL01zMUdQeWxjano5SlIyYy9NczFHUDNzVXJqOUpSMmMvdGoxTFAzc1Vyajh5N0cwL01zMUdQeWxjano5SlIyYy90ajFMUDNzVXJqOHk3RzAvdGoxTFB5bGNqejh5N0cwL3RqMUxQeWxjano4eTdHMC90ajFMUDNzVXJqOHk3RzAvemN4TVAzc1VyaitQd25VL3RqMUxQeWxjano4eTdHMC96Y3hNUDNzVXJqK1B3blUvemN4TVB5bGNqeitQd25VL3RqMUxQM3NVcmo4eTdHMC9NczFHUDNzVXJqOUpSMmMvU1NoQVAzc1Vyai9GMW1JL3RqMUxQM3NVcmo4eTdHMC9TU2hBUDNzVXJqL0YxbUkvN0ZFNFAzc1Vyait1UjJFL3RqMUxQM3NVcmo4eTdHMC83RkU0UDNzVXJqK3VSMkUvajNzd1Azc1Vyai9GMW1JL3RqMUxQM3NVcmo4eTdHMC9qM3N3UDNzVXJqL0YxbUkvcGRZcFAzc1VyajlKUjJjL3RqMUxQM3NVcmo4eTdHMC9wZFlwUDNzVXJqOUpSMmMvSVdZbFAzc1Vyajh5N0cwL3RqMUxQM3NVcmo4eTdHMC9JV1lsUDNzVXJqOHk3RzAvQ3RjalAzc1VyaitQd25VL3RqMUxQM3NVcmo4eTdHMC9DdGNqUDNzVXJqK1B3blUvSVdZbFAzc1Vyai9zbUgwL3RqMUxQM3NVcmo4eTdHMC9JV1lsUDNzVXJqL3NtSDAvcGRZcFAzc1Vyai9ySG9JL3RqMUxQM3NVcmo4eTdHMC9wZFlwUDNzVXJqL3JIb0kvajNzd1Azc1Vyajh0VjRRL3RqMUxQM3NVcmo4eTdHMC9qM3N3UDNzVXJqOHRWNFEvN0ZFNFAzc1Vyais0SG9VL3RqMUxQM3NVcmo4eTdHMC83RkU0UDNzVXJqKzRIb1UvU1NoQVAzc1Vyajh0VjRRL3RqMUxQM3NVcmo4eTdHMC9TU2hBUDNzVXJqOHRWNFEvTXMxR1Azc1Vyai9ySG9JL3RqMUxQM3NVcmo4eTdHMC9NczFHUDNzVXJqL3JIb0kvdGoxTFAzc1Vyai9zbUgwL3RqMUxQM3NVcmo4eTdHMC90ajFMUDNzVXJqL3NtSDAvemN4TVAzc1VyaitQd25VL3pjeE1QeWxjanorUHduVS90ajFMUHlsY2p6L3NtSDAvTXMxR1B5bGNqei9ySG9JL3pjeE1QeWxjanorUHduVS9NczFHUHlsY2p6L3JIb0kvU1NoQVB5bGNqejh0VjRRL3pjeE1QeWxjanorUHduVS9TU2hBUHlsY2p6OHRWNFEvN0ZFNFB5bGNqeis0SG9VL3pjeE1QeWxjanorUHduVS83RkU0UHlsY2p6KzRIb1UvajNzd1B5bGNqejh0VjRRL3pjeE1QeWxjanorUHduVS9qM3N3UHlsY2p6OHRWNFEvcGRZcFB5bGNqei9ySG9JL3pjeE1QeWxjanorUHduVS9wZFlwUHlsY2p6L3JIb0kvSVdZbFB5bGNqei9zbUgwL3pjeE1QeWxjanorUHduVS9JV1lsUHlsY2p6L3NtSDAvQ3RjalB5bGNqeitQd25VL3pjeE1QeWxjanorUHduVS9DdGNqUHlsY2p6K1B3blUvSVdZbFB5bGNqejh5N0cwL3pjeE1QeWxjanorUHduVS9JV1lsUHlsY2p6OHk3RzAvcGRZcFB5bGNqejlKUjJjL3pjeE1QeWxjanorUHduVS9wZFlwUHlsY2p6OUpSMmMvajNzd1B5bGNqei9GMW1JL3pjeE1QeWxjanorUHduVS9qM3N3UHlsY2p6L0YxbUkvN0ZFNFB5bGNqeit1UjJFL3pjeE1QeWxjanorUHduVS83RkU0UHlsY2p6K3VSMkUvU1NoQVB5bGNqei9GMW1JL3pjeE1QeWxjanorUHduVS9TU2hBUHlsY2p6L0YxbUkvTXMxR1B5bGNqejlKUjJjL3pjeE1QeWxjanorUHduVS9NczFHUHlsY2p6OUpSMmMvdGoxTFB5bGNqejh5N0cwL0N0Y2p2eFN1aHorNEhzVy9DdGNqdjJabXBqKzRIc1cvSVdZbHYyWm1waitLTThHL0N0Y2p2eFN1aHorNEhzVy9JV1lsdjJabXBqK0tNOEcvSVdZbHZ4U3VoeitLTThHL0lXWWx2eFN1aHorS004Ry9JV1lsdjJabXBqK0tNOEcvcGRZcHYyWm1wajhWNGIyL0lXWWx2eFN1aHorS004Ry9wZFlwdjJabXBqOFY0YjIvcGRZcHZ4U3VoejhWNGIyL3BkWXB2eFN1aHo4VjRiMi9wZFlwdjJabXBqOFY0YjIvajNzd3YyWm1wai9UcUx1L3BkWXB2eFN1aHo4VjRiMi9qM3N3djJabXBqL1RxTHUvajNzd3Z4U3Voei9UcUx1L2ozc3d2eFN1aHovVHFMdS9qM3N3djJabXBqL1RxTHUvN0ZFNHYyWm1wajlJNGJxL2ozc3d2eFN1aHovVHFMdS83RkU0djJabXBqOUk0YnEvN0ZFNHZ4U3VoejlJNGJxLzdGRTR2eFN1aHo5STRicS83RkU0djJabXBqOUk0YnEvU1NoQXYyWm1wai9UcUx1LzdGRTR2eFN1aHo5STRicS9TU2hBdjJabXBqL1RxTHUvU1NoQXZ4U3Voei9UcUx1L1NTaEF2eFN1aHovVHFMdS9TU2hBdjJabXBqL1RxTHUvTXMxR3YyWm1wajhWNGIyL1NTaEF2eFN1aHovVHFMdS9NczFHdjJabXBqOFY0YjIvTXMxR3Z4U3VoejhWNGIyL01zMUd2eFN1aHo4VjRiMi9NczFHdjJabXBqOFY0YjIvdGoxTHYyWm1waitLTThHL01zMUd2eFN1aHo4VjRiMi90ajFMdjJabXBqK0tNOEcvdGoxTHZ4U3VoeitLTThHL3RqMUx2eFN1aHorS004Ry90ajFMdjJabXBqK0tNOEcvemN4TXYyWm1wais0SHNXL3RqMUx2eFN1aHorS004Ry96Y3hNdjJabXBqKzRIc1cvemN4TXZ4U3Voeis0SHNXL3pjeE12eFN1aHorNEhzVy96Y3hNdjJabXBqKzRIc1cvdGoxTHYyWm1wai9uQ2NtL3pjeE12eFN1aHorNEhzVy90ajFMdjJabXBqL25DY20vdGoxTHZ4U3Voei9uQ2NtL3RqMUx2eFN1aHovbkNjbS90ajFMdjJabXBqL25DY20vTXMxR3YyWm1wajljWE15L3RqMUx2eFN1aHovbkNjbS9NczFHdjJabXBqOWNYTXkvTXMxR3Z4U3VoejljWE15L01zMUd2eFN1aHo5Y1hNeS9NczFHdjJabXBqOWNYTXkvU1NoQXYyWm1waitkbE02L01zMUd2eFN1aHo5Y1hNeS9TU2hBdjJabXBqK2RsTTYvU1NoQXZ4U3VoeitkbE02L1NTaEF2eFN1aHorZGxNNi9TU2hBdjJabXBqK2RsTTYvN0ZFNHYyWm1wajhwWE0rL1NTaEF2eFN1aHorZGxNNi83RkU0djJabXBqOHBYTSsvN0ZFNHZ4U3VoejhwWE0rLzdGRTR2eFN1aHo4cFhNKy83RkU0djJabXBqOHBYTSsvajNzd3YyWm1waitkbE02LzdGRTR2eFN1aHo4cFhNKy9qM3N3djJabXBqK2RsTTYvajNzd3Z4U3VoeitkbE02L2ozc3d2eFN1aHorZGxNNi9qM3N3djJabXBqK2RsTTYvcGRZcHYyWm1wajljWE15L2ozc3d2eFN1aHorZGxNNi9wZFlwdjJabXBqOWNYTXkvcGRZcHZ4U3VoejljWE15L3BkWXB2eFN1aHo5Y1hNeS9wZFlwdjJabXBqOWNYTXkvSVdZbHYyWm1wai9uQ2NtL3BkWXB2eFN1aHo5Y1hNeS9JV1lsdjJabXBqL25DY20vSVdZbHZ4U3Voei9uQ2NtL0lXWWx2eFN1aHovbkNjbS9JV1lsdjJabXBqL25DY20vQ3RjanYyWm1wais0SHNXL0lXWWx2eFN1aHovbkNjbS9DdGNqdjJabXBqKzRIc1cvQ3RjanZ4U3Voeis0SHNXL0lXWWx2MlptcGovbkNjbS9wZFlwdjJabXBqOWNYTXkvajNzd3YyWm1waitkbE02L0lXWWx2MlptcGovbkNjbS9qM3N3djJabXBqK2RsTTYvN0ZFNHYyWm1wajhwWE0rL0lXWWx2MlptcGovbkNjbS83RkU0djJabXBqOHBYTSsvU1NoQXYyWm1waitkbE02L0lXWWx2MlptcGovbkNjbS9TU2hBdjJabXBqK2RsTTYvTXMxR3YyWm1wajljWE15L0lXWWx2MlptcGovbkNjbS9NczFHdjJabXBqOWNYTXkvdGoxTHYyWm1wai9uQ2NtL0lXWWx2MlptcGovbkNjbS90ajFMdjJabXBqL25DY20vemN4TXYyWm1wais0SHNXL0lXWWx2MlptcGovbkNjbS96Y3hNdjJabXBqKzRIc1cvdGoxTHYyWm1waitLTThHL0lXWWx2MlptcGovbkNjbS90ajFMdjJabXBqK0tNOEcvTXMxR3YyWm1wajhWNGIyL0lXWWx2MlptcGovbkNjbS9NczFHdjJabXBqOFY0YjIvU1NoQXYyWm1wai9UcUx1L0lXWWx2MlptcGovbkNjbS9TU2hBdjJabXBqL1RxTHUvN0ZFNHYyWm1wajlJNGJxL0lXWWx2MlptcGovbkNjbS83RkU0djJabXBqOUk0YnEvajNzd3YyWm1wai9UcUx1L0lXWWx2MlptcGovbkNjbS9qM3N3djJabXBqL1RxTHUvcGRZcHYyWm1wajhWNGIyL0lXWWx2MlptcGovbkNjbS9wZFlwdjJabXBqOFY0YjIvSVdZbHYyWm1waitLTThHL0lXWWx2MlptcGovbkNjbS9JV1lsdjJabXBqK0tNOEcvQ3RjanYyWm1wais0SHNXL0N0Y2p2eFN1aHorNEhzVy9JV1lsdnhTdWh6K0tNOEcvcGRZcHZ4U3VoejhWNGIyL0N0Y2p2eFN1aHorNEhzVy9wZFlwdnhTdWh6OFY0YjIvajNzd3Z4U3Voei9UcUx1L0N0Y2p2eFN1aHorNEhzVy9qM3N3dnhTdWh6L1RxTHUvN0ZFNHZ4U3VoejlJNGJxL0N0Y2p2eFN1aHorNEhzVy83RkU0dnhTdWh6OUk0YnEvU1NoQXZ4U3Voei9UcUx1L0N0Y2p2eFN1aHorNEhzVy9TU2hBdnhTdWh6L1RxTHUvTXMxR3Z4U3VoejhWNGIyL0N0Y2p2eFN1aHorNEhzVy9NczFHdnhTdWh6OFY0YjIvdGoxTHZ4U3VoeitLTThHL0N0Y2p2eFN1aHorNEhzVy90ajFMdnhTdWh6K0tNOEcvemN4TXZ4U3Voeis0SHNXL0N0Y2p2eFN1aHorNEhzVy96Y3hNdnhTdWh6KzRIc1cvdGoxTHZ4U3Voei9uQ2NtL0N0Y2p2eFN1aHorNEhzVy90ajFMdnhTdWh6L25DY20vTXMxR3Z4U3VoejljWE15L0N0Y2p2eFN1aHorNEhzVy9NczFHdnhTdWh6OWNYTXkvU1NoQXZ4U3VoeitkbE02L0N0Y2p2eFN1aHorNEhzVy9TU2hBdnhTdWh6K2RsTTYvN0ZFNHZ4U3VoejhwWE0rL0N0Y2p2eFN1aHorNEhzVy83RkU0dnhTdWh6OHBYTSsvajNzd3Z4U3VoeitkbE02L0N0Y2p2eFN1aHorNEhzVy9qM3N3dnhTdWh6K2RsTTYvcGRZcHZ4U3VoejljWE15L0N0Y2p2eFN1aHorNEhzVy9wZFlwdnhTdWh6OWNYTXkvSVdZbHZ4U3Voei9uQ2NtL0FBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBWG9Oc1B3QUFBQUFWNzhNK0FBQ0FQd0FBQUFBQUFBQUFYb05zUHdBQUFBQVY3OE0rWG9Oc1B3QUFBQUFWNzhNK1hvTnNQd0FBQUFBVjc4TStYb05zUHdBQUFBQVY3OE0rOHdRMVB3QUFBQUR6QkRVL1hvTnNQd0FBQUFBVjc4TSs4d1ExUHdBQUFBRHpCRFUvOHdRMVB3QUFBQUR6QkRVLzh3UTFQd0FBQUFEekJEVS84d1ExUHdBQUFBRHpCRFUvRmUvRFBnQUFBQUJlZzJ3Lzh3UTFQd0FBQUFEekJEVS9GZS9EUGdBQUFBQmVnMncvRmUvRFBnQUFBQUJlZzJ3L0ZlL0RQZ0FBQUFCZWcydy9GZS9EUGdBQUFBQmVnMncvTWpHTkpBQUFBQUFBQUlBL0ZlL0RQZ0FBQUFCZWcydy9NakdOSkFBQUFBQUFBSUEvTWpHTkpBQUFBQUFBQUlBL01qR05KQUFBQUFBQUFJQS9NakdOSkFBQUFBQUFBSUEvRmUvRHZnQUFBQUJlZzJ3L01qR05KQUFBQUFBQUFJQS9GZS9EdmdBQUFBQmVnMncvRmUvRHZnQUFBQUJlZzJ3L0ZlL0R2Z0FBQUFCZWcydy9GZS9EdmdBQUFBQmVnMncvOHdRMXZ3QUFBQUR6QkRVL0ZlL0R2Z0FBQUFCZWcydy84d1ExdndBQUFBRHpCRFUvOHdRMXZ3QUFBQUR6QkRVLzh3UTF2d0FBQUFEekJEVS84d1ExdndBQUFBRHpCRFUvWG9Oc3Z3QUFBQUFWNzhNKzh3UTF2d0FBQUFEekJEVS9Yb05zdndBQUFBQVY3OE0rWG9Oc3Z3QUFBQUFWNzhNK1hvTnN2d0FBQUFBVjc4TStYb05zdndBQUFBQVY3OE0rQUFDQXZ3QUFBQUF5TVEwbFhvTnN2d0FBQUFBVjc4TStBQUNBdndBQUFBQXlNUTBsQUFDQXZ3QUFBQUF5TVEwbEFBQ0F2d0FBQUFBeU1RMGxBQUNBdndBQUFBQXlNUTBsWG9Oc3Z3QUFBQUFWNzhPK0FBQ0F2d0FBQUFBeU1RMGxYb05zdndBQUFBQVY3OE8rWG9Oc3Z3QUFBQUFWNzhPK1hvTnN2d0FBQUFBVjc4TytYb05zdndBQUFBQVY3OE8rOHdRMXZ3QUFBQUR6QkRXL1hvTnN2d0FBQUFBVjc4Tys4d1ExdndBQUFBRHpCRFcvOHdRMXZ3QUFBQUR6QkRXLzh3UTF2d0FBQUFEekJEVy84d1ExdndBQUFBRHpCRFcvRmUvRHZnQUFBQUJlZzJ5Lzh3UTF2d0FBQUFEekJEVy9GZS9EdmdBQUFBQmVnMnkvRmUvRHZnQUFBQUJlZzJ5L0ZlL0R2Z0FBQUFCZWcyeS9GZS9EdmdBQUFBQmVnMnkveXNsVHBRQUFBQUFBQUlDL0ZlL0R2Z0FBQUFCZWcyeS95c2xUcFFBQUFBQUFBSUMveXNsVHBRQUFBQUFBQUlDL3lzbFRwUUFBQUFBQUFJQy95c2xUcFFBQUFBQUFBSUMvRmUvRFBnQUFBQUJlZzJ5L3lzbFRwUUFBQUFBQUFJQy9GZS9EUGdBQUFBQmVnMnkvRmUvRFBnQUFBQUJlZzJ5L0ZlL0RQZ0FBQUFCZWcyeS9GZS9EUGdBQUFBQmVnMnkvOHdRMVB3QUFBQUR6QkRXL0ZlL0RQZ0FBQUFCZWcyeS84d1ExUHdBQUFBRHpCRFcvOHdRMVB3QUFBQUR6QkRXLzh3UTFQd0FBQUFEekJEVy84d1ExUHdBQUFBRHpCRFcvWG9Oc1B3QUFBQUFWNzhPKzh3UTFQd0FBQUFEekJEVy9Yb05zUHdBQUFBQVY3OE8rWG9Oc1B3QUFBQUFWNzhPK1hvTnNQd0FBQUFBVjc4TytYb05zUHdBQUFBQVY3OE8rQUFDQVB3QUFBQUFBQUFBQVhvTnNQd0FBQUFBVjc4TytBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQ0FBQUFBQUFBQWdEOEFBQUNBQUFBQUFBQUFnRDhBQUFDQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFnQUFBZ0w4QUFBQUFBQUFBZ0FBQWdMOEFBQUFBQUFBQWdBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQ0FQd0FBQUFBQUFBQUFBQUNBUHdBQUFBQUFBQUFBWG9Oc1B3QUFBQUFWNzhNK0FBQ0FQd0FBQUFBQUFBQUFYb05zUHdBQUFBQVY3OE0rWG9Oc1B3QUFBQUFWNzhNK1hvTnNQd0FBQUFBVjc4TStYb05zUHdBQUFBQVY3OE0rOHdRMVB3QUFBQUR6QkRVL1hvTnNQd0FBQUFBVjc4TSs4d1ExUHdBQUFBRHpCRFUvOHdRMVB3QUFBQUR6QkRVLzh3UTFQd0FBQUFEekJEVS84d1ExUHdBQUFBRHpCRFUvRmUvRFBnQUFBQUJlZzJ3Lzh3UTFQd0FBQUFEekJEVS9GZS9EUGdBQUFBQmVnMncvRmUvRFBnQUFBQUJlZzJ3L0ZlL0RQZ0FBQUFCZWcydy9GZS9EUGdBQUFBQmVnMncvTWpHTkpBQUFBQUFBQUlBL0ZlL0RQZ0FBQUFCZWcydy9NakdOSkFBQUFBQUFBSUEvTWpHTkpBQUFBQUFBQUlBL01qR05KQUFBQUFBQUFJQS9NakdOSkFBQUFBQUFBSUEvRmUvRHZnQUFBQUJlZzJ3L01qR05KQUFBQUFBQUFJQS9GZS9EdmdBQUFBQmVnMncvRmUvRHZnQUFBQUJlZzJ3L0ZlL0R2Z0FBQUFCZWcydy9GZS9EdmdBQUFBQmVnMncvOHdRMXZ3QUFBQUR6QkRVL0ZlL0R2Z0FBQUFCZWcydy84d1ExdndBQUFBRHpCRFUvOHdRMXZ3QUFBQUR6QkRVLzh3UTF2d0FBQUFEekJEVS84d1ExdndBQUFBRHpCRFUvWG9Oc3Z3QUFBQUFWNzhNKzh3UTF2d0FBQUFEekJEVS9Yb05zdndBQUFBQVY3OE0rWG9Oc3Z3QUFBQUFWNzhNK1hvTnN2d0FBQUFBVjc4TStYb05zdndBQUFBQVY3OE0rQUFDQXZ3QUFBQUF5TVEwbFhvTnN2d0FBQUFBVjc4TStBQUNBdndBQUFBQXlNUTBsQUFDQXZ3QUFBQUF5TVEwbEFBQ0F2d0FBQUFBeU1RMGxBQUNBdndBQUFBQXlNUTBsWG9Oc3Z3QUFBQUFWNzhPK0FBQ0F2d0FBQUFBeU1RMGxYb05zdndBQUFBQVY3OE8rWG9Oc3Z3QUFBQUFWNzhPK1hvTnN2d0FBQUFBVjc4TytYb05zdndBQUFBQVY3OE8rOHdRMXZ3QUFBQUR6QkRXL1hvTnN2d0FBQUFBVjc4Tys4d1ExdndBQUFBRHpCRFcvOHdRMXZ3QUFBQUR6QkRXLzh3UTF2d0FBQUFEekJEVy84d1ExdndBQUFBRHpCRFcvRmUvRHZnQUFBQUJlZzJ5Lzh3UTF2d0FBQUFEekJEVy9GZS9EdmdBQUFBQmVnMnkvRmUvRHZnQUFBQUJlZzJ5L0ZlL0R2Z0FBQUFCZWcyeS9GZS9EdmdBQUFBQmVnMnkveXNsVHBRQUFBQUFBQUlDL0ZlL0R2Z0FBQUFCZWcyeS95c2xUcFFBQUFBQUFBSUMveXNsVHBRQUFBQUFBQUlDL3lzbFRwUUFBQUFBQUFJQy95c2xUcFFBQUFBQUFBSUMvRmUvRFBnQUFBQUJlZzJ5L3lzbFRwUUFBQUFBQUFJQy9GZS9EUGdBQUFBQmVnMnkvRmUvRFBnQUFBQUJlZzJ5L0ZlL0RQZ0FBQUFCZWcyeS9GZS9EUGdBQUFBQmVnMnkvOHdRMVB3QUFBQUR6QkRXL0ZlL0RQZ0FBQUFCZWcyeS84d1ExUHdBQUFBRHpCRFcvOHdRMVB3QUFBQUR6QkRXLzh3UTFQd0FBQUFEekJEVy84d1ExUHdBQUFBRHpCRFcvWG9Oc1B3QUFBQUFWNzhPKzh3UTFQd0FBQUFEekJEVy9Yb05zUHdBQUFBQVY3OE8rWG9Oc1B3QUFBQUFWNzhPK1hvTnNQd0FBQUFBVjc4TytYb05zUHdBQUFBQVY3OE8rQUFDQVB3QUFBQUFBQUFBQVhvTnNQd0FBQUFBVjc4TytBQUNBUHdBQUFBQUFBQUFBQUFDQVB3QUFBQUFBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0Q4QUFBQ0FBQUFBQUFBQWdEOEFBQUNBQUFBQUFBQUFnRDhBQUFDQUFBQUFBQUFBZ0Q4QUFBQUFBQUFBQUFBQWdEOEFBQUFBQUFBQUFBQUFnRDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFnQUFBZ0w4QUFBQUFBQUFBZ0FBQWdMOEFBQUFBQUFBQWdBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUFBQUFBZ0w4QUFBQUFBQUFBQUFBQWdMOEFBQUFBQUFBQUFBQUFnTDhBQUFBQUFBQUJBQUlBQXdBRUFBVUFCZ0FIQUFnQUNRQUtBQXNBREFBTkFBNEFEd0FRQUJFQUVnQVRBQlFBRlFBV0FCY0FHQUFaQUJvQUd3QWNBQjBBSGdBZkFDQUFJUUFpQUNNQUpBQWxBQ1lBSndBb0FDa0FLZ0FyQUN3QUxRQXVBQzhBTUFBeEFESUFNd0EwQURVQU5nQTNBRGdBT1FBNkFEc0FQQUE5QUQ0QVB3QkFBRUVBUWdCREFFUUFSUUJHQUVjQVNBQkpBRW9BU3dCTUFFMEFUZ0JQQUZBQVVRQlNBRk1BVkFCVkFGWUFWd0JZQUZrQVdnQmJBRndBWFFCZUFGOEFZQUJoQUdJQVl3QmtBR1VBWmdCbkFHZ0FhUUJxQUdzQWJBQnRBRzRBYndCd0FIRUFjZ0J6QUhRQWRRQjJBSGNBZUFCNUFIb0Fld0I4QUgwQWZnQi9BSUFBZ1FDQ0FJTUFoQUNGQUlZQWh3Q0lBSWtBaWdDTEFJd0FqUUNPQUk4QWtBQ1JBSklBa3dDVUFKVUFsZ0NYQUpnQW1RQ2FBSnNBbkFDZEFKNEFud0NnQUtFQW9nQ2pBS1FBcFFDbUFLY0FxQUNwQUtvQXF3Q3NBSzBBcmdDdkFMQUFzUUN5QUxNQXRBQzFBTFlBdHdDNEFMa0F1Z0M3QUx3QXZRQytBTDhBd0FEQkFNSUF3d0RFQU1VQXhnREhBTWdBeVFES0FNc0F6QUROQU00QXp3RFFBTkVBMGdEVEFOUUExUURXQU5jQTJBRFpBTm9BMndEY0FOMEEzZ0RmQU9BQTRRRGlBT01BNUFEbEFPWUE1d0RvQU9rQTZnRHJBT3dBN1FEdUFPOEE4QUR4QVBJQTh3RDBBUFVBOWdEM0FQZ0ErUUQ2QVBzQS9BRDlBUDRBL3dBQUFRRUJBZ0VEQVFRQkJRRUdBUWNCQ0FFSkFRb0JDd0VNQVEwQkRnRVBBUkFCRVFFU0FSTUJGQUVWQVJZQkZ3RVlBUmtCR2dFYkFSd0JIUUVlQVI4QklBRWhBU0lCSXdFa0FTVUJKZ0VuQVNnQktRRXFBU3NCTEFFdEFTNEJMd0V3QVRFQk1nRXpBVFFCTlFFMkFUY0JPQUU1QVRvQk93RThBVDBCUGdFL0FVQUJRUUZDQVVNQlJBRkZBVVlCUndGSUFVa0JTZ0ZMQVV3QlRRRk9BVThCVUFGUkFWSUJVd0ZVQVZVQlZnRlhBVmdCV1FGYUFWc0JYQUZkQVY0Qlh3RmdBV0VCWWdGakFXUUJaUUZtQVdjQiIsCiAgICAgICJieXRlTGVuZ3RoIjogMzYxOTIKICAgIH0KICBdLAogICJidWZmZXJWaWV3cyI6IFsKICAgIHsKICAgICAgImJ1ZmZlciI6IDAsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImJ5dGVMZW5ndGgiOiAzMDI0LAogICAgICAidGFyZ2V0IjogMzQ5NjIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXIiOiAwLAogICAgICAiYnl0ZU9mZnNldCI6IDMwMjQsCiAgICAgICJieXRlTGVuZ3RoIjogMzAyNCwKICAgICAgInRhcmdldCI6IDM0OTYyCiAgICB9LAogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiA2MDQ4LAogICAgICAiYnl0ZUxlbmd0aCI6IDUwNCwKICAgICAgInRhcmdldCI6IDM0OTYzCiAgICB9LAogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiA2NTUyLAogICAgICAiYnl0ZUxlbmd0aCI6IDE3MjgsCiAgICAgICJ0YXJnZXQiOiAzNDk2MgogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlciI6IDAsCiAgICAgICJieXRlT2Zmc2V0IjogODI4MCwKICAgICAgImJ5dGVMZW5ndGgiOiAxNzI4LAogICAgICAidGFyZ2V0IjogMzQ5NjIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXIiOiAwLAogICAgICAiYnl0ZU9mZnNldCI6IDEwMDA4LAogICAgICAiYnl0ZUxlbmd0aCI6IDI4OCwKICAgICAgInRhcmdldCI6IDM0OTYzCiAgICB9LAogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiAxMDI5NiwKICAgICAgImJ5dGVMZW5ndGgiOiA4NjQsCiAgICAgICJ0YXJnZXQiOiAzNDk2MgogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlciI6IDAsCiAgICAgICJieXRlT2Zmc2V0IjogMTExNjAsCiAgICAgICJieXRlTGVuZ3RoIjogODY0LAogICAgICAidGFyZ2V0IjogMzQ5NjIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXIiOiAwLAogICAgICAiYnl0ZU9mZnNldCI6IDEyMDI0LAogICAgICAiYnl0ZUxlbmd0aCI6IDE0NCwKICAgICAgInRhcmdldCI6IDM0OTYzCiAgICB9LAogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiAxMjE2OCwKICAgICAgImJ5dGVMZW5ndGgiOiA2MTkyLAogICAgICAidGFyZ2V0IjogMzQ5NjIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXIiOiAwLAogICAgICAiYnl0ZU9mZnNldCI6IDE4MzYwLAogICAgICAiYnl0ZUxlbmd0aCI6IDYxOTIsCiAgICAgICJ0YXJnZXQiOiAzNDk2MgogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlciI6IDAsCiAgICAgICJieXRlT2Zmc2V0IjogMjQ1NTIsCiAgICAgICJieXRlTGVuZ3RoIjogMTAzMiwKICAgICAgInRhcmdldCI6IDM0OTYzCiAgICB9LAogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiAyNTU4NCwKICAgICAgImJ5dGVMZW5ndGgiOiAxNDQsCiAgICAgICJ0YXJnZXQiOiAzNDk2MgogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlciI6IDAsCiAgICAgICJieXRlT2Zmc2V0IjogMjU3MjgsCiAgICAgICJieXRlTGVuZ3RoIjogMTQ0LAogICAgICAidGFyZ2V0IjogMzQ5NjIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXIiOiAwLAogICAgICAiYnl0ZU9mZnNldCI6IDI1ODcyLAogICAgICAiYnl0ZUxlbmd0aCI6IDI0LAogICAgICAidGFyZ2V0IjogMzQ5NjMKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXIiOiAwLAogICAgICAiYnl0ZU9mZnNldCI6IDI1ODk2LAogICAgICAiYnl0ZUxlbmd0aCI6IDQzMiwKICAgICAgInRhcmdldCI6IDM0OTYyCiAgICB9LAogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiAyNjMyOCwKICAgICAgImJ5dGVMZW5ndGgiOiA0MzIsCiAgICAgICJ0YXJnZXQiOiAzNDk2MgogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlciI6IDAsCiAgICAgICJieXRlT2Zmc2V0IjogMjY3NjAsCiAgICAgICJieXRlTGVuZ3RoIjogNzIsCiAgICAgICJ0YXJnZXQiOiAzNDk2MwogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlciI6IDAsCiAgICAgICJieXRlT2Zmc2V0IjogMjY4MzIsCiAgICAgICJieXRlTGVuZ3RoIjogNDMyMCwKICAgICAgInRhcmdldCI6IDM0OTYyCiAgICB9LAogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiAzMTE1MiwKICAgICAgImJ5dGVMZW5ndGgiOiA0MzIwLAogICAgICAidGFyZ2V0IjogMzQ5NjIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXIiOiAwLAogICAgICAiYnl0ZU9mZnNldCI6IDM1NDcyLAogICAgICAiYnl0ZUxlbmd0aCI6IDcyMCwKICAgICAgInRhcmdldCI6IDM0OTYzCiAgICB9CiAgXSwKICAiYWNjZXNzb3JzIjogWwogICAgewogICAgICAiYnVmZmVyVmlldyI6IDAsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAiY291bnQiOiAyNTIsCiAgICAgICJ0eXBlIjogIlZFQzMiLAogICAgICAibWluIjogWwogICAgICAgIC0xLjU4LAogICAgICAgIC0xLjA4LAogICAgICAgIC00LjQKICAgICAgXSwKICAgICAgIm1heCI6IFsKICAgICAgICAxLjU4LAogICAgICAgIDEuMDIsCiAgICAgICAgMy45CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogMSwKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjYsCiAgICAgICJjb3VudCI6IDI1MiwKICAgICAgInR5cGUiOiAiVkVDMyIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogMiwKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjMsCiAgICAgICJjb3VudCI6IDI1MiwKICAgICAgInR5cGUiOiAiU0NBTEFSIiwKICAgICAgIm1pbiI6IFsKICAgICAgICAwCiAgICAgIF0sCiAgICAgICJtYXgiOiBbCiAgICAgICAgMjUxCiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogMywKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjYsCiAgICAgICJjb3VudCI6IDE0NCwKICAgICAgInR5cGUiOiAiVkVDMyIsCiAgICAgICJtaW4iOiBbCiAgICAgICAgLTEuNTgsCiAgICAgICAgMC43OCwKICAgICAgICAtNC40CiAgICAgIF0sCiAgICAgICJtYXgiOiBbCiAgICAgICAgMS41OCwKICAgICAgICAxLjU0LAogICAgICAgIDMuOQogICAgICBdCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDQsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAiY291bnQiOiAxNDQsCiAgICAgICJ0eXBlIjogIlZFQzMiCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDUsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTIzLAogICAgICAiY291bnQiOiAxNDQsCiAgICAgICJ0eXBlIjogIlNDQUxBUiIsCiAgICAgICJtaW4iOiBbCiAgICAgICAgMAogICAgICBdLAogICAgICAibWF4IjogWwogICAgICAgIDE0MwogICAgICBdCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDYsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAiY291bnQiOiA3MiwKICAgICAgInR5cGUiOiAiVkVDMyIsCiAgICAgICJtaW4iOiBbCiAgICAgICAgLTEuNDgsCiAgICAgICAgMC44NCwKICAgICAgICAtMi4yCiAgICAgIF0sCiAgICAgICJtYXgiOiBbCiAgICAgICAgMS40OCwKICAgICAgICAxLjYyLAogICAgICAgIDIuNAogICAgICBdCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDcsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAiY291bnQiOiA3MiwKICAgICAgInR5cGUiOiAiVkVDMyIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogOCwKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjMsCiAgICAgICJjb3VudCI6IDcyLAogICAgICAidHlwZSI6ICJTQ0FMQVIiLAogICAgICAibWluIjogWwogICAgICAgIDAKICAgICAgXSwKICAgICAgIm1heCI6IFsKICAgICAgICA3MQogICAgICBdCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDksCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAiY291bnQiOiA1MTYsCiAgICAgICJ0eXBlIjogIlZFQzMiLAogICAgICAibWluIjogWwogICAgICAgIC0wLjE2LAogICAgICAgIDAuODQ5OTk5OTk5OTk5OTk5NiwKICAgICAgICAtMwogICAgICBdLAogICAgICAibWF4IjogWwogICAgICAgIDIuMTgsCiAgICAgICAgNi4yNSwKICAgICAgICA1LjA1CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogMTAsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAiY291bnQiOiA1MTYsCiAgICAgICJ0eXBlIjogIlZFQzMiCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDExLAogICAgICAiYnl0ZU9mZnNldCI6IDAsCiAgICAgICJjb21wb25lbnRUeXBlIjogNTEyMywKICAgICAgImNvdW50IjogNTE2LAogICAgICAidHlwZSI6ICJTQ0FMQVIiLAogICAgICAibWluIjogWwogICAgICAgIDAKICAgICAgXSwKICAgICAgIm1heCI6IFsKICAgICAgICA1MTUKICAgICAgXQogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlclZpZXciOiAxMiwKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjYsCiAgICAgICJjb3VudCI6IDEyLAogICAgICAidHlwZSI6ICJWRUMzIiwKICAgICAgIm1pbiI6IFsKICAgICAgICAtMC4wOCwKICAgICAgICAxLjEyLAogICAgICAgIC0yLjk2CiAgICAgIF0sCiAgICAgICJtYXgiOiBbCiAgICAgICAgMS44NiwKICAgICAgICA0LjgyLAogICAgICAgIC0wLjc0CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogMTMsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAiY291bnQiOiAxMiwKICAgICAgInR5cGUiOiAiVkVDMyIKICAgIH0sCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogMTQsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTIzLAogICAgICAiY291bnQiOiAxMiwKICAgICAgInR5cGUiOiAiU0NBTEFSIiwKICAgICAgIm1pbiI6IFsKICAgICAgICAwCiAgICAgIF0sCiAgICAgICJtYXgiOiBbCiAgICAgICAgMTEKICAgICAgXQogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlclZpZXciOiAxNSwKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjYsCiAgICAgICJjb3VudCI6IDM2LAogICAgICAidHlwZSI6ICJWRUMzIiwKICAgICAgIm1pbiI6IFsKICAgICAgICAtMC45NiwKICAgICAgICAwLjc4LAogICAgICAgIDEuMjYKICAgICAgXSwKICAgICAgIm1heCI6IFsKICAgICAgICAwLjk2LAogICAgICAgIDAuODgsCiAgICAgICAgMS40NAogICAgICBdCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDE2LAogICAgICAiYnl0ZU9mZnNldCI6IDAsCiAgICAgICJjb21wb25lbnRUeXBlIjogNTEyNiwKICAgICAgImNvdW50IjogMzYsCiAgICAgICJ0eXBlIjogIlZFQzMiCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDE3LAogICAgICAiYnl0ZU9mZnNldCI6IDAsCiAgICAgICJjb21wb25lbnRUeXBlIjogNTEyMywKICAgICAgImNvdW50IjogMzYsCiAgICAgICJ0eXBlIjogIlNDQUxBUiIsCiAgICAgICJtaW4iOiBbCiAgICAgICAgMAogICAgICBdLAogICAgICAibWF4IjogWwogICAgICAgIDM1CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogMTgsCiAgICAgICJieXRlT2Zmc2V0IjogMCwKICAgICAgImNvbXBvbmVudFR5cGUiOiA1MTI2LAogICAgICAiY291bnQiOiAzNjAsCiAgICAgICJ0eXBlIjogIlZFQzMiLAogICAgICAibWluIjogWwogICAgICAgIC0wLjc5OTk5OTk5OTk5OTk5OTksCiAgICAgICAgMS4wNiwKICAgICAgICAtMS42MgogICAgICBdLAogICAgICAibWF4IjogWwogICAgICAgIDAuNzk5OTk5OTk5OTk5OTk5OSwKICAgICAgICAxLjM1OTk5OTk5OTk5OTk5OTksCiAgICAgICAgMS4wNAogICAgICBdCiAgICB9LAogICAgewogICAgICAiYnVmZmVyVmlldyI6IDE5LAogICAgICAiYnl0ZU9mZnNldCI6IDAsCiAgICAgICJjb21wb25lbnRUeXBlIjogNTEyNiwKICAgICAgImNvdW50IjogMzYwLAogICAgICAidHlwZSI6ICJWRUMzIgogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlclZpZXciOiAyMCwKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjMsCiAgICAgICJjb3VudCI6IDM2MCwKICAgICAgInR5cGUiOiAiU0NBTEFSIiwKICAgICAgIm1pbiI6IFsKICAgICAgICAwCiAgICAgIF0sCiAgICAgICJtYXgiOiBbCiAgICAgICAgMzU5CiAgICAgIF0KICAgIH0KICBdCn0K"
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
22
36
|
// src/asset-url.js
|
|
23
|
-
function createInlineShowcaseAssetUrl() {
|
|
24
|
-
|
|
37
|
+
function createInlineShowcaseAssetUrl(assetName) {
|
|
38
|
+
const inlineUrl = INLINE_SHOWCASE_ASSET_URLS[assetName];
|
|
39
|
+
return inlineUrl ? new URL(inlineUrl) : null;
|
|
25
40
|
}
|
|
26
41
|
function getBrowserBaseUrl() {
|
|
27
42
|
if (typeof document !== "undefined" && typeof document.baseURI === "string" && document.baseURI.length > 0) {
|
|
@@ -32,27 +47,177 @@ function getBrowserBaseUrl() {
|
|
|
32
47
|
}
|
|
33
48
|
return null;
|
|
34
49
|
}
|
|
35
|
-
function
|
|
50
|
+
function normalizeAssetName(assetName) {
|
|
51
|
+
return typeof assetName === "string" && assetName in SHOWCASE_ASSET_FILES ? assetName : "brigantine";
|
|
52
|
+
}
|
|
53
|
+
function parseResolveArgs(baseUrlOrAssetName, assetName) {
|
|
54
|
+
if (typeof baseUrlOrAssetName === "string" && baseUrlOrAssetName in SHOWCASE_ASSET_FILES && typeof assetName === "undefined") {
|
|
55
|
+
return {
|
|
56
|
+
baseUrl: import_meta.url,
|
|
57
|
+
assetName: baseUrlOrAssetName
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
baseUrl: baseUrlOrAssetName ?? import_meta.url,
|
|
62
|
+
assetName: normalizeAssetName(assetName)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function resolveShowcaseAssetUrl(baseUrlOrAssetName, assetName) {
|
|
66
|
+
const resolved = parseResolveArgs(baseUrlOrAssetName, assetName);
|
|
67
|
+
const fileName = SHOWCASE_ASSET_FILES[resolved.assetName];
|
|
36
68
|
try {
|
|
37
|
-
return new URL(
|
|
69
|
+
return new URL(`../assets/${fileName}`, resolved.baseUrl);
|
|
38
70
|
} catch {
|
|
39
71
|
const browserBaseUrl = getBrowserBaseUrl();
|
|
40
72
|
if (browserBaseUrl) {
|
|
41
73
|
try {
|
|
42
|
-
const normalizedBaseUrl = new URL(
|
|
43
|
-
return new URL(
|
|
74
|
+
const normalizedBaseUrl = new URL(resolved.baseUrl, browserBaseUrl);
|
|
75
|
+
return new URL(`../assets/${fileName}`, normalizedBaseUrl);
|
|
44
76
|
} catch {
|
|
45
|
-
|
|
77
|
+
const inlineAsset = createInlineShowcaseAssetUrl(resolved.assetName);
|
|
78
|
+
if (inlineAsset) {
|
|
79
|
+
return inlineAsset;
|
|
80
|
+
}
|
|
46
81
|
}
|
|
47
82
|
}
|
|
48
|
-
|
|
83
|
+
try {
|
|
84
|
+
return new URL(`../assets/${fileName}`, import_meta.url);
|
|
85
|
+
} catch {
|
|
86
|
+
return new URL(`assets/${fileName}`, "file:///");
|
|
87
|
+
}
|
|
49
88
|
}
|
|
50
89
|
}
|
|
51
|
-
|
|
90
|
+
function shouldUseInlineShowcaseFallback(url) {
|
|
91
|
+
const href = url instanceof URL ? url.href : String(url ?? "");
|
|
92
|
+
return href.includes("/assets/");
|
|
93
|
+
}
|
|
94
|
+
var import_meta, SHOWCASE_ASSET_FILES;
|
|
52
95
|
var init_asset_url = __esm({
|
|
53
96
|
"src/asset-url.js"() {
|
|
97
|
+
init_showcase_inline_assets();
|
|
54
98
|
import_meta = {};
|
|
55
|
-
|
|
99
|
+
SHOWCASE_ASSET_FILES = Object.freeze({
|
|
100
|
+
brigantine: "brigantine.gltf",
|
|
101
|
+
cutter: "cutter.gltf",
|
|
102
|
+
lighthouse: "lighthouse.gltf",
|
|
103
|
+
"harbor-dock": "harbor-dock.gltf"
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// src/translations/en-GB.js
|
|
109
|
+
var gpuSharedEnGbTranslations;
|
|
110
|
+
var init_en_GB = __esm({
|
|
111
|
+
"src/translations/en-GB.js"() {
|
|
112
|
+
gpuSharedEnGbTranslations = Object.freeze({
|
|
113
|
+
"gpuShared.showcase.title": "Flag by the Sea",
|
|
114
|
+
"gpuShared.showcase.subtitle": "Shared 3D validation scene using GLTF ships, cloth, fluid continuity, adaptive performance, and telemetry.",
|
|
115
|
+
"gpuShared.showcase.status.booting": "Booting 3D scene...",
|
|
116
|
+
"gpuShared.showcase.status.live": "3D scene live - {fps} FPS",
|
|
117
|
+
"gpuShared.showcase.details.booting": "Preparing a moonlit harbor scene, GLTF hull data, cloth and fluid continuity plans, and adaptive quality metadata.",
|
|
118
|
+
"gpuShared.showcase.details.physics": "Stable world snapshots are emitted from {snapshotStageId} after the authoritative solver; the heavier hull now carries momentum through mass-aware collision impulses while cloth and fluid remain downstream.",
|
|
119
|
+
"gpuShared.showcase.details.realistic": "Moonlit GLTF ships now mix a brigantine and a cutter against modeled harbor assets; cloth, fluid, and ship-local lighting stay continuous while the governor pressure is {pressureLevel}.",
|
|
120
|
+
"gpuShared.showcase.details.legacy": "Moonlit GLTF ships use the legacy brigantine and placeholder harbor blocks while cloth, fluid, and ship-local lighting stay continuous while the governor pressure is {pressureLevel}.",
|
|
121
|
+
"gpuShared.showcase.action.pause": "Pause",
|
|
122
|
+
"gpuShared.showcase.action.resume": "Resume",
|
|
123
|
+
"gpuShared.showcase.control.stressMode": "Stress mode",
|
|
124
|
+
"gpuShared.showcase.control.focus": "Focus",
|
|
125
|
+
"gpuShared.showcase.focus.integrated": "integrated",
|
|
126
|
+
"gpuShared.showcase.focus.lighting": "lighting",
|
|
127
|
+
"gpuShared.showcase.focus.cloth": "cloth",
|
|
128
|
+
"gpuShared.showcase.focus.fluid": "fluid",
|
|
129
|
+
"gpuShared.showcase.focus.physics": "physics",
|
|
130
|
+
"gpuShared.showcase.focus.performance": "performance",
|
|
131
|
+
"gpuShared.showcase.focus.debug": "debug",
|
|
132
|
+
"gpuShared.showcase.legend.title": "Scene",
|
|
133
|
+
"gpuShared.showcase.legend.shipMetadata": "GLTF ships carry hull mass and damping metadata.",
|
|
134
|
+
"gpuShared.showcase.legend.lighting": "Lanterns and torches warm the moonlit harbor.",
|
|
135
|
+
"gpuShared.showcase.legend.collisions": "Mass-aware collisions stay authoritative near the camera.",
|
|
136
|
+
"gpuShared.showcase.section.sceneState": "Scene State",
|
|
137
|
+
"gpuShared.showcase.section.qualityBudgets": "Quality + Budgets",
|
|
138
|
+
"gpuShared.showcase.section.debugTelemetry": "Debug Telemetry",
|
|
139
|
+
"gpuShared.showcase.section.notes": "Notes",
|
|
140
|
+
"gpuShared.showcase.note.assetLoading": "Ships are loaded from a GLTF asset and carry mass, damping, restitution, and hull extents from node extras.",
|
|
141
|
+
"gpuShared.showcase.note.moonlight": "Moonlight sets the cold ambient read while deck lanterns and harbor torches provide warm local contrast.",
|
|
142
|
+
"gpuShared.showcase.note.continuity": "Cloth and fluid continuity stay coherent across near, mid, far, and horizon bands even in the darker night palette.",
|
|
143
|
+
"gpuShared.showcase.note.performance": "Performance pressure reduces visual detail before mass-weighted authoritative collision motion is touched.",
|
|
144
|
+
"gpuShared.showcase.note.physicsSnapshots": "Stable world snapshots are taken after the authoritative rigid-body commit and before visual follow-up work.",
|
|
145
|
+
"gpuShared.showcase.note.physicsCollisions": "The ships collide with mass-weighted impulses and positional correction, so the heavier hull keeps more of its line.",
|
|
146
|
+
"gpuShared.showcase.note.physicsLighting": "Moonlight keeps the overall read legible while lanterns and torches make collision moments easy to track against the water.",
|
|
147
|
+
"gpuShared.debug.adapter.showcase": "3D showcase",
|
|
148
|
+
"gpuShared.debug.allocation.mainColorBuffer": "Main color buffer",
|
|
149
|
+
"gpuShared.debug.allocation.shadowImpressionAtlas": "Shadow impression atlas"
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// src/i18n.js
|
|
155
|
+
function formatTranslation(template, args = {}) {
|
|
156
|
+
return template.replace(/\{([A-Za-z0-9_]+)\}/g, (match, name) => {
|
|
157
|
+
if (!Object.prototype.hasOwnProperty.call(args, name)) {
|
|
158
|
+
return match;
|
|
159
|
+
}
|
|
160
|
+
const value = args[name];
|
|
161
|
+
return value == null ? "" : String(value);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function translateGpuSharedText(key, args, translate) {
|
|
165
|
+
const translated = translate?.(key, args);
|
|
166
|
+
if (translated && translated !== key) {
|
|
167
|
+
return translated;
|
|
168
|
+
}
|
|
169
|
+
const fallback = gpuSharedEnGbTranslations[key];
|
|
170
|
+
return fallback ? formatTranslation(fallback, args) : key;
|
|
171
|
+
}
|
|
172
|
+
function createGpuSharedTranslator(translate) {
|
|
173
|
+
return (key, args) => translateGpuSharedText(key, args, translate);
|
|
174
|
+
}
|
|
175
|
+
var gpuSharedTranslationKeys, gpuSharedTranslations;
|
|
176
|
+
var init_i18n = __esm({
|
|
177
|
+
"src/i18n.js"() {
|
|
178
|
+
init_en_GB();
|
|
179
|
+
gpuSharedTranslationKeys = Object.freeze({
|
|
180
|
+
showcaseTitle: "gpuShared.showcase.title",
|
|
181
|
+
showcaseSubtitle: "gpuShared.showcase.subtitle",
|
|
182
|
+
statusBooting: "gpuShared.showcase.status.booting",
|
|
183
|
+
statusLive: "gpuShared.showcase.status.live",
|
|
184
|
+
detailsBooting: "gpuShared.showcase.details.booting",
|
|
185
|
+
detailsPhysics: "gpuShared.showcase.details.physics",
|
|
186
|
+
detailsRealistic: "gpuShared.showcase.details.realistic",
|
|
187
|
+
detailsLegacy: "gpuShared.showcase.details.legacy",
|
|
188
|
+
pause: "gpuShared.showcase.action.pause",
|
|
189
|
+
resume: "gpuShared.showcase.action.resume",
|
|
190
|
+
stressMode: "gpuShared.showcase.control.stressMode",
|
|
191
|
+
focus: "gpuShared.showcase.control.focus",
|
|
192
|
+
focusIntegrated: "gpuShared.showcase.focus.integrated",
|
|
193
|
+
focusLighting: "gpuShared.showcase.focus.lighting",
|
|
194
|
+
focusCloth: "gpuShared.showcase.focus.cloth",
|
|
195
|
+
focusFluid: "gpuShared.showcase.focus.fluid",
|
|
196
|
+
focusPhysics: "gpuShared.showcase.focus.physics",
|
|
197
|
+
focusPerformance: "gpuShared.showcase.focus.performance",
|
|
198
|
+
focusDebug: "gpuShared.showcase.focus.debug",
|
|
199
|
+
legendTitle: "gpuShared.showcase.legend.title",
|
|
200
|
+
legendShipMetadata: "gpuShared.showcase.legend.shipMetadata",
|
|
201
|
+
legendLighting: "gpuShared.showcase.legend.lighting",
|
|
202
|
+
legendCollisions: "gpuShared.showcase.legend.collisions",
|
|
203
|
+
sceneState: "gpuShared.showcase.section.sceneState",
|
|
204
|
+
qualityBudgets: "gpuShared.showcase.section.qualityBudgets",
|
|
205
|
+
debugTelemetry: "gpuShared.showcase.section.debugTelemetry",
|
|
206
|
+
notes: "gpuShared.showcase.section.notes",
|
|
207
|
+
noteAssetLoading: "gpuShared.showcase.note.assetLoading",
|
|
208
|
+
noteMoonlight: "gpuShared.showcase.note.moonlight",
|
|
209
|
+
noteContinuity: "gpuShared.showcase.note.continuity",
|
|
210
|
+
notePerformance: "gpuShared.showcase.note.performance",
|
|
211
|
+
notePhysicsSnapshots: "gpuShared.showcase.note.physicsSnapshots",
|
|
212
|
+
notePhysicsCollisions: "gpuShared.showcase.note.physicsCollisions",
|
|
213
|
+
notePhysicsLighting: "gpuShared.showcase.note.physicsLighting",
|
|
214
|
+
debugAdapterShowcase: "gpuShared.debug.adapter.showcase",
|
|
215
|
+
debugMainColorBuffer: "gpuShared.debug.allocation.mainColorBuffer",
|
|
216
|
+
debugShadowImpressionAtlas: "gpuShared.debug.allocation.shadowImpressionAtlas"
|
|
217
|
+
});
|
|
218
|
+
gpuSharedTranslations = Object.freeze({
|
|
219
|
+
"en-GB": gpuSharedEnGbTranslations
|
|
220
|
+
});
|
|
56
221
|
}
|
|
57
222
|
});
|
|
58
223
|
|
|
@@ -75,6 +240,8 @@ function decodeDataUri(uri) {
|
|
|
75
240
|
}
|
|
76
241
|
function getComponentArray(componentType, buffer, byteOffset, count) {
|
|
77
242
|
switch (componentType) {
|
|
243
|
+
case 5121:
|
|
244
|
+
return new Uint8Array(buffer, byteOffset, count);
|
|
78
245
|
case 5123:
|
|
79
246
|
return new Uint16Array(buffer, byteOffset, count);
|
|
80
247
|
case 5125:
|
|
@@ -85,6 +252,16 @@ function getComponentArray(componentType, buffer, byteOffset, count) {
|
|
|
85
252
|
throw new Error(`Unsupported glTF componentType: ${componentType}`);
|
|
86
253
|
}
|
|
87
254
|
}
|
|
255
|
+
function getNormalizationScale(componentType) {
|
|
256
|
+
switch (componentType) {
|
|
257
|
+
case 5121:
|
|
258
|
+
return 255;
|
|
259
|
+
case 5123:
|
|
260
|
+
return 65535;
|
|
261
|
+
default:
|
|
262
|
+
return 1;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
88
265
|
function getTypeSize(type) {
|
|
89
266
|
switch (type) {
|
|
90
267
|
case "SCALAR":
|
|
@@ -100,27 +277,59 @@ function getTypeSize(type) {
|
|
|
100
277
|
}
|
|
101
278
|
}
|
|
102
279
|
function readAccessor(document2, accessorIndex, buffers) {
|
|
103
|
-
const accessor = document2.accessors[accessorIndex];
|
|
104
|
-
|
|
280
|
+
const accessor = document2.accessors?.[accessorIndex];
|
|
281
|
+
if (!accessor) {
|
|
282
|
+
throw new Error(`glTF accessor ${accessorIndex} is missing.`);
|
|
283
|
+
}
|
|
284
|
+
const bufferView = document2.bufferViews?.[accessor.bufferView];
|
|
285
|
+
if (!bufferView) {
|
|
286
|
+
throw new Error(`glTF bufferView ${accessor.bufferView} is missing.`);
|
|
287
|
+
}
|
|
105
288
|
const buffer = buffers[bufferView.buffer];
|
|
106
289
|
const componentCount = getTypeSize(accessor.type);
|
|
107
290
|
const byteOffset = (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);
|
|
108
291
|
const valueCount = accessor.count * componentCount;
|
|
109
|
-
|
|
292
|
+
const values = Array.from(
|
|
293
|
+
getComponentArray(accessor.componentType, buffer, byteOffset, valueCount)
|
|
294
|
+
);
|
|
295
|
+
if (accessor.normalized) {
|
|
296
|
+
const scale = getNormalizationScale(accessor.componentType);
|
|
297
|
+
return values.map((value) => value / scale);
|
|
298
|
+
}
|
|
299
|
+
return values;
|
|
110
300
|
}
|
|
111
|
-
function
|
|
301
|
+
function getMaterialInfo(document2, primitive) {
|
|
112
302
|
const material = document2.materials?.[primitive.material] ?? null;
|
|
113
303
|
const factor = material?.pbrMetallicRoughness?.baseColorFactor ?? [0.56, 0.33, 0.22, 1];
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
304
|
+
const emissive = material?.emissiveFactor ?? [0, 0, 0];
|
|
305
|
+
return Object.freeze({
|
|
306
|
+
name: material?.name ?? "default-material",
|
|
307
|
+
color: Object.freeze({
|
|
308
|
+
r: factor[0],
|
|
309
|
+
g: factor[1],
|
|
310
|
+
b: factor[2],
|
|
311
|
+
a: factor[3] ?? 1
|
|
312
|
+
}),
|
|
313
|
+
roughness: typeof material?.pbrMetallicRoughness?.roughnessFactor === "number" ? material.pbrMetallicRoughness.roughnessFactor : 0.92,
|
|
314
|
+
metallic: typeof material?.pbrMetallicRoughness?.metallicFactor === "number" ? material.pbrMetallicRoughness.metallicFactor : 0.08,
|
|
315
|
+
emissive: Object.freeze({
|
|
316
|
+
r: emissive[0] ?? 0,
|
|
317
|
+
g: emissive[1] ?? 0,
|
|
318
|
+
b: emissive[2] ?? 0
|
|
319
|
+
})
|
|
320
|
+
});
|
|
120
321
|
}
|
|
121
322
|
function computeBounds(positions) {
|
|
122
|
-
const min = [
|
|
123
|
-
|
|
323
|
+
const min = [
|
|
324
|
+
Number.POSITIVE_INFINITY,
|
|
325
|
+
Number.POSITIVE_INFINITY,
|
|
326
|
+
Number.POSITIVE_INFINITY
|
|
327
|
+
];
|
|
328
|
+
const max = [
|
|
329
|
+
Number.NEGATIVE_INFINITY,
|
|
330
|
+
Number.NEGATIVE_INFINITY,
|
|
331
|
+
Number.NEGATIVE_INFINITY
|
|
332
|
+
];
|
|
124
333
|
for (let index = 0; index < positions.length; index += 3) {
|
|
125
334
|
min[0] = Math.min(min[0], positions[index]);
|
|
126
335
|
min[1] = Math.min(min[1], positions[index + 1]);
|
|
@@ -129,7 +338,10 @@ function computeBounds(positions) {
|
|
|
129
338
|
max[1] = Math.max(max[1], positions[index + 1]);
|
|
130
339
|
max[2] = Math.max(max[2], positions[index + 2]);
|
|
131
340
|
}
|
|
132
|
-
return {
|
|
341
|
+
return Object.freeze({
|
|
342
|
+
min: Object.freeze([min[0], min[1], min[2]]),
|
|
343
|
+
max: Object.freeze([max[0], max[1], max[2]])
|
|
344
|
+
});
|
|
133
345
|
}
|
|
134
346
|
function resolveBrowserRequestBaseUrl() {
|
|
135
347
|
if (typeof document !== "undefined" && typeof document.baseURI === "string" && document.baseURI.length > 0) {
|
|
@@ -154,16 +366,173 @@ function resolveFetchBaseUrl(requestUrl, responseUrl) {
|
|
|
154
366
|
if (browserBaseUrl) {
|
|
155
367
|
return new URL(requestUrl, browserBaseUrl);
|
|
156
368
|
}
|
|
157
|
-
throw new Error(
|
|
369
|
+
throw new Error(
|
|
370
|
+
`Unable to resolve a stable base URL for glTF asset loading: ${String(requestUrl)}`
|
|
371
|
+
);
|
|
158
372
|
}
|
|
159
373
|
}
|
|
160
|
-
|
|
374
|
+
function createIdentityMatrix() {
|
|
375
|
+
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
376
|
+
}
|
|
377
|
+
function multiplyMatrices(a, b) {
|
|
378
|
+
const out = new Array(16).fill(0);
|
|
379
|
+
for (let column = 0; column < 4; column += 1) {
|
|
380
|
+
for (let row = 0; row < 4; row += 1) {
|
|
381
|
+
out[column * 4 + row] = a[0 * 4 + row] * b[column * 4 + 0] + a[1 * 4 + row] * b[column * 4 + 1] + a[2 * 4 + row] * b[column * 4 + 2] + a[3 * 4 + row] * b[column * 4 + 3];
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return out;
|
|
385
|
+
}
|
|
386
|
+
function composeNodeMatrix(node) {
|
|
387
|
+
if (Array.isArray(node.matrix) && node.matrix.length === 16) {
|
|
388
|
+
return [...node.matrix];
|
|
389
|
+
}
|
|
390
|
+
const translation = Array.isArray(node.translation) ? node.translation : [0, 0, 0];
|
|
391
|
+
const rotation = Array.isArray(node.rotation) ? node.rotation : [0, 0, 0, 1];
|
|
392
|
+
const scale = Array.isArray(node.scale) ? node.scale : [1, 1, 1];
|
|
393
|
+
const [x, y, z, w] = rotation;
|
|
394
|
+
const x2 = x + x;
|
|
395
|
+
const y2 = y + y;
|
|
396
|
+
const z2 = z + z;
|
|
397
|
+
const xx = x * x2;
|
|
398
|
+
const xy = x * y2;
|
|
399
|
+
const xz = x * z2;
|
|
400
|
+
const yy = y * y2;
|
|
401
|
+
const yz = y * z2;
|
|
402
|
+
const zz = z * z2;
|
|
403
|
+
const wx = w * x2;
|
|
404
|
+
const wy = w * y2;
|
|
405
|
+
const wz = w * z2;
|
|
406
|
+
return [
|
|
407
|
+
(1 - (yy + zz)) * scale[0],
|
|
408
|
+
(xy + wz) * scale[0],
|
|
409
|
+
(xz - wy) * scale[0],
|
|
410
|
+
0,
|
|
411
|
+
(xy - wz) * scale[1],
|
|
412
|
+
(1 - (xx + zz)) * scale[1],
|
|
413
|
+
(yz + wx) * scale[1],
|
|
414
|
+
0,
|
|
415
|
+
(xz + wy) * scale[2],
|
|
416
|
+
(yz - wx) * scale[2],
|
|
417
|
+
(1 - (xx + yy)) * scale[2],
|
|
418
|
+
0,
|
|
419
|
+
translation[0],
|
|
420
|
+
translation[1],
|
|
421
|
+
translation[2],
|
|
422
|
+
1
|
|
423
|
+
];
|
|
424
|
+
}
|
|
425
|
+
function transformPosition(position, matrix) {
|
|
426
|
+
return [
|
|
427
|
+
matrix[0] * position[0] + matrix[4] * position[1] + matrix[8] * position[2] + matrix[12],
|
|
428
|
+
matrix[1] * position[0] + matrix[5] * position[1] + matrix[9] * position[2] + matrix[13],
|
|
429
|
+
matrix[2] * position[0] + matrix[6] * position[1] + matrix[10] * position[2] + matrix[14]
|
|
430
|
+
];
|
|
431
|
+
}
|
|
432
|
+
function transformNormal(normal, matrix) {
|
|
433
|
+
const transformed = [
|
|
434
|
+
matrix[0] * normal[0] + matrix[4] * normal[1] + matrix[8] * normal[2],
|
|
435
|
+
matrix[1] * normal[0] + matrix[5] * normal[1] + matrix[9] * normal[2],
|
|
436
|
+
matrix[2] * normal[0] + matrix[6] * normal[1] + matrix[10] * normal[2]
|
|
437
|
+
];
|
|
438
|
+
const length = Math.hypot(transformed[0], transformed[1], transformed[2]) || 1;
|
|
439
|
+
return [transformed[0] / length, transformed[1] / length, transformed[2] / length];
|
|
440
|
+
}
|
|
441
|
+
function collectScenePrimitives(document2, buffers) {
|
|
442
|
+
const scene = document2.scenes?.[document2.scene ?? 0];
|
|
443
|
+
if (!scene || !Array.isArray(scene.nodes) || scene.nodes.length === 0) {
|
|
444
|
+
throw new Error("glTF demo asset must expose a default scene with at least one node.");
|
|
445
|
+
}
|
|
446
|
+
const results = [];
|
|
447
|
+
let modelName = null;
|
|
448
|
+
let physics = null;
|
|
449
|
+
function visit(nodeIndex, parentMatrix) {
|
|
450
|
+
const node = document2.nodes?.[nodeIndex];
|
|
451
|
+
if (!node) {
|
|
452
|
+
throw new Error(`glTF node ${nodeIndex} is missing.`);
|
|
453
|
+
}
|
|
454
|
+
const localMatrix = composeNodeMatrix(node);
|
|
455
|
+
const worldMatrix = multiplyMatrices(parentMatrix, localMatrix);
|
|
456
|
+
if (!modelName && typeof node.name === "string" && node.name.length > 0) {
|
|
457
|
+
modelName = node.name;
|
|
458
|
+
}
|
|
459
|
+
if (!physics && node.extras?.physics && typeof node.extras.physics === "object") {
|
|
460
|
+
physics = Object.freeze({ ...node.extras.physics });
|
|
461
|
+
}
|
|
462
|
+
if (typeof node.mesh === "number") {
|
|
463
|
+
const mesh = document2.meshes?.[node.mesh];
|
|
464
|
+
if (!mesh || !Array.isArray(mesh.primitives)) {
|
|
465
|
+
throw new Error(`glTF mesh ${node.mesh} is missing primitives.`);
|
|
466
|
+
}
|
|
467
|
+
mesh.primitives.forEach((primitive, primitiveIndex) => {
|
|
468
|
+
const positions = readAccessor(document2, primitive.attributes.POSITION, buffers);
|
|
469
|
+
const normals = typeof primitive.attributes.NORMAL === "number" ? readAccessor(document2, primitive.attributes.NORMAL, buffers) : null;
|
|
470
|
+
const colors = typeof primitive.attributes.COLOR_0 === "number" ? readAccessor(document2, primitive.attributes.COLOR_0, buffers) : null;
|
|
471
|
+
const transformedPositions = [];
|
|
472
|
+
const transformedNormals = [];
|
|
473
|
+
for (let index = 0; index < positions.length; index += 3) {
|
|
474
|
+
const point = transformPosition(
|
|
475
|
+
[positions[index], positions[index + 1], positions[index + 2]],
|
|
476
|
+
worldMatrix
|
|
477
|
+
);
|
|
478
|
+
transformedPositions.push(point[0], point[1], point[2]);
|
|
479
|
+
if (normals) {
|
|
480
|
+
const normal = transformNormal(
|
|
481
|
+
[normals[index], normals[index + 1], normals[index + 2]],
|
|
482
|
+
worldMatrix
|
|
483
|
+
);
|
|
484
|
+
transformedNormals.push(normal[0], normal[1], normal[2]);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const indices = typeof primitive.indices === "number" ? readAccessor(document2, primitive.indices, buffers).map((value) => Number(value)) : Array.from({ length: transformedPositions.length / 3 }, (_, index) => index);
|
|
488
|
+
const material = getMaterialInfo(document2, primitive);
|
|
489
|
+
const primitiveName = `${node.name ?? mesh.name ?? "mesh"}-${primitiveIndex}`;
|
|
490
|
+
results.push(
|
|
491
|
+
Object.freeze({
|
|
492
|
+
name: primitiveName,
|
|
493
|
+
positions: Object.freeze(transformedPositions),
|
|
494
|
+
indices: Object.freeze(indices),
|
|
495
|
+
normals: transformedNormals.length > 0 ? Object.freeze(transformedNormals) : null,
|
|
496
|
+
colors: colors ? Object.freeze(colors) : null,
|
|
497
|
+
material,
|
|
498
|
+
bounds: computeBounds(transformedPositions)
|
|
499
|
+
})
|
|
500
|
+
);
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
if (Array.isArray(node.children)) {
|
|
504
|
+
for (const childIndex of node.children) {
|
|
505
|
+
visit(childIndex, worldMatrix);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
for (const rootNodeIndex of scene.nodes) {
|
|
510
|
+
visit(rootNodeIndex, createIdentityMatrix());
|
|
511
|
+
}
|
|
512
|
+
if (results.length === 0) {
|
|
513
|
+
throw new Error("glTF demo asset must contain at least one mesh primitive.");
|
|
514
|
+
}
|
|
515
|
+
return {
|
|
516
|
+
name: modelName ?? "gltf-model",
|
|
517
|
+
physics: physics ?? Object.freeze({}),
|
|
518
|
+
primitives: results
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
async function loadGltfDocument(url) {
|
|
161
522
|
const response = await fetch(url);
|
|
162
523
|
if (!response.ok) {
|
|
163
524
|
throw new Error(`Failed to load glTF asset: ${response.status} ${response.statusText}`);
|
|
164
525
|
}
|
|
165
|
-
|
|
166
|
-
|
|
526
|
+
return {
|
|
527
|
+
document: await response.json(),
|
|
528
|
+
baseUrl: resolveFetchBaseUrl(url, response.url)
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
async function loadInlineShowcaseDocument() {
|
|
532
|
+
const module2 = await Promise.resolve().then(() => (init_showcase_inline_assets(), showcase_inline_assets_exports));
|
|
533
|
+
return loadGltfDocument(new URL(module2.INLINE_SHOWCASE_ASSET_URLS.brigantine));
|
|
534
|
+
}
|
|
535
|
+
async function buildGltfModel(document2, baseUrl2) {
|
|
167
536
|
const buffers = await Promise.all(
|
|
168
537
|
(document2.buffers ?? []).map(async (buffer) => {
|
|
169
538
|
if (typeof buffer.uri !== "string") {
|
|
@@ -179,26 +548,46 @@ async function loadGltfModel(url) {
|
|
|
179
548
|
return nested.arrayBuffer();
|
|
180
549
|
})
|
|
181
550
|
);
|
|
182
|
-
const scene = document2
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const
|
|
551
|
+
const scene = collectScenePrimitives(document2, buffers);
|
|
552
|
+
const aggregatePositions = [];
|
|
553
|
+
const aggregateIndices = [];
|
|
554
|
+
for (const primitive of scene.primitives) {
|
|
555
|
+
const vertexOffset = aggregatePositions.length / 3;
|
|
556
|
+
aggregatePositions.push(...primitive.positions);
|
|
557
|
+
aggregateIndices.push(...primitive.indices.map((index) => index + vertexOffset));
|
|
558
|
+
}
|
|
559
|
+
const color = scene.primitives[0]?.material?.color ?? { r: 0.56, g: 0.33, b: 0.22, a: 1 };
|
|
191
560
|
return Object.freeze({
|
|
192
|
-
name:
|
|
193
|
-
positions,
|
|
194
|
-
indices,
|
|
195
|
-
bounds: computeBounds(
|
|
196
|
-
color:
|
|
197
|
-
physics:
|
|
561
|
+
name: scene.name,
|
|
562
|
+
positions: Object.freeze(aggregatePositions),
|
|
563
|
+
indices: Object.freeze(aggregateIndices),
|
|
564
|
+
bounds: computeBounds(aggregatePositions),
|
|
565
|
+
color: Object.freeze({ ...color }),
|
|
566
|
+
physics: scene.physics,
|
|
567
|
+
primitives: Object.freeze(scene.primitives)
|
|
198
568
|
});
|
|
199
569
|
}
|
|
570
|
+
function shouldRetryWithInlineShowcaseFallback(url, error) {
|
|
571
|
+
if (!shouldUseInlineShowcaseFallback(url)) {
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
return error instanceof TypeError || /^Failed to load glTF asset:/u.test(error.message);
|
|
575
|
+
}
|
|
576
|
+
async function loadGltfModel(url) {
|
|
577
|
+
try {
|
|
578
|
+
const { document: document2, baseUrl: baseUrl2 } = await loadGltfDocument(url);
|
|
579
|
+
return buildGltfModel(document2, baseUrl2);
|
|
580
|
+
} catch (error) {
|
|
581
|
+
if (!shouldRetryWithInlineShowcaseFallback(url, error)) {
|
|
582
|
+
throw error;
|
|
583
|
+
}
|
|
584
|
+
const { document: document2, baseUrl: baseUrl2 } = await loadInlineShowcaseDocument();
|
|
585
|
+
return buildGltfModel(document2, baseUrl2);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
200
588
|
var init_gltf_loader = __esm({
|
|
201
589
|
"src/gltf-loader.js"() {
|
|
590
|
+
init_asset_url();
|
|
202
591
|
}
|
|
203
592
|
});
|
|
204
593
|
|
|
@@ -2519,7 +2908,7 @@ function getLightingProfile(name = defaultLightingProfile) {
|
|
|
2519
2908
|
}
|
|
2520
2909
|
return profile;
|
|
2521
2910
|
}
|
|
2522
|
-
var import_meta2, __require, baseUrl, techniqueSpecs, lightingTechniques, lightingTechniqueNames, defaultLightingTechnique, profileSpecs, lightingProfiles, lightingProfileNames, defaultLightingProfile, lightingDistanceBands, lightingWorkerQueueClass, lightingDebugOwner, lightingImportanceLevels, lightingBandPolicySpecs, lightingWorkerSpecPresets, lightingWorkerDagSpecs, lightingWorkerManifests, defaultTechnique, lightingPreludeWgslUrl, lightingJobLabels, lightingJobs;
|
|
2911
|
+
var import_meta2, __require, baseUrl, techniqueSpecs, lightingTechniques, lightingTechniqueNames, defaultLightingTechnique, profileSpecs, lightingProfiles, lightingProfileNames, defaultLightingProfile, lightingProfileModeOrder, defaultAdaptiveLightingProfilePolicy, lightingDistanceBands, lightingWorkerQueueClass, lightingDebugOwner, lightingImportanceLevels, lightingBandPolicySpecs, lightingProfileModeEstimatedCostMs, lightingWorkerSpecPresets, lightingWorkerDagSpecs, lightingWorkerManifests, defaultTechnique, lightingPreludeWgslUrl, lightingJobLabels, lightingJobs;
|
|
2523
2912
|
var init_dist3 = __esm({
|
|
2524
2913
|
"node_modules/@plasius/gpu-lighting/dist/index.js"() {
|
|
2525
2914
|
import_meta2 = {};
|
|
@@ -2613,6 +3002,16 @@ var init_dist3 = __esm({
|
|
|
2613
3002
|
);
|
|
2614
3003
|
lightingProfileNames = Object.freeze(Object.keys(lightingProfiles));
|
|
2615
3004
|
defaultLightingProfile = "realtime";
|
|
3005
|
+
lightingProfileModeOrder = Object.freeze([
|
|
3006
|
+
"realtime",
|
|
3007
|
+
"hybrid",
|
|
3008
|
+
"reference"
|
|
3009
|
+
]);
|
|
3010
|
+
defaultAdaptiveLightingProfilePolicy = Object.freeze({
|
|
3011
|
+
preferredProfile: "reference",
|
|
3012
|
+
minimumFrameRate: 30,
|
|
3013
|
+
sampleWindowSize: 4
|
|
3014
|
+
});
|
|
2616
3015
|
lightingDistanceBands = Object.freeze([
|
|
2617
3016
|
"near",
|
|
2618
3017
|
"mid",
|
|
@@ -2668,6 +3067,11 @@ var init_dist3 = __esm({
|
|
|
2668
3067
|
impressionOnly: true
|
|
2669
3068
|
})
|
|
2670
3069
|
});
|
|
3070
|
+
lightingProfileModeEstimatedCostMs = Object.freeze({
|
|
3071
|
+
realtime: 4.5,
|
|
3072
|
+
hybrid: 7.5,
|
|
3073
|
+
reference: 12.5
|
|
3074
|
+
});
|
|
2671
3075
|
lightingWorkerSpecPresets = {
|
|
2672
3076
|
hybrid: {
|
|
2673
3077
|
suggestedAllocationIds: [
|
|
@@ -6339,6 +6743,14 @@ var init_browser = __esm({
|
|
|
6339
6743
|
}
|
|
6340
6744
|
});
|
|
6341
6745
|
|
|
6746
|
+
// src/feature-flags.js
|
|
6747
|
+
var GPU_SHOWCASE_REALISTIC_MODELS_FEATURE;
|
|
6748
|
+
var init_feature_flags = __esm({
|
|
6749
|
+
"src/feature-flags.js"() {
|
|
6750
|
+
GPU_SHOWCASE_REALISTIC_MODELS_FEATURE = "gpu_showcase_realistic_models_v1";
|
|
6751
|
+
}
|
|
6752
|
+
});
|
|
6753
|
+
|
|
6342
6754
|
// src/showcase-runtime.js
|
|
6343
6755
|
var showcase_runtime_exports = {};
|
|
6344
6756
|
__export(showcase_runtime_exports, {
|
|
@@ -6375,6 +6787,11 @@ function injectStyles() {
|
|
|
6375
6787
|
radial-gradient(circle at 82% 18%, rgba(240, 188, 103, 0.08), transparent 18%),
|
|
6376
6788
|
linear-gradient(180deg, #04101d 0%, #0b1930 42%, #081321 100%);
|
|
6377
6789
|
}
|
|
6790
|
+
.${ROOT_CLASS}.${CAPTURE_CLASS} {
|
|
6791
|
+
min-height: 100vh;
|
|
6792
|
+
overflow: hidden;
|
|
6793
|
+
background: #030710;
|
|
6794
|
+
}
|
|
6378
6795
|
.${ROOT_CLASS},
|
|
6379
6796
|
.${ROOT_CLASS} * {
|
|
6380
6797
|
box-sizing: border-box;
|
|
@@ -6454,6 +6871,40 @@ function injectStyles() {
|
|
|
6454
6871
|
border: 1px solid rgba(159, 185, 223, 0.12);
|
|
6455
6872
|
background: linear-gradient(180deg, #071220 0%, #132440 42%, #10344b 42%, #05111d 100%);
|
|
6456
6873
|
}
|
|
6874
|
+
.${CAPTURE_CLASS} .plasius-demo {
|
|
6875
|
+
width: 100vw;
|
|
6876
|
+
height: 100vh;
|
|
6877
|
+
padding: 0;
|
|
6878
|
+
display: block;
|
|
6879
|
+
}
|
|
6880
|
+
.${CAPTURE_CLASS} .plasius-demo__hero,
|
|
6881
|
+
.${CAPTURE_CLASS} .plasius-demo__toolbar,
|
|
6882
|
+
.${CAPTURE_CLASS} .plasius-demo__legend,
|
|
6883
|
+
.${CAPTURE_CLASS} .plasius-demo__sidebar,
|
|
6884
|
+
.${CAPTURE_CLASS} .plasius-demo__footer {
|
|
6885
|
+
display: none;
|
|
6886
|
+
}
|
|
6887
|
+
.${CAPTURE_CLASS} .plasius-demo__layout {
|
|
6888
|
+
display: block;
|
|
6889
|
+
height: 100%;
|
|
6890
|
+
}
|
|
6891
|
+
.${CAPTURE_CLASS} .plasius-demo__canvas-panel {
|
|
6892
|
+
height: 100%;
|
|
6893
|
+
padding: 0;
|
|
6894
|
+
border: 0;
|
|
6895
|
+
border-radius: 0;
|
|
6896
|
+
background: transparent;
|
|
6897
|
+
box-shadow: none;
|
|
6898
|
+
backdrop-filter: none;
|
|
6899
|
+
}
|
|
6900
|
+
.${CAPTURE_CLASS} .plasius-demo__canvas {
|
|
6901
|
+
width: 100%;
|
|
6902
|
+
height: 100%;
|
|
6903
|
+
aspect-ratio: auto;
|
|
6904
|
+
border: 0;
|
|
6905
|
+
border-radius: 0;
|
|
6906
|
+
background: #030710;
|
|
6907
|
+
}
|
|
6457
6908
|
.plasius-demo__toolbar {
|
|
6458
6909
|
position: absolute;
|
|
6459
6910
|
top: 26px;
|
|
@@ -6545,6 +6996,10 @@ function clamp(value, min, max) {
|
|
|
6545
6996
|
function mix(a, b, t) {
|
|
6546
6997
|
return a + (b - a) * t;
|
|
6547
6998
|
}
|
|
6999
|
+
function smoothstep(min, max, value) {
|
|
7000
|
+
const t = clamp((value - min) / Math.max(1e-4, max - min), 0, 1);
|
|
7001
|
+
return t * t * (3 - 2 * t);
|
|
7002
|
+
}
|
|
6548
7003
|
function pseudoRandom(seed) {
|
|
6549
7004
|
const value = Math.sin(seed * 12.9898 + seed * seed * 17e-4) * 43758.5453;
|
|
6550
7005
|
return value - Math.floor(value);
|
|
@@ -6603,6 +7058,11 @@ function transformPoint(point, transform) {
|
|
|
6603
7058
|
const rotated = rotateY(scaled, transform.rotationY);
|
|
6604
7059
|
return addVec3(rotated, transform.position);
|
|
6605
7060
|
}
|
|
7061
|
+
function transformDirection(direction, transform) {
|
|
7062
|
+
const scale = typeof transform.scale === "number" ? { x: transform.scale, y: transform.scale, z: transform.scale } : transform.scale;
|
|
7063
|
+
const scaled = vec3(direction.x * scale.x, direction.y * scale.y, direction.z * scale.z);
|
|
7064
|
+
return normalizeVec3(rotateY(scaled, transform.rotationY));
|
|
7065
|
+
}
|
|
6606
7066
|
function projectPoint(point, camera, viewport) {
|
|
6607
7067
|
const relative = subVec3(point, camera.eye);
|
|
6608
7068
|
const viewX = dotVec3(relative, camera.right);
|
|
@@ -6626,6 +7086,66 @@ function colorToRgba(color, alpha = 1) {
|
|
|
6626
7086
|
const b = Math.round(clamp(color.b, 0, 1) * 255);
|
|
6627
7087
|
return `rgba(${r}, ${g}, ${b}, ${clamp(alpha, 0, 1)})`;
|
|
6628
7088
|
}
|
|
7089
|
+
function mixColor(a, b, t) {
|
|
7090
|
+
return {
|
|
7091
|
+
r: mix(a.r, b.r, t),
|
|
7092
|
+
g: mix(a.g, b.g, t),
|
|
7093
|
+
b: mix(a.b, b.b, t),
|
|
7094
|
+
a: mix(a.a ?? 1, b.a ?? 1, t)
|
|
7095
|
+
};
|
|
7096
|
+
}
|
|
7097
|
+
function multiplyColor(a, b) {
|
|
7098
|
+
return {
|
|
7099
|
+
r: a.r * b.r,
|
|
7100
|
+
g: a.g * b.g,
|
|
7101
|
+
b: a.b * b.b,
|
|
7102
|
+
a: (a.a ?? 1) * (b.a ?? 1)
|
|
7103
|
+
};
|
|
7104
|
+
}
|
|
7105
|
+
function createLegacyMeshPrimitive(mesh) {
|
|
7106
|
+
return Object.freeze({
|
|
7107
|
+
name: mesh.name ?? "legacy-mesh",
|
|
7108
|
+
positions: mesh.positions,
|
|
7109
|
+
indices: mesh.indices,
|
|
7110
|
+
normals: null,
|
|
7111
|
+
colors: null,
|
|
7112
|
+
material: Object.freeze({
|
|
7113
|
+
name: "legacy-material",
|
|
7114
|
+
color: mesh.color ?? { r: 0.56, g: 0.33, b: 0.22, a: 1 },
|
|
7115
|
+
roughness: 0.88,
|
|
7116
|
+
metallic: 0.08,
|
|
7117
|
+
emissive: Object.freeze({ r: 0, g: 0, b: 0 })
|
|
7118
|
+
})
|
|
7119
|
+
});
|
|
7120
|
+
}
|
|
7121
|
+
function isFeatureEnabled(featureFlags, featureName, fallback = true) {
|
|
7122
|
+
const directValue = typeof featureFlags?.[featureName] === "boolean" ? featureFlags[featureName] : featureFlags?.flags?.[featureName];
|
|
7123
|
+
if (typeof directValue === "boolean") {
|
|
7124
|
+
return directValue;
|
|
7125
|
+
}
|
|
7126
|
+
const enabledValue = typeof featureFlags?.enabled?.[featureName] === "boolean" ? featureFlags.enabled[featureName] : void 0;
|
|
7127
|
+
if (typeof enabledValue === "boolean") {
|
|
7128
|
+
return enabledValue;
|
|
7129
|
+
}
|
|
7130
|
+
return fallback;
|
|
7131
|
+
}
|
|
7132
|
+
function getMeshPrimitives(mesh) {
|
|
7133
|
+
return Array.isArray(mesh?.primitives) && mesh.primitives.length > 0 ? mesh.primitives : [createLegacyMeshPrimitive(mesh)];
|
|
7134
|
+
}
|
|
7135
|
+
function tintPrimitiveColor(material, colorOverride) {
|
|
7136
|
+
if (!colorOverride) {
|
|
7137
|
+
return material.color;
|
|
7138
|
+
}
|
|
7139
|
+
const name = String(material.name ?? "").toLowerCase();
|
|
7140
|
+
if (name.includes("sail") || name.includes("glass") || name.includes("roof")) {
|
|
7141
|
+
return material.color;
|
|
7142
|
+
}
|
|
7143
|
+
const tintAmount = name.includes("hull") ? 0.54 : name.includes("trim") ? 0.22 : name.includes("deck") ? 0.12 : 0;
|
|
7144
|
+
if (tintAmount <= 0) {
|
|
7145
|
+
return material.color;
|
|
7146
|
+
}
|
|
7147
|
+
return mixColor(material.color, multiplyColor(material.color, colorOverride), tintAmount);
|
|
7148
|
+
}
|
|
6629
7149
|
function projectShadowPoint(point, lightDir, planeY) {
|
|
6630
7150
|
const shadowDir = scaleVec3(lightDir, -1);
|
|
6631
7151
|
if (Math.abs(shadowDir.y) < 1e-4) {
|
|
@@ -6646,6 +7166,50 @@ function shadeColor(base, normal, lightDir, heightBias = 0, accent = 0) {
|
|
|
6646
7166
|
b: clamp(base.b * (brightness + 0.03), 0, 1)
|
|
6647
7167
|
};
|
|
6648
7168
|
}
|
|
7169
|
+
function getMaterialSeed(materialName) {
|
|
7170
|
+
let seed = 0;
|
|
7171
|
+
for (let index = 0; index < materialName.length; index += 1) {
|
|
7172
|
+
seed += materialName.charCodeAt(index) * (index + 1);
|
|
7173
|
+
}
|
|
7174
|
+
return seed;
|
|
7175
|
+
}
|
|
7176
|
+
function getMaterialDetailStrength(material, surfaceType) {
|
|
7177
|
+
const name = String(material?.name ?? "").toLowerCase();
|
|
7178
|
+
if (surfaceType === "water" || name.includes("glass")) {
|
|
7179
|
+
return 0.018;
|
|
7180
|
+
}
|
|
7181
|
+
if (name.includes("wood") || name.includes("timber") || name.includes("plank")) {
|
|
7182
|
+
return 0.13;
|
|
7183
|
+
}
|
|
7184
|
+
if (name.includes("stone") || name.includes("concrete") || name.includes("plaster")) {
|
|
7185
|
+
return 0.1;
|
|
7186
|
+
}
|
|
7187
|
+
if (name.includes("roof") || name.includes("crate")) {
|
|
7188
|
+
return 0.09;
|
|
7189
|
+
}
|
|
7190
|
+
if (name.includes("paint")) {
|
|
7191
|
+
return 0.045;
|
|
7192
|
+
}
|
|
7193
|
+
if (name.includes("metal")) {
|
|
7194
|
+
return 0.035;
|
|
7195
|
+
}
|
|
7196
|
+
return 0.04;
|
|
7197
|
+
}
|
|
7198
|
+
function applyMaterialDetail(color, material, worldCenter, normal, surfaceType) {
|
|
7199
|
+
const materialName = String(material?.name ?? surfaceType ?? "material");
|
|
7200
|
+
const detailStrength = getMaterialDetailStrength(material, surfaceType);
|
|
7201
|
+
const sample = worldCenter.x * 3.17 + worldCenter.y * 5.29 + worldCenter.z * 7.83 + getMaterialSeed(materialName) * 0.013;
|
|
7202
|
+
const grain = (pseudoRandom(sample) - 0.5) * detailStrength;
|
|
7203
|
+
const lowerSurface = smoothstep(7.5, -0.8, worldCenter.y);
|
|
7204
|
+
const verticalSurface = 1 - clamp(Math.abs(normal.y), 0, 1);
|
|
7205
|
+
const materialLowerWear = /stone|concrete|plaster|paint|wood|timber|plank|crate/.test(materialName.toLowerCase()) ? lowerSurface * verticalSurface * 0.055 : 0;
|
|
7206
|
+
const wetlineWear = surfaceType === "ship" && worldCenter.y < 0.72 ? smoothstep(0.72, -0.1, worldCenter.y) * 0.05 : 0;
|
|
7207
|
+
return {
|
|
7208
|
+
r: clamp(color.r * (1 + grain) - materialLowerWear - wetlineWear, 0, 1),
|
|
7209
|
+
g: clamp(color.g * (1 + grain * 0.82) - materialLowerWear * 0.9 - wetlineWear, 0, 1),
|
|
7210
|
+
b: clamp(color.b * (1 + grain * 0.62) - materialLowerWear * 0.68 - wetlineWear * 0.75, 0, 1)
|
|
7211
|
+
};
|
|
7212
|
+
}
|
|
6649
7213
|
function buildCamera(state, canvas) {
|
|
6650
7214
|
const preset = CAMERA_PRESETS[state.focus] ?? CAMERA_PRESETS.integrated;
|
|
6651
7215
|
const yaw = state.camera.yaw ?? preset.yaw;
|
|
@@ -6670,44 +7234,131 @@ function buildCamera(state, canvas) {
|
|
|
6670
7234
|
aspect: canvas.width / canvas.height
|
|
6671
7235
|
};
|
|
6672
7236
|
}
|
|
6673
|
-
function buildTrianglesFromMesh(mesh, transform,
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
const
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
7237
|
+
function buildTrianglesFromMesh(mesh, transform, colorOverride, camera, viewport, triangles, options = {}) {
|
|
7238
|
+
const primitives = getMeshPrimitives(mesh);
|
|
7239
|
+
for (const primitive of primitives) {
|
|
7240
|
+
const resolvedColor = tintPrimitiveColor(primitive.material, colorOverride);
|
|
7241
|
+
for (let index = 0; index < primitive.indices.length; index += 3) {
|
|
7242
|
+
const aIndex = primitive.indices[index] * 3;
|
|
7243
|
+
const bIndex = primitive.indices[index + 1] * 3;
|
|
7244
|
+
const cIndex = primitive.indices[index + 2] * 3;
|
|
7245
|
+
const a = transformPoint(
|
|
7246
|
+
vec3(
|
|
7247
|
+
primitive.positions[aIndex],
|
|
7248
|
+
primitive.positions[aIndex + 1],
|
|
7249
|
+
primitive.positions[aIndex + 2]
|
|
7250
|
+
),
|
|
7251
|
+
transform
|
|
7252
|
+
);
|
|
7253
|
+
const b = transformPoint(
|
|
7254
|
+
vec3(
|
|
7255
|
+
primitive.positions[bIndex],
|
|
7256
|
+
primitive.positions[bIndex + 1],
|
|
7257
|
+
primitive.positions[bIndex + 2]
|
|
7258
|
+
),
|
|
7259
|
+
transform
|
|
7260
|
+
);
|
|
7261
|
+
const c = transformPoint(
|
|
7262
|
+
vec3(
|
|
7263
|
+
primitive.positions[cIndex],
|
|
7264
|
+
primitive.positions[cIndex + 1],
|
|
7265
|
+
primitive.positions[cIndex + 2]
|
|
7266
|
+
),
|
|
7267
|
+
transform
|
|
7268
|
+
);
|
|
7269
|
+
const ab = subVec3(b, a);
|
|
7270
|
+
const ac = subVec3(c, a);
|
|
7271
|
+
const faceNormal = normalizeVec3(crossVec3(ab, ac));
|
|
7272
|
+
let normal = faceNormal;
|
|
7273
|
+
if (Array.isArray(primitive.normals)) {
|
|
7274
|
+
const aNormal = transformDirection(
|
|
7275
|
+
vec3(
|
|
7276
|
+
primitive.normals[aIndex],
|
|
7277
|
+
primitive.normals[aIndex + 1],
|
|
7278
|
+
primitive.normals[aIndex + 2]
|
|
7279
|
+
),
|
|
7280
|
+
transform
|
|
7281
|
+
);
|
|
7282
|
+
const bNormal = transformDirection(
|
|
7283
|
+
vec3(
|
|
7284
|
+
primitive.normals[bIndex],
|
|
7285
|
+
primitive.normals[bIndex + 1],
|
|
7286
|
+
primitive.normals[bIndex + 2]
|
|
7287
|
+
),
|
|
7288
|
+
transform
|
|
7289
|
+
);
|
|
7290
|
+
const cNormal = transformDirection(
|
|
7291
|
+
vec3(
|
|
7292
|
+
primitive.normals[cIndex],
|
|
7293
|
+
primitive.normals[cIndex + 1],
|
|
7294
|
+
primitive.normals[cIndex + 2]
|
|
7295
|
+
),
|
|
7296
|
+
transform
|
|
7297
|
+
);
|
|
7298
|
+
normal = normalizeVec3(
|
|
7299
|
+
scaleVec3(addVec3(addVec3(aNormal, bNormal), cNormal), 1 / 3)
|
|
7300
|
+
);
|
|
7301
|
+
}
|
|
7302
|
+
const viewDir = normalizeVec3(subVec3(camera.eye, a));
|
|
7303
|
+
if (dotVec3(faceNormal, viewDir) <= 0) {
|
|
7304
|
+
continue;
|
|
7305
|
+
}
|
|
7306
|
+
const projected = [
|
|
7307
|
+
projectPoint(a, camera, viewport),
|
|
7308
|
+
projectPoint(b, camera, viewport),
|
|
7309
|
+
projectPoint(c, camera, viewport)
|
|
7310
|
+
];
|
|
7311
|
+
if (projected.some((value) => value === null)) {
|
|
7312
|
+
continue;
|
|
7313
|
+
}
|
|
7314
|
+
triangles.push({
|
|
7315
|
+
points: projected,
|
|
7316
|
+
depth: (projected[0].depth + projected[1].depth + projected[2].depth) / 3,
|
|
7317
|
+
worldCenter: scaleVec3(addVec3(addVec3(a, b), c), 1 / 3),
|
|
7318
|
+
normal,
|
|
7319
|
+
baseColor: resolvedColor,
|
|
7320
|
+
accent: options.accent ?? 0,
|
|
7321
|
+
material: primitive.material,
|
|
7322
|
+
reflection: options.reflection ?? 0,
|
|
7323
|
+
surfaceType: options.surfaceType ?? "solid"
|
|
7324
|
+
});
|
|
6700
7325
|
}
|
|
6701
|
-
triangles.push({
|
|
6702
|
-
points: projected,
|
|
6703
|
-
depth: (projected[0].depth + projected[1].depth + projected[2].depth) / 3,
|
|
6704
|
-
worldCenter: scaleVec3(addVec3(addVec3(a, b), c), 1 / 3),
|
|
6705
|
-
normal,
|
|
6706
|
-
baseColor,
|
|
6707
|
-
accent
|
|
6708
|
-
});
|
|
6709
7326
|
}
|
|
6710
7327
|
}
|
|
7328
|
+
async function loadShowcaseAssetCatalog() {
|
|
7329
|
+
const [brigantine, cutter, lighthouse, harborDock] = await Promise.all([
|
|
7330
|
+
loadGltfModel(resolveShowcaseAssetUrl("brigantine")),
|
|
7331
|
+
loadGltfModel(resolveShowcaseAssetUrl("cutter")),
|
|
7332
|
+
loadGltfModel(resolveShowcaseAssetUrl("lighthouse")),
|
|
7333
|
+
loadGltfModel(resolveShowcaseAssetUrl("harbor-dock"))
|
|
7334
|
+
]);
|
|
7335
|
+
return Object.freeze({
|
|
7336
|
+
primaryShipKey: "brigantine",
|
|
7337
|
+
ships: Object.freeze({
|
|
7338
|
+
brigantine,
|
|
7339
|
+
cutter
|
|
7340
|
+
}),
|
|
7341
|
+
environment: Object.freeze({
|
|
7342
|
+
lighthouse,
|
|
7343
|
+
"harbor-dock": harborDock
|
|
7344
|
+
})
|
|
7345
|
+
});
|
|
7346
|
+
}
|
|
7347
|
+
function createLegacyShowcaseAssetCatalog() {
|
|
7348
|
+
const brigantine = loadGltfModel(resolveShowcaseAssetUrl("brigantine"));
|
|
7349
|
+
return Promise.resolve(brigantine).then(
|
|
7350
|
+
(primary) => Object.freeze({
|
|
7351
|
+
primaryShipKey: "brigantine",
|
|
7352
|
+
ships: Object.freeze({
|
|
7353
|
+
brigantine: primary
|
|
7354
|
+
}),
|
|
7355
|
+
environment: Object.freeze({})
|
|
7356
|
+
})
|
|
7357
|
+
);
|
|
7358
|
+
}
|
|
7359
|
+
function resolveShipModel(state, ship, fallbackModel = null) {
|
|
7360
|
+
return state.assetCatalog?.ships?.[ship.modelKey ?? state.assetCatalog?.primaryShipKey ?? "brigantine"] ?? fallbackModel ?? state.shipModel;
|
|
7361
|
+
}
|
|
6711
7362
|
function createPerformanceGovernor() {
|
|
6712
7363
|
const fluidDetail = createQualityLadderAdapter({
|
|
6713
7364
|
id: "fluid-detail",
|
|
@@ -6759,6 +7410,7 @@ function createPerformanceGovernor() {
|
|
|
6759
7410
|
return { governor, fluidDetail, clothDetail, lightingDetail };
|
|
6760
7411
|
}
|
|
6761
7412
|
function buildDemoDom(root, options) {
|
|
7413
|
+
const t = options.translate;
|
|
6762
7414
|
root.innerHTML = `
|
|
6763
7415
|
<main class="plasius-demo">
|
|
6764
7416
|
<section class="plasius-demo__hero">
|
|
@@ -6768,56 +7420,52 @@ function buildDemoDom(root, options) {
|
|
|
6768
7420
|
<p class="plasius-demo__lead">${options.subtitle}</p>
|
|
6769
7421
|
</section>
|
|
6770
7422
|
<section class="plasius-panel plasius-demo__status">
|
|
6771
|
-
<p id="demoStatus" class="plasius-demo__status-badge"
|
|
7423
|
+
<p id="demoStatus" class="plasius-demo__status-badge">${t(gpuSharedTranslationKeys.statusBooting)}</p>
|
|
6772
7424
|
<p id="demoDetails" class="plasius-demo__status-text">
|
|
6773
|
-
|
|
7425
|
+
${t(gpuSharedTranslationKeys.detailsBooting)}
|
|
6774
7426
|
</p>
|
|
6775
7427
|
</section>
|
|
6776
7428
|
</section>
|
|
6777
7429
|
<section class="plasius-demo__layout">
|
|
6778
7430
|
<section class="plasius-panel plasius-demo__canvas-panel">
|
|
6779
|
-
<canvas id="demoCanvas" class="plasius-demo__canvas" width="
|
|
7431
|
+
<canvas id="demoCanvas" class="plasius-demo__canvas" width="${DEFAULT_CANVAS_WIDTH}" height="${DEFAULT_CANVAS_HEIGHT}"></canvas>
|
|
6780
7432
|
<div class="plasius-demo__toolbar">
|
|
6781
|
-
<button id="pauseButton" type="button"
|
|
7433
|
+
<button id="pauseButton" type="button">${t(gpuSharedTranslationKeys.pause)}</button>
|
|
6782
7434
|
<label class="plasius-toggle">
|
|
6783
7435
|
<input id="stressToggle" type="checkbox" />
|
|
6784
|
-
|
|
7436
|
+
${t(gpuSharedTranslationKeys.stressMode)}
|
|
6785
7437
|
</label>
|
|
6786
7438
|
<label class="plasius-toggle">
|
|
6787
|
-
|
|
7439
|
+
${t(gpuSharedTranslationKeys.focus)}
|
|
6788
7440
|
<select id="focusMode">
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
<option value="fluid">fluid</option>
|
|
6793
|
-
<option value="physics">physics</option>
|
|
6794
|
-
<option value="performance">performance</option>
|
|
6795
|
-
<option value="debug">debug</option>
|
|
7441
|
+
${showcaseFocusModes.map(
|
|
7442
|
+
(mode) => `<option value="${mode}">${t(FOCUS_MODE_TRANSLATION_KEYS[mode])}</option>`
|
|
7443
|
+
).join("")}
|
|
6796
7444
|
</select>
|
|
6797
7445
|
</label>
|
|
6798
7446
|
</div>
|
|
6799
7447
|
<div class="plasius-demo__legend">
|
|
6800
|
-
<strong
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
7448
|
+
<strong>${t(gpuSharedTranslationKeys.legendTitle)}</strong>
|
|
7449
|
+
${t(gpuSharedTranslationKeys.legendShipMetadata)}<br />
|
|
7450
|
+
${t(gpuSharedTranslationKeys.legendLighting)}<br />
|
|
7451
|
+
${t(gpuSharedTranslationKeys.legendCollisions)}
|
|
6804
7452
|
</div>
|
|
6805
7453
|
</section>
|
|
6806
7454
|
<aside class="plasius-demo__sidebar">
|
|
6807
7455
|
<section class="plasius-panel plasius-demo__card">
|
|
6808
|
-
<h2
|
|
7456
|
+
<h2>${t(gpuSharedTranslationKeys.sceneState)}</h2>
|
|
6809
7457
|
<ul id="sceneMetrics" class="plasius-demo__metrics"></ul>
|
|
6810
7458
|
</section>
|
|
6811
7459
|
<section class="plasius-panel plasius-demo__card">
|
|
6812
|
-
<h2
|
|
7460
|
+
<h2>${t(gpuSharedTranslationKeys.qualityBudgets)}</h2>
|
|
6813
7461
|
<ul id="qualityMetrics" class="plasius-demo__metrics"></ul>
|
|
6814
7462
|
</section>
|
|
6815
7463
|
<section class="plasius-panel plasius-demo__card">
|
|
6816
|
-
<h2
|
|
7464
|
+
<h2>${t(gpuSharedTranslationKeys.debugTelemetry)}</h2>
|
|
6817
7465
|
<ul id="debugMetrics" class="plasius-demo__metrics"></ul>
|
|
6818
7466
|
</section>
|
|
6819
7467
|
<section class="plasius-panel plasius-demo__card">
|
|
6820
|
-
<h2
|
|
7468
|
+
<h2>${t(gpuSharedTranslationKeys.notes)}</h2>
|
|
6821
7469
|
<ul id="sceneNotes" class="plasius-demo__metrics"></ul>
|
|
6822
7470
|
</section>
|
|
6823
7471
|
</aside>
|
|
@@ -6841,6 +7489,11 @@ function buildDemoDom(root, options) {
|
|
|
6841
7489
|
};
|
|
6842
7490
|
}
|
|
6843
7491
|
function buildSceneSnapshot(state, shipModel) {
|
|
7492
|
+
const shipPhysics = Object.freeze(
|
|
7493
|
+
Object.fromEntries(
|
|
7494
|
+
state.ships.map((ship) => [ship.id, resolveShipModel(state, ship, shipModel)?.physics ?? null])
|
|
7495
|
+
)
|
|
7496
|
+
);
|
|
6844
7497
|
return Object.freeze({
|
|
6845
7498
|
focus: state.focus,
|
|
6846
7499
|
frame: state.frame,
|
|
@@ -6862,6 +7515,7 @@ function buildSceneSnapshot(state, shipModel) {
|
|
|
6862
7515
|
state.ships.map(
|
|
6863
7516
|
(ship) => Object.freeze({
|
|
6864
7517
|
id: ship.id,
|
|
7518
|
+
modelKey: ship.modelKey ?? "brigantine",
|
|
6865
7519
|
position: Object.freeze({ ...ship.position }),
|
|
6866
7520
|
velocity: Object.freeze({ ...ship.velocity }),
|
|
6867
7521
|
rotationY: ship.rotationY,
|
|
@@ -6882,12 +7536,13 @@ function buildSceneSnapshot(state, shipModel) {
|
|
|
6882
7536
|
)
|
|
6883
7537
|
),
|
|
6884
7538
|
shipPhysics: shipModel?.physics ?? null,
|
|
7539
|
+
shipModels: shipPhysics,
|
|
6885
7540
|
physics: Object.freeze({
|
|
6886
7541
|
profile: state.physics.profile,
|
|
6887
7542
|
plan: state.physics.plan,
|
|
6888
7543
|
manifest: state.physics.manifest,
|
|
6889
7544
|
snapshot: state.physics.snapshot,
|
|
6890
|
-
shipPhysics
|
|
7545
|
+
shipPhysics
|
|
6891
7546
|
})
|
|
6892
7547
|
});
|
|
6893
7548
|
}
|
|
@@ -6922,6 +7577,61 @@ function normalizeColorOverride(color, fallback) {
|
|
|
6922
7577
|
function readVisualNumber(value, fallback) {
|
|
6923
7578
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
6924
7579
|
}
|
|
7580
|
+
function readPositiveNumber3(value, fallback) {
|
|
7581
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
7582
|
+
}
|
|
7583
|
+
function isTruthyCaptureValue(value) {
|
|
7584
|
+
return value === "1" || value === "true" || value === "scene" || value === "video";
|
|
7585
|
+
}
|
|
7586
|
+
function resolveCaptureSettings(options) {
|
|
7587
|
+
const explicitCaptureMode = typeof options.captureMode === "boolean" ? options.captureMode : void 0;
|
|
7588
|
+
let captureMode = explicitCaptureMode ?? false;
|
|
7589
|
+
let renderScale = readPositiveNumber3(options.renderScale, void 0);
|
|
7590
|
+
try {
|
|
7591
|
+
const params = new URLSearchParams(window.location.search);
|
|
7592
|
+
if (explicitCaptureMode === void 0) {
|
|
7593
|
+
captureMode = isTruthyCaptureValue(params.get("capture")) || params.get("presentation") === "capture";
|
|
7594
|
+
}
|
|
7595
|
+
renderScale = readPositiveNumber3(Number(params.get("renderScale")), renderScale);
|
|
7596
|
+
} catch {
|
|
7597
|
+
}
|
|
7598
|
+
return {
|
|
7599
|
+
captureMode,
|
|
7600
|
+
renderScale
|
|
7601
|
+
};
|
|
7602
|
+
}
|
|
7603
|
+
function getCanvasDisplaySize(canvas) {
|
|
7604
|
+
const rect = typeof canvas.getBoundingClientRect === "function" ? canvas.getBoundingClientRect() : null;
|
|
7605
|
+
const width = Math.round(
|
|
7606
|
+
readPositiveNumber3(rect?.width, readPositiveNumber3(canvas.clientWidth, canvas.width))
|
|
7607
|
+
);
|
|
7608
|
+
const height = Math.round(
|
|
7609
|
+
readPositiveNumber3(rect?.height, readPositiveNumber3(canvas.clientHeight, canvas.height))
|
|
7610
|
+
);
|
|
7611
|
+
return {
|
|
7612
|
+
width: Math.max(1, width || DEFAULT_CANVAS_WIDTH),
|
|
7613
|
+
height: Math.max(1, height || DEFAULT_CANVAS_HEIGHT)
|
|
7614
|
+
};
|
|
7615
|
+
}
|
|
7616
|
+
function resizeCanvasToDisplaySize(canvas, state) {
|
|
7617
|
+
const { width, height } = getCanvasDisplaySize(canvas);
|
|
7618
|
+
const deviceScale = readPositiveNumber3(globalThis.devicePixelRatio, 1);
|
|
7619
|
+
const requestedScale = readPositiveNumber3(state.renderScale, deviceScale);
|
|
7620
|
+
const maxScale = state.captureMode ? 2 : 1.5;
|
|
7621
|
+
let scale = clamp(requestedScale, 1, maxScale);
|
|
7622
|
+
const pixelBudget = state.captureMode ? CAPTURE_CANVAS_PIXEL_BUDGET : DEFAULT_CANVAS_WIDTH * DEFAULT_CANVAS_HEIGHT * 1.5;
|
|
7623
|
+
const projectedPixels = width * height * scale * scale;
|
|
7624
|
+
if (projectedPixels > pixelBudget) {
|
|
7625
|
+
scale = Math.sqrt(pixelBudget / Math.max(1, width * height));
|
|
7626
|
+
}
|
|
7627
|
+
const targetWidth = Math.max(1, Math.round(width * scale));
|
|
7628
|
+
const targetHeight = Math.max(1, Math.round(height * scale));
|
|
7629
|
+
if (canvas.width !== targetWidth || canvas.height !== targetHeight) {
|
|
7630
|
+
canvas.width = targetWidth;
|
|
7631
|
+
canvas.height = targetHeight;
|
|
7632
|
+
}
|
|
7633
|
+
state.renderScale = scale;
|
|
7634
|
+
}
|
|
6925
7635
|
function resolveClothPresentation(state, meshDetail) {
|
|
6926
7636
|
const clothPlan = createClothRepresentationPlan({
|
|
6927
7637
|
garmentId: "shore-flag",
|
|
@@ -7451,6 +8161,7 @@ function buildWaterBands(state, fluidDetail, visuals) {
|
|
|
7451
8161
|
return { fluidPlan, bandMeshes };
|
|
7452
8162
|
}
|
|
7453
8163
|
function createSceneState(options) {
|
|
8164
|
+
const translate = options.translate;
|
|
7454
8165
|
const { governor, fluidDetail, clothDetail, lightingDetail } = createPerformanceGovernor();
|
|
7455
8166
|
const physicsProfile = defaultPhysicsWorkerProfile;
|
|
7456
8167
|
const physicsPlan = createPhysicsSimulationPlan(physicsProfile);
|
|
@@ -7458,7 +8169,7 @@ function createSceneState(options) {
|
|
|
7458
8169
|
const debugSession = createGpuDebugSession({
|
|
7459
8170
|
enabled: true,
|
|
7460
8171
|
adapter: {
|
|
7461
|
-
label:
|
|
8172
|
+
label: translate(gpuSharedTranslationKeys.debugAdapterShowcase),
|
|
7462
8173
|
memoryCapacityHintBytes: 6 * 1024 * 1024 * 1024,
|
|
7463
8174
|
coreCountHint: 12
|
|
7464
8175
|
}
|
|
@@ -7468,22 +8179,26 @@ function createSceneState(options) {
|
|
|
7468
8179
|
owner: "renderer",
|
|
7469
8180
|
category: "texture",
|
|
7470
8181
|
sizeBytes: 1280 * 720 * 4,
|
|
7471
|
-
label:
|
|
8182
|
+
label: translate(gpuSharedTranslationKeys.debugMainColorBuffer)
|
|
7472
8183
|
});
|
|
7473
8184
|
debugSession.trackAllocation({
|
|
7474
8185
|
id: "showcase.shadow-impression",
|
|
7475
8186
|
owner: "lighting",
|
|
7476
8187
|
category: "texture",
|
|
7477
8188
|
sizeBytes: 12 * 1024 * 1024,
|
|
7478
|
-
label:
|
|
8189
|
+
label: translate(gpuSharedTranslationKeys.debugShadowImpressionAtlas)
|
|
7479
8190
|
});
|
|
7480
8191
|
return {
|
|
8192
|
+
translate,
|
|
7481
8193
|
focus: options.focus,
|
|
7482
8194
|
governor,
|
|
7483
8195
|
fluidDetail,
|
|
7484
8196
|
clothDetail,
|
|
7485
8197
|
lightingDetail,
|
|
7486
8198
|
debugSession,
|
|
8199
|
+
showcaseRealisticModelsEnabled: options.realisticModelsEnabled !== false,
|
|
8200
|
+
captureMode: options.captureMode === true,
|
|
8201
|
+
renderScale: readPositiveNumber3(options.renderScale, void 0),
|
|
7487
8202
|
packageState: void 0,
|
|
7488
8203
|
demoDescription: null,
|
|
7489
8204
|
demoVisuals: null,
|
|
@@ -7498,6 +8213,7 @@ function createSceneState(options) {
|
|
|
7498
8213
|
ships: [
|
|
7499
8214
|
{
|
|
7500
8215
|
id: "northwind",
|
|
8216
|
+
modelKey: "brigantine",
|
|
7501
8217
|
position: vec3(-5.2, 0, 7.2),
|
|
7502
8218
|
velocity: vec3(2.35, 0, -1.08),
|
|
7503
8219
|
rotationY: 0.58,
|
|
@@ -7508,17 +8224,18 @@ function createSceneState(options) {
|
|
|
7508
8224
|
throttleResponse: 0.46,
|
|
7509
8225
|
rudderResponse: 0.54,
|
|
7510
8226
|
wanderPhase: 0.35,
|
|
7511
|
-
lanterns:
|
|
8227
|
+
lanterns: CUTTER_LANTERNS,
|
|
7512
8228
|
lanternStrength: 1.06,
|
|
7513
8229
|
collisionRadiusScale: 1.04
|
|
7514
8230
|
},
|
|
7515
8231
|
{
|
|
7516
8232
|
id: "tidecaller",
|
|
8233
|
+
modelKey: "cutter",
|
|
7517
8234
|
position: vec3(4.8, 0, 4.4),
|
|
7518
8235
|
velocity: vec3(-2.15, 0, 1.74),
|
|
7519
8236
|
rotationY: -2.48,
|
|
7520
8237
|
angularVelocity: -0.2,
|
|
7521
|
-
tint: { r: 0.
|
|
8238
|
+
tint: { r: 0.58, g: 0.24, b: 0.16 },
|
|
7522
8239
|
massScale: 0.84,
|
|
7523
8240
|
cruiseSpeed: 2.68,
|
|
7524
8241
|
throttleResponse: 0.7,
|
|
@@ -7542,6 +8259,7 @@ function createSceneState(options) {
|
|
|
7542
8259
|
manifest: physicsManifest,
|
|
7543
8260
|
snapshot: null
|
|
7544
8261
|
},
|
|
8262
|
+
assetCatalog: null,
|
|
7545
8263
|
shipModel: null
|
|
7546
8264
|
};
|
|
7547
8265
|
}
|
|
@@ -7617,10 +8335,38 @@ function drawSkyAndShore(ctx, canvas, state, nearLighting, reflectionStrength, s
|
|
|
7617
8335
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
7618
8336
|
}
|
|
7619
8337
|
}
|
|
7620
|
-
function
|
|
8338
|
+
function resolveLocalLightContribution(triangle, lightSources) {
|
|
8339
|
+
const contribution = { r: 0, g: 0, b: 0 };
|
|
8340
|
+
if (!Array.isArray(lightSources) || triangle.surfaceType === "water") {
|
|
8341
|
+
return contribution;
|
|
8342
|
+
}
|
|
8343
|
+
const normal = normalizeVec3(triangle.normal);
|
|
8344
|
+
for (const source of lightSources.slice(0, 8)) {
|
|
8345
|
+
const delta = subVec3(source.point, triangle.worldCenter);
|
|
8346
|
+
const distance = lengthVec3(delta);
|
|
8347
|
+
const attenuation = (source.glowScale ?? 1) / Math.max(1, 0.68 + distance * distance * 0.2);
|
|
8348
|
+
if (attenuation < 0.012) {
|
|
8349
|
+
continue;
|
|
8350
|
+
}
|
|
8351
|
+
const lightDir = normalizeVec3(delta);
|
|
8352
|
+
const facing = clamp(dotVec3(normal, lightDir), 0, 1);
|
|
8353
|
+
const response = attenuation * (0.18 + facing * 0.82);
|
|
8354
|
+
const glowColor = source.glowColor ?? source.coreColor ?? { r: 1, g: 0.72, b: 0.4 };
|
|
8355
|
+
contribution.r += glowColor.r * response * 0.32;
|
|
8356
|
+
contribution.g += glowColor.g * response * 0.26;
|
|
8357
|
+
contribution.b += glowColor.b * response * 0.18;
|
|
8358
|
+
}
|
|
8359
|
+
return contribution;
|
|
8360
|
+
}
|
|
8361
|
+
function drawTriangles(ctx, triangles, lightDir, reflectionStrength, camera, shadowStrength, localLights = []) {
|
|
7621
8362
|
triangles.sort((left, right) => right.depth - left.depth);
|
|
7622
8363
|
for (const triangle of triangles) {
|
|
7623
8364
|
const surfaceNormal = normalizeVec3(triangle.normal);
|
|
8365
|
+
const material = triangle.material ?? {
|
|
8366
|
+
roughness: 0.88,
|
|
8367
|
+
metallic: 0.08,
|
|
8368
|
+
emissive: { r: 0, g: 0, b: 0 }
|
|
8369
|
+
};
|
|
7624
8370
|
const shaded = shadeColor(
|
|
7625
8371
|
triangle.baseColor,
|
|
7626
8372
|
surfaceNormal,
|
|
@@ -7628,19 +8374,41 @@ function drawTriangles(ctx, triangles, lightDir, reflectionStrength, camera, sha
|
|
|
7628
8374
|
clamp((triangle.worldCenter.y + 3) / 10, 0, 1),
|
|
7629
8375
|
triangle.accent
|
|
7630
8376
|
);
|
|
7631
|
-
const reflection =
|
|
8377
|
+
const reflection = reflectionStrength * (triangle.reflection ?? 0);
|
|
7632
8378
|
const viewDir = normalizeVec3(subVec3(camera.eye, triangle.worldCenter));
|
|
7633
8379
|
const reflectedLight = reflectVec3(scaleVec3(lightDir, -1), surfaceNormal);
|
|
7634
|
-
const gloss =
|
|
7635
|
-
const
|
|
7636
|
-
const
|
|
7637
|
-
const
|
|
8380
|
+
const gloss = mix(0.78, 0.14, clamp(material.roughness ?? 0.88, 0, 1)) + (material.metallic ?? 0) * 0.18;
|
|
8381
|
+
const specularPower = mix(26, 7, clamp(material.roughness ?? 0.88, 0, 1));
|
|
8382
|
+
const specular = Math.pow(clamp(dotVec3(reflectedLight, viewDir), 0, 1), specularPower) * gloss;
|
|
8383
|
+
const emissive = material.emissive ?? { r: 0, g: 0, b: 0 };
|
|
8384
|
+
const localLight = resolveLocalLightContribution(triangle, localLights);
|
|
8385
|
+
const occlusion = triangle.surfaceType === "water" ? shadowStrength * 0.018 : shadowStrength * 0.04;
|
|
8386
|
+
const detailed = applyMaterialDetail(
|
|
7638
8387
|
{
|
|
7639
|
-
r: clamp(
|
|
7640
|
-
|
|
7641
|
-
|
|
8388
|
+
r: clamp(
|
|
8389
|
+
shaded.r + reflection * 0.08 + specular * 0.16 + emissive.r * 0.42 + localLight.r - occlusion,
|
|
8390
|
+
0,
|
|
8391
|
+
1
|
|
8392
|
+
),
|
|
8393
|
+
g: clamp(
|
|
8394
|
+
shaded.g + reflection * 0.08 + specular * 0.16 + emissive.g * 0.42 + localLight.g - occlusion,
|
|
8395
|
+
0,
|
|
8396
|
+
1
|
|
8397
|
+
),
|
|
8398
|
+
b: clamp(
|
|
8399
|
+
shaded.b + reflection * 0.16 + specular * 0.22 + emissive.b * 0.46 + localLight.b - occlusion * 0.5,
|
|
8400
|
+
0,
|
|
8401
|
+
1
|
|
8402
|
+
)
|
|
7642
8403
|
},
|
|
7643
|
-
|
|
8404
|
+
material,
|
|
8405
|
+
triangle.worldCenter,
|
|
8406
|
+
surfaceNormal,
|
|
8407
|
+
triangle.surfaceType
|
|
8408
|
+
);
|
|
8409
|
+
const fill = colorToRgba(
|
|
8410
|
+
detailed,
|
|
8411
|
+
triangle.baseColor.a ?? 0.98
|
|
7644
8412
|
);
|
|
7645
8413
|
ctx.fillStyle = fill;
|
|
7646
8414
|
ctx.beginPath();
|
|
@@ -7671,74 +8439,100 @@ function renderProjectedShadow(ctx, worldPoints, camera, viewport, lightDir, opt
|
|
|
7671
8439
|
ctx.fill();
|
|
7672
8440
|
ctx.restore();
|
|
7673
8441
|
}
|
|
7674
|
-
function pushHarborGeometry(camera, viewport, triangles,
|
|
7675
|
-
|
|
7676
|
-
{
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
8442
|
+
function pushHarborGeometry(camera, viewport, triangles, state) {
|
|
8443
|
+
if (!state.showcaseRealisticModelsEnabled) {
|
|
8444
|
+
for (const object of LEGACY_HARBOR_LAYOUT) {
|
|
8445
|
+
buildTrianglesFromMesh(
|
|
8446
|
+
{ positions: [object], indices: [0], normals: null, colors: null, material: createLegacyMeshPrimitive({})?.material, bounds: null, name: "legacy-structure" },
|
|
8447
|
+
{
|
|
8448
|
+
position: object.position,
|
|
8449
|
+
rotationY: object.rotationY,
|
|
8450
|
+
scale: object.scale
|
|
8451
|
+
},
|
|
8452
|
+
object.color,
|
|
8453
|
+
camera,
|
|
8454
|
+
viewport,
|
|
8455
|
+
triangles,
|
|
8456
|
+
{
|
|
8457
|
+
accent: object.accent,
|
|
8458
|
+
reflection: 0,
|
|
8459
|
+
surfaceType: "structure"
|
|
8460
|
+
}
|
|
8461
|
+
);
|
|
8462
|
+
}
|
|
8463
|
+
return;
|
|
8464
|
+
}
|
|
8465
|
+
for (const placement of SHOWCASE_ENVIRONMENT_LAYOUT) {
|
|
8466
|
+
const mesh = state.assetCatalog?.environment?.[placement.assetKey] ?? null;
|
|
8467
|
+
if (!mesh) {
|
|
8468
|
+
continue;
|
|
7696
8469
|
}
|
|
7697
|
-
];
|
|
7698
|
-
for (const object of harborObjects) {
|
|
7699
8470
|
buildTrianglesFromMesh(
|
|
7700
|
-
|
|
8471
|
+
mesh,
|
|
7701
8472
|
{
|
|
7702
|
-
position:
|
|
7703
|
-
rotationY:
|
|
7704
|
-
scale:
|
|
8473
|
+
position: vec3(placement.position.x, placement.position.y, placement.position.z),
|
|
8474
|
+
rotationY: placement.rotationY,
|
|
8475
|
+
scale: placement.scale
|
|
7705
8476
|
},
|
|
7706
|
-
|
|
8477
|
+
null,
|
|
7707
8478
|
camera,
|
|
7708
8479
|
viewport,
|
|
7709
8480
|
triangles,
|
|
7710
|
-
|
|
8481
|
+
{
|
|
8482
|
+
accent: placement.accent,
|
|
8483
|
+
reflection: 0,
|
|
8484
|
+
surfaceType: "structure"
|
|
8485
|
+
}
|
|
7711
8486
|
);
|
|
7712
8487
|
}
|
|
7713
8488
|
}
|
|
7714
8489
|
function renderShipRigging(ctx, ship, camera, viewport) {
|
|
7715
8490
|
const transform = { position: ship.position, rotationY: ship.rotationY, scale: SHIP_SCALE };
|
|
7716
|
-
const
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
8491
|
+
const layout = ship.modelKey === "cutter" ? {
|
|
8492
|
+
lineColor: "rgba(85, 89, 97, 0.92)",
|
|
8493
|
+
sailColor: "rgba(218, 232, 244, 0.28)",
|
|
8494
|
+
points: [
|
|
8495
|
+
vec3(0, 0.88, -0.32),
|
|
8496
|
+
vec3(0, 2.4, -0.28),
|
|
8497
|
+
vec3(0.1, 1.92, -0.3),
|
|
8498
|
+
vec3(1.18, 1.72, -0.18),
|
|
8499
|
+
vec3(1.04, 1.08, -0.12)
|
|
8500
|
+
],
|
|
8501
|
+
mastPairs: [[0, 1], [2, 3]],
|
|
8502
|
+
sailTriangle: [2, 3, 4]
|
|
8503
|
+
} : {
|
|
8504
|
+
lineColor: "rgba(73, 54, 45, 0.94)",
|
|
8505
|
+
sailColor: "rgba(238, 232, 214, 0.88)",
|
|
8506
|
+
points: [
|
|
8507
|
+
vec3(0, 0.38, -0.4),
|
|
8508
|
+
vec3(0, 3.8, -0.2),
|
|
8509
|
+
vec3(-0.25, 0.32, -1.9),
|
|
8510
|
+
vec3(-0.15, 2.7, -1.75),
|
|
8511
|
+
vec3(0.08, 3.2, -0.2),
|
|
8512
|
+
vec3(0.12, 1.2, -0.5),
|
|
8513
|
+
vec3(2.25, 2.25, 0.15)
|
|
8514
|
+
],
|
|
8515
|
+
mastPairs: [[0, 1], [2, 3]],
|
|
8516
|
+
sailTriangle: [4, 5, 6]
|
|
8517
|
+
};
|
|
8518
|
+
const projected = layout.points.map((point) => transformPoint(point, transform)).map((point) => projectPoint(point, camera, viewport));
|
|
7726
8519
|
if (projected.some((value) => value === null)) {
|
|
7727
8520
|
return;
|
|
7728
8521
|
}
|
|
7729
|
-
ctx.strokeStyle =
|
|
7730
|
-
ctx.lineWidth = 3.5;
|
|
8522
|
+
ctx.strokeStyle = layout.lineColor;
|
|
8523
|
+
ctx.lineWidth = ship.modelKey === "cutter" ? 2.2 : 3.5;
|
|
7731
8524
|
ctx.beginPath();
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
8525
|
+
for (const [from, to] of layout.mastPairs) {
|
|
8526
|
+
ctx.moveTo(projected[from].x, projected[from].y);
|
|
8527
|
+
ctx.lineTo(projected[to].x, projected[to].y);
|
|
8528
|
+
}
|
|
7736
8529
|
ctx.stroke();
|
|
7737
|
-
|
|
8530
|
+
const [a, b, c] = layout.sailTriangle;
|
|
8531
|
+
ctx.fillStyle = layout.sailColor;
|
|
7738
8532
|
ctx.beginPath();
|
|
7739
|
-
ctx.moveTo(projected[
|
|
7740
|
-
ctx.lineTo(projected[
|
|
7741
|
-
ctx.lineTo(projected[
|
|
8533
|
+
ctx.moveTo(projected[a].x, projected[a].y);
|
|
8534
|
+
ctx.lineTo(projected[b].x, projected[b].y);
|
|
8535
|
+
ctx.lineTo(projected[c].x, projected[c].y);
|
|
7742
8536
|
ctx.closePath();
|
|
7743
8537
|
ctx.fill();
|
|
7744
8538
|
}
|
|
@@ -7956,10 +8750,10 @@ function resolveBoundaryCollision(ship, state, shipModel) {
|
|
|
7956
8750
|
}
|
|
7957
8751
|
}
|
|
7958
8752
|
}
|
|
7959
|
-
function resolveShipCollision(state, a, b,
|
|
8753
|
+
function resolveShipCollision(state, a, b, shipModelA, shipModelB) {
|
|
7960
8754
|
const delta = subVec3(b.position, a.position);
|
|
7961
|
-
const radiusA = getShipCollisionRadius(a,
|
|
7962
|
-
const radiusB = getShipCollisionRadius(b,
|
|
8755
|
+
const radiusA = getShipCollisionRadius(a, shipModelA);
|
|
8756
|
+
const radiusB = getShipCollisionRadius(b, shipModelB);
|
|
7963
8757
|
const distance = Math.hypot(delta.x, delta.z);
|
|
7964
8758
|
const minDistance = radiusA + radiusB;
|
|
7965
8759
|
if (distance >= minDistance) {
|
|
@@ -7968,15 +8762,15 @@ function resolveShipCollision(state, a, b, shipModel) {
|
|
|
7968
8762
|
const normal = distance > 1e-4 ? normalizeVec3(vec3(delta.x / distance, 0, delta.z / distance)) : normalizeVec3(vec3(Math.cos(state.time * 5.2), 0, Math.sin(state.time * 4.8)));
|
|
7969
8763
|
const tangent = vec3(-normal.z, 0, normal.x);
|
|
7970
8764
|
const penetration = minDistance - distance;
|
|
7971
|
-
const invMassA = getShipInverseMass(a,
|
|
7972
|
-
const invMassB = getShipInverseMass(b,
|
|
8765
|
+
const invMassA = getShipInverseMass(a, shipModelA);
|
|
8766
|
+
const invMassB = getShipInverseMass(b, shipModelB);
|
|
7973
8767
|
const invMassSum = invMassA + invMassB;
|
|
7974
8768
|
const correction = scaleVec3(normal, penetration / Math.max(1e-4, invMassSum) * 0.72);
|
|
7975
8769
|
a.position = subVec3(a.position, scaleVec3(correction, invMassA));
|
|
7976
8770
|
b.position = addVec3(b.position, scaleVec3(correction, invMassB));
|
|
7977
8771
|
const relativeVelocity = subVec3(b.velocity, a.velocity);
|
|
7978
8772
|
const velocityAlongNormal = dotVec3(relativeVelocity, normal);
|
|
7979
|
-
const restitution = readPhysicsNumber(
|
|
8773
|
+
const restitution = (readPhysicsNumber(shipModelA.physics, "restitution", 0.22) + readPhysicsNumber(shipModelB.physics, "restitution", 0.22)) / 2 * 0.88;
|
|
7980
8774
|
if (velocityAlongNormal < 0) {
|
|
7981
8775
|
const impulseMagnitude = -(1 + restitution) * velocityAlongNormal / Math.max(1e-4, invMassSum);
|
|
7982
8776
|
const impulse = scaleVec3(normal, impulseMagnitude);
|
|
@@ -7991,8 +8785,8 @@ function resolveShipCollision(state, a, b, shipModel) {
|
|
|
7991
8785
|
const frictionImpulse = scaleVec3(tangent, frictionMagnitude);
|
|
7992
8786
|
a.velocity = subVec3(a.velocity, scaleVec3(frictionImpulse, invMassA));
|
|
7993
8787
|
b.velocity = addVec3(b.velocity, scaleVec3(frictionImpulse, invMassB));
|
|
7994
|
-
a.angularVelocity -= tangentSpeed * radiusA * getShipInverseInertia(a,
|
|
7995
|
-
b.angularVelocity += tangentSpeed * radiusB * getShipInverseInertia(b,
|
|
8788
|
+
a.angularVelocity -= tangentSpeed * radiusA * getShipInverseInertia(a, shipModelA) * 0.2 + impulseMagnitude * 24e-5;
|
|
8789
|
+
b.angularVelocity += tangentSpeed * radiusB * getShipInverseInertia(b, shipModelB) * 0.2 + impulseMagnitude * 24e-5;
|
|
7996
8790
|
const impactSpeed = Math.abs(velocityAlongNormal);
|
|
7997
8791
|
if (impactSpeed > 0.18 && Math.max(readVisualNumber(a.collisionCooldown, 0), readVisualNumber(b.collisionCooldown, 0)) <= 0) {
|
|
7998
8792
|
const contactPoint = vec3(
|
|
@@ -8024,12 +8818,17 @@ function updateShips(state, dt, shipModel) {
|
|
|
8024
8818
|
let collided = false;
|
|
8025
8819
|
state.contactCount = 0;
|
|
8026
8820
|
for (const ship of state.ships) {
|
|
8027
|
-
|
|
8028
|
-
|
|
8821
|
+
const activeShipModel = resolveShipModel(state, ship, shipModel);
|
|
8822
|
+
updateShipMotion(state, ship, dt, activeShipModel);
|
|
8823
|
+
resolveBoundaryCollision(ship, state, activeShipModel);
|
|
8029
8824
|
}
|
|
8030
8825
|
for (let index = 0; index < state.ships.length; index += 1) {
|
|
8031
8826
|
for (let otherIndex = index + 1; otherIndex < state.ships.length; otherIndex += 1) {
|
|
8032
|
-
|
|
8827
|
+
const shipA = state.ships[index];
|
|
8828
|
+
const shipB = state.ships[otherIndex];
|
|
8829
|
+
const shipModelA = resolveShipModel(state, shipA, shipModel);
|
|
8830
|
+
const shipModelB = resolveShipModel(state, shipB, shipModel);
|
|
8831
|
+
collided = resolveShipCollision(state, shipA, shipB, shipModelA, shipModelB) || collided;
|
|
8033
8832
|
}
|
|
8034
8833
|
}
|
|
8035
8834
|
state.collisionFlash = collided ? Math.max(0.12, state.collisionFlash) : Math.max(0, state.collisionFlash - dt * 1.3);
|
|
@@ -8293,6 +9092,101 @@ function renderWaterLightReflection(ctx, source, state, camera, viewport) {
|
|
|
8293
9092
|
ctx.fill();
|
|
8294
9093
|
ctx.restore();
|
|
8295
9094
|
}
|
|
9095
|
+
function renderLighthouseBeam(ctx, state, camera, viewport, visuals) {
|
|
9096
|
+
const lighthousePlacement = SHOWCASE_ENVIRONMENT_LAYOUT.find(
|
|
9097
|
+
(placement) => placement.assetKey === "lighthouse"
|
|
9098
|
+
);
|
|
9099
|
+
if (!lighthousePlacement || !state.showcaseRealisticModelsEnabled) {
|
|
9100
|
+
return;
|
|
9101
|
+
}
|
|
9102
|
+
const source = transformPoint(
|
|
9103
|
+
vec3(0, 11.34, 0),
|
|
9104
|
+
{
|
|
9105
|
+
position: vec3(
|
|
9106
|
+
lighthousePlacement.position.x,
|
|
9107
|
+
lighthousePlacement.position.y,
|
|
9108
|
+
lighthousePlacement.position.z
|
|
9109
|
+
),
|
|
9110
|
+
rotationY: lighthousePlacement.rotationY,
|
|
9111
|
+
scale: lighthousePlacement.scale
|
|
9112
|
+
}
|
|
9113
|
+
);
|
|
9114
|
+
const sweep = state.time * 0.22 + 0.8;
|
|
9115
|
+
const direction = normalizeVec3(vec3(Math.sin(sweep), -0.07, Math.cos(sweep)));
|
|
9116
|
+
const spread = perpendicularOnWater(direction);
|
|
9117
|
+
const farCenter = addVec3(source, scaleVec3(direction, 34));
|
|
9118
|
+
const left = addVec3(farCenter, scaleVec3(spread, 7.4));
|
|
9119
|
+
const right = addVec3(farCenter, scaleVec3(spread, -7.4));
|
|
9120
|
+
const projectedSource = projectPoint(source, camera, viewport);
|
|
9121
|
+
const projectedLeft = projectPoint(left, camera, viewport);
|
|
9122
|
+
const projectedRight = projectPoint(right, camera, viewport);
|
|
9123
|
+
if (!projectedSource || !projectedLeft || !projectedRight) {
|
|
9124
|
+
return;
|
|
9125
|
+
}
|
|
9126
|
+
const pulse = 0.72 + Math.sin(state.time * 1.7) * 0.08;
|
|
9127
|
+
ctx.save();
|
|
9128
|
+
ctx.globalCompositeOperation = "screen";
|
|
9129
|
+
ctx.fillStyle = colorToRgba(visuals.torchCore, 0.055 * pulse);
|
|
9130
|
+
ctx.beginPath();
|
|
9131
|
+
ctx.moveTo(projectedSource.x, projectedSource.y);
|
|
9132
|
+
ctx.lineTo(projectedLeft.x, projectedLeft.y);
|
|
9133
|
+
ctx.lineTo(projectedRight.x, projectedRight.y);
|
|
9134
|
+
ctx.closePath();
|
|
9135
|
+
ctx.fill();
|
|
9136
|
+
const beamLength = Math.hypot(
|
|
9137
|
+
projectedLeft.x - projectedSource.x,
|
|
9138
|
+
projectedLeft.y - projectedSource.y
|
|
9139
|
+
);
|
|
9140
|
+
const core = ctx.createRadialGradient(
|
|
9141
|
+
projectedSource.x,
|
|
9142
|
+
projectedSource.y,
|
|
9143
|
+
2,
|
|
9144
|
+
projectedSource.x,
|
|
9145
|
+
projectedSource.y,
|
|
9146
|
+
clamp(beamLength * 0.22, 18, 80)
|
|
9147
|
+
);
|
|
9148
|
+
core.addColorStop(0, colorToRgba(visuals.torchCore, 0.58));
|
|
9149
|
+
core.addColorStop(0.5, colorToRgba(visuals.torchGlow, 0.18));
|
|
9150
|
+
core.addColorStop(1, colorToRgba(visuals.torchGlow, 0));
|
|
9151
|
+
ctx.fillStyle = core;
|
|
9152
|
+
ctx.beginPath();
|
|
9153
|
+
ctx.arc(projectedSource.x, projectedSource.y, clamp(beamLength * 0.18, 14, 64), 0, Math.PI * 2);
|
|
9154
|
+
ctx.fill();
|
|
9155
|
+
ctx.restore();
|
|
9156
|
+
}
|
|
9157
|
+
function renderAtmosphericGrade(ctx, canvas, state, visuals) {
|
|
9158
|
+
const vignette = ctx.createRadialGradient(
|
|
9159
|
+
canvas.width * 0.5,
|
|
9160
|
+
canvas.height * 0.48,
|
|
9161
|
+
canvas.width * 0.2,
|
|
9162
|
+
canvas.width * 0.5,
|
|
9163
|
+
canvas.height * 0.5,
|
|
9164
|
+
canvas.width * 0.72
|
|
9165
|
+
);
|
|
9166
|
+
vignette.addColorStop(0, "rgba(0, 0, 0, 0)");
|
|
9167
|
+
vignette.addColorStop(0.68, "rgba(0, 0, 0, 0.08)");
|
|
9168
|
+
vignette.addColorStop(1, "rgba(0, 0, 0, 0.32)");
|
|
9169
|
+
ctx.fillStyle = vignette;
|
|
9170
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
9171
|
+
const seaHaze = ctx.createLinearGradient(0, canvas.height * 0.34, 0, canvas.height);
|
|
9172
|
+
seaHaze.addColorStop(0, "rgba(0, 0, 0, 0)");
|
|
9173
|
+
seaHaze.addColorStop(0.5, visuals.ambientMist);
|
|
9174
|
+
seaHaze.addColorStop(1, "rgba(3, 8, 16, 0.18)");
|
|
9175
|
+
ctx.fillStyle = seaHaze;
|
|
9176
|
+
ctx.fillRect(0, canvas.height * 0.34, canvas.width, canvas.height * 0.66);
|
|
9177
|
+
if (state.captureMode) {
|
|
9178
|
+
ctx.save();
|
|
9179
|
+
ctx.globalCompositeOperation = "screen";
|
|
9180
|
+
for (let index = 0; index < 70; index += 1) {
|
|
9181
|
+
const x = pseudoRandom(index * 19 + 3) * canvas.width;
|
|
9182
|
+
const y = pseudoRandom(index * 23 + 7) * canvas.height;
|
|
9183
|
+
const alpha = 8e-3 + pseudoRandom(index * 31 + 11) * 0.012;
|
|
9184
|
+
ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`;
|
|
9185
|
+
ctx.fillRect(x, y, 1.1, 1.1);
|
|
9186
|
+
}
|
|
9187
|
+
ctx.restore();
|
|
9188
|
+
}
|
|
9189
|
+
}
|
|
8296
9190
|
function renderWaterMotionEffects(ctx, effects, camera, viewport) {
|
|
8297
9191
|
ctx.save();
|
|
8298
9192
|
ctx.globalCompositeOperation = "screen";
|
|
@@ -8411,13 +9305,22 @@ function renderScene(ctx, canvas, state, shipModel, dom) {
|
|
|
8411
9305
|
worldCenter: scaleVec3(addVec3(addVec3(a, b), c), 1 / 3),
|
|
8412
9306
|
normal,
|
|
8413
9307
|
baseColor: bandMesh.color,
|
|
8414
|
-
accent: bandAccent
|
|
9308
|
+
accent: bandAccent,
|
|
9309
|
+
material: {
|
|
9310
|
+
name: "water-surface",
|
|
9311
|
+
color: bandMesh.color,
|
|
9312
|
+
roughness: 0.2,
|
|
9313
|
+
metallic: 0,
|
|
9314
|
+
emissive: { r: 0, g: 0, b: 0 }
|
|
9315
|
+
},
|
|
9316
|
+
reflection: 1,
|
|
9317
|
+
surfaceType: "water"
|
|
8415
9318
|
});
|
|
8416
9319
|
}
|
|
8417
9320
|
}
|
|
8418
9321
|
const waterMotionEffects = buildWaterMotionEffects(state);
|
|
8419
9322
|
const lightSources = collectSceneLightSources(state, visuals);
|
|
8420
|
-
pushHarborGeometry(camera, viewport, sceneTriangles,
|
|
9323
|
+
pushHarborGeometry(camera, viewport, sceneTriangles, state);
|
|
8421
9324
|
const cloth = buildClothSurface(
|
|
8422
9325
|
state,
|
|
8423
9326
|
state,
|
|
@@ -8439,23 +9342,46 @@ function renderScene(ctx, canvas, state, shipModel, dom) {
|
|
|
8439
9342
|
worldCenter: scaleVec3(addVec3(addVec3(a, b), c), 1 / 3),
|
|
8440
9343
|
normal,
|
|
8441
9344
|
baseColor: cloth.color,
|
|
8442
|
-
accent: cloth.band === "near" ? 0.1 : 0.04
|
|
9345
|
+
accent: cloth.band === "near" ? 0.1 : 0.04,
|
|
9346
|
+
material: {
|
|
9347
|
+
name: "flag-cloth",
|
|
9348
|
+
color: cloth.color,
|
|
9349
|
+
roughness: 0.94,
|
|
9350
|
+
metallic: 0,
|
|
9351
|
+
emissive: { r: 0, g: 0, b: 0 }
|
|
9352
|
+
},
|
|
9353
|
+
reflection: 0,
|
|
9354
|
+
surfaceType: "cloth"
|
|
8443
9355
|
});
|
|
8444
9356
|
}
|
|
8445
9357
|
for (const ship of state.ships) {
|
|
9358
|
+
const activeShipModel = resolveShipModel(state, ship, shipModel);
|
|
8446
9359
|
buildTrianglesFromMesh(
|
|
8447
|
-
|
|
9360
|
+
activeShipModel,
|
|
8448
9361
|
{ position: ship.position, rotationY: ship.rotationY, scale: SHIP_SCALE },
|
|
8449
9362
|
ship.tint,
|
|
8450
9363
|
camera,
|
|
8451
9364
|
viewport,
|
|
8452
9365
|
sceneTriangles,
|
|
8453
|
-
|
|
9366
|
+
{
|
|
9367
|
+
accent: nearLighting.rtParticipation.directShadows === "premium" ? 0.08 : 0.02,
|
|
9368
|
+
reflection: 0,
|
|
9369
|
+
surfaceType: "ship"
|
|
9370
|
+
}
|
|
8454
9371
|
);
|
|
8455
9372
|
}
|
|
8456
9373
|
drawTriangles(ctx, waterTriangles, lightDir, reflectionStrength, camera, shadowStrength);
|
|
8457
9374
|
for (const ship of state.ships) {
|
|
8458
|
-
renderShipShadow(
|
|
9375
|
+
renderShipShadow(
|
|
9376
|
+
ctx,
|
|
9377
|
+
resolveShipModel(state, ship, shipModel),
|
|
9378
|
+
ship,
|
|
9379
|
+
state,
|
|
9380
|
+
camera,
|
|
9381
|
+
viewport,
|
|
9382
|
+
lightDir,
|
|
9383
|
+
shadowStrength
|
|
9384
|
+
);
|
|
8459
9385
|
}
|
|
8460
9386
|
renderFlagShadow(ctx, cloth, camera, viewport, lightDir, shadowStrength);
|
|
8461
9387
|
for (const source of lightSources.reflectionLights) {
|
|
@@ -8463,9 +9389,18 @@ function renderScene(ctx, canvas, state, shipModel, dom) {
|
|
|
8463
9389
|
}
|
|
8464
9390
|
renderWaterMotionEffects(ctx, waterMotionEffects, camera, viewport);
|
|
8465
9391
|
renderWaterHighlights(ctx, water.bandMeshes, camera, viewport);
|
|
8466
|
-
drawTriangles(
|
|
9392
|
+
drawTriangles(
|
|
9393
|
+
ctx,
|
|
9394
|
+
sceneTriangles,
|
|
9395
|
+
lightDir,
|
|
9396
|
+
reflectionStrength,
|
|
9397
|
+
camera,
|
|
9398
|
+
shadowStrength,
|
|
9399
|
+
lightSources.directLights
|
|
9400
|
+
);
|
|
8467
9401
|
renderFlagPole(ctx, camera, viewport);
|
|
8468
9402
|
renderClothAccent(ctx, cloth, camera, viewport);
|
|
9403
|
+
renderLighthouseBeam(ctx, state, camera, viewport, visuals);
|
|
8469
9404
|
for (const source of lightSources.directLights) {
|
|
8470
9405
|
renderDirectLightGlow(ctx, source, camera, viewport);
|
|
8471
9406
|
}
|
|
@@ -8473,6 +9408,7 @@ function renderScene(ctx, canvas, state, shipModel, dom) {
|
|
|
8473
9408
|
renderShipRigging(ctx, ship, camera, viewport);
|
|
8474
9409
|
}
|
|
8475
9410
|
renderSprays(ctx, state.sprays, camera, viewport);
|
|
9411
|
+
renderAtmosphericGrade(ctx, canvas, state, visuals);
|
|
8476
9412
|
const debugSnapshot = state.debugSession.getSnapshot();
|
|
8477
9413
|
const quality = {
|
|
8478
9414
|
fluid: state.fluidDetail.getSnapshot(),
|
|
@@ -8481,11 +9417,11 @@ function renderScene(ctx, canvas, state, shipModel, dom) {
|
|
|
8481
9417
|
};
|
|
8482
9418
|
const sceneMetrics = [
|
|
8483
9419
|
`focus: ${state.focus}`,
|
|
8484
|
-
`ships: ${state.ships.length} active GLTF hulls`,
|
|
8485
|
-
`moonlight: cold overhead key + ${HARBOR_TORCHES.length + state.ships.
|
|
9420
|
+
`ships: ${state.ships.length} active GLTF hulls across ${new Set(state.ships.map((ship) => ship.modelKey)).size} model families`,
|
|
9421
|
+
`moonlight: cold overhead key + ${HARBOR_TORCHES.length + state.ships.reduce((total, ship) => total + (Array.isArray(ship.lanterns) ? ship.lanterns.length : 0), 0)} warm deck and harbor lights`,
|
|
8486
9422
|
`physics snapshot: ${state.physics.snapshot.stage} (${state.physics.snapshot.stability})`,
|
|
8487
9423
|
`physics contacts: ${state.contactCount}`,
|
|
8488
|
-
`mass split: ${state.ships.map((ship) => `${ship.id} ${(getShipMass(ship, shipModel) / 1e3).toFixed(1)}t`).join(" \xB7 ")}`,
|
|
9424
|
+
`mass split: ${state.ships.map((ship) => `${ship.id} ${(getShipMass(ship, resolveShipModel(state, ship, shipModel)) / 1e3).toFixed(1)}t`).join(" \xB7 ")}`,
|
|
8489
9425
|
`cloth band: ${cloth.band} -> ${cloth.representation.output}`,
|
|
8490
9426
|
`fluid near band: ${water.bandMeshes[0].representation.output}`,
|
|
8491
9427
|
`lighting profile: ${lightingPlan.profile} (${lightingDistanceBands.length} bands)`
|
|
@@ -8506,11 +9442,7 @@ function renderScene(ctx, canvas, state, shipModel, dom) {
|
|
|
8506
9442
|
`pipeline samples: ${debugSnapshot.pipeline.sampleCount}`,
|
|
8507
9443
|
`tracked memory: ${(debugSnapshot.memory.totalTrackedBytes / (1024 * 1024)).toFixed(1)} MB`
|
|
8508
9444
|
];
|
|
8509
|
-
const sceneNotes = state.focus === "physics" ?
|
|
8510
|
-
"Stable world snapshots are taken after the authoritative rigid-body commit and before visual follow-up work.",
|
|
8511
|
-
"The ships collide with mass-weighted impulses and positional correction, so the heavier hull keeps more of its line.",
|
|
8512
|
-
"Moonlight keeps the overall read legible while lanterns and torches make collision moments easy to track against the water."
|
|
8513
|
-
] : SCENE_NOTES;
|
|
9445
|
+
const sceneNotes = state.focus === "physics" ? PHYSICS_SCENE_NOTE_KEYS.map((key) => state.translate(key)) : SCENE_NOTE_KEYS.map((key) => state.translate(key));
|
|
8514
9446
|
const custom = state.demoDescription ?? null;
|
|
8515
9447
|
setListContent(
|
|
8516
9448
|
dom.sceneMetrics,
|
|
@@ -8525,8 +9457,16 @@ function renderScene(ctx, canvas, state, shipModel, dom) {
|
|
|
8525
9457
|
Array.isArray(custom?.debugMetrics) ? custom.debugMetrics : debugMetrics
|
|
8526
9458
|
);
|
|
8527
9459
|
setListContent(dom.sceneNotes, Array.isArray(custom?.notes) ? custom.notes : sceneNotes);
|
|
8528
|
-
dom.status.textContent = typeof custom?.status === "string" ? custom.status :
|
|
8529
|
-
|
|
9460
|
+
dom.status.textContent = typeof custom?.status === "string" ? custom.status : state.translate(gpuSharedTranslationKeys.statusLive, {
|
|
9461
|
+
fps: state.lastDecision.metrics.fps.toFixed(1)
|
|
9462
|
+
});
|
|
9463
|
+
dom.details.textContent = typeof custom?.details === "string" ? custom.details : state.focus === "physics" ? state.translate(gpuSharedTranslationKeys.detailsPhysics, {
|
|
9464
|
+
snapshotStageId: state.physics.plan.snapshotStageId
|
|
9465
|
+
}) : state.showcaseRealisticModelsEnabled ? state.translate(gpuSharedTranslationKeys.detailsRealistic, {
|
|
9466
|
+
pressureLevel: state.lastDecision.pressureLevel
|
|
9467
|
+
}) : state.translate(gpuSharedTranslationKeys.detailsLegacy, {
|
|
9468
|
+
pressureLevel: state.lastDecision.pressureLevel
|
|
9469
|
+
});
|
|
8530
9470
|
}
|
|
8531
9471
|
function updateSceneState(state, dt, shipModel) {
|
|
8532
9472
|
updateShips(state, dt, shipModel);
|
|
@@ -8556,15 +9496,18 @@ function syncTextState(state, shipModel) {
|
|
|
8556
9496
|
stress: state.stress,
|
|
8557
9497
|
ships: state.ships.map((ship) => ({
|
|
8558
9498
|
id: ship.id,
|
|
9499
|
+
modelKey: ship.modelKey ?? "brigantine",
|
|
8559
9500
|
x: Number(ship.position.x.toFixed(2)),
|
|
8560
9501
|
y: Number(ship.position.y.toFixed(2)),
|
|
8561
9502
|
z: Number(ship.position.z.toFixed(2)),
|
|
8562
9503
|
vx: Number(ship.velocity.x.toFixed(2)),
|
|
8563
9504
|
vz: Number(ship.velocity.z.toFixed(2)),
|
|
8564
|
-
massKg: Math.round(getShipMass(ship, shipModel)),
|
|
9505
|
+
massKg: Math.round(getShipMass(ship, resolveShipModel(state, ship, shipModel))),
|
|
8565
9506
|
lanterns: Array.isArray(ship.lanterns) ? ship.lanterns.length : 0
|
|
8566
9507
|
})),
|
|
8567
|
-
shipPhysics:
|
|
9508
|
+
shipPhysics: Object.fromEntries(
|
|
9509
|
+
state.ships.map((ship) => [ship.id, resolveShipModel(state, ship, shipModel)?.physics ?? null])
|
|
9510
|
+
),
|
|
8568
9511
|
sprays: state.sprays.length,
|
|
8569
9512
|
waveImpulses: state.waveImpulses.length,
|
|
8570
9513
|
pressure: state.lastDecision?.pressureLevel ?? "stable",
|
|
@@ -8587,22 +9530,36 @@ function syncTextState(state, shipModel) {
|
|
|
8587
9530
|
}
|
|
8588
9531
|
};
|
|
8589
9532
|
}
|
|
8590
|
-
async function mountGpuShowcase(options = {}) {
|
|
9533
|
+
async function mountGpuShowcase(options = {}, featureFlags = null) {
|
|
8591
9534
|
injectStyles();
|
|
8592
9535
|
const root = options.root ?? document.body;
|
|
8593
9536
|
root.classList?.add?.(ROOT_CLASS);
|
|
9537
|
+
const captureSettings = resolveCaptureSettings(options);
|
|
9538
|
+
if (captureSettings.captureMode) {
|
|
9539
|
+
root.classList?.add?.(CAPTURE_CLASS);
|
|
9540
|
+
}
|
|
8594
9541
|
const previousMarkup = root.innerHTML;
|
|
8595
9542
|
const previousRenderGameToText = window.render_game_to_text;
|
|
8596
9543
|
const previousAdvanceTime = window.advanceTime;
|
|
8597
9544
|
const focus = options.focus ?? new URLSearchParams(window.location.search).get("focus") ?? "integrated";
|
|
9545
|
+
const translate = createGpuSharedTranslator(options.translate);
|
|
8598
9546
|
const dom = buildDemoDom(root, {
|
|
8599
9547
|
packageName: options.packageName ?? "@plasius/gpu-demo-viewer",
|
|
8600
|
-
title: options.title ??
|
|
8601
|
-
subtitle: options.subtitle ??
|
|
9548
|
+
title: options.title ?? translate(gpuSharedTranslationKeys.showcaseTitle),
|
|
9549
|
+
subtitle: options.subtitle ?? translate(gpuSharedTranslationKeys.showcaseSubtitle),
|
|
9550
|
+
translate
|
|
8602
9551
|
});
|
|
8603
9552
|
dom.focusMode.value = focus;
|
|
8604
|
-
const state = createSceneState({
|
|
8605
|
-
|
|
9553
|
+
const state = createSceneState({
|
|
9554
|
+
focus,
|
|
9555
|
+
translate,
|
|
9556
|
+
realisticModelsEnabled: isFeatureEnabled(featureFlags, GPU_SHOWCASE_REALISTIC_MODELS_FEATURE, true),
|
|
9557
|
+
captureMode: captureSettings.captureMode,
|
|
9558
|
+
renderScale: captureSettings.renderScale
|
|
9559
|
+
});
|
|
9560
|
+
const assetCatalog = await (state.showcaseRealisticModelsEnabled ? loadShowcaseAssetCatalog() : createLegacyShowcaseAssetCatalog());
|
|
9561
|
+
const shipModel = assetCatalog.ships[assetCatalog.primaryShipKey];
|
|
9562
|
+
state.assetCatalog = assetCatalog;
|
|
8606
9563
|
state.shipModel = shipModel;
|
|
8607
9564
|
state.packageState = typeof options.createState === "function" ? options.createState() : void 0;
|
|
8608
9565
|
updatePhysicsSnapshot(state, shipModel);
|
|
@@ -8613,6 +9570,8 @@ async function mountGpuShowcase(options = {}) {
|
|
|
8613
9570
|
if (!ctx) {
|
|
8614
9571
|
throw new Error("2D canvas context is required for the shared showcase.");
|
|
8615
9572
|
}
|
|
9573
|
+
ctx.imageSmoothingEnabled = true;
|
|
9574
|
+
ctx.imageSmoothingQuality = "high";
|
|
8616
9575
|
let animationFrameId = 0;
|
|
8617
9576
|
let destroyed = false;
|
|
8618
9577
|
const renderFrame = (nowMs) => {
|
|
@@ -8633,13 +9592,14 @@ async function mountGpuShowcase(options = {}) {
|
|
|
8633
9592
|
state.lastDecision = recordTelemetry(state, syntheticFrame);
|
|
8634
9593
|
}
|
|
8635
9594
|
state.demoDescription = resolveSceneDescription(state, options, shipModel).description;
|
|
9595
|
+
resizeCanvasToDisplaySize(dom.canvas, state);
|
|
8636
9596
|
renderScene(ctx, dom.canvas, state, shipModel, dom);
|
|
8637
9597
|
syncTextState(state, shipModel);
|
|
8638
9598
|
animationFrameId = requestAnimationFrame(renderFrame);
|
|
8639
9599
|
};
|
|
8640
9600
|
const handlePauseClick = () => {
|
|
8641
9601
|
state.paused = !state.paused;
|
|
8642
|
-
dom.pauseButton.textContent = state.paused ?
|
|
9602
|
+
dom.pauseButton.textContent = state.paused ? state.translate(gpuSharedTranslationKeys.resume) : state.translate(gpuSharedTranslationKeys.pause);
|
|
8643
9603
|
};
|
|
8644
9604
|
const handleStressChange = () => {
|
|
8645
9605
|
state.stress = dom.stressToggle.checked;
|
|
@@ -8674,6 +9634,7 @@ async function mountGpuShowcase(options = {}) {
|
|
|
8674
9634
|
state.packageState = void 0;
|
|
8675
9635
|
}
|
|
8676
9636
|
root.classList?.remove?.(ROOT_CLASS);
|
|
9637
|
+
root.classList?.remove?.(CAPTURE_CLASS);
|
|
8677
9638
|
root.innerHTML = previousMarkup;
|
|
8678
9639
|
if (typeof previousRenderGameToText === "function") {
|
|
8679
9640
|
window.render_game_to_text = previousRenderGameToText;
|
|
@@ -8694,6 +9655,12 @@ async function mountGpuShowcase(options = {}) {
|
|
|
8694
9655
|
};
|
|
8695
9656
|
}
|
|
8696
9657
|
function updatePhysicsSnapshot(state, shipModel) {
|
|
9658
|
+
const rigidBodyShapes = Object.fromEntries(
|
|
9659
|
+
state.ships.map((ship) => [
|
|
9660
|
+
ship.id,
|
|
9661
|
+
resolveShipModel(state, ship, shipModel)?.physics?.shape ?? "box"
|
|
9662
|
+
])
|
|
9663
|
+
);
|
|
8697
9664
|
state.physics.snapshot = createPhysicsWorldSnapshot({
|
|
8698
9665
|
frameId: `showcase-${state.frame}`,
|
|
8699
9666
|
tick: state.frame,
|
|
@@ -8709,11 +9676,12 @@ function updatePhysicsSnapshot(state, shipModel) {
|
|
|
8709
9676
|
collisionCount: state.collisionCount,
|
|
8710
9677
|
contactCount: state.contactCount,
|
|
8711
9678
|
snapshotStageId: state.physics.plan.snapshotStageId,
|
|
8712
|
-
rigidBodyShape: shipModel.physics.shape ?? "box"
|
|
9679
|
+
rigidBodyShape: shipModel.physics.shape ?? "box",
|
|
9680
|
+
rigidBodyShapes
|
|
8713
9681
|
}
|
|
8714
9682
|
});
|
|
8715
9683
|
}
|
|
8716
|
-
var STYLE_ID, ROOT_CLASS,
|
|
9684
|
+
var STYLE_ID, ROOT_CLASS, CAPTURE_CLASS, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT, CAPTURE_CANVAS_PIXEL_BUDGET, SHIP_SCALE, HARBOR_BOUNDS, CAMERA_PRESETS, showcaseFocusModes, FOCUS_MODE_TRANSLATION_KEYS, SCENE_NOTE_KEYS, PHYSICS_SCENE_NOTE_KEYS, LEGACY_HARBOR_LAYOUT, SHOWCASE_ENVIRONMENT_LAYOUT, SHIP_LANTERNS, CUTTER_LANTERNS, HARBOR_TORCHES, FLAG_LAYOUT;
|
|
8717
9685
|
var init_showcase_runtime = __esm({
|
|
8718
9686
|
"src/showcase-runtime.js"() {
|
|
8719
9687
|
init_dist();
|
|
@@ -8724,10 +9692,14 @@ var init_showcase_runtime = __esm({
|
|
|
8724
9692
|
init_browser();
|
|
8725
9693
|
init_asset_url();
|
|
8726
9694
|
init_gltf_loader();
|
|
9695
|
+
init_feature_flags();
|
|
9696
|
+
init_i18n();
|
|
8727
9697
|
STYLE_ID = "plasius-shared-3d-showcase-style";
|
|
8728
9698
|
ROOT_CLASS = "plasius-showcase-root";
|
|
8729
|
-
|
|
8730
|
-
|
|
9699
|
+
CAPTURE_CLASS = "plasius-showcase-root--capture";
|
|
9700
|
+
DEFAULT_CANVAS_WIDTH = 1280;
|
|
9701
|
+
DEFAULT_CANVAS_HEIGHT = 720;
|
|
9702
|
+
CAPTURE_CANVAS_PIXEL_BUDGET = 1920 * 1080;
|
|
8731
9703
|
SHIP_SCALE = 1.1;
|
|
8732
9704
|
HARBOR_BOUNDS = Object.freeze({
|
|
8733
9705
|
minX: -11.2,
|
|
@@ -8745,84 +9717,75 @@ var init_showcase_runtime = __esm({
|
|
|
8745
9717
|
debug: Object.freeze({ yaw: -0.7, pitch: 0.32, distance: 24, target: [0, 2.2, 0] })
|
|
8746
9718
|
});
|
|
8747
9719
|
showcaseFocusModes = Object.freeze(Object.keys(CAMERA_PRESETS));
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
-0.5,
|
|
8757
|
-
-0.5,
|
|
8758
|
-
-0.5,
|
|
8759
|
-
0.5,
|
|
8760
|
-
-0.5,
|
|
8761
|
-
-0.5,
|
|
8762
|
-
0.5,
|
|
8763
|
-
0.5,
|
|
8764
|
-
-0.5,
|
|
8765
|
-
-0.5,
|
|
8766
|
-
0.5,
|
|
8767
|
-
-0.5,
|
|
8768
|
-
-0.5,
|
|
8769
|
-
-0.5,
|
|
8770
|
-
0.5,
|
|
8771
|
-
0.5,
|
|
8772
|
-
-0.5,
|
|
8773
|
-
0.5,
|
|
8774
|
-
0.5,
|
|
8775
|
-
0.5,
|
|
8776
|
-
0.5,
|
|
8777
|
-
-0.5,
|
|
8778
|
-
0.5,
|
|
8779
|
-
0.5
|
|
8780
|
-
]),
|
|
8781
|
-
indices: Object.freeze([
|
|
8782
|
-
0,
|
|
8783
|
-
1,
|
|
8784
|
-
2,
|
|
8785
|
-
0,
|
|
8786
|
-
2,
|
|
8787
|
-
3,
|
|
8788
|
-
5,
|
|
8789
|
-
4,
|
|
8790
|
-
7,
|
|
8791
|
-
5,
|
|
8792
|
-
7,
|
|
8793
|
-
6,
|
|
8794
|
-
4,
|
|
8795
|
-
0,
|
|
8796
|
-
3,
|
|
8797
|
-
4,
|
|
8798
|
-
3,
|
|
8799
|
-
7,
|
|
8800
|
-
1,
|
|
8801
|
-
5,
|
|
8802
|
-
6,
|
|
8803
|
-
1,
|
|
8804
|
-
6,
|
|
8805
|
-
2,
|
|
8806
|
-
3,
|
|
8807
|
-
2,
|
|
8808
|
-
6,
|
|
8809
|
-
3,
|
|
8810
|
-
6,
|
|
8811
|
-
7,
|
|
8812
|
-
4,
|
|
8813
|
-
5,
|
|
8814
|
-
1,
|
|
8815
|
-
4,
|
|
8816
|
-
1,
|
|
8817
|
-
0
|
|
8818
|
-
])
|
|
9720
|
+
FOCUS_MODE_TRANSLATION_KEYS = Object.freeze({
|
|
9721
|
+
integrated: gpuSharedTranslationKeys.focusIntegrated,
|
|
9722
|
+
lighting: gpuSharedTranslationKeys.focusLighting,
|
|
9723
|
+
cloth: gpuSharedTranslationKeys.focusCloth,
|
|
9724
|
+
fluid: gpuSharedTranslationKeys.focusFluid,
|
|
9725
|
+
physics: gpuSharedTranslationKeys.focusPhysics,
|
|
9726
|
+
performance: gpuSharedTranslationKeys.focusPerformance,
|
|
9727
|
+
debug: gpuSharedTranslationKeys.focusDebug
|
|
8819
9728
|
});
|
|
9729
|
+
SCENE_NOTE_KEYS = Object.freeze([
|
|
9730
|
+
gpuSharedTranslationKeys.noteAssetLoading,
|
|
9731
|
+
gpuSharedTranslationKeys.noteMoonlight,
|
|
9732
|
+
gpuSharedTranslationKeys.noteContinuity,
|
|
9733
|
+
gpuSharedTranslationKeys.notePerformance
|
|
9734
|
+
]);
|
|
9735
|
+
PHYSICS_SCENE_NOTE_KEYS = Object.freeze([
|
|
9736
|
+
gpuSharedTranslationKeys.notePhysicsSnapshots,
|
|
9737
|
+
gpuSharedTranslationKeys.notePhysicsCollisions,
|
|
9738
|
+
gpuSharedTranslationKeys.notePhysicsLighting
|
|
9739
|
+
]);
|
|
9740
|
+
LEGACY_HARBOR_LAYOUT = Object.freeze([
|
|
9741
|
+
Object.freeze({
|
|
9742
|
+
position: Object.freeze({ x: -8.2, y: 1.1, z: -0.9 }),
|
|
9743
|
+
rotationY: -0.16,
|
|
9744
|
+
scale: 5.4,
|
|
9745
|
+
color: { r: 0.32, g: 0.27, b: 0.23, a: 1 },
|
|
9746
|
+
accent: 0.06
|
|
9747
|
+
}),
|
|
9748
|
+
Object.freeze({
|
|
9749
|
+
position: Object.freeze({ x: -5.7, y: 0.45, z: 1.4 }),
|
|
9750
|
+
rotationY: -0.08,
|
|
9751
|
+
scale: { x: 6.8, y: 0.3, z: 2.1 },
|
|
9752
|
+
color: { r: 0.31, g: 0.31, b: 0.34, a: 1 },
|
|
9753
|
+
accent: 0.04
|
|
9754
|
+
}),
|
|
9755
|
+
Object.freeze({
|
|
9756
|
+
position: Object.freeze({ x: -10.4, y: 0.28, z: 0.8 }),
|
|
9757
|
+
rotationY: 0.22,
|
|
9758
|
+
scale: { x: 1.2, y: 0.9, z: 1.2 },
|
|
9759
|
+
color: { r: 0.31, g: 0.35, b: 0.39, a: 1 },
|
|
9760
|
+
accent: 0.02
|
|
9761
|
+
})
|
|
9762
|
+
]);
|
|
9763
|
+
SHOWCASE_ENVIRONMENT_LAYOUT = Object.freeze([
|
|
9764
|
+
Object.freeze({
|
|
9765
|
+
assetKey: "harbor-dock",
|
|
9766
|
+
position: Object.freeze({ x: -4.6, y: 0.16, z: 0.7 }),
|
|
9767
|
+
rotationY: -0.08,
|
|
9768
|
+
scale: 0.84,
|
|
9769
|
+
accent: 0.04
|
|
9770
|
+
}),
|
|
9771
|
+
Object.freeze({
|
|
9772
|
+
assetKey: "lighthouse",
|
|
9773
|
+
position: Object.freeze({ x: -9.8, y: 0, z: -0.58 }),
|
|
9774
|
+
rotationY: 0.12,
|
|
9775
|
+
scale: 0.56,
|
|
9776
|
+
accent: 0.08
|
|
9777
|
+
})
|
|
9778
|
+
]);
|
|
8820
9779
|
SHIP_LANTERNS = Object.freeze([
|
|
8821
9780
|
Object.freeze({ x: 0.94, y: 1.54, z: 2.52, glow: 1 }),
|
|
8822
9781
|
Object.freeze({ x: -0.9, y: 1.58, z: 2.44, glow: 0.92 }),
|
|
8823
9782
|
Object.freeze({ x: 0.62, y: 1.42, z: -2.18, glow: 0.88 }),
|
|
8824
9783
|
Object.freeze({ x: -0.58, y: 1.46, z: -2.04, glow: 0.84 })
|
|
8825
9784
|
]);
|
|
9785
|
+
CUTTER_LANTERNS = Object.freeze([
|
|
9786
|
+
Object.freeze({ x: 0.42, y: 1.04, z: 1.18, glow: 0.94 }),
|
|
9787
|
+
Object.freeze({ x: -0.42, y: 1.04, z: 1.12, glow: 0.88 })
|
|
9788
|
+
]);
|
|
8826
9789
|
HARBOR_TORCHES = Object.freeze([
|
|
8827
9790
|
Object.freeze({ x: -5.2, y: 1.25, z: 1.36, glow: 1.1 }),
|
|
8828
9791
|
Object.freeze({ x: -8.6, y: 2.48, z: -0.72, glow: 1 }),
|
|
@@ -8840,13 +9803,20 @@ var init_showcase_runtime = __esm({
|
|
|
8840
9803
|
// src/index.js
|
|
8841
9804
|
var index_exports = {};
|
|
8842
9805
|
__export(index_exports, {
|
|
9806
|
+
createGpuSharedTranslator: () => createGpuSharedTranslator,
|
|
9807
|
+
gpuSharedEnGbTranslations: () => gpuSharedEnGbTranslations,
|
|
9808
|
+
gpuSharedTranslationKeys: () => gpuSharedTranslationKeys,
|
|
9809
|
+
gpuSharedTranslations: () => gpuSharedTranslations,
|
|
8843
9810
|
loadGltfModel: () => loadGltfModel2,
|
|
8844
9811
|
mountGpuShowcase: () => mountGpuShowcase2,
|
|
8845
9812
|
resolveShowcaseAssetUrl: () => resolveShowcaseAssetUrl,
|
|
8846
|
-
showcaseFocusModes: () => showcaseFocusModes2
|
|
9813
|
+
showcaseFocusModes: () => showcaseFocusModes2,
|
|
9814
|
+
translateGpuSharedText: () => translateGpuSharedText
|
|
8847
9815
|
});
|
|
8848
9816
|
module.exports = __toCommonJS(index_exports);
|
|
8849
9817
|
init_asset_url();
|
|
9818
|
+
init_i18n();
|
|
9819
|
+
init_en_GB();
|
|
8850
9820
|
var showcaseFocusModes2 = Object.freeze([
|
|
8851
9821
|
"integrated",
|
|
8852
9822
|
"lighting",
|
|
@@ -8868,13 +9838,19 @@ async function mountGpuShowcase2(options = {}) {
|
|
|
8868
9838
|
}
|
|
8869
9839
|
const publicOptions = { ...options };
|
|
8870
9840
|
delete publicOptions.__runtimeLoader;
|
|
8871
|
-
|
|
9841
|
+
delete publicOptions.__featureFlags;
|
|
9842
|
+
return module2.mountGpuShowcase(publicOptions, options.__featureFlags);
|
|
8872
9843
|
}
|
|
8873
9844
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8874
9845
|
0 && (module.exports = {
|
|
9846
|
+
createGpuSharedTranslator,
|
|
9847
|
+
gpuSharedEnGbTranslations,
|
|
9848
|
+
gpuSharedTranslationKeys,
|
|
9849
|
+
gpuSharedTranslations,
|
|
8875
9850
|
loadGltfModel,
|
|
8876
9851
|
mountGpuShowcase,
|
|
8877
9852
|
resolveShowcaseAssetUrl,
|
|
8878
|
-
showcaseFocusModes
|
|
9853
|
+
showcaseFocusModes,
|
|
9854
|
+
translateGpuSharedText
|
|
8879
9855
|
});
|
|
8880
9856
|
//# sourceMappingURL=index.cjs.map
|