├── .gitignore ├── libs ├── NftMarkerCreator_wasm.wasm └── NftMarkerCreator_wasm.js ├── docs ├── wasm │ └── NftMarkerCreator_wasm.wasm ├── icons │ ├── star2.svg │ └── star.svg ├── index.html ├── style.css ├── index.js └── exif.js ├── package.json ├── README.md └── app.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | input/* 3 | output/* 4 | package-lock.json 5 | .vscode/* 6 | 7 | -------------------------------------------------------------------------------- /libs/NftMarkerCreator_wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AR-js-org/NFT-Marker-Creator/HEAD/libs/NftMarkerCreator_wasm.wasm -------------------------------------------------------------------------------- /docs/wasm/NftMarkerCreator_wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AR-js-org/NFT-Marker-Creator/HEAD/docs/wasm/NftMarkerCreator_wasm.wasm -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodegenerator", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "MIT", 11 | "dependencies": { 12 | "glob": "^7.1.6", 13 | "inkjet": "^2.1.2", 14 | "jpeg-js": "^0.3.6", 15 | "pngjs": "^3.4.0", 16 | "readline-sync": "^1.4.10" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/icons/star2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | NFt Marker Creator 8 | 9 | 10 | 11 |
12 |

NFT Marker Creator

13 | 14 | 15 | 16 |
17 | 18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 26 | 27 |
28 |

Confidence:

29 | 30 | 31 | 32 | 33 | 34 |
35 |

Warning: 36 | Images with width and/or height above 1000px might take 20min+ to generate.
37 | For a more efficient Marker generator, please use the Node script version: 38 | https://github.com/Carnaux/NFT-Marker-Creator
39 |

40 |
41 | 42 | 43 | 44 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /docs/icons/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 12 | 21 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Image Tracking (NFT) MARKER CREATOR 2 | 3 | This editor creates Image Tracking (NFT) markers for ARTOOLKIT 5.x. 4 | This can be used for AR.js and jsartoolkit5. 5 | 6 | It take an image as input and outputs three files, called image descriptors, that can be loaded on the Web App for Image Tracking, using AR.js (or jsartoolkit5). 7 | 8 | A Node version (preferred) and Web version are provided. 9 | 10 | **Original repository is from @carnaux, we thank him so much and hope to keep this collaboration alive 😀** 11 | 12 | @carnaux references: 13 | * https://github.com/Carnaux 14 | * https://twitter.com/DanielCarnaux 15 | 16 | 17 | 🖼Check out [this tutorial](https://github.com/Carnaux/NFT-Marker-Creator/wiki/Creating-good-markers) with advices from the author on how to create a good marker, choosing the right image. 18 | 19 | 20 | # Web version 21 | 22 | **Online version, ready to use: https://ar-js-org.github.io/NFT-Marker-Creator/** 23 | 24 | This version is less efficient for images with width and/or height with 1000px or higher. 25 | 26 | 27 | ## Instructions 28 | 29 | 1. Upload any JPG/PNG image. 30 | 2. If the Number of Channels is missing, it will as for it. 31 | 3. Click the generate button. 32 | 4. The files will be automatically downloaded when the generation finishes. 33 | 34 | Advanced options coming soon. 35 | 36 | ## Node version (preferred version) 37 | 38 | ### How to use it 39 | 40 | 1. Clone this repository. 41 | 42 | 2. Install all dependencies. 43 | 44 | ` npm install ` 45 | 46 | 47 | 3. Put the image you want inside the app folder. You can just paste it or you can create a folder. e.g 48 | 49 | - markerCreatorAppFolder 50 | - app.js 51 | - NftMarkerCreator.min.js 52 | - IMAGE.PNG 53 | - ... 54 | 55 | or 56 | 57 | - markerCreatorAppFolder 58 | - app.js 59 | - NftMarkerCreator.min.js 60 | - FOLDER/IMAGE.PNG 61 | - ... 62 | 63 | 4. Run it 64 | 65 | ` node app.js -i ` 66 | 67 | 5. The prompt may ask you to insert information abou the image (width in px, height in px, DPI). It's strongly suggested to insert them. 68 | 69 | 6. In the end of the process an "output" folder will be created (if it does not exist) with the image-descriptors files. 70 | 71 | You can use additional flags with the run command. 72 | 73 | e.g node app.js -i image.png -level=4 -min_thresh=8 74 | 75 | -level=n 76 | (n is an integer in range 0 (few) to 4 (many). Default 2.' 77 | -sd_thresh= 78 | -max_thresh= 79 | -min_thresh= 80 | -leveli=n 81 | (n is an integer in range 0 (few) to 3 (many). Default 1.' 82 | -feature_density= 83 | -dpi=f: Override embedded JPEG DPI value. 84 | -max_dpi= 85 | -min_dpi= 86 | -background 87 | Run in background, i.e. as daemon detached from controlling terminal. (macOS and Linux only.) 88 | -log= 89 | -loglevel=x 90 | x is one of: DEBUG, INFO, WARN, ERROR. Default is INFO. 91 | -exitcode= 92 | --help -h -? Display this help 93 | 94 | 95 | 5. The generated files will be on the "output" folder. 96 | 97 | ------ 98 | #### If you want to generate you own NftMarkerCreator.min.js use the dev branch. 99 | 100 | 101 | "Icon made by Freepik from www.flaticon.com" 102 | -------------------------------------------------------------------------------- /docs/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #eee; 3 | font-family: sans-serif; 4 | height: 100%; 5 | width: 100%; 6 | color: #023962; 7 | } 8 | 9 | .container { 10 | display: flex; 11 | flex-direction: column; 12 | height: 100%; 13 | width: 100%; 14 | align-items: center; 15 | } 16 | 17 | #title { 18 | text-align: center; 19 | font-size: 4em; 20 | } 21 | 22 | .bt { 23 | color: white; 24 | border-radius: 5px; 25 | width: 10em; 26 | margin-top: 0.5em; 27 | cursor: pointer; 28 | padding: 0.25em; 29 | font-size: 2em; 30 | outline: inherit; 31 | background-color: #023962; 32 | } 33 | 34 | .bt[disabled] { 35 | opacity: 0.5; 36 | cursor: default; 37 | } 38 | 39 | #generateBt{ 40 | margin-top: 20px; 41 | } 42 | 43 | #hideCanvas { 44 | display: none; 45 | } 46 | /* #wrapper{ 47 | margin-top: 3em; 48 | 49 | } */ 50 | #imageCanvas { 51 | margin-top: 3em; 52 | width: 20em; 53 | height: 20em; 54 | } 55 | 56 | #warning { 57 | margin-top: 4em; 58 | font-size: 18px; 59 | } 60 | 61 | /* MODAL */ 62 | #modal { 63 | position: absolute; 64 | top: 0; 65 | left: 0; 66 | width: 100vw; 67 | height: 100vh; 68 | background-color: rgba(0, 0, 0, 0.267); 69 | display: none; 70 | z-index: 1000000; 71 | } 72 | 73 | #modalBody { 74 | background-color: white; 75 | border-radius: 10px; 76 | border-style: solid; 77 | border-color: rgb(100, 100, 100); 78 | position: fixed; 79 | top: 0; 80 | bottom: 0; 81 | left: 0; 82 | right: 0; 83 | margin: auto; 84 | width: 400px; 85 | height: 280px; 86 | } 87 | 88 | #modalTitle { 89 | position: absolute; 90 | top: 40px; 91 | left: 60px; 92 | font-size: 20px; 93 | margin: auto; 94 | } 95 | 96 | #confirmBt { 97 | right: 100px; 98 | } 99 | 100 | #cancelBt { 101 | left: 100px; 102 | } 103 | 104 | .modBt { 105 | position: absolute; 106 | bottom: 30px; 107 | font-size: 20px; 108 | } 109 | 110 | #modalInput { 111 | position: absolute; 112 | bottom: 100px; 113 | left: 120px; 114 | border-color: rgb(100, 100, 100); 115 | } 116 | 117 | #modalTxt { 118 | position: absolute; 119 | bottom: 120px; 120 | font-weight: bold; 121 | text-align: center; 122 | } 123 | .confidenceEl{ 124 | width: 50px; 125 | height: auto; 126 | } 127 | .grid-template-columns { 128 | grid-template-columns: 200px 60px 60px 60px 60px 60px; 129 | } 130 | 131 | /* SPINNER */ 132 | .spinner-container { 133 | position: relative; 134 | top: -9em; 135 | display: none; 136 | margin-top: -4em; 137 | z-index: 100; 138 | } 139 | 140 | .spinner { 141 | width: 4em; 142 | height: 4em; 143 | clear: both; 144 | margin: auto; 145 | border: 4px #1A1A2C solid; 146 | border-top: 4px #eee solid; 147 | border-radius: 50%; 148 | -webkit-animation: spin .6s infinite linear; 149 | animation: spin .6s infinite linear; 150 | } 151 | 152 | @-webkit-keyframes spin { 153 | from { -webkit-transform: rotate(0deg); } 154 | to { -webkit-transform: rotate(359deg); } 155 | } 156 | 157 | @keyframes spin { 158 | from { transform: rotate(0deg); } 159 | to { transform: rotate(359deg); } 160 | } 161 | 162 | .checkmark-cover{ 163 | display: none; 164 | position: relative; 165 | top: -9em; 166 | left: -7em; 167 | margin-top: -4em; 168 | z-index: 100; 169 | } 170 | 171 | .tasks-list-mark { 172 | float:right; 173 | position: relative; 174 | display: inline-block; 175 | vertical-align: top; 176 | margin: 5px; 177 | width: 4em; 178 | height: 4em; 179 | background-color: rgb(103, 173, 94); 180 | border: 3px solid rgb(20, 99, 10); 181 | border-radius: 50%; 182 | cursor:pointer; 183 | } 184 | 185 | .tasks-list-mark:before { 186 | content: ''; 187 | display: block; 188 | position: absolute; 189 | top: 40%; 190 | left: 40%; 191 | margin: -9px 0 0 -10px; 192 | height: 1em; 193 | width: 2em; 194 | border: solid rgb(20, 99, 10); 195 | border-width: 0 0 4px 4px; 196 | -webkit-transform: rotate(-45deg); 197 | -moz-transform: rotate(-45deg); 198 | -ms-transform: rotate(-45deg); 199 | -o-transform: rotate(-45deg); 200 | transform: rotate(-45deg); 201 | } 202 | -------------------------------------------------------------------------------- /docs/index.js: -------------------------------------------------------------------------------- 1 | var imageLoader = document.getElementById('imageLoader'); 2 | imageLoader.addEventListener('change', handleImage, false); 3 | var canvas = document.getElementById('imageCanvas'); 4 | var hideCanvas = document.getElementById('hideCanvas'); 5 | hideCanvas.style.display = "none"; 6 | var ctx = canvas.getContext('2d'); 7 | ctx.fillStyle = "#949494"; 8 | ctx.fillRect(0, 0, canvas.width, canvas.height); 9 | var ctxHide = hideCanvas.getContext('2d'); 10 | 11 | var reader = new FileReader(); 12 | 13 | var name; 14 | var nameWithExt; 15 | 16 | var globalObj = { 17 | dpi: 0, 18 | nc: 0, 19 | w: 0, 20 | h: 0, 21 | arr: [] 22 | } 23 | 24 | function handleImage(e) { 25 | nameWithExt = e.target.files[0].name; 26 | console.log("Image uploaded: " + nameWithExt); 27 | 28 | name = nameWithExt.substr(0, nameWithExt.lastIndexOf('.')); 29 | 30 | let extJpg = nameWithExt.substr(nameWithExt.lastIndexOf('.')); 31 | 32 | let confidenceEl = document.getElementById("confidenceLevel"); 33 | let childEls = confidenceEl.getElementsByClassName("confidenceEl"); 34 | for(let i = 0; i < childEls.length; i++){ 35 | childEls[i].src = "./icons/star2.svg"; 36 | } 37 | 38 | if (extJpg == '.jpg' || extJpg == '.jpeg' || extJpg == '.JPG' || extJpg == '.JPEG') { 39 | useJpeg(e); 40 | } else if (extJpg == '.png' || extJpg == '.PNG') { 41 | globalObj.dpi = 72; 42 | readImage(e) 43 | } else { 44 | console.log("Invalid image format!"); 45 | } 46 | 47 | document.getElementById("generateBt").disabled = false; 48 | } 49 | 50 | function generate() { 51 | var imageCanvas = document.querySelector('#imageCanvas'); 52 | imageCanvas.style.opacity = 0.25; 53 | 54 | var spinner = document.querySelector('.spinner-container'); 55 | spinner.style.display = 'block'; 56 | 57 | setTimeout(() => { 58 | let cmdArr = [0, name]; 59 | 60 | let heapSpace = Module._malloc(globalObj.arr.length * globalObj.arr.BYTES_PER_ELEMENT); // 1 61 | Module.HEAPU8.set(globalObj.arr, heapSpace); // 2 62 | 63 | Module._createImageSet(heapSpace, globalObj.dpi, globalObj.w, globalObj.h, globalObj.nc, name, cmdArr.length, cmdArr); 64 | Module._free(heapSpace); 65 | 66 | 67 | downloadIset(); 68 | }, 500); 69 | } 70 | 71 | function downloadIset() { 72 | let mime = "application/octet-stream"; 73 | 74 | let filenameIset = "asa.iset"; 75 | let filenameFset = "asa.fset"; 76 | let filenameFset3 = "asa.fset3"; 77 | 78 | let ext = ".iset"; 79 | let ext2 = ".fset"; 80 | let ext3 = ".fset3"; 81 | 82 | let content = Module.FS.readFile(filenameIset); 83 | let contentFset = Module.FS.readFile(filenameFset); 84 | let contentFset3 = Module.FS.readFile(filenameFset3); 85 | 86 | var a = document.createElement('a'); 87 | a.download = name + ext; 88 | a.href = URL.createObjectURL(new Blob([content], { type: mime })); 89 | a.style.display = 'none'; 90 | 91 | var b = document.createElement('a'); 92 | b.download = name + ext2; 93 | b.href = URL.createObjectURL(new Blob([contentFset], { type: mime })); 94 | b.style.display = 'none'; 95 | 96 | var c = document.createElement('a'); 97 | c.download = name + ext3; 98 | c.href = URL.createObjectURL(new Blob([contentFset3], { type: mime })); 99 | c.style.display = 'none'; 100 | 101 | document.body.appendChild(a); 102 | a.click(); 103 | 104 | document.body.appendChild(b); 105 | b.click(); 106 | 107 | document.body.appendChild(c); 108 | c.click(); 109 | 110 | var spinner = document.querySelector('.spinner-container'); 111 | spinner.style.display = 'none'; 112 | 113 | var okSign = document.querySelector('.checkmark-cover'); 114 | okSign.style.display = 'block'; 115 | } 116 | 117 | function getUint8(str) { 118 | let base64 = str.substr(23, str.length); 119 | var raw = atob(base64); 120 | var rawLength = raw.length; 121 | var array = new Uint8Array(new ArrayBuffer(rawLength)); 122 | 123 | for (i = 0; i < rawLength; i++) { 124 | array[i] = raw.charCodeAt(i); 125 | } 126 | 127 | // console.log("arr", array) 128 | return array; 129 | } 130 | 131 | function openModal() { 132 | let modalWrapper = document.getElementById("modal"); 133 | modalWrapper.style.display = "block"; 134 | } 135 | 136 | function closeModal() { 137 | let modalWrapper = document.getElementById("modal"); 138 | modalWrapper.style.display = "none"; 139 | } 140 | 141 | function setValueFromModal() { 142 | let input = document.getElementById("modalInput").value; 143 | globalObj.nc = parseInt(input); 144 | closeModal(); 145 | } 146 | 147 | function detectColorSpace(arr) { 148 | let target = parseInt(arr.length / 4); 149 | 150 | let counter = 0; 151 | 152 | for (let j = 0; j < arr.length; j += 4) { 153 | let r = arr[j]; 154 | let g = arr[j + 1]; 155 | let b = arr[j + 2]; 156 | 157 | if (r == g && r == b) { 158 | counter++; 159 | } 160 | } 161 | 162 | if (target == counter) { 163 | return 1; 164 | } else { 165 | return 3; 166 | } 167 | } 168 | 169 | function useJpeg(e) { 170 | EXIF.getData(e.target.files[0], function () { 171 | var dpi1 = parseFloat(EXIF.getTag(this, "XResolution")); 172 | 173 | if (isNaN(dpi1) || dpi1 == null) { 174 | globalObj.dpi = 72 175 | } else { 176 | globalObj.dpi = dpi1; 177 | } 178 | 179 | var nc1 = EXIF.getTag(this, "ComponentsConfiguration") 180 | 181 | if (isNaN(nc1) || nc1 == null) { 182 | var nc2 = parseFloat(EXIF.getTag(this, "SamplesPerPixel")); 183 | if (isNaN(nc2) || nc2 == null) { 184 | // openModal(); 185 | } else { 186 | globalObj.nc = nc2; 187 | } 188 | } else { 189 | globalObj.nc = nc1; 190 | } 191 | 192 | readImage(e); 193 | }); 194 | 195 | } 196 | 197 | function readImage(e) { 198 | reader.onload = function (event) { 199 | 200 | var img = new Image(); 201 | img.onload = function () { 202 | var canvasEl = document.querySelector('#imageCanvas'); 203 | canvas.width = canvasEl.clientWidth; 204 | canvas.height = canvasEl.clientHeight; 205 | 206 | hideCanvas.width = img.width; 207 | hideCanvas.height = img.height; 208 | 209 | globalObj.w = img.width; 210 | globalObj.h = img.height; 211 | 212 | ctxHide.drawImage(img, 0, 0); 213 | 214 | ctx.drawImage(img, 0, 0, img.width, img.height, // source rectangle 215 | 0, 0, canvas.width, canvas.height); // destination rectangle 216 | 217 | var imgData = ctxHide.getImageData(0, 0, hideCanvas.width, hideCanvas.height); 218 | 219 | let newArr = []; 220 | 221 | let verifyColorSpace = detectColorSpace(imgData.data); 222 | 223 | if (verifyColorSpace == 1) { 224 | for (let j = 0; j < imgData.data.length; j += 4) { 225 | newArr.push(imgData.data[j]); 226 | } 227 | } else if (verifyColorSpace == 3) { 228 | for (let j = 0; j < imgData.data.length; j += 4) { 229 | newArr.push(imgData.data[j]); 230 | newArr.push(imgData.data[j + 1]); 231 | newArr.push(imgData.data[j + 2]); 232 | } 233 | } 234 | 235 | globalObj.nc = verifyColorSpace; 236 | 237 | let uint = new Uint8Array(newArr); 238 | 239 | globalObj.arr = uint; 240 | 241 | let confidence = calculateQuality(); 242 | let confidenceEl = document.getElementById("confidenceLevel"); 243 | let childEls = confidenceEl.getElementsByClassName("confidenceEl"); 244 | for(let i = 0; i < parseInt(confidence.l); i++){ 245 | childEls[i].src = "./icons/star.svg"; 246 | } 247 | confidenceEl.scrollIntoView(); 248 | } 249 | img.src = event.target.result; 250 | } 251 | reader.readAsDataURL(e.target.files[0]); 252 | } 253 | 254 | function calculateQuality(){ 255 | let gray = toGrayscale(globalObj.arr); 256 | let hist = getHistogram(gray); 257 | let ent = 0; 258 | let totSize = globalObj.w * globalObj.h; 259 | for(let i = 0; i < 255; i++){ 260 | if(hist[i] > 0){ 261 | let temp = (hist[i]/totSize)*(Math.log(hist[i]/totSize)); 262 | ent += temp; 263 | } 264 | } 265 | 266 | let entropy = (-1 * ent).toFixed(2); 267 | let oldRange = (5.17 - 4.6); 268 | let newRange = (5 - 0); 269 | let level = (((entropy - 4.6) * newRange) / oldRange); 270 | 271 | if(level > 5){ 272 | level = 5; 273 | }else if(level < 0){ 274 | level = 0; 275 | } 276 | return {l:level.toFixed(2), e: entropy}; 277 | } 278 | 279 | function toGrayscale(arr){ 280 | let gray = []; 281 | for(let i = 0; i < arr.length; i+=3){ 282 | let avg = (arr[i] + arr[i+1] + arr[i+2])/3; 283 | gray.push(parseInt(avg)); 284 | } 285 | return gray; 286 | } 287 | 288 | function getHistogram(arr){ 289 | let hist = [256]; 290 | for(let i = 0; i < arr.length; i++){ 291 | hist[i] = 0; 292 | } 293 | for(let i = 0; i < arr.length; i++){ 294 | hist[arr[i]]++; 295 | } 296 | return hist; 297 | } 298 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require('fs'); 3 | const glob = require('glob'); 4 | const inkjet = require('inkjet'); 5 | const PNG = require('pngjs').PNG; 6 | const readlineSync = require('readline-sync'); 7 | var artoolkit_wasm_url = './libs/NftMarkerCreator_wasm.wasm'; 8 | var Module = require('./libs/NftMarkerCreator_wasm.js'); 9 | 10 | 11 | // GLOBAL VARs 12 | var params = [ 13 | 0, 14 | 0 15 | ]; 16 | 17 | var validImageExt = [".jpg",".jpeg",".png"]; 18 | 19 | var srcImage; 20 | 21 | var buffer; 22 | 23 | var foundInputPath = { 24 | b: false, 25 | i: -1 26 | } 27 | 28 | var imageData = { 29 | sizeX: 0, 30 | sizeY: 0, 31 | nc: 0, 32 | dpi: 0, 33 | array: [] 34 | } 35 | 36 | 37 | Module.onRuntimeInitialized = function(){ 38 | 39 | for (let j = 2; j < process.argv.length; j++) { 40 | if(process.argv[j].indexOf('-i') !== -1 || process.argv[j].indexOf('-I') !== -1){ 41 | foundInputPath.b = true; 42 | foundInputPath.i = j+1; 43 | j++; 44 | } else { 45 | params.push(process.argv[j]); 46 | } 47 | } 48 | 49 | if(!foundInputPath.b){ 50 | console.log("\nERROR: No image in INPUT command!\n e.g:(-i /PATH/TO/IMAGE)\n"); 51 | process.exit(1); 52 | }else{ 53 | srcImage = path.join(__dirname, process.argv[foundInputPath.i]); 54 | } 55 | 56 | let fileNameWithExt = path.basename(srcImage); 57 | let fileName = path.parse(fileNameWithExt).name; 58 | let extName = path.parse(fileNameWithExt).ext; 59 | 60 | params[1] = fileNameWithExt; 61 | 62 | let foundExt = false; 63 | for (let ext in validImageExt) { 64 | if(extName.toLowerCase() === validImageExt[ext]){ 65 | foundExt = true; 66 | break; 67 | } 68 | } 69 | 70 | if(!foundExt){ 71 | console.log("\nERROR: Invalid image TYPE!\n Valid types:(jpg,JPG,jpeg,JPEG,png,PNG)\n"); 72 | process.exit(1); 73 | } 74 | 75 | if(!fs.existsSync(srcImage)){ 76 | console.log("\nERROR: Not possible to read image, probably invalid image PATH!\n"); 77 | process.exit(1); 78 | }else{ 79 | buffer = fs.readFileSync(srcImage); 80 | } 81 | 82 | if(!fs.existsSync(path.join(__dirname, '/output/'))){ 83 | fs.mkdirSync(path.join(__dirname, '/output/')); 84 | } 85 | 86 | 87 | if (extName.toLowerCase() == ".jpg" || extName.toLowerCase() == ".jpeg") { 88 | useJPG(buffer) 89 | } else if (extName.toLowerCase() == ".png") { 90 | usePNG(buffer); 91 | } 92 | 93 | let heapSpace = Module._malloc(imageData.array.length * imageData.array.BYTES_PER_ELEMENT); 94 | Module.HEAPU8.set(imageData.array, heapSpace); 95 | Module._createImageSet(heapSpace, imageData.dpi, imageData.sizeX, imageData.sizeY, imageData.nc, fileName, params.length, params) 96 | Module._free(heapSpace); 97 | 98 | let filenameIset = "asa.iset"; 99 | let filenameFset = "asa.fset"; 100 | let filenameFset3 = "asa.fset3"; 101 | 102 | let ext = ".iset"; 103 | let ext2 = ".fset"; 104 | let ext3 = ".fset3"; 105 | 106 | let content = Module.FS.readFile(filenameIset); 107 | let contentFset = Module.FS.readFile(filenameFset); 108 | let contentFset3 = Module.FS.readFile(filenameFset3); 109 | 110 | fs.writeFileSync(path.join(__dirname, '/output/') + fileName + ext, content); 111 | fs.writeFileSync(path.join(__dirname, '/output/') + fileName + ext2, contentFset); 112 | fs.writeFileSync(path.join(__dirname, '/output/') + fileName + ext3, contentFset3); 113 | 114 | let confidence = calculateQuality(); 115 | 116 | let txt = " - - - - - "; 117 | if(confidence.l != 0){ 118 | let str = txt.split(" "); 119 | str.pop(); 120 | str.shift(); 121 | for(let i = 0; i < parseInt(confidence.l); i++){ 122 | str[i] = " *"; 123 | } 124 | str.push(" "); 125 | txt = str.join(""); 126 | } 127 | console.log("Confidence level: [" + txt + "] %f/5 || Entropy: %f || Current max: 5.17 min: 4.6", confidence.l, confidence.e) 128 | } 129 | 130 | function useJPG(buf) { 131 | inkjet.decode(buf, function (err, decoded) { 132 | if (err) { 133 | console.log("\n" + err + "\n"); 134 | process.exit(1); 135 | } else { 136 | let newArr = []; 137 | 138 | let verifyColorSpace = detectColorSpace(decoded.data); 139 | 140 | if (verifyColorSpace == 1) { 141 | for (let j = 0; j < decoded.data.length; j += 4) { 142 | newArr.push(decoded.data[j]); 143 | } 144 | } else if (verifyColorSpace == 3) { 145 | for (let j = 0; j < decoded.data.length; j += 4) { 146 | newArr.push(decoded.data[j]); 147 | newArr.push(decoded.data[j + 1]); 148 | newArr.push(decoded.data[j + 2]); 149 | } 150 | } 151 | 152 | let uint = new Uint8Array(newArr); 153 | imageData.nc = verifyColorSpace; 154 | imageData.array = uint; 155 | } 156 | }); 157 | 158 | inkjet.exif(buf, function (err, metadata) { 159 | if (err) { 160 | console.log("\n" + err + "\n"); 161 | process.exit(1); 162 | } else { 163 | if (metadata == null || metadata == undefined || metadata.length == undefined) { 164 | var answer = readlineSync.question('The EXIF info of this image is empty or it does not exist. Do you want to inform its properties manually?[y/n]\n'); 165 | 166 | if (answer == "y") { 167 | var answerWH = readlineSync.question('Inform the width and height: e.g W=200 H=400\n'); 168 | 169 | let valWH = getValues(answerWH, "wh"); 170 | imageData.sizeX = valWH.w; 171 | imageData.sizeY = valWH.h; 172 | 173 | // var answerNC = readlineSync.question('Inform the number of channels(nc):(black and white images have NC=1, colored images have NC=3) e.g NC=3 \n'); 174 | 175 | // let valNC = getValues(answerNC, "nc"); 176 | // imageData.nc = valNC; 177 | 178 | var answerDPI = readlineSync.question('Inform the DPI: e.g DPI=220 [Default = 72](Press enter to use default)\n'); 179 | 180 | if (answerDPI == "") { 181 | imageData.dpi = 72; 182 | } else { 183 | let val = getValues(answerDPI, "dpi"); 184 | imageData.dpi = val; 185 | } 186 | } else { 187 | console.log("Exiting process!") 188 | process.exit(1); 189 | } 190 | } else { 191 | let dpi = Math.min(parseInt(metadata.XResolution.value), parseInt(metadata.YResolution.value)); 192 | if (dpi == null || dpi == undefined || dpi == NaN) { 193 | console.log("\nWARNING: No DPI value found! Using 72 as default value!\n") 194 | dpi = 72; 195 | } 196 | 197 | if (metadata.ImageWidth == null || metadata.ImageWidth == undefined) { 198 | if (metadata.PixelXDimension == null || metadata.PixelXDimension == undefined) { 199 | var answer = readlineSync.question('The image does not contain any width or height info, do you want to inform them?[y/n]\n'); 200 | if (answer == "y") { 201 | var answer2 = readlineSync.question('Inform the width and height: e.g W=200 H=400\n'); 202 | 203 | let vals = getValues(answer2, "wh"); 204 | imageData.sizeX = vals.w; 205 | imageData.sizeY = vals.h; 206 | } else { 207 | console.log("It's not possible to proceed without width or height info!") 208 | process.exit(1); 209 | } 210 | } else { 211 | imageData.sizeX = metadata.PixelXDimension.value; 212 | imageData.sizeY = metadata.PixelYDimension.value; 213 | } 214 | } else { 215 | imageData.sizeX = metadata.ImageWidth.value; 216 | imageData.sizeY = metadata.ImageLength.value; 217 | } 218 | 219 | if (metadata.SamplesPerPixel == null || metadata.ImageWidth == undefined) { 220 | // var answer = readlineSync.question('The image does not contain the number of channels(nc), do you want to inform it?[y/n]\n'); 221 | 222 | // if(answer == "y"){ 223 | // var answer2 = readlineSync.question('Inform the number of channels(nc):(black and white images have NC=1, colored images have NC=3) e.g NC=3 \n'); 224 | 225 | // let vals = getValues(answer2, "nc"); 226 | // imageData.nc = vals; 227 | // }else{ 228 | // console.log("It's not possible to proceed without the number of channels!") 229 | // process.exit(1); 230 | // } 231 | } else { 232 | imageData.nc = metadata.SamplesPerPixel.value; 233 | } 234 | imageData.dpi = dpi; 235 | } 236 | } 237 | }); 238 | } 239 | 240 | function usePNG(buf) { 241 | let data; 242 | var png = PNG.sync.read(buf); 243 | 244 | var arrByte = new Uint8Array(png.data); 245 | if (png.alpha) { 246 | data = rgbaToRgb(arrByte); 247 | } else { 248 | data = arrByte; 249 | } 250 | 251 | let newArr = []; 252 | 253 | let verifyColorSpace = detectColorSpace(data); 254 | 255 | if (verifyColorSpace == 1) { 256 | for (let j = 0; j < data.length; j += 4) { 257 | newArr.push(data[j]); 258 | } 259 | } else if (verifyColorSpace == 3) { 260 | for (let j = 0; j < data.length; j += 4) { 261 | newArr.push(data[j]); 262 | newArr.push(data[j + 1]); 263 | newArr.push(data[j + 2]); 264 | } 265 | } 266 | 267 | let uint = new Uint8Array(newArr); 268 | 269 | imageData.array = uint; 270 | imageData.nc = verifyColorSpace; 271 | imageData.sizeX = png.width; 272 | imageData.sizeY = png.height; 273 | imageData.dpi = 72; 274 | } 275 | 276 | function getValues(str, type) { 277 | let values; 278 | if (type == "wh") { 279 | let Wstr = "W="; 280 | let Hstr = "H="; 281 | var doesContainW = str.indexOf(Wstr); 282 | var doesContainH = str.indexOf(Hstr); 283 | 284 | let valW = parseInt(str.slice(doesContainW + 2, doesContainH)); 285 | let valH = parseInt(str.slice(doesContainH + 2)); 286 | 287 | values = { 288 | w: valW, 289 | h: valH 290 | } 291 | } else if (type == "nc") { 292 | let nc = "NC="; 293 | var doesContainNC = str.indexOf(nc); 294 | values = parseInt(str.slice(doesContainNC + 3)); 295 | } else if (type == "dpi") { 296 | let dpi = "DPI="; 297 | var doesContainDPI = str.indexOf(dpi); 298 | values = parseInt(str.slice(doesContainDPI + 4)); 299 | } 300 | 301 | return values; 302 | } 303 | 304 | function detectColorSpace(arr) { 305 | let target = parseInt(arr.length / 4); 306 | 307 | let counter = 0; 308 | 309 | for (let j = 0; j < arr.length; j += 4) { 310 | let r = arr[j]; 311 | let g = arr[j + 1]; 312 | let b = arr[j + 2]; 313 | 314 | if (r == g && r == b) { 315 | counter++; 316 | } 317 | } 318 | 319 | if (target == counter) { 320 | return 1; 321 | } else { 322 | return 3; 323 | } 324 | } 325 | 326 | function rgbaToRgb(arr) { 327 | let newArr = []; 328 | let BGColor = { 329 | R: 255, 330 | G: 255, 331 | B: 255 332 | } 333 | 334 | for (let i = 0; i < arr.length; i += 4) { 335 | 336 | let r = parseInt(255 * (((1 - arr[i + 3]) * BGColor.R) + (arr[i + 3] * arr[i]))); 337 | let g = parseInt(255 * (((1 - arr[i + 3]) * BGColor.G) + (arr[i + 3] * arr[i + 1]))); 338 | let b = parseInt(255 * (((1 - arr[i + 3]) * BGColor.B) + (arr[i + 3] * arr[i + 2]))); 339 | 340 | newArr.push(r); 341 | newArr.push(g); 342 | newArr.push(b); 343 | } 344 | return newArr; 345 | } 346 | 347 | function calculateQuality(){ 348 | let gray = toGrayscale(imageData.array); 349 | let hist = getHistogram(gray); 350 | let ent = 0; 351 | let totSize = imageData.sizeX * imageData.sizeY; 352 | for(let i = 0; i < 255; i++){ 353 | if(hist[i] > 0){ 354 | let temp = (hist[i]/totSize)*(Math.log(hist[i]/totSize)); 355 | ent += temp; 356 | } 357 | } 358 | 359 | let entropy = (-1 * ent).toFixed(2); 360 | let oldRange = (5.17 - 4.6); 361 | let newRange = (5 - 0); 362 | let level = (((entropy - 4.6) * newRange) / oldRange); 363 | 364 | if(level > 5){ 365 | level = 5; 366 | }else if(level < 0){ 367 | level = 0; 368 | } 369 | return {l:level.toFixed(2), e: entropy}; 370 | } 371 | 372 | function toGrayscale(arr){ 373 | let gray = []; 374 | for(let i = 0; i < arr.length; i+=3){ 375 | let avg = (arr[i] + arr[i+1] + arr[i+2])/3; 376 | gray.push(parseInt(avg)); 377 | } 378 | return gray; 379 | } 380 | 381 | function getHistogram(arr){ 382 | let hist = [256]; 383 | for(let i = 0; i < arr.length; i++){ 384 | hist[i] = 0; 385 | } 386 | for(let i = 0; i < arr.length; i++){ 387 | hist[arr[i]]++; 388 | } 389 | return hist; 390 | } 391 | -------------------------------------------------------------------------------- /docs/exif.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var debug = false; 4 | 5 | var root = this; 6 | 7 | var EXIF = function(obj) { 8 | if (obj instanceof EXIF) return obj; 9 | if (!(this instanceof EXIF)) return new EXIF(obj); 10 | this.EXIFwrapped = obj; 11 | }; 12 | 13 | if (typeof exports !== 'undefined') { 14 | if (typeof module !== 'undefined' && module.exports) { 15 | exports = module.exports = EXIF; 16 | } 17 | exports.EXIF = EXIF; 18 | } else { 19 | root.EXIF = EXIF; 20 | } 21 | 22 | var ExifTags = EXIF.Tags = { 23 | 24 | // version tags 25 | 0x9000 : "ExifVersion", // EXIF version 26 | 0xA000 : "FlashpixVersion", // Flashpix format version 27 | 28 | // colorspace tags 29 | 0xA001 : "ColorSpace", // Color space information tag 30 | 31 | // image configuration 32 | 0xA002 : "PixelXDimension", // Valid width of meaningful image 33 | 0xA003 : "PixelYDimension", // Valid height of meaningful image 34 | 0x9101 : "ComponentsConfiguration", // Information about channels 35 | 0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel 36 | 37 | // user information 38 | 0x927C : "MakerNote", // Any desired information written by the manufacturer 39 | 0x9286 : "UserComment", // Comments by user 40 | 41 | // related file 42 | 0xA004 : "RelatedSoundFile", // Name of related sound file 43 | 44 | // date and time 45 | 0x9003 : "DateTimeOriginal", // Date and time when the original image was generated 46 | 0x9004 : "DateTimeDigitized", // Date and time when the image was stored digitally 47 | 0x9290 : "SubsecTime", // Fractions of seconds for DateTime 48 | 0x9291 : "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal 49 | 0x9292 : "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized 50 | 51 | // picture-taking conditions 52 | 0x829A : "ExposureTime", // Exposure time (in seconds) 53 | 0x829D : "FNumber", // F number 54 | 0x8822 : "ExposureProgram", // Exposure program 55 | 0x8824 : "SpectralSensitivity", // Spectral sensitivity 56 | 0x8827 : "ISOSpeedRatings", // ISO speed rating 57 | 0x8828 : "OECF", // Optoelectric conversion factor 58 | 0x9201 : "ShutterSpeedValue", // Shutter speed 59 | 0x9202 : "ApertureValue", // Lens aperture 60 | 0x9203 : "BrightnessValue", // Value of brightness 61 | 0x9204 : "ExposureBias", // Exposure bias 62 | 0x9205 : "MaxApertureValue", // Smallest F number of lens 63 | 0x9206 : "SubjectDistance", // Distance to subject in meters 64 | 0x9207 : "MeteringMode", // Metering mode 65 | 0x9208 : "LightSource", // Kind of light source 66 | 0x9209 : "Flash", // Flash status 67 | 0x9214 : "SubjectArea", // Location and area of main subject 68 | 0x920A : "FocalLength", // Focal length of the lens in mm 69 | 0xA20B : "FlashEnergy", // Strobe energy in BCPS 70 | 0xA20C : "SpatialFrequencyResponse", // 71 | 0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit 72 | 0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit 73 | 0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution 74 | 0xA214 : "SubjectLocation", // Location of subject in image 75 | 0xA215 : "ExposureIndex", // Exposure index selected on camera 76 | 0xA217 : "SensingMethod", // Image sensor type 77 | 0xA300 : "FileSource", // Image source (3 == DSC) 78 | 0xA301 : "SceneType", // Scene type (1 == directly photographed) 79 | 0xA302 : "CFAPattern", // Color filter array geometric pattern 80 | 0xA401 : "CustomRendered", // Special processing 81 | 0xA402 : "ExposureMode", // Exposure mode 82 | 0xA403 : "WhiteBalance", // 1 = auto white balance, 2 = manual 83 | 0xA404 : "DigitalZoomRation", // Digital zoom ratio 84 | 0xA405 : "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm) 85 | 0xA406 : "SceneCaptureType", // Type of scene 86 | 0xA407 : "GainControl", // Degree of overall image gain adjustment 87 | 0xA408 : "Contrast", // Direction of contrast processing applied by camera 88 | 0xA409 : "Saturation", // Direction of saturation processing applied by camera 89 | 0xA40A : "Sharpness", // Direction of sharpness processing applied by camera 90 | 0xA40B : "DeviceSettingDescription", // 91 | 0xA40C : "SubjectDistanceRange", // Distance to subject 92 | 93 | // other tags 94 | 0xA005 : "InteroperabilityIFDPointer", 95 | 0xA420 : "ImageUniqueID" // Identifier assigned uniquely to each image 96 | }; 97 | 98 | var TiffTags = EXIF.TiffTags = { 99 | 0x0100 : "ImageWidth", 100 | 0x0101 : "ImageHeight", 101 | 0x8769 : "ExifIFDPointer", 102 | 0x8825 : "GPSInfoIFDPointer", 103 | 0xA005 : "InteroperabilityIFDPointer", 104 | 0x0102 : "BitsPerSample", 105 | 0x0103 : "Compression", 106 | 0x0106 : "PhotometricInterpretation", 107 | 0x0112 : "Orientation", 108 | 0x0115 : "SamplesPerPixel", 109 | 0x011C : "PlanarConfiguration", 110 | 0x0212 : "YCbCrSubSampling", 111 | 0x0213 : "YCbCrPositioning", 112 | 0x011A : "XResolution", 113 | 0x011B : "YResolution", 114 | 0x0128 : "ResolutionUnit", 115 | 0x0111 : "StripOffsets", 116 | 0x0116 : "RowsPerStrip", 117 | 0x0117 : "StripByteCounts", 118 | 0x0201 : "JPEGInterchangeFormat", 119 | 0x0202 : "JPEGInterchangeFormatLength", 120 | 0x012D : "TransferFunction", 121 | 0x013E : "WhitePoint", 122 | 0x013F : "PrimaryChromaticities", 123 | 0x0211 : "YCbCrCoefficients", 124 | 0x0214 : "ReferenceBlackWhite", 125 | 0x0132 : "DateTime", 126 | 0x010E : "ImageDescription", 127 | 0x010F : "Make", 128 | 0x0110 : "Model", 129 | 0x0131 : "Software", 130 | 0x013B : "Artist", 131 | 0x8298 : "Copyright" 132 | }; 133 | 134 | var GPSTags = EXIF.GPSTags = { 135 | 0x0000 : "GPSVersionID", 136 | 0x0001 : "GPSLatitudeRef", 137 | 0x0002 : "GPSLatitude", 138 | 0x0003 : "GPSLongitudeRef", 139 | 0x0004 : "GPSLongitude", 140 | 0x0005 : "GPSAltitudeRef", 141 | 0x0006 : "GPSAltitude", 142 | 0x0007 : "GPSTimeStamp", 143 | 0x0008 : "GPSSatellites", 144 | 0x0009 : "GPSStatus", 145 | 0x000A : "GPSMeasureMode", 146 | 0x000B : "GPSDOP", 147 | 0x000C : "GPSSpeedRef", 148 | 0x000D : "GPSSpeed", 149 | 0x000E : "GPSTrackRef", 150 | 0x000F : "GPSTrack", 151 | 0x0010 : "GPSImgDirectionRef", 152 | 0x0011 : "GPSImgDirection", 153 | 0x0012 : "GPSMapDatum", 154 | 0x0013 : "GPSDestLatitudeRef", 155 | 0x0014 : "GPSDestLatitude", 156 | 0x0015 : "GPSDestLongitudeRef", 157 | 0x0016 : "GPSDestLongitude", 158 | 0x0017 : "GPSDestBearingRef", 159 | 0x0018 : "GPSDestBearing", 160 | 0x0019 : "GPSDestDistanceRef", 161 | 0x001A : "GPSDestDistance", 162 | 0x001B : "GPSProcessingMethod", 163 | 0x001C : "GPSAreaInformation", 164 | 0x001D : "GPSDateStamp", 165 | 0x001E : "GPSDifferential" 166 | }; 167 | 168 | // EXIF 2.3 Spec 169 | var IFD1Tags = EXIF.IFD1Tags = { 170 | 0x0100: "ImageWidth", 171 | 0x0101: "ImageHeight", 172 | 0x0102: "BitsPerSample", 173 | 0x0103: "Compression", 174 | 0x0106: "PhotometricInterpretation", 175 | 0x0111: "StripOffsets", 176 | 0x0112: "Orientation", 177 | 0x0115: "SamplesPerPixel", 178 | 0x0116: "RowsPerStrip", 179 | 0x0117: "StripByteCounts", 180 | 0x011A: "XResolution", 181 | 0x011B: "YResolution", 182 | 0x011C: "PlanarConfiguration", 183 | 0x0128: "ResolutionUnit", 184 | 0x0201: "JpegIFOffset", // When image format is JPEG, this value show offset to JPEG data stored.(aka "ThumbnailOffset" or "JPEGInterchangeFormat") 185 | 0x0202: "JpegIFByteCount", // When image format is JPEG, this value shows data size of JPEG image (aka "ThumbnailLength" or "JPEGInterchangeFormatLength") 186 | 0x0211: "YCbCrCoefficients", 187 | 0x0212: "YCbCrSubSampling", 188 | 0x0213: "YCbCrPositioning", 189 | 0x0214: "ReferenceBlackWhite" 190 | }; 191 | 192 | var StringValues = EXIF.StringValues = { 193 | ExposureProgram : { 194 | 0 : "Not defined", 195 | 1 : "Manual", 196 | 2 : "Normal program", 197 | 3 : "Aperture priority", 198 | 4 : "Shutter priority", 199 | 5 : "Creative program", 200 | 6 : "Action program", 201 | 7 : "Portrait mode", 202 | 8 : "Landscape mode" 203 | }, 204 | MeteringMode : { 205 | 0 : "Unknown", 206 | 1 : "Average", 207 | 2 : "CenterWeightedAverage", 208 | 3 : "Spot", 209 | 4 : "MultiSpot", 210 | 5 : "Pattern", 211 | 6 : "Partial", 212 | 255 : "Other" 213 | }, 214 | LightSource : { 215 | 0 : "Unknown", 216 | 1 : "Daylight", 217 | 2 : "Fluorescent", 218 | 3 : "Tungsten (incandescent light)", 219 | 4 : "Flash", 220 | 9 : "Fine weather", 221 | 10 : "Cloudy weather", 222 | 11 : "Shade", 223 | 12 : "Daylight fluorescent (D 5700 - 7100K)", 224 | 13 : "Day white fluorescent (N 4600 - 5400K)", 225 | 14 : "Cool white fluorescent (W 3900 - 4500K)", 226 | 15 : "White fluorescent (WW 3200 - 3700K)", 227 | 17 : "Standard light A", 228 | 18 : "Standard light B", 229 | 19 : "Standard light C", 230 | 20 : "D55", 231 | 21 : "D65", 232 | 22 : "D75", 233 | 23 : "D50", 234 | 24 : "ISO studio tungsten", 235 | 255 : "Other" 236 | }, 237 | Flash : { 238 | 0x0000 : "Flash did not fire", 239 | 0x0001 : "Flash fired", 240 | 0x0005 : "Strobe return light not detected", 241 | 0x0007 : "Strobe return light detected", 242 | 0x0009 : "Flash fired, compulsory flash mode", 243 | 0x000D : "Flash fired, compulsory flash mode, return light not detected", 244 | 0x000F : "Flash fired, compulsory flash mode, return light detected", 245 | 0x0010 : "Flash did not fire, compulsory flash mode", 246 | 0x0018 : "Flash did not fire, auto mode", 247 | 0x0019 : "Flash fired, auto mode", 248 | 0x001D : "Flash fired, auto mode, return light not detected", 249 | 0x001F : "Flash fired, auto mode, return light detected", 250 | 0x0020 : "No flash function", 251 | 0x0041 : "Flash fired, red-eye reduction mode", 252 | 0x0045 : "Flash fired, red-eye reduction mode, return light not detected", 253 | 0x0047 : "Flash fired, red-eye reduction mode, return light detected", 254 | 0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode", 255 | 0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", 256 | 0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", 257 | 0x0059 : "Flash fired, auto mode, red-eye reduction mode", 258 | 0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode", 259 | 0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode" 260 | }, 261 | SensingMethod : { 262 | 1 : "Not defined", 263 | 2 : "One-chip color area sensor", 264 | 3 : "Two-chip color area sensor", 265 | 4 : "Three-chip color area sensor", 266 | 5 : "Color sequential area sensor", 267 | 7 : "Trilinear sensor", 268 | 8 : "Color sequential linear sensor" 269 | }, 270 | SceneCaptureType : { 271 | 0 : "Standard", 272 | 1 : "Landscape", 273 | 2 : "Portrait", 274 | 3 : "Night scene" 275 | }, 276 | SceneType : { 277 | 1 : "Directly photographed" 278 | }, 279 | CustomRendered : { 280 | 0 : "Normal process", 281 | 1 : "Custom process" 282 | }, 283 | WhiteBalance : { 284 | 0 : "Auto white balance", 285 | 1 : "Manual white balance" 286 | }, 287 | GainControl : { 288 | 0 : "None", 289 | 1 : "Low gain up", 290 | 2 : "High gain up", 291 | 3 : "Low gain down", 292 | 4 : "High gain down" 293 | }, 294 | Contrast : { 295 | 0 : "Normal", 296 | 1 : "Soft", 297 | 2 : "Hard" 298 | }, 299 | Saturation : { 300 | 0 : "Normal", 301 | 1 : "Low saturation", 302 | 2 : "High saturation" 303 | }, 304 | Sharpness : { 305 | 0 : "Normal", 306 | 1 : "Soft", 307 | 2 : "Hard" 308 | }, 309 | SubjectDistanceRange : { 310 | 0 : "Unknown", 311 | 1 : "Macro", 312 | 2 : "Close view", 313 | 3 : "Distant view" 314 | }, 315 | FileSource : { 316 | 3 : "DSC" 317 | }, 318 | 319 | Components : { 320 | 0 : "", 321 | 1 : "Y", 322 | 2 : "Cb", 323 | 3 : "Cr", 324 | 4 : "R", 325 | 5 : "G", 326 | 6 : "B" 327 | } 328 | }; 329 | 330 | function addEvent(element, event, handler) { 331 | if (element.addEventListener) { 332 | element.addEventListener(event, handler, false); 333 | } else if (element.attachEvent) { 334 | element.attachEvent("on" + event, handler); 335 | } 336 | } 337 | 338 | function imageHasData(img) { 339 | return !!(img.exifdata); 340 | } 341 | 342 | 343 | function base64ToArrayBuffer(base64, contentType) { 344 | contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg' 345 | base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, ''); 346 | var binary = atob(base64); 347 | var len = binary.length; 348 | var buffer = new ArrayBuffer(len); 349 | var view = new Uint8Array(buffer); 350 | for (var i = 0; i < len; i++) { 351 | view[i] = binary.charCodeAt(i); 352 | } 353 | return buffer; 354 | } 355 | 356 | function objectURLToBlob(url, callback) { 357 | var http = new XMLHttpRequest(); 358 | http.open("GET", url, true); 359 | http.responseType = "blob"; 360 | http.onload = function(e) { 361 | if (this.status == 200 || this.status === 0) { 362 | callback(this.response); 363 | } 364 | }; 365 | http.send(); 366 | } 367 | 368 | function getImageData(img, callback) { 369 | function handleBinaryFile(binFile) { 370 | var data = findEXIFinJPEG(binFile); 371 | img.exifdata = data || {}; 372 | var iptcdata = findIPTCinJPEG(binFile); 373 | img.iptcdata = iptcdata || {}; 374 | if (EXIF.isXmpEnabled) { 375 | var xmpdata= findXMPinJPEG(binFile); 376 | img.xmpdata = xmpdata || {}; 377 | } 378 | if (callback) { 379 | callback.call(img); 380 | } 381 | } 382 | 383 | if (img.src) { 384 | if (/^data\:/i.test(img.src)) { // Data URI 385 | var arrayBuffer = base64ToArrayBuffer(img.src); 386 | handleBinaryFile(arrayBuffer); 387 | 388 | } else if (/^blob\:/i.test(img.src)) { // Object URL 389 | var fileReader = new FileReader(); 390 | fileReader.onload = function(e) { 391 | handleBinaryFile(e.target.result); 392 | }; 393 | objectURLToBlob(img.src, function (blob) { 394 | fileReader.readAsArrayBuffer(blob); 395 | }); 396 | } else { 397 | var http = new XMLHttpRequest(); 398 | http.onload = function() { 399 | if (this.status == 200 || this.status === 0) { 400 | handleBinaryFile(http.response); 401 | } else { 402 | throw "Could not load image"; 403 | } 404 | http = null; 405 | }; 406 | http.open("GET", img.src, true); 407 | http.responseType = "arraybuffer"; 408 | http.send(null); 409 | } 410 | } else if (self.FileReader && (img instanceof self.Blob || img instanceof self.File)) { 411 | var fileReader = new FileReader(); 412 | fileReader.onload = function(e) { 413 | if (debug) console.log("Got file of length " + e.target.result.byteLength); 414 | handleBinaryFile(e.target.result); 415 | }; 416 | 417 | fileReader.readAsArrayBuffer(img); 418 | } 419 | } 420 | 421 | function findEXIFinJPEG(file) { 422 | var dataView = new DataView(file); 423 | 424 | if (debug) console.log("Got file of length " + file.byteLength); 425 | if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { 426 | if (debug) console.log("Not a valid JPEG"); 427 | return false; // not a valid jpeg 428 | } 429 | 430 | var offset = 2, 431 | length = file.byteLength, 432 | marker; 433 | 434 | while (offset < length) { 435 | if (dataView.getUint8(offset) != 0xFF) { 436 | if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset)); 437 | return false; // not a valid marker, something is wrong 438 | } 439 | 440 | marker = dataView.getUint8(offset + 1); 441 | if (debug) console.log(marker); 442 | 443 | // we could implement handling for other markers here, 444 | // but we're only looking for 0xFFE1 for EXIF data 445 | 446 | if (marker == 225) { 447 | if (debug) console.log("Found 0xFFE1 marker"); 448 | 449 | return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2); 450 | 451 | // offset += 2 + file.getShortAt(offset+2, true); 452 | 453 | } else { 454 | offset += 2 + dataView.getUint16(offset+2); 455 | } 456 | 457 | } 458 | 459 | } 460 | 461 | function findIPTCinJPEG(file) { 462 | var dataView = new DataView(file); 463 | 464 | if (debug) console.log("Got file of length " + file.byteLength); 465 | if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { 466 | if (debug) console.log("Not a valid JPEG"); 467 | return false; // not a valid jpeg 468 | } 469 | 470 | var offset = 2, 471 | length = file.byteLength; 472 | 473 | 474 | var isFieldSegmentStart = function(dataView, offset){ 475 | return ( 476 | dataView.getUint8(offset) === 0x38 && 477 | dataView.getUint8(offset+1) === 0x42 && 478 | dataView.getUint8(offset+2) === 0x49 && 479 | dataView.getUint8(offset+3) === 0x4D && 480 | dataView.getUint8(offset+4) === 0x04 && 481 | dataView.getUint8(offset+5) === 0x04 482 | ); 483 | }; 484 | 485 | while (offset < length) { 486 | 487 | if ( isFieldSegmentStart(dataView, offset )){ 488 | 489 | // Get the length of the name header (which is padded to an even number of bytes) 490 | var nameHeaderLength = dataView.getUint8(offset+7); 491 | if(nameHeaderLength % 2 !== 0) nameHeaderLength += 1; 492 | // Check for pre photoshop 6 format 493 | if(nameHeaderLength === 0) { 494 | // Always 4 495 | nameHeaderLength = 4; 496 | } 497 | 498 | var startOffset = offset + 8 + nameHeaderLength; 499 | var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength); 500 | 501 | return readIPTCData(file, startOffset, sectionLength); 502 | 503 | break; 504 | 505 | } 506 | 507 | 508 | // Not the marker, continue searching 509 | offset++; 510 | 511 | } 512 | 513 | } 514 | var IptcFieldMap = { 515 | 0x78 : 'caption', 516 | 0x6E : 'credit', 517 | 0x19 : 'keywords', 518 | 0x37 : 'dateCreated', 519 | 0x50 : 'byline', 520 | 0x55 : 'bylineTitle', 521 | 0x7A : 'captionWriter', 522 | 0x69 : 'headline', 523 | 0x74 : 'copyright', 524 | 0x0F : 'category' 525 | }; 526 | function readIPTCData(file, startOffset, sectionLength){ 527 | var dataView = new DataView(file); 528 | var data = {}; 529 | var fieldValue, fieldName, dataSize, segmentType, segmentSize; 530 | var segmentStartPos = startOffset; 531 | while(segmentStartPos < startOffset+sectionLength) { 532 | if(dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos+1) === 0x02){ 533 | segmentType = dataView.getUint8(segmentStartPos+2); 534 | if(segmentType in IptcFieldMap) { 535 | dataSize = dataView.getInt16(segmentStartPos+3); 536 | segmentSize = dataSize + 5; 537 | fieldName = IptcFieldMap[segmentType]; 538 | fieldValue = getStringFromDB(dataView, segmentStartPos+5, dataSize); 539 | // Check if we already stored a value with this name 540 | if(data.hasOwnProperty(fieldName)) { 541 | // Value already stored with this name, create multivalue field 542 | if(data[fieldName] instanceof Array) { 543 | data[fieldName].push(fieldValue); 544 | } 545 | else { 546 | data[fieldName] = [data[fieldName], fieldValue]; 547 | } 548 | } 549 | else { 550 | data[fieldName] = fieldValue; 551 | } 552 | } 553 | 554 | } 555 | segmentStartPos++; 556 | } 557 | return data; 558 | } 559 | 560 | 561 | 562 | function readTags(file, tiffStart, dirStart, strings, bigEnd) { 563 | var entries = file.getUint16(dirStart, !bigEnd), 564 | tags = {}, 565 | entryOffset, tag, 566 | i; 567 | 568 | for (i=0;i 4 ? valueOffset : (entryOffset + 8); 593 | vals = []; 594 | for (n=0;n 4 ? valueOffset : (entryOffset + 8); 602 | return getStringFromDB(file, offset, numValues-1); 603 | 604 | case 3: // short, 16 bit int 605 | if (numValues == 1) { 606 | return file.getUint16(entryOffset + 8, !bigEnd); 607 | } else { 608 | offset = numValues > 2 ? valueOffset : (entryOffset + 8); 609 | vals = []; 610 | for (n=0;n dataView.byteLength) { // this should not happen 695 | // console.log('******** IFD1Offset is outside the bounds of the DataView ********'); 696 | return {}; 697 | } 698 | // console.log('******* thumbnail IFD offset (IFD1) is: %s', IFD1OffsetPointer); 699 | 700 | var thumbTags = readTags(dataView, tiffStart, tiffStart + IFD1OffsetPointer, IFD1Tags, bigEnd) 701 | 702 | // EXIF 2.3 specification for JPEG format thumbnail 703 | 704 | // If the value of Compression(0x0103) Tag in IFD1 is '6', thumbnail image format is JPEG. 705 | // Most of Exif image uses JPEG format for thumbnail. In that case, you can get offset of thumbnail 706 | // by JpegIFOffset(0x0201) Tag in IFD1, size of thumbnail by JpegIFByteCount(0x0202) Tag. 707 | // Data format is ordinary JPEG format, starts from 0xFFD8 and ends by 0xFFD9. It seems that 708 | // JPEG format and 160x120pixels of size are recommended thumbnail format for Exif2.1 or later. 709 | 710 | if (thumbTags['Compression']) { 711 | // console.log('Thumbnail image found!'); 712 | 713 | switch (thumbTags['Compression']) { 714 | case 6: 715 | // console.log('Thumbnail image format is JPEG'); 716 | if (thumbTags.JpegIFOffset && thumbTags.JpegIFByteCount) { 717 | // extract the thumbnail 718 | var tOffset = tiffStart + thumbTags.JpegIFOffset; 719 | var tLength = thumbTags.JpegIFByteCount; 720 | thumbTags['blob'] = new Blob([new Uint8Array(dataView.buffer, tOffset, tLength)], { 721 | type: 'image/jpeg' 722 | }); 723 | } 724 | break; 725 | 726 | case 1: 727 | console.log("Thumbnail image format is TIFF, which is not implemented."); 728 | break; 729 | default: 730 | console.log("Unknown thumbnail image format '%s'", thumbTags['Compression']); 731 | } 732 | } 733 | else if (thumbTags['PhotometricInterpretation'] == 2) { 734 | console.log("Thumbnail image format is RGB, which is not implemented."); 735 | } 736 | return thumbTags; 737 | } 738 | 739 | function getStringFromDB(buffer, start, length) { 740 | var outstr = ""; 741 | for (var n = start; n < start+length; n++) { 742 | outstr += String.fromCharCode(buffer.getUint8(n)); 743 | } 744 | return outstr; 745 | } 746 | 747 | function readEXIFData(file, start) { 748 | if (getStringFromDB(file, start, 4) != "Exif") { 749 | if (debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4)); 750 | return false; 751 | } 752 | 753 | var bigEnd, 754 | tags, tag, 755 | exifData, gpsData, 756 | tiffOffset = start + 6; 757 | 758 | // test for TIFF validity and endianness 759 | if (file.getUint16(tiffOffset) == 0x4949) { 760 | bigEnd = false; 761 | } else if (file.getUint16(tiffOffset) == 0x4D4D) { 762 | bigEnd = true; 763 | } else { 764 | if (debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"); 765 | return false; 766 | } 767 | 768 | if (file.getUint16(tiffOffset+2, !bigEnd) != 0x002A) { 769 | if (debug) console.log("Not valid TIFF data! (no 0x002A)"); 770 | return false; 771 | } 772 | 773 | var firstIFDOffset = file.getUint32(tiffOffset+4, !bigEnd); 774 | 775 | if (firstIFDOffset < 0x00000008) { 776 | if (debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset+4, !bigEnd)); 777 | return false; 778 | } 779 | 780 | tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd); 781 | 782 | if (tags.ExifIFDPointer) { 783 | exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd); 784 | for (tag in exifData) { 785 | switch (tag) { 786 | case "LightSource" : 787 | case "Flash" : 788 | case "MeteringMode" : 789 | case "ExposureProgram" : 790 | case "SensingMethod" : 791 | case "SceneCaptureType" : 792 | case "SceneType" : 793 | case "CustomRendered" : 794 | case "WhiteBalance" : 795 | case "GainControl" : 796 | case "Contrast" : 797 | case "Saturation" : 798 | case "Sharpness" : 799 | case "SubjectDistanceRange" : 800 | case "FileSource" : 801 | exifData[tag] = StringValues[tag][exifData[tag]]; 802 | break; 803 | 804 | case "ExifVersion" : 805 | case "FlashpixVersion" : 806 | exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]); 807 | break; 808 | 809 | case "ComponentsConfiguration" : 810 | exifData[tag] = 811 | StringValues.Components[exifData[tag][0]] + 812 | StringValues.Components[exifData[tag][1]] + 813 | StringValues.Components[exifData[tag][2]] + 814 | StringValues.Components[exifData[tag][3]]; 815 | break; 816 | } 817 | tags[tag] = exifData[tag]; 818 | } 819 | } 820 | 821 | if (tags.GPSInfoIFDPointer) { 822 | gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd); 823 | for (tag in gpsData) { 824 | switch (tag) { 825 | case "GPSVersionID" : 826 | gpsData[tag] = gpsData[tag][0] + 827 | "." + gpsData[tag][1] + 828 | "." + gpsData[tag][2] + 829 | "." + gpsData[tag][3]; 830 | break; 831 | } 832 | tags[tag] = gpsData[tag]; 833 | } 834 | } 835 | 836 | // extract thumbnail 837 | tags['thumbnail'] = readThumbnailImage(file, tiffOffset, firstIFDOffset, bigEnd); 838 | 839 | return tags; 840 | } 841 | 842 | function findXMPinJPEG(file) { 843 | 844 | if (!('DOMParser' in self)) { 845 | // console.warn('XML parsing not supported without DOMParser'); 846 | return; 847 | } 848 | var dataView = new DataView(file); 849 | 850 | if (debug) console.log("Got file of length " + file.byteLength); 851 | if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { 852 | if (debug) console.log("Not a valid JPEG"); 853 | return false; // not a valid jpeg 854 | } 855 | 856 | var offset = 2, 857 | length = file.byteLength, 858 | dom = new DOMParser(); 859 | 860 | while (offset < (length-4)) { 861 | if (getStringFromDB(dataView, offset, 4) == "http") { 862 | var startOffset = offset - 1; 863 | var sectionLength = dataView.getUint16(offset - 2) - 1; 864 | var xmpString = getStringFromDB(dataView, startOffset, sectionLength) 865 | var xmpEndIndex = xmpString.indexOf('xmpmeta>') + 8; 866 | xmpString = xmpString.substring( xmpString.indexOf( ' 0) { 898 | json['@attributes'] = {}; 899 | for (var j = 0; j < xml.attributes.length; j++) { 900 | var attribute = xml.attributes.item(j); 901 | json['@attributes'][attribute.nodeName] = attribute.nodeValue; 902 | } 903 | } 904 | } else if (xml.nodeType == 3) { // text node 905 | return xml.nodeValue; 906 | } 907 | 908 | // deal with children 909 | if (xml.hasChildNodes()) { 910 | for(var i = 0; i < xml.childNodes.length; i++) { 911 | var child = xml.childNodes.item(i); 912 | var nodeName = child.nodeName; 913 | if (json[nodeName] == null) { 914 | json[nodeName] = xml2json(child); 915 | } else { 916 | if (json[nodeName].push == null) { 917 | var old = json[nodeName]; 918 | json[nodeName] = []; 919 | json[nodeName].push(old); 920 | } 921 | json[nodeName].push(xml2json(child)); 922 | } 923 | } 924 | } 925 | 926 | return json; 927 | } 928 | 929 | function xml2Object(xml) { 930 | try { 931 | var obj = {}; 932 | if (xml.children.length > 0) { 933 | for (var i = 0; i < xml.children.length; i++) { 934 | var item = xml.children.item(i); 935 | var attributes = item.attributes; 936 | for(var idx in attributes) { 937 | var itemAtt = attributes[idx]; 938 | var dataKey = itemAtt.nodeName; 939 | var dataValue = itemAtt.nodeValue; 940 | 941 | if(dataKey !== undefined) { 942 | obj[dataKey] = dataValue; 943 | } 944 | } 945 | var nodeName = item.nodeName; 946 | 947 | if (typeof (obj[nodeName]) == "undefined") { 948 | obj[nodeName] = xml2json(item); 949 | } else { 950 | if (typeof (obj[nodeName].push) == "undefined") { 951 | var old = obj[nodeName]; 952 | 953 | obj[nodeName] = []; 954 | obj[nodeName].push(old); 955 | } 956 | obj[nodeName].push(xml2json(item)); 957 | } 958 | } 959 | } else { 960 | obj = xml.textContent; 961 | } 962 | return obj; 963 | } catch (e) { 964 | console.log(e.message); 965 | } 966 | } 967 | 968 | EXIF.enableXmp = function() { 969 | EXIF.isXmpEnabled = true; 970 | } 971 | 972 | EXIF.disableXmp = function() { 973 | EXIF.isXmpEnabled = false; 974 | } 975 | 976 | EXIF.getData = function(img, callback) { 977 | if (((self.Image && img instanceof self.Image) 978 | || (self.HTMLImageElement && img instanceof self.HTMLImageElement)) 979 | && !img.complete) 980 | return false; 981 | 982 | if (!imageHasData(img)) { 983 | getImageData(img, callback); 984 | } else { 985 | if (callback) { 986 | callback.call(img); 987 | } 988 | } 989 | return true; 990 | } 991 | 992 | EXIF.getTag = function(img, tag) { 993 | if (!imageHasData(img)) return; 994 | return img.exifdata[tag]; 995 | } 996 | 997 | EXIF.getIptcTag = function(img, tag) { 998 | if (!imageHasData(img)) return; 999 | return img.iptcdata[tag]; 1000 | } 1001 | 1002 | EXIF.getAllTags = function(img) { 1003 | if (!imageHasData(img)) return {}; 1004 | var a, 1005 | data = img.exifdata, 1006 | tags = {}; 1007 | for (a in data) { 1008 | if (data.hasOwnProperty(a)) { 1009 | tags[a] = data[a]; 1010 | } 1011 | } 1012 | return tags; 1013 | } 1014 | 1015 | EXIF.getAllIptcTags = function(img) { 1016 | if (!imageHasData(img)) return {}; 1017 | var a, 1018 | data = img.iptcdata, 1019 | tags = {}; 1020 | for (a in data) { 1021 | if (data.hasOwnProperty(a)) { 1022 | tags[a] = data[a]; 1023 | } 1024 | } 1025 | return tags; 1026 | } 1027 | 1028 | EXIF.pretty = function(img) { 1029 | if (!imageHasData(img)) return ""; 1030 | var a, 1031 | data = img.exifdata, 1032 | strPretty = ""; 1033 | for (a in data) { 1034 | if (data.hasOwnProperty(a)) { 1035 | if (typeof data[a] == "object") { 1036 | if (data[a] instanceof Number) { 1037 | strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a].denominator + "]\r\n"; 1038 | } else { 1039 | strPretty += a + " : [" + data[a].length + " values]\r\n"; 1040 | } 1041 | } else { 1042 | strPretty += a + " : " + data[a] + "\r\n"; 1043 | } 1044 | } 1045 | } 1046 | return strPretty; 1047 | } 1048 | 1049 | EXIF.readFromBinaryFile = function(file) { 1050 | return findEXIFinJPEG(file); 1051 | } 1052 | 1053 | if (typeof define === 'function' && define.amd) { 1054 | define('exif-js', [], function() { 1055 | return EXIF; 1056 | }); 1057 | } 1058 | }.call(this)); 1059 | -------------------------------------------------------------------------------- /libs/NftMarkerCreator_wasm.js: -------------------------------------------------------------------------------- 1 | var Module=typeof Module!=="undefined"?Module:{};var scope;if(typeof window!=="undefined"){scope=window}else if(typeof window=="undefined"){scope=global}else{scope=global}if(scope.artoolkit_wasm_url){var downloadWasm=function(url){return new Promise(function(resolve,reject){var wasmXHR=new XMLHttpRequest;wasmXHR.open("GET",url,true);wasmXHR.responseType="arraybuffer";wasmXHR.onload=function(){resolve(wasmXHR.response)};wasmXHR.onerror=function(){reject("error "+wasmXHR.status)};wasmXHR.send(null)})};var wasm=downloadWasm(scope.artoolkit_wasm_url);Module.instantiateWasm=function(imports,successCallback){console.log("instantiateWasm: instantiating synchronously");wasm.then(function(wasmBinary){console.log("wasm download finished, begin instantiating");var wasmInstantiate=WebAssembly.instantiate(new Uint8Array(wasmBinary),imports).then(function(output){console.log("wasm instantiation succeeded");successCallback(output.instance)}).catch(function(e){console.log("wasm instantiation failed! "+e)})});return{}}}var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_HAS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_HAS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_NODE=ENVIRONMENT_HAS_NODE&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)")}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){scriptDirectory=__dirname+"/";read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{throw new Error("environment detection error")}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(!Object.getOwnPropertyDescriptor(Module,"arguments"))Object.defineProperty(Module,"arguments",{configurable:true,get:function(){abort("Module.arguments has been replaced with plain arguments_")}});if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(!Object.getOwnPropertyDescriptor(Module,"thisProgram"))Object.defineProperty(Module,"thisProgram",{configurable:true,get:function(){abort("Module.thisProgram has been replaced with plain thisProgram")}});if(Module["quit"])quit_=Module["quit"];if(!Object.getOwnPropertyDescriptor(Module,"quit"))Object.defineProperty(Module,"quit",{configurable:true,get:function(){abort("Module.quit has been replaced with plain quit_")}});assert(typeof Module["memoryInitializerPrefixURL"]==="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]==="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]==="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]==="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["read"]==="undefined","Module.read option was removed (modify read_ in JS)");assert(typeof Module["readAsync"]==="undefined","Module.readAsync option was removed (modify readAsync in JS)");assert(typeof Module["readBinary"]==="undefined","Module.readBinary option was removed (modify readBinary in JS)");assert(typeof Module["setWindowTitle"]==="undefined","Module.setWindowTitle option was removed (modify setWindowTitle in JS)");if(!Object.getOwnPropertyDescriptor(Module,"read"))Object.defineProperty(Module,"read",{configurable:true,get:function(){abort("Module.read has been replaced with plain read_")}});if(!Object.getOwnPropertyDescriptor(Module,"readAsync"))Object.defineProperty(Module,"readAsync",{configurable:true,get:function(){abort("Module.readAsync has been replaced with plain readAsync")}});if(!Object.getOwnPropertyDescriptor(Module,"readBinary"))Object.defineProperty(Module,"readBinary",{configurable:true,get:function(){abort("Module.readBinary has been replaced with plain readBinary")}});stackSave=stackRestore=stackAlloc=function(){abort("cannot use the stack before compiled code is ready to run, and has provided stack access")};function dynamicAlloc(size){assert(DYNAMICTOP_PTR);var ret=HEAP32[DYNAMICTOP_PTR>>2];var end=ret+size+15&-16;if(end>_emscripten_get_heap_size()){abort("failure to dynamicAlloc - memory growth etc. is not supported there, call malloc/sbrk directly")}HEAP32[DYNAMICTOP_PTR>>2]=end;return ret}function getNativeTypeSize(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return 4}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0,"getNativeTypeSize invalid bits "+bits+", type "+type);return bits/8}else{return 0}}}}function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}var asm2wasmImports={"f64-rem":function(x,y){return x%y},"debugger":function(){debugger}};var functionPointers=new Array(0);var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(!Object.getOwnPropertyDescriptor(Module,"wasmBinary"))Object.defineProperty(Module,"wasmBinary",{configurable:true,get:function(){abort("Module.wasmBinary has been replaced with plain wasmBinary")}});var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(!Object.getOwnPropertyDescriptor(Module,"noExitRuntime"))Object.defineProperty(Module,"noExitRuntime",{configurable:true,get:function(){abort("Module.noExitRuntime has been replaced with plain noExitRuntime")}});if(typeof WebAssembly!=="object"){abort("No WebAssembly support found. Build with -s WASM=0 to target JavaScript instead.")}function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}var wasmMemory;var wasmTable=new WebAssembly.Table({"initial":720,"maximum":720,"element":"anyfunc"});var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var ALLOC_NORMAL=0;var ALLOC_NONE=3;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,stackAlloc,dynamicAlloc][allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var stop;ptr=ret;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr>2]=0}stop=ret+size;while(ptr>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i=endIdx))++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;if(u>=2097152)warnOnce("Invalid Unicode code point 0x"+u.toString(16)+" encountered when serializing a JS string to an UTF-8 string on the asm.js/wasm heap! (Valid unicode code points should be in range 0-0x1FFFFF).");outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeArrayToMemory(array,buffer){assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var STACK_BASE=57760,STACK_MAX=5300640,DYNAMIC_BASE=5300640,DYNAMICTOP_PTR=57568;assert(STACK_BASE%16===0,"stack must start aligned");assert(DYNAMIC_BASE%16===0,"heap must start aligned");var TOTAL_STACK=5242880;if(Module["TOTAL_STACK"])assert(TOTAL_STACK===Module["TOTAL_STACK"],"the stack size can no longer be determined at runtime");var INITIAL_TOTAL_MEMORY=Module["TOTAL_MEMORY"]||268435456;if(!Object.getOwnPropertyDescriptor(Module,"TOTAL_MEMORY"))Object.defineProperty(Module,"TOTAL_MEMORY",{configurable:true,get:function(){abort("Module.TOTAL_MEMORY has been replaced with plain INITIAL_TOTAL_MEMORY")}});assert(INITIAL_TOTAL_MEMORY>=TOTAL_STACK,"TOTAL_MEMORY should be larger than TOTAL_STACK, was "+INITIAL_TOTAL_MEMORY+"! (TOTAL_STACK="+TOTAL_STACK+")");assert(typeof Int32Array!=="undefined"&&typeof Float64Array!=="undefined"&&Int32Array.prototype.subarray!==undefined&&Int32Array.prototype.set!==undefined,"JS engine does not provide full typed array support");if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_TOTAL_MEMORY/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_TOTAL_MEMORY=buffer.byteLength;assert(INITIAL_TOTAL_MEMORY%WASM_PAGE_SIZE===0);updateGlobalBufferAndViews(buffer);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;function writeStackCookie(){assert((STACK_MAX&3)==0);HEAPU32[(STACK_MAX>>2)-1]=34821223;HEAPU32[(STACK_MAX>>2)-2]=2310721022;HEAP32[0]=1668509029}function checkStackCookie(){var cookie1=HEAPU32[(STACK_MAX>>2)-1];var cookie2=HEAPU32[(STACK_MAX>>2)-2];if(cookie1!=34821223||cookie2!=2310721022){abort("Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x02135467, but received 0x"+cookie2.toString(16)+" "+cookie1.toString(16))}if(HEAP32[0]!==1668509029)abort("Runtime error: The application has corrupted its heap memory area (address zero)!")}function abortStackOverflow(allocSize){abort("Stack overflow! Attempted to allocate "+allocSize+" bytes on the stack, but stack has only "+(STACK_MAX-stackSave()+allocSize)+" bytes available!")}(function(){var h16=new Int16Array(1);var h8=new Int8Array(h16.buffer);h16[0]=25459;if(h8[0]!==115||h8[1]!==99)throw"Runtime error: expected the system to be little-endian!"})();function abortFnPtrError(ptr,sig){abort("Invalid function pointer "+ptr+" called with signature '"+sig+"'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this). Build with ASSERTIONS=2 for more info.")}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){checkStackCookie();assert(!runtimeInitialized);runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){checkStackCookie();FS.ignorePermissions=false;callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){checkStackCookie();runtimeExited=true}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}assert(Math.imul,"This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.fround,"This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.clz32,"This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.trunc,"This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");var Math_abs=Math.abs;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_min=Math.min;var Math_trunc=Math.trunc;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function getUniqueRunDependency(id){var orig=id;while(1){if(!runDependencyTracking[id])return id;id=orig+Math.random()}return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!=="undefined"){runDependencyWatcher=setInterval(function(){if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err("dependency: "+dep)}if(shown){err("(end of list)")}},1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";out(what);err(what);ABORT=true;EXITSTATUS=1;var output="abort("+what+") at "+stackTrace();what=output;throw new WebAssembly.RuntimeError(what)}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}var wasmBinaryFile="NftMarkerCreator_wasm.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(){var info={"env":asmLibraryArg,"wasi_snapshot_preview1":asmLibraryArg,"global":{"NaN":NaN,Infinity:Infinity},"global.Math":Math,"asm2wasm":asm2wasmImports};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");var trueModule=Module;function receiveInstantiatedSource(output){assert(Module===trueModule,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");trueModule=null;receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}Module["asm"]=createWasm;var tempDouble;var tempI64;__ATINIT__.push({func:function(){___emscripten_environ_constructor()}},{func:function(){__GLOBAL__sub_I_iostream_cpp()}});var tempDoublePtr=57744;assert(tempDoublePtr%8==0);function demangle(func){warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");return func}function demangleAll(text){var regex=/\b__Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}var ENV={};function ___buildEnvironment(environ){var MAX_ENV_VALUES=64;var TOTAL_ENV_SIZE=1024;var poolPtr;var envPtr;if(!___buildEnvironment.called){___buildEnvironment.called=true;ENV["USER"]="web_user";ENV["LOGNAME"]="web_user";ENV["PATH"]="/";ENV["PWD"]="/";ENV["HOME"]="/home/web_user";ENV["LANG"]=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";ENV["_"]=thisProgram;poolPtr=getMemory(TOTAL_ENV_SIZE);envPtr=getMemory(MAX_ENV_VALUES*4);HEAP32[envPtr>>2]=poolPtr;HEAP32[environ>>2]=envPtr}else{envPtr=HEAP32[environ>>2];poolPtr=HEAP32[envPtr>>2]}var strings=[];var totalSize=0;for(var key in ENV){if(typeof ENV[key]==="string"){var line=key+"="+ENV[key];strings.push(line);totalSize+=line.length}}if(totalSize>TOTAL_ENV_SIZE){throw new Error("Environment size exceeded TOTAL_ENV_SIZE!")}var ptrSize=4;for(var i=0;i>2]=poolPtr;poolPtr+=line.length+1}HEAP32[envPtr+strings.length*ptrSize>>2]=0}function ___cxa_allocate_exception(size){return _malloc(size)}var ___exception_infos={};var ___exception_last=0;function ___cxa_throw(ptr,type,destructor){___exception_infos[ptr]={ptr:ptr,adjusted:[ptr],type:type,destructor:destructor,refcount:0,caught:false,rethrown:false};___exception_last=ptr;if(!("uncaught_exception"in __ZSt18uncaught_exceptionv)){__ZSt18uncaught_exceptionv.uncaught_exceptions=1}else{__ZSt18uncaught_exceptionv.uncaught_exceptions++}throw ptr+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."}function ___lock(){}function ___setErrNo(value){if(Module["___errno_location"])HEAP32[Module["___errno_location"]()>>2]=value;else err("failed to set errno from JS");return value}function ___map_file(pathname,size){___setErrNo(63);return-1}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node}return node},getFileDataAsRegularArray:function(node){if(node.contents&&node.contents.subarray){var arr=[];for(var i=0;i=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(new ArrayBuffer(newSize));if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var err=FS.mayLookup(parent);if(err){throw new FS.ErrnoError(err,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){if(!FS.FSNode){FS.FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};FS.FSNode.prototype={};var readMode=292|73;var writeMode=146;Object.defineProperties(FS.FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}})}var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var err=FS.nodePermissions(dir,"x");if(err)return err;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var err=FS.nodePermissions(dir,"wx");if(err){return err}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}})}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){console.log("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(err){assert(FS.syncFSRequests>0);FS.syncFSRequests--;return callback(err)}function done(err){if(err){if(!done.errored){done.errored=true;return doCallback(err)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){if(typeof type==="string"){throw type}var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var err=FS.mayCreate(parent,name);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;console.log("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags){var buffer=new Uint8Array(HEAPU8.subarray(addr,addr+len));FS.msync(stream,buffer,0,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:0,get:function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(){var ret=UTF8ToString(SYSCALLS.get());return ret},getStreamFromFD:function(fd){if(fd===undefined)fd=SYSCALLS.get();var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(){var low=SYSCALLS.get(),high=SYSCALLS.get();if(low>=0)assert(high===0);else assert(high===-1);return low},getZero:function(){assert(SYSCALLS.get()===0)}};function ___syscall221(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),cmd=SYSCALLS.get();switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:___setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall5(which,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(),flags=SYSCALLS.get(),mode=SYSCALLS.get();var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall54(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),op=SYSCALLS.get();switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function __emscripten_syscall_munmap(addr,len){if(addr===-1||len===0){return-28}var info=SYSCALLS.mappings[addr];if(!info)return 0;if(len===info.len){var stream=FS.getStream(info.fd);SYSCALLS.doMsync(addr,stream,len,info.flags);FS.munmap(stream);SYSCALLS.mappings[addr]=null;if(info.allocated){_free(info.malloc)}}return 0}function ___syscall91(which,varargs){SYSCALLS.varargs=varargs;try{var addr=SYSCALLS.get(),len=SYSCALLS.get();return __emscripten_syscall_munmap(addr,len)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___unlock(){}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function ___wasi_fd_close(){return _fd_close.apply(null,arguments)}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function ___wasi_fd_read(){return _fd_read.apply(null,arguments)}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function ___wasi_fd_seek(){return _fd_seek.apply(null,arguments)}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function ___wasi_fd_write(){return _fd_write.apply(null,arguments)}function _abort(){abort()}function _emscripten_get_heap_size(){return HEAP8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){console.error("emscripten_realloc_buffer: Attempted to grow heap from "+buffer.byteLength+" bytes to "+size+" bytes, but got error: "+e)}}function _emscripten_resize_heap(requestedSize){var oldSize=_emscripten_get_heap_size();assert(requestedSize>oldSize);var PAGE_MULTIPLE=65536;var LIMIT=2147483648-PAGE_MULTIPLE;if(requestedSize>LIMIT){err("Cannot enlarge memory, asked to go up to "+requestedSize+" bytes, but the limit is "+LIMIT+" bytes!");return false}var MIN_TOTAL_MEMORY=16777216;var newSize=Math.max(oldSize,MIN_TOTAL_MEMORY);while(newSize>2]=now/1e3|0;HEAP32[ptr+4>>2]=now%1e3*1e3|0;return 0}function _llvm_exp2_f32(x){return Math.pow(2,x)}function _llvm_stackrestore(p){var self=_llvm_stacksave;var ret=self.LLVM_SAVEDSTACKS[p];self.LLVM_SAVEDSTACKS.splice(p,1);stackRestore(ret)}function _llvm_stacksave(){var self=_llvm_stacksave;if(!self.LLVM_SAVEDSTACKS){self.LLVM_SAVEDSTACKS=[]}self.LLVM_SAVEDSTACKS.push(stackSave());return self.LLVM_SAVEDSTACKS.length-1}var _llvm_trunc_f32=Math_trunc;var ___tm_current=57600;var ___tm_timezone=(stringToUTF8("GMT",57648,4),57648);function _tzset(){if(_tzset.called)return;_tzset.called=true;HEAP32[__get_timezone()>>2]=(new Date).getTimezoneOffset()*60;var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);HEAP32[__get_daylight()>>2]=Number(winter.getTimezoneOffset()!=summer.getTimezoneOffset());function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=allocate(intArrayFromString(winterName),"i8",ALLOC_NORMAL);var summerNamePtr=allocate(intArrayFromString(summerName),"i8",ALLOC_NORMAL);if(summer.getTimezoneOffset()>2]=winterNamePtr;HEAP32[__get_tzname()+4>>2]=summerNamePtr}else{HEAP32[__get_tzname()>>2]=summerNamePtr;HEAP32[__get_tzname()+4>>2]=winterNamePtr}}function _localtime_r(time,tmPtr){_tzset();var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var start=new Date(date.getFullYear(),0,1);var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst;var zonePtr=HEAP32[__get_tzname()+(dst?4:0)>>2];HEAP32[tmPtr+40>>2]=zonePtr;return tmPtr}function _localtime(time){return _localtime_r(time,___tm_current)}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]);return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.indexOf(rule)>=0){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm){return _strftime(s,maxsize,format,tm)}function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}FS.staticInit();Module["FS_createFolder"]=FS.createFolder;Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createLink"]=FS.createLink;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}function nullFunc_ii(x){abortFnPtrError(x,"ii")}function nullFunc_iidiiii(x){abortFnPtrError(x,"iidiiii")}function nullFunc_iii(x){abortFnPtrError(x,"iii")}function nullFunc_iiii(x){abortFnPtrError(x,"iiii")}function nullFunc_iiiii(x){abortFnPtrError(x,"iiiii")}function nullFunc_iiiiid(x){abortFnPtrError(x,"iiiiid")}function nullFunc_iiiiii(x){abortFnPtrError(x,"iiiiii")}function nullFunc_iiiiiid(x){abortFnPtrError(x,"iiiiiid")}function nullFunc_iiiiiii(x){abortFnPtrError(x,"iiiiiii")}function nullFunc_iiiiiiii(x){abortFnPtrError(x,"iiiiiiii")}function nullFunc_iiiiiiiii(x){abortFnPtrError(x,"iiiiiiiii")}function nullFunc_iiiiij(x){abortFnPtrError(x,"iiiiij")}function nullFunc_jiji(x){abortFnPtrError(x,"jiji")}function nullFunc_v(x){abortFnPtrError(x,"v")}function nullFunc_vi(x){abortFnPtrError(x,"vi")}function nullFunc_vii(x){abortFnPtrError(x,"vii")}function nullFunc_viii(x){abortFnPtrError(x,"viii")}function nullFunc_viiii(x){abortFnPtrError(x,"viiii")}function nullFunc_viiiii(x){abortFnPtrError(x,"viiiii")}function nullFunc_viiiiii(x){abortFnPtrError(x,"viiiiii")}function nullFunc_viiiiiii(x){abortFnPtrError(x,"viiiiiii")}function nullFunc_viijii(x){abortFnPtrError(x,"viijii")}var asmGlobalArg={};var asmLibraryArg={"___buildEnvironment":___buildEnvironment,"___cxa_allocate_exception":___cxa_allocate_exception,"___cxa_throw":___cxa_throw,"___lock":___lock,"___map_file":___map_file,"___syscall221":___syscall221,"___syscall5":___syscall5,"___syscall54":___syscall54,"___syscall91":___syscall91,"___unlock":___unlock,"___wasi_fd_close":___wasi_fd_close,"___wasi_fd_read":___wasi_fd_read,"___wasi_fd_seek":___wasi_fd_seek,"___wasi_fd_write":___wasi_fd_write,"__memory_base":1024,"__table_base":0,"_abort":_abort,"_emscripten_get_heap_size":_emscripten_get_heap_size,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_emscripten_resize_heap":_emscripten_resize_heap,"_exit":_exit,"_getenv":_getenv,"_gettimeofday":_gettimeofday,"_llvm_exp2_f32":_llvm_exp2_f32,"_llvm_stackrestore":_llvm_stackrestore,"_llvm_stacksave":_llvm_stacksave,"_llvm_trunc_f32":_llvm_trunc_f32,"_localtime":_localtime,"_strftime":_strftime,"_strftime_l":_strftime_l,"_time":_time,"abortStackOverflow":abortStackOverflow,"memory":wasmMemory,"nullFunc_ii":nullFunc_ii,"nullFunc_iidiiii":nullFunc_iidiiii,"nullFunc_iii":nullFunc_iii,"nullFunc_iiii":nullFunc_iiii,"nullFunc_iiiii":nullFunc_iiiii,"nullFunc_iiiiid":nullFunc_iiiiid,"nullFunc_iiiiii":nullFunc_iiiiii,"nullFunc_iiiiiid":nullFunc_iiiiiid,"nullFunc_iiiiiii":nullFunc_iiiiiii,"nullFunc_iiiiiiii":nullFunc_iiiiiiii,"nullFunc_iiiiiiiii":nullFunc_iiiiiiiii,"nullFunc_iiiiij":nullFunc_iiiiij,"nullFunc_jiji":nullFunc_jiji,"nullFunc_v":nullFunc_v,"nullFunc_vi":nullFunc_vi,"nullFunc_vii":nullFunc_vii,"nullFunc_viii":nullFunc_viii,"nullFunc_viiii":nullFunc_viiii,"nullFunc_viiiii":nullFunc_viiiii,"nullFunc_viiiiii":nullFunc_viiiiii,"nullFunc_viiiiiii":nullFunc_viiiiiii,"nullFunc_viijii":nullFunc_viijii,"table":wasmTable};var asm=Module["asm"](asmGlobalArg,asmLibraryArg,buffer);Module["asm"]=asm;var __GLOBAL__sub_I_iostream_cpp=Module["__GLOBAL__sub_I_iostream_cpp"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["__GLOBAL__sub_I_iostream_cpp"].apply(null,arguments)};var __ZSt18uncaught_exceptionv=Module["__ZSt18uncaught_exceptionv"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["__ZSt18uncaught_exceptionv"].apply(null,arguments)};var ___emscripten_environ_constructor=Module["___emscripten_environ_constructor"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["___emscripten_environ_constructor"].apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["___errno_location"].apply(null,arguments)};var __get_daylight=Module["__get_daylight"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["__get_daylight"].apply(null,arguments)};var __get_timezone=Module["__get_timezone"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["__get_timezone"].apply(null,arguments)};var __get_tzname=Module["__get_tzname"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["__get_tzname"].apply(null,arguments)};var _createImageSet=Module["_createImageSet"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["_createImageSet"].apply(null,arguments)};var _fflush=Module["_fflush"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["_fflush"].apply(null,arguments)};var _free=Module["_free"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["_free"].apply(null,arguments)};var _malloc=Module["_malloc"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["_malloc"].apply(null,arguments)};var establishStackSpace=Module["establishStackSpace"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["establishStackSpace"].apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["stackAlloc"].apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["stackRestore"].apply(null,arguments)};var stackSave=Module["stackSave"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["stackSave"].apply(null,arguments)};var dynCall_v=Module["dynCall_v"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["dynCall_v"].apply(null,arguments)};var dynCall_vi=Module["dynCall_vi"]=function(){assert(runtimeInitialized,"you need to wait for the runtime to be ready (e.g. wait for main() to be called)");assert(!runtimeExited,"the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)");return Module["asm"]["dynCall_vi"].apply(null,arguments)};Module["asm"]=asm;if(!Object.getOwnPropertyDescriptor(Module,"intArrayFromString"))Module["intArrayFromString"]=function(){abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"intArrayToString"))Module["intArrayToString"]=function(){abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"ccall"))Module["ccall"]=function(){abort("'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"cwrap"))Module["cwrap"]=function(){abort("'cwrap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"setValue"))Module["setValue"]=function(){abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"getValue"))Module["getValue"]=function(){abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"allocate"))Module["allocate"]=function(){abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};Module["getMemory"]=getMemory;if(!Object.getOwnPropertyDescriptor(Module,"AsciiToString"))Module["AsciiToString"]=function(){abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stringToAscii"))Module["stringToAscii"]=function(){abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"UTF8ArrayToString"))Module["UTF8ArrayToString"]=function(){abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"UTF8ToString"))Module["UTF8ToString"]=function(){abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stringToUTF8Array"))Module["stringToUTF8Array"]=function(){abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stringToUTF8"))Module["stringToUTF8"]=function(){abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"lengthBytesUTF8"))Module["lengthBytesUTF8"]=function(){abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"UTF16ToString"))Module["UTF16ToString"]=function(){abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stringToUTF16"))Module["stringToUTF16"]=function(){abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"lengthBytesUTF16"))Module["lengthBytesUTF16"]=function(){abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"UTF32ToString"))Module["UTF32ToString"]=function(){abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stringToUTF32"))Module["stringToUTF32"]=function(){abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"lengthBytesUTF32"))Module["lengthBytesUTF32"]=function(){abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"allocateUTF8"))Module["allocateUTF8"]=function(){abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stackTrace"))Module["stackTrace"]=function(){abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"addOnPreRun"))Module["addOnPreRun"]=function(){abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"addOnInit"))Module["addOnInit"]=function(){abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"addOnPreMain"))Module["addOnPreMain"]=function(){abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"addOnExit"))Module["addOnExit"]=function(){abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"addOnPostRun"))Module["addOnPostRun"]=function(){abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"writeStringToMemory"))Module["writeStringToMemory"]=function(){abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"writeArrayToMemory"))Module["writeArrayToMemory"]=function(){abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"writeAsciiToMemory"))Module["writeAsciiToMemory"]=function(){abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};Module["addRunDependency"]=addRunDependency;Module["removeRunDependency"]=removeRunDependency;if(!Object.getOwnPropertyDescriptor(Module,"ENV"))Module["ENV"]=function(){abort("'ENV' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};Module["FS"]=FS;Module["FS_createFolder"]=FS.createFolder;Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createLink"]=FS.createLink;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;if(!Object.getOwnPropertyDescriptor(Module,"GL"))Module["GL"]=function(){abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"dynamicAlloc"))Module["dynamicAlloc"]=function(){abort("'dynamicAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"loadDynamicLibrary"))Module["loadDynamicLibrary"]=function(){abort("'loadDynamicLibrary' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"loadWebAssemblyModule"))Module["loadWebAssemblyModule"]=function(){abort("'loadWebAssemblyModule' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"getLEB"))Module["getLEB"]=function(){abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"getFunctionTables"))Module["getFunctionTables"]=function(){abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"alignFunctionTables"))Module["alignFunctionTables"]=function(){abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"registerFunctions"))Module["registerFunctions"]=function(){abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"addFunction"))Module["addFunction"]=function(){abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"removeFunction"))Module["removeFunction"]=function(){abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"getFuncWrapper"))Module["getFuncWrapper"]=function(){abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"prettyPrint"))Module["prettyPrint"]=function(){abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"makeBigInt"))Module["makeBigInt"]=function(){abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"dynCall"))Module["dynCall"]=function(){abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"getCompilerSetting"))Module["getCompilerSetting"]=function(){abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"print"))Module["print"]=function(){abort("'print' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"printErr"))Module["printErr"]=function(){abort("'printErr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"getTempRet0"))Module["getTempRet0"]=function(){abort("'getTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"setTempRet0"))Module["setTempRet0"]=function(){abort("'setTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"callMain"))Module["callMain"]=function(){abort("'callMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"abort"))Module["abort"]=function(){abort("'abort' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"Pointer_stringify"))Module["Pointer_stringify"]=function(){abort("'Pointer_stringify' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"warnOnce"))Module["warnOnce"]=function(){abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stackSave"))Module["stackSave"]=function(){abort("'stackSave' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stackRestore"))Module["stackRestore"]=function(){abort("'stackRestore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"stackAlloc"))Module["stackAlloc"]=function(){abort("'stackAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};if(!Object.getOwnPropertyDescriptor(Module,"establishStackSpace"))Module["establishStackSpace"]=function(){abort("'establishStackSpace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")};Module["writeStackCookie"]=writeStackCookie;Module["checkStackCookie"]=checkStackCookie;Module["abortStackOverflow"]=abortStackOverflow;if(!Object.getOwnPropertyDescriptor(Module,"ALLOC_NORMAL"))Object.defineProperty(Module,"ALLOC_NORMAL",{configurable:true,get:function(){abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")}});if(!Object.getOwnPropertyDescriptor(Module,"ALLOC_STACK"))Object.defineProperty(Module,"ALLOC_STACK",{configurable:true,get:function(){abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")}});if(!Object.getOwnPropertyDescriptor(Module,"ALLOC_DYNAMIC"))Object.defineProperty(Module,"ALLOC_DYNAMIC",{configurable:true,get:function(){abort("'ALLOC_DYNAMIC' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")}});if(!Object.getOwnPropertyDescriptor(Module,"ALLOC_NONE"))Object.defineProperty(Module,"ALLOC_NONE",{configurable:true,get:function(){abort("'ALLOC_NONE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)")}});Module["calledRun"]=calledRun;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}writeStackCookie();preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}checkStackCookie()}Module["run"]=run;function checkUnflushedContent(){var print=out;var printErr=err;var has=false;out=err=function(x){has=true};try{var flush=Module["_fflush"];if(flush)flush(0);["stdout","stderr"].forEach(function(name){var info=FS.analyzePath("/dev/"+name);if(!info)return;var stream=info.object;var rdev=stream.rdev;var tty=TTY.ttys[rdev];if(tty&&tty.output&&tty.output.length){has=true}})}catch(e){}out=print;err=printErr;if(has){warnOnce("stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.")}}function exit(status,implicit){checkUnflushedContent();if(implicit&&noExitRuntime&&status===0){return}if(noExitRuntime){if(!implicit){err("program exited (with status: "+status+"), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)")}}else{ABORT=true;EXITSTATUS=status;exitRuntime();if(Module["onExit"])Module["onExit"](status)}quit_(status,new ExitStatus(status))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); 2 | --------------------------------------------------------------------------------