diff --git a/.github/actions/build_and_deploy/action.yml b/.github/actions/build_and_deploy/action.yml new file mode 100644 index 00000000..29acb255 --- /dev/null +++ b/.github/actions/build_and_deploy/action.yml @@ -0,0 +1,86 @@ +name: 'Build and Deploy' +description: 'Build and Deploy' + +runs: + using: "composite" + steps: + - name: Setup MSVC + uses: ilammy/msvc-dev-cmd@v1 + - name: Install Qt + uses: jurplel/install-qt-action@v4 + if: ${{ matrix.os != 'macos-latest' && matrix.os != 'ubuntu-22.04-arm' }} + with: + cache: true + version: '5.15.2' + - name: Setup Env variables + shell: bash + id: envs + run: | + echo "name=VCINSTALLDIR::C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC" >> $GITHUB_ENV + ARCH=$(uname -m) + echo "arch=$ARCH" >> $GITHUB_OUTPUT + - name: Clone VCG + shell: bash + run: | + cd .. + git clone --single-branch --branch devel https://github.com/cnr-isti-vclab/vcglib + - name: Install dependencies Linux + shell: bash + if: ${{ runner.os == 'Linux' }} + run: | + sudo apt-get install -y mesa-common-dev libglu1-mesa-dev libglew-dev ninja-build + - name: Install dependencies Linux arm + shell: bash + if: ${{ matrix.os == 'ubuntu-22.04-arm' }} + run: | + sudo apt-get install -y qtbase5-dev qt5-qmake + - name: Install dependencies macOS arm + shell: bash + if: ${{ matrix.os == 'macos-latest' }} + run: | + brew install qt@5 + echo Qt5_DIR=$(brew --prefix qt@5) >> $GITHUB_ENV + echo $(brew --prefix qt@5)/bin >> $GITHUB_PATH + - name: Ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ matrix.os }}-${{ github.ref }} + - name: Configure and Build + shell: bash + run: | + mkdir build + mkdir install + cd build + cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Release -GNinja -DCMAKE_INSTALL_PREFIX=../install .. + ninja + ninja install + - name: Deploy Linux + shell: bash + if: ${{ runner.os == 'Linux' }} + run: | + cd install + # download linuxdeployqt + wget https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20250213-2/linuxdeploy-${{ steps.envs.outputs.arch }}.AppImage + chmod +x linuxdeploy-${{ steps.envs.outputs.arch }}.AppImage + wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/1-alpha-20250213-1/linuxdeploy-plugin-qt-${{ steps.envs.outputs.arch }}.AppImage + chmod +x linuxdeploy-plugin-qt-${{ steps.envs.outputs.arch }}.AppImage + # deploy + ./linuxdeploy-${{ steps.envs.outputs.arch }}.AppImage --executable=$PWD/bin/nxsbuild --executable=$PWD/bin/nxscompress --executable=$PWD/bin/nxsedit --executable=$PWD/bin/nxsview --appdir=. --plugin qt + rm -r bin + rm linuxdeploy-${{ steps.envs.outputs.arch }}.AppImage linuxdeploy-plugin-qt-${{ steps.envs.outputs.arch }}.AppImage + - name: Deploy MacOS + shell: bash + if: ${{ runner.os == 'macOS' }} + run: | + cd install + macdeployqt nxsview.app -executable=nxsview.app/Contents/MacOS/nxsbuild -executable=nxsview.app/Contents/MacOS/nxscompress -executable=nxsview.app/Contents/MacOS/nxsedit + rm -r bin + rm -r lib + - name: Deploy Windows + shell: bash + if: ${{ runner.os == 'Windows' }} + run: | + cd install/bin + windeployqt nxsview.exe + cd .. + mv bin nexus_portable-${{ steps.envs.outputs.arch }} diff --git a/.github/actions/upload/action.yml b/.github/actions/upload/action.yml new file mode 100644 index 00000000..be7d571e --- /dev/null +++ b/.github/actions/upload/action.yml @@ -0,0 +1,48 @@ +name: 'Upload' +description: 'Upload' + +runs: + using: "composite" + steps: + - name: Setup Env variables + shell: bash + id: envs + run: | + ARCH=$(uname -m) + echo "arch=$ARCH" >> $GITHUB_OUTPUT + - name: Archive Linux + shell: bash + if: ${{ runner.os == 'Linux' }} + run: | + cd install + tar -cvzf nexus-linux-${{ steps.envs.outputs.arch }}.tar.gz * + - name: Upload nexus Linux + uses: actions/upload-artifact@v4 + if: ${{ runner.os == 'Linux' }} + with: + name: nexus-linux-${{ steps.envs.outputs.arch }} + path: install/nexus-linux-${{ steps.envs.outputs.arch }}.tar.gz + - name: Archive MacOS + shell: bash + if: ${{ runner.os == 'macOS' }} + run: | + cd install + tar -cvzf nxsview-macos-${{ steps.envs.outputs.arch }}.tar.gz * + - name: Upload nxsview MacOS + uses: actions/upload-artifact@v4 + if: ${{ runner.os == 'macOS' }} + with: + name: nxsview-macos-${{ steps.envs.outputs.arch }} + path: install/nxsview-macos-${{ steps.envs.outputs.arch }}.tar.gz + - name: Archive Windows + shell: bash + if: ${{ runner.os == 'Windows' }} + run: | + cd install + powershell Compress-Archive -Path nexus_portable-${{ steps.envs.outputs.arch }} -DestinationPath nexus-windows-${{ steps.envs.outputs.arch }}.zip + - name: Uploading Nexus Windows + uses: actions/upload-artifact@v4 + if: ${{ runner.os == 'Windows' }} + with: + name: nexus-windows-${{ steps.envs.outputs.arch }} + path: install/nexus-windows-${{ steps.envs.outputs.arch }}.zip diff --git a/.github/workflows/BuildNexus.yml b/.github/workflows/BuildNexus.yml new file mode 100644 index 00000000..6d2ecdc0 --- /dev/null +++ b/.github/workflows/BuildNexus.yml @@ -0,0 +1,22 @@ +name: BuildNexus + +on: + [push, pull_request] + +jobs: + build_nexus: + name: Build Nexus + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: ['ubuntu-22.04', 'ubuntu-22.04-arm', 'macos-15-intel', 'macos-latest', 'windows-latest'] + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Build and Deploy + uses: ./.github/actions/build_and_deploy + - name: Upload + uses: ./.github/actions/upload diff --git a/.github/workflows/CreateRelease.yml b/.github/workflows/CreateRelease.yml new file mode 100644 index 00000000..b5fc62bd --- /dev/null +++ b/.github/workflows/CreateRelease.yml @@ -0,0 +1,70 @@ +name: CreateRelease + +on: + workflow_dispatch: + inputs: + version: + description: 'New Nexus Version' + required: true + default: 'X.Y' + +jobs: + update_version: + name: Update Version + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Update NEXUS_VERSION + run: | + echo ${{ github.event.inputs.version }} | tr -d '\n'> NEXUS_VERSION + - name: Commit change + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: Set Nexus version to ${{ github.event.inputs.version }} + + build_nexus: + name: Build Nexus + needs: update_version + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: ['ubuntu-22.04', 'ubuntu-22.04-arm', 'macos-15-intel', 'macos-latest', 'windows-latest'] + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Build and Deploy + uses: ./.github/actions/build_and_deploy + - name: Sign and Notarize + uses: cnr-isti-vclab/sign-and-notarize@v1 + with: + input-path: 'install/*.app' + macos-certificate: '${{ secrets.MACOS_CERTIFICATE }}' + macos-certificate-id: '${{ secrets.MACOS_CERT_ID }}' + macos-certificate-password: '${{ secrets.MACOS_CERTIFICATE_PSSW }}' + macos-notarization-team: '${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}' + macos-notarization-user: '${{ secrets.MACOS_NOTARIZATION_USER }}' + macos-notarization-password: '${{ secrets.MACOS_NOTARIZATION_PSSW }}' + - name: Upload + uses: ./.github/actions/upload + + create_release: + name: Create Release + needs: build_nexus + runs-on: ubuntu-latest + steps: + #download all the artifacts + - name: Download Nexus Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts/ + + #Create release + - name: Create Release + uses: "ncipollo/release-action@v1" + with: + token: "${{ secrets.GITHUB_TOKEN }}" + tag: v${{ github.event.inputs.version }} + name: 'Nexus v${{ github.event.inputs.version }}' + artifacts: | + artifacts/n*/* diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml deleted file mode 100644 index 7283f610..00000000 --- a/.github/workflows/Linux.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Linux - -on: - [push, pull_request] - -jobs: - linux_build: - name: Build Nexus (Linux) - runs-on: ubuntu-20.04 #in order to deploy, need to use oldest supported version - - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Qt - uses: jurplel/install-qt-action@v3 - with: - cache: true - version: '5.15.2' - - name: Install dependencies - run: | - sudo apt-get install -y mesa-common-dev libglu1-mesa-dev libglew-dev - cd .. - git clone --single-branch --branch devel https://github.com/cnr-isti-vclab/vcglib - - name: Configure and Build - shell: bash - run: | - mkdir build - cd build - cmake .. - make -j4 diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml deleted file mode 100644 index 1785b4f7..00000000 --- a/.github/workflows/MacOS.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: MacOS - -on: - [push, pull_request] - -jobs: - macos_build: - name: Build Nexus (MacOS) - runs-on: macos-latest - - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Qt - uses: jurplel/install-qt-action@v3 - with: - cache: true - version: '5.15.2' - - name: Install dependencies - run: | - cd .. - git clone --single-branch --branch devel https://github.com/cnr-isti-vclab/vcglib - - name: Configure and Build - shell: bash - run: | - mkdir build - mkdir install - cd build - cmake -DCMAKE_INSTALL_PREFIX=../install .. - make -j4 - make install - - name: Deploy - shell: bash - run: | - cd install - macdeployqt nxsview.app -executable=nxsview.app/Contents/MacOS/nxsbuild -executable=nxsview.app/Contents/MacOS/nxscompress -executable=nxsview.app/Contents/MacOS/nxsedit - rm -r bin - rm -r lib - tar -cvzf nxsview-macos.tar.gz * - - name: Upload nxsview Portable - uses: actions/upload-artifact@v3 - with: - name: nxsview_macos_portable - path: install/nxsview-macos.tar.gz diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml deleted file mode 100644 index c3858d26..00000000 --- a/.github/workflows/Windows.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Windows - -on: - [push, pull_request] - -jobs: - linux_build: - name: Build Nexus (Windows) - runs-on: windows-latest - - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Setup MSVC - uses: ilammy/msvc-dev-cmd@v1 - - name: Install Qt - uses: jurplel/install-qt-action@v3 - with: - cache: true - version: '5.15.2' - - name: Install dependencies - run: | - cd .. - git clone --single-branch --branch devel https://github.com/cnr-isti-vclab/vcglib - echo "VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC" >> $GITHUB_ENV - - name: Configure and Build - shell: bash - run: | - mkdir build - mkdir install - cd build - cmake -GNinja -DCMAKE_INSTALL_PREFIX=../install .. - ninja - ninja install - - name: Deploy - shell: bash - run: | - cd install/bin - windeployqt nxsview.exe - cd .. - mv bin nexus_portable - - name: Uploading Nexus Portable - uses: actions/upload-artifact@v3 - with: - name: nexus_windows_portable - path: install/nexus_portable diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a484b15..2f455906 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ #export CMAKE_PREFIX_PATH=path to Qt/5.5/gcc_64/ (where you would find bin/qmake) -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.10) project(nexus) option(BUILD_NXS_BUILD "" ON) @@ -13,7 +13,7 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -find_package(Qt5Widgets) +find_package(Qt6 COMPONENTS Widgets REQUIRED) if (BUILD_NXS_VIEW) include(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/tools.cmake) @@ -27,7 +27,12 @@ else() endif() # VCGLib -- required -if (VCGDIR) # VCGDIR exists - using custom user vcglib path +find_package(vcglib CONFIG) +if(TARGET vcglib::vcglib) + message(STATUS "nexus - VCGLib - using system provided library") + add_library(vcglib ALIAS vcglib::vcglib) + get_target_property(VCGDIR vcglib::vcglib INTERFACE_INCLUDE_DIRECTORIES) +elseif (VCGDIR) # VCGDIR exists - using custom user vcglib path if(EXISTS ${VCGDIR}) add_subdirectory(${VCGDIR} ${CMAKE_CURRENT_BINARY_DIR}/vcglib) message(STATUS "nexus - VCGLib - using custom VCGDIR path library") @@ -53,7 +58,13 @@ endif() set(BUILD_CORTO_CODEC_UNITY OFF) set(BUILD_CORTO_EXE OFF) -add_subdirectory(src/corto EXCLUDE_FROM_ALL) +find_package(corto CONFIG) +if(TARGET corto::corto) + message(STATUS "nexus - corto - using system provided library") + add_library(corto ALIAS corto::corto) +else() + add_subdirectory(src/corto EXCLUDE_FROM_ALL) +endif() add_subdirectory(src) @@ -68,3 +79,25 @@ endif() if(BUILD_NXS_VIEW) add_subdirectory(src/nxsview) endif() + +if(TARGET vcglib::vcglib AND TARGET corto::corto) + install(EXPORT nexusTargets + DESTINATION lib/cmake/nexus + NAMESPACE nexus:: + FILE nexusTargets.cmake + ) + + include(CMakePackageConfigHelpers) + # generate the config file that includes the exports + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/nexusConfig.cmake" + INSTALL_DESTINATION lib/cmake/nexus + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) + + install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/nexusConfig.cmake" + DESTINATION lib/cmake/nexus + ) +endif() diff --git a/Config.cmake.in b/Config.cmake.in new file mode 100644 index 00000000..0457a3ae --- /dev/null +++ b/Config.cmake.in @@ -0,0 +1,7 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(vcglib) +find_dependency(corto) + +include ( "${CMAKE_CURRENT_LIST_DIR}/nexusTargets.cmake" ) diff --git a/NEXUS_VERSION b/NEXUS_VERSION index 89f71c74..15689348 100644 --- a/NEXUS_VERSION +++ b/NEXUS_VERSION @@ -1 +1 @@ -4.3 \ No newline at end of file +2025.05 \ No newline at end of file diff --git a/html/js/nexus.js b/html/js/nexus.js index 8a7e0ae8..c4c9bdd4 100644 --- a/html/js/nexus.js +++ b/html/js/nexus.js @@ -319,7 +319,7 @@ Mesh.prototype = { let request = indexedDB.open(url); request.onsuccess = () => { this.db = request.result; }; request.onupgradeneeded = (event) => { - let db = event.target.result; + let db = event.target.result; this.meshStore = db.createObjectStore('mesh'); this.texStore = db.createObjectStore('tex'); }; @@ -1093,6 +1093,11 @@ function httpRequestNodeGeometry(context, node) { let request = { load:function() { delete m.georeq[n]; + if(m.db) { + let transaction = m.db.transaction('mesh', "readwrite"); + transaction.objectStore('mesh').put(this.response, n); + transaction.commit(); + } loadNodeGeometry(this, context, node); }, error:function() { delete m.georeq[n]; @@ -1137,7 +1142,7 @@ function requestNodeTexture(context, node) { let request = transaction.objectStore('tex').get(node.id); request.onsuccess = (e) => { if(request.result) { - loadNodeTecture({ response: request.result}, context, node); + loadNodeTexture({ response: request.result}, context, node, tex); } else { httpRequestNodeTexture(context, node, tex); } @@ -1155,7 +1160,13 @@ function httpRequestNodeTexture(context, node, tex) { let request = { load:function() { delete m.texreq[n]; - loadNodeTexture(this, context, node, tex); }, + if(m.db) { + let transaction = m.db.transaction('tex', "readwrite"); + transaction.objectStore('tex').put(this.response, tex); + transaction.commit(); + } + loadNodeTexture(this, context, node, tex); + }, error:function() { if(Debug.verbose) console.log("Texture request error!"); delete m.texreq[n]; @@ -1215,12 +1226,6 @@ function loadNodeGeometry(request, context, node) { node.buffer = request.response; - if(m.db) { - let transaction = m.db.transaction('mesh', "readwrite"); - transaction.objectStore('mesh').put(node.buffer, n); - transaction.commit(); - } - if(!m.compressed) readyNode(node); else if(m.meco) { diff --git a/nexus3d/README.md b/nexus3d/README.md new file mode 100644 index 00000000..6a6a0095 --- /dev/null +++ b/nexus3d/README.md @@ -0,0 +1,102 @@ +# Nexus3D + +Streaming 3D on the web (three.js supported). + +## Install + +Install three.js (npm will save to `dependencies` automatically): + +```bash +npm install three +``` + +If you use webpack for local development: + +```bash +npm install --save-dev webpack webpack-cli webpack-dev-server +``` + +Build the example with webpack: + +```bash +npx webpack --mode development +``` + +Run the dev server: + +```bash +npm run start +``` + +## Getting started (minimal) + +**Important:** Nexus3D expects three.js to be available. You need to include three.js in your project either via npm or a CDN. + +```js +import * as THREE from 'three'; +import { Nexus3D } from './build/nexus3D.js'; + +const renderer = new THREE.WebGLRenderer({ antialias: true }); +renderer.setSize(window.innerWidth, window.innerHeight); +document.body.appendChild(renderer.domElement); + +const scene = new THREE.Scene(); +const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); + +const url = 'https://example.com/models/my.nxs'; +const n = new Nexus3D(url, renderer, { + material: new THREE.MeshStandardMaterial(), + onLoad: (mesh) => { scene.add(mesh); }, + onProgress: (mesh, available, total) => { console.log('progress', available, total); } +}); + +function animate() { + requestAnimationFrame(animate); + renderer.render(scene, camera); +} +animate(); +``` + +## API (brief) + +- Constructor: `new Nexus3D(urlOrNxsObject, renderer, options = {})` + - `urlOrNxsObject`: string URL to the NXS file or an already-loaded NXS object + - `renderer`: a `THREE.WebGLRenderer` instance (required) + - `options`: + - `material`: optional `THREE.Material` instance to use as the template + - `onLoad(mesh)`: optional function called when root metadata is ready + - `onUpdate(mesh)`: optional function called when node availability changes + - `onProgress(mesh, availableNodes, nodesCount)`: progress callback + +- Cache: a shared `Cache` instance is used by default (see `src/Cache.js`). You can tune behavior via `mesh.cache.minFps` and similar properties. + +## Docs + +### Material + +NXS material is actually a template material that is used for each patch of the nexus, you cannot set the map properties, which will be overwritten by the patches own textures. + +You can change the material of the NXS either by replacing the material or by changing a value (the color for example). If you want to disable texture rendering set the parameter 'map' to false, and set `material.needsUpdate = true`. + +### FPS + +The Cache class can throttle the amount of geometry rendered trying to maintain the fps above a certain target (minFps), reducing the targetError. You can set this property through the `NXS.cache.minFps` property (default 30). + +### Instances + +You can render multiple instances of the same mesh, just using the reference to an existing NXS instead of the url in the constructor. Cache will be shared, balancing the quality among all the instances. + +## Notes + +- This library is compatible with three.js v0.181.x (see `package.json`). + +## Roadmap / TODO + +- Make cache global per rendering context instead of per-model. +- GPU transfer metering and prefetch control. +- Improve examples and add automated tests. +- Add CI to build and test on push. + +## Contributing + +Please open issues or pull requests on the repository. If you change three.js versions, please note compatibility in the README. diff --git a/nexus3d/build/nexus3D.js b/nexus3d/build/nexus3D.js new file mode 100644 index 00000000..20e9655a --- /dev/null +++ b/nexus3d/build/nexus3D.js @@ -0,0 +1,205 @@ +/* + * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). + * This devtool is neither made for production nor for readable output files. + * It uses "eval()" calls to create a separate source file in the browser devtools. + * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) + * or disable the default devtool with "devtool: false". + * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("three")); + else if(typeof define === 'function' && define.amd) + define(["three"], factory); + else if(typeof exports === 'object') + exports["Nexus3D"] = factory(require("three")); + else + root["Nexus3D"] = factory(root["THREE"]); +})(this, (__WEBPACK_EXTERNAL_MODULE_three__) => { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "./src/Binary.js" +/*!***********************!*\ + !*** ./src/Binary.js ***! + \***********************/ +(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ getFloat32: () => (/* binding */ getFloat32),\n/* harmony export */ getUint16: () => (/* binding */ getUint16),\n/* harmony export */ getUint32: () => (/* binding */ getUint32),\n/* harmony export */ getUint64: () => (/* binding */ getUint64),\n/* harmony export */ matInv: () => (/* binding */ matInv),\n/* harmony export */ matMul: () => (/* binding */ matMul),\n/* harmony export */ vecMul: () => (/* binding */ vecMul)\n/* harmony export */ });\n/* UTILITIES */\n \nfunction getUint64(view) {\n var s = 0;\n var lo = view.getUint32(view.offset, true);\n var hi = view.getUint32(view.offset + 4, true);\n view.offset += 8;\n return ((hi * (1 << 32)) + lo);\n}\n\nfunction getUint32(view) {\n var s = view.getUint32(view.offset, true);\n view.offset += 4;\n return s;\n}\n\nfunction getUint16(view) {\n var s = view.getUint16(view.offset, true);\n view.offset += 2;\n return s;\n}\n\nfunction getFloat32(view) {\n var s = view.getFloat32(view.offset, true);\n view.offset += 4;\n return s;\n}\n\n/* MATRIX STUFF */\n\nfunction vecMul(m, v, r) {\n var w = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15];\n\n r[0] = (m[0]*v[0] + m[4]*v[1] + m[8 ]*v[2] + m[12 ])/w;\n r[1] = (m[1]*v[0] + m[5]*v[1] + m[9 ]*v[2] + m[13 ])/w;\n r[2] = (m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14])/w;\n}\n\n\nfunction matMul(a, b, r) {\n r[ 0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];\n r[ 1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];\n r[ 2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];\n r[ 3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];\n\n r[ 4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];\n r[ 5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];\n r[ 6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];\n r[ 7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];\n\n r[ 8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];\n r[ 9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];\n r[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];\n r[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];\n\n r[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];\n r[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];\n r[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];\n r[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];\n}\n\nfunction matInv(m, t) {\n var s = 1.0/(\n m[12]* m[9]*m[6]*m[3]-m[8]*m[13]*m[6]*m[3]-m[12]*m[5]*m[10]*m[3]+m[4]*m[13]*m[10]*m[3]+\n m[8]*m[5]*m[14]*m[3]-m[4]*m[9]*m[14]*m[3]-m[12]*m[9]*m[2]*m[7]+m[8]*m[13]*m[2]*m[7]+\n m[12]*m[1]*m[10]*m[7]-m[0]*m[13]*m[10]*m[7]-m[8]*m[1]*m[14]*m[7]+m[0]*m[9]*m[14]*m[7]+\n m[12]*m[5]*m[2]*m[11]-m[4]*m[13]*m[2]*m[11]-m[12]*m[1]*m[6]*m[11]+m[0]*m[13]*m[6]*m[11]+\n m[4]*m[1]*m[14]*m[11]-m[0]*m[5]*m[14]*m[11]-m[8]*m[5]*m[2]*m[15]+m[4]*m[9]*m[2]*m[15]+\n m[8]*m[1]*m[6]*m[15]-m[0]*m[9]*m[6]*m[15]-m[4]*m[1]*m[10]*m[15]+m[0]*m[5]*m[10]*m[15]\n );\n\n t[ 0] = (m[9]*m[14]*m[7]-m[13]*m[10]*m[7]+m[13]*m[6]*m[11]-m[5]*m[14]*m[11]-m[9]*m[6]*m[15]+m[5]*m[10]*m[15])*s;\n t[ 1] = (m[13]*m[10]*m[3]-m[9]*m[14]*m[3]-m[13]*m[2]*m[11]+m[1]*m[14]*m[11]+m[9]*m[2]*m[15]-m[1]*m[10]*m[15])*s;\n t[ 2] = (m[5]*m[14]*m[3]-m[13]*m[6]*m[3]+m[13]*m[2]*m[7]-m[1]*m[14]*m[7]-m[5]*m[2]*m[15]+m[1]*m[6]*m[15])*s;\n t[ 3] = (m[9]*m[6]*m[3]-m[5]*m[10]*m[3]-m[9]*m[2]*m[7]+m[1]*m[10]*m[7]+m[5]*m[2]*m[11]-m[1]*m[6]*m[11])*s;\n\n t[ 4] = (m[12]*m[10]*m[7]-m[8]*m[14]*m[7]-m[12]*m[6]*m[11]+m[4]*m[14]*m[11]+m[8]*m[6]*m[15]-m[4]*m[10]*m[15])*s;\n t[ 5] = (m[8]*m[14]*m[3]-m[12]*m[10]*m[3]+m[12]*m[2]*m[11]-m[0]*m[14]*m[11]-m[8]*m[2]*m[15]+m[0]*m[10]*m[15])*s;\n t[ 6] = (m[12]*m[6]*m[3]-m[4]*m[14]*m[3]-m[12]*m[2]*m[7]+m[0]*m[14]*m[7]+m[4]*m[2]*m[15]-m[0]*m[6]*m[15])*s;\n t[ 7] = (m[4]*m[10]*m[3]-m[8]*m[6]*m[3]+m[8]*m[2]*m[7]-m[0]*m[10]*m[7]-m[4]*m[2]*m[11]+m[0]*m[6]*m[11])*s;\n\n t[ 8] = (m[8]*m[13]*m[7]-m[12]*m[9]*m[7]+m[12]*m[5]*m[11]-m[4]*m[13]*m[11]-m[8]*m[5]*m[15]+m[4]*m[9]*m[15])*s;\n t[ 9] = (m[12]*m[9]*m[3]-m[8]*m[13]*m[3]-m[12]*m[1]*m[11]+m[0]*m[13]*m[11]+m[8]*m[1]*m[15]-m[0]*m[9]*m[15])*s;\n t[10] = (m[4]*m[13]*m[3]-m[12]*m[5]*m[3]+m[12]*m[1]*m[7]-m[0]*m[13]*m[7]-m[4]*m[1]*m[15]+m[0]*m[5]*m[15])*s;\n t[11] = (m[8]*m[5]*m[3]-m[4]*m[9]*m[3]-m[8]*m[1]*m[7]+m[0]*m[9]*m[7]+m[4]*m[1]*m[11]-m[0]*m[5]*m[11])*s;\n\n t[12] = (m[12]*m[9]*m[6]-m[8]*m[13]*m[6]-m[12]*m[5]*m[10]+m[4]*m[13]*m[10]+m[8]*m[5]*m[14]-m[4]*m[9]*m[14])*s;\n t[13] = (m[8]*m[13]*m[2]-m[12]*m[9]*m[2]+m[12]*m[1]*m[10]-m[0]*m[13]*m[10]-m[8]*m[1]*m[14]+m[0]*m[9]*m[14])*s;\n t[14] = (m[12]*m[5]*m[2]-m[4]*m[13]*m[2]-m[12]*m[1]*m[6]+m[0]*m[13]*m[6]+m[4]*m[1]*m[14]-m[0]*m[5]*m[14])*s;\n t[15] = (m[4]*m[9]*m[2]-m[8]*m[5]*m[2]+m[8]*m[1]*m[6]-m[0]*m[9]*m[6]-m[4]*m[1]*m[10]+m[0]*m[5]*m[10])*s;\n}\n\nlet binary = { \n getUint64: getUint64,\n getUint32: getUint32,\n getUint16: getUint16,\n getFloat32: getFloat32,\n vecMul: vecMul,\n matMul: matMul,\n matInv: matInv\n}\n\n\n\n\n\n//# sourceURL=webpack://Nexus3D/./src/Binary.js?\n}"); + +/***/ }, + +/***/ "./src/Cache.js" +/*!**********************!*\ + !*** ./src/Cache.js ***! + \**********************/ +(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Cache: () => (/* binding */ Cache)\n/* harmony export */ });\n\nfunction powerOf2(n) {\n\treturn n && (n & (n - 1)) === 0;\n}\n\nvar targetError = 2.0; //error won't go lower than this if we reach it\nvar maxError = 15; //error won't go over this even if fps is low\nvar minFps = 15;\nvar maxPending = 3;\nvar maxBlocked = 3;\nvar maxReqAttempt = 2;\nvar maxCacheSize = 1024 *(1<<20); \nvar drawBudget = 5*(1<<20);\n\nfunction _Cache() {\n let t = this;\n t.cortopath = '.';\n\tt.frame = 0; //keep track of the time\n\n t.maxCacheSize = maxCacheSize;\n t.minFps = minFps;\n t.currentFps = 0;\n t.targetError = targetError;\n t.currentError = targetError;\n t.maxError = maxError;\n t.realError = 0;\n\n t.pending = 0;\n t.maxPending = 3;\n t.cacheSize = 0;\n t.candidates = []; //list of nodes to be loaded\n t.nodes = new Map(); //for each mesh a list of node ids.\n \n t.last_frametime = 0;\n t.frametime = 0;\n t.end_frametime = 0;\n\n t.debug = { \n verbose : false, //debug messages\n nodes : false, //color each node\n draw : false, //final rendering call disabled\n extract : false, //extraction disabled}\n }\n\n t.totswapped = 0; //in the last frame.\n t.swaprate = 0;\n t.lastupdate = performance.now();\n}\n\n_Cache.prototype = {\n getTargetError: function() { return this.targetError; },\n getMinFps: function() { return this.minFps; },\n setMinFps: function(fps) { this.minFps = fps; },\n getMaxCacheSize: function() { return this.maxCacheSize; },\n setMaxCacheSize: function(size) { this.maxCacheSize = size; },\n setTargetError: function(error) { this.targetError = error; },\n \n loadCorto: function() {\n let workerPath = this.cortopath + 'corto.worker.js'; \n try {\n workerPath = new URL(/* asset import */ Object(function webpackMissingModule() { var e = new Error(\"Cannot find module './corto.worker.js'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }()), __webpack_require__.b).href;\n } catch (e) {\n //reverrt to es if import.meta.url is not available\n }\n let corto = new Worker(workerPath);\n corto.requests = {};\n corto.count = 0;\n corto.postRequest = function(node) {\n corto.postMessage({ buffer: node.buffer, request:this.count, rgba_colors: true, short_index: true, short_normals: true});\n node.buffer = null;\n this.requests[this.count++] = node;\n }\n corto.onmessage = function(e) {\n var request = e.data.request;\n var node = this.requests[request];\n delete this.requests[request];\n node.model = e.data.model;\n node.cache.readyGeometryNode(node.mesh, node.id, node.model);\n };\n this.corto = corto;\n },\n\n \n beginFrame: function(fps) { //each context has a separate frame count.\n let c = this;\n c.frametime = performance.now();\n let elapsed = c.frametime - c.last_frametime;\n c.last_frametime = c.frametime;\n if(elapsed < 500)\n c.currentFps = 0.9*c.currentFps + 0.1*(1000/elapsed);\n\n fps = c.currentFps;\n\n\t c.frame++;\n\t c.candidates = [];\n\t if(fps && c.minFps) {\n\t\t c.currentFps = fps;\n\t\t const r = c.minFps/fps;\n\t\t if(r > 1.1)\n\t\t\t c.currentError *= 1.05;\n\t\t if(r < 0.9)\n\t\t\t c.currentError *= 0.95;\n\n\t\t c.currentError = Math.max(c.targetError, Math.min(c.maxError, c.currentError));\n\n\t } else\n\t\t c.currentError = c.targetError;\n\n\t c.rendered = 0;\n\t c.realError = 1e20;\n c.totswapped = 0;\n },\n\n endFrame: function() {\n\t this.update();\n },\n\n\n\n requestNode: function(mesh, id) {\n\t mesh.status[id] = 2; \n\n\t \n\t this.cacheSize += mesh.nsize[id];\n\t mesh.reqAttempt[id] = 0;\n\n\t\tif(!this.nodes.has(mesh))\n\t\t\tthis.nodes.set(mesh, new Set());\n\t\tthis.nodes.get(mesh).add(id);\n\n\t this.requestNodeGeometry(mesh, id);\n\t this.requestNodeTexture(mesh, id);\n },\n\n requestNodeGeometry: function(mesh, id) {\n\t\tthis.pending++;\n\t mesh.status[id]++;\n\t\tlet url = mesh.deepzoom ? mesh.baseurl + id + \".nxn\" : mesh.url;\n\t\tlet start = mesh.deepzoom ? 0 : mesh.noffsets[id];\n\t\tlet end = mesh.deepzoom ? 0 : mesh.noffsets[id+1];\n\t let request = mesh.georeq[id] = mesh.httpRequest(url,\n\t\t start,\n\t\t end, \n\t\t ()=>{\n delete mesh.georeq[id];\n this.loadNodeGeometry(request, mesh, id);\n\t\t\t\tthis.pending--;\n },\n\t\t ()=>{\n delete mesh.georeq[id];\n\t\t\t if(this.debug.verbose) console.log(\"Geometry request error!\");\n\t\t\t this.recoverNode(mesh, id, 0);\n\t\t\t\tthis.pending--;\n\t\t },\n\t\t ()=>{\n delete mesh.georeq[id];\n\t\t\t if(this.debug.verbose) console.log(\"Geometry request abort!\");\n\t\t\t this.removeNode(mesh, id);\n\t\t\t\tthis.pending--;\n\t\t },\n\t\t 'arraybuffer'\n );\n },\n\n requestNodeTexture: function(mesh, id) {\n\n\t if(!mesh.vertex.texCoord) return;\n\n\t let tex = mesh.patches[mesh.nfirstpatch[id]*3+2];\n\t mesh.texref[tex]++;\n\t mesh.status[id]++;\n\n\t\tlet url = mesh.deepzoom ? mesh.baseurl + tex + \".jpg\" : mesh.url;\n\t\tlet start = mesh.deepzoom ? 0 : mesh.textures[tex];\n\t\tlet end = mesh.deepzoom ? 0 : mesh.textures[tex+1];\n\t let request = mesh.texreq[tex] = mesh.httpRequest(url,\n\t\t start,\n\t\t end,\n\t\t ()=>{ \n delete mesh.texreq[tex];\n this.loadNodeTexture(request, mesh, id, tex); \n\n },\n\t\t ()=>{\n delete mesh.texreq[tex];\n\t\t \tif(this.debug.verbose) console.log(\"Texture request error!\");\n\t\t\t this.recoverNode(mesh, id, 1);\n\t\t },\n\t\t ()=>{\n delete mesh.texreq[tex];\n\t\t \tif(this.debug.verbose) console.log(\"Texture request abort!\");\n\t\t \tthis.removeNode(mesh, id);\n\t\t },\n\t\t 'blob'\n\t );\n },\n\n recoverNode: function(mesh, id, mode) {\n\t if(mesh.status[id] == 0) return;\n\n\t mesh.status[id]--;\n\n let t = this;\n\n\t if(mesh.reqAttempt[id] > maxReqAttempt) {\n\t\t if(this.debug.verbose) console.log(\"Max request limit for \" + m.url + \" node: \" + n);\n\t\t t.removeNode(mesh, id);\n\t\t return;\n\t }\n\n\t mesh.reqAttempt[id]++;\n\n\t switch (mode){\n\t\tcase 0:\n\t\t t.requestNodeGeometry(mesh, id);\n\t\t if(this.debug.verbose) console.log(\"Recovering geometry for \" + m.url + \" node: \" + n);\n\t\t break;\n\t\tcase 1:\n\t\t\tt.requestNodeTexture(mesh, id);\n\t\t\tif(this.debug.verbose) console.log(\"Recovering texture for \" + m.url + \" node: \" + n);\n\t\t\tbreak;\n\t }\n },\n\n loadNodeGeometry: function(request, mesh, id) {\n\t if(mesh.status[id] == 0) return;\n \n\t if(!mesh.compressed)\n\t\t this.readyGeometryNode(mesh, id, request.response);\n\t else {\n if(!this.corto) this.loadCorto();\n\t\t this.corto.postRequest( { mesh:mesh, id:id, buffer: request.response, cache: this });\n }\n },\n\n\n loadNodeTexture: function(request, mesh, id, texid) {\n if(mesh.status[id] == 0) {\n throw \"Should not load texture twice\";\n }\n\n\t let blob = request.response;\n let callback = (img) => {\n if(mesh.status[id] == 0) //call was aborted.\n return;\n mesh.createTexture(texid, img);\n\n\t\t mesh.status[id]--;\n\n if(mesh.status[id] == 2)\n this.readyNode(mesh, id);\n\t\t }\n\n if(typeof createImageBitmap != 'undefined') {\n\t\t\ttry {\n\t\t\t\tcreateImageBitmap(blob, { imageOrientation: 'flipY' }).then(callback);\n\t\t\t} catch(error) { //old version of firefox do not support options (but flip anyway)\n\t\t\t\tcreateImageBitmap(blob).then(callback);\n\t\t\t}\n\n } else { //fallback for IOS\n var urlCreator = window.URL || window.webkitURL;\n var img = document.createElement('img');\n img.onerror = function(e) { console.log(\"Texture loading error!\"); };\n img.src = urlCreator.createObjectURL(blob);\n \n img.onload = function() {\n urlCreator.revokeObjectURL(img.src);\n callback(img);\n }\n }\n },\n\n removeNode: function(mesh, id) {\n this.nodes.get(mesh).delete(id);\n\n if(mesh.status[id] == 0) {\n\t\t\tif(this.debug.verbose)\n\t\t\t\tconsole.log(\"Double remove due to abort.\");\n return; //TODO\n\t\t}\n\n\t mesh.status[id] = 0;\n\t if (id in mesh.georeq && mesh.georeq[id].readyState != 4) {\n mesh.georeq[id].abort();\n delete mesh.georeq[id];\n\t\t //this.pending--;\n\t }\n mesh.availableNodes--;\n this.cacheSize -= mesh.nsize[id];\n mesh.deleteNodeGeometry(id);\n\n\t if(!mesh.vertex.texCoord) return;\n\n\t const tex = mesh.patches[mesh.nfirstpatch[id]*3+2]; //TODO assuming one texture per node\n\n\t if (tex in mesh.texreq && mesh.texreq[tex].readyState != 4) {\n mesh.texreq[tex].abort();\n delete mesh.texreq[tex];\n }\n\n\t mesh.texref[tex]--;\n \tif(mesh.texref[tex] == 0) {\n mesh.deleteTexture(tex);\n }\n },\n\n readyGeometryNode: function(mesh, id, buffer) {\n if(mesh.status[id] == 0) //call was aborted\n return;\n const nv = mesh.nvertices[id];\n const nf = mesh.nfaces[id];\n\t let geometry = {};\n\n\t \n\t if(!mesh.corto) {\n\t\t geometry.index = new Uint16Array(buffer, nv*mesh.vsize, nf*3);\n geometry.position = new Float32Array(buffer, 0, nv*3);\n\n\t\t var off = nv*12;\n\t\t if(mesh.vertex.texCoord) {\n geometry.uv = new Float32Array(buffer, off, nv*2);\n off += nv*8;\n }\n if(mesh.vertex.normal) {\n\t\t\t\tgeometry.normal = new Int16Array(buffer, off, nv*3);\n off += nv*6;\n\t\t\t}\n\n if(mesh.vertex.color) {\n geometry.color = new Uint8Array(buffer, off, nv*4);\n off += nv*4;\n\t\t\t}\n\n\t\t\n\t } else {\n geometry = buffer;\n\t }\n\n\t //if(nf == 0)\n \t//\tscramble(nv, v, no, co);\n\n mesh.createNodeGeometry(id, geometry);\n\t mesh.status[id]--;\n\n\t if(mesh.status[id] == 2) {\n this.readyNode(mesh, id);\n\t }\n },\n\n //the node is finished, add to cache, and update counters\n readyNode: function(mesh, id) {\n\n\t mesh.status[id]--;\n if(mesh.status[id] != 1) throw \"A ready node should have status ==1\"\n\n\t\t\n\t\tmesh.reqAttempt[id] = 0;\n //this.pending--;\n mesh.createNode(id);\n\t\tmesh.availableNodes++;\n\n for(let callback of mesh.onUpdate)\n callback();\n this.update();\n },\n\n flush: function(mesh) {\n if(!this.nodes.has(mesh)) return;\n\n for(let id of this.nodes.get(mesh))\n this.removeNode(mesh, id);\n this.nodes.delete(mesh);\n }, \n\n update: function() {\n if(this.pending >= maxPending)\n return;\n\n //the best candidate has the highest error\n let best = null;\n for(let c of this.candidates) {\n if(c.mesh.status[c.id] == 0 && (!best || c.error > best.error)) \n best = c;\n\t }\n if(!best) return;\n\n\t// record amount of data transfer per second.\n /*\n let now = performance.now();\n if(Math.floor(now/1000) > Math.floor(this.lastupdate/1000)) { //new second\n this.swaprate = (this.totswapped/1000)/(now - this.lastupdate); //transfer in mb/s\n if(this.debug.verbose)\n console.log(\"Memory loaded in GPU: \", this.swaprate);\n this.totswapped = 0;\n this.lastupdate = now;\n }\n */\n \n \n //make room for new nodes!\n \n\t while(this.cacheSize > this.maxCacheSize) {\n let worst = null;\n \n //find node with smallest error in cache and remove it if worse than the best candidate.\n for(let [mesh, ids] of this.nodes) {\n for(let id of ids) {\n //we need to recompute the errors for the cache, as if not traversed doesn't get updated.\n let error = mesh.errors[id];\n let frame = mesh.frames[id];\n if( !worst || error < worst.error) {\n worst = { id: id, frame: frame, error: error, mesh: mesh }\n }\n }\n }\n if(!worst || worst.error >= best.error*0.9) {\n //(worst.frame + 30 >= best.frame && )) //dont' remove if the best candidate is not good enogh\n return;\n }\n\t\t this.removeNode(worst.mesh, worst.id);\n\t }\n this.totswapped += best.mesh.nsize[best.id];\n this.candidates = this.candidates.filter(e => e.mesh == best.mesh && e.id == best.id);\n \tthis.requestNode(best.mesh, best.id);\n\t this.update(); //try again.\n }\n};\n\nlet Cache = new _Cache;\n\n\n\n\n//# sourceURL=webpack://Nexus3D/./src/Cache.js?\n}"); + +/***/ }, + +/***/ "./src/Mesh.js" +/*!*********************!*\ + !*** ./src/Mesh.js ***! + \*********************/ +(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Mesh: () => (/* binding */ Mesh)\n/* harmony export */ });\n/* harmony import */ var _Binary_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Binary.js */ \"./src/Binary.js\");\n\n\n/* MESH DEFINITION */\nlet Debug = { verbose: true };\n\nlet glP = WebGLRenderingContext.prototype;\nlet attrGlMap = [glP.NONE, glP.BYTE, glP.UNSIGNED_BYTE, glP.SHORT, glP.UNSIGNED_SHORT, glP.INT, glP.UNSIGNED_INT, glP.FLOAT, glP.DOUBLE];\nlet attrSizeMap = [0, 1, 1, 2, 2, 4, 4, 4, 8];\n\n//All addresses in the file are n*256 so, 256 * 2^32 is the max size of a Nxs file \nvar padding = 256;\n\nlet Mesh = function(url) {\n var t = this;\n t.isReady = false;\n t.onLoad = [];\n t.onUpdate = [];\n t.reqAttempt = 0;\n t.georeq = {}; //keeps track of existing httprequests\n t.texreq = {};\n t.frame = 0; //last time this mesh was traversed in rendering.\n t.availableNodes = 0\n if(url)\n t.open(url);\n}\n\nMesh.prototype = {\n open: function(url) {\n let mesh = this;\n mesh.url = url;\n mesh.httpRequest(url,\n 0,\n 88,\n function() {\n if(Debug.verbose) console.log(\"Loading header for \" + mesh.url);\n let view = new DataView(this.response);\n view.offset = 0;\n mesh.reqAttempt++;\n const header = mesh.importHeader(view);\n if(!header) {\n if(Debug.verbose) console.log(\"Empty header!\");\n if(mesh.reqAttempt < maxReqAttempt) mesh.open(mesh.url + '?' + Math.random()); // BLINK ENGINE CACHE BUG PATCH\n return;\n }\n mesh.reqAttempt = 0;\n for(let i in header)\n mesh[i] = header[i];\n mesh.vertex = mesh.signature.vertex;\n mesh.face = mesh.signature.face;\n mesh.renderMode = mesh.face.index?[\"FILL\", \"POINT\"]:[\"POINT\"];\n mesh.compressed = (mesh.signature.flags & (2 | 4)); //meco or corto\n mesh.meco = (mesh.signature.flags & 2);\n mesh.corto = (mesh.signature.flags & 4);\n\n\t\t\t\tmesh.deepzoom = (mesh.signature.flags & 8);\n\t\t\t\tif(mesh.deepzoom)\n\t\t\t\t\tmesh.baseurl = url.substr(0, url.length -4) + '_files/';\n\n\n mesh.requestIndex();\n },\n function() { console.log(\"Open request error!\");},\n function() { console.log(\"Open request abort!\");}\n );\n },\n\n httpRequest: function(url, start, end, load, error, abort, type) {\n if(!type) type = 'arraybuffer';\n var r = new XMLHttpRequest();\n r.open('GET', url, true);\n r.responseType = type;\n\t\tif(end)\n\t\t\tr.setRequestHeader(\"Range\", \"bytes=\" + start + \"-\" + (end -1));\n r.onload = function(){\n switch (this.status){\n case 0:\n//\t\t\t\t\tconsole.log(\"0 response: server unreachable.\");//returned in chrome for local files\n\t\t\t\t\terror();\n\t\t\t\t\tbreak;\n case 206:\n//\t\t\t\t\tconsole.log(\"206 response: partial content loaded.\");\n load.bind(this)();\n break;\n case 200:\n//\t\t\t\t\tconsole.log(\"200 response: server does not support byte range requests.\");\n\t\t\t\t\tif(end == 0)\n\t\t\t\t\t\tload.bind(this)();\n\t\t\t\t\telse\n\t\t\t\t\t\terror();\n\t\t\t\t\tbreak;\n }\n };\n r.onerror = error;\n r.onabort = abort;\n r.send();\n return r;\n },\n\n requestIndex: function() {\n var mesh = this;\n var end = 88 + mesh.nodesCount*44 + mesh.patchesCount*12 + mesh.texturesCount*68;\n mesh.httpRequest(this.url,\n 88,\n end,\n function() { if(Debug.verbose) console.log(\"Loading index for \" + mesh.url); mesh.handleIndex(this.response); },\n function() { console.log(\"Index request error!\");},\n function() { console.log(\"Index request abort!\");}\n );\n },\n\n handleIndex: function(buffer) {\n let t = this;\n let view = new DataView(buffer);\n view.offset = 0;\n\n const n = t.nodesCount;\n\n t.noffsets = new Uint32Array(n);\n t.nvertices = new Uint32Array(n);\n t.nfaces = new Uint32Array(n);\n t.nerrors = new Float32Array(n);\n t.nspheres = new Float32Array(n*5);\n t.nsize = new Float32Array(n);\n t.nfirstpatch = new Uint32Array(n);\n\n for(let i = 0; i < n; i++) {\n t.noffsets[i] = padding*(0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view); //offset\n t.nvertices[i] = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint16)(view); //verticesCount\n t.nfaces[i] = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint16)(view); //facesCount\n t.nerrors[i] = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getFloat32)(view);\n view.offset += 8; //skip cone\n for(let k = 0; k < 5; k++)\n t.nspheres[i*5+k] = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getFloat32)(view); //sphere + tight\n t.nfirstpatch[i] = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view); //first patch\n }\n t.sink = n -1;\n\n t.patches = new Uint32Array(view.buffer, view.offset, t.patchesCount*3); //noded, lastTriangle, texture\n t.nroots = t.nodesCount;\n for(let j = 0; j < t.nroots; j++) {\n for(let i = t.nfirstpatch[j]; i < t.nfirstpatch[j+1]; i++) {\n if(t.patches[i*3] < t.nroots)\n t.nroots = t.patches[i*3];\n }\n }\n\n view.offset += t.patchesCount*12;\n\n t.textures = new Uint32Array(t.texturesCount);\n t.texref = new Uint32Array(t.texturesCount);\n for(let i = 0; i < t.texturesCount; i++) {\n t.textures[i] = padding*(0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view);\n view.offset += 16*4; //skip proj matrix\n }\n\n t.vsize = 12 + (t.vertex.normal?6:0) + (t.vertex.color?4:0) + (t.vertex.texCoord?8:0);\n t.fsize = 6;\n\n //problem: I have no idea how much space a texture is needed in GPU. 10x factor assumed.\n let tmptexsize = new Uint32Array(n-1);\n let tmptexcount = new Uint32Array(n-1);\n for(let i = 0; i < n-1; i++) {\n for(let p = t.nfirstpatch[i]; p != t.nfirstpatch[i+1]; p++) {\n let tex = t.patches[p*3+2];\n tmptexsize[i] += t.textures[tex+1] - t.textures[tex];\n tmptexcount[i]++;\n }\n t.nsize[i] = t.vsize*t.nvertices[i] + t.fsize*t.nfaces[i];\n }\n for(let i = 0; i < n-1; i++) {\n t.nsize[i] += 10*tmptexsize[i]/tmptexcount[i];\n }\n\n t.status = new Uint8Array(n); //0 for none, 1 for ready, 2+ for waiting data\n t.frames = new Uint32Array(n);\n t.errors = new Float32Array(n); //biggest error of instances\n t.reqAttempt = new Uint8Array(n);\n \n t.isReady = true;\n for(let callback of t.onLoad)\n callback(this);\n },\n\n importAttribute: function(view) {\n let a = {};\n a.type = view.getUint8(view.offset++, true);\n a.size = view.getUint8(view.offset++, true);\n a.glType = attrGlMap[a.type];\n a.normalized = a.type < 7;\n a.stride = attrSizeMap[a.type]*a.size;\n if(a.size == 0) return null;\n return a;\n },\n\n importElement: function(view) {\n let e = [];\n for(let i = 0; i < 8; i++)\n e[i] = this.importAttribute(view);\n return e;\n },\n\n importVertex: function(view) {\t//enum POSITION, NORMAL, COLOR, TEXCOORD, DATA0\n const e = this.importElement(view);\n let color = e[2];\n if(color) {\n color.type = 2; //unsigned byte\n color.glType = attrGlMap[2];\n }\n return { position: e[0], normal: e[1], color: e[2], texCoord: e[3], data: e[4] };\n },\n\n //enum INDEX, NORMAL, COLOR, TEXCOORD, DATA0\n importFace: function(view) {\n const e = this.importElement(view);\n let color = e[2];\n if(color) {\n color.type = 2; //unsigned byte\n color.glType = attrGlMap[2];\n }\n return { index: e[0], normal: e[1], color: e[2], texCoord: e[3], data: e[4] };\n },\n\n importSignature: function(view) {\n let s = {};\n s.vertex = this.importVertex(view);\n s.face = this.importFace(view);\n s.flags = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view);\n return s;\n },\n\n importHeader: function(view) {\n const magic = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view);\n if(magic != 0x4E787320) return null;\n let h = {};\n h.version = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view);\n h.verticesCount = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint64)(view);\n h.facesCount = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint64)(view);\n h.signature = this.importSignature(view);\n h.nodesCount = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view);\n h.patchesCount = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view);\n h.texturesCount = (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getUint32)(view);\n h.sphere = {\n center: [(0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getFloat32)(view), (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getFloat32)(view), (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getFloat32)(view)],\n radius: (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.getFloat32)(view)\n };\n return h;\n },\n //OVERRIDE THESE METHOS\n\n //assemble node and geometry\n createNode: function(id) {},\n\n createNodeGeometry: function(id, data) {},\n deleteNodeGeometry: function(id) {},\n\n createTexture: function(id, image) {},\n deleteTexture: function(id) {},\n};\n\n\n\n\n\n//# sourceURL=webpack://Nexus3D/./src/Mesh.js?\n}"); + +/***/ }, + +/***/ "./src/Nexus3D.js" +/*!************************!*\ + !*** ./src/Nexus3D.js ***! + \************************/ +(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Cache: () => (/* reexport safe */ _Cache_js__WEBPACK_IMPORTED_MODULE_3__.Cache),\n/* harmony export */ Nexus3D: () => (/* binding */ Nexus3D)\n/* harmony export */ });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"three\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(three__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _Traversal_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Traversal.js */ \"./src/Traversal.js\");\n/* harmony import */ var _Mesh_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Mesh.js */ \"./src/Mesh.js\");\n/* harmony import */ var _Cache_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Cache.js */ \"./src/Cache.js\");\n\n\n\n\n\nclass Nexus3D extends three__WEBPACK_IMPORTED_MODULE_0__.Mesh {\n\n\tconstructor(url, renderer, options = {}) {\n\n\t\tsuper();\n\n\t\tthis.patchWebGLRenderer(renderer);\n\n\t\tObject.assign(this, {\n\t\t\tisNXS: true,\n\t\t\ttype:'NXS',\n\t\t\turl: url,\n\t\t\tgl: renderer.getContext(),\n\t\t\tXRMode: false, //set to true to avoid flickering due to double eye rendering.\n\t\t\tmaterial: null,\n\n\t\t\tautoUpdate: true,\n\t\t\tmesh: new _Mesh_js__WEBPACK_IMPORTED_MODULE_2__.Mesh(),\n\t\t\tvbo: [],\n\t\t\tibo: [],\n\t\t\tvao: [],\n\t\t\ttextures: [],\n\t\t\tattributes: {}, //here we store the uniform attributes of the shader.\n\n\t\t\tbasemesh: null, //highest level of the nexus, for picking\n\t\t});\n\n\t\tif('material' in options)\n\t\t\tthis.material = options.material;\n\t\tif(!this.material) \n\t\t\tthis.material = new three__WEBPACK_IMPORTED_MODULE_0__.MeshStandardMaterial();\n\t\t\t\n\t\tfor(let call of ['onLoad', 'onUpdate', 'onProgress']) {\n\t\t\tthis['_' + call] = [];\n\t\t\tif(call in options)\n\t\t\t\tthis['_' + call].push(options[call])\n\t\t}\n\n\t\tif(this.url) {\n\t\t\tif(typeof url == 'object') {\n\t\t\t\tthis.nxs = this.url;\n\t\t\t\tthis.nxs.onLoad.push((m) => { \n\t\t\t\t\tthis.mesh = this.nxs.mesh;\n\t\t\t\t\tthis.traversal = this.nxs.traversal;\n\t\t\t\t\tthis.cache = this.nxs.cache;\n\t\t\t\t\tthis.vbo = this.nxs.vbo;\n\t\t\t\t\tthis.ibo = this.nxs.ibo;\n\t\t\t\t\tthis.vao = this.nxs.vao;\n\t\t\t\t\tthis.textures = this.nxs.textures;\n\t\t\t\t\tthis.onLoadCallback(this); \n\t\t\t\t});\n\t\t\t} else\n\t\t\t\tthis.open(this.url);\n\t\t}\n\t}\n\n\tcopy(source) {\n\t\tthree__WEBPACK_IMPORTED_MODULE_0__.Object3D.prototype.copy.call(this, source, false);\n\t\tthrow new Error(\"Can't really copy a Nexus3D object.\");\n\t\t// removed by dead control flow\n\n\t}\n\n\t\n\topen(url) {\n\t\tlet t = this;\n\t\tthis.mesh.open(url);\n\t\tthis.mesh.createNode = (id) => { };\n\t\tthis.mesh.createNodeGeometry = (id, geometry) => { t.createNodeGeometry(id, geometry); };\n\t\tthis.mesh.createTexture = (id, image) => { t.createTexture(id, image); };\n\t\tthis.mesh.deleteNodeGeometry = (id) => { t.deleteNodeGeometry(id); };\n\t\tthis.mesh.deleteTexture = (id) => { t.deleteTexture(id); };\n\t\tthis.mesh.onLoad.push(() => { t.onLoadCallback(); });\n\t\tthis.mesh.onUpdate.push(() => { \n\t\t\tfor(let callback of t._onUpdate) callback(this); \n\t\t\tfor(let callback of t._onProgress) callback(this, this.mesh.availableNodes, this.mesh.nodesCount); \n\t\t});\n\n\t\tthis.traversal = new _Traversal_js__WEBPACK_IMPORTED_MODULE_1__.Traversal();\n\t\tthis.cache = _Cache_js__WEBPACK_IMPORTED_MODULE_3__.Cache; //new Cache();\n\t\tthis.textures = {}; \n\t}\n\n\tset onLoad(callback) {\n\t\tthis._onLoad.push(callback);\n\t}\n\n\tset onUpdate(callback) {\n\t\tthis._onUpdate.push(callback);\n\t}\n\n\tset onProgress(callback) {\n\t\tthis._onProgress.push(callback);\n\t}\n\n\t//TODO this is not really needed, we might just conform to THREEJS standard of updating.\n\t/*set material(material) {\n\t\tthis.material = material;\n\t\tthis.material.needsUpdate = true;\n\t}*/\n\t\n\tupdateMaterials() {\n\t\tif(this.material.map !== false && this.mesh.vertex.texCoord)\n\t\t\tthis.material.map = this.material_texture;\n\n\t\tif(this.mesh.vertex.color)\n\t\t\tthis.material.vertexColors = true; \n\t\tthis.material.needsUpdate = true; \n\t}\n\n\tonLoadCallback() {\n\t\tconst c = this.mesh.sphere.center;\n\t\tconst center = new three__WEBPACK_IMPORTED_MODULE_0__.Vector3(c[0], c[1], c[2]);\n\t\tconst radius = this.mesh.sphere.radius;\n\t\tthis.boundingSphere = new three__WEBPACK_IMPORTED_MODULE_0__.Sphere(center, radius);\n\n\t\tvar geometry = new three__WEBPACK_IMPORTED_MODULE_0__.BufferGeometry();\n\n\t\tgeometry.setAttribute( 'position', new three__WEBPACK_IMPORTED_MODULE_0__.BufferAttribute(new Float32Array(3), 3));\n\t\t\n\t\tif(this.mesh.vertex.normal)\n\t\t\tgeometry.setAttribute( 'normal', new three__WEBPACK_IMPORTED_MODULE_0__.BufferAttribute(new Float32Array(3), 3));\n\t\tif(this.mesh.vertex.color)\n\t\t\tgeometry.setAttribute( 'color', new three__WEBPACK_IMPORTED_MODULE_0__.BufferAttribute(new Float32Array(4), 4));\n\t\tif(this.mesh.vertex.texCoord)\n\t\t\tgeometry.setAttribute( 'uv', new three__WEBPACK_IMPORTED_MODULE_0__.BufferAttribute(new Float32Array(2), 2));\n\n\t\tif(this.mesh.vertex.texCoord) {\n\t\t\tthis.material_texture = new three__WEBPACK_IMPORTED_MODULE_0__.DataTexture( new Uint8Array([1, 1, 1, 1]), 1, 1, three__WEBPACK_IMPORTED_MODULE_0__.RGBAFormat );\n\t\t\tthis.material_texture.needsUpdate = true;\n\t\t}\n\n\t\tthis.updateMaterials();\n\t\tthis.geometry = geometry;\n\t\t\n\t\tthis.frustumCulled = false;\n\t\t\t\n\t\tfor(let callback of this._onLoad)\n\t\t\tcallback(this);\n\t}\n\n\trenderBufferDirect(renderer, scene, camera, geometry, material, group) {\n\t\tlet s = new three__WEBPACK_IMPORTED_MODULE_0__.Vector4();\n\t\trenderer.getViewport(s);\n\n\t \t//object modelview is multiplied by camera during rendering, we need to do it here for visibility computations\n\t\tthis.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, this.matrixWorld );\n\t\tif(s.x == 0 || !this.XRMode) { //hack to only traverse on the left eye\n\t\t\tthis.traversal.updateView(s, camera.projectionMatrix.elements, this.modelViewMatrix.elements);\n\t\t\tthis.instance_errors = this.traversal.traverse(this.mesh, this.cache);\n\t\t}\n\t\t//threejs increments version when setting neeedsUpdate\n\t\t/*if(this.material.version > 0) {\n\t\t\tthis.updateMaterials();\n\t\t\tthis.material.version = 0;\n\t\t\tfor(let callback of this.onUpdate) \n\t\t\t\tcallback(this); \n\t\t}*/\n\t\tlet gl = this.gl;\n\t\tlet program = gl.getParameter(gl.CURRENT_PROGRAM);\n\n\t\t//TODO these calls could be cached saving attrs per each material.\n\t\tlet attr = this.attributes;\n\t\tattr.position = gl.getAttribLocation(program, \"position\");\n\t\tattr.normal = gl.getAttribLocation(program, \"normal\");\n\t\tattr.color = gl.getAttribLocation(program, \"color\");\n\t\tattr.uv = gl.getAttribLocation(program, \"uv\");\n\t\tattr.size = gl.getUniformLocation(program, \"size\");\n\t\tattr.scale = gl.getUniformLocation(program, \"scale\");\n\n\t\tlet map_location = gl.getUniformLocation(program, \"map\"); \n\t\tattr.map = map_location ? gl.getUniform(program, map_location) : null;\n\t\t\n\t\n\t\t//hack to detect if threejs using point or triangle shaders\n\t\t//instance.mode = attr.size ? \"POINT\" : \"FILL\";\n\t\t//if(attr.size != -1) \n\t\t// instance.pointsize = material.size;\n\t\n\t\t//can't find docs or code on how material.scale is computed in threejs.\n\t\t//if(attr.scale != -1)\n\t\t// instance.pointscale = 2.0;\n\n\t\tthis.setVisibility();\n\t}\n\n\tsetVisibility() {\n\t\t//set visibile what is visible!\n\t\tlet t = this.traversal;\n\t\tlet m = this.mesh;\n\t\n\t\tif(!m.isReady)\n\t\t\treturn;\n\t\tlet rendered = 0;\n\t\t\n\t\tlet attr = this.attributes;\n\t\tlet mesh = this.mesh;\n\t\tlet gl = this.gl;\n\t\tlet gl2 = gl instanceof WebGL2RenderingContext;\n\t\tlet state = attr.uv + 10*attr.color + 100*attr.normal;\n\t\t\t\n\t\tfor(let id = 0; id < m.nodesCount; id++) {\n// let err = m.nerrors[id];\n\n\t\t\tif(!t.selected[id]) continue;\n\n\t\t\t//check for children: if all are selected, bail out.\n\t\t\t{\n\t\t\t\tlet visible = false;\n\t\t\t\tlet offset = 0;\n\t\t\t\tlet end = 0;\n\t\t\t\tlet last = m.nfirstpatch[id+1]-1;\n\t\t\t\tfor (var p = m.nfirstpatch[id]; p < m.nfirstpatch[id+1]; ++p) {\n\t\t\t\t\tvar child = m.patches[p*3];\n\t\n\t\t\t\t\tif(!t.selected[child]) {\n\t\t\t\t\t\tvisible = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(!visible) continue;\n\t\t\t}\n\n\t\t\tvar sp = m.nspheres;\n\t\t\tvar off = id*5;\n\t\t\tif(!t.isVisible(sp[off], sp[off+1], sp[off+2], sp[off+4])) //tight radius\n\t\t\t\tcontinue;\n\t\n\t\t\tlet doBind = true;\n\n\t\t\tif(gl2) {\n\t\t\t\tif(state in this.vao[id])\n\t\t\t\t\tdoBind = false;\n\t\t\t\telse\n\t\t\t\t\tthis.vao[id][state] = gl.createVertexArray();\n\t\t\t\t\t\n\t\t\t \tgl.bindVertexArray(this.vao[id][state]);\n\t\t\t}\n\t\t\t\n\t\t\tif(doBind) { \n\t\t\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this.vbo[id]);\n\t\t\t \tgl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ibo[id]);\n\t\n\t\t\t\tgl.vertexAttribPointer(attr.position, 3, gl.FLOAT, false, 12, 0);\n\t\t\t\tgl.enableVertexAttribArray(attr.position);\n\t\n\t\t\t\tlet nv = this.mesh.nvertices[id];\n\t\t\t\tlet offset = nv*12;\n\t\n\t\t\t\tif(mesh.vertex.texCoord) {\n\t\t\t\t\tif(attr.uv >= 0) {\n\t\t\t\t\t\tgl.vertexAttribPointer(attr.uv, 2, gl.FLOAT, false, 8, offset);\n\t\t\t\t\t\tgl.enableVertexAttribArray(attr.uv);\n\t\t\t\t\t}\n\t\t\t\t\toffset += nv*8;\n\t\t\t\t}\n\t\t\t\tif(mesh.vertex.color) {\n\t\t\t\t\tif(attr.color >= 0) {\n\t\t\t\t\t\tgl.vertexAttribPointer(attr.color, 4, gl.UNSIGNED_BYTE, true, 4, offset);\n\t\t\t\t\t\tgl.enableVertexAttribArray(attr.color);\n\t\t\t\t\t}\n\t\t\t\t\toffset += nv*4;\n\t\t\t\t}\n\t\t\t\tif(mesh.vertex.normal) {\n\t\t\t\t\tif(attr.normal >= 0) {\n\t\t\t\t\t\tgl.vertexAttribPointer(attr.normal, 3, gl.SHORT, true, 6, offset);\n\t\t\t\t\t\tgl.enableVertexAttribArray(attr.normal);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(this.cache.debug.nodes) {\n\t\t\t\t\tgl.disableVertexAttribArray(attr.color);\n\n\t\t\t\t\tvar error = this.instance_errors[id]; //this.mesh.errors[id];\n\t\t\t\t\tvar palette = [\n\t\t\t\t\t\t[1, 1, 1, 1], //white\n\t\t\t\t\t\t[1, 1, 1, 1], //white\n\t\t\t\t\t\t[0, 1, 0, 1], //green\n\t\t\t\t\t\t[0, 1, 1, 1], //cyan\n\t\t\t\t\t\t[1, 1, 0, 1], //yellow\n\t\t\t\t\t\t[1, 0, 1, 1], //magenta\n\t\t\t\t\t\t[1, 0, 0, 1] //red\n\t\t\t\t\t];\n\t\t\t\t\tlet w = Math.min(5.99, Math.max(0, Math.log2(error)/2));\n\t\t\t\t\tlet low = Math.floor(w);\n\t\t\t\t\tw -= low;\n\t\t\t\t\tlet color = [];\n\t\t\t\t\tfor( let k = 0; k < 4; k++)\n\t\t\t\t\t\tcolor[k] = palette[low][k]*(1-w) + palette[low+1][k]*w;\n\t\t\t\t\t\n\t\t\t\t\tgl.vertexAttrib4fv(attr.color, color);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.cache.realError = Math.min(this.mesh.errors[id], this.cache.realError);\n\t\t\t\n\t\t\tlet offset = 0;\n\t\t\tlet end = 0;\n\t\t\tlet last = m.nfirstpatch[id+1]-1;\n\t\t\tfor (let p = m.nfirstpatch[id]; p < m.nfirstpatch[id+1]; ++p) {\n\t\t\t\tlet child = m.patches[p*3];\n\t\n\t\t\t\tif(!t.selected[child]) {\n\t\t\t\t\tend = m.patches[p*3+1];\n\t\t\t\t\tif(p < last) //we join patches if possible.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif(end > offset) {\n\t\t\t\t\tif(m.vertex.texCoord && attr.uv >= 0) {\n\t\t\t\t\t\tvar tex = m.patches[p*3+2];\n\t\t\t\t\t\tif(tex != -1) { //bind texture\n\t\t\t\t\t\t\tvar texid = this.textures[tex];\n\t\t\t\t\t\t\tgl.activeTexture(gl.TEXTURE0 + attr.map);\n\t\t\t\t\t\t\tgl.bindTexture(gl.TEXTURE_2D, texid);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlet mode = this.material.wireframe ? gl.LINE_STRIP : gl.TRIANGLES;\n\n\t\t\t\t\tgl.drawElements(mode, (end - offset) * 3, gl.UNSIGNED_SHORT, offset * 6);\n\t\t\t\t\trendered += end - offset;\n\t\t\t\t}\n\t\t\t\toffset = m.patches[p*3+1];\n\t\t\t}\n\t\t}\n\t\tthis.cache.rendered += rendered;\n\t}\n\n\tcreateNodeGeometry(id, data) {\n\t\tlet m = this.mesh;\n\t\tvar nv = m.nvertices[id];\n\t\tvar nf = m.nfaces[id];\n\t\tlet indices = data.index;\n\t\tlet vertices = new ArrayBuffer(nv*m.vsize);\n\t\tvar position = new Float32Array(vertices, 0, nv*3);\n\t\tposition.set(data.position);\n\t\tvar off = nv*12;\n\t\tif(m.vertex.texCoord) {\n\t\t\tvar uv = new Float32Array(vertices, off, nv*2);\n\t\t\tuv.set(data.uv);\n\t\t\toff += nv*8;\n\t\t}\n\t\tif(m.vertex.color) {\n\t\t\tvar color = new Uint8Array(vertices, off, nv*4);\n\t\t\tcolor.set(data.color);\n\t\t\toff += nv*4;\n\t\t}\n\t\tif(m.vertex.normal) {\n\t\t\tvar normal = new Int16Array(vertices, off, nv*3);\n\t\t\tnormal.set(data.normal);\n\t\t\toff += nv*6;\n\t\t}\n\t\t\n\t\t//needed for approximate picking.\n\t\tif(id < this.mesh.nroots) {\n\t\t\tlet basegeometry = new three__WEBPACK_IMPORTED_MODULE_0__.BufferGeometry();\n\t\t\tbasegeometry.setAttribute( 'position', new three__WEBPACK_IMPORTED_MODULE_0__.BufferAttribute(data.position, 3 ) );\n\t\t\tbasegeometry.setAttribute( 'normal', new three__WEBPACK_IMPORTED_MODULE_0__.BufferAttribute(data.normal, 3 ) );\n\t\t\tbasegeometry.setIndex(new three__WEBPACK_IMPORTED_MODULE_0__.BufferAttribute( data.index, 1 ) );\n\n\t\t\tthis.basemesh = new three__WEBPACK_IMPORTED_MODULE_0__.Mesh(basegeometry, this.material);\n\t\t\tthis.basemesh.visible = false;\n\t\t\tthis.add(this.basemesh);\n\t\t}\n\t\t\n\t\tvar gl = this.gl\n\t\tthis.vao[id] = {}; //one for each attrib combination in use (casting shadows for example).\n\t\tgl.bindVertexArray(null);\n\t\t\n\t\tvar vbo = this.vbo[id] = gl.createBuffer();\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, vbo);\n\t\tgl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\t\tvar ibo = this.ibo[id] = gl.createBuffer();\n\t\tgl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);\n\t\tgl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);\n\t}\n\n\tcreateTexture(id, image) {\n\t\tlet gl = this.gl;\n\t\tvar flip = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);\n\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n\t\tlet tex = this.textures[id] = gl.createTexture();\n\t\tgl.bindTexture(gl.TEXTURE_2D, tex);\n\n\t\t//TODO some textures might be alpha only! save space\n\t\tlet internalFormat;\n\t\tif (this.material && this.material.map && this.material.map.colorSpace === three__WEBPACK_IMPORTED_MODULE_0__.LinearSRGBColorSpace) {\n\t\t\tinternalFormat = gl.RGBA;\n\t\t} else if (typeof gl.SRGB8_ALPHA8 !== 'undefined') {\n\t\t\tinternalFormat = gl.SRGB8_ALPHA8;\n\t\t} else {\n\t\t\tinternalFormat = gl.RGBA;\n\t\t}\n\t\tgl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, gl.RGBA, gl.UNSIGNED_BYTE, image);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n\t\tfunction powerOf2(n) { return n && (n & (n - 1)) === 0; }\n\t\tif(!(gl instanceof WebGLRenderingContext) || (powerOf2(image.width) && powerOf2(image.height))) {\n\t\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);\n\t\t\tgl.generateMipmap(gl.TEXTURE_2D);\n\t\t} else {\n\t\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\t\t}\n\n\t\tgl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip); \n\t}\n\t//schedule for removal of this node( might not want to delete it in the middle of something.\n\t//TODO check if this is really needed!\n\tdeleteNodeGeometry(id) {\n\t\tthis.gl.deleteBuffer(this.vbo[id]);\n\t\tthis.gl.deleteBuffer(this.ibo[id]);\n\n\t\tthis.vbo[id] = this.ibo[id] = null;\n\t\tif(this.vao[id]) //node might have been loaded and unloaded before a rendering\n\t\t\tfor(const [state, vao] of Object.entries(this.vao[id]))\n\t\t\t\tthis.gl.deleteVertexArray(vao);\n\t\tthis.vao[id] = null;\n\t}\n\n\tdeleteTexture(tex) {\n\t\tif(!this.textures[tex])\n\t\t\treturn;\n\t\t//\tthrow \"Deleting missing texture!\"\n\n\t\tthis.gl.deleteTexture(this.textures[tex]);\n\t\tthis.textures[tex] = 0;\n\t}\n\n\tflush() {\n\t\tthis.cache.flush(this.mesh);\n\t}\n\n\tdispose() {\n\t\tthis.flush();\n\t\tfor(let child of this.children)\n\t\t\tchild.geometry.dispose();\n\t}\n\n\ttoJSON(meta) {\n\t\tthrow new Error(\"Can't convert to json.\");\n\t}\n\n\tpatchWebGLRenderer(renderer) {\n\t\tif(renderer.nexusPatched) return;\n\t\tlet f = renderer.renderBufferDirect;\n\t\trenderer.renderBufferDirect = ( camera, scene, geometry, material, object, group) => { \n\t\t\tf( camera, scene, geometry, material, object, group );\n\t\t\tif ( object.renderBufferDirect)\n\t\t\t\tobject.renderBufferDirect(renderer, scene, camera, geometry, material, group);\n\t\t};\n\t\trenderer.originalRender = renderer.render;\n\t\trenderer.render = (scene, camera) => {\n\t\t\t_Cache_js__WEBPACK_IMPORTED_MODULE_3__.Cache.beginFrame(30);\n\t\t\trenderer.originalRender(scene, camera);\n\t\t\t_Cache_js__WEBPACK_IMPORTED_MODULE_3__.Cache.endFrame();\n\t\t}\n\t\trenderer.nexusPatched = true;\n\t} \n\n}\n\n\n\n\n\n\n\n//# sourceURL=webpack://Nexus3D/./src/Nexus3D.js?\n}"); + +/***/ }, + +/***/ "./src/PriorityQueue.js" +/*!******************************!*\ + !*** ./src/PriorityQueue.js ***! + \******************************/ +(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PriorityQueue: () => (/* binding */ PriorityQueue)\n/* harmony export */ });\n \n function PriorityQueue(max_length) {\n this.error = new Float32Array(max_length);\n this.data = new Int32Array(max_length);\n this.size = 0;\n}\n\nPriorityQueue.prototype = {\n push: function(data, error) {\n this.data[this.size] = data;\n this.error[this.size] = error;\n this.bubbleUp(this.size);\n this.size++;\n },\n\n pop: function() {\n var result = this.data[0];\n this.size--;\n if(this.size > 0) {\n this.data[0] = this.data[this.size];\n this.error[0] = this.error[this.size];\n this.sinkDown(0);\n }\n return result;\n },\n\n bubbleUp: function(n) {\n var data = this.data[n];\n var error = this.error[n];\n while (n > 0) {\n var pN = ((n+1)>>1) -1;\n var pError = this.error[pN];\n if(pError > error)\n break;\n //swap\n this.data[n] = this.data[pN];\n this.error[n] = pError;\n this.data[pN] = data;\n this.error[pN] = error;\n n = pN;\n }\n },\n\n sinkDown: function(n) {\n var data = this.data[n];\n var error = this.error[n];\n\n while(true) {\n var child2N = (n + 1) * 2;\n var child1N = child2N - 1;\n var swap = -1;\n if (child1N < this.size) {\n var child1Error = this.error[child1N];\n if(child1Error > error)\n swap = child1N;\n }\n if (child2N < this.size) {\n var child2Error = this.error[child2N];\n if (child2Error > (swap == -1 ? error : child1Error))\n swap = child2N;\n }\n\n if (swap == -1) break;\n\n this.data[n] = this.data[swap];\n this.error[n] = this.error[swap];\n this.data[swap] = data;\n this.error[swap] = error;\n n = swap;\n }\n }\n};\n\n\n\n\n\n\n//# sourceURL=webpack://Nexus3D/./src/PriorityQueue.js?\n}"); + +/***/ }, + +/***/ "./src/Traversal.js" +/*!**************************!*\ + !*** ./src/Traversal.js ***! + \**************************/ +(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Traversal: () => (/* binding */ Traversal)\n/* harmony export */ });\n/* harmony import */ var _Binary_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Binary.js */ \"./src/Binary.js\");\n/* harmony import */ var _PriorityQueue_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./PriorityQueue.js */ \"./src/PriorityQueue.js\");\n\n\n\nfunction Traversal() {\n let t = this;\n t.maxBlocked = 30;\n\n t.modelMatrix = new Float32Array(16);\n t.viewMatrix = new Float32Array(16);\n t.projectionMatrix = new Float32Array(16);\n t.modelView = new Float32Array(16);\n t.modelViewInv = new Float32Array(16);\n t.modelViewProj = new Float32Array(16);\n t.modelViewProjInv = new Float32Array(16);\n t.planes = new Float32Array(24);\n t.viewport = new Float32Array(4);\n t.viewpoint = new Float32Array(4);\n}\n\nTraversal.prototype = {\n updateView: function(viewport, projection, modelView) {\n let t = this;\n\n for(let i = 0; i < 16; i++) {\n t.projectionMatrix[i] = projection[i];\n t.modelView[i] = modelView[i];\n }\n for(let i = 0; i < 4; i++)\n t.viewport[i] = viewport[i];\n\n (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.matMul)(t.projectionMatrix, t.modelView, t.modelViewProj);\n (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.matInv)(t.modelViewProj, t.modelViewProjInv);\n\n (0,_Binary_js__WEBPACK_IMPORTED_MODULE_0__.matInv)(t.modelView, t.modelViewInv);\n t.viewpoint[0] = t.modelViewInv[12];\n t.viewpoint[1] = t.modelViewInv[13];\n t.viewpoint[2] = t.modelViewInv[14];\n t.viewpoint[3] = 1.0;\n\n\n const m = t.modelViewProj;\n const mi = t.modelViewProjInv;\n let p = t.planes;\n\n //frustum planes Ax + By + Cz + D = 0;\n p[0] = m[0] + m[3]; p[1] = m[4] + m[7]; p[2] = m[8] + m[11]; p[3] = m[12] + m[15]; //left\n p[4] = -m[0] + m[3]; p[5] = -m[4] + m[7]; p[6] = -m[8] + m[11]; p[7] = -m[12] + m[15]; //right\n p[8] = m[1] + m[3]; p[9] = m[5] + m[7]; p[10] = m[9] + m[11]; p[11] = m[13] + m[15]; //bottom\n p[12] = -m[1] + m[3]; p[13] = -m[5] + m[7]; p[14] = -m[9] + m[11]; p[15] = -m[13] + m[15]; //top\n p[16] = -m[2] + m[3]; p[17] = -m[6] + m[7]; p[18] = -m[10] + m[11]; p[19] = -m[14] + m[15]; //near\n p[20] = -m[2] + m[3]; p[21] = -m[6] + m[7]; p[22] = -m[10] + m[11]; p[23] = -m[14] + m[15]; //far\n\n //normalize planes to get also correct distances\n for(let i = 0; i < 24; i+= 4) {\n let l = Math.sqrt(p[i]*p[i] + p[i+1]*p[i+1] + p[i+2]*p[i+2]);\n p[i] /= l; p[i+1] /= l; p[i+2] /= l; p[i+3] /= l;\n }\n \n //side is M'(1,0,0,1) - M'(-1,0,0,1) and they lie on the planes\n const r3 = mi[3] + mi[15];\n const r0 = (mi[0] + mi[12 ])/r3;\n const r1 = (mi[1] + mi[13 ])/r3;\n const r2 = (mi[2] + mi[14 ])/r3;\n\n const l3 = -mi[3] + mi[15];\n const l0 = (-mi[0] + mi[12 ])/l3 - r0;\n const l1 = (-mi[1] + mi[13 ])/l3 - r1;\n const l2 = (-mi[2] + mi[14 ])/l3 - r2;\n\n const side = Math.sqrt(l0*l0 + l1*l1 + l2*l2);\n\n //center of the scene is M'*(0, 0, 0, 1)\n const c0 = mi[12]/mi[15] - t.viewpoint[0];\n const c1 = mi[13]/mi[15] - t.viewpoint[1];\n const c2 = mi[14]/mi[15] - t.viewpoint[2];\n const dist = Math.sqrt(c0*c0 + c1*c1 + c2*c2);\n\n const resolution = (2*side/dist)/ t.viewport[2];\n t.currentResolution == resolution ? t.sameResolution = true : t.sameResolution = false;\n t.currentResolution = resolution;\n },\n\n traverse : function (mesh, cache) {\n let t = this;\n t.mesh = mesh;\n// if(Debug.extract == true)\n // return;\n\n if(!mesh.isReady) return;\n \n const n = mesh.nodesCount;\n t.visited = new Uint8Array(n);\n t.blocked = new Uint8Array(n);\n t.selected = new Uint8Array(n);\n\n t.frame = cache.frame;\n\n t.instance_errors = new Float32Array(n);\n\n if(t.frame > mesh.frame) { //clean the errors.\n mesh.errors = new Float32Array(n); \n mesh.frame = t.frame;\n }\n\n t.visitQueue = new _PriorityQueue_js__WEBPACK_IMPORTED_MODULE_1__.PriorityQueue(n);\n for(var i = 0; i < mesh.nroots; i++)\n t.insertNode(i);\n \n t.currentError = cache.currentError;\n t.drawSize = 0;\n t.nblocked = 0;\n\n var requested = 0;\n while(t.visitQueue.size && t.nblocked < t.maxBlocked) {\n var error = t.visitQueue.error[0];\n var id = t.visitQueue.pop();\n\n //if not loaded and the queue is not full add to the candidates.\n if (mesh.status[id] == 0 && requested < cache.maxPending) {\n cache.candidates.push({id: id, mesh:mesh, frame:t.frame, error:error});\n requested++;\n }\n /* we don't want to stop as soon as a node is not availabe, because the nodes are sorted by error, \n this could cause a large drop in quality elsewere.\n we still need to mark all children as blocked, to prevent including them in the cut of the dag. */\n var blocked = t.blocked[id] || !t.expandNode(id, error);\n if (blocked)\n t.nblocked++;\n else {\n t.selected[id] = 1;\n //cache.realError = Math.min(error, cache.realError);\n }\n t.insertChildren(id, blocked);\n }\n\n //update remaining errors in the cache\n if(cache.nodes.has(mesh)) {\n for(let id of cache.nodes.get(mesh)) {\n let error = t.nodeError(id);\n if(t.instance_errors[id] == 0) {\n t.instance_errors[i] = error;\n mesh.errors[id] = Math.max(mesh.errors[id], error);\n }\n }\n }\n\n t.mesh = null;\n return t.instance_errors;\n },\n\n insertNode: function (node) {\n let t = this;\n t.visited[node] = 1;\n\n const error = t.nodeError(node);\n\n t.instance_errors[node] = error;\n t.mesh.errors[node] = Math.max(error, t.mesh.errors[node]);\n t.mesh.frames[node] = t.frame;\n\n// if(node > 0 && error < t.currentError) return; //2% speed TODO check if needed\n\n t.visitQueue.push(node, error);\n },\n\n insertChildren : function (node, block) {\n let t = this;\n for(let i = t.mesh.nfirstpatch[node]; i < t.mesh.nfirstpatch[node+1]; ++i) {\n const child = t.mesh.patches[i*3];\n if (child == t.mesh.sink) return;\n if (block) t.blocked[child] = 1;\n if (!t.visited[child])\n t.insertNode(child);\n }\n },\n\n expandNode : function (node, error) {\n let t = this;\n if(node > 0 && error < t.currentError) {\n//\t\t\tconsole.log(\"Reached error\", error, t.currentError);\n return false;\n }\n\n if(t.drawSize > t.drawBudget) {\n//\t\t\tconsole.log(\"Reached drawsize\", t.drawSize, t.drawBudget);\n return false;\n }\n\n if(t.mesh.status[node] != 1) { //not ready\n//\t\t\tconsole.log(\"Node \" + node + \" still not loaded (cache?)\");\n return false;\n }\n\n const sp = t.mesh.nspheres;\n const off = node*5;\n if(t.isVisible(sp[off], sp[off+1], sp[off+2], sp[off+3])) //expanded radius\n t.drawSize += t.mesh.nvertices[node]*0.8;\n //we are adding half of the new faces. (but we are using the vertices so *2)\n\n return true;\n },\n\n nodeError : function (n, tight) {\n let t = this;\n const spheres = t.mesh.nspheres;\n const b = t.viewpoint;\n const off = n*5;\n const cx = spheres[off+0];\n const cy = spheres[off+1];\n const cz = spheres[off+2];\n let r = spheres[off+3];\n if(tight)\n r = spheres[off+4];\n const d0 = b[0] - cx;\n const d1 = b[1] - cy;\n const d2 = b[2] - cz;\n let dist = Math.sqrt(d0*d0 + d1*d1 + d2*d2) - r;\n if (dist < 0.1)\n dist = 0.1;\n\n //resolution is how long is a pixel at distance 1.\n let error = t.mesh.nerrors[n]/(t.currentResolution*dist); //in pixels\n\n //causes flickering due to things popping in and out of visibility, causes a huge resorting.\n /*if (!t.isVisible(cx, cy, cz, spheres[off+4]))\n error /= 100.0; */\n\n //more stable, at least it's continuous.\n let d = t.distance(cx, cy, cz, spheres[off+4]);\n if(d < -r) {\n error /= 101.0;\n } else if(d < 0) {\n error /= 1 -( d/r)*100.0\n } \n return error;\n },\n\n distance: function(x, y, z, r) {\n const p = this.planes;\n let min_distance = 1e20;\n for (let i = 0; i < 24; i +=4) {\n let d = p[i]*x + p[i+1]*y + p[i+2]*z + p[i+3] + r;\n if(d < min_distance)\n min_distance = d;\n }\n return min_distance;\n },\n\n isVisible : function (x, y, z, r) {\n const p = this.planes;\n for (let i = 0; i < 24; i +=4) {\n if(p[i]*x + p[i+1]*y + p[i+2]*z + p[i+3] + r < 0) //plane is ax+by+cz+d = 0; \n return false;\n }\n return true;\n }\n}; \n\n\n\n\n//# sourceURL=webpack://Nexus3D/./src/Traversal.js?\n}"); + +/***/ }, + +/***/ "three" +/*!**************************************************************************************!*\ + !*** external {"commonjs":"three","commonjs2":"three","amd":"three","root":"THREE"} ***! + \**************************************************************************************/ +(module) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_three__; + +/***/ } + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ if (!(moduleId in __webpack_modules__)) { +/******/ delete __webpack_module_cache__[moduleId]; +/******/ var e = new Error("Cannot find module '" + moduleId + "'"); +/******/ e.code = 'MODULE_NOT_FOUND'; +/******/ throw e; +/******/ } +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/compat get default export */ +/******/ (() => { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = (module) => { +/******/ var getter = module && module.__esModule ? +/******/ () => (module['default']) : +/******/ () => (module); +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/jsonp chunk loading */ +/******/ (() => { +/******/ __webpack_require__.b = (typeof document !== 'undefined' && document.baseURI) || self.location.href; +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ "Nexus3D": 0 +/******/ }; +/******/ +/******/ // no chunk on demand loading +/******/ +/******/ // no prefetching +/******/ +/******/ // no preloaded +/******/ +/******/ // no HMR +/******/ +/******/ // no HMR manifest +/******/ +/******/ // no on chunks loaded +/******/ +/******/ // no jsonp function +/******/ })(); +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module can't be inlined because the eval devtool is used. +/******/ var __webpack_exports__ = __webpack_require__("./src/Nexus3D.js"); +/******/ +/******/ return __webpack_exports__; +/******/ })() +; +}); \ No newline at end of file diff --git a/nexus3d/build/nexus3D.min.js b/nexus3d/build/nexus3D.min.js new file mode 100644 index 00000000..9402fc9a --- /dev/null +++ b/nexus3d/build/nexus3D.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("three")):"function"==typeof define&&define.amd?define(["exports","three"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Nexus3D={},e.THREE)}(this,function(e,t){"use strict";function r(e){var t=e.getUint32(e.offset,!0),r=e.getUint32(e.offset+4,!0);return e.offset+=8,1*r+t}function o(e){var t=e.getUint32(e.offset,!0);return e.offset+=4,t}function s(e){var t=e.getUint16(e.offset,!0);return e.offset+=2,t}function i(e){var t=e.getFloat32(e.offset,!0);return e.offset+=4,t}function a(e,t){var r=1/(e[12]*e[9]*e[6]*e[3]-e[8]*e[13]*e[6]*e[3]-e[12]*e[5]*e[10]*e[3]+e[4]*e[13]*e[10]*e[3]+e[8]*e[5]*e[14]*e[3]-e[4]*e[9]*e[14]*e[3]-e[12]*e[9]*e[2]*e[7]+e[8]*e[13]*e[2]*e[7]+e[12]*e[1]*e[10]*e[7]-e[0]*e[13]*e[10]*e[7]-e[8]*e[1]*e[14]*e[7]+e[0]*e[9]*e[14]*e[7]+e[12]*e[5]*e[2]*e[11]-e[4]*e[13]*e[2]*e[11]-e[12]*e[1]*e[6]*e[11]+e[0]*e[13]*e[6]*e[11]+e[4]*e[1]*e[14]*e[11]-e[0]*e[5]*e[14]*e[11]-e[8]*e[5]*e[2]*e[15]+e[4]*e[9]*e[2]*e[15]+e[8]*e[1]*e[6]*e[15]-e[0]*e[9]*e[6]*e[15]-e[4]*e[1]*e[10]*e[15]+e[0]*e[5]*e[10]*e[15]);t[0]=(e[9]*e[14]*e[7]-e[13]*e[10]*e[7]+e[13]*e[6]*e[11]-e[5]*e[14]*e[11]-e[9]*e[6]*e[15]+e[5]*e[10]*e[15])*r,t[1]=(e[13]*e[10]*e[3]-e[9]*e[14]*e[3]-e[13]*e[2]*e[11]+e[1]*e[14]*e[11]+e[9]*e[2]*e[15]-e[1]*e[10]*e[15])*r,t[2]=(e[5]*e[14]*e[3]-e[13]*e[6]*e[3]+e[13]*e[2]*e[7]-e[1]*e[14]*e[7]-e[5]*e[2]*e[15]+e[1]*e[6]*e[15])*r,t[3]=(e[9]*e[6]*e[3]-e[5]*e[10]*e[3]-e[9]*e[2]*e[7]+e[1]*e[10]*e[7]+e[5]*e[2]*e[11]-e[1]*e[6]*e[11])*r,t[4]=(e[12]*e[10]*e[7]-e[8]*e[14]*e[7]-e[12]*e[6]*e[11]+e[4]*e[14]*e[11]+e[8]*e[6]*e[15]-e[4]*e[10]*e[15])*r,t[5]=(e[8]*e[14]*e[3]-e[12]*e[10]*e[3]+e[12]*e[2]*e[11]-e[0]*e[14]*e[11]-e[8]*e[2]*e[15]+e[0]*e[10]*e[15])*r,t[6]=(e[12]*e[6]*e[3]-e[4]*e[14]*e[3]-e[12]*e[2]*e[7]+e[0]*e[14]*e[7]+e[4]*e[2]*e[15]-e[0]*e[6]*e[15])*r,t[7]=(e[4]*e[10]*e[3]-e[8]*e[6]*e[3]+e[8]*e[2]*e[7]-e[0]*e[10]*e[7]-e[4]*e[2]*e[11]+e[0]*e[6]*e[11])*r,t[8]=(e[8]*e[13]*e[7]-e[12]*e[9]*e[7]+e[12]*e[5]*e[11]-e[4]*e[13]*e[11]-e[8]*e[5]*e[15]+e[4]*e[9]*e[15])*r,t[9]=(e[12]*e[9]*e[3]-e[8]*e[13]*e[3]-e[12]*e[1]*e[11]+e[0]*e[13]*e[11]+e[8]*e[1]*e[15]-e[0]*e[9]*e[15])*r,t[10]=(e[4]*e[13]*e[3]-e[12]*e[5]*e[3]+e[12]*e[1]*e[7]-e[0]*e[13]*e[7]-e[4]*e[1]*e[15]+e[0]*e[5]*e[15])*r,t[11]=(e[8]*e[5]*e[3]-e[4]*e[9]*e[3]-e[8]*e[1]*e[7]+e[0]*e[9]*e[7]+e[4]*e[1]*e[11]-e[0]*e[5]*e[11])*r,t[12]=(e[12]*e[9]*e[6]-e[8]*e[13]*e[6]-e[12]*e[5]*e[10]+e[4]*e[13]*e[10]+e[8]*e[5]*e[14]-e[4]*e[9]*e[14])*r,t[13]=(e[8]*e[13]*e[2]-e[12]*e[9]*e[2]+e[12]*e[1]*e[10]-e[0]*e[13]*e[10]-e[8]*e[1]*e[14]+e[0]*e[9]*e[14])*r,t[14]=(e[12]*e[5]*e[2]-e[4]*e[13]*e[2]-e[12]*e[1]*e[6]+e[0]*e[13]*e[6]+e[4]*e[1]*e[14]-e[0]*e[5]*e[14])*r,t[15]=(e[4]*e[9]*e[2]-e[8]*e[5]*e[2]+e[8]*e[1]*e[6]-e[0]*e[9]*e[6]-e[4]*e[1]*e[10]+e[0]*e[5]*e[10])*r}function h(e){this.error=new Float32Array(e),this.data=new Int32Array(e),this.size=0}function l(){let e=this;e.maxBlocked=30,e.modelMatrix=new Float32Array(16),e.viewMatrix=new Float32Array(16),e.projectionMatrix=new Float32Array(16),e.modelView=new Float32Array(16),e.modelViewInv=new Float32Array(16),e.modelViewProj=new Float32Array(16),e.modelViewProjInv=new Float32Array(16),e.planes=new Float32Array(24),e.viewport=new Float32Array(4),e.viewpoint=new Float32Array(4)}h.prototype={push:function(e,t){this.data[this.size]=e,this.error[this.size]=t,this.bubbleUp(this.size),this.size++},pop:function(){var e=this.data[0];return this.size--,this.size>0&&(this.data[0]=this.data[this.size],this.error[0]=this.error[this.size],this.sinkDown(0)),e},bubbleUp:function(e){for(var t=this.data[e],r=this.error[e];e>0;){var o=(e+1>>1)-1,s=this.error[o];if(s>r)break;this.data[e]=this.data[o],this.error[e]=s,this.data[o]=t,this.error[o]=r,e=o}},sinkDown:function(e){for(var t=this.data[e],r=this.error[e];;){var o=2*(e+1),s=o-1,i=-1;if(sr&&(i=s)}if(o(-1==i?r:n)&&(i=o);if(-1==i)break;this.data[e]=this.data[i],this.error[e]=this.error[i],this.data[i]=t,this.error[i]=r,e=i}}},l.prototype={updateView:function(e,t,r){let o=this;for(let e=0;e<16;e++)o.projectionMatrix[e]=t[e],o.modelView[e]=r[e];for(let t=0;t<4;t++)o.viewport[t]=e[t];var s,i,n;s=o.projectionMatrix,i=o.modelView,(n=o.modelViewProj)[0]=s[0]*i[0]+s[4]*i[1]+s[8]*i[2]+s[12]*i[3],n[1]=s[1]*i[0]+s[5]*i[1]+s[9]*i[2]+s[13]*i[3],n[2]=s[2]*i[0]+s[6]*i[1]+s[10]*i[2]+s[14]*i[3],n[3]=s[3]*i[0]+s[7]*i[1]+s[11]*i[2]+s[15]*i[3],n[4]=s[0]*i[4]+s[4]*i[5]+s[8]*i[6]+s[12]*i[7],n[5]=s[1]*i[4]+s[5]*i[5]+s[9]*i[6]+s[13]*i[7],n[6]=s[2]*i[4]+s[6]*i[5]+s[10]*i[6]+s[14]*i[7],n[7]=s[3]*i[4]+s[7]*i[5]+s[11]*i[6]+s[15]*i[7],n[8]=s[0]*i[8]+s[4]*i[9]+s[8]*i[10]+s[12]*i[11],n[9]=s[1]*i[8]+s[5]*i[9]+s[9]*i[10]+s[13]*i[11],n[10]=s[2]*i[8]+s[6]*i[9]+s[10]*i[10]+s[14]*i[11],n[11]=s[3]*i[8]+s[7]*i[9]+s[11]*i[10]+s[15]*i[11],n[12]=s[0]*i[12]+s[4]*i[13]+s[8]*i[14]+s[12]*i[15],n[13]=s[1]*i[12]+s[5]*i[13]+s[9]*i[14]+s[13]*i[15],n[14]=s[2]*i[12]+s[6]*i[13]+s[10]*i[14]+s[14]*i[15],n[15]=s[3]*i[12]+s[7]*i[13]+s[11]*i[14]+s[15]*i[15],a(o.modelViewProj,o.modelViewProjInv),a(o.modelView,o.modelViewInv),o.viewpoint[0]=o.modelViewInv[12],o.viewpoint[1]=o.modelViewInv[13],o.viewpoint[2]=o.modelViewInv[14],o.viewpoint[3]=1;const h=o.modelViewProj,l=o.modelViewProjInv;let u=o.planes;u[0]=h[0]+h[3],u[1]=h[4]+h[7],u[2]=h[8]+h[11],u[3]=h[12]+h[15],u[4]=-h[0]+h[3],u[5]=-h[4]+h[7],u[6]=-h[8]+h[11],u[7]=-h[12]+h[15],u[8]=h[1]+h[3],u[9]=h[5]+h[7],u[10]=h[9]+h[11],u[11]=h[13]+h[15],u[12]=-h[1]+h[3],u[13]=-h[5]+h[7],u[14]=-h[9]+h[11],u[15]=-h[13]+h[15],u[16]=-h[2]+h[3],u[17]=-h[6]+h[7],u[18]=-h[10]+h[11],u[19]=-h[14]+h[15],u[20]=-h[2]+h[3],u[21]=-h[6]+h[7],u[22]=-h[10]+h[11],u[23]=-h[14]+h[15];for(let e=0;e<24;e+=4){let t=Math.sqrt(u[e]*u[e]+u[e+1]*u[e+1]+u[e+2]*u[e+2]);u[e]/=t,u[e+1]/=t,u[e+2]/=t,u[e+3]/=t}const d=l[3]+l[15],c=(l[0]+l[12])/d,f=(l[1]+l[13])/d,m=(l[2]+l[14])/d,p=-l[3]+l[15],x=(-l[0]+l[12])/p-c,v=(-l[1]+l[13])/p-f,b=(-l[2]+l[14])/p-m,g=Math.sqrt(x*x+v*v+b*b),w=l[12]/l[15]-o.viewpoint[0],A=l[13]/l[15]-o.viewpoint[1],y=l[14]/l[15]-o.viewpoint[2],E=2*g/Math.sqrt(w*w+A*A+y*y)/o.viewport[2];o.currentResolution==E?o.sameResolution=!0:o.sameResolution=!1,o.currentResolution=E},traverse:function(e,t){let r=this;if(r.mesh=e,!e.isReady)return;const o=e.nodesCount;r.visited=new Uint8Array(o),r.blocked=new Uint8Array(o),r.selected=new Uint8Array(o),r.frame=t.frame,r.instance_errors=new Float32Array(o),r.frame>e.frame&&(e.errors=new Float32Array(o),e.frame=r.frame),r.visitQueue=new h(o);for(var s=0;s0&&tr.drawBudget)return!1;if(1!=r.mesh.status[e])return!1;const o=r.mesh.nspheres,s=5*e;return r.isVisible(o[s],o[s+1],o[s+2],o[s+3])&&(r.drawSize+=.8*r.mesh.nvertices[e]),!0},nodeError:function(e,t){let r=this;const o=r.mesh.nspheres,s=r.viewpoint,i=5*e,n=o[i+0],a=o[i+1],h=o[i+2];let l=o[i+3];t&&(l=o[i+4]);const u=s[0]-n,d=s[1]-a,c=s[2]-h;let f=Math.sqrt(u*u+d*d+c*c)-l;f<.1&&(f=.1);let m=r.mesh.nerrors[e]/(r.currentResolution*f),p=r.distance(n,a,h,o[i+4]);return p<-l?m/=101:p<0&&(m/=1-p/l*100),m},distance:function(e,t,r,o){const s=this.planes;let i=1e20;for(let n=0;n<24;n+=4){let a=s[n]*e+s[n+1]*t+s[n+2]*r+s[n+3]+o;a1.1&&(t.currentError*=1.05),r<.9&&(t.currentError*=.95),t.currentError=Math.max(t.targetError,Math.min(t.maxError,t.currentError))}else t.currentError=t.targetError;t.rendered=0,t.realError=1e20,t.totswapped=0},endFrame:function(){this.update()},requestNode:function(e,t){e.status[t]=2,this.cacheSize+=e.nsize[t],e.reqAttempt[t]=0,this.nodes.has(e)||this.nodes.set(e,new Set),this.nodes.get(e).add(t),this.requestNodeGeometry(e,t),this.requestNodeTexture(e,t)},requestNodeGeometry:function(e,t){this.pending++,e.status[t]++;let r=e.deepzoom?e.baseurl+t+".nxn":e.url,o=e.deepzoom?0:e.noffsets[t],s=e.deepzoom?0:e.noffsets[t+1],i=e.georeq[t]=e.httpRequest(r,o,s,()=>{delete e.georeq[t],this.loadNodeGeometry(i,e,t),this.pending--},()=>{delete e.georeq[t],this.debug.verbose&&console.log("Geometry request error!"),this.recoverNode(e,t,0),this.pending--},()=>{delete e.georeq[t],this.debug.verbose&&console.log("Geometry request abort!"),this.removeNode(e,t),this.pending--},"arraybuffer")},requestNodeTexture:function(e,t){if(!e.vertex.texCoord)return;let r=e.patches[3*e.nfirstpatch[t]+2];e.texref[r]++,e.status[t]++;let o=e.deepzoom?e.baseurl+r+".jpg":e.url,s=e.deepzoom?0:e.textures[r],i=e.deepzoom?0:e.textures[r+1],n=e.texreq[r]=e.httpRequest(o,s,i,()=>{delete e.texreq[r],this.loadNodeTexture(n,e,t,r)},()=>{delete e.texreq[r],this.debug.verbose&&console.log("Texture request error!"),this.recoverNode(e,t,1)},()=>{delete e.texreq[r],this.debug.verbose&&console.log("Texture request abort!"),this.removeNode(e,t)},"blob")},recoverNode:function(e,t,r){if(0==e.status[t])return;e.status[t]--;let o=this;if(e.reqAttempt[t]>2)return this.debug.verbose&&console.log("Max request limit for "+m.url+" node: "+n),void o.removeNode(e,t);switch(e.reqAttempt[t]++,r){case 0:o.requestNodeGeometry(e,t),this.debug.verbose&&console.log("Recovering geometry for "+m.url+" node: "+n);break;case 1:o.requestNodeTexture(e,t),this.debug.verbose&&console.log("Recovering texture for "+m.url+" node: "+n)}},loadNodeGeometry:function(e,t,r){0!=t.status[r]&&(t.compressed?(this.corto||this.loadCorto(),this.corto.postRequest({mesh:t,id:r,buffer:e.response,cache:this})):this.readyGeometryNode(t,r,e.response))},loadNodeTexture:function(e,t,r,o){if(0==t.status[r])throw"Should not load texture twice";let s=e.response,i=e=>{0!=t.status[r]&&(t.createTexture(o,e),t.status[r]--,2==t.status[r]&&this.readyNode(t,r))};if("undefined"!=typeof createImageBitmap)try{createImageBitmap(s,{imageOrientation:"flipY"}).then(i)}catch(e){createImageBitmap(s).then(i)}else{var n=window.URL||window.webkitURL,a=document.createElement("img");a.onerror=function(e){console.log("Texture loading error!")},a.src=n.createObjectURL(s),a.onload=function(){n.revokeObjectURL(a.src),i(a)}}},removeNode:function(e,t){if(this.nodes.get(e).delete(t),0==e.status[t])return void(this.debug.verbose&&console.log("Double remove due to abort."));if(e.status[t]=0,t in e.georeq&&4!=e.georeq[t].readyState&&(e.georeq[t].abort(),delete e.georeq[t]),e.availableNodes--,this.cacheSize-=e.nsize[t],e.deleteNodeGeometry(t),!e.vertex.texCoord)return;const r=e.patches[3*e.nfirstpatch[t]+2];r in e.texreq&&4!=e.texreq[r].readyState&&(e.texreq[r].abort(),delete e.texreq[r]),e.texref[r]--,0==e.texref[r]&&e.deleteTexture(r)},readyGeometryNode:function(e,t,r){if(0==e.status[t])return;const o=e.nvertices[t],s=e.nfaces[t];let i={};if(e.corto)i=r;else{i.index=new Uint16Array(r,o*e.vsize,3*s),i.position=new Float32Array(r,0,3*o);var n=12*o;e.vertex.texCoord&&(i.uv=new Float32Array(r,n,2*o),n+=8*o),e.vertex.normal&&(i.normal=new Int16Array(r,n,3*o),n+=6*o),e.vertex.color&&(i.color=new Uint8Array(r,n,4*o),n+=4*o)}e.createNodeGeometry(t,i),e.status[t]--,2==e.status[t]&&this.readyNode(e,t)},readyNode:function(e,t){if(e.status[t]--,1!=e.status[t])throw"A ready node should have status ==1";e.reqAttempt[t]=0,e.createNode(t),e.availableNodes++;for(let t of e.onUpdate)t();this.update()},flush:function(e){if(this.nodes.has(e)){for(let t of this.nodes.get(e))this.removeNode(e,t);this.nodes.delete(e)}},update:function(){if(this.pending>=3)return;let e=null;for(let t of this.candidates)0==t.mesh.status[t.id]&&(!e||t.error>e.error)&&(e=t);if(e){for(;this.cacheSize>this.maxCacheSize;){let t=null;for(let[e,r]of this.nodes)for(let o of r){let r=e.errors[o],s=e.frames[o];(!t||r=.9*e.error)return;this.removeNode(t.mesh,t.id)}this.totswapped+=e.mesh.nsize[e.id],this.candidates=this.candidates.filter(t=>t.mesh==e.mesh&&t.id==e.id),this.requestNode(e.mesh,e.id),this.update()}}};let x=new p;class v extends t.Mesh{constructor(e,r,o={}){super(),this.patchWebGLRenderer(r),Object.assign(this,{isNXS:!0,type:"NXS",url:e,gl:r.getContext(),XRMode:!1,material:null,autoUpdate:!0,mesh:new f,vbo:[],ibo:[],vao:[],textures:[],attributes:{},basemesh:null}),"material"in o&&(this.material=o.material),this.material||(this.material=new t.MeshStandardMaterial);for(let e of["onLoad","onUpdate","onProgress"])this["_"+e]=[],e in o&&this["_"+e].push(o[e]);this.url&&("object"==typeof e?(this.nxs=this.url,this.nxs.onLoad.push(e=>{this.mesh=this.nxs.mesh,this.traversal=this.nxs.traversal,this.cache=this.nxs.cache,this.vbo=this.nxs.vbo,this.ibo=this.nxs.ibo,this.vao=this.nxs.vao,this.textures=this.nxs.textures,this.onLoadCallback(this)})):this.open(this.url))}copy(e){throw t.Object3D.prototype.copy.call(this,e,!1),new Error("Can't really copy a Nexus3D object.")}open(e){let t=this;this.mesh.open(e),this.mesh.createNode=e=>{},this.mesh.createNodeGeometry=(e,r)=>{t.createNodeGeometry(e,r)},this.mesh.createTexture=(e,r)=>{t.createTexture(e,r)},this.mesh.deleteNodeGeometry=e=>{t.deleteNodeGeometry(e)},this.mesh.deleteTexture=e=>{t.deleteTexture(e)},this.mesh.onLoad.push(()=>{t.onLoadCallback()}),this.mesh.onUpdate.push(()=>{for(let e of t._onUpdate)e(this);for(let e of t._onProgress)e(this,this.mesh.availableNodes,this.mesh.nodesCount)}),this.traversal=new l,this.cache=x,this.textures={}}set onLoad(e){this._onLoad.push(e)}set onUpdate(e){this._onUpdate.push(e)}set onProgress(e){this._onProgress.push(e)}updateMaterials(){!1!==this.material.map&&this.mesh.vertex.texCoord&&(this.material.map=this.material_texture),this.mesh.vertex.color&&(this.material.vertexColors=!0),this.material.needsUpdate=!0}onLoadCallback(){const e=this.mesh.sphere.center,r=new t.Vector3(e[0],e[1],e[2]),o=this.mesh.sphere.radius;this.boundingSphere=new t.Sphere(r,o);var s=new t.BufferGeometry;s.setAttribute("position",new t.BufferAttribute(new Float32Array(3),3)),this.mesh.vertex.normal&&s.setAttribute("normal",new t.BufferAttribute(new Float32Array(3),3)),this.mesh.vertex.color&&s.setAttribute("color",new t.BufferAttribute(new Float32Array(4),4)),this.mesh.vertex.texCoord&&s.setAttribute("uv",new t.BufferAttribute(new Float32Array(2),2)),this.mesh.vertex.texCoord&&(this.material_texture=new t.DataTexture(new Uint8Array([1,1,1,1]),1,1,t.RGBAFormat),this.material_texture.needsUpdate=!0),this.updateMaterials(),this.geometry=s,this.frustumCulled=!1;for(let e of this._onLoad)e(this)}renderBufferDirect(e,r,o,s,i,n){let a=new t.Vector4;e.getViewport(a),this.modelViewMatrix.multiplyMatrices(o.matrixWorldInverse,this.matrixWorld),0==a.x&&this.XRMode&&(this.traversal.updateView(a,o.projectionMatrix.elements,this.modelViewMatrix.elements),this.instance_errors=this.traversal.traverse(this.mesh,this.cache));let h=this.gl,l=h.getParameter(h.CURRENT_PROGRAM),u=this.attributes;u.position=h.getAttribLocation(l,"position"),u.normal=h.getAttribLocation(l,"normal"),u.color=h.getAttribLocation(l,"color"),u.uv=h.getAttribLocation(l,"uv"),u.size=h.getUniformLocation(l,"size"),u.scale=h.getUniformLocation(l,"scale");let d=h.getUniformLocation(l,"map");u.map=d?h.getUniform(l,d):null,this.setVisibility()}setVisibility(){let e=this.traversal,t=this.mesh;if(!t.isReady)return;let r=0,o=this.attributes,s=this.mesh,i=this.gl,n=i instanceof WebGL2RenderingContext,a=o.uv+10*o.color+100*o.normal;for(let x=0;x=0&&(i.vertexAttribPointer(o.uv,2,i.FLOAT,!1,8,t),i.enableVertexAttribArray(o.uv)),t+=8*e),s.vertex.color&&(o.color>=0&&(i.vertexAttribPointer(o.color,4,i.UNSIGNED_BYTE,!0,4,t),i.enableVertexAttribArray(o.color)),t+=4*e),s.vertex.normal&&o.normal>=0&&(i.vertexAttribPointer(o.normal,3,i.SHORT,!0,6,t),i.enableVertexAttribArray(o.normal)),this.cache.debug.nodes){i.disableVertexAttribArray(o.color);var c=this.instance_errors[x],f=[[1,1,1,1],[1,1,1,1],[0,1,0,1],[0,1,1,1],[1,1,0,1],[1,0,1,1],[1,0,0,1]];let e=Math.min(5.99,Math.max(0,Math.log2(c)/2)),t=Math.floor(e);e-=t;let r=[];for(let o=0;o<4;o++)r[o]=f[t][o]*(1-e)+f[t+1][o]*e;i.vertexAttrib4fv(o.color,r)}}this.cache.realError=Math.min(this.mesh.errors[x],this.cache.realError);let b=0,g=0,w=t.nfirstpatch[x+1]-1;for(let s=t.nfirstpatch[x];sb){if(t.vertex.texCoord&&o.uv>=0){var m=t.patches[3*s+2];if(-1!=m){var p=this.textures[m];i.activeTexture(i.TEXTURE0+o.map),i.bindTexture(i.TEXTURE_2D,p)}}let e=this.material.wireframe?i.LINE_STRIP:i.TRIANGLES;i.drawElements(e,3*(g-b),i.UNSIGNED_SHORT,6*b),r+=g-b}b=t.patches[3*s+1]}}}this.cache.rendered+=r}createNodeGeometry(e,r){let o=this.mesh;var s=o.nvertices[e];o.nfaces[e];let i=r.index,n=new ArrayBuffer(s*o.vsize);new Float32Array(n,0,3*s).set(r.position);var a=12*s;o.vertex.texCoord&&(new Float32Array(n,a,2*s).set(r.uv),a+=8*s);o.vertex.color&&(new Uint8Array(n,a,4*s).set(r.color),a+=4*s);o.vertex.normal&&(new Int16Array(n,a,3*s).set(r.normal),a+=6*s);if(e{t(r,o,s,i,n,a),n.renderBufferDirect&&n.renderBufferDirect(e,o,r,s,i,a)},e.originalRender=e.render,e.render=(t,r)=>{x.beginFrame(30),e.originalRender(t,r),x.endFrame()},e.nexusPatched=!0}}e.Cache=x,e.Nexus3D=v,Object.defineProperty(e,"__esModule",{value:!0})}); diff --git a/nexus3d/dist/corto.em.js b/nexus3d/dist/corto.em.js new file mode 100644 index 00000000..ce276157 --- /dev/null +++ b/nexus3d/dist/corto.em.js @@ -0,0 +1,216 @@ +/* +Corto +Copyright (c) 2017-2020, Visual Computing Lab, ISTI - CNR +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +onmessage = async function(job) { + if(typeof(job.data) == "string") return; + + var buffer = job.data.buffer; + if(!buffer) return; + if(!CortoDecoder.instance) + await CortoDecoder.ready; + + var model = CortoDecoder.decode(buffer, job.data.short_index, job.data.short_normals, job.data.rgba_colors ? 4 : 3); + postMessage({ model: model, buffer: buffer, request: job.data.request}); +}; + +var CortoDecoder = (function() { + "use strict"; + var wasm_base = "0061736D0100000001530D60037F7F7F0060027F7F0060017F017F60017F0060047F7F7F7F0060027F7F017F60057F7F7F7F7F0060037F7F7F017F60000060067F7F7F7F7F7F0060047F7F7F7F017F60077F7F7F7F7F7F7F006000017F02410203656E761F656D736372697074656E5F6E6F746966795F6D656D6F72795F67726F77746800030D776173695F756E737461626C650970726F635F65786974000303A401A2010302070107080C08070703010307050102080200010901010A00050003010405040501050101020008010402000603070402000605030802040500010203020401030300020204050100000404000200000004000102020100020302010005000606000000010600060A020003010003010101000203030102010000090901060605070504040007070503030302010B00000101010000010004000100030201020504050170013E3E05030100100608017F014190DD010B07FF0117066D656D6F727902000A6E65774465636F64657200A301076E67726F75707300760667726F7570730072056E76657274006C056E66616365003307686173417474720060096861734E6F726D616C005008686173436F6C6F72004705686173557600A2010C736574506F736974696F6E730099010C7365744E6F726D616C7333320094010C7365744E6F726D616C73313600900109736574436F6C6F7273008801067365745576730080010A736574496E6465783136007B0A736574496E64657833320079066465636F646500780D64656C6574654465636F6465720077065F7374617274002A066D616C6C6F63003904667265650002047362726B00120955010041010B3D285D5C5B696867666564635E5830575A2F565553522F59302D514F4C4AA0019F012D9E019D019C019A01970196012A401E8F018D01338C01401E3F3F8A011E89017E810187011E7F820186011E84010A89A303A2018C0D01077F02402000450D00200041786A22032000417C6A280200220141787122006A2105024020014101710D002001410371450D012003200328020022026B220341A8192802002204490D01200020026A2100200341AC19280200470440200241FF014D0440200328020822042002410376220241037441C0196A471A2004200328020C2201460440419819419819280200417E200277713602000C030B2004200136020C200120043602080C020B2003280218210602402003200328020C22014704402004200328020822024D0440200228020C1A0B2002200136020C200120023602080C010B0240200341146A220228020022040D00200341106A220228020022040D00410021010C010B0340200221072004220141146A220228020022040D00200141106A2102200128021022040D000B200741003602000B2006450D0102402003200328021C220241027441C81B6A22042802004604402004200136020020010D01419C19419C19280200417E200277713602000C030B20064110411420062802102003461B6A20013602002001450D020B2001200636021820032802102202044020012002360210200220013602180B20032802142202450D0120012002360214200220013602180C010B200528020422014103714103470D0041A019200036020020052001417E7136020420032000410172360204200020036A20003602000F0B200520034D0D0020052802042201410171450D0002402001410271450440200541B01928020046044041B019200336020041A41941A41928020020006A220036020020032000410172360204200341AC19280200470D0341A019410036020041AC1941003602000F0B200541AC1928020046044041AC19200336020041A01941A01928020020006A220036020020032000410172360204200020036A20003602000F0B200141787120006A21000240200141FF014D0440200528020C2102200528020822042001410376220141037441C0196A220747044041A8192802001A0B20022004460440419819419819280200417E200177713602000C020B2002200747044041A8192802001A0B2004200236020C200220043602080C010B2005280218210602402005200528020C220147044041A819280200200528020822024D0440200228020C1A0B2002200136020C200120023602080C010B0240200541146A220228020022040D00200541106A220228020022040D00410021010C010B0340200221072004220141146A220228020022040D00200141106A2102200128021022040D000B200741003602000B2006450D0002402005200528021C220241027441C81B6A22042802004604402004200136020020010D01419C19419C19280200417E200277713602000C020B20064110411420062802102005461B6A20013602002001450D010B2001200636021820052802102202044020012002360210200220013602180B20052802142202450D0020012002360214200220013602180B20032000410172360204200020036A2000360200200341AC19280200470D0141A01920003602000F0B20052001417E7136020420032000410172360204200020036A20003602000B200041FF014D04402000410376220141037441C0196A2100027F41981928020022024101200174220171450440419819200120027236020020000C010B20002802080B2102200020033602082002200336020C2003200036020C200320023602080F0B200342003702102003027F410020004108762201450D001A411F200041FFFFFF074B0D001A200120014180FE3F6A411076410871220174220220024180E01F6A411076410471220274220420044180800F6A411076410271220474410F7620012002722004726B22014101742000200141156A7641017172411C6A0B220236021C200241027441C81B6A21010240419C1928020022044101200274220771450440419C192004200772360200200120033602002003200336020C20032001360218200320033602080C010B20004100411920024101766B2002411F461B7421022001280200210102400340200122042802044178712000460D012002411D76210120024101742102200420014104716A220741106A28020022010D000B200720033602102003200336020C20032004360218200320033602080C010B20042802082200200336020C20042003360208200341003602182003200436020C200320003602080B41B81941B819280200417F6A220036020020000D0041E01C210303402003280200220041086A210320000D000B41B819417F3602000B0B2F01027F2000410120001B2100034002402000103922010D004194192802002202450D0020021108000C010B0B20010B820401037F20024180C0004F0440200020012002107C20000F0B200020026A210302402000200173410371450440024020024101480440200021020C010B2000410371450440200021020C010B200021020340200220012D00003A0000200141016A2101200241016A220220034F0D0120024103710D000B0B02402003417C71220441C000490D002002200441406A22054B0D0003402002200128020036020020022001280204360204200220012802083602082002200128020C36020C2002200128021036021020022001280214360214200220012802183602182002200128021C36021C2002200128022036022020022001280224360224200220012802283602282002200128022C36022C2002200128023036023020022001280234360234200220012802383602382002200128023C36023C200141406B2101200241406B220220054D0D000B0B200220044F0D01034020022001280200360200200141046A2101200241046A22022004490D000B0C010B20034104490440200021020C010B2003417C6A22042000490440200021020C010B200021020340200220012D00003A0000200220012D00013A0001200220012D00023A0002200220012D00033A0003200141046A2101200241046A220220044D0D000B0B200220034904400340200220012D00003A0000200141016A2101200241016A22022003470D000B0B20000BE40101067F0240024020002802082203200028020422026B20014F04400340200241003A00002000200028020441016A22023602042001417F6A22010D000C02000B000B2002200028020022046B220620016A2202417F4C0D01027F2002200320046B2203410174220720072002491B41FFFFFFFF07200341FFFFFFFF03491B220304402003100321050B200520066A22020B41002001100A1A0340200241016A21022001417F6A22010D000B200641014E044020052004200610041A0B200020053602002000200320056A360208200020023602042004450D00200410020B0F0B1007000B1C00200245044020002001460F0B20002802042001280204108B01450B080041F912100C000B05001038000B05001038000BF30202027F017E02402002450D00200020026A2203417F6A20013A0000200020013A000020024103490D002003417E6A20013A0000200020013A00012003417D6A20013A0000200020013A000220024107490D002003417C6A20013A0000200020013A000320024109490D002000410020006B41037122046A2203200141FF017141818284086C22013602002003200220046B417C7122046A2202417C6A200136020020044109490D002003200136020820032001360204200241786A2001360200200241746A200136020020044119490D002003200136021820032001360214200320013602102003200136020C200241706A20013602002002416C6A2001360200200241686A2001360200200241646A20013602002004200341047141187222046B22024120490D002001AD22054220862005842105200320046A2101034020012005370318200120053703102001200537030820012005370300200141206A2101200241606A2202411F4B0D000B0B20000BA50201037F230041406A220324002000280200220441786A28020021052004417C6A280200210420034100360214200320013602102003200036020C2003200236020841002101200341186A41004127100A1A200020056A2100024020042002410010060440200341013602382004200341086A200020004101410020042802002802141109002000410020032802204101461B21010C010B2004200341086A2000410141002004280200280218110600200328022C220041014B0D00200041016B0440200328021C410020032802284101461B410020032802244101461B410020032802304101461B21010C010B2003280220410147044020032802300D0120032802244101470D0120032802284101470D010B200328021821010B200341406B240020010B2D01027F100822022201419813360200200141C413360200200141046A2000109501200241F4133602001009000BF20101077F20002802082202200028020422036B41027520014F044020002003410020014102742200100A20006A3602040F0B02402003200028020022036B2206410275220720016A2205418080808004490440027F41002005200220036B2202410175220420042005491B41FFFFFFFF03200241027541FFFFFFFF01491B2202450D001A20024180808080044F0D022002410274100322080B220420074102746A41002001410274100A1A200641014E044020082003200610041A0B200020043602002000200420024102746A3602082000200420054102746A36020420030440200310020B0F0B1007000B41F009100C000B1B0002402000280208450D0020002802042200450D00200010020B0B4301037F02402002450D00034020002D0000220420012D00002205460440200141016A2101200041016A21002002417F6A22020D010C020B0B200420056B21030B20030B810101037F027F20002802142202200148044020004120200120026B22026B22013602142000200028020C220341046A36020C200041106A2104200028021020027420032802002202200176720C010B2000200220016B2201360214200041106A2104200028021022022001760B210320042002417F200174417F737136020020030B5501017F230041106B220224002000420037020020004100360208024020012C000B41004E044020002001280208360208200020012902003702000C010B2000200128020020012802041093010B200241106A24000B4A01017F41901D280200220120006A2200417F4C04404190194130360200417F0F0B024020003F004110744D0D002000107A0D004190194130360200417F0F0B41901D200036020020010B080041A812100C000B8F0101037F20002101024002402000410371450D0020002D00004504400C020B0340200141016A2201410371450D0120012D00000D000B0C010B03402001220241046A210120022802002203417F73200341FFFDFB776A7141808182847871450D000B200341FF0171450440200221010C010B034020022D00012103200241016A2201210220030D000B0B200120006B0BC50201067F027F20002802082204044020002802140C010B418002210420004180023602084180081003210320004280808080800437021020004100360200200020033602042000200336020C41200B220320024C0440200020002802102003742001200220036B767222083602100240200028020022032004480440200028020421060C010B417F20044103742004410174220541FEFFFFFF03712005471B1003220620002802042207200441027410042104200704402007100220002802084101742105200028020021030B20002005360208200020043602040B2000200341016A360200200620034102746A200836020020004100360210200028021421044120210320004120360214200220046B220241027441F0086A28020020017121010B200241014E04402000200320026B360214200020002802102002742001723602100B0B9D0101047F02402000280200220241014D0440200241016B450D012000280208220328000021022000200341046A2203360208024020022001280204200128020022046B22054B04402001200220056B100520012802002104200028020821030C010B200220054F0D002001200220046A3602040B2000200220036A36020820042003200210041A0F0B100822004199083602001009000B2000200110740B900201077F02402000280204200028020022076B220841186D220B41016A220641ABD5AAD5004904402006200028020820076B41186D2209410174220C200C2006491B41AAD5AAD500200941D5AAD52A491B22060440200641ABD5AAD5004F0D02200641186C1003210A0B2001280200210920022802002102200328020021032004280200210420052802002105200A200B41186C6A220141003A0014200120053602102001200436020C2001200336020820012002360204200120093602002001200841686D41186C6A2102200841014E044020022007200810041A0B200020023602002000200A200641186C6A3602082000200141186A36020420070440200710020B0F0B1007000B41AD11100C000B41002001044020002001280200101820002001280204101820012C0027417F4C0440200128021C10020B20012C001B417F4C0440200128021010020B200110020B0BFA0101067F20011071200041046A21062001280200210502402000280208200028020422026B2203417B4D044020064104100520002802082104200028020421020C010B2000200220036A41046A22043602080B200220036A20053602000240200420026B220320034104200341037122056B410020051B22076A220549044020062007100520002802082104200028020421020C010B200320054D0D002000200220056A22043602080B200128020421050240200420026B22042004200128020041027422016A2203490440200620011005200628020021020C010B200420034D0D002000200220036A3602080B200220046A2005200110041A0BFD0201047F20022D00012104024020012D0001220720002D00014D0440200441FF017120074D0D0120012F00002104200120022F00003B0000200220043B00004101210520012D000120002D00014D0440200441087621040C020B20002F00002104200020012F00003B0000200120043B000020022D00012104410221050C010B20002F00002106200441FF017120074B0440200020022F00003B0000200220063B000020064180FE03714108762104410121050C010B200020012F00003B0000200120063B00004101210520022D00012204200641087622074D0D00200120022F00003B0000200220063B000041022105200721040B20032D0001200441FF01714B047F20022F00002104200220032F00003B0000200320043B000020022D000120012D00014D0440200541016A0F0B20012F00002103200120022F00003B0000200220033B000020012D000120002D00014D0440200541026A0F0B20002F00002102200020012F00003B0000200120023B0000200541036A0520050B0B8E0201067F20002802082204200028020422036B41027520014F0440034020032002280200360200200341046A21032001417F6A22010D000B200020033602040F0B02402003200028020022066B2207410275220820016A2203418080808004490440027F41002003200420066B2204410175220520052003491B41FFFFFFFF03200441027541FFFFFFFF01491B2204450D001A20044180808080044F0D02200441027410030B220520084102746A2103034020032002280200360200200341046A21032001417F6A22010D000B200741014E044020052006200710041A0B200020053602002000200520044102746A3602082000200336020420060440200610020B0F0B1007000B41F009100C000B440020002001360208417F2001410274200141FFFFFFFF03712001471B1003210120004280808080800437021020004100360200200020013602042000200136020C20000BBF0101047F02402000280200220341014D0440200341016B450D01200041046A210602402000280208200028020422036B2204417B4D044020064104100520002802082105200028020421030C010B2000200320046A41046A22053602080B200320046A20013602000240200520036B2204200120046A2205490440200620011005200628020021030C010B200420054D0D002000200320056A3602080B200320046A2002200110041A0F0B10084199083602001009000B20002002200110750B0600200010020BC50101067F02402000280204200028020022046B2206410275220541016A2202418080808004490440027F41002002200028020820046B2203410175220720072002491B41FFFFFFFF03200341027541FFFFFFFF01491B2202450D001A20024180808080044F0D02200241027410030B220320054102746A22052001280200360200200641014E044020032004200610041A0B200020033602002000200320024102746A3602082000200541046A36020420040440200410020B0F0B1007000B41AD11100C000B850301047F230041306B22042400200441003602102004420037030802402001101422064170490440024002402006410B4F0440200641106A4170712207100321052004200741808080807872360210200420053602082004200636020C0C010B200420063A0013200441086A21052006450D010B20052001200610041A0B200520066A41003A0000200041146A2206200441086A1023210520042C0013417F4C0440200428020810020B2005200041186A470440200441003602102004420037030820011014220041704F0D02024002402000410B4F0440200041106A4170712207100321052004200741808080807872360210200420053602082004200036020C0C010B200420003A0013200441086A21052000450D010B20052001200010041A0B200020056A41003A00002004200441086A360220200441286A2006200441086A200441206A1022200428022828021C210020042C0013417F4C0440200428020810020B20002002360204200020033602140B200441306A24000F0B1013000B1013000B8D03010A7F230041106B2202240020024100360208200242003703002001101422034170490440024002402003410B4F0440200341106A417071220610032104200220064180808080787236020820022004360200200220033602040C010B200220033A000B200221042003450D010B20042001200310041A0B200320046A41003A000020022D000B2201411874411875210A027F410020002802182205450D001A20022802042001200A41004822001B21082002280200200220001B210B0340200541106A2107024002400240024002400240200528021420052D001B2200200041187441187541004822031B22062008200620084922011B22090440200B2007280200200720031B22042009100F22000D010B20082006490D052009450D022007280200200720031B21040C010B2000417F4C0D040B2004200B2009100F22000D010B20010D0141010C040B2000417F4C0D0041010C030B200541046A21050B200528020022050D000B41000B2100200A417F4C0440200228020010020B200241106A240020000F0B1013000BAA03010A7F0240200141046A220528020022040440200228020420022D000B2205200541187441187541004822051B21072002280200200220051B2108200141046A21050340200441106A21020240024002400240024002400240200428021420042D001B2206200641187441187541004822091B220A2007200A200749220C1B2206044020082002280200200220091B220B2006100F220D0D010B2007200A490D012006450D032002280200200220091B210B0C020B200D417F4A0D010B200428020022020D04200421050C070B200B20082006100F22020D010B200C0D010C050B2002417F4A0D040B200441046A210520042802042202450D03200521040B20042105200221040C00000B000B200521040B200020052802002202047F4100054120100322022003280200220329020037021020022003280208360218200342003702002003410036020820022004360208200242003702002002410036021C200520023602002002210420012802002802002203044020012003360200200528020021040B2001280204200410262001200128020841016A36020841010B3A0004200020023602000B9B0201087F02400240200041046A22052802002200450D00200128020420012D000B2202200241187441187541004822021B21032001280200200120021B210720052102034002402003200028021420002D001B2201200141187441187541004822091B2208200320084922041B22060440200041106A2201280200200120091B20072006100F22010D010B417F200420082003491B21010B2002200020014100481B210220002001411D764104716A28020022000D000B20022005460D000240200228021420022D001B2200200041187441187541004822061B2204200320042003491B220104402007200241106A2200280200200020061B2001100F22000D010B20032004490D010C020B2000417F4A0D010B200521020B20020B2F002001044020002001280200102420002001280204102420012C001B417F4C0440200128021010020B200110020B0B5701027F2000420037020020004100360208024020010440200141D6AAD5AA014F0D0120002001410C6C2201100322023602002000200120026A2203360208200241002001100A1A200020033602040B20000F0B1007000B9C0401037F2001200020014622033A000C024020030D000340200128020822032D000C0D0102402003200328020822022802002204460440024020022802042204450D0020042D000C0D000C020B024020012003280200460440200321010C010B200320032802042201280200220036020420012000047F2000200336020820032802080520020B36020820032802082200200041046A20002802002003461B20013602002001200336020020032001360208200128020821020B200141013A000C200241003A000C200220022802002200280204220136020020010440200120023602080B2000200228020836020820022802082201200141046A20012802002002461B200036020020002002360204200220003602080F0B02402004450D0020042D000C0D000C010B024020012003280200470440200321010C010B20032001280204220036020020012000047F2000200336020820032802080520020B36020820032802082200200041046A20002802002003461B20013602002001200336020420032001360208200128020821020B200141013A000C200241003A000C200220022802042200280200220136020420010440200120023602080B2000200228020836020820022802082201200141046A20012802002002461B200036020020002002360200200220003602080C020B2004410C6A2101200341013A000C200220002002463A000C200141013A0000200222012000470D000B0B0BC60E01097F024003402001417F6A210A2001417E6A210803402000210203400240024002400240200120026B2203410175220041054D0440024002400240200041026B0E0400010402070B2001417F6A2D000020022D00014D0D0620022F0000210020022001417E6A22012F00003B0000200120003B00000F0B2001417E6A21002001417F6A22072D0000210320022D0003220420022D00014D0440200320044D0D0620022F00022101200220002F00003B0002200020013B000020022D000320022D00014D0D0620022F000221000C0A0B20022F00002101200320044B0440200220002F00003B0000200020013B00000F0B20022F00022103200220013B0002200220033B000020072D000020014180FE03714108764D0D05200220002F00003B0002200020013B00000F0B2002200241026A200241046A200241066A101A1A2001417F6A2D0000200241076A2D00004D0D0420022F0006210020022001417E6A22012F00003B0006200120003B000020022D000720022D00054D0D0420022F00062100200220022F00043B0006200220003B000420022D0003200041087622014F0D04200220022F00023B0004200220003B000220022D000120014F0D040C080B2003413D4C044020022D00052100024020022D0003220420022D000122034D0440200020044D0D0120022F00042100200220022F00023B0004200220003B0002200320004108764F0D01200220022F00003B0002200220003B00000C010B20022F00002103200020044B044020022F00042100200220033B0004200220003B00000C010B20022F00022104200220033B0002200220043B0000200020034180FE03714108764D0D0020022F00042100200220033B0004200220003B00020B200241066A22002001460D04200241046A21040340200022072D000120042D00014B044020072F00002208410876210520072103034002402003200422002F00003B000020002002460440200221000C010B2000417E6A2104200021032000417F6A2D00002005490D010B0B200020083B00000B2007220441026A22002001470D000B0C040B2002200041026D41017422096A21050240200341CF0F4E044020022002200041046D41017422036A22002005200320056A2203101A2106200A2D000020032D00014D0D0120032F00002104200320082F00003B0000200820043B000020032D0001200220096A220441016A2D00004D0440200641016A21060C020B20052F00002107200520032F00003B0000200320073B000020042D000120002D00014D0440200641026A21060C020B20002F00002103200020052F00003B0000200520033B000020002D000120022D00014D0440200641036A21060C020B20022F00002103200220002F00003B0000200020033B0000200641046A21060C010B200A2D000021030240200220096A220041016A2D0000220420022D00014D044041002106200320044D0D0220052F00002103200520082F00003B0000200820033B00004101210620002D000120022D00014D0D0220022F00002100200220052F00003B0000200520003B00000C010B20022F00002100200320044B0440200220082F00003B0000200820003B0000410121060C020B200220052F00003B0000200520003B000041012106200A2D000020004180FE03714108764D0D01200520082F00003B0000200820003B00000B410221060B2008210402402002220741016A2D00002203200220096A2D000122024B0440200821000C010B03402004417E6A22002007460440200741026A21042003200A2D00004B0D0520042008460D060340200320042D00014B044020042F00002100200420082F00003B0000200820003B0000200441026A21040C070B200441026A22042008470D000B0C060B2004417F6A21092000210420092D000020024D0D000B20072F00002103200720002F00003B0000200020033B0000200641016A21060B200741026A220320004F0D01034020052D0001210403402003220241026A210320022D000120044B0D000B03402000417F6A21092000417E6A210020092D000020044D0D000B200220004B0440200221030C030520022F00002104200220002F00003B0000200020043B00002000200520022005461B2105200641016A21060C010B00000B000B2002200241026A200241046A2001417E6A101A1A0C020B024020032005460D0020052D000120032D00014D0D0020032F00002100200320052F00003B0000200520003B0000200641016A21060B20064504402007200310362102200341026A220020011036044020032101200721002002450D060C030B20020D040B200320076B200120036B480440200720031027200341026A21000C040B200341026A2001102720032101200721000C040B200420082200460D00034020072D0001210303402004220241026A2104200320022D00014D0D000B03402000417F6A21052000417E6A2100200320052D00004B0D000B200220004F0D0220022F00002103200220002F00003B0000200020033B00000C00000B000B0B0B0B0F0B200220022F00003B0002200220003B00000B1400200041C413360200200041046A108E0120000B10002002044020002001200210041A0B0B0300010BE803010A7F230041306B220324002001280208220428000021022001200441046A360208200041206A21050240200220002802242204200028022022076B41047522064B04402005200220066B10A101200028022421040C010B200220064F0D002004200720024104746A22024704400340200441746A200441786A2802001018200441706A22042002470D000B0B20002002360224200221040B20042005280200220547044003402005200128020822022800003602002001200241056A2200360208024020022D00042208450D00200541046A210941002106034002402001200041026A220720002F00006A22003602082001200041026A220A20002F00006A360208200341003602102003420037030820071014220241704F0D00024002402002410B4F0440200241106A417071220B100321002003200B41808080807872360210200320003602082003200236020C0C010B200320023A0013200341086A21002002450D010B20002007200210041A0B200020026A41003A00002003200341086A360220200341286A2009200341086A200341206A102C2003280228411C6A200A103D20032C0013417F4C0440200328020810020B200641016A22062008460D02200128020821000C010B0B1013000B200541106A22052004470D000B0B200341306A24000BB103010A7F0240200141046A220528020022040440200228020420022D000B2205200541187441187541004822051B21072002280200200220051B2108200141046A21050340200441106A21020240024002400240024002400240200428021420042D001B2206200641187441187541004822091B220A2007200A200749220C1B2206044020082002280200200220091B220B2006100F220D0D010B2007200A490D012006450D032002280200200220091B210B0C020B200D417F4A0D010B200428020022020D04200421050C070B200B20082006100F22020D010B200C0D010C050B2002417F4A0D040B200441046A210520042802042202450D03200521040B20042105200221040C00000B000B200521040B200020052802002202047F410005412810032202200328020022032902003702102002200328020836021820034200370200200341003602082002200436020820024200370200200241003602242002420037021C200520023602002002210420012802002802002203044020012003360200200528020021040B2001280204200410262001200128020841016A36020841010B3A0004200020023602000B040041010B9D0301077F230041306B220324002003420037032820034200370320200342003703182000280208220628000021042000200641046A2205360208200520002802046B410371220604402000200520066B41046A22053602080B2003420037022820034100360220200320043602182003200536021C200320053602242000200028020820044102746A3602082003410036021020034200370308024020024101480D000240200145044003402000200341086A1016200741016A22072002470D000B20032802082104200328020C1A0C010B03402000200341086A101641002105200328020C2208210420032802082206200847044003400240200520066A22092D000022044504402001200220056C20076A6A41003A00000C010B2001200220056C20076A6A4100200341186A200410102204410120092D0000417F6A7422066A6B200420042006481B3A000020032802082106200328020C21080B200541016A22052008200622046B490D000B0B200741016A22072002470D000B0B2004450D002003200436020C200410020B200341186A100E200341306A24000B0300010B3A01017F2000418410360200200028022C2201044020002001360230200110020B20002802202201044020002001360224200110020B200010020B970301077F230041306B220324002003420037032820034200370320200342003703182000280208220428000021052000200441046A2204360208200420002802046B410371220604402000200420066B41046A22043602080B2003420037022820034100360220200320053602182003200436021C200320043602242000200028020820054102746A36020820034100360210200342003703082000200341086A1016200328020C2206200328020822006B210402402001450D002004450D0020024101480440410021010340200141016A22012004490D000B0C010B200241027421084100210503402001200220056C4102746A21070240200020056A22092D00002204044041012004744101752106410021000340200720004102746A200341186A200441FF0171101020066B3602002002200041016A220047044020092D000021040C010B0B20032802082100200328020C21060C010B200741002008100A1A0B200541016A2205200620006B2204490D000B0B200004402003200036020C200010020B200341186A100E200341306A240020040B960501097F230041306B22062400200641186A2001101C210A200641003602102006420037030802402001450D0002402001417F4A044020062001100322053602082006200536020C2006200120056A360210200121040340200541003A00002006200628020C41016A220536020C2004417F6A22040D000B2001450D0220034102480D01034002402002200320096C4102746A220C280200220741016A220441014D0440200441016B450D01410121070C010B2007411F7520077321044102210503402005220741016A2105200441017522040D000B0B4101210B03400240200C200B4102746A280200220841016A220441014D0440200441016B450D01410121080C010B2008411F7520087321054102210403402004220841016A2104200541017522050D000B0B2008200720072008491B2107200B41016A220B2003470D000B200628020820096A20073A000002402007450D0020034101480D0041012007417F6A742104410021050340200A200C20054102746A28020020046A20071015200541016A22052003470D000B0B200941016A22092001470D000B0C020B1007000B03400240024002402002200320096C4102746A2207280200220441016A220841014D044041012104200841016B0D010C020B2004411F7520047321054102210803402008220441016A2108200541017522050D000B0B200628020820096A20043A000020034101480D0141012004417F6A742108410021050340200A200720054102746A28020020086A20041015200541016A22052003470D000B0C010B200628020820096A41003A00000B200941016A22092001470D000B0B2000200A10192000200628020C200628020822006B2000101D2006280208220004402006200036020C200010020B200A100E200641306A24000B070020002802040BC50201057F02400240024020002802082205200028020422036B410C6D20014F04400340200320022902003702002003200228020836020820002000280204410C6A22033602042001417F6A22010D000C02000B000B2003200028020022046B410C6D220620016A220341D6AAD5AA014F0D01027F41002003200520046B410C6D2205410174220420042003491B41D5AAD5AA01200541AAD5AAD500491B2205450D001A200541D6AAD5AA014F0D032005410C6C10030B22072006410C6C6A22042103034020032002290200370200200320022802083602082003410C6A21032001417F6A22010D000B20042000280204200028020022016B220241746D410C6C6A2104200241014E044020042001200210041A0B20002004360200200020072005410C6C6A360208200020033602042001450D00200110020B0F0B1007000B41800E100C000B880302097F067D230041106B220524002004200428020036020420054100360208200542003703002000044020042000200510340B200241036C220041014E0440200320004102746A210A20042802002106034020012003280208410C6C220B6A2207280200210C20012003280204410C6C220D6A2208280200210420012003280200410C6C22026A22092802002100200220066A220220022A02002008280204B22009280204B222109322122007280208B22009280208B2220E93220F942008280208B2200E93220E2007280204B2201093221394932211923802002002200E200CB22000B2220E932210942004B2200E93220E200F9493220F20022A0204923802042002200E201394201220109493220E20022A0208923802082006200D6A2200201120002A0200923802002000200F20002A0204923802042000200E20002A0208923802082006200B6A2200201120002A0200923802002000200F20002A0204923802042000200E20002A0208923802082003410C6A2203200A490D000B0B200541106A24000BAF0601077F41012102024002400240200120006B410175220341054D04400240024002400240200341026B0E0400010203050B2001417F6A2D000020002D00014D0D0420002F0000210220002001417E6A22002F00003B0000200020023B00000C060B2001417E6A21032001417F6A22062D0000210420002D0003220520002D00014D0440200420054D0D0420002F00022101200020032F00003B0002200320013B000020002D000320002D00014D0D0420002F000221010C050B20002F00002101200420054B0440200020032F00003B0000200320013B00000C060B20002F00022104200020013B0002200020043B000020062D000020014180FE03714108764D0D03200020032F00003B0002200320013B00000C050B2000200041026A200041046A2001417E6A101A1A0C040B2000200041026A200041046A200041066A101A1A2001417F6A2D000020002D00074D0D0120002F0006210320002001417E6A22012F00003B0006200120033B000020002D000720002D00054D0D0120002F00062101200020002F00043B0006200020013B000420002D0003200141087622034F0D01200020002F00023B0004200020013B000220002D000120034F0D010C020B20002D00052102024020002D0003220420002D000122034D0440200220044D0D0120002F00042102200020002F00023B0004200020023B0002200320024108764F0D01200020002F00003B0002200020023B00000C010B20002F00002103200220044B044020002F00042102200020033B0004200020023B00000C010B20002F00022104200020033B0002200020043B0000200220034180FE03714108764D0D0020002F00042102200020033B0004200020023B00020B2001200041066A2202460D02200041046A210402400340200222032D000120042D00014B044020032F00002207410876210820032105034002402005200422022F00003B000020002002460440200021020C010B2002417E6A2104200221052002417F6A2D00002008490D010B0B200220073B0000200641016A22064108460D020B2003220441026A22022001470D000B0C030B200341026A20014621020B20020F0B200020002F00003B0002200020013B00000B41010B940F01177F230041206B2205240002402000280210200028020C6B221441017522064102490D002000280204210220054100360218200542003703100240027F0240027F02400240024002404101200274220B4101742204044020044180808080044F0D012005200B4103742201100322023602102005200220044102746A3602182005200241002001100A20016A3602140B200041186A210F02402004200028021C200028021822026B41027522014B0440200F200420016B100D0C010B200420014F0D002000200220044102746A36021C0B200041246A2110024020042000280228200028022422026B41027522014B04402010200420016B100D0C010B200420014F0D002000200220044102746A3602280B200041306A210E02402000280234200028023022026B220141FF3F4D0440200E4180C00020016B10050C010B20014180C000460D00200020024180406B3602340B200541003602082005420037030002402014044020064180808080044F0D01200520144101742202100322073602002005200720064102746A3602082005200741002002100A20026A3602040B200B417F6A22172006417F6A22166E2104200028020C22022D000341087421014102210320022D000122084108742212210A03400240200A20126C411076210A2003220920044F0D00200941016A2103200A20014B0D010B0B2009410F4D044020140D03410021014100210241000C080B200E28020020022D00003A00002009417F6A210C41012101200641014D0D034101210203402001200C6A2107200028020C210303402001220420002802306A20032D00003A0000200028020C2103200141016A22012007470D000B200E28020020076A200320024101746A2D00003A0000200441026A2101200241016A22022006470D000B200528020022022006200C6C221336020041012103200641014D0D040340200220034102746A2003360200200341016A22032006470D000B20052802102215200641014D0D051A2000280224210D20002802182111200028020C210E41002102034041012103200241016A2104200220066C210C024020020440034020152003200C6A41027422076A200E20034101746A2D0001200A6C410874411076360200200720116A200320096C20026B3602002007200D6A2004360200200341016A22032006470D000C02000B000B034020152003200C6A41027422076A200E20034101746A2D0001410874360200200720116A200320096C3602002007200D6A2004360200200341016A22032006470D000B0B200A20126C411076201220021B210A200422022009470D000B200528021021080C060B1007000B1007000B4100210103402007200141027422046A2001360200200528021020046A200841FF0171410874360200200F28020020046A2001360200201028020020046A4101360200200E28020020016A200220014101746A2D00003A0000200141016A220120064F04402001210220060C0605200028020C220220014101746A2D00012108200528020021070C010B00000B000B20052802002006200C6C22133602000B20052802100B2108410021030340200A20126C411076201220031B210A200341016A22032009470D000B2010280200210D200F28020021110B2008201341027422026A200A360200200220116A41003602002002200D6A2009360200200620096C2102200920166C41016A0B220D200B4F0D00201404400340410021032005280210210A2005280200210941002108410021070340200A200920034102746A2802004102746A28020022042008200420084B22041B21082003200720041B2107200341016A22032006490D000B201028020022112009200741027422156A28020041027422046A280200221341016A210E2004200A6A280200410874210C200F280200220820046A28020021074100210303400240200A200241027422046A200C20034101742209200028020C6A2D00016C411076360200200420086A2001360200200420116A200E3602002000280230220420016A200420076A201310041A200120136A220120002802306A200028020C20096A2D00003A0000200241016A2102200141016A21012003200D6A2017460D00200341016A220320064F0D0020102802002111200F28020021082005280210210A0C010B0B20032006460440200528020020156A2204200428020020066A3602000B200D20166A220D200B490D000C02000B000B0340200D20166A220D200B490D000B0B200204402005280200210C4100210141002103410021080340200C2001410020012006491B22074102746A28020020034D0440200F2802002209200841027422016A2009200341027422046A2802003602002001201028020022016A200120046A280200360200200841016A21080B200741016A2101200341016A22032002470D000B0B0240200B200028021C200028021822026B41027522014B0440200F200B20016B100D0C010B200B20014F0D0020002002200B4102746A36021C0B0240200B2000280228200028022422026B41027522014B04402010200B20016B100D0C010B200B20014F0D0020002002200B4102746A3602280B20052802002200044020052000360204200010020B20052802102200450D0020052000360214200010020B200541206A24000B070041011001000BC82D010B7F230041106B220B240002400240024002400240024002400240024002400240200041F4014D0440419819280200220641102000410B6A4178712000410B491B2205410376220076220141037104402001417F7341017120006A2202410374220441C8196A280200220141086A2100024020012802082203200441C0196A22044604404198192006417E200277713602000C010B41A8192802001A2003200436020C200420033602080B200120024103742202410372360204200120026A220120012802044101723602040C0C0B200541A01928020022084D0D0120010440024041022000742202410020026B722001200074712200410020006B71417F6A22002000410C764110712200762201410576410871220220007220012002762200410276410471220172200020017622004101764102712201722000200176220041017641017122017220002001766A2202410374220341C8196A28020022012802082200200341C0196A22034604404198192006417E2002777122063602000C010B41A8192802001A2000200336020C200320003602080B200141086A210020012005410372360204200120056A22072002410374220220056B2203410172360204200120026A2003360200200804402008410376220441037441C0196A210141AC192802002102027F20064101200474220471450440419819200420067236020020010C010B20012802080B2104200120023602082004200236020C2002200136020C200220043602080B41AC19200736020041A01920033602000C0C0B419C19280200220A450D01200A4100200A6B71417F6A22002000410C764110712200762201410576410871220220007220012002762200410276410471220172200020017622004101764102712201722000200176220041017641017122017220002001766A41027441C81B6A280200220128020441787120056B210320012102034002402002280210220045044020022802142200450D010B200028020441787120056B22022003200220034922021B21032000200120021B2101200021020C010B0B200128021821092001200128020C220447044041A819280200200128020822004D0440200028020C1A0B2000200436020C200420003602080C0B0B200141146A2202280200220045044020012802102200450D03200141106A21020B0340200221072000220441146A220228020022000D00200441106A2102200428021022000D000B200741003602000C0A0B417F2105200041BF7F4B0D002000410B6A22004178712105419C192802002207450D00410020056B2102024002400240027F410020004108762200450D001A411F200541FFFFFF074B0D001A200020004180FE3F6A411076410871220074220120014180E01F6A411076410471220174220320034180800F6A411076410271220374410F7620002001722003726B22004101742005200041156A7641017172411C6A0B220841027441C81B6A2802002203450440410021000C010B20054100411920084101766B2008411F461B7421014100210003400240200328020441787120056B220620024F0D0020032104200622020D0041002102200321000C030B200020032802142206200620032001411D764104716A2802102203461B200020061B21002001200341004774210120030D000B0B200020047245044041022008742200410020006B722007712200450D032000410020006B71417F6A22002000410C764110712200762201410576410871220320007220012003762200410276410471220172200020017622004101764102712201722000200176220041017641017122017220002001766A41027441C81B6A28020021000B2000450D010B0340200028020441787120056B220320024921012003200220011B21022000200420011B210420002802102201047F20010520002802140B22000D000B0B2004450D00200241A01928020020056B4F0D00200428021821082004200428020C220147044041A819280200200428020822004D0440200028020C1A0B2000200136020C200120003602080C090B200441146A2203280200220045044020042802102200450D03200441106A21030B0340200321062000220141146A220328020022000D00200141106A2103200128021022000D000B200641003602000C080B41A019280200220120054F044041AC1928020021000240200120056B220241104F044041A019200236020041AC19200020056A220336020020032002410172360204200020016A2002360200200020054103723602040C010B41AC19410036020041A019410036020020002001410372360204200020016A220120012802044101723602040B200041086A21000C0A0B41A419280200220120054B044041A419200120056B220136020041B01941B019280200220020056A22023602002002200141017236020420002005410372360204200041086A21000C0A0B410021002005412F6A2204027F41F01C280200044041F81C2802000C010B41FC1C427F37020041F41C4280A0808080800437020041F01C200B410C6A41707141D8AAD5AA057336020041841D410036020041D41C41003602004180200B22026A2206410020026B220771220220054D0D0941D01C2802002203044041C81C280200220820026A220920084D0D0A200920034B0D0A0B41D41C2D00004104710D040240024041B0192802002203044041D81C210003402000280200220820034D0440200820002802046A20034B0D030B200028020822000D000B0B410010122201417F460D052002210641F41C2802002200417F6A22032001710440200220016B200120036A410020006B716A21060B200620054D0D05200641FEFFFFFF074B0D0541D01C2802002200044041C81C280200220320066A220720034D0D06200720004B0D060B2006101222002001470D010C070B200620016B200771220641FEFFFFFF074B0D04200610122201200028020020002802046A460D03200121000B200021010240200541306A20064D0D00200641FEFFFFFF074B0D002001417F460D0041F81C2802002200200420066B6A410020006B71220041FEFFFFFF074B0D0620001012417F470440200020066A21060C070B410020066B10121A0C040B2001417F470D050C030B410021040C070B410021010C050B2001417F470D020B41D41C41D41C2802004104723602000B200241FEFFFFFF074B0D012002101222014100101222004F0D012001417F460D012000417F460D01200020016B2206200541286A4D0D010B41C81C41C81C28020020066A2200360200200041CC1C2802004B044041CC1C20003602000B02400240024041B0192802002203044041D81C21000340200120002802002202200028020422046A460D02200028020822000D000B0C020B41A81928020022004100200120004F1B45044041A81920013602000B4100210041DC1C200636020041D81C200136020041B819417F36020041BC1941F01C28020036020041E41C410036020003402000410374220241C8196A200241C0196A2203360200200241CC196A2003360200200041016A22004120470D000B41A419200641586A2200417820016B4107714100200141086A4107711B22026B220336020041B019200120026A220236020020022003410172360204200020016A412836020441B41941801D2802003602000C020B20002D000C4108710D00200120034D0D00200220034B0D002000200420066A36020441B0192003417820036B4107714100200341086A4107711B22006A220136020041A41941A41928020020066A220220006B220036020020012000410172360204200220036A412836020441B41941801D2802003602000C010B200141A819280200220449044041A8192001360200200121040B200120066A210241D81C2100024002400240024002400240034020022000280200470440200028020822000D010C020B0B20002D000C410871450D010B41D81C210003402000280200220220034D0440200220002802046A220420034B0D030B200028020821000C00000B000B200020013602002000200028020420066A3602042001417820016B4107714100200141086A4107711B6A220920054103723602042002417820026B4107714100200241086A4107711B6A220120096B20056B2100200520096A21072001200346044041B019200736020041A41941A41928020020006A2200360200200720004101723602040C030B200141AC1928020046044041AC19200736020041A01941A01928020020006A220036020020072000410172360204200020076A20003602000C030B2001280204220241037141014604402002417871210A0240200241FF014D0440200128020822032002410376220441037441C0196A471A2003200128020C2202460440419819419819280200417E200477713602000C020B2003200236020C200220033602080C010B2001280218210802402001200128020C22064704402004200128020822024D0440200228020C1A0B2002200636020C200620023602080C010B0240200141146A220328020022050D00200141106A220328020022050D00410021060C010B0340200321022005220641146A220328020022050D00200641106A2103200628021022050D000B200241003602000B2008450D0002402001200128021C220241027441C81B6A22032802004604402003200636020020060D01419C19419C19280200417E200277713602000C020B20084110411420082802102001461B6A20063602002006450D010B2006200836021820012802102202044020062002360210200220063602180B20012802142202450D0020062002360214200220063602180B2001200A6A21012000200A6A21000B20012001280204417E7136020420072000410172360204200020076A2000360200200041FF014D04402000410376220141037441C0196A2100027F41981928020022024101200174220171450440419819200120027236020020000C010B20002802080B2101200020073602082001200736020C2007200036020C200720013602080C030B2007027F410020004108762201450D001A411F200041FFFFFF074B0D001A200120014180FE3F6A411076410871220174220220024180E01F6A411076410471220274220320034180800F6A411076410271220374410F7620012002722003726B22014101742000200141156A7641017172411C6A0B220136021C20074200370210200141027441C81B6A21020240419C1928020022034101200174220471450440419C192003200472360200200220073602000C010B20004100411920014101766B2001411F461B742103200228020021010340200122022802044178712000460D032003411D76210120034101742103200220014104716A220428021022010D000B200420073602100B200720023602182007200736020C200720073602080C020B41A419200641586A2200417820016B4107714100200141086A4107711B22026B220736020041B019200120026A220236020020022007410172360204200020016A412836020441B41941801D28020036020020032004412720046B4107714100200441596A4107711B6A41516A22002000200341106A491B2202411B360204200241E01C290200370210200241D81C29020037020841E01C200241086A36020041DC1C200636020041D81C200136020041E41C4100360200200241186A2100034020004107360204200041086A2101200041046A210020012004490D000B20022003460D0320022002280204417E713602042003200220036B220441017236020420022004360200200441FF014D04402004410376220141037441C0196A2100027F41981928020022024101200174220171450440419819200120027236020020000C010B20002802080B2101200020033602082001200336020C2003200036020C200320013602080C040B200342003702102003027F410020044108762200450D001A411F200441FFFFFF074B0D001A200020004180FE3F6A411076410871220074220120014180E01F6A411076410471220174220220024180800F6A411076410271220274410F7620002001722002726B22004101742004200041156A7641017172411C6A0B220036021C200041027441C81B6A21010240419C1928020022024101200074220671450440419C19200220067236020020012003360200200320013602180C010B20044100411920004101766B2000411F461B742100200128020021010340200122022802044178712004460D042000411D76210120004101742100200220014104716A220628021022010D000B20062003360210200320023602180B2003200336020C200320033602080C030B20022802082200200736020C20022007360208200741003602182007200236020C200720003602080B200941086A21000C050B20022802082200200336020C20022003360208200341003602182003200236020C200320003602080B41A419280200220020054D0D0041A419200020056B220136020041B01941B019280200220020056A22023602002002200141017236020420002005410372360204200041086A21000C030B4190194130360200410021000C020B02402008450D000240200428021C220041027441C81B6A220328020020044604402003200136020020010D01419C192007417E2000777122073602000C020B20084110411420082802102004461B6A20013602002001450D010B2001200836021820042802102200044020012000360210200020013602180B20042802142200450D0020012000360214200020013602180B02402002410F4D04402004200220056A2200410372360204200020046A220020002802044101723602040C010B20042005410372360204200420056A22032002410172360204200220036A2002360200200241FF014D04402002410376220141037441C0196A2100027F41981928020022024101200174220171450440419819200120027236020020000C010B20002802080B2101200020033602082001200336020C2003200036020C200320013602080C010B2003027F410020024108762200450D001A411F200241FFFFFF074B0D001A200020004180FE3F6A411076410871220074220120014180E01F6A411076410471220174220520054180800F6A411076410271220574410F7620002001722005726B22004101742002200041156A7641017172411C6A0B220036021C20034200370210200041027441C81B6A21010240024020074101200074220571450440419C192005200772360200200120033602000C010B20024100411920004101766B2000411F461B742100200128020021050340200522012802044178712002460D022000411D76210520004101742100200120054104716A220628021022050D000B200620033602100B200320013602182003200336020C200320033602080C010B20012802082200200336020C20012003360208200341003602182003200136020C200320003602080B200441086A21000C010B02402009450D000240200128021C220041027441C81B6A220228020020014604402002200436020020040D01419C19200A417E200077713602000C020B20094110411420092802102001461B6A20043602002004450D010B2004200936021820012802102200044020042000360210200020043602180B20012802142200450D0020042000360214200020043602180B02402003410F4D04402001200320056A2200410372360204200020016A220020002802044101723602040C010B20012005410372360204200120056A22042003410172360204200320046A2003360200200804402008410376220541037441C0196A210041AC192802002102027F41012005742205200671450440419819200520067236020020000C010B20002802080B2105200020023602082005200236020C2002200036020C200220053602080B41AC19200436020041A01920033602000B200141086A21000B200B41106A240020000BA30100200041013A0035024020002802042002470D00200041013A00342000280210220245044020004101360224200020033602182000200136021020034101470D0120002802304101470D01200041013A00360F0B2001200246044020002802182202410246044020002003360218200321020B20002802304101470D0120024101470D01200041013A00360F0B200041013A00362000200028022441016A3602240B0B4E01017F02402001450D00200141DC1441DC16100B2201450D0020012802082000280208417F73710D00200028020C200128020C41001006450D00200028021020012802104100100621020B20020B5D01017F200028021022034504402000410136022420002002360218200020013602100F0B02402001200346044020002802184102470D01200020023602180F0B200041013A0036200041023602182000200028022441016A3602240B0B0D0020002001200110141092010B1400417F200049044041B512100C000B200010030B0300010B040020000B981702137F017E23004190016B22042400200441003602880120044200370380010240200028027022050440200541ABD5AAD5004F0D012004200541186C2206100322053602840120042005360280012004200520066A360288010B20044100360278200442003703700240200220016B2205410176220604402005417F4C0D0120042006410274220610032205360274200420053602702004200520066A3602780B200441003602682004420037036041C000200035020042018879A76B21052004417F36025C0240200220014D0D00200541016A210D200041D8006A210C2004412C6A2114200441186A2112200441D0006A210F200441CC006A2113200441C8006A210E200441C4006A21100340027F024002400240200428025C2205417F460440024020112004280274200428027022056B4102754F044020042802642004280260470D01200028028401210520032003280200220741016A3602002005417F6A2105410021062004027F02402007200028024C6A2D00004106470D00200C410310102206410171450D00200C200D10100C010B2000280234200028028401410C6C6A2207200536020820072005360204200720053602002000200028028401220541016A3602840120050B22073602400240200028022422090440200920014101746A20073B01000C010B200028022020014102746A20073602000B2006410271450D05200C200D10100C060B2004200520114102746A2802002205360258201141016A21110C030B2004280264220520042802604704402005417C6A22062802002105200420063602640C020B10084180113602001009000B2004417F36025C0B200420053602580B200F2004280280012207200541186C6A2206290210370300200E200629020837030020042006290200370340024020042D00540D0020032003280200220641016A3602002006200028024C6A2D0000220A4104460D0020042004280240221536023C20042004280244221636023820042007200428024C41186C6A2209290208370328200420092902103703302004200929020037032020042007200428025041186C6A220829020837031020122008290210370300200420082902003703082004200428028401220620076B41186D220B36025C2004417F3602040240200A41064B0D000240024002400240024002400240200A41016B0E06030406070500010B200C200D101021050C010B2000280234200028028401410C6C6A2205200428024836020820052015360204200520163602002000200028028401220541016A360284010B200420053602042004280280012206200428024C41186C6A200428025C3602102006200428025041186C6A200428025C41016A36020C2004200428025C41016A220736020002402004280284012205200428028801490440200428023C2109200428020421082004280238210A200428024C210B200541003A0014200520073602102005200B36020C2005200A36020820052008360204200520093602002004200541186A2205360284010C010B20044180016A2004413C6A200441046A200441386A201320041017200428028401210520042802800121060B2004200520066B41186D22073602000240200428027422062004280278490440200620073602002004200641046A3602740C010B200441F0006A2004101F20042802840121050B20052004280288014904402004280204210620042802382107200428023C2109200428025C21082004280250210A200541003A00142005200A3602102005200836020C2005200936020820052007360204200520063602002004200541186A360284010C050B20044180016A200441046A200441386A2004413C6A200441DC006A200F10170C040B200941013A00142007200428022C41186C6A200B3602102007200428025041186C6A200428025C36020C20042004280220220536020420042802880120064B044020042802382107200428023C2109200428022C21082004280250210A200641003A00142006200A3602102006200836020C2006200936020820062007360204200620053602002004200641186A360284010C040B20044180016A200441046A200441386A2004413C6A2014200F10170C030B200841013A00142007200428021841186C6A200B36020C2007200428024C41186C6A200428025C3602102004200428020C220536020420042802880120064B0440200428023C210720042802382109200428024C21082004280218210A200641003A00142006200A3602102006200836020C2006200936020820062005360204200620073602002004200641186A360284010C030B20044180016A2004413C6A200441046A200441386A2013201210170C020B200428026422062004280268470440200620053602002004200641046A3602642004417F36025C0C030B200441E0006A200441D8006A101F2004417F36025C0C020B200941013A0014200841013A00142007200428022C220541186C6A20042802183602102007200428021841186C6A200536020C2004417F36025C200420042802203602040B200428023821050240200028022422060440200620014101746A220620053B01002006200428023C3B0102200620042802043B01040C010B200028022020014102746A220620053602002006200428023C360204200620042802043602080B200141036A21010B20012002490D020C030B2000280234200028028401410C6C6A2207200536020820072005360204200720053602002000200028028401220541016A3602840120050B2107200141016A2109200420073602440240200028022422080440200820094101746A20073B01000C010B200028022020094102746A20073602000B024020064104710440200C200D101021050C010B2000280234200028028401410C6C6A2206200536020820062005360204200620053602002000200028028401220541016A360284010B200141026A2106200420053602480240200028022422070440200720064101746A20053B01000C010B200028022020064102746A20053602000B200420042802840122052004280280016B41186D22063602200240200428027422072004280278490440200720063602002004200741046A3602740C010B200441F0006A200441206A101F20042802840121050B2004200641026A22073602202004200641016A2209360208024020052004280288014904402004290244211720042802402108200541003A0014200520093602102005200736020C20052008360208200520173702002004200541186A2205360284010C010B20044180016A2010200E200441406B200441206A200441086A101720042802840121050B200420052004280280016B41186D220A36022002402004280274220820042802784904402008200A3602002004200841046A3602740C010B200441F0006A200441206A101F20042802840121050B200420063602202004200736020802402005200428028801490440200428024821082004280240210A2004280244210B200541003A0014200520073602102005200636020C2005200B3602082005200A360204200520083602002004200541186A2205360284010C010B20044180016A200E200441406B2010200441206A200441086A101720042802840121050B200420052004280280016B41186D22083602200240200428027422072004280278490440200720083602002004200741046A3602740C010B200441F0006A200441206A101F20042802840121050B200141036A21012004200936022020042006360208024020052004280288014904402004290240211720042802482107200541003A0014200520063602102005200936020C20052007360208200520173702002004200541186A360284010C010B20044180016A200441406B2010200E200441206A200441086A10170B20012002490D000B0B20042802602200044020042000360264200010020B20042802702200044020042000360274200010020B200428028001220004402004200036028401200010020B20044190016A24000F0B41AD11100C000B41AD11100C000BEB0101067F20002802082203200028020422026B410C6D20014F0440200020022001410C6C6A3602040F0B02402002200028020022026B2205410C6D220620016A220441D6AAD5AA01490440027F41002004200320026B410C6D2203410174220720072004491B41D5AAD5AA01200341AAD5AAD500491B2204450D001A200441D6AAD5AA014F0D022004410C6C10030B22072006410C6C6A2206200541746D410C6C6A2103200541014E044020032002200510041A0B20002003360200200020072004410C6C6A360208200020062001410C6C6A36020420020440200210020B0F0B1007000B41AD11100C000BC10401067F230041206B220324002003410036021820034200370310200041206A200041F8006A2206102B20002802142201200041186A2205470440034020032001220241106A10112003200228021C220136020C200120002802002006200128020028021C11000020032C000B417F4C0440200328020010020B024020022802042204450440200228020822012802002002460D01200241086A210203402002280200220441086A2102200420042802082201280200470D000B0C010B03402004220128020022040D000B0B20012005470D000B200028021421010B024020012005460D00034020032001220241106A10112003200228021C220136020C20012000280200200341106A200128020028022011000020032C000B417F4C0440200328020010020B024020022802042204450440200228020822012802002002460D01200241086A210203402002280200220441086A2102200420042802082201280200470D000B0C010B03402004220128020022040D000B0B20012005470D000B200028021422042005460D00034020032004220241106A10112003200228021C220136020C20012000280200200128020028022811010020032C000B417F4C0440200328020010020B024020022802042201450440200228020822042802002002460D01200241086A210203402002280200220141086A2102200120012802082204280200470D000B0C010B03402001220428020022010D000B0B20042005470D000B0B20032802102200044020032000360214200010020B200341206A24000B800801087F230041206B22042400200041206A2208200041F8006A2205102B200020002802800122012800003602702000200141046A360280012005200041CC006A1016200028028001220328000021012000200341046A2203360280012003200028027C6B410371220204402000200320026B41046A2203360280010B2000420037026820004100360260200020013602582000200336025C20002003360264200020002802800120014102746A3602800120002802142201200041186A22064704400340200441106A2001220241106A10112004200228021C220136021C200120002802002005200128020028021C11000020042C001B417F4C0440200428021010020B024020022802042203450440200228020822012802002002460D01200241086A210303402003280200220241086A2103200220022802082201280200470D000B0C010B03402003220128020022030D000B0B20012006470D000B0B0240200028020022012000280238200041346A220728020022026B410C6D22034B04402007200120036B10420C010B200120034F0D00200020022001410C6C6A3602380B410021012004410036020C200041406B28020022032000280244220247044003402000200141036C200328020041036C2004410C6A104120032802002101200341106A2205210320022005470D000B0B0240200041146A220528020022012006460D000340200441106A2001220241106A10112004200228021C220136021C200120002802002007200128020028022011000020042C001B417F4C0440200428021010020B024020022802042203450440200228020822012802002002460D01200241086A210303402003280200220241086A2103200220022802082201280200470D000B0C010B03402003220128020022030D000B0B20012006470D000B200528020022012006460D000340200441106A2001220241106A10112004200228021C220136021C20012000280200200028020420052008200128020028022411060020042C001B417F4C0440200428021010020B024020022802042203450440200228020822012802002002460D01200241086A210303402003280200220241086A2103200220022802082201280200470D000B0C010B03402003220128020022030D000B0B20012006470D000B200528020022012006460D000340200441106A2001220241106A10112004200228021C220136021C20012000280200200128020028022811010020042C001B417F4C0440200428021010020B024020022802042203450440200228020822012802002002460D01200241086A210303402003280200220241086A2103200220022802082201280200470D000B0C010B03402003220128020022030D000B0B20012006470D000B0B200441206A24000BFE0101037F230041306B220324002003418080802836021020034200370308200341003A000D200341FA10280000360208200341FE102D00003A000C200041146A2204200341086A1023210520032C0013417F4C0440200328020810020B2005200041186A470440200341808080283602102003420037030841002100200341FA10280000360208200341FE102D00003A000C200341003A000D2003200341086A360220200341286A2004200341086A200341206A1022200328022828021C22040440200441B40B41F00F100B21000B20032C0013417F4C0440200328020810020B2000200236024820002001360204200041043602140B200341306A24000BED0201057F230041106B2204240020002802142201200041186A2205470440034020042001220341106A10112004200128021C220136020C20010440200120012802002802041103000B20042C000B417F4C0440200428020010020B024020032802042202450440200328020822012802002003460D01200341086A210203402002280200220341086A2102200320032802082201280200470D000B0C010B03402002220128020022020D000B0B20012005470D000B0B200041D8006A100E200028024C2201044020002001360250200110020B200041406B28020022010440027F2001200120002802442202460D001A0340200241746A200241786A2802001018200241706A22022001470D000B20002802400B210220002001360244200210020B20002802342201044020002001360238200110020B2000280228220104402000200136022C200110020B200041146A20002802181024200041086A200028020C1018200441106A240020000B0900200041870810210B8F03010A7F0240200141046A220528020022040440200228020420022D000B2205200541187441187541004822051B21072002280200200220051B2108200141046A21050340200441106A21020240024002400240024002400240200428021420042D001B2206200641187441187541004822091B220A2007200A200749220C1B2206044020082002280200200220091B220B2006100F220D0D010B2007200A490D012006450D032002280200200220091B210B0C020B200D417F4A0D010B200428020022020D04200421050C070B200B20082006100F22020D010B200C0D010C050B2002417F4A0D040B200441046A210520042802042202450D03200521040B20042105200221040C00000B000B200521040B200020052802002202047F41000541201003220241106A2003280200101120022004360208200242003702002002410036021C200520023602002002210420012802002802002203044020012003360200200528020021040B2001280204200410262001200128020841016A36020841010B3A0004200020023602000B830901097F230041306B220224002000410C6A22034200370200200041186A220442003702002000200336020820002004360214200041206A410041D400100A1A200042003702800120004201370278024002400240200141037145044020002001360280012000200136027C200128000021032000200141046A3602800120034180C6E9C307470D012000200141096A36028001200020012D00083602782001280009210420002001410D6A2201360280012004450D03200041086A210803402000200141026A220620012F00006A2201360280012000200141026A220520012F00006A36028001200241003602102002420037030820061014220141704F0D03024002402001410B4F0440200141106A4170712209100321032002200941808080807872360210200220033602082002200136020C0C010B200220013A0013200241086A21032001450D010B20032006200110041A0B200120036A41003A00002002200241086A360220200241286A2008200241086A200241206A102C2002280228411C6A2005103D20022C0013417F4C0440200228020810020B2000280280012101200741016A22072004470D000B0C030B100841C4103602001009000B100841EA103602001009000B1013000B200128000021062000200141046A2201360280010240200641014E0440200041146A21094100210803402000200141026A220520012F00006A220136028001200241003602102002420037030820051014220341704F0D02024002402003410B4F0440200341106A4170712207100321042002200741808080807872360210200220043602082002200336020C0C010B200220033A0013200241086A21042003450D010B20042005200310041A0B200320046A41003A0000200128000021042000200141046A36028001200128000421052000200141096A3602800120012D0008210320002001410A6A3602800120012D0009210720002001410B6A3602800120012D000A210A02402004417E6A220141014D0440200141016B044041C8001003220141B40D36020020014201370214200142003702242001420037022C200142003702342001420037023C200141003602442001428080808030370204200141003602202001430000004438020C200141023602100C020B41CC0010032201420037020420014104360248200141900F36020020014284808080800137024020014284808080C0003702382001420037020C20014200370220200142013702142001420037022820014200370230200120033602080C010B4138100322014200370204200141FC113602002001420037020C20014201370214200142003702202001420037022820014200370230200120033602080B2001200536020C2001200A360210200120073602142002200241086A360220200241286A2009200241086A200241206A10482002280228200136021C20022C0013417F4C0440200228020810020B2000280280012101200841016A22082006470D000B0B200020012800003602002000200141046A36028001200020012800043602042000200141086A36028001200241306A240020000F0B1013000BB10602047F027D024020002802042204450D002000280214220341074B0D00200028020820016C210202400240024002400240024002400240200341016B0E0703060200040105070B2002450D072004027F20002A020C20042C0000B29422068B430000004F5D04402006A80C010B4180808080780B3A00004101210320024101460D072000220121040340027F20012A020C200428020420036A22052C0000B29422068B430000004F5D04402006A80C010B4180808080780B2100200520003A0000200341016A22032002470D000B0C070B2002450D06410021010340200420014102746A20002A020C200120046A2D0000B394380200200141016A22012002470D000B0C060B2002450D0520002A020C2107410021010340027F2007200420014101746A22032F0100B3942206430000804F5D20064300000000607104402006A90C010B41000B2100200320003B0100200141016A22012002470D000B0C050B2002450D0420002A020C2107410021010340027F2007200420014102746A2203280200B3942206430000804F5D20064300000000607104402006A90C010B41000B210020032000360200200141016A22012002470D000B0C040B2002450D032004027F20002A020C20042C0000B29422068B430000004F5D04402006A80C010B4180808080780B3A00004101210320024101460D032000220121040340027F20012A020C200428020420036A22052C0000B29422068B430000004F5D04402006A80C010B4180808080780B2100200520003A0000200341016A22032002470D000B0C030B2002450D0220002A020C2106410021010340200420014103746A2006200120046A2D0000B394BB390300200141016A22012002470D000B0C020B2002450D0120002A020C2107410021010340027F2007200420014101746A22032F0100B3942206430000804F5D20064300000000607104402006A90C010B41000B2100200320003B0100200141016A22012002470D000B0C010B2002450D0020002A020C2107410021010340027F2007200420014102746A2203280200B3942206430000804F5D20064300000000607104402006A90C010B41000B210020032000360200200141016A22012002470D000B0B0B840301067F230041306B220324002003420037032820034200370320200342003703182000280208220428000021052000200441046A2204360208200420002802046B410371220604402000200420066B41046A22043602080B2003420037022820034100360220200320053602182003200436021C200320043602242000200028020820054102746A36020820034100360210200342003703082000200341086A1016200328020C2206200328020822006B210402402001450D002004450D0041002105200241014E044003402001200220056C6A21070240200020056A22082D00002204044041012004744101762106410021000340200020076A200341186A200441FF0171101020066B3A00002002200041016A220047044020082D000021040C010B0B20032802082100200328020C21060C010B200741002002100A1A0B200541016A2205200620006B490D000C02000B000B0340200541016A22052004490D000B0B200004402003200036020C200010020B200341186A100E200341306A24000B2E01017F200028020821012000280204210320002D00104102710440200220032001104B0F0B200220032001102E0BC00301087F230041306B22082400200841186A2001101C2109200841086A200310252105024020034101480D00200104400340027F02402005280200200A410C6C6A220622072802042006280200220B6B220420014F0440200420014D0D0120072001200B6A36020441000C020B2006200120046B10050B41000B2104034002402002200320046C200A6A6A2D000022070440200628020020046A41C1002007AD42018879A76B220B3A000020092007200B10150C010B200628020020046A41003A00000B200441016A22042001470D000B200A41016A220A2003470D000B0C010B20052802002101034020012004410C6C6A2202220628020420022802002202470440200620023602040B200441016A22042003470D000B0B2000200910194100210420052802002101200341004A04400340200020012004410C6C6A2201280204200128020022016B2001101D20052802002101200441016A22042003470D000B0B20010440027F2001200120052802042200460D001A0340200041746A220228020022030440200041786A2003360200200310020B200222002001470D000B20052802000B210020052001360204200010020B2009100E200841306A24000BF90301077F230041306B22062400200641186A2001101C21092006410036021020064200370308024002402001450D002001417F4C0D0120062001100322043602082006200436020C2006200120046A360210200121050340200441003A00002006200628020C41016A220436020C2005417F6A22050D000B2001450D00200341024E0440034041222002200320076C6A220A2D00002205410176676B410020051B210441012105034041222005200A6A2D00002208410176676B410020081B2208200420042008481B2104200541016A22052003470D000B200628020820076A20043A000002402004450D0020034101480D0041012004417F6A742108410021050340200920082005200A6A2D00006A20041015200541016A22052003470D000B0B200741016A22072001470D000C02000B000B034002402002200320076C6A220A2D00002205450440200628020820076A41003A00000C010B200628020820076A412220054101766722046B22053A00002005450D0020034101480D004101412120046B742108410021040340200920082004200A6A2D00006A20051015200441016A22042003470D000B0B200741016A22072001470D000B0B2000200910192000200628020C200628020822006B2000101D2006280208220004402006200036020C200010020B2009100E200641306A24000F0B1007000B6901027F2002200228020820022802046B36021020002802082103200028022C2104024020002D001041027104402002200120042003104E0C010B2002200120042003104D0B200228021021012002200228020820022802046B22023602102000200220016B3602180B0900200041800810210B9A0603077F017D017C200041206A21080240200028020820016C22032000280224200028022022046B22014B04402008200320016B10050C010B200320014F0D002000200320046A3602240B024020032000280230200028022C22046B22014B04402000412C6A200320016B10050C010B200320014F0D002000200320046A3602300B0240024002400240024002402000280214417F6A220141064B0D000240200141016B0E06010301040500020B2003450D05410021010340200028022020016A027F200220014103746A2B030020002A020CBBA3220B44000000000000F04163200B44000000000000000066710440200BAB0C010B41000B3A0000200141016A22012003470D000B0C050B100841B0103602001009000B2003450D03410021010340200028022020016A027F200220014102746A280200B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A0000200141016A22012003470D000B0C030B2003450D02410021010340200028022020016A027F200220014101746A2E0100B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A0000200141016A22012003470D000B0C020B2003450D01410021010340200028022020016A027F200120026A2C0000B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A0000200141016A22012003470D000B0C010B2003450D00410021010340200028022020016A027F200220014102746A2A020020002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A0000200141016A22012003470D000B0B2000410036021C2000280208220441014E044003402008280200220920056A2D000021020240200520034F0440200221010C010B20022101200420056A220620034F0D000340200620096A2D00002207200120012007491B210120072002200220074A1B2102200420066A22062003490D000B0B2000200028021C220441C00020012002417F736AAC42018879A76B220141016A200420014A1B36021C200541016A220520002802082204480D000B0B0BC80301067F024020002802042205450D00200228020421042002280200210320002D00104101710440200420036B410C6D4102490D012000220641086A2802002100410121010340200041014E044020032001410C6C6A220421074100210303402005200020016C20036A6A220820082D00002005200428020420006C20036A6A2D00002005200428020020006C20036A6A2D00006A2005200728020820006C20036A6A2D00006B6A3A0000200341016A220320062802082200480D000B20022802042104200228020021030B200141016A2201200420036B410C6D490D000B0C010B20032004470440200420036B410C6D4102490D012000220641086A2802002100410121010340200041014E044020032001410C6C6A21044100210303402005200020016C20036A6A220720072D00002005200428020020006C20036A6A2D00006A3A0000200341016A220320062802082200480D000B20022802042104200228020021030B200141016A2201200420036B410C6D490D000B0C010B2000220241086A2802002200200020016C4F0D00200021030340200320056A220620062D00002005200320006B6A2D00006A3A0000200341016A22032002280208220020016C490D000B0B0B5201037F2000280208220441014E04402002280208210103402002200141016A2205360208200020034102746A20012D000036023820052101200341016A22032004480D000B0B200220002802042004102E0BE30301087F230041306B22092400200941186A2001101C210A200941086A200310252106024020034101480D00200104400340027F02402006280200200B410C6C6A22082205280204200828020022076B220420014F0440200420014D0D012005200120076A36020441000C020B2008200120046B10050B41000B2104034002402002200320046C200B6A6A2C000022050440200828020020046A41C10020052005411F7522076A200773AD42018879A76B22073A0000200A4100200541012007744101756A6B200520054100481B200710150C010B200828020020046A41003A00000B200441016A22042001470D000B200B41016A220B2003470D000B0C010B2006280200210241002101034020022001410C6C6A2204220528020420042802002204470440200520043602040B200141016A22012003470D000B0B2000200A10194100210120062802002104200341004A04400340200020042001410C6C6A2202280204200228020022026B2002101D20062802002104200141016A22012003470D000B0B20040440027F2004200420062802042200460D001A0340200041746A220128020022020440200041786A2002360200200210020B200122002004470D000B20062802000B210020062004360204200010020B200A100E200941306A24000BC10101057F200220022802082204200228020422036B3602100240200028020822054101480D00200241046A21070340200020064102746A28023821050240200420036B2204417F470440200741011005200728020021030C010B200220033602080B200320046A20053A0000200641016A2206200028020822054E0D0120022802082104200228020421030C00000B000B20022001200028022C20051054200228021021012002200228020820022802046B22023602102000200220016B3602180BD10301087F2000280208220341014E04400340200028022C20026A2000280220200128020028020020036C20026A6A2D00003A0000200241016A220220002802082203480D000B0B2001280204200128020022026B410475220441024F0440410121060340200220064104746A22052108024002402005280204220420052802082209460D0020002D0010410171450D0020034101480D01410021020340200028022C200320066C20026A6A20002802202207200528020020036C20026A6A2D00002007200320046C20026A6A2D00006B2007200320096C20026A6A2D00006B2007200528020C20036C20026A6A2D00006A3A0000200241016A2202200028020822034E0D0220052802082109200828020421040C00000B000B20034101480D00410021020340200028022C200320066C20026A6A20002802202207200528020020036C20026A6A2D00002007200320046C20026A6A2D00006B3A0000200241016A2202200028020822034E0D01200828020421040C00000B000B200641016A22062001280204200128020022026B4104752204490D000B0B200320046C22012000280230200028022C22036B22024B04402000412C6A200120026B10050F0B200120024904402000200120036A3602300B0B040041030B3801017F2000418410360200200028022C2201044020002001360230200110020B20002802202201044020002001360224200110020B20000BDC0401077F230041106B220324000240024020002802042206450D00024002402000280214417C6A220241024B0D000240200241016B0E020102000B2000280208210420002802482107200341FF013A0003200120046C22024101480D02200220066A21082006200120076C6A21050340200820046B210841002102200441004A04400340200220036A200220086A2D00003A0000200241016A22022004470D000B0B200520076B2105200320032D00002201410874200120032D00026A41FF01717220032D000120016A41FF01714110747220032D00034118747236020041002102200741004A04400340200220056A200220036A2D0000200020024102746A2D00386C3A0000200241016A220220002802482207480D000B200028020421060B200820064D0D03200028020821040C00000B000B100841E50E3602001009000B2003410036020820034200370300200145044041002006200141027410041A0C010B20014180808080044F0D01200320014102742205100322023602002003200220056A22043602082003200436020420022006200510041A410021050340200220054102746A220220022D00002204410874200420022D00026A41FF01717220022D000120046A41FF01714110747220022D000341187472360000410021022000280248220441004A044003402006200241027422076A220820082A0200200020076A280238B2944300007F4395380200200241016A22022004480D000B0B200620044102746A210620032802002102200541016A22052001470D000B2002450D0020032002360204200210020B200341106A24000F0B1007000BA80502077F017D230041106B220424000240200028020820016C22032000280224200041206A220528020022076B22064B04402005200320066B10050C010B200320064F0D002000200320076A3602240B0240200320002802302000412C6A220728020022086B22064B04402007200320066B10050C010B200320064F0D002000200320086A3602300B0240024002402000280214417C6A220341024B0D000240200341016B0E020102000B2001450D02200528020021062000280208210541002107034041002103200541004A044003402004410C6A20036A200220036A2D0000200020034102746A2802386D3A0000200341016A22032005480D000B0B200420042D000E20042D000D22036B41FF017141087420037220042D000C20036B41FF01714110747220042D000F4118747236020C41002103200541004A04400340200320066A2004410C6A20036A2D00003A0000200341016A220320002802082205480D000B0B200520066A2106200220056A2102200741016A22072001470D000B0C020B1008220041C50E3602001009000B200441FF013A000B2001450D00200028020821052000280220210741002108034041002103200541004A044003402000200341027422066A2802382109200441086A20036A027F200220066A2A02004300007F4394220A8B430000004F5D0440200AA80C010B4180808080780B20096D3A0000200341016A22032005480D000B0B200420042D000A20042D000922036B41FF017141087420037220042D000820036B41FF01714110747220042D000B4118747236020841002103200541004A04400340200320076A200441086A20036A2D00003A0000200341016A220320002802082205480D000B0B200520076A2107200220054102746A2102200841016A22082001470D000B0B2000410036021C200441106A24000B040041020B5201017F200041B40D360200200028023C22010440200041406B2001360200200110020B20002802302201044020002001360234200110020B20002802242201044020002001360228200110020B200010020B5001017F200041B40D360200200028023C22010440200041406B2001360200200110020B20002802302201044020002001360234200110020B20002802242201044020002001360228200110020B20000B950502077F047D02402000280204450D0020002802200D00024002402000280214417D6A220241034B0D000240200241016B0E03010102000B2001450D020340200028023C2202200541037422064104726A280200411074220341107522042003411F7522036A2003732103200220066A280200411074220241107522062002411F7522026A2002732107027F20002A020C22098B430000004F5D04402009A80C010B4180808080780B220220076B220720036B2208B2210A027D2008417F4A04402006B2210B2004B20C010B200220036B2202410020026B200641004A1BB2210B2007410020076B200441004A1BB20B21092000280204200541066C6A2204027F200A200A200A942009200994200B200B94929291220A954300FEFF4694220C8B430000004F5D0440200CA80C010B4180808080780B3B01042004027F2009200A954300FEFF469422098B430000004F5D04402009A80C010B4180808080780B3B01022004027F200B200A954300FEFF469422098B430000004F5D04402009A80C010B4180808080780B3B0100200541016A22052001470D000B0C020B1008220041E30C3602001009000B2001450D000340200028023C2202200541037422034104726A28020022042004411F7522066A2006732106200220036A28020022022002411F7522036A2003732107027F20002A020C22098B430000004F5D04402009A80C010B4180808080780B220320076B220720066B2208B221092008417F4C0440410020076B200720044101481B21044100200320066B22036B200320024101481B21020B20002802042005410C6C6A2203200920092009942004B222092009942002B2220B200B94929291220A9538020820032009200A953802042003200B200A95380200200541016A22052001470D000B0B0BBB04020B7F047D2002280204200228020022036B2204410C6D210B02402004450D00200028023C210C034020012008410C6C22056A2104200320056A21030240024020002802204101470440200028022420084102746A280200450D010B20032A020022108B20032A020422118B9220032A0208220E8B92210F200E43000000005D4101732103027F20002A020C220E8B430000004F5D0440200EA80C010B4180808080780B21052011200F95210E2010200F95210F024020030440200F21100C010B430000803F200E8B93220E8C200E201043000000005D1B2110430000803F200F8B93210E201143000000005D4101730D00200E8C210E0B027F200E2005B2220F94220E8B430000004F5D0440200EA80C010B4180808080780B200C20094103746A22062802046A22032003411F7522076A200773210A2005027F2010200F94220F8B430000004F5D0440200FA80C010B4180808080780B20062802006A22072007411F7522066A2006736B2206200A6B220DB2210F200D417F4C044041002005200A6B22056B200520074101481B2107410020066B200620034101481B21030B200941016A210920042007B22210200F200F942003B2220E200E9420102010949292912210953802002004200F2010953802082004200E2010953802040C010B200420032A0200220F200F200F9420032A0204220F200F949220032A020822102010949291220E9538020020042010200E953802082004200F200E953802040B200841016A2208200B4F0D01200228020021030C00000B000B0B08002000200110210BBD06020A7F047D2002280204200228020022046B2203410C6D210A02402003450D00200028023C210B034020042006410C6C6A21030240024020002802204101470440200028022420064102746A280200450D010B20032A0200220F8B20032A020422108B9220032A0208220D8B92210E200D43000000005D4101732103027F20002A020C220D8B430000004F5D0440200DA80C010B4180808080780B21042010200E95210D200F200E95210E024020030440200E210F0C010B430000803F200D8B93220D8C200D200F43000000005D1B210F430000803F200E8B93210D201043000000005D4101730D00200D8C210D0B027F200D2004B2220E94220D8B430000004F5D0440200DA80C010B4180808080780B200B20084103746A22052802046A411074220741107522032007411F7522076A20077321072004027F200F200E94220F8B430000004F5D0440200FA80C010B4180808080780B20052802006A411074220541107522092005411F7522056A2005736B220520076B220CB2210D027D200C417F4A04402003B2210E2009B20C010B2005410020056B200341004A1BB2210E200420076B2204410020046B200941004A1BB20B210F2001200641066C6A2204027F200D200D200D94200E200E94200F200F94929291220D954300FEFF469422108B430000004F5D04402010A80C010B4180808080780B3B0104200841016A21082004027F200E200D954300FEFF4694220E8B430000004F5D0440200EA80C010B4180808080780B3B0102200F200D954300FEFF4694220F8B430000004F5D04402004200FA83B01000C020B20044180808080783B01000C010B20032A0200220F200F9420032A0204220E200E949220032A0208220D200D949291221043ACC527375D4101734504402003410036020020034100360204200341808080FC033602080C010B2001200641066C6A2204027F4300FEFF462010952210200D94220D8B430000004F5D0440200DA80C010B4180808080780B3B01042004027F2010200E94220E8B430000004F5D0440200EA80C010B4180808080780B3B01022004027F2010200F94220F8B430000004F5D0440200FA80C010B4180808080780B3B01000B200641016A2206200A4F0D01200228020021040C00000B000B0B880302097F067D230041106B220524002004200428020036020420054100360208200542003703002000044020042000200510340B200241036C220041014E0440200320004101746A210A200428020021060340200120032F0104410C6C220B6A2207280200210C200120032F0102410C6C220D6A22082802002104200120032F0100410C6C22026A22092802002100200220066A220220022A02002008280204B22009280204B222109322122007280208B22009280208B2220E93220F942008280208B2200E93220E2007280204B2201093221394932211923802002002200E200CB22000B2220E932210942004B2200E93220E200F9493220F20022A0204923802042002200E201394201220109493220E20022A0208923802082006200D6A2200201120002A0200923802002000200F20002A0204923802042000200E20002A0208923802082006200B6A2200201120002A0200923802002000200F20002A0204923802042000200E20002A020892380208200341066A2203200A490D000B0B200541106A24000BCD0701047F230041306B22052400024002400240024002402000280204450D002000280220450D0020054100360210200541003A0010200542F0DECDCBC6AEDAB7EE00370308200541083A00132003200541086A1023210620052C0013417F4C0440200528020810020B2006200341046A460D0120054100360210200541003A0010200542F0DECDCBC6AEDAB7EE00370308200541083A00132005200541086A360220200541286A2003200541086A200541206A1022200528022828021C22030440200341B40B41D40B100B21070B20052C0013417F4C0440200528020810020B2007450D02200541003602102005420037030820010440200141D6AAD5AA014F0D0420052001410C6C2206100322033602082005200336020C2005200320066A360210200341002006100A1A2001210603402003410C6A21032006417F6A22060D000B2005200336020C0B2007280204210302402004280200220604402001200320022006200541086A10350C010B2001200320022004280204200541086A10620B024020002802204102470D002004280200220304402000200028022436022820054100360228200041246A21042001044020042001200541286A101B0B200241036C22014101480D01200320014102746A2102200428020021010340200120032802004102746A22042004280200200328020473360200200120032802004102746A22042004280200200328020873360200200120032802044102746A22042004280200200328020873360200200120032802044102746A22042004280200200328020073360200200120032802084102746A22042004280200200328020073360200200120032802084102746A220420042802002003280204733602002003410C6A22032002490D000B0C010B200428020421032000200028022436022820054100360228200041246A21042001044020042001200541286A101B0B200241036C22014101480D00200320014101746A2107200428020021010340200120032F010022024102746A220820032F0104220420032F0102220620082802007373360200200120064102746A22082008280200200220047373360200200120044102746A22042004280200200220067373360200200341066A22032007490D000B0B0240024002402000280214417D6A220141034B0D000240200141016B0E03010102000B20002000280204200541086A10610C020B100841A50C3602000C060B20002000280204200541086A105F0B20052802082200450D002005200036020C200010020B200541306A24000F0B100841DD0A3602000C020B100841E00B3602000C010B1007000B1009000BE20101037F02402000280204450D0020002802200D002002280204200228020022056B2202410C6D21032002044020034102490D01200028023C21004101210203402000200241037422016A22042004280200200020052002410C6C6A22042802004103746A2802006A360200200020014104726A22012001280200200020042802004103744104726A2802006A360200200241016A22022003470D000B0C010B200141017422024103490D00200028023C2103410221000340200320004102746A22012001280200200141786A2802006A360200200041016A22002002470D000B0B0BC80101037F20022002280208220341016A360208200020032D00003602202000413C6A2103024020014101742204200041406B280200200028023C22016B41027522054B04402003200420056B100D200328020021010C010B200420054F0D00200041406B200120044102746A3602000B20022001410210312101024020002802204102470D0020014101742201200041406B280200200028023C22046B41027522024B04402003200120026B100D0F0B200120024F0D00200041406B200420014102746A3602000B0B970101027F2000280220210302402002280208200228020422016B2204417F470440200241046A41011005200228020421010C010B200220013602080B200120046A20033A00002002200228020820022802046B3602102002200041406B280200200028023C22016B410275410176200141021032200228021021012002200228020820022802046B22023602102000200220016B3602180BFB0301087F0240024002402000280220220304402001280204220420012802002205460D01200420056B4104752106410021010340200520014104746A22072802002104024020034102460440200028022420044102746A280200450D010B200028023C2203200241037422086A2000280230220920044103746A280200360200200320084104726A200920072802004103744104726A280200360200200241016A21020B200141016A220120064F0D02200028022021030C00000B000B200028023C220320002802302205200128020022042802004103746A2802003602002003200520042802004103744104726A28020036020441012102200128020420046B2206410475220741014B044003402003200241037422086A2005200420024104746A22012802004103746A280200200520012802044103746A2802006B360200200320084104726A200520012802004103744104726A280200200520012802044103744104726A2802006B360200200241016A22022007490D000B0B20064103752201200041406B28020020036B41027522024B04400C030B200120024F0D01200041406B200320014102746A3602000F0B20024101742201200041406B280200200028023C22036B41027522024B04400C020B200120024F0D00200041406B200320014102746A3602000B0F0B2000413C6A200120026B100D0BE00602027F067D230041306B2205240002402000280220450D0020054100360210200541003A0010200542F0DECDCBC6AEDAB7EE00370308200541083A00132003200541086A1023210620052C0013417F4C0440200528020810020B0240024002402006200341046A4704404100210620054100360210200541003A0010200542F0DECDCBC6AEDAB7EE00370308200541083A00132005200541086A360220200541286A2003200541086A200541206A1022200528022828021C22030440200341B40B41D40B100B21060B20052C0013417F4C0440200528020810020B2006450D012004280208210320054100360210200542003703082001200628022020022003200541086A1035024020002802204102470D002000200028022436022820054100360228200041246A21042001044020042001200541286A101B0B200241036C22024101480D00200320024102746A2106200428020021020340200220032802004102746A22042004280200200328020473360200200220032802004102746A22042004280200200328020873360200200220032802044102746A22042004280200200328020873360200200220032802044102746A22042004280200200328020073360200200220032802084102746A22042004280200200328020073360200200220032802084102746A220420042802002003280204733602002003410C6A22032006490D000B0B200528020821022001450D0220002802302104027F20002A020C22078B430000004F5D04402007A80C010B4180808080780BB2210A41002103034020022003410C6C6A22002A0204220B20002A020022098B200B8B9220002A0208220C8B922207952108200920079521070240200C43000000005D4101730440200721090C010B430000803F20088B9322088C2008200943000000005D1B2109430000803F20078B932108200B43000000005D4101730D0020088C21080B200420034103746A22002000280200027F2009200A9422078B430000004F5D04402007A80C010B4180808080780B6B36020020002000280204027F2008200A9422078B430000004F5D04402007A80C010B4180808080780B6B360204200341016A22032001470D000B0C030B100841DD0A3602001009000B100841E00B3602001009000B2002450D010B2005200236020C200210020B200541306A24000BCA0C04097F017E047D027C200041306A210B0240200141017422032000280234200028023022056B410275220A4B0440200B2003200A6B100D0C010B2003200A4F0D002000200520034102746A3602340B02402003200041406B280200200028023C22056B410275220A4B04402000413C6A2003200A6B100D0C010B2003200A4F0D00200041406B200520034102746A3602000B0240024002400240024002402000280214417F6A220341054B0D002000280230210A024002400240200341016B0E050301030204000B2001450D05034020022007410C6C6A220328020422052005411F7522066A200673200328020022062006411F7522046A2004736A200328020822092009411F7522036A2003736A2104027F20002A020C220D8B430000004F5D0440200DA80C010B4180808080780B2108200A20074103746A027F20044504404100210341000C010B200520086C20046D2103200620086C20046D22042009417F4A0D001A200541004821094100027F2008B722112004B799A122129944000000000000E0416304402012AA0C010B4180808080780B22046B210820064100482106027F20112003B799A122119944000000000000E0416304402011AA0C010B4180808080780B21052008200420091B2103410020056B200520061B0BAD2003AD42208684370200200741016A22072001470D000B0C040B2001450D0403402002200741066C6A22032E010222052005411F7522066A20067320032E010022062006411F7522046A2004736A20032E010422092009411F7522036A2003736A2104027F20002A020C220D8B430000004F5D0440200DA80C010B4180808080780B2108200A20074103746A027F20044504404100210341000C010B200520086C20046D2103200620086C20046D22042009417F4A0D001A200541004821094100027F2008B722112004B799A122129944000000000000E0416304402012AA0C010B4180808080780B22046B210820064100482106027F20112003B799A122119944000000000000E0416304402011AA0C010B4180808080780B21052008200420091B2103410020056B200520061B0BAD2003AD42208684370200200741016A22072001470D000B0C030B2001450D0303402002200741036C6A22032C000122052005411F7522066A20067320032C000022062006411F7522046A2004736A20032C000222092009411F7522036A2003736A2104027F20002A020C220D8B430000004F5D0440200DA80C010B4180808080780B2108200A20074103746A027F20044504404100210341000C010B200520086C20046D2103200620086C20046D22042009417F4A0D001A200541004821094100027F2008B722112004B799A122129944000000000000E0416304402012AA0C010B4180808080780B22046B210820064100482106027F20112003B799A122119944000000000000E0416304402011AA0C010B4180808080780B21052008200420091B2103410020056B200520061B0BAD2003AD42208684370200200741016A22072001470D000B0C020B100841B40A3602001009000B2001450D01034020022007410C6C6A22032A0200220F8B20032A020422108B9220032A0208220E8B92210D200E43000000005D4101732103027F20002A020C220E8B430000004F5D0440200EA80C010B4180808080780B21052010200D95210E200F200D95210D024020030440200D210F0C010B430000803F200E8B93220E8C200E200F43000000005D1B210F430000803F200D8B93210E201043000000005D4101730D00200E8C210E0B027F200E2005B2220D94220E8B430000004F5D0440200EA80C010B4180808080780BAD422086210C200A20074103746A200C027F200F200D94220D8B430000004F5D0440200DA80C010B4180808080780BAD84370200200741016A22072001470D000B0B41012105200B2802002202280204210720022802002103200141014B0D012007210B200321020C020B200B2802002201280204220B21072001280200220221030C010B200321022007210B0340200A20054103746A220428020422062007200620074A1B2107200428020022042003200420034A1B21032006200B2006200B481B210B2004200220042002481B2102200541016A22052001470D000B0B200041C0002007200B417F736AAC42018879A76B220041C00020032002417F736AAC42018879A76B220120012000481B41016A36021C0B9E0101027F2000280210200028020C22056B4102470440200320046A2104200120026A417F6A220220014B0440034020012D0000410274220520002802246A280200220620032000280230200028021820056A2802006A200610046A2103200141016A22012002470D000B200221010B20032000280230200028021820012D00004102746A2802006A200420036B10041A0F0B200320052D00002004100A1A0BF902010D7F2000280210200028020C6B220641024604402003410036020041000F0B2002410174417F2002417F4A1B1003210920034100360200024020024101480D002006410175210C200041406B280200210F410021060340410021080240200028023C22072002200A6B220D200D20074A1B220B4101480440410021040C010B2001200A6A211041002104034020072008460D01200028024C200820106A2D00006A2D00002004200C6C6A2104200841016A2208200B470D000B0B2007200D4A044003402004200C6C2104200B41016A220B2007480D000B0B027F200F200420056B4102746A280200220541004E04402003200641016A2204360200200620096A20053A0000200028022420054102746A280200200E6B2107200421064100210541000C010B2007200E6A0B210E2007200A6A220A2002480D000B2005417F4A0D00200041406B28020021000340200020054102746B28020022054100480D000B2003200641016A360200200620096A20053A00000B20090B070020002802000B850201047F0240024020002802082204200028020422036B20014F04400340200320022D00003A00002000200028020441016A22033602042001417F6A22010D000C02000B000B2003200028020022056B220620016A2203417F4C0D01027F41002003200420056B2204410174220520052003491B41FFFFFFFF07200441FFFFFFFF03491B2203450D001A200310030B220420036A2105200420066A220421030340200320022D00003A0000200341016A21032001417F6A22010D000B20042000280204200028020022016B22026B2104200241014E044020042001200210041A0B2000200436020020002005360208200020033602042001450D00200110020B0F0B1007000BC805010D7F230041106B2206240002402000280210200028020C22026B22034104480D004101210720034101752104200028023C220541004A04400340200420076C2107200141016A22012005480D000B0B200641003A000F02402000280250200028024C22056B220141FF014D0440200041CC006A41800220016B2006410F6A106D200028020C21020C010B2001418002460D00200020054180026A3602500B200341014E0440410021010340200028024C200220014101746A2D00006A20013A0000200028020C2102200141016A22012004480D000B0B200028020020022D0001480D0020002000280240360244200641FFFFFF07360208200041406B21052007044020052007200641086A101B0B2000280218220B200028021C460D000340410021094100210C03402000280210200028020C6B410175210D200028023C210A4100210402402008410274220320002802246A28020020096B22024101480440410021010C010B20002802302003200B6A28020020096A6A21034100210103402004200A4E0D01200028024C200320046A2D00006A2D00002001200D6C6A2101200441016A22042002470D000B0B200141016A210420022103200A20024A044003402004200D6C21042001200D6C2101200341016A2203200A470D000B0B2002200A4C04402001200448044020052802002102034020022001200C6A4102746A2008360200200141016A22012004470D000B0B200841016A2208200028021C200B6B410275490D02052006200528020022022001200C6A41027422046A22032802002201360204024020014100480D0020034100200028024420026B41027522036B3602002003200320076A220149044020052007200641046A101B2000280218210B200028024021020C010B200320014D0D002000200220014102746A3602440B200028023C20096A21094100200220046A2802006B210C0C010B0B0B0B200641106A24000BBA0101057F02402000280204200028020022046B2205417D4A0440027F41002005410175220641016A2203200028020820046B220220022003491B41FFFFFFFF07200241017541FFFFFFFF03491B2203450D001A2003417F4C0D02200341017410030B2102200220064101746A220620012F00003B0000200541014E044020022004200510041A0B200020023602002000200220034101746A3602082000200641026A36020420040440200410020B0F0B1007000B41F009100C000BEB0101047F230041106B220524002000200028020C36021041800810034100418008100A2106200241004A044003402006200120036A2D00004102746A2204200428020041016A360200200341016A22032002470D000B0B2000410C6A21014100210303400240200620034102746A28020022044101480D00200520033A000E2005200441FF016C20026D3A000F200028021022042000280214490440200420052F010E3B00002000200028021041026A3602100C010B20012005410E6A106F0B200341FF01492104200341016A210320040D000B200028020C2000280210102720061002200541106A24000BB10101067F2000280214220141204704402000280210200174210602402000280200220120002802082202480440200028020421040C010B417F20024103742002410174220341FEFFFFFF03712003471B1003220420002802042205200241027410042102200504402005100220002802084101742103200028020021010B20002003360208200020023602040B2000200141016A360200200420014102746A20063602002000428080808080043702100B0B4801027F2000280244200041406B28020022006B220341004A0440200341047521030340200120024102746A200020024104746A280200360200200241016A22022003480D000B0B0BD10101057F20002802082202200028020422036B41017520014F04402000200320014101746A3602040F0B02402003200028020022036B2205410175220620016A2204417F4A0440027F41002004200220036B220220022004491B41FFFFFFFF07200241017541FFFFFFFF03491B2202450D001A2002417F4C0D02200241017410030B2104200541014E044020042003200510041A0B200020043602002000200420024101746A3602082000200420064101746A20014101746A36020420030440200310020B0F0B1007000B41A908100C000BAD0301057F230041E0006B220224002002420037021C200242003702242002420037022C200242003702342002420037023C200242003703502002420037035820024200370214200242FF8180808001370308200242003703482002410236024420002000280208220341016A22043602082000200420032D0000220341017422056A3602082003047F200241146A2003107320022802140541000B2004200510041A200241086A10372000280208220328000021042000200341046A2203360208024020042001280204200128020022066B22054B04402001200420056B1005200028020821030C010B200420054F0D002001200420066A3602040B2000200341046A2200200328000022036A36020820040440200241086A2000200320012802002004106A0B20022802542200044020022000360258200010020B2002280248220004402002200036024C200010020B2002280238220004402002200036023C200010020B200228022C2200044020022000360230200010020B20022802202200044020022000360224200010020B20022802142200044020022000360218200010020B200241E0006A24000BA40501077F230041E0006B220324002003420037021C200342003702242003420037022C200342003702342003420037023C200342003703502003420037035820034200370214200342FF81808080013703082003420037034820034102360244200341086A200120021070200341086A1037200341086A106E200341086A20012002200341046A106B2108200041046A2106200328021820032802146B410176210402402000280208200028020422016B2205417F470440200641011005200628020021010C010B200020013602080B200120056A20043A000002402000280208200028020422016B220420042003280218200328021422096B22056A2207490440200620051005200628020021010C010B200420074D0D002000200120076A3602080B200120046A2009200510041A02402000280208200028020422016B2204417B4D044020064104100520002802082105200028020421010C010B2000200120046A41046A22053602080B200120046A2002360200200328020421070240200520016B2202417B4D044020064104100520002802082104200028020421010C010B2000200120026A41046A22043602080B200120026A20073602000240200420016B22022002200328020422046A2205490440200620041005200628020021010C010B200220054D0D002000200120056A3602080B200120026A2008200410041A20080440200810020B20032802141A20032802181A20032802041A20032802542200044020032000360258200010020B2003280248220004402003200036024C200010020B2003280238220004402003200036023C200010020B200328022C2200044020032000360230200010020B20032802202200044020032000360224200010020B20032802142200044020032000360218200010020B200341E0006A24000B13002000280244200041406B2802006B4104750B0D00200004402000104610020B0B1700024020002802040440200010440C010B200010430B0B0900200020013602200B230020003F004110746B41FFFF036A4110764000417F46044041000F0B4100100041010B0900200020013602240B3B01017F2002044003402000200120024180202002418020491B22031004210020014180206A210120004180206A2100200220036B22020D000B0B0BE40201027F024020002001460D000240200120026A20004B0440200020026A220420014B0D010B20002001200210041A0F0B20002001734103712103024002402000200149044020030D022000410371450D0103402002450D04200020012D00003A0000200141016A21012002417F6A2102200041016A22004103710D000B0C010B024020030D002004410371044003402002450D0520002002417F6A22026A2203200120026A2D00003A000020034103710D000B0B200241034D0D00034020002002417C6A22026A200120026A280200360200200241034B0D000B0B2002450D02034020002002417F6A22026A200120026A2D00003A000020020D000B0C020B200241034D0D0020022103034020002001280200360200200141046A2101200041046A21002003417C6A220341034B0D000B200241037121020B2002450D000340200020012D00003A0000200041016A2100200141016A21012002417F6A22020D000B0B0B1A00200020012802082005100604402001200220032004103A0B0B3700200020012802082005100604402001200220032004103A0F0B200028020822002001200220032004200520002802002802141109000B0D002000418D082001410610200BA7010020002001280208200410060440024020012802042002470D00200128021C4101460D002001200336021C0B0F0B02402000200128020020041006450D0002402002200128021047044020012802142002470D010B20034101470D01200141013602200F0B20012002360214200120033602202001200128022841016A360228024020012802244101470D0020012802184102470D00200141013A00360B2001410436022C0B0B88020020002001280208200410060440024020012802042002470D00200128021C4101460D002001200336021C0B0F0B02402000200128020020041006044002402002200128021047044020012802142002470D010B20034101470D02200141013602200F0B200120033602200240200128022C4104460D00200141003B01342000280208220020012002200241012004200028020028021411090020012D003504402001410336022C20012D0034450D010C030B2001410436022C0B200120023602142001200128022841016A36022820012802244101470D0120012802184102470D01200141013A00360F0B20002802082200200120022003200420002802002802181106000B0BA10101027F02400340200145044041000F0B200141DC1441EC15100B2202450D012002280208200041086A280200417F73710D0120002201410C6A280200200228020C41001006044041010F0B20002D0008410171450D01200128020C2200450D01200041DC1441EC15100B22000440200228020C21010C010B0B200128020C2200450D00200041DC1441DC16100B2200450D002000200228020C103B21030B20030BE80301047F230041406A22052400024002400240200141C817410010060440200241003602000C010B2000200110850104404101210320022802002200450D03200220002802003602000C030B2001450D01200141DC1441EC15100B2201450D02200228020022040440200220042802003602000B2001280208220420002802082206417F73714107710D022004417F7320067141E000710D0241012103200028020C200128020C410010060D02200028020C41BC17410010060440200128020C2200450D03200041DC1441A016100B4521030C030B200028020C2204450D0141002103200441DC1441EC15100B2204044020002D0008410171450D032004200128020C10830121030C030B200028020C2204450D02200441DC1441DC16100B2204044020002D0008410171450D032004200128020C103B21030C030B200028020C2200450D02200041DC14418C15100B2204450D02200128020C2200450D02200041DC14418C15100B2200450D022005417F360214200520043602102005410036020C20052000360208200541186A41004127100A1A200541013602382000200541086A20022802004101200028020028021C11040020052802204101470D022002280200450D00200220052802183602000B410121030C010B410021030B200541406B240020030B400002402000200120002D0008411871047F410105410021002001450D01200141DC1441BC15100B2201450D0120012D00084118714100470B100621000B20000B310020002001280208410010060440200120022003103C0F0B20002802082200200120022003200028020028021C1104000B180020002001280208410010060440200120022003103C0B0B0A0020002001200210450BA30101017F230041406A22032400027F410120002001410010060D001A41002001450D001A4100200141DC14418C15100B2201450D001A2003417F360214200320003602102003410036020C20032001360208200341186A41004127100A1A200341013602382001200341086A20022802004101200128020028021C110400410020032802204101470D001A2002200328021836020041010B2100200341406B240020000B0A0020002001410010060B4D01027F20012D00002102024020002D00002203450D0020022003470D00034020012D0001210220002D00012203450D01200141016A2101200041016A210020022003460D000B0B200320026B0B0B00200010281A200010020B08002000102810020B2B01017F0240200028020041746A220022012001280208417F6A22013602082001417F4A0D00200010020B0B05004180130B0D0020004180082001410310200BAD0201057F230041106B220724002001417F73416F6A20024F0440027F20002C000B410048044020002802000C010B20000B2109027F41E7FFFFFF0720014B0440200720014101743602082007200120026A36020C027F230041106B220224002007410C6A2208280200200741086A220A28020049210B200241106A2400200A2008200B1B2802002202410B4F0B047F200241106A41707122022002417F6A22022002410B461B05410A0B0C010B416E0B41016A2208103E21022005044020022006200510290B200320046B220322060440200220056A200420096A200610290B2001410A470440200910020B2000200236020020002008418080808078723602082000200320056A2200360204200741003A0007200020026A20072D00073A0000200741106A24000F0B1013000BC60101037F230041106B22042400024020002C000B410048047F200028020841FFFFFFFF0771417F6A05410A0B220320024F0440027F20002C000B410048044020002802000C010B20000B2203210520020440200520012002107D0B200441003A000F200220036A20042D000F3A0000024020002C000B4100480440200020023602040C010B200020023A000B0B0C010B20002003200220036B027F20002C000B410048044020002802040C010B20002D000B0B22002000200220011091010B200441106A24000B990101037F230041106B22042400416F20024F044002402002410A4D0440200020023A000B200021030C010B20002002410B4F047F200241106A41707122032003417F6A22032003410B461B05410A0B41016A2205103E22033602002000200541808080807872360208200020023602040B2003200120021029200441003A000F200220036A20042D000F3A0000200441106A24000F0B1013000B0D0020004180082001410610200B3701027F200110142202410D6A100322034100360208200320023602042003200236020020002003410C6A2001200241016A10043602000BB30602047F027D024020002802042204450D002000280214220241074B0D00200028020820016C210302400240024002400240024002400240200241016B0E0703060200040105070B2003450D072004027F20002A020C20042C0000B29422068B430000004F5D04402006A80C010B4180808080780B3A00004101210220034101460D072000220121040340027F20012A020C200428020420026A22052C0000B29422068B430000004F5D04402006A80C010B4180808080780B2100200520003A0000200241016A22022003470D000B0C070B2003450D06410021010340200420014102746A220220002A020C2002280200B294380200200141016A22012003470D000B0C060B2003450D0520002A020C2107410021010340027F2007200420014101746A22022F0100B3942206430000804F5D20064300000000607104402006A90C010B41000B2100200220003B0100200141016A22012003470D000B0C050B2003450D0420002A020C2107410021010340027F2007200420014102746A2202280200B3942206430000804F5D20064300000000607104402006A90C010B41000B210020022000360200200141016A22012003470D000B0C040B2003450D032004027F20002A020C20042C0000B29422068B430000004F5D04402006A80C010B4180808080780B3A00004101210220034101460D032000220121040340027F20012A020C200428020420026A22052C0000B29422068B430000004F5D04402006A80C010B4180808080780B2100200520003A0000200241016A22022003470D000B0C030B2003450D0220002A020C2106410021010340200420014103746A2006200420014102746A280200B294BB390300200141016A22012003470D000B0C020B2003450D0120002A020C2107410021010340027F2007200420014101746A22022F0100B3942206430000804F5D20064300000000607104402006A90C010B41000B2100200220003B0100200141016A22012003470D000B0C010B2003450D0020002A020C2107410021010340027F2007200420014102746A2202280200B3942206430000804F5D20064300000000607104402006A90C010B41000B210020022000360200200141016A22012003470D000B0B0BAF0301077F024020002802042203450D002002280204200228020022086B2202410C6D210420002D0010410171044020044102490D012000220541086A2802002102410121010340200241014E044020082001410C6C6A220621074100210003402003200120026C20006A4102746A220920092802002003200628020420026C20006A4102746A2802002003200628020020026C20006A4102746A2802006A2003200728020820026C20006A4102746A2802006B6A360200200041016A220020052802082202480D000B0B200141016A22012004490D000B0C010B2002044020044102490D012000220541086A2802002102410121010340200241014E044020082001410C6C6A21064100210003402003200120026C20006A4102746A220720072802002003200628020020026C20006A4102746A2802006A360200200041016A220020052802082202480D000B0B200141016A22012004470D000B0C010B2000220541086A2802002202200120026C4F0D00200221000340200320004102746A220420042802002003200020026B4102746A2802006A360200200041016A22002005280208220220016C490D000B0B0BA30301077F230041306B220324002003420037032820034200370320200342003703182000280208220628000021042000200641046A2205360208200520002802046B410371220604402000200520066B41046A22053602080B2003420037022820034100360220200320043602182003200536021C200320053602242000200028020820044102746A3602082003410036021020034200370308024020024101480D000240200145044003402000200341086A1016200741016A22072002470D000B20032802082104200328020C1A0C010B03402000200341086A101641002105200328020C2208210420032802082206200847044003400240200520066A22092D000022044504402001200220056C20076A4102746A41003602000C010B2001200220056C20076A4102746A4100200341186A200410102204410120092D0000417F6A7422066A6B200420042006481B36020020032802082106200328020C21080B200541016A22052008200622046B490D000B0B200741016A22072002470D000B0B2004450D002003200436020C200410020B200341186A100E200341306A24000B0D0020004190082001410610200B3001017F200028020821012000280204210320002D0010410271044020022003200110311A0F0B2002200320011098010BE60301087F230041306B22092400200941186A2001101C210A200941086A200310252106024020034101480D00200104400340027F02402006280200200B410C6C6A22082205280204200828020022076B220420014F0440200420014D0D012005200120076A36020441000C020B2008200120046B10050B41000B2104034002402002200320046C200B6A4102746A28020022050440200828020020046A41C10020052005411F7522076A200773AD42018879A76B22073A0000200A4100200541012007744101756A6B200520054100481B200710150C010B200828020020046A41003A00000B200441016A22042001470D000B200B41016A220B2003470D000B0C010B2006280200210241002101034020022001410C6C6A2204220528020420042802002204470440200520043602040B200141016A22012003470D000B0B2000200A10194100210120062802002104200341004A04400340200020042001410C6C6A2202280204200228020022026B2002101D20062802002104200141016A22012003470D000B0B20040440027F2004200420062802042200460D001A0340200041746A220128020022020440200041786A2002360200200210020B200122002004470D000B20062802000B210020062004360204200010020B200A100E200941306A24000B6A01027F2002200228020820022802046B36021020002802082103200028022C2104024020002D00104102710440200220012004200310320C010B2002200120042003109B010B200228021021012002200228020820022802046B22023602102000200220016B3602180B8D04010A7F02402000280208220341004C0440200128020021070C010B200028022C210420002802202106200128020021070340200420024102746A2006200728020020036C20026A4102746A280200360200200241016A220220002802082203480D000B0B200128020420076B2201410475220941024F044020014104752109410121010340200720014104746A2204210A024002402004280204220620042802082208460D0020002D0010410171450D0020034101480D01200028022C210B20002802202105410021020340200B200120036C20026A4102746A2005200428020C20036C20026A4102746A2802002005200428020020036C20026A4102746A2802002005200320066C20026A4102746A2802006B2005200320086C20026A4102746A2802006B6A360200200241016A2202200028020822034E0D0220042802082108200A28020421060C00000B000B20034101480D00200028022C2108200028022021054100210203402008200120036C20026A4102746A2005200428020020036C20026A4102746A2802002005200320066C20026A4102746A2802006B360200200241016A2202200028020822034E0D01200A28020421060C00000B000B200141016A22012009490D000B0B200320096C22012000280230200028022C22036B41027522024B04402000412C6A200120026B100D0F0B200120024904402000200320014102746A3602300B0BCD0603087F027D027C200041206A21090240200028020820016C22032000280224200028022022046B41027522014B04402009200320016B100D0C010B200320014F0D002000200420034102746A3602240B024020032000280230200028022C22046B41027522014B04402000412C6A200320016B100D0C010B200320014F0D002000200420034102746A3602300B0240024002400240024002402000280214417F6A220141064B0D000240200141016B0E06010301040500020B2003450D0520002A020CBB210D20002802202104410021010340200420014102746A027F200220014103746A2B0300200DA3220E9944000000000000E041630440200EAA0C010B4180808080780B360200200141016A22012003470D000B0C050B10084199113602001009000B2003450D0320002A020C210B200028022021044100210103402004200141027422056A027F200220056A280200B2200B95220C8B430000004F5D0440200CA80C010B4180808080780B360200200141016A22012003470D000B0C030B2003450D0220002A020C210B20002802202104410021010340200420014102746A027F200220014101746A2E0100B2200B95220C8B430000004F5D0440200CA80C010B4180808080780B360200200141016A22012003470D000B0C020B2003450D0120002A020C210B20002802202104410021010340200420014102746A027F200120026A2C0000B2200B95220C8B430000004F5D0440200CA80C010B4180808080780B360200200141016A22012003470D000B0C010B2003450D0020002A020C210B200028022021044100210103402004200141027422056A027F200220056A2A0200200B95220C8B430000004F5D0440200CA80C010B4180808080780B360200200141016A22012003470D000B0B20002202410036021C20002204280208220541014E044003402009280200220A20064102746A28020021010240200620034F0440200121000C010B20012100200520066A220720034F0D000340200A20074102746A2802002208200020002008481B210020082001200120084A1B2101200520076A22072003490D000B0B2002200228021C220541C00020002001417F736AAC42018879A76B220041016A200520004A1B36021C200641016A220620042802082205480D000B0B0B3A01017F200041FC11360200200028022C2201044020002001360230200110020B20002802202201044020002001360224200110020B200010020B3801017F200041FC11360200200028022C2201044020002001360230200110020B20002802202201044020002001360224200110020B20000BE30301087F024020002802082204200028020422026B41047520014F04400340200241086A22034200370200200220033602042000200028020441106A22023602042001417F6A22010D000C02000B000B027F024002402002200028020022026B410475220520016A2203418080808001490440027F41002003200420026B2202410375220420042003491B41FFFFFFFF00200241047541FFFFFF3F491B2203450D001A20034180808080014F0D02200341047410030B2102200220034104746A2107200220054104746A220521020340200241086A2203420037020020022003360204200241106A21022001417F6A22010D000B2000280204220320002802002204460D020340200541706A2205200341706A220128020036020020052001280204360204200541086A2206200128020822083602002005200128020C220936020C02402009450440200520063602040C010B200820063602082001200341786A2203360204200341003602002001410036020C0B200122032004470D000B2000280204210420002802000C030B1007000B41AD11100C000B20040B2101200020053602002000200736020820002002360204200120044704400340200441746A200441786A2802001018200441706A22042001470D000B0B2001450D00200110020B0B09002000418D0810210B0B004188011003200110490B0B9A1104004180080B6C6E6F726D616C00636F6C6F7200757600706F736974696F6E00556E6B6E6F776E20656E74726F707900616C6C6F6361746F723C543E3A3A616C6C6F636174652873697A655F74206E2920276E272065786365656473206D6178696D756D20737570706F727465642073697A650041F4080BFC080100000003000000070000000F0000001F0000003F0000007F000000FF000000FF010000FF030000FF070000FF0F0000FF1F0000FF3F0000FF7F0000FFFF0000FFFF0100FFFF0300FFFF0700FFFF0F00FFFF1F00FFFF3F00FFFF7F00FFFFFF00FFFFFF01FFFFFF03FFFFFF07FFFFFF0FFFFFFF1FFFFFFF3FFFFFFF7F616C6C6F6361746F723C543E3A3A616C6C6F636174652873697A655F74206E2920276E272065786365656473206D6178696D756D20737570706F727465642073697A6500556E7369676E6564207479706573206E6F7420737570706F7274656420666F72206E6F726D616C73004E6F20706F736974696F6E2061747472696275746520666F756E642E205573652044494646206E6F726D616C20737472617465677920696E73746561642E004E3363727431355665727465784174747269627574654500F80B00009C0500004E33637274313147656E6572696341747472496945450000200C0000BC050000B4050000506F736974696F6E206174747220686173206265656E206F7665726C6F616465642C205573652044494646206E6F726D616C20737472617465677920696E73746561642E00466F726D6174206E6F7420737570706F7274656420666F72206E6F726D616C206174747269627574652028666C6F61742C20696E743136206F6E6C792900466F726D6174206E6F7420737570706F7274656420666F72206E6F726D616C206174747269627574652028666C6F61742C20696E743332206F7220696E743136206F6E6C792900000000000000F406000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000004E3363727431304E6F726D616C41747472450000200C0000E0060000B4050000616C6C6F6361746F723C543E3A3A616C6C6F636174652873697A655F74206E2920276E272065786365656473206D6178696D756D20737570706F727465642073697A650000556E737570706F7274656420636F6C6F7220696E70757420666F726D61742E00556E737570706F7274656420636F6C6F72206F757470757420666F726D61742E00000000000000F00700000D0000000E0000000F00000010000000110000001200000013000000140000001500000016000000170000004E3363727439436F6C6F724174747245004E33637274313147656E65726963417474724968454500200C0000CD070000B4050000200C0000BC070000E407000000000000E40700000D00000018000000190000001A00000011000000120000001B0000001C00000015000000160000001D000000556E737570706F7274656420666F726D61742E004D656D6F7279206D75737420626520616C69676E65676E6564206F6E20342062797465732E004E6F742061206372742066696C652E00636F6C6F72004465636F64696E6720746F706F6C6F6779206661696C656400556E737570706F7274656420666F726D61742E00616C6C6F6361746F723C543E3A3A616C6C6F636174652873697A655F74206E2920276E272065786365656473206D6178696D756D20737570706F727465642073697A650041F8110B9507D40500001E0000001F00000020000000210000001100000022000000230000002400000025000000160000002600000062617369635F737472696E6700616C6C6F6361746F723C543E3A3A616C6C6F636174652873697A655F74206E2920276E272065786365656473206D6178696D756D20737570706F727465642073697A6500766563746F72007374643A3A657863657074696F6E000000000000B409000028000000290000002A000000537439657863657074696F6E00000000F80B0000A409000000000000E0090000010000002B0000002C000000537431316C6F6769635F6572726F7200200C0000D0090000B409000000000000140A0000010000002D0000002C000000537431326C656E6774685F6572726F7200000000200C0000000A0000E0090000537439747970655F696E666F00000000F80B0000200A00004E31305F5F637878616269763131365F5F7368696D5F747970655F696E666F4500000000200C0000380A0000300A00004E31305F5F637878616269763131375F5F636C6173735F747970655F696E666F45000000200C0000680A00005C0A00004E31305F5F637878616269763131375F5F70626173655F747970655F696E666F45000000200C0000980A00005C0A00004E31305F5F637878616269763131395F5F706F696E7465725F747970655F696E666F4500200C0000C80A0000BC0A00004E31305F5F637878616269763132305F5F66756E6374696F6E5F747970655F696E666F4500000000200C0000F80A00005C0A00004E31305F5F637878616269763132395F5F706F696E7465725F746F5F6D656D6265725F747970655F696E666F45000000200C00002C0B0000BC0A000000000000AC0B00002E0000002F0000003000000031000000320000004E31305F5F637878616269763132335F5F66756E64616D656E74616C5F747970655F696E666F4500200C0000840B00005C0A000076000000700B0000B80B0000446E0000700B0000C40B000063000000700B0000D00B0000504B63007C0C0000DC0B000001000000D40B0000000000008C0A00002E0000003300000030000000310000003400000035000000360000003700000000000000680C00002E00000038000000300000003100000034000000390000003A0000003B0000004E31305F5F637878616269763132305F5F73695F636C6173735F747970655F696E666F4500000000200C0000400C00008C0A000000000000EC0A00002E0000003C00000030000000310000003D0041901D0B02306F"; +/* var wasm_simd = ""; + var detector = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,4,26,11]); + + var wasm = wasm_base; + + if (WebAssembly.validate(detector)) { + wasm = wasm_simd; + console.log("Warning: corto is using experimental SIMD support"); + }*/ + var instance, heap; + + var env = { + emscripten_notify_memory_growth: function(index) { + heap = new Uint8Array(instance.exports.memory.buffer); + }, + proc_exit: function(rval) { return 52; }, //WASI_ENOSYS + }; + + function unhex(data) { + var bytes = new Uint8Array(data.length / 2); + for (var i = 0; i < data.length; i += 2) { + bytes[i / 2] = parseInt(data.substr(i, 2), 16); + } + return bytes.buffer; + } + + var promise = + WebAssembly.instantiate(unhex(wasm_base), { env:env, wasi_unstable:env }) + .then(function(result) { + instance = result.instance; + instance.exports._start(); + env.emscripten_notify_memory_growth(0); + }); + + function pad() { + return; + var s = instance.exports.sbrk(0); + var t = s & 0x3; + if(t) + instance.exports.sbrk(4 -t); + } + + function decode(source, shortIndex = false, shortNormal = false, colorComponents = 4) { + if(!source.length) + source = new Uint8Array(source); + var len = source.length; + var exports = instance.exports; + var sbrk = exports.malloc; //yes I am a criminal. + var free = exports.free; + + +//copy source to heap. we could use directly source, but that is good only for the first em call. + + + //We could use the heap instead of malloc, don't know cost (not much probably), and can't debug properly. + //set initial heap position, to be restored at the end of the deconding. + var pos = sbrk(0); + + var sptr = sbrk(len); + heap.set(source, sptr); + + var decoder = exports.newDecoder(len, sptr); + var nvert = exports.nvert(decoder); + var nface = exports.nface(decoder); + + var geometry = { + nvert: nvert, + nface: nface, + } + + var ngroups = exports.ngroups(decoder); + if(ngroups > 0) { + pad(); + var gp = sbrk(4*ngroups); + exports.groups(decoder, gp); + geometry.groups = new Uint32Array( ngroups*4); + geometry.grous.set(gp); + free(gp); + } + + var hasNormal = exports.hasNormal(decoder); + var hasColor = exports.hasColor(decoder); + var hasUv = exports.hasUv(decoder); + + var iptr = 0, pptr = 0, nptr = 0, cptr = 0, uptr = 0; + if(nface) { + pad(); //memory align needed for int, short, floats arrays if using sbrk + if(shortIndex) { + iptr = sbrk(nface * 6); + exports.setIndex16(decoder, iptr); + } else { + iptr = sbrk(nface * 12); + exports.setIndex32(decoder, iptr); + } + } + + pptr = sbrk(nvert * 12); + exports.setPositions(decoder, pptr); + + if(hasUv) { + pad(); + uptr = sbrk(nvert * 8); + exports.setUvs(decoder, uptr); + } + + if(hasNormal) { + pad(); + if(shortNormal) { + nptr = sbrk(nvert * 6); + exports.setNormals16(decoder, nptr); + } else { + pptr = sbrk(nvert * 12); + exports.setNormals32(decoder, nptr); + } + } + + if(hasColor) { + pad(); + cptr = sbrk(nvert * colorComponents); + exports.setColors(decoder, cptr, colorComponents); + } + pad(); + exports.decode(decoder); + + + //typed arrays needs to be created in javascript space, not as views of heap (next call will overwrite them!) + //hence the double typed array. + if(nface) { + if(shortIndex) + geometry.index = new Uint16Array(new Uint16Array(heap.buffer, iptr, nface*3)); + else + geometry.index = new Uint32Array(new Uint32Array(heap.buffer, iptr, nface*3)); + } + + geometry.position = new Float32Array(new Float32Array(heap.buffer, pptr, nvert*3)); + + if(hasNormal) { + if(shortNormal) + geometry.normal = new Int16Array(new Int16Array(heap.buffer, nptr, nvert*3)); + else + geometry.normal = new Float32Array(new Float32Array(heap.buffer, nptr, nvert*3)); + } + + if(hasColor) + geometry.color = new Uint8Array(new Uint8Array(heap.buffer, cptr, nvert*colorComponents)); + + if(hasUv) + geometry.uv = new Float32Array(new Float32Array(heap.buffer, uptr, nvert*2)); + + exports.deleteDecoder(decoder); + + //restore heap position if using sbrk + //sbrk(pos - sbrk(0)); + free(sptr); + if(iptr) free(iptr); + if(pptr) free(pptr); + if(cptr) free(cptr); + if(nptr) free(nptr); + if(uptr) free(uptr); + + return geometry; + }; + + return { + ready: promise, + decode: decode + }; +})(); + +if (typeof exports === 'object' && typeof module === 'object') + module.exports = CortoDecoder; +else if (typeof define === 'function' && define['amd']) + define([], function() { + return CortoDecoder; + }); +else if (typeof exports === 'object') + exports["CortoDecoder"] = CortoDecoder; diff --git a/nexus3d/dist/index.html b/nexus3d/dist/index.html new file mode 100644 index 00000000..1dc8d236 --- /dev/null +++ b/nexus3d/dist/index.html @@ -0,0 +1,32 @@ + + + + + Nexus example + + + + + + + + + + +
+ + + + + diff --git a/nexus3d/dist/models/gargo.nxz b/nexus3d/dist/models/gargo.nxz new file mode 100644 index 00000000..41726278 Binary files /dev/null and b/nexus3d/dist/models/gargo.nxz differ diff --git a/nexus3d/package.json b/nexus3d/package.json new file mode 100644 index 00000000..2b2b402b --- /dev/null +++ b/nexus3d/package.json @@ -0,0 +1,47 @@ +{ + "name": "nexus3d", + "version": "1.0.10", + "description": "Streaming 3D on the web (threejs supported)", + "author": "Federico Ponchio", + "license": "MIT", + "private": false, + "browser": "build/nexus3D.min.js", + "main": "build/nexus3D.min.js", + "module": "build/nexus3D.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "webpack-dev-server --hot", + "build": "webpack --mode development", + "rollup": "rollup -c rollup.config.js", + "buildlib": "webpack -c webpacklib.config.js --mode development", + "prepare": "npm run buildlib" + }, + "repository": { + "type": "git", + "url": "https://github.com/cnr-isti-vclab/nexus" + }, + "keywords": ["threejs","streaming","nexus3d"], + "homepage": "https://github.com/cnr-isti-vclab/nexus", + "devDependencies": { + "html-webpack-plugin": "^5.5.4", + "rollup-plugin-terser": "^7.0.2", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1" + }, + "dependencies": { + "three": "^0.181.0" + }, +"files": [ + "build/nexus3D.js", + "build/nexus3D.min.js", + "build/corto.worker.js" +], +"exports": { + ".": { + "import": "./build/nexus3D.js", + "require": "./build/nexus3D.min.js" + }, + "./worker": "./build/corto.worker.js" +} +} diff --git a/nexus3d/rollup.config.js b/nexus3d/rollup.config.js new file mode 100644 index 00000000..d21bd0f9 --- /dev/null +++ b/nexus3d/rollup.config.js @@ -0,0 +1,37 @@ +import { terser } from "rollup-plugin-terser"; + +// Helper for license header +const license = "// vcg.isti.cnr.it/nexus/license\n"; + +export default [ + // Build the Main Library (Nexus3D) + { + input: './src/Nexus3D.js', + output: [ + { + format: 'es', + file: 'build/nexus3D.js', + }, + { + format: 'umd', + name: 'Nexus3D', + file: 'build/nexus3D.min.js', + plugins: [terser()], + globals: { three: 'THREE' } + } + ], + external: ['three'] + }, + // Build the Worker (Corto) + { + input: './dist/corto.em.js', + output: { + format: 'iife', // Classic worker format is safest for wide compatibility + file: 'build/corto.worker.js', + plugins: [ + terser(), + { renderChunk: (code) => license + code } + ] + } + } +]; \ No newline at end of file diff --git a/nexus3d/src/Binary.js b/nexus3d/src/Binary.js new file mode 100644 index 00000000..024b4802 --- /dev/null +++ b/nexus3d/src/Binary.js @@ -0,0 +1,104 @@ +/* UTILITIES */ + +function getUint64(view) { + var s = 0; + var lo = view.getUint32(view.offset, true); + var hi = view.getUint32(view.offset + 4, true); + view.offset += 8; + return ((hi * (1 << 32)) + lo); +} + +function getUint32(view) { + var s = view.getUint32(view.offset, true); + view.offset += 4; + return s; +} + +function getUint16(view) { + var s = view.getUint16(view.offset, true); + view.offset += 2; + return s; +} + +function getFloat32(view) { + var s = view.getFloat32(view.offset, true); + view.offset += 4; + return s; +} + +/* MATRIX STUFF */ + +function vecMul(m, v, r) { + var w = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]; + + r[0] = (m[0]*v[0] + m[4]*v[1] + m[8 ]*v[2] + m[12 ])/w; + r[1] = (m[1]*v[0] + m[5]*v[1] + m[9 ]*v[2] + m[13 ])/w; + r[2] = (m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14])/w; +} + + +function matMul(a, b, r) { + r[ 0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; + r[ 1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; + r[ 2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; + r[ 3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; + + r[ 4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; + r[ 5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; + r[ 6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; + r[ 7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; + + r[ 8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; + r[ 9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; + r[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; + r[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; + + r[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; + r[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; + r[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; + r[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; +} + +function matInv(m, t) { + var s = 1.0/( + m[12]* m[9]*m[6]*m[3]-m[8]*m[13]*m[6]*m[3]-m[12]*m[5]*m[10]*m[3]+m[4]*m[13]*m[10]*m[3]+ + m[8]*m[5]*m[14]*m[3]-m[4]*m[9]*m[14]*m[3]-m[12]*m[9]*m[2]*m[7]+m[8]*m[13]*m[2]*m[7]+ + m[12]*m[1]*m[10]*m[7]-m[0]*m[13]*m[10]*m[7]-m[8]*m[1]*m[14]*m[7]+m[0]*m[9]*m[14]*m[7]+ + m[12]*m[5]*m[2]*m[11]-m[4]*m[13]*m[2]*m[11]-m[12]*m[1]*m[6]*m[11]+m[0]*m[13]*m[6]*m[11]+ + m[4]*m[1]*m[14]*m[11]-m[0]*m[5]*m[14]*m[11]-m[8]*m[5]*m[2]*m[15]+m[4]*m[9]*m[2]*m[15]+ + m[8]*m[1]*m[6]*m[15]-m[0]*m[9]*m[6]*m[15]-m[4]*m[1]*m[10]*m[15]+m[0]*m[5]*m[10]*m[15] + ); + + t[ 0] = (m[9]*m[14]*m[7]-m[13]*m[10]*m[7]+m[13]*m[6]*m[11]-m[5]*m[14]*m[11]-m[9]*m[6]*m[15]+m[5]*m[10]*m[15])*s; + t[ 1] = (m[13]*m[10]*m[3]-m[9]*m[14]*m[3]-m[13]*m[2]*m[11]+m[1]*m[14]*m[11]+m[9]*m[2]*m[15]-m[1]*m[10]*m[15])*s; + t[ 2] = (m[5]*m[14]*m[3]-m[13]*m[6]*m[3]+m[13]*m[2]*m[7]-m[1]*m[14]*m[7]-m[5]*m[2]*m[15]+m[1]*m[6]*m[15])*s; + t[ 3] = (m[9]*m[6]*m[3]-m[5]*m[10]*m[3]-m[9]*m[2]*m[7]+m[1]*m[10]*m[7]+m[5]*m[2]*m[11]-m[1]*m[6]*m[11])*s; + + t[ 4] = (m[12]*m[10]*m[7]-m[8]*m[14]*m[7]-m[12]*m[6]*m[11]+m[4]*m[14]*m[11]+m[8]*m[6]*m[15]-m[4]*m[10]*m[15])*s; + t[ 5] = (m[8]*m[14]*m[3]-m[12]*m[10]*m[3]+m[12]*m[2]*m[11]-m[0]*m[14]*m[11]-m[8]*m[2]*m[15]+m[0]*m[10]*m[15])*s; + t[ 6] = (m[12]*m[6]*m[3]-m[4]*m[14]*m[3]-m[12]*m[2]*m[7]+m[0]*m[14]*m[7]+m[4]*m[2]*m[15]-m[0]*m[6]*m[15])*s; + t[ 7] = (m[4]*m[10]*m[3]-m[8]*m[6]*m[3]+m[8]*m[2]*m[7]-m[0]*m[10]*m[7]-m[4]*m[2]*m[11]+m[0]*m[6]*m[11])*s; + + t[ 8] = (m[8]*m[13]*m[7]-m[12]*m[9]*m[7]+m[12]*m[5]*m[11]-m[4]*m[13]*m[11]-m[8]*m[5]*m[15]+m[4]*m[9]*m[15])*s; + t[ 9] = (m[12]*m[9]*m[3]-m[8]*m[13]*m[3]-m[12]*m[1]*m[11]+m[0]*m[13]*m[11]+m[8]*m[1]*m[15]-m[0]*m[9]*m[15])*s; + t[10] = (m[4]*m[13]*m[3]-m[12]*m[5]*m[3]+m[12]*m[1]*m[7]-m[0]*m[13]*m[7]-m[4]*m[1]*m[15]+m[0]*m[5]*m[15])*s; + t[11] = (m[8]*m[5]*m[3]-m[4]*m[9]*m[3]-m[8]*m[1]*m[7]+m[0]*m[9]*m[7]+m[4]*m[1]*m[11]-m[0]*m[5]*m[11])*s; + + t[12] = (m[12]*m[9]*m[6]-m[8]*m[13]*m[6]-m[12]*m[5]*m[10]+m[4]*m[13]*m[10]+m[8]*m[5]*m[14]-m[4]*m[9]*m[14])*s; + t[13] = (m[8]*m[13]*m[2]-m[12]*m[9]*m[2]+m[12]*m[1]*m[10]-m[0]*m[13]*m[10]-m[8]*m[1]*m[14]+m[0]*m[9]*m[14])*s; + t[14] = (m[12]*m[5]*m[2]-m[4]*m[13]*m[2]-m[12]*m[1]*m[6]+m[0]*m[13]*m[6]+m[4]*m[1]*m[14]-m[0]*m[5]*m[14])*s; + t[15] = (m[4]*m[9]*m[2]-m[8]*m[5]*m[2]+m[8]*m[1]*m[6]-m[0]*m[9]*m[6]-m[4]*m[1]*m[10]+m[0]*m[5]*m[10])*s; +} + +let binary = { + getUint64: getUint64, + getUint32: getUint32, + getUint16: getUint16, + getFloat32: getFloat32, + vecMul: vecMul, + matMul: matMul, + matInv: matInv +} + +export { getUint64, getUint32, getUint16, getFloat32, vecMul, matMul, matInv } + diff --git a/nexus3d/src/Cache.js b/nexus3d/src/Cache.js new file mode 100644 index 00000000..1fc9aee4 --- /dev/null +++ b/nexus3d/src/Cache.js @@ -0,0 +1,432 @@ + +function powerOf2(n) { + return n && (n & (n - 1)) === 0; +} + +var targetError = 2.0; //error won't go lower than this if we reach it +var maxError = 15; //error won't go over this even if fps is low +var minFps = 15; +var maxPending = 3; +var maxBlocked = 3; +var maxReqAttempt = 2; +var maxCacheSize = 1024 *(1<<20); +var drawBudget = 5*(1<<20); + +function _Cache() { + let t = this; + t.cortopath = '.'; + t.frame = 0; //keep track of the time + + t.maxCacheSize = maxCacheSize; + t.minFps = minFps; + t.currentFps = 0; + t.targetError = targetError; + t.currentError = targetError; + t.maxError = maxError; + t.realError = 0; + + t.pending = 0; + t.maxPending = 3; + t.cacheSize = 0; + t.candidates = []; //list of nodes to be loaded + t.nodes = new Map(); //for each mesh a list of node ids. + + t.last_frametime = 0; + t.frametime = 0; + t.end_frametime = 0; + + t.debug = { + verbose : false, //debug messages + nodes : false, //color each node + draw : false, //final rendering call disabled + extract : false, //extraction disabled} + } + + t.totswapped = 0; //in the last frame. + t.swaprate = 0; + t.lastupdate = performance.now(); +} + +_Cache.prototype = { + getTargetError: function() { return this.targetError; }, + getMinFps: function() { return this.minFps; }, + setMinFps: function(fps) { this.minFps = fps; }, + getMaxCacheSize: function() { return this.maxCacheSize; }, + setMaxCacheSize: function(size) { this.maxCacheSize = size; }, + setTargetError: function(error) { this.targetError = error; }, + + loadCorto: function() { + let workerPath = this.cortopath + 'corto.worker.js'; + try { + workerPath = new URL('./corto.worker.js', import.meta.url).href; + } catch (e) { + //reverrt to es if import.meta.url is not available + } + let corto = new Worker(workerPath); + corto.requests = {}; + corto.count = 0; + corto.postRequest = function(node) { + corto.postMessage({ buffer: node.buffer, request:this.count, rgba_colors: true, short_index: true, short_normals: true}); + node.buffer = null; + this.requests[this.count++] = node; + } + corto.onmessage = function(e) { + var request = e.data.request; + var node = this.requests[request]; + delete this.requests[request]; + node.model = e.data.model; + node.cache.readyGeometryNode(node.mesh, node.id, node.model); + }; + this.corto = corto; + }, + + + beginFrame: function(fps) { //each context has a separate frame count. + let c = this; + c.frametime = performance.now(); + let elapsed = c.frametime - c.last_frametime; + c.last_frametime = c.frametime; + if(elapsed < 500) + c.currentFps = 0.9*c.currentFps + 0.1*(1000/elapsed); + + fps = c.currentFps; + + c.frame++; + c.candidates = []; + if(fps && c.minFps) { + c.currentFps = fps; + const r = c.minFps/fps; + if(r > 1.1) + c.currentError *= 1.05; + if(r < 0.9) + c.currentError *= 0.95; + + c.currentError = Math.max(c.targetError, Math.min(c.maxError, c.currentError)); + + } else + c.currentError = c.targetError; + + c.rendered = 0; + c.realError = 1e20; + c.totswapped = 0; + }, + + endFrame: function() { + this.update(); + }, + + + + requestNode: function(mesh, id) { + mesh.status[id] = 2; + + + this.cacheSize += mesh.nsize[id]; + mesh.reqAttempt[id] = 0; + + if(!this.nodes.has(mesh)) + this.nodes.set(mesh, new Set()); + this.nodes.get(mesh).add(id); + + this.requestNodeGeometry(mesh, id); + this.requestNodeTexture(mesh, id); + }, + + requestNodeGeometry: function(mesh, id) { + this.pending++; + mesh.status[id]++; + let url = mesh.deepzoom ? mesh.baseurl + id + ".nxn" : mesh.url; + let start = mesh.deepzoom ? 0 : mesh.noffsets[id]; + let end = mesh.deepzoom ? 0 : mesh.noffsets[id+1]; + let request = mesh.georeq[id] = mesh.httpRequest(url, + start, + end, + ()=>{ + delete mesh.georeq[id]; + this.loadNodeGeometry(request, mesh, id); + this.pending--; + }, + ()=>{ + delete mesh.georeq[id]; + if(this.debug.verbose) console.log("Geometry request error!"); + this.recoverNode(mesh, id, 0); + this.pending--; + }, + ()=>{ + delete mesh.georeq[id]; + if(this.debug.verbose) console.log("Geometry request abort!"); + this.removeNode(mesh, id); + this.pending--; + }, + 'arraybuffer' + ); + }, + + requestNodeTexture: function(mesh, id) { + + if(!mesh.vertex.texCoord) return; + + let tex = mesh.patches[mesh.nfirstpatch[id]*3+2]; + mesh.texref[tex]++; + mesh.status[id]++; + + let url = mesh.deepzoom ? mesh.baseurl + tex + ".jpg" : mesh.url; + let start = mesh.deepzoom ? 0 : mesh.textures[tex]; + let end = mesh.deepzoom ? 0 : mesh.textures[tex+1]; + let request = mesh.texreq[tex] = mesh.httpRequest(url, + start, + end, + ()=>{ + delete mesh.texreq[tex]; + this.loadNodeTexture(request, mesh, id, tex); + + }, + ()=>{ + delete mesh.texreq[tex]; + if(this.debug.verbose) console.log("Texture request error!"); + this.recoverNode(mesh, id, 1); + }, + ()=>{ + delete mesh.texreq[tex]; + if(this.debug.verbose) console.log("Texture request abort!"); + this.removeNode(mesh, id); + }, + 'blob' + ); + }, + + recoverNode: function(mesh, id, mode) { + if(mesh.status[id] == 0) return; + + mesh.status[id]--; + + let t = this; + + if(mesh.reqAttempt[id] > maxReqAttempt) { + if(this.debug.verbose) console.log("Max request limit for " + m.url + " node: " + n); + t.removeNode(mesh, id); + return; + } + + mesh.reqAttempt[id]++; + + switch (mode){ + case 0: + t.requestNodeGeometry(mesh, id); + if(this.debug.verbose) console.log("Recovering geometry for " + m.url + " node: " + n); + break; + case 1: + t.requestNodeTexture(mesh, id); + if(this.debug.verbose) console.log("Recovering texture for " + m.url + " node: " + n); + break; + } + }, + + loadNodeGeometry: function(request, mesh, id) { + if(mesh.status[id] == 0) return; + + if(!mesh.compressed) + this.readyGeometryNode(mesh, id, request.response); + else { + if(!this.corto) this.loadCorto(); + this.corto.postRequest( { mesh:mesh, id:id, buffer: request.response, cache: this }); + } + }, + + + loadNodeTexture: function(request, mesh, id, texid) { + if(mesh.status[id] == 0) { + throw "Should not load texture twice"; + } + + let blob = request.response; + let callback = (img) => { + if(mesh.status[id] == 0) //call was aborted. + return; + mesh.createTexture(texid, img); + + mesh.status[id]--; + + if(mesh.status[id] == 2) + this.readyNode(mesh, id); + } + + if(typeof createImageBitmap != 'undefined') { + try { + createImageBitmap(blob, { imageOrientation: 'flipY' }).then(callback); + } catch(error) { //old version of firefox do not support options (but flip anyway) + createImageBitmap(blob).then(callback); + } + + } else { //fallback for IOS + var urlCreator = window.URL || window.webkitURL; + var img = document.createElement('img'); + img.onerror = function(e) { console.log("Texture loading error!"); }; + img.src = urlCreator.createObjectURL(blob); + + img.onload = function() { + urlCreator.revokeObjectURL(img.src); + callback(img); + } + } + }, + + removeNode: function(mesh, id) { + this.nodes.get(mesh).delete(id); + + if(mesh.status[id] == 0) { + if(this.debug.verbose) + console.log("Double remove due to abort."); + return; //TODO + } + + mesh.status[id] = 0; + if (id in mesh.georeq && mesh.georeq[id].readyState != 4) { + mesh.georeq[id].abort(); + delete mesh.georeq[id]; + //this.pending--; + } + mesh.availableNodes--; + this.cacheSize -= mesh.nsize[id]; + mesh.deleteNodeGeometry(id); + + if(!mesh.vertex.texCoord) return; + + const tex = mesh.patches[mesh.nfirstpatch[id]*3+2]; //TODO assuming one texture per node + + if (tex in mesh.texreq && mesh.texreq[tex].readyState != 4) { + mesh.texreq[tex].abort(); + delete mesh.texreq[tex]; + } + + mesh.texref[tex]--; + if(mesh.texref[tex] == 0) { + mesh.deleteTexture(tex); + } + }, + + readyGeometryNode: function(mesh, id, buffer) { + if(mesh.status[id] == 0) //call was aborted + return; + const nv = mesh.nvertices[id]; + const nf = mesh.nfaces[id]; + let geometry = {}; + + + if(!mesh.corto) { + geometry.index = new Uint16Array(buffer, nv*mesh.vsize, nf*3); + geometry.position = new Float32Array(buffer, 0, nv*3); + + var off = nv*12; + if(mesh.vertex.texCoord) { + geometry.uv = new Float32Array(buffer, off, nv*2); + off += nv*8; + } + if(mesh.vertex.normal) { + geometry.normal = new Int16Array(buffer, off, nv*3); + off += nv*6; + } + + if(mesh.vertex.color) { + geometry.color = new Uint8Array(buffer, off, nv*4); + off += nv*4; + } + + + } else { + geometry = buffer; + } + + //if(nf == 0) + // scramble(nv, v, no, co); + + mesh.createNodeGeometry(id, geometry); + mesh.status[id]--; + + if(mesh.status[id] == 2) { + this.readyNode(mesh, id); + } + }, + + //the node is finished, add to cache, and update counters + readyNode: function(mesh, id) { + + mesh.status[id]--; + if(mesh.status[id] != 1) throw "A ready node should have status ==1" + + + mesh.reqAttempt[id] = 0; + //this.pending--; + mesh.createNode(id); + mesh.availableNodes++; + + for(let callback of mesh.onUpdate) + callback(); + this.update(); + }, + + flush: function(mesh) { + if(!this.nodes.has(mesh)) return; + + for(let id of this.nodes.get(mesh)) + this.removeNode(mesh, id); + this.nodes.delete(mesh); + }, + + update: function() { + if(this.pending >= maxPending) + return; + + //the best candidate has the highest error + let best = null; + for(let c of this.candidates) { + if(c.mesh.status[c.id] == 0 && (!best || c.error > best.error)) + best = c; + } + if(!best) return; + + // record amount of data transfer per second. + /* + let now = performance.now(); + if(Math.floor(now/1000) > Math.floor(this.lastupdate/1000)) { //new second + this.swaprate = (this.totswapped/1000)/(now - this.lastupdate); //transfer in mb/s + if(this.debug.verbose) + console.log("Memory loaded in GPU: ", this.swaprate); + this.totswapped = 0; + this.lastupdate = now; + } + */ + + + //make room for new nodes! + + while(this.cacheSize > this.maxCacheSize) { + let worst = null; + + //find node with smallest error in cache and remove it if worse than the best candidate. + for(let [mesh, ids] of this.nodes) { + for(let id of ids) { + //we need to recompute the errors for the cache, as if not traversed doesn't get updated. + let error = mesh.errors[id]; + let frame = mesh.frames[id]; + if( !worst || error < worst.error) { + worst = { id: id, frame: frame, error: error, mesh: mesh } + } + } + } + if(!worst || worst.error >= best.error*0.9) { + //(worst.frame + 30 >= best.frame && )) //dont' remove if the best candidate is not good enogh + return; + } + this.removeNode(worst.mesh, worst.id); + } + this.totswapped += best.mesh.nsize[best.id]; + this.candidates = this.candidates.filter(e => e.mesh == best.mesh && e.id == best.id); + this.requestNode(best.mesh, best.id); + this.update(); //try again. + } +}; + +let Cache = new _Cache; +export { Cache } + diff --git a/nexus3d/src/Mesh.js b/nexus3d/src/Mesh.js new file mode 100644 index 00000000..24fd750d --- /dev/null +++ b/nexus3d/src/Mesh.js @@ -0,0 +1,261 @@ +import { getUint64, getUint32, getUint16, getFloat32 } from './Binary.js' + +/* MESH DEFINITION */ +let Debug = { verbose: true }; + +let glP = WebGLRenderingContext.prototype; +let attrGlMap = [glP.NONE, glP.BYTE, glP.UNSIGNED_BYTE, glP.SHORT, glP.UNSIGNED_SHORT, glP.INT, glP.UNSIGNED_INT, glP.FLOAT, glP.DOUBLE]; +let attrSizeMap = [0, 1, 1, 2, 2, 4, 4, 4, 8]; + +//All addresses in the file are n*256 so, 256 * 2^32 is the max size of a Nxs file +var padding = 256; + +let Mesh = function(url) { + var t = this; + t.isReady = false; + t.onLoad = []; + t.onUpdate = []; + t.reqAttempt = 0; + t.georeq = {}; //keeps track of existing httprequests + t.texreq = {}; + t.frame = 0; //last time this mesh was traversed in rendering. + t.availableNodes = 0 + if(url) + t.open(url); +} + +Mesh.prototype = { + open: function(url) { + let mesh = this; + mesh.url = url; + mesh.httpRequest(url, + 0, + 88, + function() { + if(Debug.verbose) console.log("Loading header for " + mesh.url); + let view = new DataView(this.response); + view.offset = 0; + mesh.reqAttempt++; + const header = mesh.importHeader(view); + if(!header) { + if(Debug.verbose) console.log("Empty header!"); + if(mesh.reqAttempt < maxReqAttempt) mesh.open(mesh.url + '?' + Math.random()); // BLINK ENGINE CACHE BUG PATCH + return; + } + mesh.reqAttempt = 0; + for(let i in header) + mesh[i] = header[i]; + mesh.vertex = mesh.signature.vertex; + mesh.face = mesh.signature.face; + mesh.renderMode = mesh.face.index?["FILL", "POINT"]:["POINT"]; + mesh.compressed = (mesh.signature.flags & (2 | 4)); //meco or corto + mesh.meco = (mesh.signature.flags & 2); + mesh.corto = (mesh.signature.flags & 4); + + mesh.deepzoom = (mesh.signature.flags & 8); + if(mesh.deepzoom) + mesh.baseurl = url.substr(0, url.length -4) + '_files/'; + + + mesh.requestIndex(); + }, + function() { console.log("Open request error!");}, + function() { console.log("Open request abort!");} + ); + }, + + httpRequest: function(url, start, end, load, error, abort, type) { + if(!type) type = 'arraybuffer'; + var r = new XMLHttpRequest(); + r.open('GET', url, true); + r.responseType = type; + if(end) + r.setRequestHeader("Range", "bytes=" + start + "-" + (end -1)); + r.onload = function(){ + switch (this.status){ + case 0: +// console.log("0 response: server unreachable.");//returned in chrome for local files + error(); + break; + case 206: +// console.log("206 response: partial content loaded."); + load.bind(this)(); + break; + case 200: +// console.log("200 response: server does not support byte range requests."); + if(end == 0) + load.bind(this)(); + else + error(); + break; + } + }; + r.onerror = error; + r.onabort = abort; + r.send(); + return r; + }, + + requestIndex: function() { + var mesh = this; + var end = 88 + mesh.nodesCount*44 + mesh.patchesCount*12 + mesh.texturesCount*68; + mesh.httpRequest(this.url, + 88, + end, + function() { if(Debug.verbose) console.log("Loading index for " + mesh.url); mesh.handleIndex(this.response); }, + function() { console.log("Index request error!");}, + function() { console.log("Index request abort!");} + ); + }, + + handleIndex: function(buffer) { + let t = this; + let view = new DataView(buffer); + view.offset = 0; + + const n = t.nodesCount; + + t.noffsets = new Uint32Array(n); + t.nvertices = new Uint32Array(n); + t.nfaces = new Uint32Array(n); + t.nerrors = new Float32Array(n); + t.nspheres = new Float32Array(n*5); + t.nsize = new Float32Array(n); + t.nfirstpatch = new Uint32Array(n); + + for(let i = 0; i < n; i++) { + t.noffsets[i] = padding*getUint32(view); //offset + t.nvertices[i] = getUint16(view); //verticesCount + t.nfaces[i] = getUint16(view); //facesCount + t.nerrors[i] = getFloat32(view); + view.offset += 8; //skip cone + for(let k = 0; k < 5; k++) + t.nspheres[i*5+k] = getFloat32(view); //sphere + tight + t.nfirstpatch[i] = getUint32(view); //first patch + } + t.sink = n -1; + + t.patches = new Uint32Array(view.buffer, view.offset, t.patchesCount*3); //noded, lastTriangle, texture + t.nroots = t.nodesCount; + for(let j = 0; j < t.nroots; j++) { + for(let i = t.nfirstpatch[j]; i < t.nfirstpatch[j+1]; i++) { + if(t.patches[i*3] < t.nroots) + t.nroots = t.patches[i*3]; + } + } + + view.offset += t.patchesCount*12; + + t.textures = new Uint32Array(t.texturesCount); + t.texref = new Uint32Array(t.texturesCount); + for(let i = 0; i < t.texturesCount; i++) { + t.textures[i] = padding*getUint32(view); + view.offset += 16*4; //skip proj matrix + } + + t.vsize = 12 + (t.vertex.normal?6:0) + (t.vertex.color?4:0) + (t.vertex.texCoord?8:0); + t.fsize = 6; + + //problem: I have no idea how much space a texture is needed in GPU. 10x factor assumed. + let tmptexsize = new Uint32Array(n-1); + let tmptexcount = new Uint32Array(n-1); + for(let i = 0; i < n-1; i++) { + for(let p = t.nfirstpatch[i]; p != t.nfirstpatch[i+1]; p++) { + let tex = t.patches[p*3+2]; + tmptexsize[i] += t.textures[tex+1] - t.textures[tex]; + tmptexcount[i]++; + } + t.nsize[i] = t.vsize*t.nvertices[i] + t.fsize*t.nfaces[i]; + } + for(let i = 0; i < n-1; i++) { + t.nsize[i] += 10*tmptexsize[i]/tmptexcount[i]; + } + + t.status = new Uint8Array(n); //0 for none, 1 for ready, 2+ for waiting data + t.frames = new Uint32Array(n); + t.errors = new Float32Array(n); //biggest error of instances + t.reqAttempt = new Uint8Array(n); + + t.isReady = true; + for(let callback of t.onLoad) + callback(this); + }, + + importAttribute: function(view) { + let a = {}; + a.type = view.getUint8(view.offset++, true); + a.size = view.getUint8(view.offset++, true); + a.glType = attrGlMap[a.type]; + a.normalized = a.type < 7; + a.stride = attrSizeMap[a.type]*a.size; + if(a.size == 0) return null; + return a; + }, + + importElement: function(view) { + let e = []; + for(let i = 0; i < 8; i++) + e[i] = this.importAttribute(view); + return e; + }, + + importVertex: function(view) { //enum POSITION, NORMAL, COLOR, TEXCOORD, DATA0 + const e = this.importElement(view); + let color = e[2]; + if(color) { + color.type = 2; //unsigned byte + color.glType = attrGlMap[2]; + } + return { position: e[0], normal: e[1], color: e[2], texCoord: e[3], data: e[4] }; + }, + + //enum INDEX, NORMAL, COLOR, TEXCOORD, DATA0 + importFace: function(view) { + const e = this.importElement(view); + let color = e[2]; + if(color) { + color.type = 2; //unsigned byte + color.glType = attrGlMap[2]; + } + return { index: e[0], normal: e[1], color: e[2], texCoord: e[3], data: e[4] }; + }, + + importSignature: function(view) { + let s = {}; + s.vertex = this.importVertex(view); + s.face = this.importFace(view); + s.flags = getUint32(view); + return s; + }, + + importHeader: function(view) { + const magic = getUint32(view); + if(magic != 0x4E787320) return null; + let h = {}; + h.version = getUint32(view); + h.verticesCount = getUint64(view); + h.facesCount = getUint64(view); + h.signature = this.importSignature(view); + h.nodesCount = getUint32(view); + h.patchesCount = getUint32(view); + h.texturesCount = getUint32(view); + h.sphere = { + center: [getFloat32(view), getFloat32(view), getFloat32(view)], + radius: getFloat32(view) + }; + return h; + }, + //OVERRIDE THESE METHOS + + //assemble node and geometry + createNode: function(id) {}, + + createNodeGeometry: function(id, data) {}, + deleteNodeGeometry: function(id) {}, + + createTexture: function(id, image) {}, + deleteTexture: function(id) {}, +}; + + +export { Mesh } diff --git a/nexus3d/src/Monitor.js b/nexus3d/src/Monitor.js new file mode 100644 index 00000000..05ba3e02 --- /dev/null +++ b/nexus3d/src/Monitor.js @@ -0,0 +1,321 @@ +/* +Nexus +Copyright (c) 2012-2020, Visual Computing Lab, ISTI - CNR +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +let css = ` +#nexusMonitor { + position:absolute; + top:10px; left:10px; + opacity:0.7; + background-color:black; + color:white; + padding:10px 20px; + width:300px; + font-family:Arial; + font-size: 12px; +} +#nexusMonitor table, #monitor tr { color:white; } +#nexusMonitor p { margin:0px 10px; padding:5px 0px; } + +.progress { + color:black; + height: 1.5em; + width: 240px; + background-color: #c9c9c9; + position: relative; +} +.progress:before { + content: attr(data-label); + font-size: 0.8em; + position: absolute; + text-align: center; + top: 5px; + left: 0; + right: 0; +} +.progress .value { + background-color: #7cc4ff; + display: inline-block; + height: 100%; +} +#nexusMonitor canvas { + width:300px; + height:600px; + background: transparent; +} +` + + +let html = ` + + + + + + + + + + + + + + + + + + +
Cache
+ +
Error
+ +
Fps
+ +
Progress
+ +
Rendered
Show patches
Target Error px
+ +`; + +//INJECT STYLE IN THE HEADER + + +function greenToRed(percent) { + const r = 255 * percent/100; + const g = 255 - (255 * percent/100); + return 'rgb('+r+','+g+',0)'; +} + +function toHuman(bytes, unit = '', decimals = 1) { + if (bytes === 0) return '0 Bytes'; + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i] + unit; +} + +class Monitor { + + constructor(cache, model) { + this.cache = cache; + this.div = null; + this.interval = null; + this.model = model; + this.mesh = model.mesh; + + document.addEventListener('DOMContentLoaded', () => { + + let style = document.createElement('STYLE'); + style.type = 'text/css'; + style.appendChild(document.createTextNode(css)); + document.head.appendChild(style); + + + this.div = document.createElement('div'); + this.div.setAttribute('id', 'nexusMonitor'); + + this.div.innerHTML = html; + let e = this.elements = { + cacheLabel: this.div.querySelector('#nexusMonitorCache'), + cacheStyle: this.div.querySelector('#nexusMonitorCache > span'), + errorLabel: this.div.querySelector('#nexusMonitorError'), + errorStyle: this.div.querySelector('#nexusMonitorError > span'), + fpsLabel : this.div.querySelector('#nexusMonitorFps'), + fpsStyle : this.div.querySelector('#nexusMonitorFps > span'), + progressLabel : this.div.querySelector('#nexusMonitorProgress'), + progressStyle : this.div.querySelector('#nexusMonitorProgress > span'), + + + trianglesCount: this.div.querySelector('#nexusMonitorTriangles'), + nodesCheckbox : this.div.querySelector('#nexusMonitorNodes'), + editError : this.div.querySelector('#nexusMonitorEditError') + } + + let cache = this.cache; + e.nodesCheckbox.addEventListener('click', function() { + cache.debug.nodes = this.checked; + for( let [mesh, ids] of cache.nodes) { + for(let callback of mesh.onUpdate) + callback(mesh); + } + }); + + e.editError.addEventListener('change', function() { + cache.targetError = this.value; + for( let [mesh, ids] of cache.nodes) { + for(let callback of mesh.onUpdate) + callback(mesh); + } + }); + + document.body.appendChild(this.div); + this.canvas = this.div.querySelector('canvas'); + this.ctx = this.canvas.getContext('2d'); + + + this.start(); + }, false); + } + + update() { + let context = this.cache; + + let cacheSize = context.cacheSize; + let maxCacheSize = context.maxCacheSize; + let cacheFraction = parseInt(100*cacheSize/maxCacheSize); + + let targetError = context.targetError; + let realError = Math.min(1000, context.realError); + let currentError = context.currentError; + let errorFraction = 100*Math.min(5, Math.log2(currentError/targetError))/5; + + let minFps = context.minFps; + let currentFps = context.currentFps; + let fpsFraction = 100*(Math.min(3, Math.max(0, 60/currentFps -1)))/3; + + + let mesh = context.nodes.keys().next(); + if(mesh) mesh = mesh.value; + + let progressFraction = mesh? mesh.availableNodes / mesh.nodesCount : 0; + let progressNodes = mesh ? mesh.availableNodes : 0; + + let rendered = context.rendered; + + let e = this.elements; + + e.cacheLabel.setAttribute('data-label', `${toHuman(cacheSize, 'B')}/${toHuman(maxCacheSize, 'B')}`); + e.cacheStyle.style.background_color = greenToRed(cacheFraction); + e.cacheStyle.style.width = cacheFraction; + + e.errorLabel.setAttribute('data-label', `Real: ${realError.toFixed(1)} px Target: ${currentError.toFixed(1)} px`); + e.errorStyle.style.background_color = greenToRed(errorFraction); + e.errorStyle.style.width = errorFraction; + + e.fpsLabel.setAttribute('data-label', `${parseInt(Math.round(currentFps))} fps`); + e.fpsStyle.style.background_color = greenToRed(fpsFraction); + e.fpsStyle.style.width = fpsFraction; + + e.progressLabel.setAttribute('data-label', `${parseInt(Math.round(progressNodes))} nodes`); + e.progressStyle.style.background_color = greenToRed(progressFraction); + e.progressStyle.style.width = progressFraction; + + e.trianglesCount.innerHTML = `${toHuman(rendered)} triangles`; + + if(!e.editError.value) + e.editError.value = targetError; + + if(!this.levels) { + if(this.mesh.isReady) + this.buildLevels(); + } else + this.updateNodeMonitor(); + } + + start() { + this.stop(); + this.div.style.display = 'block'; + this.interval = setInterval(() => { this.update(); }, 100); + } + + stop() { + this.div.style.display = 'none'; + if(this.interval) + clearInterval(this.interval); + } + + buildLevels() { + let m = this.mesh; + this.levelsCount = 0; + this.levels = new Array(m.nodesCount); + this.levels.fill(-1); + this.nodes = []; + for(let n = 0; n < m.nodesCount-1; n++) { + let level = this.levels[n]; + if(level == -1) + level = this.levels[n] = 0; + if(this.nodes.length <= level) + this.nodes[level] = []; + + this.nodes[level].push(n); + + for(let p = m.nfirstpatch[n]; p < m.nfirstpatch[n+1]; p++) { + let child = m.patches[p*3]; + if(child == m.nodesCount-1) + continue; + + this.levels[child] = level+1; + } + this.levelsCount = Math.max(level, this.levelsCount); + } + } + + updateNodeMonitor() { + + let ctx = this.ctx; + ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + let h = 10; + let w = 300; + + let y = 0; + for(let level = 0; level < this.nodes.length; level++) { + let nodes = this.nodes[level]; + let x = 0; + let dx = 10; + for(let i = 0; i < nodes.length; i++) { + let n = nodes[i]; + let selected = this.model.traversal.selected ? this.model.traversal.selected[n] : false; + let status = this.mesh.status[n]; + let color = 'red'; + if(selected) + color = 'green'; + else if(status == 1) + color = 'yellow'; + else if(status > 1) + color = 'orange'; + else + color = 'red'; + //let color = status == 0 ? 'red' : (status == 1? 'green' : 'orange'); + + + ctx.beginPath(); + ctx.rect(x, y, dx, h); + ctx.fillStyle = color; + ctx.fill(); + x += dx + 1; + if(x >= w - 10) { + x = 0; + y += 11; + } + } + y += h + 3; + } + } +} + + +export { Monitor } diff --git a/nexus3d/src/NXS.js b/nexus3d/src/NXS.js new file mode 100644 index 00000000..de533457 --- /dev/null +++ b/nexus3d/src/NXS.js @@ -0,0 +1,295 @@ +import * as THREE from 'three' +import { Traversal } from './Traversal.js' +import { Mesh } from './Mesh.js' +import { Cache } from './Cache.js' + +function NXS(url, onLoad, onUpdate, material) { + + THREE.Object3D.call( this ); + + this.type = 'NXS'; + + this.autoUpdate = true; + this.mesh = null; + this.url = url; + this.onLoadCallback = onLoad; + this.onUpdate = onUpdate || function() {}; + this.debug = false; + + if(this.url) + this.open(this.url) + +} + +NXS.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { + + constructor: NXS, + + isNXS: true, + + copy: function(source) { + + Object3D.prototype.copy.call( this, source, false ); + throw "Can't really copy." + return this; + + }, + + + open: function(url) { + let t = this; + this.mesh = new Mesh(url); + this.mesh.createMaterials = (materials) => { t.createMaterials(materials) }; + this.mesh.createNode = (id) => { t.updateMaterial(id) }; + this.mesh.createNodeGeometry = (id, geometry) => { t.createNodeGeometry(id, geometry); }; + this.mesh.createTexture = (id, image) => { t.createTexture(id, image); }; + this.mesh.deleteNodeGeometry = (id) => { t.deleteNodeGeometry(id); }; + this.mesh.deleteTexture = (id) => { t.deleteTexture(id); }; + this.mesh.onLoad = () => { t.onLoad(); } + this.mesh.onUpdate = () => { t.onUpdate(t.mesh); } + this.traversal = new Traversal(); + this.cache = new Cache(); + this.materials = []; + this.textures = {}; + this.nodes = {} //can't use getObjectById, it's slow //TODO use Map! + + this.toDelete = []; + + //this is needed for a onbeforerender callback! + const geometry = new THREE.BoxBufferGeometry(0.0, 0.0, 0.0); + const material = new THREE.MeshBasicMaterial(); + let cube = new THREE.Mesh(geometry, material); + cube.frustumCulled = false; + cube.onBeforeRender = (renderer, scene, camera, geometry, material, group) => { + t.onBeforeRender(renderer, scene, camera, geometry, material, group) } + cube.onAfterRender = (renderer, scene, camera, geometry, material, group) => { + t.onAfterRender(renderer, scene, camera, geometry, material, group) } + this.add(cube); + + }, + + set material(material) { + this.material = material; + this.material.needsUpdate = true; + }, + + set debug(debug) { + if(this.debug != debug) { + this.debug = debug; + this.material.needsUpdate = true; + } + }, + + onLoad: function() { + const c = this.mesh.sphere.center; + const center = new THREE.Vector3(c[0], c[1], c[2]); + const radius = this.mesh.sphere.radius; + + this.boundingSphere = new THREE.Sphere(center, radius); + if(this.material == null || this.material == false) + this.createMaterial(); + this.onLoadCallback(this); + }, + + onBeforeRender: function(renderer, scene, camera, geometry, material, group) { + let s = new THREE.Vector2(); + renderer.getSize(s); + + for(let id of this.toDelete) + this.actuallyDeleteNodeGeometry(id); + this.toDelete = []; + //object modelview is multiplied by camera during rendering, we need to do it here for visibility computations + this.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, this.matrixWorld ); + this.traversal.updateView([0, 0, s.width, s.height], camera.projectionMatrix.elements, this.modelViewMatrix.elements); + this.traversal.traverse(this.mesh, this.cache); + this.setVisibility(); + }, + onAfterRender: function(renderer, scene, camera, geometry, material, group) { + this.cache.update(); + }, + + setVisibility: function() { + if(this.material) { + if(this.debug != this.cache.debug.nodes) { + this.debug = this.cache.debug.nodes; + this.material.needsUpdate = true; + } + //threejs increments version when setting neeedsUpdate + if(this.material.version > 0) { + this.updateMaterials(); + this.material.version = 0; + this.onUpdate(); + } + } + + //set visibile what is visible! + let t = this.traversal; + let m = this.mesh; + + if(!m.isReady) + return; + let rendered = 0; + + for(let id = 0; id < m.nodesCount; id++) { + if(!(id in this.nodes)) + continue; + + let node = this.nodes[id]; + //let err = m.errors[n]; //careful this is wrong if multiple instances + let err = m.nerrors[id]; + + node.visible = false; + + + if(!t.selected[id]) continue; + + var sp = m.nspheres; + var off = id*5; + if(!t.isVisible(sp[off], sp[off+1], sp[off+2], sp[off+4])) //tight radius + continue; + + //There is no way to control group visibility, so we remove and recreate them. + node.geometry.clearGroups(); + + var offset = 0; + var end = 0; + var last = m.nfirstpatch[id+1]-1; + for (var p = m.nfirstpatch[id]; p < m.nfirstpatch[id+1]; ++p) { + var child = m.patches[p*3]; + + if(!t.selected[child]) { + end = m.patches[p*3+1]; + if(p < last) //we join patches if possible. + continue; + } + + if(end > offset) { + node.visible = true; + if(this.cache.debug.nodes) { + node.material[0].color = new THREE.Color(0, 1, 0); + if(child == m.sink) { + } else { + //node.material[0].color.setHSL(err/50, 0.5, 0.7); + let h = id*89.0/244.0; + h -= Math.floor(h); + node.material[0].color.setHSL(h, 0.6, 0.7); + } + } + + node.geometry.addGroup(offset*3, (end-offset)*3) + rendered += end - offset; + } + offset = m.patches[p*3+1]; + } + } + this.cache.rendered += rendered; + }, + + //we need to hijack the material when nxs has textures: when we change the material it might have a map or not + //and we need to update all the materials! + //we also need to create an array of materials for groups to work. + + //Nexus has a list of materials and, usually, each node attach his texture. + createMaterial: function() { + let options = {} + if(this.mesh.vertex.texCoord) + options.map = null; + if(this.mesh.vertex.color) + options.vertexColors = true; + //options.wireframe = true; + this.material = new THREE.MeshStandardMaterial(options); + //this.material = [new THREE.MeshPhongMaterial(options)]; + //this.material[0] = new THREE.MeshPhongMaterial( { color: 0xff0000 } ); + }, + + updateMaterials: function() { + for(let id in this.nodes) + this.updateMaterial(id); + }, + + updateMaterial: function(id) { + let node = this.nodes[id]; + const m = this.mesh; + //debug has each node with a different color, so we need to clone materials + if(!m.vertex.texCoord && !this.cache.debug.nodes) { + this.nodes[id].material = [this.material]; + return; + } + + let material = this.material.clone(); + if(m.vertex.texCoord) { + var texid = m.patches[m.nfirstpatch[id]*3+2]; + if(texid != -1) + material.map = this.textures[texid]; + } + + this.nodes[id].material = [material]; + }, + + createNodeGeometry: function(id, data) { + let geometry = new THREE.BufferGeometry() + geometry.setAttribute( 'position', new THREE.BufferAttribute(data.position, 3 ) ); + if(data.normal) { + geometry.setAttribute( 'normal', new THREE.BufferAttribute(data.normal, 3, true ) ); + } + if(data.color) + geometry.setAttribute( 'color', new THREE.BufferAttribute(data.color, 4, true ) ); + if(data.uv) + geometry.setAttribute( 'uv', new THREE.BufferAttribute(data.uv, 2 ) ); + geometry.setIndex(new THREE.BufferAttribute( data.index, 1 ) ); + + //if material include maps we need a different material for each + let node = new THREE.Mesh(geometry); + node.frustumCulled = false; + geometry.addGroup(0, data.index.length); + node.visible = false; + this.nodes[id] = node; + this.add(node); + }, + + createTexture: function(id, image) { + this.textures[id] = new THREE.CanvasTexture(image); + }, + //schedule for removal of this node( might not want to delete it in the middle of something. + //TODO check if this is really needed! + deleteNodeGeometry: function(id) { + this.toDelete.push(id); + }, + //check for leaking memory. + actuallyDeleteNodeGeometry(id) { + this.remove(this.nodes[id]); + delete this.nodes[id]; + }, + + deleteTexture: function(tex) { + if(!this.textures[tex]) + throw "Deleting missing texture!" + this.textures[tex].dispose(); + delete this.textures[tex]; + }, + + + toJSON: function ( meta ) { + throw "Can't" + }, + + raycast: function ( raycaster, intersects ) { + + const levels = this.levels; + + if ( levels.length > 0 ) { + + _v1.setFromMatrixPosition( this.matrixWorld ); + + const distance = raycaster.ray.origin.distanceTo( _v1 ); + + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + + } + + }, + +} ); + + +export { NXS }; diff --git a/nexus3d/src/NXSRaw.js b/nexus3d/src/NXSRaw.js new file mode 100644 index 00000000..d4179aba --- /dev/null +++ b/nexus3d/src/NXSRaw.js @@ -0,0 +1,402 @@ +import * as THREE from 'three' +import { Traversal } from './traversal.js' +import { Mesh } from './mesh.js' +import { Cache } from './cache.js' + +function NXSRaw(url, onLoad, onUpdate, renderer, material) { + + THREE.Object3D.call( this ); + + this.type = 'NXS'; + + this.gl = renderer.getContext(); + this.material = material; + + this.url = url; + this.onLoad = [onLoad]; + this.onUpdate = []; + if(onUpdate) this.onUpdate.push(onUpdate); + + this.autoUpdate = true; + this.mesh = new Mesh(); + + this.vbo = []; + this.ibo = []; + this.textures = []; + this.attributes = {}; //here we store the uniform attributes of the shader. + + //this is needed for a onbeforerender callback! + if(!this.material) + this.material = new THREE.MeshStandardMaterial(); + + if(this.url) { + if(typeof url == 'object') { + this.nxs = this.url; + this.nxs.onLoad.push((m) => { + this.mesh = this.nxs.mesh; + this.traversal = this.nxs.traversal; + this.cache = this.nxs.cache; + this.vbo = this.nxs.vbo; + this.ibo = this.nxs.ibo; + this.textures = this.nxs.textures; + this.onLoadCallback(this); + }); + } else + this.open(this.url); + } + +} + +NXSRaw.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { + + constructor: NXSRaw, + + isNXS: true, + + copy: function(source) { + + Object3D.prototype.copy.call( this, source, false ); + throw "Can't really copy." + return this; + + }, + + + open: function(url) { + let t = this; + this.mesh.open(url); + this.mesh.createNode = (id) => { }; + this.mesh.createNodeGeometry = (id, geometry) => { t.createNodeGeometry(id, geometry); }; + this.mesh.createTexture = (id, image) => { t.createTexture(id, image); }; + this.mesh.deleteNodeGeometry = (id) => { t.deleteNodeGeometry(id); }; + this.mesh.deleteTexture = (id) => { t.deleteTexture(id); }; + this.mesh.onLoad.push(() => { t.onLoadCallback(); }); + this.mesh.onUpdate.push(() => { for(let callback of t.onUpdate) callback(this); }); + + this.traversal = new Traversal(); + this.cache = new Cache(); + this.textures = {}; + }, + + set material(material) { + this.cube.material = this.material = material; + this.material.needsUpdate = true; + }, + + //we need to hijack the material when nxs has textures: when we change the material it might have a map or not + //and we need to update all the materials! + //we also need to create an array of materials for groups to work. + + //Nexus has a list of materials and, usually, each node attach his texture. + + updateMaterials: function() { + if(this.material.map !== false && this.mesh.vertex.texCoord) + this.material.map = this.cube_texture; + + if(this.mesh.vertex.color) + this.material.vertexColors = true; + }, + + onLoadCallback: function() { + const c = this.mesh.sphere.center; + const center = new THREE.Vector3(c[0], c[1], c[2]); + const radius = this.mesh.sphere.radius; + this.boundingSphere = new THREE.Sphere(center, radius); + + var geometry = new THREE.BufferGeometry(); + + if(this.mesh.vertex.normal) + geometry.setAttribute( 'normal', new THREE.BufferAttribute(new Float32Array(3), 3)); + if(this.mesh.vertex.color) + geometry.setAttribute( 'color', new THREE.BufferAttribute(new Float32Array(4), 4)); + if(this.mesh.vertex.texCoord) + geometry.setAttribute( 'uv', new THREE.BufferAttribute(new Float32Array(2), 2)); + + this.cube_texture = new THREE.DataTexture( new Uint8Array([1, 1, 1]), 1, 1, THREE.RGBFormat ); + this.cube_texture.needsUpdate = true; + + this.updateMaterials(); + + let cube = new THREE.Mesh(geometry, this.material); + cube.frustumCulled = false; + cube.onBeforeRender = (renderer, scene, camera, geometry, material, group) => { + this.onBeforeRender(renderer, scene, camera, geometry, material, group) } + cube.onAfterRender = (renderer, scene, camera, geometry, material, group) => { + this.onAfterRender(renderer, scene, camera, geometry, material, group) } + + this.add(cube); + + for(let callback of this.onLoad) + callback(this); + }, + + onBeforeRender: function(renderer, scene, camera, geometry, material, group) { + }, + onAfterRender: function(renderer, scene, camera, geometry, material, group) { + let s = new THREE.Vector2(); + renderer.getSize(s); + + //object modelview is multiplied by camera during rendering, we need to do it here for visibility computations + this.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, this.matrixWorld ); + this.traversal.updateView([0, 0, s.width, s.height], camera.projectionMatrix.elements, this.modelViewMatrix.elements); + this.instance_errors = this.traversal.traverse(this.mesh, this.cache); + + let gl = this.gl; + var program = gl.getParameter(gl.CURRENT_PROGRAM); + + + var attr = this.attributes; + attr.position = gl.getAttribLocation(program, "position"); + attr.normal = gl.getAttribLocation(program, "normal"); + attr.color = gl.getAttribLocation(program, "color"); + attr.uv = gl.getAttribLocation(program, "uv"); + attr.size = gl.getUniformLocation(program, "size"); + attr.scale = gl.getUniformLocation(program, "scale"); + let map_location = gl.getUniformLocation(program, "map"); + attr.map = map_location ? gl.getUniform(program, map_location) : null; + + + //hack to detect if threejs using point or triangle shaders + //instance.mode = attr.size ? "POINT" : "FILL"; + //if(attr.size != -1) + // instance.pointsize = material.size; + + //can't find docs or code on how material.scale is computed in threejs. + //if(attr.scale != -1) + // instance.pointscale = 2.0; + + this.setVisibility(); + }, + + setVisibility: function() { + //threejs increments version when setting neeedsUpdate + if(this.material.version > 0) { + this.updateMaterials(); + this.material.version = 0; + for(let callback of t.onUpdate) callback(this); + } + + //set visibile what is visible! + let t = this.traversal; + let m = this.mesh; + + if(!m.isReady) + return; + let rendered = 0; + + for(let id = 0; id < m.nodesCount; id++) { +// let err = m.nerrors[id]; + + if(!t.selected[id]) continue; + + //check for children: if all are selected, bail out. + { + let visible = false; + let offset = 0; + let end = 0; + let last = m.nfirstpatch[id+1]-1; + for (var p = m.nfirstpatch[id]; p < m.nfirstpatch[id+1]; ++p) { + var child = m.patches[p*3]; + + if(!t.selected[child]) { + visible = true; + break; + } + } + if(!visible) continue; + } + + var sp = m.nspheres; + var off = id*5; + if(!t.isVisible(sp[off], sp[off+1], sp[off+2], sp[off+4])) //tight radius + continue; + + let attr = this.attributes; + let mesh = this.mesh; + let gl = this.gl; + gl.bindVertexArray(null); + gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo[id]); + //if(t.mode != "POINT") + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ibo[id]); + + gl.vertexAttribPointer(attr.position, 3, gl.FLOAT, false, 12, 0); + gl.enableVertexAttribArray(attr.position); + + let nv = this.mesh.nvertices[id]; + let offset = nv*12; + + if(mesh.vertex.texCoord) { + if(attr.uv >= 0) { + gl.vertexAttribPointer(attr.uv, 2, gl.FLOAT, false, 8, offset); + gl.enableVertexAttribArray(attr.uv); + } + offset += nv*8; + } + if(mesh.vertex.color) { + if(attr.color >= 0) { + gl.vertexAttribPointer(attr.color, 4, gl.UNSIGNED_BYTE, true, 4, offset); + gl.enableVertexAttribArray(attr.color); + } + offset += nv*4; + } + if(mesh.vertex.normal) { + if(attr.normal >= 0) { + gl.vertexAttribPointer(attr.normal, 3, gl.SHORT, true, 6, offset); + gl.enableVertexAttribArray(attr.normal); + } + } + + if(this.cache.debug.nodes) { + gl.disableVertexAttribArray(attr.color); + + var error = this.instance_errors[id]; //this.mesh.errors[id]; + var palette = [ + [1, 1, 1, 1], //white + [1, 1, 1, 1], //white + [0, 1, 0, 1], //green + [0, 1, 1, 1], //cyan + [1, 1, 0, 1], //yellow + [1, 0, 1, 1], //magenta + [1, 0, 0, 1] //red + ]; + let w = Math.min(5.99, Math.max(0, Math.log2(error)/2)); + let low = Math.floor(w); + w -= low; + let color = []; + for( let k = 0; k < 4; k++) + color[k] = palette[low][k]*(1-w) + palette[low+1][k]*w; + + gl.vertexAttrib4fv(attr.color, color); + } + this.cache.realError = Math.min(this.mesh.errors[id], this.cache.realError); + + offset = 0; + let end = 0; + let last = m.nfirstpatch[id+1]-1; + for (let p = m.nfirstpatch[id]; p < m.nfirstpatch[id+1]; ++p) { + let child = m.patches[p*3]; + + if(!t.selected[child]) { + end = m.patches[p*3+1]; + if(p < last) //we join patches if possible. + continue; + } + + if(end > offset) { + if(m.vertex.texCoord && attr.uv >= 0) { + var tex = m.patches[p*3+2]; + if(tex != -1) { //bind texture + var texid = this.textures[tex]; + gl.activeTexture(gl.TEXTURE0 + attr.map); + gl.bindTexture(gl.TEXTURE_2D, texid); + } + } + gl.drawElements(gl.TRIANGLES, (end - offset) * 3, gl.UNSIGNED_SHORT, offset * 6); + rendered += end - offset; + } + offset = m.patches[p*3+1]; + } + } + this.cache.rendered += rendered; + }, + + + + createNodeGeometry: function(id, data) { + let m = this.mesh; + var nv = m.nvertices[id]; + var nf = m.nfaces[id]; + let indices = data.index; + let vertices = new ArrayBuffer(nv*m.vsize); + var position = new Float32Array(vertices, 0, nv*3); + position.set(data.position); + var off = nv*12; + if(m.vertex.texCoord) { + var uv = new Float32Array(vertices, off, nv*2); + uv.set(data.uv); + off += nv*8; + } + if(m.vertex.color) { + var color = new Uint8Array(vertices, off, nv*4); + color.set(data.color); + off += nv*4; + } + if(m.vertex.normal) { + var normal = new Int16Array(vertices, off, nv*3); + normal.set(data.normal); + off += nv*6; + } + + var gl = this.gl + var vbo = this.vbo[id] = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vbo); + gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); + var ibo = this.ibo[id] = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); + }, + + createTexture: function(id, image) { + let gl = this.gl; + var flip = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + let tex = this.textures[id] = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + + //TODO some textures might be alpha only! save space + var s = gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + + function powerOf2(n) { return n && (n & (n - 1)) === 0; } + if(!(gl instanceof WebGLRenderingContext) || (powerOf2(image.width) && powerOf2(image.height))) { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR); + gl.generateMipmap(gl.TEXTURE_2D); + } else { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + } + + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip); + }, + //schedule for removal of this node( might not want to delete it in the middle of something. + //TODO check if this is really needed! + deleteNodeGeometry: function(id) { + this.gl.deleteBuffer(this.vbo[id]); + this.gl.deleteBuffer(this.ibo[id]); + this.vbo[id] = this.ibo[id] = null; + }, + + deleteTexture: function(tex) { + if(!this.textures[tex]) + throw "Deleting missing texture!" + + this.gl.deleteTexture(this.textures[tex]); + this.textures[tex] = 0; + }, + + + toJSON: function ( meta ) { + throw "Can't" + }, + + raycast: function ( raycaster, intersects ) { + + const levels = this.levels; + + if ( levels.length > 0 ) { + + _v1.setFromMatrixPosition( this.matrixWorld ); + + const distance = raycaster.ray.origin.distanceTo( _v1 ); + + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + + } + + }, + +} ); + + +export { NXSRaw }; diff --git a/nexus3d/src/Nexus3D.js b/nexus3d/src/Nexus3D.js new file mode 100644 index 00000000..8e492b4f --- /dev/null +++ b/nexus3d/src/Nexus3D.js @@ -0,0 +1,482 @@ +import { + Mesh as THREEMesh, + MeshStandardMaterial, + Object3D, + Vector3, + Vector4, + Sphere, + BufferGeometry, + BufferAttribute, + DataTexture, + RGBAFormat, + LinearSRGBColorSpace +} from 'three' +import { Traversal } from './Traversal.js' +import { Mesh } from './Mesh.js' +import { Cache } from './Cache.js' + +class Nexus3D extends THREEMesh { + + constructor(url, renderer, options = {}) { + + super(); + + this.patchWebGLRenderer(renderer); + + Object.assign(this, { + isNXS: true, + type:'NXS', + url: url, + gl: renderer.getContext(), + XRMode: false, //set to true to avoid flickering due to double eye rendering. + material: null, + + autoUpdate: true, + mesh: new Mesh(), + vbo: [], + ibo: [], + vao: [], + textures: [], + attributes: {}, //here we store the uniform attributes of the shader. + + basemesh: null, //highest level of the nexus, for picking + }); + + if('material' in options) + this.material = options.material; + if(!this.material) + this.material = new MeshStandardMaterial(); + + for(let call of ['onLoad', 'onUpdate', 'onProgress']) { + this['_' + call] = []; + if(call in options) + this['_' + call].push(options[call]) + } + + if(this.url) { + if(typeof url == 'object') { + this.nxs = this.url; + this.nxs.onLoad.push((m) => { + this.mesh = this.nxs.mesh; + this.traversal = this.nxs.traversal; + this.cache = this.nxs.cache; + this.vbo = this.nxs.vbo; + this.ibo = this.nxs.ibo; + this.vao = this.nxs.vao; + this.textures = this.nxs.textures; + this.onLoadCallback(this); + }); + } else + this.open(this.url); + } + } + + copy(source) { + Object3D.prototype.copy.call(this, source, false); + throw new Error("Can't really copy a Nexus3D object."); + return this; + } + + + open(url) { + let t = this; + this.mesh.open(url); + this.mesh.createNode = (id) => { }; + this.mesh.createNodeGeometry = (id, geometry) => { t.createNodeGeometry(id, geometry); }; + this.mesh.createTexture = (id, image) => { t.createTexture(id, image); }; + this.mesh.deleteNodeGeometry = (id) => { t.deleteNodeGeometry(id); }; + this.mesh.deleteTexture = (id) => { t.deleteTexture(id); }; + this.mesh.onLoad.push(() => { t.onLoadCallback(); }); + this.mesh.onUpdate.push(() => { + for(let callback of t._onUpdate) callback(this); + for(let callback of t._onProgress) callback(this, this.mesh.availableNodes, this.mesh.nodesCount); + }); + + this.traversal = new Traversal(); + this.cache = Cache; //new Cache(); + this.textures = {}; + } + + set onLoad(callback) { + this._onLoad.push(callback); + } + + set onUpdate(callback) { + this._onUpdate.push(callback); + } + + set onProgress(callback) { + this._onProgress.push(callback); + } + + //TODO this is not really needed, we might just conform to THREEJS standard of updating. + /*set material(material) { + this.material = material; + this.material.needsUpdate = true; + }*/ + + updateMaterials() { + if(this.material.map !== false && this.mesh.vertex.texCoord) + this.material.map = this.material_texture; + + if(this.mesh.vertex.color) + this.material.vertexColors = true; + this.material.needsUpdate = true; + } + + onLoadCallback() { + const c = this.mesh.sphere.center; + const center = new Vector3(c[0], c[1], c[2]); + const radius = this.mesh.sphere.radius; + this.boundingSphere = new Sphere(center, radius); + + var geometry = new BufferGeometry(); + + geometry.setAttribute( 'position', new BufferAttribute(new Float32Array(3), 3)); + + if(this.mesh.vertex.normal) + geometry.setAttribute( 'normal', new BufferAttribute(new Float32Array(3), 3)); + if(this.mesh.vertex.color) + geometry.setAttribute( 'color', new BufferAttribute(new Float32Array(4), 4)); + if(this.mesh.vertex.texCoord) + geometry.setAttribute( 'uv', new BufferAttribute(new Float32Array(2), 2)); + + if(this.mesh.vertex.texCoord) { + this.material_texture = new DataTexture( new Uint8Array([1, 1, 1, 1]), 1, 1, RGBAFormat ); + this.material_texture.needsUpdate = true; + } + + this.updateMaterials(); + this.geometry = geometry; + + this.frustumCulled = false; + + for(let callback of this._onLoad) + callback(this); + } + + renderBufferDirect(renderer, scene, camera, geometry, material, group) { + let s = new Vector4(); + renderer.getViewport(s); + + //object modelview is multiplied by camera during rendering, we need to do it here for visibility computations + this.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, this.matrixWorld ); + if(s.x == 0 || !this.XRMode) { //hack to only traverse on the left eye + this.traversal.updateView(s, camera.projectionMatrix.elements, this.modelViewMatrix.elements); + this.instance_errors = this.traversal.traverse(this.mesh, this.cache); + } + //threejs increments version when setting neeedsUpdate + /*if(this.material.version > 0) { + this.updateMaterials(); + this.material.version = 0; + for(let callback of this.onUpdate) + callback(this); + }*/ + let gl = this.gl; + let program = gl.getParameter(gl.CURRENT_PROGRAM); + + //TODO these calls could be cached saving attrs per each material. + let attr = this.attributes; + attr.position = gl.getAttribLocation(program, "position"); + attr.normal = gl.getAttribLocation(program, "normal"); + attr.color = gl.getAttribLocation(program, "color"); + attr.uv = gl.getAttribLocation(program, "uv"); + attr.size = gl.getUniformLocation(program, "size"); + attr.scale = gl.getUniformLocation(program, "scale"); + + let map_location = gl.getUniformLocation(program, "map"); + attr.map = map_location ? gl.getUniform(program, map_location) : null; + + + //hack to detect if threejs using point or triangle shaders + //instance.mode = attr.size ? "POINT" : "FILL"; + //if(attr.size != -1) + // instance.pointsize = material.size; + + //can't find docs or code on how material.scale is computed in threejs. + //if(attr.scale != -1) + // instance.pointscale = 2.0; + + this.setVisibility(); + } + + setVisibility() { + //set visibile what is visible! + let t = this.traversal; + let m = this.mesh; + + if(!m.isReady) + return; + let rendered = 0; + + let attr = this.attributes; + let mesh = this.mesh; + let gl = this.gl; + let gl2 = gl instanceof WebGL2RenderingContext; + let state = attr.uv + 10*attr.color + 100*attr.normal; + + for(let id = 0; id < m.nodesCount; id++) { +// let err = m.nerrors[id]; + + if(!t.selected[id]) continue; + + //check for children: if all are selected, bail out. + { + let visible = false; + let offset = 0; + let end = 0; + let last = m.nfirstpatch[id+1]-1; + for (var p = m.nfirstpatch[id]; p < m.nfirstpatch[id+1]; ++p) { + var child = m.patches[p*3]; + + if(!t.selected[child]) { + visible = true; + break; + } + } + if(!visible) continue; + } + + var sp = m.nspheres; + var off = id*5; + if(!t.isVisible(sp[off], sp[off+1], sp[off+2], sp[off+4])) //tight radius + continue; + + let doBind = true; + + if(gl2) { + if(state in this.vao[id]) + doBind = false; + else + this.vao[id][state] = gl.createVertexArray(); + + gl.bindVertexArray(this.vao[id][state]); + } + + if(doBind) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo[id]); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ibo[id]); + + gl.vertexAttribPointer(attr.position, 3, gl.FLOAT, false, 12, 0); + gl.enableVertexAttribArray(attr.position); + + let nv = this.mesh.nvertices[id]; + let offset = nv*12; + + if(mesh.vertex.texCoord) { + if(attr.uv >= 0) { + gl.vertexAttribPointer(attr.uv, 2, gl.FLOAT, false, 8, offset); + gl.enableVertexAttribArray(attr.uv); + } + offset += nv*8; + } + if(mesh.vertex.color) { + if(attr.color >= 0) { + gl.vertexAttribPointer(attr.color, 4, gl.UNSIGNED_BYTE, true, 4, offset); + gl.enableVertexAttribArray(attr.color); + } + offset += nv*4; + } + if(mesh.vertex.normal) { + if(attr.normal >= 0) { + gl.vertexAttribPointer(attr.normal, 3, gl.SHORT, true, 6, offset); + gl.enableVertexAttribArray(attr.normal); + } + } + + if(this.cache.debug.nodes) { + gl.disableVertexAttribArray(attr.color); + + var error = this.instance_errors[id]; //this.mesh.errors[id]; + var palette = [ + [1, 1, 1, 1], //white + [1, 1, 1, 1], //white + [0, 1, 0, 1], //green + [0, 1, 1, 1], //cyan + [1, 1, 0, 1], //yellow + [1, 0, 1, 1], //magenta + [1, 0, 0, 1] //red + ]; + let w = Math.min(5.99, Math.max(0, Math.log2(error)/2)); + let low = Math.floor(w); + w -= low; + let color = []; + for( let k = 0; k < 4; k++) + color[k] = palette[low][k]*(1-w) + palette[low+1][k]*w; + + gl.vertexAttrib4fv(attr.color, color); + } + } + this.cache.realError = Math.min(this.mesh.errors[id], this.cache.realError); + + let offset = 0; + let end = 0; + let last = m.nfirstpatch[id+1]-1; + for (let p = m.nfirstpatch[id]; p < m.nfirstpatch[id+1]; ++p) { + let child = m.patches[p*3]; + + if(!t.selected[child]) { + end = m.patches[p*3+1]; + if(p < last) //we join patches if possible. + continue; + } + + if(end > offset) { + if(m.vertex.texCoord && attr.uv >= 0) { + var tex = m.patches[p*3+2]; + if(tex != -1) { //bind texture + var texid = this.textures[tex]; + gl.activeTexture(gl.TEXTURE0 + attr.map); + gl.bindTexture(gl.TEXTURE_2D, texid); + } + } + let mode = this.material.wireframe ? gl.LINE_STRIP : gl.TRIANGLES; + + gl.drawElements(mode, (end - offset) * 3, gl.UNSIGNED_SHORT, offset * 6); + rendered += end - offset; + } + offset = m.patches[p*3+1]; + } + } + this.cache.rendered += rendered; + } + + createNodeGeometry(id, data) { + let m = this.mesh; + var nv = m.nvertices[id]; + var nf = m.nfaces[id]; + let indices = data.index; + let vertices = new ArrayBuffer(nv*m.vsize); + var position = new Float32Array(vertices, 0, nv*3); + position.set(data.position); + var off = nv*12; + if(m.vertex.texCoord) { + var uv = new Float32Array(vertices, off, nv*2); + uv.set(data.uv); + off += nv*8; + } + if(m.vertex.color) { + var color = new Uint8Array(vertices, off, nv*4); + color.set(data.color); + off += nv*4; + } + if(m.vertex.normal) { + var normal = new Int16Array(vertices, off, nv*3); + normal.set(data.normal); + off += nv*6; + } + + //needed for approximate picking. + if(id < this.mesh.nroots) { + let basegeometry = new BufferGeometry(); + basegeometry.setAttribute( 'position', new BufferAttribute(data.position, 3 ) ); + basegeometry.setAttribute( 'normal', new BufferAttribute(data.normal, 3 ) ); + basegeometry.setIndex(new BufferAttribute( data.index, 1 ) ); + + this.basemesh = new THREEMesh(basegeometry, this.material); + this.basemesh.visible = false; + this.add(this.basemesh); + } + + var gl = this.gl + this.vao[id] = {}; //one for each attrib combination in use (casting shadows for example). + gl.bindVertexArray(null); + + var vbo = this.vbo[id] = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vbo); + gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); + var ibo = this.ibo[id] = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); + } + + createTexture(id, image) { + let gl = this.gl; + var flip = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + let tex = this.textures[id] = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + + //TODO some textures might be alpha only! save space + let internalFormat; + if (this.material && this.material.map && this.material.map.colorSpace === LinearSRGBColorSpace) { + internalFormat = gl.RGBA; + } else if (typeof gl.SRGB8_ALPHA8 !== 'undefined') { + internalFormat = gl.SRGB8_ALPHA8; + } else { + internalFormat = gl.RGBA; + } + gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, gl.RGBA, gl.UNSIGNED_BYTE, image); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + + function powerOf2(n) { return n && (n & (n - 1)) === 0; } + if(!(gl instanceof WebGLRenderingContext) || (powerOf2(image.width) && powerOf2(image.height))) { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR); + gl.generateMipmap(gl.TEXTURE_2D); + } else { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + } + + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip); + } + //schedule for removal of this node( might not want to delete it in the middle of something. + //TODO check if this is really needed! + deleteNodeGeometry(id) { + this.gl.deleteBuffer(this.vbo[id]); + this.gl.deleteBuffer(this.ibo[id]); + + this.vbo[id] = this.ibo[id] = null; + if(this.vao[id]) //node might have been loaded and unloaded before a rendering + for(const [state, vao] of Object.entries(this.vao[id])) + this.gl.deleteVertexArray(vao); + this.vao[id] = null; + } + + deleteTexture(tex) { + if(!this.textures[tex]) + return; + // throw "Deleting missing texture!" + + this.gl.deleteTexture(this.textures[tex]); + this.textures[tex] = 0; + } + + flush() { + this.cache.flush(this.mesh); + } + + dispose() { + this.flush(); + for(let child of this.children) + child.geometry.dispose(); + } + + toJSON(meta) { + throw new Error("Can't convert to json."); + } + + patchWebGLRenderer(renderer) { + if(renderer.nexusPatched) return; + let f = renderer.renderBufferDirect; + renderer.renderBufferDirect = ( camera, scene, geometry, material, object, group) => { + f( camera, scene, geometry, material, object, group ); + if ( object.renderBufferDirect) + object.renderBufferDirect(renderer, scene, camera, geometry, material, group); + }; + renderer.originalRender = renderer.render; + renderer.render = (scene, camera) => { + Cache.beginFrame(30); + renderer.originalRender(scene, camera); + Cache.endFrame(); + } + renderer.nexusPatched = true; + } + +} + + + + +export { Nexus3D, Cache }; diff --git a/nexus3d/src/PriorityQueue.js b/nexus3d/src/PriorityQueue.js new file mode 100644 index 00000000..2b9c2622 --- /dev/null +++ b/nexus3d/src/PriorityQueue.js @@ -0,0 +1,76 @@ + + function PriorityQueue(max_length) { + this.error = new Float32Array(max_length); + this.data = new Int32Array(max_length); + this.size = 0; +} + +PriorityQueue.prototype = { + push: function(data, error) { + this.data[this.size] = data; + this.error[this.size] = error; + this.bubbleUp(this.size); + this.size++; + }, + + pop: function() { + var result = this.data[0]; + this.size--; + if(this.size > 0) { + this.data[0] = this.data[this.size]; + this.error[0] = this.error[this.size]; + this.sinkDown(0); + } + return result; + }, + + bubbleUp: function(n) { + var data = this.data[n]; + var error = this.error[n]; + while (n > 0) { + var pN = ((n+1)>>1) -1; + var pError = this.error[pN]; + if(pError > error) + break; + //swap + this.data[n] = this.data[pN]; + this.error[n] = pError; + this.data[pN] = data; + this.error[pN] = error; + n = pN; + } + }, + + sinkDown: function(n) { + var data = this.data[n]; + var error = this.error[n]; + + while(true) { + var child2N = (n + 1) * 2; + var child1N = child2N - 1; + var swap = -1; + if (child1N < this.size) { + var child1Error = this.error[child1N]; + if(child1Error > error) + swap = child1N; + } + if (child2N < this.size) { + var child2Error = this.error[child2N]; + if (child2Error > (swap == -1 ? error : child1Error)) + swap = child2N; + } + + if (swap == -1) break; + + this.data[n] = this.data[swap]; + this.error[n] = this.error[swap]; + this.data[swap] = data; + this.error[swap] = error; + n = swap; + } + } +}; + + +export { PriorityQueue } + diff --git a/nexus3d/src/Traversal.js b/nexus3d/src/Traversal.js new file mode 100644 index 00000000..4cbb6065 --- /dev/null +++ b/nexus3d/src/Traversal.js @@ -0,0 +1,259 @@ +import { vecMul, matMul, matInv } from './Binary.js' +import { PriorityQueue } from "./PriorityQueue.js" + +function Traversal() { + let t = this; + t.maxBlocked = 30; + + t.modelMatrix = new Float32Array(16); + t.viewMatrix = new Float32Array(16); + t.projectionMatrix = new Float32Array(16); + t.modelView = new Float32Array(16); + t.modelViewInv = new Float32Array(16); + t.modelViewProj = new Float32Array(16); + t.modelViewProjInv = new Float32Array(16); + t.planes = new Float32Array(24); + t.viewport = new Float32Array(4); + t.viewpoint = new Float32Array(4); +} + +Traversal.prototype = { + updateView: function(viewport, projection, modelView) { + let t = this; + + for(let i = 0; i < 16; i++) { + t.projectionMatrix[i] = projection[i]; + t.modelView[i] = modelView[i]; + } + for(let i = 0; i < 4; i++) + t.viewport[i] = viewport[i]; + + matMul(t.projectionMatrix, t.modelView, t.modelViewProj); + matInv(t.modelViewProj, t.modelViewProjInv); + + matInv(t.modelView, t.modelViewInv); + t.viewpoint[0] = t.modelViewInv[12]; + t.viewpoint[1] = t.modelViewInv[13]; + t.viewpoint[2] = t.modelViewInv[14]; + t.viewpoint[3] = 1.0; + + + const m = t.modelViewProj; + const mi = t.modelViewProjInv; + let p = t.planes; + + //frustum planes Ax + By + Cz + D = 0; + p[0] = m[0] + m[3]; p[1] = m[4] + m[7]; p[2] = m[8] + m[11]; p[3] = m[12] + m[15]; //left + p[4] = -m[0] + m[3]; p[5] = -m[4] + m[7]; p[6] = -m[8] + m[11]; p[7] = -m[12] + m[15]; //right + p[8] = m[1] + m[3]; p[9] = m[5] + m[7]; p[10] = m[9] + m[11]; p[11] = m[13] + m[15]; //bottom + p[12] = -m[1] + m[3]; p[13] = -m[5] + m[7]; p[14] = -m[9] + m[11]; p[15] = -m[13] + m[15]; //top + p[16] = -m[2] + m[3]; p[17] = -m[6] + m[7]; p[18] = -m[10] + m[11]; p[19] = -m[14] + m[15]; //near + p[20] = -m[2] + m[3]; p[21] = -m[6] + m[7]; p[22] = -m[10] + m[11]; p[23] = -m[14] + m[15]; //far + + //normalize planes to get also correct distances + for(let i = 0; i < 24; i+= 4) { + let l = Math.sqrt(p[i]*p[i] + p[i+1]*p[i+1] + p[i+2]*p[i+2]); + p[i] /= l; p[i+1] /= l; p[i+2] /= l; p[i+3] /= l; + } + + //side is M'(1,0,0,1) - M'(-1,0,0,1) and they lie on the planes + const r3 = mi[3] + mi[15]; + const r0 = (mi[0] + mi[12 ])/r3; + const r1 = (mi[1] + mi[13 ])/r3; + const r2 = (mi[2] + mi[14 ])/r3; + + const l3 = -mi[3] + mi[15]; + const l0 = (-mi[0] + mi[12 ])/l3 - r0; + const l1 = (-mi[1] + mi[13 ])/l3 - r1; + const l2 = (-mi[2] + mi[14 ])/l3 - r2; + + const side = Math.sqrt(l0*l0 + l1*l1 + l2*l2); + + //center of the scene is M'*(0, 0, 0, 1) + const c0 = mi[12]/mi[15] - t.viewpoint[0]; + const c1 = mi[13]/mi[15] - t.viewpoint[1]; + const c2 = mi[14]/mi[15] - t.viewpoint[2]; + const dist = Math.sqrt(c0*c0 + c1*c1 + c2*c2); + + const resolution = (2*side/dist)/ t.viewport[2]; + t.currentResolution == resolution ? t.sameResolution = true : t.sameResolution = false; + t.currentResolution = resolution; + }, + + traverse : function (mesh, cache) { + let t = this; + t.mesh = mesh; +// if(Debug.extract == true) + // return; + + if(!mesh.isReady) return; + + const n = mesh.nodesCount; + t.visited = new Uint8Array(n); + t.blocked = new Uint8Array(n); + t.selected = new Uint8Array(n); + + t.frame = cache.frame; + + t.instance_errors = new Float32Array(n); + + if(t.frame > mesh.frame) { //clean the errors. + mesh.errors = new Float32Array(n); + mesh.frame = t.frame; + } + + t.visitQueue = new PriorityQueue(n); + for(var i = 0; i < mesh.nroots; i++) + t.insertNode(i); + + t.currentError = cache.currentError; + t.drawSize = 0; + t.nblocked = 0; + + var requested = 0; + while(t.visitQueue.size && t.nblocked < t.maxBlocked) { + var error = t.visitQueue.error[0]; + var id = t.visitQueue.pop(); + + //if not loaded and the queue is not full add to the candidates. + if (mesh.status[id] == 0 && requested < cache.maxPending) { + cache.candidates.push({id: id, mesh:mesh, frame:t.frame, error:error}); + requested++; + } + /* we don't want to stop as soon as a node is not availabe, because the nodes are sorted by error, + this could cause a large drop in quality elsewere. + we still need to mark all children as blocked, to prevent including them in the cut of the dag. */ + var blocked = t.blocked[id] || !t.expandNode(id, error); + if (blocked) + t.nblocked++; + else { + t.selected[id] = 1; + //cache.realError = Math.min(error, cache.realError); + } + t.insertChildren(id, blocked); + } + + //update remaining errors in the cache + if(cache.nodes.has(mesh)) { + for(let id of cache.nodes.get(mesh)) { + let error = t.nodeError(id); + if(t.instance_errors[id] == 0) { + t.instance_errors[i] = error; + mesh.errors[id] = Math.max(mesh.errors[id], error); + } + } + } + + t.mesh = null; + return t.instance_errors; + }, + + insertNode: function (node) { + let t = this; + t.visited[node] = 1; + + const error = t.nodeError(node); + + t.instance_errors[node] = error; + t.mesh.errors[node] = Math.max(error, t.mesh.errors[node]); + t.mesh.frames[node] = t.frame; + +// if(node > 0 && error < t.currentError) return; //2% speed TODO check if needed + + t.visitQueue.push(node, error); + }, + + insertChildren : function (node, block) { + let t = this; + for(let i = t.mesh.nfirstpatch[node]; i < t.mesh.nfirstpatch[node+1]; ++i) { + const child = t.mesh.patches[i*3]; + if (child == t.mesh.sink) return; + if (block) t.blocked[child] = 1; + if (!t.visited[child]) + t.insertNode(child); + } + }, + + expandNode : function (node, error) { + let t = this; + if(node > 0 && error < t.currentError) { +// console.log("Reached error", error, t.currentError); + return false; + } + + if(t.drawSize > t.drawBudget) { +// console.log("Reached drawsize", t.drawSize, t.drawBudget); + return false; + } + + if(t.mesh.status[node] != 1) { //not ready +// console.log("Node " + node + " still not loaded (cache?)"); + return false; + } + + const sp = t.mesh.nspheres; + const off = node*5; + if(t.isVisible(sp[off], sp[off+1], sp[off+2], sp[off+3])) //expanded radius + t.drawSize += t.mesh.nvertices[node]*0.8; + //we are adding half of the new faces. (but we are using the vertices so *2) + + return true; + }, + + nodeError : function (n, tight) { + let t = this; + const spheres = t.mesh.nspheres; + const b = t.viewpoint; + const off = n*5; + const cx = spheres[off+0]; + const cy = spheres[off+1]; + const cz = spheres[off+2]; + let r = spheres[off+3]; + if(tight) + r = spheres[off+4]; + const d0 = b[0] - cx; + const d1 = b[1] - cy; + const d2 = b[2] - cz; + let dist = Math.sqrt(d0*d0 + d1*d1 + d2*d2) - r; + if (dist < 0.1) + dist = 0.1; + + //resolution is how long is a pixel at distance 1. + let error = t.mesh.nerrors[n]/(t.currentResolution*dist); //in pixels + + //causes flickering due to things popping in and out of visibility, causes a huge resorting. + /*if (!t.isVisible(cx, cy, cz, spheres[off+4])) + error /= 100.0; */ + + //more stable, at least it's continuous. + let d = t.distance(cx, cy, cz, spheres[off+4]); + if(d < -r) { + error /= 101.0; + } else if(d < 0) { + error /= 1 -( d/r)*100.0 + } + return error; + }, + + distance: function(x, y, z, r) { + const p = this.planes; + let min_distance = 1e20; + for (let i = 0; i < 24; i +=4) { + let d = p[i]*x + p[i+1]*y + p[i+2]*z + p[i+3] + r; + if(d < min_distance) + min_distance = d; + } + return min_distance; + }, + + isVisible : function (x, y, z, r) { + const p = this.planes; + for (let i = 0; i < 24; i +=4) { + if(p[i]*x + p[i+1]*y + p[i+2]*z + p[i+3] + r < 0) //plane is ax+by+cz+d = 0; + return false; + } + return true; + } +}; + +export { Traversal } diff --git a/nexus3d/src/corto.worker.js b/nexus3d/src/corto.worker.js new file mode 100644 index 00000000..bcb41e5e --- /dev/null +++ b/nexus3d/src/corto.worker.js @@ -0,0 +1,221 @@ +/* +Corto +Copyright (c) 2017-2020, Visual Computing Lab, ISTI - CNR +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +onmessage = async function(job) { + if(typeof(job.data) == "string") return; + + var buffer = job.data.buffer; + if(!buffer) return; + if(!CortoDecoder.instance) + await CortoDecoder.ready; + + var model = CortoDecoder.decode(buffer, job.data.short_index, job.data.short_normals, job.data.rgba_colors ? 4 : 3); + postMessage({ model: model, buffer: buffer, request: job.data.request}); +}; + +var CortoDecoder = (function() { + "use strict"; + var wasm_base = "0061736D01000000014E0D60027F7F0060037F7F7F0060017F017F60017F0060057F7F7F7F7F0060037F7F7F017F60047F7F7F7F0060027F7F017F60067F7F7F7F7F7F006000006000017F60017E017F60047F7F7F7F017F024A0203656E761F656D736372697074656E5F6E6F746966795F6D656D6F72795F67726F777468000316776173695F736E617073686F745F70726576696577310970726F635F657869740003037D7C09070200020207070202020000000100000003030B010000000701030107000300010C0701040500040601000106000105010400020302010002030204000101010102010101000000060700020301000101010005090A050502020203020902000200000203010000010002030505050106060601040408080A03020405017001333305060101108080020608017F0141D0D2010B07D4021C066D656D6F727902000A6E65774465636F6465720003076E67726F75707300040667726F7570730005056E766572740006056E66616365000707686173417474720008096861734E6F726D616C000A08686173436F6C6F72000B056861735576000C0C736574506F736974696F6E73000D0C7365744E6F726D616C733332000E0C7365744E6F726D616C733136000F09736574436F6C6F727300100673657455767300110A736574496E646578313600120A736574496E64657833320013066465636F646500140D64656C6574654465636F6465720015195F5F696E6469726563745F66756E6374696F6E5F7461626C6501000B5F696E697469616C697A650002105F5F6572726E6F5F6C6F636174696F6E0058066D616C6C6F63005D0466726565005E047362726B005C09737461636B53617665007B0C737461636B526573746F7265007C0A737461636B416C6C6F63007D0938010041010B3236373826272D2E313334353B3C3D393E3F4041433E3A3C44454647484E4F44505152535455026D6E6767707A78736E7977740ADFD6037C0300010B850B010A7F027F418801105F2102230041306B220324002002410C6A22004200370200200241186A220442003702002002200036020820022004360214200241206A410041D40010591A20024100360284012002410136027820024180016A2200200141096A3602002002200136027C200220012D00083602782001280009210520002001410D6A2201360200024020050440200241086A2106200341106A210703402002200141026A220420012F00006A2201360280012002200141026A220820012F00006A360280012004105B220141704F0D02024002402001410B4F0440200141106A4170712209105F21002003200941808080807872360210200320003602082003200136020C0C010B200320013A0013200341086A21002001450D010B20002004200110561A0B200020016A41003A00002006200341286A200341086A1028220028020022014504404128105F22012007280200360218200120032903083702102007410036020020034200370308200141003602242001420037021C20012003280228360208200142003702002000200136020020062802002802002204047F2006200436020020002802000520010B2100200228020C200010292002200228021041016A3602100B2001411C6A2008106C20032C001341004804402003280208105E0B2002280280012101200A41016A220A2005470D000B0B200128000021092002200141046A2201360280014100210A200941004A0440200241146A210703402002200141026A220420012F00006A360280012004105B220141704F0D02024002402001410B4F0440200141106A4170712208105F21002003200841808080807872360210200320003602082003200136020C0C010B200320013A0013200341086A21002001450D010B20002004200110561A0B200020016A41003A0000200228028001220128000021002002200141046A36028001200128000421042002200141096A3602800120012D0008210520022001410A6A3602800120012D0009210820022001410B6A3602800120012D000A21060240024002400240200041026B0E020001020B41C800105F220142003702042001420137021420014200370224200141AC0A3602002001410C6A220042003702002001420037022C200142003702342001420037023C20014100360244200141033602082001410036022020004300000044380200200120012802104102723602100C020B41CC00105F22014200370204200142003702202001420137021420014104360248200141800B36020020014284808080C0003702382001420037020C200142003702282001420037023020012005360208200141406B428480808080013702000C010B4138105F220142003702042001420137021420014200370220200141AC0C3602002001420037020C2001420037022820014200370230200120053602080B200120083602142001200436020C200120063602102003200341086A360220200341206A2100230041106B22062400200341286A220B20072006410C6A200341086A102822082802002204047F4100054120105F220441106A21050240200028020022002C000B41004E044020052000290200370200200520002802083602080C010B200520002802002000280204106B0B2004410036021C2004200628020C360208200442003702002008200436020020072802002802002200047F2007200036020020082802000520040B21002007280204200010292007200728020841016A36020841010B3A0004200B2004360200200641106A24002003280228200136021C20032C001341004804402003280208105E0B2002280280012101200A41016A220A2009470D000B0B200220012800003602002002200141046A36028001200220012800043602042002200141086A36028001200341306A240020020C010B1057000B0B13002000280244200041406B2802006B4104750BF60101047F02402000280244200041406B28020022026B220041004C0D00200041047622004101200041014A1B2203410371210541002100200341016B41034F0440200341FCFFFFFF007121030340200120004102746A200220004104746A2802003602002001200041017222044102746A200220044104746A2802003602002001200041027222044102746A200220044104746A2802003602002001200041037222044102746A200220044104746A280200360200200041046A2100200341046B22030D000B0B2005450D000340200120004102746A200220004104746A280200360200200041016A2100200541016B22050D000B0B0B070020002802000B070020002802040B08002000200110090BF90201077F230041106B220424002001105B22024170490440024002402002410B4F0440200241106A4170712205105F2103200420054180808080787236020820042003360200200420023602040C010B200420023A000B200421032002450D010B20032001200210561A0B200220036A41003A0000027F20042101200041146A2802042203047F2001280200200120012D000B220041187441187541004822021B21072001280204200020021B21010340024002400240200328021420032D001B2200200041187441187541004822051B22002001200020014922081B2202044002402007200341106A2206280200200620051B22062002105A2205450440200020014D0D010C050B20054100480D040B200620072002105A2200450D0120004100480D0241010C060B200020014B0D020B20080D0041010C040B200341046A21030B200328020022030D000B41000541000B0B210220042C000B41004804402004280200105E0B200441106A240020024100470F0B1057000B0900200041920810090B0900200041830810090B0900200041800810090B0D00200041890820014106104B0B0D00200041920820014106104B0B0D00200041920820014103104B0BDE0201067F230041106B22032400200341053A000B200341003A0005200341830828000036020020034187082D00003A00042000220541146A22002003104C210420032C000B41004804402003280200105E0B2004200541186A470440200341053A000B200341003A0005200341830828000036020020034187082D00003A000420002003410C6A20031028220828020022044504404120105F2204200341086A22072802003602182004200329030037021020074100360200200342003703002004410036021C2004200328020C360208200442003702002008200436020020002802002802002207047F2000200736020020082802000520040B21002005280218200010292005411C6A2205200528020041016A3602000B200428021C22050440200541F80941E00B107121060B20032C000B41004804402003280200105E0B2006200236024820062001360204200641043602140B200341106A24000B0D00200041800820014106104B0B0900200020013602240B0900200020013602200B9430012B7F024020002802040440230041206B221124002000220941206A2224200041F8006A2215104D2015280208220028000021022015200041046A3602082024200236025020152024412C6A101A2015280208220028000021022015200041046A2200360208200020152802046B410371220404402015200020046B41046A22003602080B202441386A20022000101C2015201528020820024102746A36020820092802142200200941186A221F47044003400240200022022C001B41004E04402011200241106A2205280208360218201120052902003703100C010B201141106A20022802102002280214106B0B2011200228021C220536021C200520092802002015200528020028021C11010020112C001B41004804402011280210105E0B024020022802042205450440200228020822002802002002460D01200241086A210203402002280200220541086A2102200520052802082200280200470D000B0C010B03402005220028020022050D000B0B2000201F470D000B0B0240200928020022052009280238200941346A221528020022026B410C6D22004B0440200520006B220A20152802082202201528020422046B410C6D4D044020152004200A410C6C410C6E410C6C6A3602040C020B02402004201528020022006B2204410C6D2213200A6A221741D6AAD5AA014F0D002017200220006B410C6D2202410174220320032017491B41D5AAD5AA01200241AAD5AAD500491B2202047F200241D6AAD5AA014F0D012002410C6C105F0541000B22172013410C6C6A2203200441746D410C6C6A21132003200A410C6C410C6E410C6C6A210A20172002410C6C6A2102200441004A044020132000200410561A0B201520023602082015200A36020420152013360200200004402000105E0B0C020B1057000B200020054D0D00200920022005410C6C6A3602380B410021002011410036020C200941406B2802002205200928024422254704400340200041036C2119200528020041036C21262011410C6A21274100211B4100211C410021174100210A410021204100212141002128410021224100212B02400240200928027022000440200041ABD5AAD5004F0D01200041186C2200105F220A20006A21200B4101211D202620196B220041024F044020004100480D0120004101764102742200105F221720006A21210B2009350200101621000240201920264F0440200A2104201721130C010B200941D8006A2123200041016A2129417F21144101211E200A210420172113024003402019211A20202106200A210120042100202121072017210820132102034002400240027F0240027F02400240201E4101714504402019211A20202106200A210120042100202121072017210820132102201421220C010B201D2028200820026B2212410275220F4F2203710440200928028401210320272027280200220D41016A360200200341016B21034100210B027F0240200D200928024C6A2D00004106470D0020234103101F220B410171450D0020232029101F0C010B2009280234200928028401410C6C6A220D2003360208200D2003360204200D20033602002009200928028401220341016A3602840120030B210C02402009280224220D0440200D201A4101746A200C3B01000C010B2009280220201A4102746A200C3602000B200B410271450D0220232029101F0C030B02402003450440200220284102746A2103202841016A21280C010B201B201C460D01201C41046B2203211C0B200328020021220B417F21142000202241186C6A22032D00140D022003280210210C200328020C210E200328020821162003280204210D2003280200210B20272027280200220341016A3602002003200928024C6A2D000022104104460D02200120006B221841186D21142000200C41186C6A221241146A21042000200E41186C6A220F41106A212A2012280210211D200F28020C211E200F2802002119417F210302400240024002400240024002400240024020100E0701030406080500080B20232029101F21030C010B2009280234200928028401410C6C6A220320163602082003200B3602042003200D3602002009200928028401220341016A360284010B202A20143602002012201441016A220F36020C024020012006490440200141003A00142001200F3602102001200E36020C2001200D360208200120033602042001200B3602002000210E0C010B200F41ABD5AAD5004F0D11200F200620006B41186D220141017422062006200F491B41AAD5AAD500200141D5AAD52A491B220141ABD5AAD5004F0D11200141186C2206105F2210201441186C6A220141003A00142001200F3602102001200E36020C2001200D360208200120033602042001200B3602002001201841686D41186C6A210E201841004A0440200E2000201810561A0B200620106A21062000105E0B200141186A2212200E6B220F41186D21000240200720084B044020082000360200200841046A21080C010B200820026B2216410275221841016A22084180808080044F0D112008200720026B22074101752210200820104B1B41FFFFFFFF03200741027541FFFFFFFF01491B2207047F20074180808080044F0D122007410274105F0541000B221020184102746A2208200036020020074102742107201641004A044020102002201610561A0B200720106A2107200841046A2108200204402002105E0B201021020B200620124B044020012003360218200141003A002C2001200C360228200120143602242001200B3602202001200D36021C200141306A2101200E21000C060B200041016A220141ABD5AAD5004F0D1020012006200E6B41186D22064101742210200120104B1B41AAD5AAD500200641D5AAD52A491B220141ABD5AAD5004F0D10200141186C2206105F2210200041186C6A220141003A00142001200C3602102001201436020C2001200B3602082001200D360204200120033602002001200F41686D41186C6A2100200F41004A04402000200E200F10561A0B200620106A2106200141186A2101200E105E0C050B200F41013A00142000201E41186C6A20143602102012201436020C20012006490440200141003A00142001200C3602102001201E36020C2001200B3602082001200D36020420012019360200200141186A21010C040B201441016A220341ABD5AAD5004F0D0F2003200620006B41186D22014101742206200320064B1B41AAD5AAD500200141D5AAD52A491B220341ABD5AAD5004F0D0F200341186C2201105F2206201441186C6A220341003A00142003200C3602102003201E36020C2003200B3602082003200D360204200320193602002003201841686D41186C6A210C201841004A0440200C2000201810561A0B200120066A2106200341186A21012000105E20192103200C21000C040B20122802042103200441013A00002000201D41186C6A201436020C202A201436020020012006490440200141003A00142001201D3602102001200E36020C2001200D360208200120033602042001200B360200200141186A21010C040B201441016A220141ABD5AAD5004F0D0E2001200620006B41186D2206410174220C2001200C4B1B41AAD5AAD500200641D5AAD52A491B220141ABD5AAD5004F0D0E200141186C2206105F220F201441186C6A220141003A00142001201D3602102001200E36020C2001200D360208200120033602042001200B3602002001201841686D41186C6A210C201841004A0440200C2000201810561A0B2006200F6A2106200141186A21012000105E200C21000C030B201C202B470440201C2022360200201C41046A211C417F21140C060B202B201B6B220D410275220C41016A22034180808080044F0D0D2003200D410175220B2003200B4B1B41FFFFFFFF03200C41FFFFFFFF01491B220B047F200B4180808080044F0D0E200B410274105F0541000B2203200C4102746A220C2022360200200B410274210B200D41004A04402003201B200D10561A0B2003200B6A212B200C41046A211C417F2114201B4504402003211B0C060B201B105E2003211B0C050B200F41013A0014200441013A00002000201E41186C6A201D3602102000201D41186C6A201E36020C417F21140B201921030B02402009280224220C0440200C201A4101746A220C200D3B0100200C200B3B0102200C20033B01040C010B2009280220201A4102746A220C200D360200200C2003360208200C200B3602040B200221132008211720072121200021042001210A20062120201A41036A0C030B2009280234200928028401410C6C6A220D2003360208200D2003360204200D20033602002009200928028401220341016A3602840120030B210D201A41016A210E02402009280224221004402010200E4101746A200D3B01000C010B2009280220200E4102746A200D3602000B0240200B410471044020232029101F210B0C010B2009280234200928028401410C6C6A220B2003360208200B2003360204200B20033602002009200928028401220B41016A360284010B201A41026A210302402009280224220E0440200E20034101746A200B3B01000C010B200928022020034102746A200B3602000B200120006B221041186D2103200720084D0D0220082003360200200841046A21080C030B200221132008211720072121200021042001210A20062120201A0B2119201B201C46211D2014417F46211E20192026490D030C040B200F41016A220E4180808080044F0D05200E200720026B220741017522082008200E491B41FFFFFFFF03200741027541FFFFFFFF01491B2207047F20074180808080044F0D062007410274105F0541000B220E200F4102746A2208200336020020074102742107201241004A0440200E2002201210561A0B2007200E6A2107200841046A2108200204402002105E0B200E21020B200341016A210E200341026A210F024020012006490440200141003A00142001200E3602102001200F36020C2001200C3602082001200B3602042001200D360200200141186A21010C010B200E41ABD5AAD5004F0D05200E200620006B41186D220141017422062006200E491B41AAD5AAD500200141D5AAD52A491B220141ABD5AAD5004F0D05200141186C2206105F2216200341186C6A220141003A00142001200E3602102001200F36020C2001200C3602082001200B3602042001200D3602002001201041686D41186C6A2112201041004A044020122000201010561A0B200620166A2106200141186A2101200004402000105E0B201221000B200120006B221241186D21100240200720084B044020082010360200200841046A21080C010B200820026B2218410275222A41016A22084180808080044F0D052008200720026B22074101752216200820164B1B41FFFFFFFF03200741027541FFFFFFFF01491B2207047F20074180808080044F0D062007410274105F0541000B2216202A4102746A2208201036020020074102742107201841004A044020162002201810561A0B200720166A2107200841046A2108200204402002105E0B201621020B024020012006490440200141003A00142001200F3602102001200336020C2001200D3602082001200C3602042001200B360200200141186A21010C010B201041016A220141ABD5AAD5004F0D052001200620006B41186D22064101742216200120164B1B41AAD5AAD500200641D5AAD52A491B220141ABD5AAD5004F0D05200141186C2206105F2216201041186C6A220141003A00142001200F3602102001200336020C2001200D3602082001200C3602042001200B3602002001201241686D41186C6A210F201241004A0440200F2000201210561A0B200620166A2106200141186A2101200004402000105E0B200F21000B200120006B221041186D210F0240200720084B04402008200F360200200841046A21080C010B200820026B2216410275221841016A22084180808080044F0D052008200720026B22074101752212200820124B1B41FFFFFFFF03200741027541FFFFFFFF01491B2207047F20074180808080044F0D062007410274105F0541000B221220184102746A2208200F36020020074102742107201641004A044020122002201610561A0B200720126A2107200841046A2108200204402002105E0B201221020B024020012006490440200141003A0014200120033602102001200E36020C2001200B3602082001200D3602042001200C360200200141186A21010C010B200F41016A220141ABD5AAD5004F0D052001200620006B41186D22064101742212200120124B1B41AAD5AAD500200641D5AAD52A491B220141ABD5AAD5004F0D05200141186C2206105F2212200F41186C6A220141003A0014200120033602102001200E36020C2001200B3602082001200D3602042001200C3602002001201041686D41186C6A2103201041004A044020032000201010561A0B200620126A2106200141186A2101200004402000105E0B200321000B201A41036A221A2026490D000B0B20022113200021040B201B450D00201B105E0B201304402013105E0B200404402004105E0B0C010B1057000B20052802002100200541106A2202210520022025470D000B0B0240200941146A22252802002200201F460D0003400240200022022C001B41004E04402011200241106A2205280208360218201120052902003703100C010B201141106A20022802102002280214106B0B2011200228021C220536021C200520092802002015200528020028022011010020112C001B41004804402011280210105E0B024020022802042205450440200228020822002802002002460D01200241086A210203402002280200220541086A2102200520052802082200280200470D000B0C010B03402005220028020022050D000B0B2000201F470D000B20092802142200201F460D0003400240200022022C001B41004E04402011200241106A2205280208360218201120052902003703100C010B201141106A20022802102002280214106B0B2011200228021C220536021C20052009280200200928020420252024200528020028022411040020112C001B41004804402011280210105E0B024020022802042205450440200228020822002802002002460D01200241086A210203402002280200220541086A2102200520052802082200280200470D000B0C010B03402005220028020022050D000B0B2000201F470D000B20252802002200201F460D0003400240200022022C001B41004E04402011200241106A2205280208360218201120052902003703100C010B201141106A20022802102002280214106B0B2011200228021C220536021C20052009280200200528020028022811000020112C001B41004804402011280210105E0B024020022802042205450440200228020822002802002002460D01200241086A210203402002280200220541086A2102200520052802082200280200470D000B0C010B03402005220028020022050D000B0B2000201F470D000B0B201141206A24000C010B230041206B220A2400200A4100360218200A42003703102000221341206A200041F8006A2203104D20002802142200201341186A221747044003400240200022042C001B41004E0440200A200441106A2200280208360208200A20002902003703000C010B200A20042802102004280214106B0B200A200428021C220036020C200020132802002003200028020028021C110100200A2C000B4100480440200A280200105E0B024020042802042202450440200428020822002802002004460D01200441086A210403402004280200220241086A2104200220022802082200280200470D000B0C010B03402002220028020022020D000B0B20002017470D000B201328021421000B024020002017460D0003400240200022042C001B41004E0440200A200441106A2200280208360208200A20002902003703000C010B200A20042802102004280214106B0B200A200428021C220036020C20002013280200200A41106A2000280200280220110100200A2C000B4100480440200A280200105E0B024020042802042202450440200428020822002802002004460D01200441086A210403402004280200220241086A2104200220022802082200280200470D000B0C010B03402002220028020022020D000B0B20002017470D000B201328021422022017460D0003400240200222042C001B41004E0440200A200441106A2200280208360208200A20002902003703000C010B200A20042802102004280214106B0B200A200428021C220036020C200020132802002000280200280228110000200A2C000B4100480440200A280200105E0B024020042802042200450440200428020822022802002004460D01200441086A210403402004280200220041086A2104200020002802082202280200470D000B0C010B03402000220228020022000D000B0B20022017470D000B0B200A28021022000440200A20003602142000105E0B200A41206A24000B0BA60301057F20000440230041106B22042400200022022802142200200241186A220547044003400240200022032C001B41004E04402004200341106A2201280208360208200420012902003703000C010B200420032802102003280214106B0B2004200328021C220136020C20010440200120012802002802041103000B20042C000B41004804402004280200105E0B024020032802042201450440200328020822002802002003460D01200341086A210303402003280200220141086A2103200120012802082200280200470D000B0C010B03402001220028020022010D000B0B20002005470D000B0B200241D8006A101D200228024C22010440200220013602502001105E0B200241406B2802002200044020002002280244220146047F20000503402001410C6B200141086B2802001049200141106B22012000470D000B20022802400B2101200220003602442001105E0B200228023422010440200220013602382001105E0B200241146A21002002280228220104402002200136022C2001105E0B20002002280218104A200241086A200228020C1049200441106A24002002105E0B0B2A01027F200042025A04400340200141016A2101200042035621022000420188210020020D000B0B20010BC21D01147F024002400240024020002802000E020001020B200041046A2111024020002802082204200028020422066B2208417B4D0440200028020C220D20046B41044F0440200441003600002000200441046A2204360208201128020021060C020B200841046A22044100480D042004200D20066B220D410174220B2004200B4B1B41FFFFFFFF07200D41FFFFFFFF03491B220404402004105F21160B200820166A220D4100360000200420166A210B200D41046A2104200841004A044020162006200810561A0B2000200B36020C2000200436020820002016360204200604402006105E200028020821040B201128020021060C010B2000200620086A41046A22043602080B200620086A20013602000240200420066B2208200120086A2204490440201120011018201128020021060C010B200420084F0D002000200420066A3602080B200620086A2002200110561A0F0B230041E0006B220424002004420037021C200442003702242004420037022C200442003702342004420037023C200442003703502004420037035820044200370214200442FF8180808001370308200442003703482004410236024420022103200441086A2206200628020C360210418008105F4100418008105921110240200141004C0D0020014103712108200141016B41034F04402001417C71210D034020112003200E6A2D00004102746A220F200F28020041016A36020020112003200E4101726A2D00004102746A220F200F28020041016A36020020112003200E4102726A2D00004102746A220F200F28020041016A36020020112003200E4103726A2D00004102746A220F200F28020041016A360200200E41046A210E200D41046B220D0D000B0B2008450D00034020112003200E6A2D00004102746A220D200D28020041016A360200200E41016A210E200841016B22080D000B0B02400240034002402011200B4102746A280200220E41004C0D00200E41FF016C20016D21082006280210220E2006280214220F490440200E200B41FF01712008410874723B00002006200E41026A3602100C010B200E200628020C22036B220D417D4C0D02200D410175221041016A2214200F20036B220E200E2014491B41FFFFFFFF07200E41017541FFFFFFFF03491B220F047F200F4100480D03200F410174105F0541000B210E200E20104101746A2214200B41FF01712008410874723B0000200E200F4101746A2108201441026A210F200D41004A0440200E2003200D10561A0B200620083602142006200F3602102006200E36020C2003450D002003105E0B200B41016A220B418002470D000B200628020C200628021010202011105E0C010B1057000B200041046A2116200441086A102141002108230041106B220D24000240200441086A2207280210200728020C6B220B4104480D004101210E200B41017521050240200728023C220A41004C0D00200A4107712109200A41016B41074F0440200A417871210A03402005200E6C20056C20056C20056C20056C20056C20056C20056C210E200A41086B220A0D000B0B2009450D0003402005200E6C210E200941016B22090D000B0B200D41003A000F02402007280250200728024C220A6B220941FF014D0440200D410F6A210C41800220096B2213200741CC006A22152802082203201528020422146B4D044002402013450D00201341016B21102014210320134107712212044003402003200C2D00003A0000200341016A2103201241016B22120D000B0B201320146A211420104107490D0003402003200C2D00003A00002003200C2D00003A00012003200C2D00003A00022003200C2D00003A00032003200C2D00003A00042003200C2D00003A00052003200C2D00003A00062003200C2D00003A0007200341086A22032014470D000B0B201520143602040C020B2014201528020022106B220F20136A221241004E0440200F2012200320106B2203410174221020102012491B41FFFFFFFF07200341FFFFFFFF03491B220F047F200F105F0541000B22116A221021032013410771221204402010210303402003200C2D00003A0000200341016A2103201241016B22120D000B0B201020136A2112201341016B41074F044003402003200C2D00003A00002003200C2D00003A00012003200C2D00003A00022003200C2D00003A00032003200C2D00003A00042003200C2D00003A00052003200C2D00003A00062003200C2D00003A0007200341086A22032012470D000B0B200F20116A2113201020142015280200220C6B22036B2114200341004A04402014200C200310561A0B201520133602082015201236020420152014360200200C0440200C105E0B0C020B1057000B2009418002460D002007200A4180026A3602500B0240200B41004C0D0020054101200541014A1B220A410371210941002105200A41016B41034F0440200A41FCFFFFFF0771210A0340200728024C200728020C20054101746A2D00006A20053A0000200728024C200728020C2005410172220B4101746A2D00006A200B3A0000200728024C200728020C2005410272220B4101746A2D00006A200B3A0000200728024C200728020C2005410372220B4101746A2D00006A200B3A0000200541046A2105200A41046B220A0D000B0B2009450D000340200728024C200728020C20054101746A2D00006A20053A0000200541016A2105200941016B22090D000B0B2007280200200728020C2D0001480D0020072007280240360244200D41FFFFFF07360208200741406B2113200E04402013200E200D41086A10230B2007280218220F200728021C460D000340410021124100211503402007280210200728020C6B4101752105200728023C210C02402008410274220920072802246A280200221020126B220341004C0440410021090C010B2009200F6A28020020126A2106200728024C2111200728023021144100210A200C4100200C41004A1B210B410021090340200A200B460D01201120142006200A6A6A2D00006A2D0000200520096C6A2109200A41016A220A2003470D000B0B200941016A210A02402003200C4E0D00200C20126A20106B220641016B21112003210B2006410771220604400340200B41016A210B2005200A6C210A200520096C2109200641016B22060D000B0B20114107490D0003402005200A6C20056C20056C20056C20056C20056C20056C20056C210A200520096C20056C20056C20056C20056C20056C20056C20056C2109200B41086A220B200C470D000B0B02402003200C4C04402009200A4E0D012013280200210B200A2009417F736A2106200A20096B410371220504400340200B200920156A4102746A2008360200200941016A2109200541016B22050D000B0B200641024D0D010340200B200920156A4102746A220520083602002005200836020C2005200836020820052008360204200941046A2209200A470D000B0C010B200D2013280200220A200920156A41027422096A220B2802002205360204024020054100480D00200B41002007280244200A6B41027522056B3602002005200E6A220B20054B04402013200E200D41046A10232007280218210F0C010B2005200B4D0D002007200A200B4102746A3602440B200728023C20126A21124100200728024020096A2802006B21150C010B0B200841016A2208200728021C200F6B410275490D000B0B200D41106A2400027F200441046A21154100210A410021034100210F4100210D200441086A2213280210201328020C6B41024604402015410036020041000C010B2001410174417F200141004E1B105F210E201541003602000240200141004C0D002013280210201328020C6B4101752107201328022421112013280240210B0340410021100240201328023C22092001200F6B2208200820094A1B220C41004C0D00201328024C21144100211220094100200941004A1B2106034020062012460D0120142002200F20126A6A2D00006A2D0000200720106C6A2110201241016A2212200C470D000B0B0240200820094E0D002009200C417F736A21062009200C6B410771221204400340200C41016A210C200720106C2110201241016B22120D000B0B20064107490D000340200720106C20076C20076C20076C20076C20076C20076C20076C2110200C41086A220C2009470D000B0B027F200B2010200A6B4102746A280200220A41004E04402015200341016A22103602002003200E6A200A3A00002011200A4102746A280200200D6B2109201021034100210A41000C010B2009200D6A0B210D2009200F6A220F2001480D000B200A41004E0D002013280240210703402007200A4102746B280200220A4100480D000B2015200341016A3602002003200E6A200A3A00000B200E0B2114200428021821102004280214210B02400240024020002802082206200028020422026B2208417F4704402006200028020C220D470440200641003A00002000200641016A360208201628020021020C020B200841016A22114100480D0241002106200D20026B220D41017422032011200320084B1B41FFFFFFFF07200D41FFFFFFFF03491B220D0440200D105F21060B200620086A221141003A00002006200D6A210D201141016A2111200841004A044020062002200810561A0B2000200D36020C2000201136020820002006360204200204402002105E0B201628020021020C010B200020023602080B200220086A2010200B6B4101763A000002402000280208200028020422086B220220022004280218200428021422106B22066A220B490440201620061018201628020021080C010B2002200B4D0D0020002008200B6A3602080B200220086A2010200610561A20002001101920002004280204101902402000280208200028020422026B22012001200428020422086A2206490440201620081018201628020021020C010B200120064D0D002000200220066A3602080B200120026A2014200810561A201404402014105E0B20042802041A20042802141A20042802181A200428025422000440200420003602582000105E0B2004280248220004402004200036024C2000105E0B2004280238220004402004200036023C2000105E0B200428022C22000440200420003602302000105E0B200428022022000440200420003602242000105E0B200428021422000440200420003602182000105E0B200441E0006A24000C010B1057000B0B0F0B1057000BC60101067F200120002802082203200028020422026B4D044020002001047F200241002001105920016A0520020B3602040F0B2002200028020022046B220520016A220641004E0440410021022006200320046B22034101742207200620074B1B41FFFFFFFF07200341FFFFFFFF03491B220304402003105F21020B200220036A2103200220056A41002001105920016A2101200541004A044020022004200510561A0B200020033602082000200136020420002002360200200404402004105E0B0F0B1057000BF70101067F0240024020002802082202200028020422036B2205417B4D0440200028020C220420026B41044F0440200241003600002000200241046A360208200028020421030C020B200541046A22064100480D02410021022006200420036B22044101742207200620074B1B41FFFFFFFF07200441FFFFFFFF03491B220404402004105F21020B200220056A22064100360000200220046A2104200641046A2106200541004A044020022003200510561A0B2000200436020C2000200636020820002002360204200304402003105E0B200028020421030C010B2000200320056A41046A3602080B200320056A20013602000F0B1057000B8A0701097F02400240024020002802000E020001020B2000280208220328000021022000200341046A220336020802402001280204200128020022046B220620024904402001200220066B101820012802002104200028020821030C010B200220064F0D002001200220046A3602040B2000200220036A36020820042003200210561A0F0B230041E0006B220224002002420037021C200242003702242002420037022C200242003702342002420037023C200242003703502002420037035820024200370214200242FF8180808001370308200242003703482002410236024420002000280208220341016A22043602082000200420032D0000220341017422066A3602082003047F02402003200241146A22082802082207200828020422056B4101754D04402008200520034101746A3602040C010B02402005200828020022096B220A41017520036A22054100480D002005200720096B220320032005491B41FFFFFFFF07200341017541FFFFFFFF03491B2207047F20074100480D012007410174105F0541000B2103200320074101746A2107200320054101746A2105200A41004A044020032009200A10561A0B200820073602082008200536020420082003360200200904402009105E0B0C010B1057000B20022802140541000B2004200610561A200241086A10212000280208220328000021042000200341046A220336020802402001280204200128020022056B220620044904402001200420066B1018200028020821030C010B200420064F0D002001200420056A3602040B2000200341046A2206200328000022036A36020820040440024020012802002100200241086A2201280210200128020C22056B4102470440200020046A2107200341014A0440200320066A41016B2105034020062D0000410274220320012802246A280200210420002001280230200128021820036A2802006A2004105620046A2100200641016A22062005490D000B0B20002001280230200128021820062D00004102746A2802006A200720006B10561A0C010B200020052D0000200410591A0B0B200228025422000440200220003602582000105E0B2002280248220004402002200036024C2000105E0B2002280238220004402002200036023C2000105E0B200228022C22000440200220003602302000105E0B200228022022000440200220003602242000105E0B200228021422000440200220003602182000105E0B200241E0006A24000B0B440020002001360208417F2001410274200141FFFFFFFF03712001471B105F210120004280808080800437021020004100360200200020013602042000200136020C20000B2500200042003702102000410036020820002001360200200020023602042000200236020C0B1B0002402000280208450D0020002802042200450D002000105E0B0BC50201067F027F20002802082204044020002802140C010B41800221042000418002360208418008105F210320004280808080800437021020004100360200200020033602042000200336020C41200B220320024C0440200020002802102003742001200220036B7672220836021002402004200028020022034A0440200028020421060C010B417F20044103742004410174220541FEFFFFFF03712005471B105F220620002802042207200441027410562104200704402007105E20002802084101742105200028020021030B20002005360208200020043602040B2000200341016A360200200620034102746A200836020020004100360210200028021421044120210320004120360214200220046B220241027441E0086A28020020017121010B200241004A04402000200320026B360214200020002802102002742001723602100B0B810101037F027F2001200028021422024A044020004120200120026B22036B22013602142000200028020C220241046A36020C200041106A2104200028021020037420022802002202200176720C010B2000200220016B2201360214200041106A2104200028021022022001760B210320042002417F200174417F737136020020030BDE0E01097F0340200141016B210A200141026B21090340024002400240024002400240200120006B220241017522030E06050500010203040B200141016B2D000020002D00014D0D0420002F000021022000200141026B22032F00003B0000200320023B00000F0B200141026B2102200141016B22082D0000210320002D0003220420002D00014D0440200341FF017120044D0D0420002F00022103200020022F00003B0002200220033B000020002D000320002D00014D0D04200020002800004110773600000F0B20002F000021052004200341FF0171490440200020022F00003B0000200220053B00000F0B20002F00022103200020053B0002200020033B000020082D000020054180FE03714108764D0D03200020022F00003B0002200220053B00000F0B2000200041026A200041046A200141026B10241A0F0B2000200041026A200041046A200041066A10241A200141016B2D000020002D00074D0D0120002F000621022000200141026B22032F00003B0006200320023B000020002D000720002D00054D0D0120002F00062102200020002F00043B0006200020023B00042002410876220320002D00034D0D01200020002F00023B0004200020023B000220002D000120034F0D01200020002F00003B0002200020023B00000C010B2002413D4C044020002D00052102024020002D0003220320002D000122044D0440200241FF017120034D0D0120002F00042102200020002F00023B0004200020023B0002200420024108764F0D01200020002F00003B0002200020023B00000C010B20002F000021042003200241FF0171220249044020002F00042102200020043B0004200020023B00000C010B20002F00022103200020043B0002200020033B0000200220044180FE03714108764D0D0020002F00042102200020043B0004200020023B00020B200041066A22022001460D01200041046A21030340200222082D000120032D00014B044020082F00002206410876210520082104034002402004200322022F00003B000020002002460440200021020C010B200241026B210320022104200241016B2D00002005490D010B0B200220063B00000B20012008220341026A2202470D000B0C010B2000200341026D41017422046A21060240200241CF0F4E044020002000200341046D41017422026A22032006200220066A220210242107200A2D000020022D00014D0D0120022F00002105200220092F00003B0000200920053B000020022D0001200020046A22052D00014D0440200741016A21070C020B20062F00002108200620022F00003B0000200220083B000020052D000120032D00014D0440200741026A21070C020B20032F00002102200320062F00003B0000200620023B000020032D000120002D00014D0440200741036A21070C020B20002F00002102200020032F00003B0000200320023B0000200741046A21070C010B200A2D000021020240200020046A22052D0001220320002D00014D044041002107200241FF017120034D0D0220062F00002102200620092F00003B0000200920023B00004101210720052D000120002D00014D0D0220002F00002102200020062F00003B0000200620023B00000C010B20002F000021052003200241FF0171490440200020092F00003B0000200920053B0000410121070C020B200020062F00003B0000200620053B000041012107200A2D000020054180FE03714108764D0D01200620092F00003B0000200920053B00000B410221070B20092103027F0240024020002D00012208200020046A2D000122054B0440200921020C010B0340200341026B22022000460440200041026A21042008200A2D00004B0D0320042009460D05034020042D0001200849044020042F00002102200420092F00003B0000200920023B0000200441026A21040C050B2009200441026A2204470D000B0C050B200341016B21042002210320042D000020054D0D000B20002F00002103200020022F00003B0000200220033B0000200741016A21070B2002200041026A22044B0440037F20062D0001210803402004220341026A2104200841FF0171220520032D0001490D000B0340200241016B2108200241026B210220082D000020054D0D000B2002200349047F20030520032F00002105200320022F00003B0000200220053B00002002200620032006461B2106200741016A21070C010B0B21040B024020042006460D0020062D000120042D00014D0D0020042F00002102200420062F00003B0000200620023B0000200741016A21070B20074504402000200410252105200441026A2203200110250440200421012005450D060C040B410220050D021A0B200420006B200120046B480440200020041020200441026A21000C040B200441026A20011020200421010C040B200420092202460D01037F20002D0001210803402004220341026A2104200841FF0171220520032D00014D0D000B0340200241016B2108200241026B2102200520082D00004B0D000B200220034D047F41040520032F00002105200320022F00003B0000200220053B00000C010B0B0B21022003210020024104460D0120024102460D010B0B0B0BFF0F01197F02402000280210200028020C6B221641017522074102490D00027F0240024002404101200028020474220A4101742201044020014180808080044F0D01200A4103742204105F220B4100200410591A0B200041186A210E0240200028021C200028021822026B41027522042001490440200E200120046B10220C010B200120044F0D002000200220014102746A36021C0B200041246A210F02402000280228200028022422026B41027522042001490440200F200120046B10220C010B200120044F0D002000200220014102746A3602280B200041306A210602402000280234200028023022046B220141FF3F4D044020064180C00020016B10180C010B20014180C000460D00200020044180406B3602340B20074180808080044F0D0020164101742201105F4100200110592109200A41016B2218200741016B22146E2102200028020C22052D000341087421044102210120052D000122034108742213210C0340024020012108200C20136C411076220C20044D0D00200841016A2101200220084B0D010B0B2008410F4D044020160D024100210441000C040B200628020020052D00003A0000200841016B2106200741024F044020064103712103200841026B410349210D41012104410121050340200421012003220204400340200028023020016A200028020C2D00003A0000200141016A2101200241016B22020D000B0B200420066A2102200D4504400340200028023020016A200028020C2D00003A0000200120002802306A200028020C2D00003A0001200120002802306A200028020C2D00003A0002200120002802306A200028020C2D00003A0003200141046A22012002470D000B0B200028023020026A200028020C20054101746A2D00003A0000200420086A2104200541016A22052007470D000B2009200620076C221536020020074102490D032014410771210241012101200741026B41074F0440201441787121050340200920014102746A20013602002009200141016A22034102746A20033602002009200141026A22034102746A20033602002009200141036A22034102746A20033602002009200141046A22034102746A20033602002009200141056A22034102746A20033602002009200141066A22034102746A20033602002009200141076A22034102746A2003360200200141086A2101200541086B22050D000B0B2002450D030340200920014102746A2001360200200141016A2101200241016B22020D000B0C030B2009200620076C2215360200410121040C020B1057000B20074101200741014B1B21044100210103402009200141027422026A20013602002002200B6A200341FF0171410874360200200E28020020026A2001360200200F28020020026A4101360200200628020020016A200520014101746A2D00003A00002004200141016A22014604402007211020040C0305200028020C220520014101746A2D000121030C010B000B000B410021050340200541016A2106200741014B0440200C410874210D200520076C21112000280224211220002802182110200028020C2117410121010340200B200120116A41027422026A200D201720014101746A2D000122036C411076200341087420051B360200200220106A200120086C20056B360200200220126A2006360200200141016A22012007470D000B0B200C20136C411076201320051B210C200820062205470D000B200B201541027422016A200C360200200E28020020016A4100360200200F28020020016A2008360200200820146C41016A2110200720086C0B21050240200A20104D0D0020074101200741014B1B220C417E712115200C41017121190340410021014100210602402016450D00410021024100210320152108200741024F04400340200B20092002410172220D4102746A2802004102746A2802002211200B200920024102746A2802004102746A28020022122003200320124922121B2203200320114922111B2103200D2002200620121B20111B2106200241026A2102200841026B22080D000B0B2019450D0020022006200B200920024102746A2802004102746A28020020034B1B21060B200F2802002208200920064102746A221328020041027422026A280200220341016A21112002200B6A2802004108742112200E280200220620026A28020021170340200B200541027422026A20122001410174220D200028020C6A2D00016C411076360200200220066A2004360200200220086A20113602002000280230220220046A200220176A200310561A200320046A220420002802306A200028020C200D6A2D00003A0000200541016A2105200441016A210402402018200120106A47047F200141016A2201200C470D01200C0520010B20074604402013201328020020076A3602000B201020146A2210200A490D020C030B200F2802002108200E28020021060C000B000B000B200E280200210320050440200F28020021084100210441002101410021020340200120092004410020042007491B22044102746A2802004F04402003200241027422066A20032001410274220D6A280200360200200620086A2008200D6A280200360200200241016A21020B200441016A2104200141016A22012005470D000B200E28020021030B0240200028021C20036B4102752201200A490440200E200A20016B10220C010B2001200A4D0D0020002003200A4102746A36021C0B02402000280228200028022422046B4102752201200A490440200F200A20016B10220C010B2001200A4D0D0020002004200A4102746A3602280B2009105E200B450D00200B105E0B0BF80101067F200120002802082202200028020422036B4102754D044020002001047F2003410020014102742201105920016A0520030B3602040F0B02402003200028020022046B2206410275220520016A22074180808080044F0D00410021032005410274027F2007200220046B2202410175220520052007491B41FFFFFFFF03200241027541FFFFFFFF01491B2202044020024180808080044F0D022002410274105F21030B20030B6A410020014102742201105920016A2101200320024102746A2102200641004A044020032004200610561A0B200020023602082000200136020420002003360200200404402004105E0B0F0B1057000BAE0401087F200120002802082203200028020422046B4102754D044002402001450D002001410274210620042103200141027441046B220541027641016A41077122010440034020032002280200360200200341046A2103200141016B22010D000B0B200420066A21042005411C490D0003402003200228020036020020032002280200360204200320022802003602082003200228020036020C2003200228020036021020032002280200360214200320022802003602182003200228020036021C200341206A22032004470D000B0B200020043602040F0B02402004200028020022066B2208410275220720016A22044180808080044F0D002004200320066B22034101752205200420054B1B41FFFFFFFF03200341027541FFFFFFFF01491B2205047F20054180808080044F0D012005410274105F0541000B220420074102746A220721032001410274220941046B220A41027641016A4107712201044020072103034020032002280200360200200341046A2103200141016B22010D000B0B200720096A2101200A411C4F044003402003200228020036020020032002280200360204200320022802003602082003200228020036020C2003200228020036021020032002280200360214200320022802003602182003200228020036021C200341206A22032001470D000B0B200420054102746A2102200841004A044020042006200810561A0B200020023602082000200136020420002004360200200604402006105E0B0F0B1057000BF90201037F20022D00012104027F20012D0001220520002D00014D04404100200441FF017120054D0D011A20012F00002104200120022F00003B0000200220043B000020012D000120002D00014D04402004410876210441010C020B20002F00002104200020012F00003B0000200120043B000020022D0001210441020C010B20002F000021062005200441FF0171490440200020022F00003B0000200220063B000020064180FE0371410876210441010C010B200020012F00003B0000200120063B0000410120022D00012204200641087622054D0D001A200120022F00003B0000200220063B00002005210441020B210520032D0001200441FF01714B047F20022F00002104200220032F00003B0000200320043B000020022D000120012D00014D0440200541016A0F0B20012F00002104200120022F00003B0000200220043B000020012D000120002D00014D0440200541026A0F0B20002F00002102200020012F00003B0000200120023B0000200541036A0520050B0BBF0601077F41012106024002400240024002400240200120006B4101750E06050500010203040B200141016B2D000020002D00014D0D0420002F000021022000200141026B22062F00003B0000200620023B000041010F0B200141026B2102200141016B22012D0000210320002D0003220420002D00014D0440200341FF017120044D0D0420002F00022103200020022F00003B0002200220033B000020002D000320002D00014D0D042000200028000041107736000041010F0B20002F000021052004200341FF0171490440200020022F00003B0000200220053B000041010F0B20002F00022103200020053B0002200020033B000020012D000020054180FE03714108764D0D03200020022F00003B0002200220053B000041010F0B2000200041026A200041046A200141026B10241A41010F0B2000200041026A200041046A200041066A10241A200141016B2D000020002D00074D0D0120002F000621022000200141026B22032F00003B0006200320023B000020002D000720002D00054D0D0120002F00062102200020002F00043B0006200020023B00042002410876220320002D00034D0D01200020002F00023B0004200020023B000220002D000120034F0D01200020002F00003B0002200020023B000041010F0B20002D00052102024020002D0003220320002D000122044D0440200241FF017120034D0D0120002F00042102200020002F00023B0004200020023B0002200420024108764F0D01200020002F00003B0002200020023B00000C010B20002F000021042003200241FF0171220249044020002F00042102200020043B0004200020023B00000C010B20002F00022103200020043B0002200020033B0000200220044180FE03714108764D0D0020002F00042102200020043B0004200020023B00020B200041066A22022001460D00200041046A210602400340200222052D000120062D00014B044020052F00002208410876210420052103034002402003200622022F00003B000020002002460440200021020C010B200241026B210620022103200241016B2D00002004490D010B0B200220083B0000200741016A22074108460D020B20052106200541026A22022001470D000B41010F0B200541026A20014621060B20060BDC0D040A7F047D027C017E200041306A210B0240200141017422092000280234200028023022036B41027522064B0440200B200920066B10220C010B200620094D0D002000200320094102746A3602340B0240200041406B280200200028023C22036B410275220620094904402000413C6A200920066B10220C010B200620094D0D002000200320094102746A3602400B2000280230210902400240024002400240024002400240200028021441016B0E06000401040203040B2001450D0441002106034020022006410C6C6A220328020422052005411F7522046A200473200328020022042004411F7522076A2007736A200328020822072007411F7522036A2003736A2103027F20002A020C220D8B430000004F5D0440200DA80C010B4180808080780B2108200920064103746A027F20034504404100210A41000C010B200520086C20036D210A200420086C20036D2203200741004E0D001A200541004821074100027F2008B722112003B799A122129944000000000000E0416304402012AA0C010B4180808080780B22036B210820044100482104027F2011200AB799A122119944000000000000E0416304402011AA0C010B4180808080780B21052008200320071B210A410020056B200520041B0BAD200AAD42208684370200200641016A22062001470D000B0C030B2001450D034100210603402002200641066C6A22032E010222052005411F7522046A20047320032E010022042004411F7522076A2007736A20032E010422072007411F7522036A20037341FFFF03716A2103027F20002A020C220D8B430000004F5D0440200DA80C010B4180808080780B2108200920064103746A027F20034504404100210A41000C010B200520086C20036D210A200420086C20036D2203200741004E0D001A200541004821074100027F2008B722112003B799A122129944000000000000E0416304402012AA0C010B4180808080780B22036B210820044100482104027F2011200AB799A122119944000000000000E0416304402011AA0C010B4180808080780B21052008200320071B210A410020056B200520041B0BAD200AAD42208684370200200641016A22062001470D000B0C020B2001450D024100210603402002200641036C6A22032C000122052005411F7522046A20047320032C000022042004411F7522076A2007736A20032C000222072007411F7522036A20037341FF01716A2103027F20002A020C220D8B430000004F5D0440200DA80C010B4180808080780B2108200920064103746A027F20034504404100210A41000C010B200520086C20036D210A200420086C20036D2203200741004E0D001A200541004821074100027F2008B722112003B799A122129944000000000000E0416304402012AA0C010B4180808080780B22036B210820044100482104027F2011200AB799A122119944000000000000E0416304402011AA0C010B4180808080780B21052008200320071B210A410020056B200520041B0BAD200AAD42208684370200200641016A22062001470D000B0C010B2001450D0141002106034020022006410C6C6A22032A0200220F8B20032A020422108B9220032A0208220D8B92210E200D43000000005D2103027F20002A020C220D8B430000004F5D0440200DA80C010B4180808080780B21052010200E95210D200F200E95210E02402003450440200E210F0C010B430000803F200D8B93220D8C200D200F43000000005D1B210F430000803F200E8B93210D201043000000005D450D00200D8C210D0B027F200D2005B2220E94220D8B430000004F5D0440200DA80C010B4180808080780BAD4220862113200920064103746A2013027F200F200E94220D8B430000004F5D0440200DA80C010B4180808080780BAD84370200200641016A22062001470D000B0B200B28020022022802042105200228020021042001410249044020052107200421080C030B4101210A200141016B2202410171210C2001410246044020042108200521070C020B2002417E71210B200421082005210703402009200A4103746A220128020C220220012802042206200520052006481B2203200220034A1B210520012802082203200128020022012004200120044A1B2204200320044A1B210420022006200720062007481B220620022006481B210720032001200820012008481B2201200120034A1B2108200A41026A210A200B41026B220B0D000B0C010B200B2802002209280204220721052009280200220821040C010B200C450D002009200A4103746A220128020022092008200820094A1B210820012802042201200720012007481B21072009200420042009481B210420012005200120054A1B21050B20042008417F736AAC10162109200020052007417F736AAC101622012009200120094A1B41016A36021C0BEF0402057F067D230041106B2206240002402000280220450D00200641003A0008200642F0DECDCBC6AEDAB7EE00370300200641083A000B20032006410C6A20061028220728020022054504404120105F2205200641086A22082802003602182005200629030037021020084100360200200642003703002005410036021C2005200628020C360208200542003702002007200536020020032802002802002208047F2003200836020020072802000520050B21072003280204200710292003200328020841016A3602080B200528021C22050440200541F80941980A107121090B20062C000B41004804402006280200105E0B20042802082105200641003602082006420037030020012009280220200220052006102A20002802204102460440200120022005200041246A102B0B20002802302104027F20002A020C220A8B430000004F5D0440200AA80C010B4180808080780B210020062802002102200104402000B2210E41002100034020022000410C6C6A22052A0204220C20052A0200220B8B200C8B9220052A0208220F8B92220D95210A200B200D95210D0240200F43000000005D450440200D210B0C010B430000803F200A8B93220A8C200A200B43000000005D1B210B430000803F200D8B93210A200C43000000005D450D00200A8C210A0B200420004103746A22052005280200027F200B200E94220C8B430000004F5D0440200CA80C010B4180808080780B6B36020020052005280204027F200A200E94220A8B430000004F5D0440200AA80C010B4180808080780B6B360204200041016A22002001470D000B200628020021020B2002450D00200620023602042002105E0B200641106A24000B950201077F200041046A210402402000280204220004402002280200200220022D000B220341187441187541004822051B21082002280204200320051B21020340024002400240024002400240200028021420002D001B2203200341187441187541004822061B22032002200220034B22091B220504402008200041106A2207280200200720061B22072005105A220645044020022003490D020C030B200641004E0D020C010B200220034F0D020B200028020022030D042001200036020020000F0B200720082005105A22030D010B20090D010C050B200341004E0D040B200041046A210420002802042203450D03200421000B20002104200321000C000B000B2001200436020020040F0B2001200036020020040BA20401037F2001200020014622033A000C024020030D000340200128020822022D000C0D010240027F2002200228020822032802002204460440024020032802042204450D0020042D000C0D002004410C6A21040C030B024020012002280200460440200221040C010B200220022802042204280200220136020420042001047F2001200236020820022802080520030B3602082002280208220320032802002002474102746A20043602002004200236020020022004360208200428020821030B200441013A000C200341003A000C200320032802002202280204220436020020040440200420033602080B200220032802083602082003280208220420042802002003474102746A200236020020022003360204200341086A0C010B02402004450D0020042D000C0D002004410C6A21040C020B024020012002280200470440200221010C010B20022001280204220436020020012004047F2004200236020820022802080520030B3602082002280208220320032802002002474102746A20013602002001200236020420022001360208200128020821030B200141013A000C200341003A000C200320032802042202280200220436020420040440200420033602080B200220032802083602082003280208220420042802002003474102746A200236020020022003360200200341086A0B20023602000C020B200241013A000C2003200020034622023A000C200441013A0000200321012002450D000B0B0B8A0302077D097F230041106B220D240020042004280200220C360204200D4100360208200D42003703002000044020042000200D102C2004280200210C0B200241036C220441004A0440200320044102746A210F034020012003280208410C6C22106A2200280200211120012003280204410C6C22126A2202280200211320012003280200410C6C22046A220E28020021142004200C6A220420042A02002002280204B2200E280204B222069322072000280208B2200E280208B22205932209942002280208B220059322052000280204B2200693220A9493220692380200200420052011B22014B2220893220B942013B2200893220820099493220520042A02049238020420042008200A942007200B9493220720042A020892380208200C20126A2204200620042A0200923802002004200520042A0204923802042004200720042A020892380208200C20106A2204200620042A0200923802002004200520042A0204923802042004200720042A0208923802082003410C6A2203200F490D000B0B200D41106A24000B860201027F230041106B220524002003200328020022043602042005410036020C20000440200320002005410C6A1023200328020021040B200141036C220341004A0440200220034102746A21000340200420022802004102746A22032003280200200228020473360200200420022802004102746A22032003280200200228020873360200200420022802044102746A22032003280200200228020873360200200420022802044102746A22032003280200200228020073360200200420022802084102746A22032003280200200228020073360200200420022802084102746A220320032802002002280204733602002002410C6A22022000490D000B0B200541106A24000BE10401077F200120002802082203200028020422066B410C6D4D044002402001450D002001410C6C2104200621032001410C6C410C6B2205410C6E41016A41037122010440034020032002290200370200200320022802083602082003410C6A2103200141016B22010D000B0B200420066A210620054124490D000340200320022902003702002003200241086A2201280200360208200320012802003602142003200229020037020C2003200128020036022020032002290200370218200320022902003702242003200128020036022C200341306A22032006470D000B0B200020063602040F0B02402006200028020022056B410C6D220820016A220441D6AAD5AA014F0D002004200320056B410C6D22034101742205200420054B1B41D5AAD5AA01200341AAD5AAD500491B2207047F200741D6AAD5AA014F0D012007410C6C105F0541000B22092008410C6C6A220521032001410C6C2204410C6B2208410C6E41016A4103712201044020052103034020032002290200370200200320022802083602082003410C6A2103200141016B22010D000B0B200420056A2104200841244F04400340200320022902003702002003200241086A2201280200360208200320012802003602142003200229020037020C2003200128020036022020032002290200370218200320022902003702242003200128020036022C200341306A22032004470D000B0B20092007410C6C6A210720052006200028020022036B220241746D410C6C6A2101200241004A044020012003200210561A0B200020073602082000200436020420002001360200200304402003105E0B0F0B1057000BF10301097F024002400240200028022022040440200028023C21072001280204200128020022086B22020D010C020B200028023C220520002802302202200128020022062802004103746A2802003602002005200220062802004103746A28020436020441012103200128020420066B2209410475220841014B04400340200520034103746A22042002200620034104746A22012802004103746A280200200220012802044103746A2802006B3602002004200220012802004103746A280204200220012802044103746A2802046B360204200341016A22032008470D000B0B20094103752202200041406B28020020056B41027522034B04402000413C6A200220036B10220F0B200220034F0D022000200520024102746A3602400F0B200028023021062000280224210A200241047522024101200241014B1B2109410021020340200820024104746A22052802002101024020044102460440200A20014102746A280200450D010B200720034103746A2204200620014103746A2802003602002004200620052802004103746A280204360204200341016A21030B200241016A22022009460D01200028022021040C000B000B20034101742202200041406B28020020076B41027522034B04402000413C6A200220036B10220F0B200220034F0D002000200720024102746A3602400B0BC60201067F200028022021070240024020022802082203200228020422016B2204417F4704402003200228020C2205470440200341003A00002002200341016A360208200228020421010C020B200441016A22064100480D0241002103200520016B22054101742208200620042008491B41FFFFFFFF07200541FFFFFFFF03491B220504402005105F21030B200320046A220641003A0000200320056A2105200641016A2106200441004A044020032001200410561A0B2002200536020C2002200636020820022003360204200104402001105E0B200228020421010C010B200220013602080B200120046A20073A00002002200228020820022802046B3602102002200041406B280200200028023C22016B41027541017620014102102F200228021021012002200228020820022802046B22043602102000200420016B3602180F0B1057000B9A03010C7F230041206B220C2400200C41086A2001101B210702402001450D00200141004E04402001105F2208410020011059220E20016A210F034020022003200A6C4102746A220D28020022092105024002400240200941016A0E020002010B410121050C010B410221052009411F7520097322044102490D000340200541016A21052004410175220441014B0D000B0B4101210B200341014A04400340024002400240200D200B4102746A280200220441016A0E020002010B410121040C010B2004411F7520047321064102210420064102490D000340200441016A21042006410175220641014B0D000B0B20042005200420054A1B2105200B41016A220B2003470D000B0B200A200E6A20053A000002402005450D00200341004C0D00200720094101200541016B7422066A2005101E4101210420034101460D0003402007200D20044102746A28020020066A2005101E200441016A22042003470D000B0B2001200A41016A220A470D000B0C010B1057000B2000200710302000200F20086B20081017200804402008105E0B2007101D200C41206A24000BD60401087F2001280214220341204704402001280210200374210702402001280200220320012802082202480440200128020421050C010B417F20024103742002410174220441FEFFFFFF03712004471B105F220520012802042206200241027410562102200604402006105E20012802084101742104200128020021030B20012004360208200120023602040B2001200341016A360200200520034102746A20073602002001428080808080043702100B200041046A2106200128020021050240024020002802082202200028020422036B2204417B4D0440200028020C220720026B41044F0440200241003600002000200241046A2202360208200628020021030C020B200441046A22024100480D022002200720036B22074101742209200220094B1B41FFFFFFFF07200741FFFFFFFF03491B220204402002105F21080B200420086A22074100360000200220086A2109200741046A2102200441004A044020082003200410561A0B2000200936020C2000200236020820002008360204200304402003105E200028020821020B200628020021030C010B2000200320046A41046A22023602080B200320046A20053602000240200220036B220420044104200441037122056B410020051B22086A220549044020062008101820002802042103200028020821020C010B200420054D0D002000200320056A22023602080B200128020421040240200220036B22022002200128020041027422016A2205490440200620011018200628020021030C010B200220054D0D002000200320056A3602080B200220036A2004200110561A0F0B1057000BBF0101037F20022002280208220341016A360208200020032D00003602202000413C6A2103024020014101742204200041406B280200200028023C22016B41027522054B04402003200420056B1022200328020021010C010B200420054F0D002000200120044102746A3602400B20022001410210322102024020002802204102470D00200241017422022000280240200028023C22046B41027522014B04402003200220016B10220F0B200120024D0D002000200420024102746A3602400B0B8A0301087F230041306B220324002003420037032820034200370320200342003703182000280208220428000021062000200441046A2204360208200420002802046B410371220504402000200420056B41046A22043602080B200341186A20062004101C2000200028020820064102746A3602084100210420034100360210200342003703082000200341086A101A024020010440200328020C220820032802082200460D012002410274210A200241004C210903402001200220076C4102746A21040240200020076A22062D0000220545044020090D0120044100200A10591A0C010B20090D002004200341186A2005101F410120057441017522056B36020041012100200241014704400340200420004102746A200341186A20062D0000101F20056B360200200041016A22002002470D000B0B20032802082100200328020C21080B200741016A2207200820006B2204490D000B0C010B200328020C200328020822006B21040B200004402003200036020C2000105E0B200341186A101D200341306A240020040BF70101037F02402000280204450D0020002802200D002002280204200228020022056B2202410C6D21042002044041012102200441014D0D01200028023C21030340200320024103746A22002000280200200320052002410C6C6A22012802004103746A2802006A360200200041046A22002000280200200320012802004103746A2802046A360200200241016A22022004470D000B0C010B410221032001410174220441024D0D00200028023C210003402000200341027422016A22022002280200200241086B2802006A360200200020014104726A22012001280200200241046B2802006A360200200341026A22032004470D000B0B0BB91302077D0E7F230041106B220E2400024002402000280204450D002000280220450D00200E41003A0008200E42F0DECDCBC6AEDAB7EE00370300200E41083A000B2003200E410C6A200E10282210280200220F4504404120105F220F200E41086A2211280200360218200F200E29030037021020114100360200200E4200370300200F410036021C200F200E28020C360208200F42003702002010200F36020020032802002802002211047F20032011360200201028020005200F0B21102003280204201010292003200328020841016A3602080B200F28021C22030440200341F80941980A1071210D0B200E2C000B4100480440200E280200105E0B200E4100360208200E420037030020010440200141D6AAD5AA014F0D02200E2001410C6C2203105F220F360200200E2003200F6A2210360208200F41002003410C6B22032003410C706B410C6A10591A200E20103602040B200D280204210302402004280200220F0440200120032002200F200E102A0C010B2002210F20042802042115230041106B22172400200E220D200E28020022163602042017410036020820174200370300200122100440200D20102017102C200D28020021160B200F41036C220D41004A04402015200D4101746A21190340200320152F0104410C6C22146A2210280200210C200320152F0102410C6C22126A220F2802002113200320152F0100410C6C220D6A22182802002111200D20166A220D200D2A0200200F280204B22018280204B2220A93220B2010280208B22018280208B2220993220894200F280208B220099322092010280204B2200A9322069493220A92380200200D2009200CB22011B22205932207942013B22005932205200894932209200D2A020492380204200D2005200694200B20079493220B200D2A020892380208201220166A220D200A200D2A020092380200200D2009200D2A020492380204200D200B200D2A020892380208201420166A220D200A200D2A020092380200200D2009200D2A020492380204200D200B200D2A020892380208201541066A22152019490D000B0B201741106A24000B024020002802204102470D00200428020022030440200120022003200041246A102B0C010B20042802042103200020002802242204360228200E410036020C20010440200041246A22042001200E410C6A1023200428020021040B200241036C220141004C0D00200320014101746A21100340200420032F010022014102746A220F20032F01042202200F28020020032F0102220F73733602002004200F4102746A220D200D280200200120027373360200200420024102746A220220022802002001200F7373360200200341066A22032010490D000B0B024002400240200028021441036B0E0401020200020B200028020421014100210D410021100240200E280204200E28020022146B220C450D00200028023C2104200C410C6D220C4101200C41014B1B210303402001200D410C6C22126A210C201220146A211402400240200028022041014704402000280224200D4102746A280200450D010B20142A020022078B20142A020422088B9220142A020822058B922106200543000000005D2114027F20002A020C22058B430000004F5D04402005A80C010B4180808080780B2113200820069521052007200695210602402014450440200621070C010B430000803F20058B9322058C2005200743000000005D1B2107430000803F20068B932105200843000000005D450D0020058C21050B2013027F20052013B222069422058B430000004F5D04402005A80C010B4180808080780B200420104103746A22122802046A22142014411F75220F6A200F73220F027F200720069422058B430000004F5D04402005A80C010B4180808080780B20122802006A22122012411F7522116A20117322026A6B2211B22105201041016A2110200C2011410048047F4100201320026B22116B2011201441004C1B211441002013200F6B22136B2013201241004C1B0520120BB2220620052005942014B222072007942006200694929291220695380200200C2005200695380208200C20072006953802040C010B200C20142A02002205200520059420142A020422052005949220142A020822062006949291220795380200200C2006200795380208200C20052007953802040B200D41016A220D2003460D01200E28020021140C000B000B0C010B200028020421044100210D0240200E280204200E280200220C6B2213450D00200028023C21032013410C6D22134101201341014B1B2102410021130340200C2013410C6C6A210C0240024020002802204101470440200028022420134102746A280200450D010B200C2A020022078B200C2A020422088B92200C2A020822058B922106200543000000005D2111027F20002A020C22058B430000004F5D04402005A80C010B4180808080780B210C200820069521052007200695210602402011450440200621070C010B430000803F20058B9322058C2005200743000000005D1B2107430000803F20068B932105200843000000005D450D0020058C21050B200C027F2005200CB222069422058B430000004F5D04402005A80C010B4180808080780B2003200D4103746A22122802046A4110742211411075220F2011411F7522116A20117341FFFF03712211027F200720069422058B430000004F5D04402005A80C010B4180808080780B20122802006A411074221241107522102012411F7522126A20127341FFFF037122016A6B2212B22105027D201241004E0440200FB221062010B20C010B200C20016B2212410020126B200F41004A1BB22106200C20116B220C4100200C6B201041004A1BB20B21072004201341066C6A220C027F20052005200594200620069420072007949292912208954300FEFF469422058B430000004F5D04402005A80C010B4180808080780B3B0104200D41016A210D200C027F20062008954300FEFF469422058B430000004F5D04402005A80C010B4180808080780B3B010220072008954300FEFF469422058B430000004F5D0440200C2005A83B01000C020B200C41003B01000C010B200C2A02002205200594200C2A0204220620069492200C2A020822072007949291220843ACC527375D0440200C4100360200200C4100360204200C41808080FC033602080C010B2004201341066C6A220C027F4300FEFF46200895220820079422078B430000004F5D04402007A80C010B4180808080780B3B0104200C027F200820069422068B430000004F5D04402006A80C010B4180808080780B3B0102200C027F200820059422058B430000004F5D04402005A80C010B4180808080780B3B01000B201341016A22132002460D01200E280200210C0C000B000B0B200E2802002203450D00200E20033602042003105E0B200E41106A24000F0B1057000BFA0402077F047D02402000280204450D0020002802200D0002400240200028021441036B0E0400020201020B2001450D010340200028023C20064103746A2202280200411074220341107522042003411F7522036A20037341FFFF037122072002280204411074220241107522032002411F7522026A20027341FFFF037122086A2105027F20002A020C22098B430000004F5D04402009A80C010B4180808080780B220220056B2205B22109027D200541004E04402003B2210A2004B20C010B200220076B2205410020056B200341004A1BB2210A200220086B2202410020026B200441004A1BB20B210B2000280204200641066C6A2202027F20092009200994200A200A94200B200B94929291220C954300FEFF469422098B430000004F5D04402009A80C010B4180808080780B3B01042002027F200A200C954300FEFF469422098B430000004F5D04402009A80C010B4180808080780B3B01022002027F200B200C954300FEFF469422098B430000004F5D04402009A80C010B4180808080780B3B0100200641016A22062001470D000B0C010B2001450D000340200028023C20064103746A220328020422022002411F7522046A2004732207200328020022032003411F7522046A20047322086A2105027F20002A020C22098B430000004F5D04402009A80C010B4180808080780B220420056B2205B22109200541004804404100200420086B22056B2005200241004C1B21024100200420076B22046B2004200341004C1B21030B20002802042006410C6C6A2204200920092009942002B2220B200B942003B2220A200A94929291220C953802082004200B200C953802042004200A200C95380200200641016A22062001470D000B0B0B5001017F200041AC0A360200200028023C22010440200041406B20013602002001105E0B200028023022010440200020013602342001105E0B200028022422010440200020013602282001105E0B20000B5201017F200041AC0A360200200028023C22010440200041406B20013602002001105E0B200028023022010440200020013602342001105E0B200028022422010440200020013602282001105E0B2000105E0B040041020BE807020A7F017D230041106B22052400200041206A21070240200028020820016C22032000280224200028022022066B22044B04402007200320046B10180C010B200320044F0D002000200320066A3602240B02402000280230200028022C22066B220420034904402000412C6A200320046B10180C010B200320044F0D002000200320066A3602300B024002400240200028021441046B0E03000201020B2001450D0120072802002106200028020821070340200741004A04402007410171210B41002103200741014704402007417E71210803402005410C6A20036A200220036A2D0000200041386A220920034102746A2802006D3A0000200341017222042005410C6A6A200220046A2D0000200920044102746A2802006D3A0000200341026A2103200841026B22080D000B0B200B04402005410C6A20036A200220036A2D0000200020034102746A2802386D3A00000B20052D000F210C20052D000E210820052D000D210420052D000C21030B2005200441FF0171200C411874200320046B220941FF017141107472200820046B220B41FF0171410874727236020C41002103200741004A04400340200320066A2005410C6A20036A2D00003A0000200341016A220320002802082207480D000B0B200620076A2106200220076A21022004210320092108200B2104200A41016A220A2001470D000B0C010B200541FF013A000B2001450D00200028020821042000280220210741FF01210C0340200441004A04402004410171210C41002103200441014704402004417E7121060340200041386A2208200341027422096A280200210A200541086A20036A027F200220096A2A02004300007F4394220D8B430000004F5D0440200DA80C010B4180808080780B200A6D3A0000200820034101722209410274220A6A2802002108200541086A20096A027F2002200A6A2A02004300007F4394220D8B430000004F5D0440200DA80C010B4180808080780B20086D3A0000200341026A2103200641026B22060D000B0B200C04402000200341027422066A2802382108200541086A20036A027F200220066A2A02004300007F4394220D8B430000004F5D0440200DA80C010B4180808080780B20086D3A00000B20052D000B210C20052D000A210820052D0009210620052D000821030B2005200641FF0171200C411874200320066B220941FF017141107472200820066B220A41FF0171410874727236020841002103200441004A04400340200320076A200541086A20036A2D00003A0000200341016A220320002802082204480D000B0B200420076A2107200220044102746A21022006210320092108200A2106200B41016A220B2001470D000B0B2000410036021C200541106A24000B8605010C7F230041106B220524000240024020002802042204450D0002400240200028021441046B0E03000201020B2000280248210320002802082102200541FF013A000F200120026C220741004C0D01200420076A21092004200120036C6A210741FF01210A0340200920026B2109200720036B21072005200241004A047F2005410C6A2009200210561A20052D000F210A20052D000D210B20052D000C210620052D000E0520080B20066A220841FF0171200A4118742006200B6A220141FF017141107472200641FF0171410874727236020C41002102200341004A04400340200220076A2005410C6A20026A2D0000200020024102746A2D00386C3A0000200241016A220220002802482203480D000B200028020421040B200420094F0D02200028020821022006210B20082106200121080C000B000B200145044041002004200141027410561A0C010B20014180808080044F0D0120014102742202105F200420021056210A20002802482208417E71210C2008410171210D0340200A200B4102746A220220022D000341187420022D0000220320022D00016A41FF017141107472200341087472200320022D00026A41FF0171723600000240200841004C0D0041002102200C21072008410147044003402004200241027422036A220620062A0200200041386A220620036A280200B2944300007F43953802002004200341047222036A220920092A0200200320066A280200B2944300007F4395380200200241026A2102200741026B22070D000B0B200D450D002004200241027422026A220320032A0200200020026A280238B2944300007F43953802000B200420084102746A2104200B41016A220B2001470D000B200A105E0B200541106A24000F0B1057000B3801017F200041F40B360200200028022C22010440200020013602302001105E0B200028022022010440200020013602242001105E0B20000B3A01017F200041F40B360200200028022C22010440200020013602302001105E0B200028022022010440200020013602242001105E0B2000105E0B040041030B0300010BE003010A7F2000280208220341004A04400340200028022C20026A2000280220200128020028020020036C20026A6A2D00003A0000200241016A220220002802082203480D000B0B410121062001280204200128020022026B410475220441014B04400340200220064104746A220541046A2108024002402005280204220420052802082209460D0020002D0010410171450D00200341004C0D01200541086A210A2005410C6A210B410021020340200028022C200320066C20026A6A20002802202207200528020020036C20026A6A2D00002007200320046C20026A6A2D00002007200320096C20026A6A2D00006A6B2007200B28020020036C20026A6A2D00006A3A0000200241016A2202200028020822034E0D02200A2802002109200828020021040C000B000B41002102200341004C0D000340200028022C200320066C20026A6A20002802202207200528020020036C20026A6A2D00002007200320046C20026A6A2D00006B3A0000200241016A2202200028020822034E0D01200828020021040C000B000B200641016A22062001280204200128020022026B4104752204490D000B0B200320046C22032000280230200028022C22046B22024B04402000412C6A200320026B10180F0B200220034B04402000200320046A3602300B0BFE05010B7F200220022802082204200228020422056B360210024002402000280208220641004C0D000340200020034102746A28023821090240200420056B2206417F4704402004200228020C2208470440200441003A00002002200441016A360208200228020421050C020B200641016A22044100480D042006200820056B2208410174220A20042006200A491B41FFFFFFFF07200841FFFFFFFF03491B2208047F2008105F0541000B22046A220A41003A0000200420086A2108200A41016A210A200641004A044020042005200610561A0B2002200836020C2002200A36020820022004360204200504402005105E0B200228020421050C010B200220053602080B200520066A20093A0000200341016A2203200028020822064E0D0120022802042105200228020821040C000B000B200028022C210A41002104230041206B22082400200841086A20012209101B21050240200622010440200141D6AAD5AA014904402001410C6C2203105F41002003410C6B410C6E410C6C410C6A22031059220C20036A2106034002402009200C2004410C6C6A220D280204200D28020022076B22034B0440200D200920036B10180C010B200320094D0D00200D200720096A3602040B410021072009044003400240200A200120076C20046A6A2C00002203450440200D28020020076A41003A00000C010B20032003411F75220B6A200B73AD1016210B200D28020020076A200B41016A220B3A0000200541004101200B7441017520036A6B200320034100481B200B101E0B200741016A22072009470D000B0B200441016A22042001470D000B2002200510304100210303402002200C2003410C6C6A2207280204200728020022076B20071017200341016A22032001470D000B2006200C47044003402006410C6B220328020022070440200641086B20073602002007105E0B200321062003200C470D000B0B200C105E0C020B1057000B2002200510300B2005101D200841206A2400200228021021052002200228020820022802046B22043602102000200420056B3602180F0B1057000B890201077F02402000280208220541004C0D0020054103712107200228020821010240200541016B4103490440200121040C010B2005417C712109200041386A210603402002200141016A3602082006200341027422086A20012D00003602002002200141026A360208200620084104726A20012D00013602002002200141036A360208200620084108726A20012D00023602002002200141046A220436020820062008410C726A20012D0003360200200341046A210320042101200941046B22090D000B0B2007450D0003402002200441016A2201360208200020034102746A20042D0000360238200341016A210320012104200741016B22070D000B0B20022000280204200510420BE10201077F230041306B220324002003420037032820034200370320200342003703182000280208220428000021052000200441046A2204360208200420002802046B410371220604402000200420066B41046A22043602080B200341186A20052004101C2000200028020820054102746A36020820034100360210200342003703080240200241004C0D0003402000200341086A101A02402001450D0041002104200328020C220620032802082205460D0003400240200420056A22082D000022094504402001200220046C20076A6A41003A00000C010B2001200220046C20076A6A4100200341186A2009101F2205410120082D000041016B7422066A6B200520052006481B3A000020032802082105200328020C21060B200441016A2204200620056B490D000B0B200741016A22072002470D000B200328020C1A20032802082204450D002003200436020C2004105E0B200341186A101D200341306A24000BC90301077F024020002802042207450D0020002D0010410171044020022802042206200228020022056B410C6D4102490D012000280208210341012101034041002104200341004A044020052001410C6C6A220641086A2108200641046A210903402007200120036C20046A6A220520052D00002007200928020020036C20046A6A2D00002007200628020020036C20046A6A2D00006A2007200828020020036C20046A6A2D00006B6A3A0000200441016A220420002802082203480D000B20022802002105200228020421060B200141016A2201200620056B410C6D490D000B0C010B2002280204220620022802002205470440200620056B410C6D4102490D012000280208210341012101034041002104200341004A044020052001410C6C6A210603402007200120036C20046A6A220520052D00002007200628020020036C20046A6A2D00006A3A0000200441016A220420002802082203480D000B20022802002105200228020421060B200141016A2201200620056B410C6D490D000B0C010B20002802082203200120036C4F0D00200321040340200420076A220520052D00002007200420036B6A2D00006A3A0000200441016A22042000280208220320016C490D000B0B0B040041010B9E0C03077F017D017C200041206A21090240200028020820016C22042000280224200028022022036B22014B04402009200420016B10180C010B200120044D0D002000200320046A3602240B02402000280230200028022C22036B220120044904402000412C6A200420016B10180C010B200120044D0D002000200320046A3602300B024002400240024002400240200028021441016B0E0701050205030400050B2004450D042004410171210641002101200441014704402004417E7121030340200028022020016A027F200220014103746A2B030020002A020CBBA3220B44000000000000F04163200B44000000000000000066710440200BAB0C010B41000B3A00002001410172220520002802206A027F200220054103746A2B030020002A020CBBA3220B44000000000000F04163200B44000000000000000066710440200BAB0C010B41000B3A0000200141026A2101200341026B22030D000B0B2006450D04200028022020016A027F200220014103746A2B030020002A020CBBA3220B44000000000000F04163200B44000000000000000066710440200BAB0C010B41000B3A00000C040B2004450D032004410171210641002101200441014704402004417E7121030340200028022020016A027F200220014102746A280200B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A00002001410172220520002802206A027F200220054102746A280200B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A0000200141026A2101200341026B22030D000B0B2006450D03200028022020016A2103200220014102746A280200B220002A020C95220A430000804F5D200A4300000000607104402003200AA93A00000C040B200341003A00000C030B2004450D022004410171210641002101200441014704402004417E7121030340200028022020016A027F200220014101746A2E0100B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A00002001410172220520002802206A027F200220054101746A2E0100B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A0000200141026A2101200341026B22030D000B0B2006450D02200028022020016A2103200220014101746A2E0100B220002A020C95220A430000804F5D200A4300000000607104402003200AA93A00000C030B200341003A00000C020B2004450D012004410171210641002101200441014704402004417E7121030340200028022020016A027F200120026A2C0000B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A00002001410172220520002802206A027F200220056A2C0000B220002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A0000200141026A2101200341026B22030D000B0B2006450D01200028022020016A2103200120026A2C0000B220002A020C95220A430000804F5D200A4300000000607104402003200AA93A00000C020B200341003A00000C010B2004450D002004410171210641002101200441014704402004417E7121030340200028022020016A027F200220014102746A2A020020002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A00002001410172220520002802206A027F200220054102746A2A020020002A020C95220A430000804F5D200A430000000060710440200AA90C010B41000B3A0000200141026A2101200341026B22030D000B0B2006450D00200028022020016A2103200220014102746A2A020020002A020C95220A430000804F5D200A4300000000607104402003200AA93A00000C010B200341003A00000B2000410036021C2000280208220841004A044003402009280200220620076A2D000021010240200420074D0440200121030C010B20012103200720086A220520044F0D000340200520066A2D000022022003200220034B1B210320022001200120024A1B2101200520086A22052004490D000B0B20032001417F736AAC101621022000200028021C2201200241016A200120024A1B36021C200741016A220720002802082208480D000B0B0B9A0801157F2002200228020820022802046B36021020002802082108200028022C2116024020002D0010410271044020082109230041206B220E2400200E41086A20012203101B211002402003450D00200341004E0440200941016B2204417E712101200441017121072003105F2211410020031059220C20036A21172009410248210D0340410021060240024002402016200920146C6A22152D0000220B0E020201000B41022106200B21040340200641016A210620044104492105200441017621042005450D000B0C010B410221060B0240200D0D004101211220012108200941024704400340410021054100210A024002400240201220156A220F2D000022040E020201000B4102210A0340200A41016A210A20044104492113200441017621042013450D000B0C010B4102210A0B200A20062006200A491B2113024002400240200F2D000122040E020200010B410221050C010B410221050340200541016A2105200441034B210A20044101762104200A0D000B0B20052013200520134B1B2106201241026A2112200841026B22080D000B0B2007450D0041002105024002400240201220156A2D000022040E020200010B410221050C010B410221050340200541016A2105200441034B210A20044101762104200A0D000B0B20052006200520064B1B21060B200C20146A20063A000002402006450D00200941004C0D0020104101200641016B742205200B6A2006101E4101210420094101460D00034020102005200420156A2D00006A2006101E200441016A22042009470D000B0B2003201441016A2214470D000B0C010B1057000B2002201010302002201720116B20111017201104402011105E0B2010101D200E41206A24000C010B230041206B22092400200941086A2001220B101B2104024020080440200841D6AAD5AA014904402008410C6C2203105F41002003410C6B410C6E410C6C410C6A22031059220C20036A210103400240200B200C200F410C6C6A220D280204200D28020022076B22034B0440200D200B20036B10180C010B2003200B4D0D00200D2007200B6A3602040B41002103200B0440034002402016200320086C200F6A6A2D00002207450440200D28020020036A41003A00000C010B2007AD1016210E200D28020020036A200E41016A220E3A000020042007200E101E0B200341016A2203200B470D000B0B200F41016A220F2008470D000B2002200410304100210303402002200C2003410C6C6A2207280204200728020022076B20071017200341016A22032008470D000B2001200C47044003402001410C6B220328020022070440200141086B20073602002007105E0B200321012003200C470D000B0B200C105E0C020B1057000B2002200410300B2004101D200941206A24000B200228021021012002200228020820022802046B22083602102000200820016B3602180B960301077F200028020821012000280204210620002D00104102710440230041306B220024002000420037032820004200370320200042003703182002280208220328000021052002200341046A2203360208200320022802046B410371220404402002200320046B41046A22033602080B200041186A20052003101C2002200228020820054102746A36020820004100360210200042003703082002200041086A101A024020060440200028020C220820002802082202460D01200141004C210903402006200120076C6A21030240200220076A22052D0000220445044020090D0120034100200110591A0C010B20090D002003200041186A2004101F410120047441017622046B3A000041012102200141014704400340200220036A200041186A20052D0000101F20046B3A0000200241016A22022001470D000B0B20002802082102200028020C21080B200741016A2207200820026B490D000B0C010B200028020C200028020822026B1A0B200204402000200236020C2002105E0B200041186A101D200041306A24000F0B20022006200110420BC21202057F027D024020002802042203450D00200028020820016C21020240024002400240024002400240024020002802140E080703060200040105080B2002450D072003027F20002A020C20032C0000B29422088B430000004F5D04402008A80C010B4180808080780B3A00004101210320024101460D07200241016B22014101712104200241024704402001417E7121010340027F20002A020C200028020420036A22022C0000B29422088B430000004F5D04402008A80C010B4180808080780B2105200220053A0000027F20002A020C200320002802046A41016A22022C0000B29422088B430000004F5D04402008A80C010B4180808080780B2105200220053A0000200341026A2103200141026B22010D000B0B2004450D07027F20002A020C200028020420036A22002C0000B29422088B430000004F5D04402008A80C010B4180808080780B2103200020033A00000C070B2002450D062002410171210441002101200241014704402002417E7121020340200320014102746A20002A020C200120036A2D0000B3943802002003200141017222054102746A20002A020C200320056A2D0000B394380200200141026A2101200241026B22020D000B0B2004450D06200320014102746A20002A020C200120036A2D0000B3943802000F0B2002450D0520002A020C21082002410371210541002100200241016B41034F04402002417C7121020340027F20082003200041017422016A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014102726A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014104726A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014106726A22012F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2104200120043B0100200041046A2100200241046B22020D000B0B2005450D050340027F2008200320004101746A22012F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2102200120023B0100200041016A2100200541016B22050D000B0C050B2002450D0420002A020C21082002410371210541002100200241016B41034F04402002417C7121020340027F20082003200041027422016A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F2008200320014104726A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F2008200320014108726A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F200820032001410C726A2201280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210420012004360200200041046A2100200241046B22020D000B0B2005450D040340027F2008200320004102746A2201280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210220012002360200200041016A2100200541016B22050D000B0C040B2002450D032003027F20002A020C20032C0000B29422088B430000004F5D04402008A80C010B4180808080780B3A00004101210320024101460D03200241016B22014101712104200241024704402001417E7121010340027F20002A020C200028020420036A22022C0000B29422088B430000004F5D04402008A80C010B4180808080780B2105200220053A0000027F20002A020C200320002802046A41016A22022C0000B29422088B430000004F5D04402008A80C010B4180808080780B2105200220053A0000200341026A2103200141026B22010D000B0B2004450D0320002A020C200028020420036A22032C0000B29422088B430000004F5D044020032008A83A00000F0B200341003A00000F0B2002450D0220002A020C21082002410171210541002100200241014704402002417E7121010340200320004103746A2008200020036A2D0000B394BB3903002003200041017222024103746A2008200220036A2D0000B394BB390300200041026A2100200141026B22010D000B0B2005450D02200320004103746A2008200020036A2D0000B394BB3903000F0B2002450D0120002A020C21082002410371210541002100200241016B41034F04402002417C7121020340027F20082003200041017422016A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014102726A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014104726A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014106726A22012F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2104200120043B0100200041046A2100200241046B22020D000B0B2005450D010340027F2008200320004101746A22012F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2102200120023B0100200041016A2100200541016B22050D000B0C010B2002450D0020002A020C21082002410371210541002100200241016B41034F04402002417C7121020340027F20082003200041027422016A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F2008200320014104726A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F2008200320014108726A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F200820032001410C726A2201280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210420012004360200200041046A2100200241046B22020D000B0B2005450D000340027F2008200320004102746A2201280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210220012002360200200041016A2100200541016B22050D000B0B0B41002001044020002001280200104920002001280204104920012C00274100480440200128021C105E0B20012C001B41004804402001280210105E0B2001105E0B0B2F002001044020002001280200104A20002001280204104A20012C001B41004804402001280210105E0B2001105E0B0BDB0301057F230041106B2205240002402001105B220441704F0D00200041146A2108024002402004410B4F0440200441106A4170712207105F2106200520074180808080787236020820052006360200200520043602040C010B200520043A000B200521062004450D010B20062001200410561A0B200420066A41003A0000200041186A210620082005104C210720052C000B41004804402005280200105E0B200620074704402001105B220441704F0D01024002402004410B4F0440200441106A4170712207105F2106200520074180808080787236020820052006360200200520043602040C010B200520043A000B200521062004450D010B20062001200410561A0B200420066A41003A000020082005410C6A20051028220128020022044504404120105F2204200541086A22062802003602182004200529030037021020064100360200200542003703002004410036021C2004200528020C360208200442003702002001200436020020082802002802002206047F2008200636020020012802000520040B21012000280218200110292000411C6A2201200128020041016A3602000B200428021C210420052C000B41004804402005280200105E0B20042002360204200420033602140B200541106A24000F0B1057000B9D0201087F200041046A21050240024020002802042200450D002001280200200120012D000B220241187441187541004822041B21072001280204200220041B210220052103034002402002200028021420002D001B2201200141187441187541004822011B2204200220044922081B22060440200041106A2209280200200920011B20072006105A22010D010B417F2008200220044B1B21010B2003200020014100481B210320002001411D764104716A28020022000D000B20032005460D000240200328021420032D001B2200200041187441187541004822011B2200200220002002491B220404402007200341106A2206280200200620011B2004105A22010D010B200020024B0D010C020B200141004E0D010B200521030B20030BA90C010C7F230041106B220924002001280208220228000021032001200241046A360208200041206A2106024020002802242202200028022022076B410475220820034904400240200320086B220320062802082202200628020422046B4104754D044002402003450D002003410474210720042102200341047441106B220841047641016A410771220304400340200241086A2205420037020020022005360204200241106A2102200341016B22030D000B0B200420076A2104200841F000490D000340200241086A22034200370200200241186A2205420037020020022003360204200241286A2203420037020020022005360214200241386A2205420037020020022003360224200241C8006A2203420037020020022005360234200241D8006A2205420037020020022003360244200241E8006A2203420037020020022005360254200241F8006A22054200370200200220033602642002200536027420024180016A22022004470D000B0B200620043602040C010B0240024002402004200628020022076B410475220420036A22054180808080014F0D002005200220076B22024103752207200520074B1B41FFFFFFFF00200241047541FFFFFF3F491B2207047F20074180808080014F0D012007410474105F0541000B220820044104746A220521022003410474220A41106B220B41047641016A41077122030440200521020340200241086A2204420037020020022004360204200241106A2102200341016B22030D000B0B2005200A6A210C200B41F0004F04400340200241086A22034200370200200241186A2204420037020020022003360204200241286A2203420037020020022004360214200241386A2204420037020020022003360224200241C8006A2203420037020020022004360234200241D8006A2204420037020020022003360244200241E8006A2203420037020020022004360254200241F8006A22044200370200200220033602642002200436027420024180016A2202200C470D000B0B200820074104746A210D2006280204220420062802002208460D010340200541106B2203200441106B22022802003602002003200228020436020420032002280208220A36020820032002410C6A220B280200220736020C024020074504402003200541086B3602040C010B200A200541086B3602082002200441086B220536020420054100360200200B41003602000B200321052002210420022008470D000B2006200D360208200628020421022006200C360204200628020021082006200336020020022008460D0203402002410C6B200241086B2802001049200241106B22022008470D000B0C020B1057000B2006200D3602082006200C360204200620053602000B200804402008105E0B0B200028022421050C010B200320084F0440200221050C010B200720034104746A2205200247044003402002410C6B200241086B2802001049200241106B22022005470D000B0B200020053602240B200520062802002204470440200941086A210A03402004200128020822022800003602002001200241056A360208024020022D0004220B450D002001200241076A220320022F00056A22023602082001200241026A220820022F00006A3602082003105B2202416F4D0440200441046A2107410021060340024002402002410B4F0440200241106A417071220C105F21002009200C4180808080787236020820092000360200200920023602040C010B200920023A000B200921002002450D010B20002003200210561A0B200020026A41003A000020072009410C6A20091028220028020022024504404128105F2202200A28020036021820022009290300370210200A410036020020094200370300200241003602242002420037021C2002200928020C360208200242003702002000200236020020072802002802002203047F2007200336020020002802000520020B21002004280208200010292004200428020C41016A36020C0B2002411C6A2008106C20092C000B41004804402009280200105E0B200641016A2206200B460D0220012001280208220241026A220320022F00006A22023602082001200241026A220820022F00006A3602082003105B2202416F4D0D000B0B1057000B200441106A22042005470D000B0B200941106A24000B3801017F200041AC0C360200200028022C22010440200020013602302001105E0B200028022022010440200020013602242001105E0B20000B3A01017F200041AC0C360200200028022C22010440200020013602302001105E0B200028022022010440200020013602242001105E0B2000105E0BF30B03077F027D027C200041206A21080240200028020820016C22042000280224200028022022036B41027522014B04402008200420016B10220C010B200120044D0D002000200320044102746A3602240B02402000280230200028022C22036B410275220120044904402000412C6A200420016B10220C010B200120044D0D002000200320044102746A3602300B024002400240024002400240200028021441016B0E0701050205030400050B2004450D042000280220210320002A020CBB210C2004410171210641002101200441014704402004417E7121050340200320014102746A027F200220014103746A2B0300200CA3220D9944000000000000E041630440200DAA0C010B4180808080780B3602002003200141017222074102746A027F200220074103746A2B0300200CA3220D9944000000000000E041630440200DAA0C010B4180808080780B360200200141026A2101200541026B22050D000B0B2006450D04200320014102746A027F200220014103746A2B0300200CA3220C9944000000000000E041630440200CAA0C010B4180808080780B3602000C040B2004450D032000280220210520002A020C210A2004410171210641002101200441014704402004417E71210703402005200141027422036A027F200220036A280200B2200A95220B8B430000004F5D0440200BA80C010B4180808080780B3602002005200341047222036A027F200220036A280200B2200A95220B8B430000004F5D0440200BA80C010B4180808080780B360200200141026A2101200741026B22070D000B0B2006450D032005200141027422016A2103200120026A280200B2200A95220A8B430000004F5D04402003200AA83602000C040B20034180808080783602000C030B2004450D022000280220210320002A020C210A2004410171210641002101200441014704402004417E7121050340200320014102746A027F200220014101746A2E0100B2200A95220B8B430000004F5D0440200BA80C010B4180808080780B3602002003200141017222074102746A027F200220074101746A2E0100B2200A95220B8B430000004F5D0440200BA80C010B4180808080780B360200200141026A2101200541026B22050D000B0B2006450D02200320014102746A2103200220014101746A2E0100B2200A95220A8B430000004F5D04402003200AA83602000C030B20034180808080783602000C020B2004450D012000280220210320002A020C210A2004410171210641002101200441014704402004417E7121050340200320014102746A027F200120026A2C0000B2200A95220B8B430000004F5D0440200BA80C010B4180808080780B3602002003200141017222074102746A027F200220076A2C0000B2200A95220B8B430000004F5D0440200BA80C010B4180808080780B360200200141026A2101200541026B22050D000B0B2006450D01200320014102746A2103200120026A2C0000B2200A95220A8B430000004F5D04402003200AA83602000C020B20034180808080783602000C010B2004450D002000280220210520002A020C210A2004410171210641002101200441014704402004417E71210703402005200141027422036A027F200220036A2A0200200A95220B8B430000004F5D0440200BA80C010B4180808080780B3602002005200341047222036A027F200220036A2A0200200A95220B8B430000004F5D0440200BA80C010B4180808080780B360200200141026A2101200741026B22070D000B0B2006450D002005200141027422016A2103200120026A2A0200200A95220A8B430000004F5D04402003200AA83602000C010B20034180808080783602000B410021062000410036021C2000280208220741004A044003402008280200220920064102746A28020021010240200420064D0440200121030C010B20012103200620076A220520044F0D000340200920054102746A28020022022003200220034A1B210320022001200120024A1B2101200520076A22052004490D000B0B20032001417F736AAC101621022000200028021C2201200241016A200120024A1B36021C200641016A220620002802082207480D000B0B0B8204010C7F200028022C2104200128020021082000280208220341004A0440200028022021050340200420024102746A2005200828020020036C20026A4102746A280200360200200241016A220220002802082203480D000B0B41012107200128020420086B410475220941014B04400340200820074104746A220641046A210A02400240200628020422052006280208220B460D0020002D0010410171450D00200028022C2104200341004C0D01200641086A210C2006410C6A210D200028022021014100210203402004200320076C20026A4102746A2001200D28020020036C20026A4102746A2802002001200628020020036C20026A4102746A2802002001200320056C20026A4102746A28020020012003200B6C20026A4102746A2802006A6B6A360200200241016A2202200028020822034E0D02200C280200210B200A28020021050C000B000B200028022C2104200341004C0D00200028022021014100210203402004200320076C20026A4102746A2001200628020020036C20026A4102746A2802002001200320056C20026A4102746A2802006B360200200241016A2202200028020822034E0D01200A28020021050C000B000B200741016A22072009470D000B0B200320096C2203200028023020046B41027522024B04402000412C6A200320026B10220F0B200220034B04402000200420034102746A3602300B0BFA03010B7F2002200228020820022802046B36021020002802082105200028022C210C024020002D0010410271044020022001200C2005102F0C010B230041206B220D2400200D41086A20012206101B210A024020050440200541D6AAD5AA014904402005410C6C2203105F41002003410C6B410C6E410C6C410C6A22031059220820036A21010340024020062008200B410C6C6A2209280204200928020022046B22034B04402009200620036B10180C010B200320064D0D002009200420066A3602040B410021042006044003400240200C200420056C200B6A4102746A2802002203450440200928020020046A41003A00000C010B20032003411F7522076A200773AD10162107200928020020046A200741016A22073A0000200A4100200341012007744101756A6B200320034100481B2007101E0B200441016A22042006470D000B0B200B41016A220B2005470D000B2002200A1030410021030340200220082003410C6C6A2204280204200428020022046B20041017200341016A22032005470D000B2001200847044003402001410C6B220328020022040440200141086B20043602002004105E0B2003210120032008470D000B0B2008105E0C020B1057000B2002200A10300B200A101D200D41206A24000B200228021021012002200228020820022802046B22053602102000200520016B3602180B8A0301077F200028020821012000280204210720002D0010410271044020022007200110321A0F0B230041306B220324002003420037032820034200370320200342003703182002280208220428000021052002200441046A2204360208200420022802046B410371220604402002200420066B41046A22043602080B200341186A20052004101C2002200228020820054102746A36020820034100360210200342003703080240200141004C0D0003402002200341086A101A02402007450D0041002104200328020C220620032802082205460D0003400240200420056A22092D000022004504402007200120046C20086A4102746A41003602000C010B2007200120046C20086A4102746A4100200341186A2000101F2205410120092D000041016B7422066A6B200520052006481B36020020032802082105200328020C21060B200441016A2204200620056B490D000B0B200841016A22082001470D000B200328020C1A20032802082204450D002003200436020C2004105E0B200341186A101D200341306A24000BAA0301087F024020002802042204450D002002280204200228020022086B2202410C6D210620002D0010410171044020064102490D012000280208210341012101034041002102200341004A044020082001410C6C6A220741086A2109200741046A210A03402004200120036C20026A4102746A220520052802002004200A28020020036C20026A4102746A2802002004200728020020036C20026A4102746A2802006A2004200928020020036C20026A4102746A2802006B6A360200200241016A220220002802082203480D000B0B200141016A22012006470D000B0C010B2002044020064102490D012000280208210341012101034041002102200341004A044020082001410C6C6A210703402004200120036C20026A4102746A220520052802002004200728020020036C20026A4102746A2802006A360200200241016A220220002802082203480D000B0B200141016A22012006470D000B0C010B20002802082203200120036C4F0D00200321020340200420024102746A220520052802002004200220036B4102746A2802006A360200200241016A22022000280208220320016C490D000B0B0BC51202057F027D024020002802042203450D00200028020820016C21020240024002400240024002400240024020002802140E080703060200040105080B2002450D072003027F20002A020C20032C0000B29422088B430000004F5D04402008A80C010B4180808080780B3A00004101210320024101460D07200241016B22014101712104200241024704402001417E7121010340027F20002A020C200028020420036A22022C0000B29422088B430000004F5D04402008A80C010B4180808080780B2105200220053A0000027F20002A020C200320002802046A41016A22022C0000B29422088B430000004F5D04402008A80C010B4180808080780B2105200220053A0000200341026A2103200141026B22010D000B0B2004450D07027F20002A020C200028020420036A22002C0000B29422088B430000004F5D04402008A80C010B4180808080780B2103200020033A00000C070B2002450D062002410171210641002101200241014704402002417E71210203402003200141027422056A220420002A020C2004280200B294380200200320054104726A220520002A020C2005280200B294380200200141026A2101200241026B22020D000B0B2006450D06200320014102746A220320002A020C2003280200B2943802000F0B2002450D0520002A020C21082002410371210541002100200241016B41034F04402002417C7121020340027F20082003200041017422016A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014102726A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014104726A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014106726A22012F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2104200120043B0100200041046A2100200241046B22020D000B0B2005450D050340027F2008200320004101746A22012F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2102200120023B0100200041016A2100200541016B22050D000B0C050B2002450D0420002A020C21082002410371210541002100200241016B41034F04402002417C7121020340027F20082003200041027422016A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F2008200320014104726A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F2008200320014108726A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F200820032001410C726A2201280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210420012004360200200041046A2100200241046B22020D000B0B2005450D040340027F2008200320004102746A2201280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210220012002360200200041016A2100200541016B22050D000B0C040B2002450D032003027F20002A020C20032C0000B29422088B430000004F5D04402008A80C010B4180808080780B3A00004101210320024101460D03200241016B22014101712104200241024704402001417E7121010340027F20002A020C200028020420036A22022C0000B29422088B430000004F5D04402008A80C010B4180808080780B2105200220053A0000027F20002A020C200320002802046A41016A22022C0000B29422088B430000004F5D04402008A80C010B4180808080780B2105200220053A0000200341026A2103200141026B22010D000B0B2004450D0320002A020C200028020420036A22032C0000B29422088B430000004F5D044020032008A83A00000F0B200341003A00000F0B2002450D0220002A020C21082002410171210541002100200241014704402002417E7121010340200320004103746A2008200320004102746A280200B294BB3903002003200041017222024103746A2008200320024102746A280200B294BB390300200041026A2100200141026B22010D000B0B2005450D02200320004103746A2008200320004102746A280200B294BB3903000F0B2002450D0120002A020C21082002410371210541002100200241016B41034F04402002417C7121020340027F20082003200041017422016A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014102726A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014104726A22042F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2106200420063B0100027F2008200320014106726A22012F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2104200120043B0100200041046A2100200241046B22020D000B0B2005450D010340027F2008200320004101746A22012F0100B3942207430000804F5D20074300000000607104402007A90C010B41000B2102200120023B0100200041016A2100200541016B22050D000B0C010B2002450D0020002A020C21082002410371210541002100200241016B41034F04402002417C7121020340027F20082003200041027422016A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F2008200320014104726A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F2008200320014108726A2204280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210620042006360200027F200820032001410C726A2201280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210420012004360200200041046A2100200241046B22020D000B0B2005450D000340027F2008200320004102746A2201280200B3942207430000804F5D20074300000000607104402007A90C010B41000B210220012002360200200041016A2100200541016B22050D000B0B0BE40301037F200020026A210302400240024020002001734103714504402000410371450D01200241004C0D01200021020340200220012D00003A0000200141016A2101200241016A2202410371450D0320022003490D000B0C020B024020034104490D00200341046B22042000490D00200021020340200220012D00003A0000200220012D00013A0001200220012D00023A0002200220012D00033A0003200141046A2101200241046A220220044D0D000B0C030B200021020C020B200021020B02402003417C71220441C000490D002002200441406A22054B0D0003402002200128020036020020022001280204360204200220012802083602082002200128020C36020C2002200128021036021020022001280214360214200220012802183602182002200128021C36021C2002200128022036022020022001280224360224200220012802283602282002200128022C36022C2002200128023036023020022001280234360234200220012802383602382002200128023C36023C200141406B2101200241406B220220054D0D000B0B200220044F0D00034020022001280200360200200141046A2101200241046A22022004490D000B0B200220034904400340200220012D00003A0000200141016A2101200241016A22022003470D000B0B20000B070041011001000B050041D80E0BF20202027F017E02402002450D00200020013A0000200020026A220341016B20013A000020024103490D00200020013A0002200020013A0001200341036B20013A0000200341026B20013A000020024107490D00200020013A0003200341046B20013A000020024109490D002000410020006B41037122046A2203200141FF017141818284086C22013602002003200220046B417C7122046A220241046B200136020020044109490D002003200136020820032001360204200241086B20013602002002410C6B200136020020044119490D002003200136021820032001360214200320013602102003200136020C200241106B2001360200200241146B2001360200200241186B20013602002002411C6B20013602002004200341047141187222046B22024120490D002001AD4281808080107E2105200320046A2101034020012005370318200120053703102001200537030820012005370300200141206A2101200241206B2202411F4B0D000B0B20000B810101027F02400240200241044F044020002001724103710D01034020002802002001280200470D02200141046A2101200041046A2100200241046B220241034B0D000B0B2002450D010B034020002D0000220320012D00002204460440200141016A2101200041016A2100200241016B22020D010C020B0B200320046B0F0B41000B7F01037F20002101024020004103710440034020012D0000450D02200141016A22014103710D000B0B03402001220241046A210120022802002203417F73200341818284086B7141808182847871450D000B200341FF0171450440200220006B0F0B034020022D00012103200241016A2201210220030D000B0B200120006B0B6C01027F41D40E2802002201200041036A417C7122026A2100024020024100200020014D1B0D0020003F004110744B044020003F004110746B41FFFF036A4110764000417F46047F4100054100100041010B450D010B41D40E200036020020010F0B41D80E4130360200417F0BA72D010B7F230041106B220B240002400240024002400240024002400240024002400240200041F4014D044041DC0E280200220641102000410B6A4178712000410B491B2205410376220176220041037104402000417F7341017120016A22034103742202418C0F6A280200220141086A2100024020012802082205200241840F6A220246044041DC0E2006417E200377713602000C010B2005200236020C200220053602080B200120034103742203410372360204200120036A41046A220120012802004101723602000C0C0B200541E40E28020022084D0D01200004400240200020017441022001742200410020006B72712200410020006B7141016B22002000410C764110712200762201410576410871220320007220012003762200410276410471220172200020017622004101764102712201722000200176220041017641017122017220002001766A22034103742202418C0F6A28020022012802082200200241840F6A220246044041DC0E2006417E2003777122063602000C010B2000200236020C200220003602080B200141086A210020012005410372360204200120056A22022003410374220420056B2203410172360204200120046A2003360200200804402008410376220441037441840F6A210541F00E2802002101027F2006410120047422047145044041DC0E200420067236020020050C010B20052802080B2104200520013602082004200136020C2001200536020C200120043602080B41F00E200236020041E40E20033602000C0C0B41E00E2802002209450D012009410020096B7141016B22002000410C764110712200762201410576410871220320007220012003762200410276410471220172200020017622004101764102712201722000200176220041017641017122017220002001766A410274418C116A280200220228020441787120056B210120022103034002402003280210220045044020032802142200450D010B200028020441787120056B22032001200120034B22031B21012000200220031B2102200021030C010B0B2002280218210A2002200228020C22044704402002280208220041EC0E280200491A2000200436020C200420003602080C0B0B200241146A2203280200220045044020022802102200450D03200241106A21030B0340200321072000220441146A220328020022000D00200441106A2103200428021022000D000B200741003602000C0A0B417F2105200041BF7F4B0D002000410B6A2200417871210541E00E2802002208450D00027F41002005418002490D001A411F200541FFFFFF074B0D001A2000410876220020004180FE3F6A411076410871220074220120014180E01F6A411076410471220174220320034180800F6A411076410271220374410F7620002001722003726B22004101742005200041156A7641017172411C6A0B2107410020056B21010240024002402007410274418C116A2802002203450440410021000C010B4100210020054100411920074101766B2007411F461B74210203400240200328020441787120056B220620014F0D0020032104200622010D0041002101200321000C030B200020032802142206200620032002411D764104716A2802102203461B200020061B21002002410174210220030D000B0B20002004724504404100210441022007742200410020006B722008712200450D032000410020006B7141016B22002000410C764110712200762203410576410871220220007220032002762200410276410471220372200020037622004101764102712203722000200376220041017641017122037220002003766A410274418C116A28020021000B2000450D010B0340200028020441787120056B220620014921022006200120021B21012000200420021B210420002802102203047F20030520002802140B22000D000B0B2004450D00200141E40E28020020056B4F0D00200428021821072004200428020C22024704402004280208220041EC0E280200491A2000200236020C200220003602080C090B200441146A2203280200220045044020042802102200450D03200441106A21030B0340200321062000220241146A220328020022000D00200241106A2103200228021022000D000B200641003602000C080B200541E40E28020022004D044041F00E28020021010240200020056B220341104F044041E40E200336020041F00E200120056A220236020020022003410172360204200020016A2003360200200120054103723602040C010B41F00E410036020041E40E410036020020012000410372360204200020016A41046A220020002802004101723602000B200141086A21000C0A0B200541E80E280200220249044041E80E200220056B220136020041F40E41F40E280200220020056A22033602002003200141017236020420002005410372360204200041086A21000C0A0B410021002005412F6A2208027F41B412280200044041BC122802000C010B41C012427F37020041B8124280A0808080800437020041B412200B410C6A41707141D8AAD5AA057336020041C812410036020041981241003602004180200B22016A2206410020016B220771220420054D0D0941941228020022010440418C12280200220320046A220920034D0D0A20012009490D0A0B4198122D00004104710D040240024041F40E28020022010440419C12210003402001200028020022034F0440200320002802046A20014B0D030B200028020822000D000B0B4100105C2202417F460D052004210641B812280200220041016B22012002710440200420026B200120026A410020006B716A21060B200520064F0D05200641FEFFFFFF074B0D0541941228020022000440418C12280200220120066A220320014D0D0620002003490D060B2006105C22002002470D010C070B200620026B200771220641FEFFFFFF074B0D042006105C2202200028020020002802046A460D03200221000B02402000417F460D00200541306A20064D0D0041BC122802002201200820066B6A410020016B71220141FEFFFFFF074B0440200021020C070B2001105C417F470440200120066A2106200021020C070B410020066B105C1A0C040B200021022000417F470D050C030B410021040C070B410021020C050B2002417F470D020B4198124198122802004104723602000B200441FEFFFFFF074B0D012004105C21024100105C21002002417F460D012000417F460D01200020024D0D01200020026B2206200541286A4D0D010B418C12418C1228020020066A2200360200419012280200200049044041901220003602000B02400240024041F40E28020022010440419C1221000340200220002802002203200028020422046A460D02200028020822000D000B0C020B41EC0E28020022004100200020024D1B45044041EC0E20023602000B4100210041A0122006360200419C12200236020041FC0E417F36020041800F41B41228020036020041A8124100360200034020004103742201418C0F6A200141840F6A2203360200200141900F6A2003360200200041016A22004120470D000B41F40E2002417820026B4107714100200241086A4107711B22006A220136020041E80E200620006B41286B220036020020012000410172360204200220066A41246B412836020041F80E41C4122802003602000C020B20002D000C4108710D0020012003490D00200120024F0D002000200420066A36020441F40E2001417820016B4107714100200141086A4107711B22006A220336020041E80E41E80E28020020066A220220006B220036020020032000410172360204200120026A412836020441F80E41C4122802003602000C010B41EC0E28020020024B044041EC0E20023602000B200220066A2104419C122100024002400240024002400240034020042000280200470440200028020822000D010C020B0B20002D000C410871450D010B419C12210003402001200028020022034F0440200320002802046A220320014B0D030B200028020821000C000B000B200020023602002000200028020420066A3602042002417820026B4107714100200241086A4107711B6A220620054103723602042004417820046B4107714100200441086A4107711B6A2204200520066A22056B21032001200446044041F40E200536020041E80E41E80E28020020036A2200360200200520004101723602040C030B200441F00E28020046044041F00E200536020041E40E41E40E28020020036A220036020020052000410172360204200020056A20003602000C030B200428020422004103714101460440200041787121080240200041FF014D0440200428020822012000410376220741037441840F6A461A2001200428020C220046044041DC0E41DC0E280200417E200777713602000C020B2001200036020C200020013602080C010B2004280218210902402004200428020C220247044020042802082200200236020C200220003602080C010B0240200441146A220028020022010D00200441106A220028020022010D00410021020C010B0340200021072001220241146A220028020022010D00200241106A2100200228021022010D000B200741003602000B2009450D0002402004200428021C2201410274418C116A22002802004604402000200236020020020D0141E00E41E00E280200417E200177713602000C020B20094110411420092802102004461B6A20023602002002450D010B2002200936021820042802102200044020022000360210200020023602180B20042802142200450D0020022000360214200020023602180B200420086A2104200320086A21030B20042004280204417E7136020420052003410172360204200320056A2003360200200341FF014D04402003410376220141037441840F6A2100027F41DC0E2802002203410120017422017145044041DC0E200120037236020020000C010B20002802080B2101200020053602082001200536020C2005200036020C200520013602080C030B411F2100200341FFFFFF074D04402003410876220020004180FE3F6A411076410871220074220120014180E01F6A411076410471220174220220024180800F6A411076410271220274410F7620002001722002726B22004101742003200041156A7641017172411C6A21000B2005200036021C200542003702102000410274418C116A2101024041E00E2802002202410120007422047145044041E00E200220047236020020012005360200200520013602180C010B20034100411920004101766B2000411F461B742100200128020021020340200222012802044178712003460D032000411D76210220004101742100200120024104716A41106A220428020022020D000B20042005360200200520013602180B2005200536020C200520053602080C020B41F40E2002417820026B4107714100200241086A4107711B22006A220736020041E80E200620006B41286B220036020020072000410172360204200441246B412836020041F80E41C41228020036020020012003412720036B4107714100200341276B4107711B6A412F6B22002000200141106A491B2204411B360204200441A4122902003702102004419C1229020037020841A412200441086A36020041A0122006360200419C12200236020041A8124100360200200441186A2100034020004107360204200041086A2102200041046A210020022003490D000B20012004460D0320042004280204417E713602042001200420016B220641017236020420042006360200200641FF014D04402006410376220341037441840F6A2100027F41DC0E2802002202410120037422037145044041DC0E200220037236020020000C010B20002802080B2103200020013602082003200136020C2001200036020C200120033602080C040B411F210020014200370210200641FFFFFF074D04402006410876220020004180FE3F6A411076410871220074220320034180E01F6A411076410471220374220220024180800F6A411076410271220274410F7620002003722002726B22004101742006200041156A7641017172411C6A21000B2001200036021C2000410274418C116A2103024041E00E2802002202410120007422047145044041E00E200220047236020020032001360200200120033602180C010B20064100411920004101766B2000411F461B742100200328020021020340200222032802044178712006460D042000411D76210220004101742100200320024104716A41106A220428020022020D000B20042001360200200120033602180B2001200136020C200120013602080C030B20012802082200200536020C20012005360208200541003602182005200136020C200520003602080B200641086A21000C050B20032802082200200136020C20032001360208200141003602182001200336020C200120003602080B41E80E280200220020054D0D0041E80E200020056B220136020041F40E41F40E280200220020056A22033602002003200141017236020420002005410372360204200041086A21000C030B41D80E4130360200410021000C020B02402007450D000240200428021C2203410274418C116A220028020020044604402000200236020020020D0141E00E2008417E2003777122083602000C020B20074110411420072802102004461B6A20023602002002450D010B2002200736021820042802102200044020022000360210200020023602180B20042802142200450D0020022000360214200020023602180B02402001410F4D04402004200120056A2200410372360204200020046A41046A220020002802004101723602000C010B20042005410372360204200420056A22022001410172360204200120026A2001360200200141FF014D04402001410376220141037441840F6A2100027F41DC0E2802002203410120017422017145044041DC0E200120037236020020000C010B20002802080B2101200020023602082001200236020C2002200036020C200220013602080C010B411F2100200141FFFFFF074D04402001410876220020004180FE3F6A411076410871220074220320034180E01F6A411076410471220374220520054180800F6A411076410271220574410F7620002003722005726B22004101742001200041156A7641017172411C6A21000B2002200036021C200242003702102000410274418C116A2103024002402008410120007422057145044041E00E200520087236020020032002360200200220033602180C010B20014100411920004101766B2000411F461B742100200328020021050340200522032802044178712001460D022000411D76210520004101742100200320054104716A41106A220628020022050D000B20062002360200200220033602180B2002200236020C200220023602080C010B20032802082200200236020C20032002360208200241003602182002200336020C200220003602080B200441086A21000C010B0240200A450D000240200228021C2203410274418C116A220028020020024604402000200436020020040D0141E00E2009417E200377713602000C020B200A41104114200A2802102002461B6A20043602002004450D010B2004200A36021820022802102200044020042000360210200020043602180B20022802142200450D0020042000360214200020043602180B02402001410F4D04402002200120056A2200410372360204200020026A41046A220020002802004101723602000C010B20022005410372360204200220056A22032001410172360204200120036A2001360200200804402008410376220441037441840F6A210541F00E2802002100027F4101200474220420067145044041DC0E200420067236020020050C010B20052802080B2104200520003602082004200036020C2000200536020C200020043602080B41F00E200336020041E40E20013602000B200241086A21000B200B41106A240020000BA70C01077F02402000450D00200041086B2202200041046B280200220141787122006A2105024020014101710D002001410371450D012002200228020022016B220241EC0E280200490D01200020016A2100200241F00E280200470440200141FF014D0440200228020822042001410376220741037441840F6A461A2004200228020C220146044041DC0E41DC0E280200417E200777713602000C030B2004200136020C200120043602080C020B2002280218210602402002200228020C220347044020022802082201200336020C200320013602080C010B0240200241146A220128020022040D00200241106A220128020022040D00410021030C010B0340200121072004220341146A220128020022040D00200341106A2101200328021022040D000B200741003602000B2006450D0102402002200228021C2204410274418C116A22012802004604402001200336020020030D0141E00E41E00E280200417E200477713602000C030B20064110411420062802102002461B6A20033602002003450D020B2003200636021820022802102201044020032001360210200120033602180B20022802142201450D0120032001360214200120033602180C010B200528020422014103714103470D0041E40E200036020020052001417E7136020420022000410172360204200020026A20003602000F0B200220054F0D0020052802042201410171450D0002402001410271450440200541F40E28020046044041F40E200236020041E80E41E80E28020020006A220036020020022000410172360204200241F00E280200470D0341E40E410036020041F00E41003602000F0B200541F00E28020046044041F00E200236020041E40E41E40E28020020006A220036020020022000410172360204200020026A20003602000F0B200141787120006A21000240200141FF014D0440200528020822042001410376220741037441840F6A461A2004200528020C220146044041DC0E41DC0E280200417E200777713602000C020B2004200136020C200120043602080C010B2005280218210602402005200528020C22034704402005280208220141EC0E280200491A2001200336020C200320013602080C010B0240200541146A220128020022040D00200541106A220128020022040D00410021030C010B0340200121072004220341146A220128020022040D00200341106A2101200328021022040D000B200741003602000B2006450D0002402005200528021C2204410274418C116A22012802004604402001200336020020030D0141E00E41E00E280200417E200477713602000C020B20064110411420062802102005461B6A20033602002003450D010B2003200636021820052802102201044020032001360210200120033602180B20052802142201450D0020032001360214200120033602180B20022000410172360204200020026A2000360200200241F00E280200470D0141E40E20003602000F0B20052001417E7136020420022000410172360204200020026A20003602000B200041FF014D04402000410376220141037441840F6A2100027F41DC0E2802002204410120017422017145044041DC0E200120047236020020000C010B20002802080B2101200020023602082001200236020C2002200036020C200220013602080F0B411F210120024200370210200041FFFFFF074D04402000410876220120014180FE3F6A411076410871220174220420044180E01F6A411076410471220474220320034180800F6A411076410271220374410F7620012004722003726B22014101742000200141156A7641017172411C6A21010B2002200136021C2001410274418C116A210402400240024041E00E2802002203410120017422057145044041E00E200320057236020020042002360200200220043602180C010B20004100411920014101766B2001411F461B742101200428020021030340200322042802044178712000460D022001411D76210320014101742101200420034104716A41106A220528020022030D000B20052002360200200220043602180B2002200236020C200220023602080C010B20042802082200200236020C20042002360208200241003602182002200436020C200220003602080B41FC0E41FC0E28020041016B2202417F20021B3602000B0B3201017F2000410120001B2101024003402001105D22000D0141CC122802002200044020001109000C010B0B1057000B20000B05001057000B110020001063044020002802000F0B20000B0C00200020012D00003A00000B0A0020002D000B4107760B0900200020013602040B0900200020013A000B0B24002000410B4F047F200041106A4170712200200041016B22002000410B461B05410A0B0B0300010B10002002044020002001200210561A0B0B0900200020013602000B100020002001418080808078723602080B5101027F024002402002410A4D0440200021032000200210650C010B2002416F4B0D0120002002106641016A2204105F2203106920002004106A2000200210640B20032001200241016A10680F0B1060000BEA05010A7F2001105B2105230041106B220A240002402005200022041063047F200428020841FFFFFFFF077141016B05410A0B22004D04402004106121002005220204400240200122032000460D002003200020026A22016B410020024101746B4D044020002003200210561A0C010B20002003734103712108024002402000200349044020080440200021010C030B2000410371450440200021010C020B2000210103402002450D04200120032D00003A0000200341016A2103200241016B2102200141016A22014103710D000B0C010B024020080D002001410371044003402002450D052000200241016B22026A2201200220036A2D00003A000020014103710D000B0B200241034D0D0003402000200241046B22026A200220036A280200360200200241034B0D000B0B2002450D0203402000200241016B22026A200220036A2D00003A000020020D000B0C020B200241034D0D00034020012003280200360200200341046A2103200141046A2101200241046B220241034B0D000B0B2002450D000340200120032D00003A0000200141016A2101200341016A2103200241016B22020D000B0B0B200A41003A000F200020056A200A410F6A106202402004106304402004200510640C010B2004200510650B0C010B20002103200520006B2106027F20041063044020042802040C010B20042D000B0B2100230041106B22072400024020062003417F7341116B4D0440200410612108027F200341E7FFFFFF07490440200720034101743602082007200320066A36020C230041106B220624002007410C6A2209280200200741086A220B280200492102200641106A2400200B200920021B28020010660C010B416E0B41016A220B105F21062005044020062001200510680B410022090440200520066A200020086A200910680B2003410A4704402008105E0B2004200610692004200B106A2004200520096A22041064200741003A0007200420066A200741076A1062200741106A24000C010B1060000B0B200A41106A24000B040020000B06002000105E0B7401017F200245044020002802042001280204460F0B2000200146044041010F0B200128020422022D000021010240200028020422032D00002200450D0020002001470D00034020022D0001210120032D00012200450D01200241016A2102200341016A210320002001460D000B0B20002001460BA20101017F230041406A22032400027F4101200020014100106F0D001A41002001450D001A4100200141FC0C41AC0D10712201450D001A200341086A4104724100413410591A200341013602382003417F36021420032000360210200320013602082001200341086A20022802004101200128020028021C110600200328022022004101460440200220032802183602000B20004101460B2100200341406B240020000BA10201037F230041406A220324002000280200220541046B2802002104200541086B280200210520034100360214200320013602102003200036020C2003200236020841002101200341186A4100412710591A200020056A21000240200420024100106F0440200341013602382004200341086A200020004101410020042802002802141108002000410020032802204101461B21010C010B2004200341086A200041014100200428020028021811040002400240200328022C0E020001020B200328021C410020032802284101461B410020032802244101461B410020032802304101461B21010C010B2003280220410147044020032802300D0120032802244101470D0120032802284101470D010B200328021821010B200341406B240020010B5D01017F200028021022034504402000410136022420002002360218200020013602100F0B02402001200346044020002802184102470D01200020023602180F0B200041013A0036200041023602182000200028022441016A3602240B0B1800200020012802084100106F044020012002200310720B0B3100200020012802084100106F044020012002200310720F0B20002802082200200120022003200028020028021C1106000B9A0100200041013A0035024020002802042002470D00200041013A003402402000280210220245044020004101360224200020033602182000200136021020002802304101470D0220034101460D010C020B2001200246044020002802182202410246044020002003360218200321020B20002802304101470D0220024101460D010C020B2000200028022441016A3602240B200041013A00360B0B2000024020002802042001470D00200028021C4101460D002000200236021C0B0BF20100200020012802082004106F044020012002200310760F0B0240200020012802002004106F044002402002200128021047044020012802142002470D010B20034101470D02200141013602200F0B200120033602200240200128022C4104460D00200141003B01342000280208220020012002200241012004200028020028021411080020012D003504402001410336022C20012D0034450D010C030B2001410436022C0B200120023602142001200128022841016A36022820012802244101470D0120012802184102470D01200141013A00360F0B20002802082200200120022003200420002802002802181104000B0B910100200020012802082004106F044020012002200310760F0B0240200020012802002004106F450D0002402002200128021047044020012802142002470D010B20034101470D01200141013602200F0B20012002360214200120033602202001200128022841016A360228024020012802244101470D0020012802184102470D00200141013A00360B2001410436022C0B0B3700200020012802082005106F0440200120022003200410750F0B200028020822002001200220032004200520002802002802141108000B1A00200020012802082005106F0440200120022003200410750B0B040023000B0600200024000B1000230020006B4170712200240020000B0BDE0603004180080B9D04757600636F6C6F7200706F736974696F6E006E6F726D616C00616C6C6F6361746F723C543E3A3A616C6C6F636174652873697A655F74206E2920276E272065786365656473206D6178696D756D20737570706F727465642073697A6500000000000000000100000003000000070000000F0000001F0000003F0000007F000000FF000000FF010000FF030000FF070000FF0F0000FF1F0000FF3F0000FF7F0000FFFF0000FFFF0100FFFF0300FFFF0700FFFF0F00FFFF1F00FFFF3F00FFFF7F00FFFFFF00FFFFFF01FFFFFF03FFFFFF07FFFFFF0FFFFFFF1FFFFFFF3FFFFFFF7F4E3363727431355665727465784174747269627574654500C0060000E00400004E33637274313147656E6572696341747472496945450000E806000000050000F8040000000000006C0500000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000004E3363727431304E6F726D616C41747472450000E806000058050000F804000000000000E00500000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000004E3363727439436F6C6F724174747245004E33637274313147656E65726963417474724968454500E8060000BD050000F8040000E8060000AC050000D405000000000000D40500000C00000017000000180000001900000010000000110000001A0000001B00000014000000150000001C0041A80C0BAA02180500001D0000001E0000001F00000020000000100000002100000022000000230000002400000015000000250000004E31305F5F637878616269763131365F5F7368696D5F747970655F696E666F4500000000E8060000580600004C0700004E31305F5F637878616269763131375F5F636C6173735F747970655F696E666F45000000E8060000880600007C06000000000000AC0600002700000028000000290000002A0000002B0000002C0000002D0000002E0000000000000030070000270000002F000000290000002A0000002B0000003000000031000000320000004E31305F5F637878616269763132305F5F73695F636C6173735F747970655F696E666F4500000000E806000008070000AC060000537439747970655F696E666F00000000C00600003C070041D40E0B025069"; +/* var wasm_simd = ""; + var detector = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,4,26,11]); + + var wasm = wasm_base; + + if (WebAssembly.validate(detector)) { + wasm = wasm_simd; + console.log("Warning: corto is using experimental SIMD support"); + }*/ + var instance, heap; + + var env = { + emscripten_notify_memory_growth: function(index) { + heap = new Uint8Array(instance.exports.memory.buffer); + }, + proc_exit: function(rval) { return 52; }, //WASI_ENOSYS + }; + + function unhex(data) { + var bytes = new Uint8Array(data.length / 2); + for (var i = 0; i < data.length; i += 2) { + bytes[i / 2] = parseInt(data.substr(i, 2), 16); + } + return bytes.buffer; + } + + + var promise = + WebAssembly.instantiate(unhex(wasm_base), { env:env, wasi_unstable:env, "wasi_snapshot_preview1": { + proc_exit() { + return 0; + } + } }) + .then(function(result) { + instance = result.instance; + //instance.exports._start(); + env.emscripten_notify_memory_growth(0); + }); + + function pad() { + return; + var s = instance.exports.sbrk(0); + var t = s & 0x3; + if(t) + instance.exports.sbrk(4 -t); + } + + function decode(source, shortIndex = false, shortNormal = false, colorComponents = 4) { + if(!source.length) + source = new Uint8Array(source); + var len = source.length; + var exports = instance.exports; + var sbrk = exports.malloc; //yes I am a criminal. + var free = exports.free; + + +//copy source to heap. we could use directly source, but that is good only for the first em call. + + + //We could use the heap instead of malloc, don't know cost (not much probably), and can't debug properly. + //set initial heap position, to be restored at the end of the deconding. + var pos = sbrk(0); + + var sptr = sbrk(len); + heap.set(source, sptr); + + var decoder = exports.newDecoder(len, sptr); + var nvert = exports.nvert(decoder); + var nface = exports.nface(decoder); + + var geometry = { + nvert: nvert, + nface: nface, + } + + var ngroups = exports.ngroups(decoder); + if(ngroups > 0) { + pad(); + var gp = sbrk(4*ngroups); + exports.groups(decoder, gp); + geometry.groups = new Uint32Array( ngroups*4); + geometry.grous.set(gp); + free(gp); + } + + var hasNormal = exports.hasNormal(decoder); + var hasColor = exports.hasColor(decoder); + var hasUv = exports.hasUv(decoder); + + var iptr = 0, pptr = 0, nptr = 0, cptr = 0, uptr = 0; + if(nface) { + pad(); //memory align needed for int, short, floats arrays if using sbrk + if(shortIndex) { + iptr = sbrk(nface * 6); + exports.setIndex16(decoder, iptr); + } else { + iptr = sbrk(nface * 12); + exports.setIndex32(decoder, iptr); + } + } + + pptr = sbrk(nvert * 12); + exports.setPositions(decoder, pptr); + + if(hasUv) { + pad(); + uptr = sbrk(nvert * 8); + exports.setUvs(decoder, uptr); + } + + if(hasNormal) { + pad(); + if(shortNormal) { + nptr = sbrk(nvert * 6); + exports.setNormals16(decoder, nptr); + } else { + pptr = sbrk(nvert * 12); + exports.setNormals32(decoder, nptr); + } + } + + if(hasColor) { + pad(); + cptr = sbrk(nvert * colorComponents); + exports.setColors(decoder, cptr, colorComponents); + } + pad(); + exports.decode(decoder); + + + //typed arrays needs to be created in javascript space, not as views of heap (next call will overwrite them!) + //hence the double typed array. + if(nface) { + if(shortIndex) + geometry.index = new Uint16Array(new Uint16Array(heap.buffer, iptr, nface*3)); + else + geometry.index = new Uint32Array(new Uint32Array(heap.buffer, iptr, nface*3)); + } + + geometry.position = new Float32Array(new Float32Array(heap.buffer, pptr, nvert*3)); + + if(hasNormal) { + if(shortNormal) + geometry.normal = new Int16Array(new Int16Array(heap.buffer, nptr, nvert*3)); + else + geometry.normal = new Float32Array(new Float32Array(heap.buffer, nptr, nvert*3)); + } + + if(hasColor) + geometry.color = new Uint8Array(new Uint8Array(heap.buffer, cptr, nvert*colorComponents)); + + if(hasUv) + geometry.uv = new Float32Array(new Float32Array(heap.buffer, uptr, nvert*2)); + + exports.deleteDecoder(decoder); + + //restore heap position if using sbrk + //sbrk(pos - sbrk(0)); + free(sptr); + if(iptr) free(iptr); + if(pptr) free(pptr); + if(cptr) free(cptr); + if(nptr) free(nptr); + if(uptr) free(uptr); + + return geometry; + }; + + return { + ready: promise, + decode: decode + }; +})(); + +if (typeof exports === 'object' && typeof module === 'object') + module.exports = CortoDecoder; +else if (typeof define === 'function' && define['amd']) + define([], function() { + return CortoDecoder; + }); +else if (typeof exports === 'object') + exports["CortoDecoder"] = CortoDecoder; diff --git a/nexus3d/src/index.js b/nexus3d/src/index.js new file mode 100644 index 00000000..73de1465 --- /dev/null +++ b/nexus3d/src/index.js @@ -0,0 +1,209 @@ +//npx webpack + +import { + Vector2, + Euler, + Color, + Fog, + AmbientLight, + DirectionalLight, + PerspectiveCamera, + Raycaster, + WebGLRenderer, + Scene, + Clock, + + + Mesh, + BoxGeometry, + MeshPhongMaterial, + BasicShadowMap + //BoxBufferGeometry, + + //MeshBasicMaterial, +} from 'three' + +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; +import { Nexus3D, Cache } from './Nexus3D.js' +import { Monitor } from './Monitor.js' + + +let container = document.getElementById( 'scene'); + +let camera = new PerspectiveCamera( 30, container.innerWidth / container.innerHeight, 0.1, 100 ); +camera.position.set(0, 0, 10); + + +let controls_options = { + rotateSpeed: 0.5, + zoomSpeed: 4, + panSpeed: 0.8, + noZoom: false, + noPan: false, + enableDamping: true, + staticMoving: true, + dynamicDampingFactor: 0.3, +} +let controls = new OrbitControls(camera, container ); +for( const [key, value] of Object.entries(controls_options)) + controls[key] = value; + +controls.addEventListener( 'change', function() { redraw = true; } ); + + + +let scene = new Scene(); +scene.background = new Color( 0xaaaaff ); +scene.fog = new Fog( 0x050505, 2000, 3500 ); +scene.add( new AmbientLight( 0x444444 ) ); + +var light1 = new DirectionalLight( 0xffffff, 1.0 ); +light1.position.set( 2, 1, -0.5 ); + +light1.castShadow = true; +light1.shadow.camera.near = 1; +light1.shadow.camera.far = 10; +light1.shadow.camera.right = 2; +light1.shadow.camera.left = - 2; +light1.shadow.camera.top = 2; +light1.shadow.camera.bottom = - 2; +light1.shadow.mapSize.width = 1024; +light1.shadow.mapSize.height = 1024; + + +scene.add( light1 ); + +var light2 = new DirectionalLight( 0xffffff, 1.0 ); +light2.position.set( -1, -1, 1 ); +//scene.add( light2 ); + +var renderer = new WebGLRenderer( { antialias: false } ); +renderer.setClearColor( scene.fog.color ); +renderer.setPixelRatio( window.devicePixelRatio ); +renderer.shadowMap.enabled = true; +renderer.shadowMap.type = BasicShadowMap; + +container.appendChild(renderer.domElement); + + +function onNexusLoad(nexus) { + const p = nexus.boundingSphere.center.clone().negate(); + const s = 1/nexus.boundingSphere.radius; + //nexus.rotateX(-3.1415/2); + + if(nexus == nexus1) { + nexus.position.set(p.x*s + 1, p.y*s, p.z*s); + } else + nexus.position.set(p.x*s - 1, p.y*s, p.z*s); + + nexus.scale.set(s, s, s); + redraw = true; +} + +var url = "models/gargo.nxz"; + +//onUpdate parameter here is used to trigger a redraw +let nexus1 = new Nexus3D(url, renderer, { onLoad: onNexusLoad, onUpdate: () => { redraw = true; }} ); +//nexus1.castShadow = true; +nexus1.receiveShadow = true; + +//create a second instance and position it. +let nexus2 = new Nexus3D(url, renderer, { onLoad: onNexusLoad, onUpdate: () => { redraw = true; }} ); +nexus2.castShadow = true; +nexus2.receiveShadow = true; + + + +//material can be changed replacing the material or modifying it. +//nexus1.material = new MeshBasicMaterial( { color: 0xffff00, wireframe: true } ); +//nexus.material.color = new Color(1, 0, 0)); +//nexus.material.wireframe = true; + +let monitor = new Monitor(Cache, nexus2); +scene.add(nexus1); +scene.add(nexus2); + +nexus1.castShadow = true; + + +let geometry = new BoxGeometry( 10, 0.15, 10 ); +let material = new MeshPhongMaterial( { + color: 0xa0adaf, + shininess: 150, + specular: 0x111111 +} ); + +const ground = new Mesh( geometry, material ); +ground.scale.multiplyScalar( 3 ); +ground.castShadow = false; +ground.receiveShadow = true; +ground.position.set(0, -1, 0); +scene.add( ground ); + + + +window.addNexus = () => { + nexus2 = new Nexus3D(url, renderer, { onLoad: onNexusLoad, onUpdate: () => { redraw = true; }} ); + scene.add(nexus2); + redraw = true; +}; +window.removeNexus = () => { + scene.remove(nexus2); + nexus2.dispose(); + nexus2 = null; + redraw = true; +}; + +var mouse = new Vector2(); + +function onMouseMove( event ) { + event.preventDefault(); + mouse.x = ( event.clientX / container.offsetWidth ) * 2 - 1; + mouse.y = - ( event.clientY / container.offsetHeight ) * 2 + 1; +} + +document.addEventListener( 'mousemove', onMouseMove, false ); + + + +new ResizeObserver(onWindowResize).observe(container); + +function onWindowResize() { + camera.aspect = container.clientWidth / container.clientHeight; + camera.updateProjectionMatrix(); + + renderer.setSize( container.clientWidth, container.clientHeight ); + + redraw = true; +} + +const clock = new Clock(); +var redraw = true; + +function animate() { + const delta = clock.getDelta() + controls.update(delta); + + if(redraw) { + //during rendering it might be apparent we need another render pass, set it to false BEFORE render + redraw = true; + + + var raycaster = new Raycaster(); + raycaster.setFromCamera( mouse, camera ); + + var intersections = raycaster.intersectObjects( [nexus1], true ); + if(intersections.length) { + nexus1.material.color = new Color(1, 0, 0); +// nexus1.material.wireframe = true; + nexus1.material.needsUpdate = true; + } else { + nexus1.material.color = new Color(1, 1, 1); + } + renderer.render( scene, camera ); + } +} + +renderer.setAnimationLoop(animate); + +onWindowResize(); diff --git a/nexus3d/webpack.config.js b/nexus3d/webpack.config.js new file mode 100644 index 00000000..272f1f23 --- /dev/null +++ b/nexus3d/webpack.config.js @@ -0,0 +1,55 @@ +var webpack = require('webpack') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const path = require('path') + +module.exports = { + + mode: 'development', + entry: { + main: './src/index.js', + }, + + output: { + path: path.resolve(__dirname + 'dist'), + filename: '[name].bundle.js', + }, + + devServer: { + static: './dist', + client: { + overlay: false + } + }, + + resolve: { + alias: { + 'three$': path.resolve(__dirname, './node_modules/three/build/three.module.js') + } + }, + + optimization: { + minimize: false, + usedExports: true, + splitChunks: { + chunks: 'all', + cacheGroups: { + vendor: { + test: /[\\/]node_modules[\\/]/, + name: 'vendors', + priority: 10 + } + } + } + }, + performance: { + hints: false + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new HtmlWebpackPlugin({ + title: 'Nexus3D', + template: path.resolve(__dirname + '/src/index.html'), + inject: 'body' + }), + ], +} diff --git a/nexus3d/webpacklib.config.js b/nexus3d/webpacklib.config.js new file mode 100644 index 00000000..2ba6fcc3 --- /dev/null +++ b/nexus3d/webpacklib.config.js @@ -0,0 +1,29 @@ +var webpack = require('webpack') + +module.exports = { + + entry: { + Nexus3D: './src/Nexus3D.js', + }, + + output: { + path: __dirname + '/build', + filename: 'nexus3D.js', + libraryTarget: 'umd', + library: 'Nexus3D', + globalObject: 'this' + }, + + externals: { + three: { + commonjs: 'three', + commonjs2: 'three', + amd: 'three', + root: 'THREE' + } + }, + + optimization: { + minimize: false + } +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f3a7d22c..fb42c5b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.10) project(nexus) set(HEADERS @@ -20,7 +20,9 @@ set(HEADERS nxsbuild/stlloader.h nxsbuild/texpyramid.h nxsbuild/tmesh.h + nxsbuild/colormap.h nxsbuild/tsploader.h + nxsbuild/tsloader.h nxsbuild/vcgloader.h nxsedit/extractor.h nxszip/bitstream.h @@ -46,7 +48,9 @@ set(SOURCES nxsbuild/stlloader.cpp nxsbuild/texpyramid.cpp nxsbuild/tmesh.cpp + nxsbuild/colormap.cpp nxsbuild/tsploader.cpp + nxsbuild/tsloader.cpp nxsedit/extractor.cpp nxszip/abitstream.cpp nxszip/atunstall.cpp @@ -58,10 +62,21 @@ add_library(nexus STATIC ${SOURCES} ${HEADERS}) target_include_directories(nexus PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}) + $ + $ +) -target_link_libraries(nexus PUBLIC vcglib corto Qt5::Widgets) +target_link_libraries(nexus PUBLIC vcglib corto Qt6::Widgets) if (WIN32) target_compile_definitions(nexus PUBLIC NOMINMAX) endif() + +foreach(DIR common nxsbuild nxsedit nxsview nxszip) + install(DIRECTORY ${DIR} + DESTINATION include + FILES_MATCHING PATTERN "*.h") +endforeach() +install(TARGETS nexus + EXPORT nexusTargets + LIBRARY DESTINATION lib) diff --git a/src/common/controller.cpp b/src/common/controller.cpp index 99ea0e2e..046e9171 100644 --- a/src/common/controller.cpp +++ b/src/common/controller.cpp @@ -29,7 +29,7 @@ Controller::Controller(): max_tokens(300), max_ram(512*1000*1000), max_gpu(256*1 //setMaxTokens(max_tokens); } -void Controller::setWidget(QGLWidget *widget) { +void Controller::setWidget(QOpenGLWidget *widget) { //TODO check destruction of widget #ifdef SHARED_CONTEXT gpu_cache.shared = widget; //new QGLWidget(NULL, widget); diff --git a/src/common/controller.h b/src/common/controller.h index 5da11eb1..3bdb2309 100644 --- a/src/common/controller.h +++ b/src/common/controller.h @@ -25,7 +25,7 @@ for more details. #include "gpu_cache.h" -class QGLWidget; +class QOpenGLWidget; namespace nx { @@ -50,7 +50,7 @@ class Controller: public vcg::Controller { ~Controller() { finish(); } - void setWidget(QGLWidget *widget); + void setWidget(QOpenGLWidget *widget); void setGpu(uint64_t size) { max_gpu = size; gpu_cache.setCapacity(size); } uint64_t maxGpu() const { return max_gpu; } diff --git a/src/common/nexus.cpp b/src/common/nexus.cpp index 626d3a22..6e1eb1ca 100644 --- a/src/common/nexus.cpp +++ b/src/common/nexus.cpp @@ -22,7 +22,7 @@ for more details. #include "globalgl.h" #include "qtnexusfile.h" -#include +#include using namespace nx; @@ -117,14 +117,22 @@ void Nexus::loadIndex(char *buffer) { void nx::Nexus::loadImageFromData(nx::TextureData& data, int t) { Texture& texture = textures[t]; - data.memory = (char*)file->map(texture.getBeginOffset(), texture.getSize()); + if(header.signature.isDeepzoom()) { + data.memory = file->loadDZTex(t); + } else { + data.memory = (char*)file->map(texture.getBeginOffset(), texture.getSize()); + } if (!data.memory) { std::cerr << "Failed mapping texture data" << std::endl; exit(0); } QImage img; bool success = img.loadFromData((uchar*)data.memory, texture.getSize()); - file->unmap((uchar*)data.memory); + if(header.signature.isDeepzoom()) { + file->dropDZTex(data.memory); + } else { + file->unmap((uchar*)data.memory); + } if (!success) { std::cerr << "Failed loading texture" << std::endl; @@ -148,7 +156,6 @@ void nx::Nexus::loadImageFromData(nx::TextureData& data, int t) } void Nexus::loadIndex() { NexusData::loadIndex(); - loaded = true; } diff --git a/src/common/nexusdata.cpp b/src/common/nexusdata.cpp index ea481f78..2f3a4c10 100644 --- a/src/common/nexusdata.cpp +++ b/src/common/nexusdata.cpp @@ -149,6 +149,7 @@ uint32_t NexusData::size(uint32_t node) { return nodes[node].getSize(); } + uint64_t NexusData::loadRam(uint32_t n) { Signature &sign = header.signature; @@ -160,21 +161,28 @@ uint64_t NexusData::loadRam(uint32_t n) { uint64_t size = node.nvert*sign.vertex.size() + node.nface*sign.face.size(); - if(!sign.isCompressed()) { - d.memory = (char *)file->map(offset, size); + + if(!sign.isCompressed()) { + if(sign.isDeepzoom()) + d.memory = file->loadDZNode(n); + else + d.memory = (char *)file->map(offset, size); } else { - char *buffer = new char[compressed_size]; - file->seek(offset); - int64_t r = file->read(buffer, compressed_size); - assert(r == (int64_t)compressed_size); + char *buffer = nullptr; + if(sign.isDeepzoom()) { + buffer = file->loadDZNode(n); + } else { + buffer = new char[compressed_size]; + file->seek(offset); + int64_t r = file->read(buffer, compressed_size); + assert(r == (int64_t)compressed_size); + } d.memory = new char[size]; - int iterations = 1; - if(sign.flags & Signature::MECO) { meco::MeshDecoder coder(node, d, patches, sign); coder.decode(compressed_size, (unsigned char *)buffer); @@ -195,6 +203,10 @@ uint64_t NexusData::loadRam(uint32_t n) { decoder.decode(); } + if(sign.isDeepzoom()) + file->dropDZNode(buffer); + else + delete []buffer; //Shuffle points in compressed point clouds if(!sign.face.hasIndex()) { @@ -228,6 +240,7 @@ uint64_t NexusData::loadRam(uint32_t n) { } assert(d.memory); + // If DEEPZOOM mode, textures are stored externally (in _files/) — skip texture loading here. if(header.n_textures) { //be sure to load images for(uint32_t p = node.first_patch; p < node.last_patch(); p++) { @@ -240,13 +253,17 @@ uint64_t NexusData::loadRam(uint32_t n) { continue; Texture &texture = textures[t]; - data.memory = (char *)file->map(texture.getBeginOffset(), texture.getSize()); + if(sign.isDeepzoom()) { + data.memory = file->loadDZTex(n); + } else { + data.memory = (char *)file->map(texture.getBeginOffset(), texture.getSize()); + } if(!data.memory) { cerr << "Failed mapping texture data" << endl; exit(0); } - loadImageFromData(data, t); + //loadImageFromData(data, t); /* QImage img; @@ -288,16 +305,21 @@ uint64_t NexusData::dropRam(uint32_t n, bool write) { assert(!data.vbo); assert(data.memory); - if(!header.signature.isCompressed()) //not compressed. - file->unmap((unsigned char *)data.memory); - else + auto &sign = header.signature; + if(!sign.isCompressed()) { + if(sign.isDeepzoom()) + file->dropDZNode(data.memory); + else + file->unmap((unsigned char *)data.memory); + } else { delete []data.memory; + } data.memory = NULL; //report RAM size for compressed meshes. - uint32_t size = node.nvert * header.signature.vertex.size() + - node.nface * header.signature.face.size(); + uint32_t size = node.nvert * sign.vertex.size() + + node.nface * sign.face.size(); if(header.n_textures) { for(uint32_t p = node.first_patch; p < node.last_patch(); p++) { @@ -307,9 +329,11 @@ uint64_t NexusData::dropRam(uint32_t n, bool write) { TextureData &tdata = texturedata[t]; tdata.count_ram--; if(tdata.count_ram != 0) continue; + if(sign.isDeepzoom()) + file->dropDZTex(tdata.memory); + else + file->unmap((unsigned char *)tdata.memory); - file->unmap((unsigned char *)tdata.memory); - //delete []tdata.memory; tdata.memory = NULL; size += tdata.width*tdata.height*4; } diff --git a/src/common/nexusfile.h b/src/common/nexusfile.h index d7dca9b6..b9200a82 100644 --- a/src/common/nexusfile.h +++ b/src/common/nexusfile.h @@ -2,6 +2,7 @@ #define NX_NEXUSFILE_H #include +#include namespace nx { class NexusFile { public: @@ -13,6 +14,7 @@ namespace nx { }; virtual ~NexusFile() {} virtual void setFileName(const char* uri) = 0; + virtual const char *fileName() = 0; virtual bool open(OpenMode mode) = 0; virtual long long int read(char* where, size_t length) = 0; virtual long long int write(char* from, size_t length) = 0; @@ -20,6 +22,11 @@ namespace nx { virtual void* map(size_t from, size_t size) = 0; virtual bool unmap(void* mapped) = 0; virtual bool seek(size_t to) = 0; + + virtual char *loadDZNode(uint32_t n) = 0; + virtual void dropDZNode(char *data) = 0; + virtual char *loadDZTex(uint32_t n) = 0; + virtual void dropDZTex(char *data) = 0; }; } diff --git a/src/common/qcontroller.h b/src/common/qcontroller.h index d974895a..3160399a 100644 --- a/src/common/qcontroller.h +++ b/src/common/qcontroller.h @@ -5,11 +5,11 @@ #include #include "controller.h" -class QGLWidget; +class QOpenGLWidget; class QController: public QObject, public Controller { Q_OBJECT public: - void start(QGLWidget *shared = NULL); + void start(QOpenGLWidget *shared = NULL); signals: ///emitted at most every (1/fps)s if the cache is changed diff --git a/src/common/qtnexusfile.cpp b/src/common/qtnexusfile.cpp index 8b9ff977..7cb8bfe8 100644 --- a/src/common/qtnexusfile.cpp +++ b/src/common/qtnexusfile.cpp @@ -1,10 +1,15 @@ #include "qtnexusfile.h" +#include namespace nx { void nx::QTNexusFile::setFileName(const char* uri) { file.setFileName(uri); } + const char *nx::QTNexusFile::fileName() { + QByteArray ba = file.fileName().toUtf8(); + return ba.constData(); + } bool nx::QTNexusFile::open(OpenMode openmode) { @@ -46,4 +51,43 @@ namespace nx { { return file.seek(to); } -} \ No newline at end of file + + char *nx::QTNexusFile::loadDZNode(uint32_t n) { + QString fname = file.fileName(); + // expect a companion folder named "_files" like the saver produces + if(fname.size() < 5) + return nullptr; + QString basename = fname.left(fname.size()-4) + "_files"; + QString nodefile = QString("%1/%2.nxn").arg(basename).arg(n); + return readDZFile(nodefile); + } + + void nx::QTNexusFile::dropDZNode(char *data) { + delete [] data; + } + + char *nx::QTNexusFile::loadDZTex(uint32_t n) { + QString fname = file.fileName(); + if(fname.size() < 5) + return nullptr; + QString basename = fname.left(fname.size()-4) + "_files"; + QString texfile = QString("%1/%2.jpg").arg(basename).arg(n); + return readDZFile(texfile); + } + + void nx::QTNexusFile::dropDZTex(char *data) { + delete [] data; + } + + char *nx::QTNexusFile::readDZFile(const QString &path) { + QFile f(path); + if(!f.open(QIODevice::ReadOnly)) + return nullptr; + QByteArray ba = f.readAll(); + char *buf = new char[ba.size()]; + if(ba.size()) + memcpy(buf, ba.constData(), ba.size()); + return buf; + } + +} diff --git a/src/common/qtnexusfile.h b/src/common/qtnexusfile.h index b1e51b27..320f575b 100644 --- a/src/common/qtnexusfile.h +++ b/src/common/qtnexusfile.h @@ -3,14 +3,17 @@ #include "nexusfile.h" #include +#include namespace nx { class QTNexusFile : public NexusFile { private: QFile file; + char *readDZFile(const QString &path); public: void setFileName(const char* uri) override; + const char *fileName() override; bool open(OpenMode openmode) override; long long int read(char* where, size_t length) override; long long int write(char* from, size_t length) override; @@ -18,7 +21,13 @@ namespace nx { void* map(size_t from, size_t size) override; bool unmap(void* mapped) override; bool seek(size_t to) override; + + char *loadDZNode(uint32_t n) override; + void dropDZNode(char *data) override; + char *loadDZTex(uint32_t n) override; + void dropDZTex(char *data) override; + }; } -#endif // NX_QTNEXUSFILE_H \ No newline at end of file +#endif // NX_QTNEXUSFILE_H diff --git a/src/common/renderer.cpp b/src/common/renderer.cpp index 840cf321..4625dc67 100644 --- a/src/common/renderer.cpp +++ b/src/common/renderer.cpp @@ -28,11 +28,11 @@ for more details. #ifdef WIN32 //microsoft compiler does not provide it. -double log2( double n ) +/*double log2( double n ) { // log(n)/log(2) is log2. return log( n )* 3.32192809; -} +}*/ #endif extern int current_texture; diff --git a/src/common/signature.h b/src/common/signature.h index 2996ba4d..bedf2620 100644 --- a/src/common/signature.h +++ b/src/common/signature.h @@ -97,6 +97,7 @@ class Signature { bool hasPTextures() { return (bool)(flags | PTEXTURE); } bool isCompressed() { return (bool)(flags & (MECO|CORTO)); } + bool isDeepzoom() { return (bool)(flags & (DEEPZOOM)); } Signature(): flags(0) {} }; diff --git a/src/corto b/src/corto index d880519c..d240e693 160000 --- a/src/corto +++ b/src/corto @@ -1 +1 @@ -Subproject commit d880519c490c88a39d12c31a914b6a687a7019c3 +Subproject commit d240e69306a39417c098475d7002eb16b7264248 diff --git a/src/nxsbuild/CMakeLists.txt b/src/nxsbuild/CMakeLists.txt index 13a7fc02..2abf05a8 100644 --- a/src/nxsbuild/CMakeLists.txt +++ b/src/nxsbuild/CMakeLists.txt @@ -1,6 +1,6 @@ #export CMAKE_PREFIX_PATH=path to Qt/5.5/gcc_64/ (save for bin/qmake) -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.10) project(nxsbuild) SET(HEADERS @@ -15,10 +15,6 @@ SET(SOURCES main.cpp ) -cmake_minimum_required(VERSION 3.1) - -project(nxsbuild) - set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) diff --git a/src/nxsbuild/colormap.cpp b/src/nxsbuild/colormap.cpp new file mode 100644 index 00000000..3b10914b --- /dev/null +++ b/src/nxsbuild/colormap.cpp @@ -0,0 +1,77 @@ +#include "colormap.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#define clamp(v, m, M) std::min(M, std::max(m, v)); + +using namespace std; + +bool Colormap::loadFromCSV(const string& filename) { + ifstream file(filename); + if (!file.is_open()) return false; + + colormap.clear(); + string line; + while (getline(file, line)) { + stringstream ss(line); + Color color; + for (float& c : color) { + string value; + if (!getline(ss, value, ',')) return false; + c = stof(value); + } + colormap.push_back(color); + } + return !colormap.empty(); +} + +bool Colormap::setColormap(const string& name) { + static const std::map> predefinedColormaps = { + {"viridis", {{0.267f, 0.004f, 0.329f, 1.0f}, {0.283f, 0.141f, 0.458f, 1.0f}, {0.254f, 0.265f, 0.530f, 1.0f}, {0.207f, 0.372f, 0.553f, 1.0f}, {0.164f, 0.471f, 0.558f, 1.0f}, {0.128f, 0.567f, 0.551f, 1.0f}, {0.135f, 0.659f, 0.518f, 1.0f}, {0.267f, 0.850f, 0.441f, 1.0f}, {0.477f, 1.000f, 0.318f, 1.0f}}}, + {"spectral", {{0.619f, 0.003f, 0.258f, 1.0f}, {0.835f, 0.243f, 0.310f, 1.0f}, {0.957f, 0.427f, 0.263f, 1.0f}, {0.992f, 0.682f, 0.380f, 1.0f}, {1.000f, 0.878f, 0.545f, 1.0f}, {0.878f, 1.000f, 0.392f, 1.0f}, {0.671f, 0.866f, 0.204f, 1.0f}, {0.471f, 0.671f, 0.059f, 1.0f}, {0.267f, 0.459f, 0.000f, 1.0f}}}, + {"plasma", {{0.050f, 0.029f, 0.529f, 1.0f}, {0.294f, 0.001f, 0.635f, 1.0f}, {0.492f, 0.012f, 0.603f, 1.0f}, {0.676f, 0.209f, 0.486f, 1.0f}, {0.830f, 0.369f, 0.326f, 1.0f}, {0.959f, 0.566f, 0.152f, 1.0f}, {0.987f, 0.788f, 0.071f, 1.0f}, {0.941f, 0.975f, 0.320f, 1.0f}}} + }; + + auto it = predefinedColormaps.find(name); + if (it == predefinedColormaps.end()) { + return false; + } + colormap = it->second; + cout << "Returning true" << endl; + return true; +} + +Colormap::Colorb Colormap::map(float value) const { + value = clamp((value - minValue) / (maxValue - minValue), 0.0f, 1.0f); + float scaled = value * (colormap.size() - 1); + size_t idx = static_cast(scaled); + float t = scaled - idx; + + Color c; + if (idx >= colormap.size() - 1) + c = colormap.back(); + else + c = interpolate(colormap[idx], colormap[idx + 1], t); + + Colorb cb; + for(int i = 0; i < 4; i++) { + cb[i] = static_cast(floor(c[i]*255)); + } + return cb; +} + + +Colormap::Color Colormap::interpolate(const Color& c1, const Color& c2, float t) { + Color result; + for (size_t i = 0; i < 4; ++i) { + result[i] = c1[i] * (1.0f - t) + c2[i] * t; + } + return result; +} diff --git a/src/nxsbuild/colormap.h b/src/nxsbuild/colormap.h new file mode 100644 index 00000000..3d5584d2 --- /dev/null +++ b/src/nxsbuild/colormap.h @@ -0,0 +1,34 @@ +#ifndef COLORMAP_H +#define COLORMAP_H + + +#include +#include +#include +#include +#include +#include +#include + + +class Colormap { +public: + using Color = std::array; // RGBA + using Colorb = std::array; + + float minValue, maxValue; + std::vector colormap; + + Colormap(float min = 0.0f, float max = 1.0f) : minValue(min), maxValue(max) {} + + void setColormap(const std::vector& colors) { colormap = colors; } + bool setColormap(const std::string& name); + bool loadFromCSV(const std::string& filename); + + Colorb map(float value) const; + + static Color interpolate(const Color& c1, const Color& c2, float t); +}; + + +#endif // COLORMAP_H diff --git a/src/nxsbuild/main.cpp b/src/nxsbuild/main.cpp index 215b2e1c..d8069027 100644 --- a/src/nxsbuild/main.cpp +++ b/src/nxsbuild/main.cpp @@ -53,6 +53,8 @@ int main(int argc, char *argv[]) { QString output(""); //output file QString mtl; QString translate; + QString scalate; + QString colormap; bool center = false; @@ -118,7 +120,11 @@ int main(int argc, char *argv[]) { opt.addOption('r', "ram", "max ram used (in MegaBytes), default 2000 (WARNING: just an approximation)", &ram_buffer); opt.addOption('w', "workers", "number of workers: default = 4", &n_threads); opt.addOption('T', "origin", "new origin for the model in the format X:Y:Z", &translate); + opt.addOption('W', "scale", "scale vector (after origin subtraction) X:Y:Z", &scalate); opt.addSwitch('G', "center", "set origin in the bounding box center of the input meshes", ¢er); + + //ts specific options + opt.addOption('K', "colormap", "for .ts files: property:colormap such as temperature:viridis (or plasma, spectral)", &colormap); opt.parse(); //Check parameters are correct @@ -144,7 +150,11 @@ int main(int argc, char *argv[]) { } } - if(output == "") output = inputs[0].left(inputs[0].length()-4); + + if(output == "") { + int last = inputs[0].lastIndexOf("."); + output = inputs[0].left(last); + } if(!output.endsWith(".nxs")) output += ".nxs"; @@ -175,6 +185,26 @@ int main(int argc, char *argv[]) { } } + + vcg::Point3d scale(0, 0, 0); + if(!scalate.isEmpty()) { + QStringList p = scalate.split(':'); + if(p.size() != 3) { + cerr << "Malformed scale parameter, expecting X:Y:Z" << endl; + return -1; + } + + bool ok = false; + for(int i = 0; i < 3; i++) { + scale[i] = p[i].toDouble(&ok); + if(!ok) { + cerr << "Malformed scale parameter, expecting X:Y:Z" << endl; + return -1; + } + } + } + + Stream *stream = 0; KDTree *tree = 0; int returncode = 0; @@ -197,6 +227,14 @@ int main(int argc, char *argv[]) { else stream = new StreamSoup("cache_stream"); + if(!colormap.isNull()) { + stream->colormap = colormap.split(":"); + if(stream->colormap.size() != 2) { + throw QString("Format for color map is 'property:colormap'"); + } + colors = true; + } + stream->setVertexQuantization(vertex_quantization); stream->setMaxMemory(max_memory); if(center) { @@ -207,6 +245,8 @@ int main(int argc, char *argv[]) { stream->origin = box.Center(); } else stream->origin = origin; + if(!scalate.isEmpty()) + stream->scale = scale; vcg::Point3d &o = stream->origin; if(o[0] != 0.0 || o[1] != 0.0 || o[2] != 0.0) { diff --git a/src/nxsbuild/meshloader.h b/src/nxsbuild/meshloader.h index 97755cc9..ad8752ad 100644 --- a/src/nxsbuild/meshloader.h +++ b/src/nxsbuild/meshloader.h @@ -46,6 +46,7 @@ class MeshLoader { virtual bool hasTextures() { return has_textures; } vcg::Point3d origin = vcg::Point3d(0, 0, 0); + vcg::Point3d scale = vcg::Point3d(1, 1, 1); vcg::Box3d box; std::vector texture_filenames; diff --git a/src/nxsbuild/meshstream.cpp b/src/nxsbuild/meshstream.cpp index 0eb689ad..16e0af77 100644 --- a/src/nxsbuild/meshstream.cpp +++ b/src/nxsbuild/meshstream.cpp @@ -26,6 +26,7 @@ for more details. #include "stlloader.h" #include "vcgloadermesh.h" #include "vcgloader.h" +#include "tsloader.h" #include @@ -59,6 +60,13 @@ MeshLoader *loader = nullptr; else if(file.endsWith(".stl")) loader = new STLLoader(file); + else if(file.endsWith(".ts")) { + TsLoader *ts = new TsLoader(file); + loader = ts; + if(!colormap.isEmpty()) + ts->useColormapFor(colormap[0], colormap[1]); + } + else loader = new VcgLoader(file); /* else if(file.endsWith(".off")) @@ -95,6 +103,7 @@ vcg::Box3d Stream::getBox(QStringList paths) { void Stream::load(MeshLoader *loader) { loader->setVertexQuantization(vertex_quantization); loader->origin = origin; + loader->scale = scale; loadMesh(loader); has_colors &= loader->hasColors(); has_normals &= loader->hasNormals(); diff --git a/src/nxsbuild/meshstream.h b/src/nxsbuild/meshstream.h index 817e0189..3188bb80 100644 --- a/src/nxsbuild/meshstream.h +++ b/src/nxsbuild/meshstream.h @@ -39,6 +39,8 @@ class Stream { bool has_textures; std::vector textures; vcg::Point3d origin = vcg::Point3d(0, 0, 0); + vcg::Point3d scale = vcg::Point3d(1, 1, 1); + QStringList colormap; //used to convert a value into a color, .ts only Stream(); virtual ~Stream() {} diff --git a/src/nxsbuild/nxsbuild.pro b/src/nxsbuild/nxsbuild.pro index 491ef5ef..a8d8ad52 100644 --- a/src/nxsbuild/nxsbuild.pro +++ b/src/nxsbuild/nxsbuild.pro @@ -23,6 +23,7 @@ SOURCES += \ ../../../vcglib/wrap/ply/plylib.cpp \ ../common/virtualarray.cpp \ ../common/cone.cpp \ + colormap.cpp \ main.cpp \ meshstream.cpp \ meshloader.cpp \ @@ -34,7 +35,8 @@ SOURCES += \ objloader.cpp \ tmesh.cpp \ texpyramid.cpp \ - stlloader.cpp + stlloader.cpp \ + tsloader.cpp HEADERS += \ ../../../vcglib/wrap/system/qgetopt.h \ @@ -42,6 +44,7 @@ HEADERS += \ ../common/signature.h \ ../common/cone.h \ ../common/virtualarray.h \ + colormap.h \ meshstream.h \ meshloader.h \ plyloader.h \ @@ -57,7 +60,8 @@ HEADERS += \ texpyramid.h \ stlloader.h \ vcgloader.h \ - vcgloadermesh.h + vcgloadermesh.h \ + tsloader.h DESTDIR = "../../bin" diff --git a/src/nxsbuild/objloader.cpp b/src/nxsbuild/objloader.cpp index f9893d9a..09b9b6f9 100644 --- a/src/nxsbuild/objloader.cpp +++ b/src/nxsbuild/objloader.cpp @@ -19,6 +19,7 @@ for more details. #include #include #include +#include #include @@ -40,7 +41,7 @@ ObjLoader::ObjLoader(QString filename, QString _mtl): if(!file.open(QFile::ReadOnly)) throw QString("could not open file %1. Error: %2").arg(filename).arg(file.errorString()); - readMTL(); + readMTL(file); } ObjLoader::~ObjLoader() { @@ -83,20 +84,32 @@ void ObjLoader::cacheTextureUV() { } } -void ObjLoader::readMTL() { +void ObjLoader::readMTL(QFile &file) { - quint64 pos = file.pos(); char buffer[1024]; if (!mtl.isNull()) { if(!QFileInfo::exists(mtl)) throw QString("Could not find .mtl file: %1").arg(mtl); - } else { + } + + if(mtl.isNull()) { //look for mtllib + while (1) { + if(file.readLine(buffer, 1000) == -1) + break; + if(strncmp(buffer, "mtllib", 6) != 0) + continue; + + QString m = QString(buffer).mid(7).trimmed(); + if (QFileInfo::exists(m)) + mtl = m; + break; + } + } + if(mtl.isNull()) { //assume the name is the same QString fname = file.fileName(); QFileInfo info = QFileInfo(fname); - - //assuming mtl base file name the same as obj mtl = info.path() + "/" + info.completeBaseName() + ".mtl"; } @@ -164,8 +177,8 @@ void ObjLoader::readMTL() { } if(str.startsWith("Map_Kd", Qt::CaseInsensitive)){ txtfname = str.mid(7).trimmed(); - txtfname = txtfname.remove(QRegExp("^(\")")); - txtfname = txtfname.remove(QRegExp("(\")$")); + txtfname = txtfname.remove(QRegularExpression("^(\")")); + txtfname = txtfname.remove(QRegularExpression("(\")$")); continue; } if(str.startsWith("Kd", Qt::CaseInsensitive)){ @@ -247,6 +260,9 @@ void ObjLoader::cacheVertices() { int n = sscanf(buffer, "v %lf %lf %lf", &p[0], &p[1], &p[2]); if(n != 3) throw QString("error parsing vertex line %1 while caching").arg(buffer); p -= origin; + p[0] *= scale[0]; + p[1] *= scale[1]; + p[2] *= scale[2]; box.Add(p); vertex.v[0] = (float)p[0]; @@ -270,8 +286,8 @@ void ObjLoader::cacheVertices() { QFileInfo info = QFileInfo(fname); mtl = QString(buffer).mid(7).trimmed(); - mtl = mtl.remove(QRegExp("^(\")")); - mtl = mtl.remove(QRegExp("(\")$")); + mtl = mtl.remove(QRegularExpression("^(\")")); + mtl = mtl.remove(QRegularExpression("(\")$")); mtl = info.dir().filePath(mtl); } } @@ -348,8 +364,8 @@ quint32 ObjLoader::getTriangles(quint32 size, Triangle *faces) { QString str = QString(buffer).simplified(); - QRegExp rx("[ ]");// match a space - QStringList list = str.split(rx, QString::SkipEmptyParts); + QRegularExpression rx("[ ]");// match a space + QStringList list = str.split(rx, Qt::SkipEmptyParts); list.removeFirst(); //'f' if (list.last().startsWith('\n') || list.last().startsWith('\r')) list.removeLast(); @@ -543,6 +559,9 @@ quint32 ObjLoader::getVertices(quint32 size, Splat *vertices) { if(n != 3) throw QString("error parsing vertex line %1").arg(buffer); p -= origin; + p[0] *= scale[0]; + p[1] *= scale[1]; + p[2] *= scale[2]; box.Add(p); vertex.v[0] = (float)p[0]; diff --git a/src/nxsbuild/objloader.h b/src/nxsbuild/objloader.h index 6c70b33c..5e778b92 100644 --- a/src/nxsbuild/objloader.h +++ b/src/nxsbuild/objloader.h @@ -37,7 +37,7 @@ class ObjLoader: public MeshLoader { private: - void readMTL(); + void readMTL(QFile &file); //obj file passed to search for mtllib void cacheTextureUV(); void cacheVertices(); diff --git a/src/nxsbuild/plyloader.cpp b/src/nxsbuild/plyloader.cpp index 04971671..f1075a7e 100644 --- a/src/nxsbuild/plyloader.cpp +++ b/src/nxsbuild/plyloader.cpp @@ -145,8 +145,8 @@ PlyLoader::PlyLoader(QString filename): texture_filenames.push_back(tex); } } -// if(has_textures && texture_filenames.size() == 0) -// has_textures = false; + if(has_textures && texture_filenames.size() == 0) + has_textures = false; for(auto &tex: texture_filenames) { sanitizeTextureFilepath(tex.filename); @@ -249,13 +249,13 @@ void PlyLoader::cacheVertices() { Vertex &v = vertices[i]; pf.Read((void *)&vertex); if(double_coords) { - v.v[0] = vertex.dv[0] - origin[0]; - v.v[1] = vertex.dv[1] - origin[1]; - v.v[2] = vertex.dv[2] - origin[2]; + v.v[0] = (float)(vertex.dv[0] - origin[0])*scale[0]; + v.v[1] = (float)(vertex.dv[1] - origin[1])*scale[1]; + v.v[2] = (float)(vertex.dv[2] - origin[2])*scale[2]; } else { - v.v[0] = vertex.v[0] - origin[0]; - v.v[1] = vertex.v[1] - origin[1]; - v.v[2] = vertex.v[2] - origin[2]; + v.v[0] = (float)(vertex.v[0] - origin[0])*scale[0]; + v.v[1] = (float)(vertex.v[1] - origin[1])*scale[1]; + v.v[2] = (float)(vertex.v[2] - origin[2])*scale[2]; } if(has_colors) { v.c[0] = vertex.c[0]; @@ -352,17 +352,21 @@ quint32 PlyLoader::getVertices(quint32 size, Splat *splats) { Splat &v = splats[count++]; current_vertex++; + vcg::Point3d p; if(double_coords) { - box.Add(vcg::Point3d(vertex.dv) - origin); - v.v[0] = (float)(vertex.dv[0] - origin[0]); - v.v[1] = (float)(vertex.dv[1] - origin[1]); - v.v[2] = (float)(vertex.dv[2] - origin[2]); + p = vcg::Point3d(vertex.dv); } else { - box.Add(vcg::Point3d(vertex.v[0], vertex.v[1], vertex.v[2]) - origin); - v.v[0] = vertex.v[0] - (float)origin[0]; - v.v[1] = vertex.v[1] - (float)origin[1]; - v.v[2] = vertex.v[2] - (float)origin[2]; + p = vcg::Point3d(vertex.v[0], vertex.v[1], vertex.v[2]); } + p -= origin; + p[0] *= scale[0]; + p[1] *= scale[1]; + p[2] *= scale[2]; + box.Add(p); + v.v[0] = (float)p[0]; + v.v[1] = (float)p[1]; + v.v[2] = (float)p[2]; + if(has_colors) { v.c[0] = vertex.c[0]; v.c[1] = vertex.c[1]; diff --git a/src/nxsbuild/stlloader.cpp b/src/nxsbuild/stlloader.cpp index cb95099f..01a9e3d7 100644 --- a/src/nxsbuild/stlloader.cpp +++ b/src/nxsbuild/stlloader.cpp @@ -62,6 +62,9 @@ quint32 STLLoader::getTrianglesAscii(quint32 size, Triangle *buffer) { if(n != 4) throw QString("Invalid STL file"); d -= origin; + d[0] *= scale[0]; + d[1] *= scale[1]; + d[0] *= scale[2]; box.Add(d); v[0] = (float)(d[0]); @@ -97,7 +100,7 @@ quint32 STLLoader::getTrianglesBinary(quint32 size, Triangle *buffer) { Triangle &tri = buffer[i]; for(int t = 0; t < 3; t++) for(int k = 0; k < 3; k++) - tri.vertices[t].v[k] = pos[t*3 + k] - origin[k]; + tri.vertices[t].v[k] = (pos[t*3 + k] - origin[k])*scale[k]; tri.node = 0; current_triangle++; start += 50; diff --git a/src/nxsbuild/tsloader.cpp b/src/nxsbuild/tsloader.cpp new file mode 100644 index 00000000..f02791f2 --- /dev/null +++ b/src/nxsbuild/tsloader.cpp @@ -0,0 +1,276 @@ +/* +Nexus + +Copyright(C) 2012 - Federico Ponchio +ISTI - Italian National Research Council - Visual Computing Lab + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License (http://www.gnu.org/licenses/gpl.txt) +for more details. +*/ +#include "tsloader.h" +#include +#include +#include +#include + +using namespace std; + +TsLoader::TsLoader(QString filename): + vertices("cache_tsvertex"), + n_vertices(0), + n_triangles(0), + current_vertex(0) { + + file.setFileName(filename); + if(!file.open(QFile::ReadOnly)) + throw QString("could not open file %1. Error: %2").arg(filename).arg(file.errorString()); + + //search for properties, here an example: + /* + PROPERTY_CLASS_HEADER temperature { + kind: Real Number + unit: unitless + pclip: 99 + low_clip: 9 + high_clip: 143.54482 + } + */ +} + +bool TsLoader::useColormapFor(const QString &_property, const QString &palette) { + property = _property; + + bool inside_property = false; + while(1) { + QString line = file.readLine(1024).trimmed(); + if(line.isEmpty()) + break; + if(line.startsWith(QString("PROPERTY_CLASSES"))) { + QStringList props = line.split(" "); + int pos = props.indexOf(property); + if(pos == -1) { + throw QString("Could not find property: %1").arg(property); + } + property_position = pos-1; + } + + if(line.startsWith(QString("PROPERTY_CLASS_HEADER %1").arg(property))) { + inside_property = true; + } + + if(inside_property) { + if(line.startsWith("low_clip")) { + bool ok; + colormap.minValue = line.split(" ").back().toFloat(&ok); + if(!ok) throw QString("Proble parsing line: %1").arg(line); + } + if(line.startsWith("high_clip")) { + bool ok; + colormap.maxValue = line.split(" ").back().toFloat(&ok); + if(!ok) throw QString("Proble parsing line: %1").arg(line); + } + if(line[0] == '}') { + break; + } + } + if(line.startsWith("TFACE")) { + break; + } + } + file.seek(0); + + bool found = colormap.setColormap(palette.toStdString()); + + if(!found) { + throw QString("Could not find colormap: %1 (values accepted are plasma, spectral and viridis)"); + return false; + } + return true; +} + +TsLoader::~TsLoader() { + file.close(); +} + + + +void TsLoader::cacheVertices() { + vertices.setElementsPerBlock(1<<20); + file.seek(0); + char buffer[1024]; + char tmp[32]; + int cnt = 0; + + while(1) { + + int s = file.readLine(buffer, 1024); + if (s == -1) { //end of file + std::cout << "Vertices read: " << cnt << std::endl; + break; + + } + if(s == 0) continue; //skip empty lines + buffer[s] = '\0'; //terminating line, readLine wont do this. + + if(strncmp(buffer, "VRTX", 4) == 0 || strncmp(buffer, "PVRTX", 5) == 0) { + + vertices.resize(n_vertices+1); + Vertex &vertex = vertices[n_vertices]; + n_vertices++; + + vcg::Point3d p; + int id; + QString line(buffer); + QStringList parts = line.trimmed().split(" "); + if(parts.size() < 5 || parts.size() < property_position) + throw QString("error parsing vertex line %1 while caching").arg(buffer); + p[0] = parts[2].toFloat(); + p[1] = parts[3].toFloat(); + p[2] = parts[4].toFloat(); + + //std::string pattern = "%*s %*d %lf %lf %lf"; + //int n = sscanf(buffer, pattern.c_str(), &p[0], &p[1], &p[2]); + + p -= origin; + p[0] *= scale[0]; + p[1] *= scale[1]; + p[2] *= scale[2]; + box.Add(p); + + vertex.v[0] = (float)p[0]; + vertex.v[1] = (float)p[1]; + vertex.v[2] = (float)p[2]; + + if(property_position >= 0) { + float value = parts[5 + property_position].toFloat(); + std::array c = colormap.map(value); + for(int k = 0; k < 4; k++) + vertex.c[k] = c[k]; + } + + cnt++; + if(quantization) { + quantize(vertex.v[0]); + quantize(vertex.v[1]); + quantize(vertex.v[2]); + } + } + if(strncmp(buffer, "ATOM", 4) == 0) { + int id; + int n = sscanf(buffer, "%*s %*d %d", &id); + if(n != 1) throw QString("error parsing atom line %1 while caching").arg(buffer); + vertices.resize(n_vertices+1); + vertices[n_vertices] = vertices[id -1]; + } + } +} + +void TsLoader::setMaxMemory(quint64 max_memory) { + vertices.setMaxMemory(max_memory); +} + +quint32 TsLoader::getTriangles(quint32 size, Triangle *faces) { + + if (n_triangles == 0) { + cacheVertices(); + } + + char buffer[1024]; + file.seek(current_tri_pos); + + qint32 R = (0x7f << 24); + qint32 G = (0x7f << 16); + qint32 B = (0x7f << 8); + + quint32 count = 0; + qint64 cpos = current_tri_pos; + + while (count < size) { + cpos = file.pos(); + int s = file.readLine(buffer, 1024); + if (s == -1) { //end of file + cpos = file.pos(); + break; + } + + if (strncmp(buffer, "TRGL", 4) != 0) + continue; + + Triangle ¤t = faces[count]; + int f[3]; + int n = sscanf(buffer, "%*s %d %d %d", f, f+1, f+2); + if(n != 3) throw QString("error parsing triangle line %1 while reading").arg(buffer); + + current.vertices[0] = vertices[f[0]-1]; + current.vertices[1] = vertices[f[1]-1]; + current.vertices[2] = vertices[f[2]-1]; + + current.node = 0; + count++; + n_triangles++; + cpos = file.pos(); + } + + current_tri_pos = cpos; + + if (count == 0) + std::cout << "faces read: " << n_triangles << std::endl; + + return count; +} + + +/* + * Seeks all verteces in whole file + */ +quint32 TsLoader::getVertices(quint32 size, Splat *vertices) { + char buffer[1024]; + + quint32 count = 0; + while(count < size) { + int s = file.readLine(buffer, 1024); + if(s == -1) //end of file + return count; + + if(strncmp(buffer, "VRTX", 4) != 0 || strncmp(buffer, "PVRTX", 5) != 0) + continue; + + + buffer[s] = '\0'; //terminating line, readLine wont do this. + + + Splat &vertex = vertices[count]; + + vcg::Point3d p; + int n = sscanf(buffer, "%*s %*d %lf %lf %lf", &p[0], &p[1], &p[2]); + if(n != 3) throw QString("error parsing vertex line %1").arg(buffer); + + p -= origin; + p[0] *= scale[0]; + p[1] *= scale[1]; + p[2] *= scale[2]; + box.Add(p); + + vertex.v[0] = (float)p[0]; + vertex.v[1] = (float)p[1]; + vertex.v[2] = (float)p[2]; + + if(quantization) { + quantize(vertex.v[0]); + quantize(vertex.v[1]); + quantize(vertex.v[2]); + } + n_vertices++; + current_vertex++; + count++; + } + return count; +} diff --git a/src/nxsbuild/tsloader.h b/src/nxsbuild/tsloader.h new file mode 100644 index 00000000..f4fa7c25 --- /dev/null +++ b/src/nxsbuild/tsloader.h @@ -0,0 +1,32 @@ +#ifndef TSLOADER_H +#define TSLOADER_H + +#include "meshloader.h" +#include "colormap.h" + +class TsLoader: public MeshLoader { +public: + TsLoader(QString file); + ~TsLoader(); + + bool useColormapFor(const QString &_property, const QString &palette); + void setMaxMemory(quint64 max_memory); + quint32 getTriangles(quint32 size, Triangle *buffer); + quint32 getVertices(quint32 size, Splat *vertex); + +private: + + void cacheVertices(); + + QFile file; + VirtualArray vertices; + quint64 n_vertices; + quint64 n_triangles; + quint64 current_triangle; + quint64 current_vertex; + qint64 current_tri_pos = 0; + QString property; + int property_position = -1; + Colormap colormap; +}; +#endif // TSLOADER_H diff --git a/src/nxsedit/CMakeLists.txt b/src/nxsedit/CMakeLists.txt index 2a4f0c28..378db4a7 100644 --- a/src/nxsedit/CMakeLists.txt +++ b/src/nxsedit/CMakeLists.txt @@ -1,6 +1,6 @@ #export CMAKE_PREFIX_PATH=path to Qt/5.5/gcc_64/ (save for bin/qmake) -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.10) project(nxsedit) SET(HEADERS @@ -23,10 +23,6 @@ SET(SOURCES extractor.cpp ) -cmake_minimum_required(VERSION 3.1) - -project(nxsedit) - set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) @@ -56,10 +52,6 @@ SET(SOURCES main_compress.cpp ) -cmake_minimum_required(VERSION 3.1) - -project(nxscompress) - set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) diff --git a/src/nxsedit/extractor.cpp b/src/nxsedit/extractor.cpp index 155499bf..db39ed44 100644 --- a/src/nxsedit/extractor.cpp +++ b/src/nxsedit/extractor.cpp @@ -16,6 +16,9 @@ GNU General Public License (http://www.gnu.org/licenses/gpl.txt) for more details. */ #include +#include +#include +#include #include "extractor.h" #include "../nxszip/meshcoder.h" @@ -26,6 +29,28 @@ for more details. using namespace std; using namespace nx; +namespace { +QString deepzoomFolderFromOutput(const QString &output) { + QFileInfo info(output); + QString dirPath = info.absolutePath(); + if(dirPath.isEmpty()) + dirPath = "."; + return dirPath + "/" + info.completeBaseName() + "_files"; +} + +QString deepzoomFilePath(const QString &folder, uint32_t index, const QString &ext) { + return QString("%1/%2.%3").arg(folder).arg(index).arg(ext); +} + +void ensureDeepzoomFolder(const QString &folder) { + QDir dir; + if(dir.exists(folder)) + return; + if(!dir.mkpath(folder)) + throw QString("could not create deepzoom folder %1").arg(folder); +} +} + Extractor::Extractor(NexusData *nx): transform(false), max_size(0), current_size(0), @@ -99,6 +124,13 @@ void Extractor::save(QString output, nx::Signature &signature) { file.setFileName(output); if(!file.open(QIODevice::WriteOnly | QFile::Truncate)) throw QString("could not open file " + output + " for writing"); + + const bool saveAsDeepzoom = signature.isDeepzoom(); + QString deepzoomFolder; + if(saveAsDeepzoom) { + deepzoomFolder = deepzoomFolderFromOutput(output); + ensureDeepzoomFolder(deepzoomFolder); + } nx::Header header = nexus->header; header.signature = signature; @@ -196,9 +228,25 @@ void Extractor::save(QString output, nx::Signature &signature) { } } if(signature.isCompressed()) { - compress(file, signature, node, nexus->nodedata[i], &*patches.begin()); + if(saveAsDeepzoom) { + QFile nodeFile(deepzoomFilePath(deepzoomFolder, n, QStringLiteral("nxn"))); + if(!nodeFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + throw QString("could not open node file %1 for writing").arg(nodeFile.fileName()); + compress(nodeFile, signature, node, nexus->nodedata[i], &*patches.begin()); + nodeFile.close(); + } else { + compress(file, signature, node, nexus->nodedata[i], &*patches.begin()); + } } else { - file.write(memory, data_size); + if(saveAsDeepzoom) { + QFile nodeFile(deepzoomFilePath(deepzoomFolder, n, QStringLiteral("nxn"))); + if(!nodeFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + throw QString("could not open node file %1 for writing").arg(nodeFile.fileName()); + nodeFile.write(memory, data_size); + nodeFile.close(); + } else { + file.write(memory, data_size); + } } if(transform) delete []memory; @@ -209,16 +257,35 @@ void Extractor::save(QString output, nx::Signature &signature) { //save textures if(textures.size()) { - for(uint i = 0; i < textures.size()-1; i++) { + for(uint32_t i = 0; i < textures.size()-1; i++) { Texture &in = nexus->textures[i]; Texture &out = textures[i] = in; quint64 start = in.getBeginOffset(); quint64 size = in.getSize(); - char *memory = (char *)nexus->file->map(start, size); + char *memory = 0; + if(nexus->header.signature.isDeepzoom()) { + memory = nexus->file->loadDZTex(i); + } else { + memory = (char *)nexus->file->map(start, size); + } out.offset = file.pos()/NEXUS_PADDING; - file.write(memory, size); + if(saveAsDeepzoom) { + QFile texFile(deepzoomFilePath(deepzoomFolder, i, QStringLiteral("jpg"))); + if(!texFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + throw QString("could not open texture file %1 for writing").arg(texFile.fileName()); + texFile.write(memory, size); + texFile.close(); + } else { + file.write(memory, size); + } + + if(nexus->header.signature.isDeepzoom()) { + nexus->file->dropDZTex(memory); + } else { + nexus->file->unmap(memory); + } } textures.back().offset = file.pos()/NEXUS_PADDING; } diff --git a/src/nxsview/CMakeLists.txt b/src/nxsview/CMakeLists.txt index d011b16c..fdc871f0 100644 --- a/src/nxsview/CMakeLists.txt +++ b/src/nxsview/CMakeLists.txt @@ -1,6 +1,6 @@ #export CMAKE_PREFIX_PATH=path to Qt/5.5/gcc_64/ (save for bin/qmake) -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.10) project(nxsview) SET(HEADERS @@ -46,15 +46,15 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) -find_package(Qt5OpenGL) +find_package(Qt6 COMPONENTS OpenGL OpenGLWidgets REQUIRED) include(${CMAKE_CURRENT_SOURCE_DIR}/glew.cmake) add_executable(nxsview MACOSX_BUNDLE ${SOURCES} ${HEADERS}) if (WIN32) - target_link_libraries(nxsview PUBLIC nexus Qt5::OpenGL external-glew glu32 OpenGL32) + target_link_libraries(nxsview PUBLIC nexus Qt6::OpenGL Qt6::OpenGLWidgets external-glew glu32 OpenGL32) else() - target_link_libraries(nxsview PUBLIC nexus Qt5::OpenGL external-glew OpenGL::GLU OpenGL::GL) + target_link_libraries(nxsview PUBLIC nexus Qt6::OpenGL Qt6::OpenGLWidgets external-glew OpenGL::GLU OpenGL::GL) endif() target_compile_definitions(nxsview PRIVATE GL_COMPATIBILITY) diff --git a/src/nxsview/gl_nxsview.cpp b/src/nxsview/gl_nxsview.cpp index ca1e6934..12955c10 100644 --- a/src/nxsview/gl_nxsview.cpp +++ b/src/nxsview/gl_nxsview.cpp @@ -37,7 +37,7 @@ int current_texture = 0; void glV(Point3f &p) { glVertex3f(p[0], p[1], p[2]); } GLNxsview::GLNxsview(QWidget *parent, bool _share): - QGLWidget(parent), share(_share), + QOpenGLWidget(parent), share(_share), default_trackball(true), extracting(true), current_viewpoint(-1), current_time(-1), playing(false), hasToPick(false), fov(60), info(false) { @@ -133,7 +133,7 @@ void GLNxsview::setColorBottom() { } void GLNxsview::getSnapshot() { - QImage im = grabFrameBuffer(); + QImage im = grabFramebuffer(); QString file = QFileDialog::getSaveFileName(this, tr("Select .png filename to save shapshot"), "", @@ -352,7 +352,7 @@ void GLNxsview::paintEvent(QPaintEvent * /*event*/) { if(extracting) renderer.endFrame(); - static QTime time; + static QElapsedTimer time; static bool first_time = true; if(first_time) time.start(); @@ -406,7 +406,7 @@ Trackball::Button QT2VCG(Qt::MouseButton qtbt, Qt::KeyboardModifiers modifiers) int vcgbt=Trackball::BUTTON_NONE; if(qtbt & Qt::LeftButton) vcgbt |= Trackball::BUTTON_LEFT; if(qtbt & Qt::RightButton) vcgbt |= Trackball::BUTTON_RIGHT; - if(qtbt & Qt::MidButton) vcgbt |= Trackball::BUTTON_MIDDLE; + if(qtbt & Qt::MiddleButton) vcgbt |= Trackball::BUTTON_MIDDLE; if(modifiers & Qt::ShiftModifier) vcgbt |= Trackball::KEY_SHIFT; if(modifiers & Qt::ControlModifier) vcgbt |= Trackball::KEY_CTRL; if(modifiers & Qt::AltModifier) vcgbt |= Trackball::KEY_ALT; @@ -414,7 +414,7 @@ Trackball::Button QT2VCG(Qt::MouseButton qtbt, Qt::KeyboardModifiers modifiers) } void GLNxsview::wheelEvent(QWheelEvent *e) { - if(e->delta() > 0) + if(e->angleDelta().y() > 0) trackball.MouseWheel(1); else trackball.MouseWheel(-1); diff --git a/src/nxsview/gl_nxsview.h b/src/nxsview/gl_nxsview.h index ba849540..4f70b8ee 100644 --- a/src/nxsview/gl_nxsview.h +++ b/src/nxsview/gl_nxsview.h @@ -20,9 +20,9 @@ for more details. #include #include -#include +#include #include -#include +#include #include #include @@ -32,7 +32,7 @@ for more details. #include "../common/renderer.h" #include "scene.h" -class GLNxsview : public QGLWidget { +class GLNxsview : public QOpenGLWidget { Q_OBJECT public: @@ -88,7 +88,7 @@ public slots: std::vector viewpoints; quint32 current_viewpoint; float current_time; //this will be modified by velocity - QTime time; + QElapsedTimer time; bool playing; void init(QString file); diff --git a/src/nxsview/main.cpp b/src/nxsview/main.cpp index 5fc48340..a827c10b 100644 --- a/src/nxsview/main.cpp +++ b/src/nxsview/main.cpp @@ -59,7 +59,9 @@ class QMyWindow: public QWidget { int main(int argc, char *argv[]) { +#if QT_VERSION < 0x060000 QApplication::setAttribute(Qt::AA_X11InitThreads); +#endif QApplication app(argc, argv); QMyWindow *window = new QMyWindow(NULL);