diff --git a/index.js b/index.js index 54bc8de..0c437c8 100644 --- a/index.js +++ b/index.js @@ -13,6 +13,7 @@ const logger = require('./src/helper/logger.js'); const validation = require('./src/helper/validationUtils.js'); const configUtils = require('./src/helper/configUtils.js'); const assertions = require('./src/helper/assertionUtils.js') +const coolprop = require('./src/coolprop-node/src/index.js'); // Domain-specific modules const { MeasurementContainer } = require('./src/measurements/index.js'); @@ -39,6 +40,7 @@ module.exports = { MeasurementContainer, nrmse, state, + coolprop, convert, MenuManager, childRegistrationUtils, diff --git a/src/configs/pumpingStation.json b/src/configs/pumpingStation.json new file mode 100644 index 0000000..d6a0668 --- /dev/null +++ b/src/configs/pumpingStation.json @@ -0,0 +1,694 @@ +{ + "general": { + "name": { + "default": "Pumping Station", + "rules": { + "type": "string", + "description": "A human-readable name or label for this pumping station configuration." + } + }, + "id": { + "default": null, + "rules": { + "type": "string", + "nullable": true, + "description": "A unique identifier for this pumping station configuration. If not provided, defaults to null." + } + }, + "unit": { + "default": "m3/h", + "rules": { + "type": "string", + "description": "The default flow unit used for reporting station throughput." + } + }, + "logging": { + "logLevel": { + "default": "info", + "rules": { + "type": "enum", + "values": [ + { + "value": "debug", + "description": "Log verbose diagnostic messages that aid in troubleshooting the station." + }, + { + "value": "info", + "description": "Log general informational messages about station behavior." + }, + { + "value": "warn", + "description": "Log warnings when station behavior deviates from expected ranges." + }, + { + "value": "error", + "description": "Log only error level messages for critical failures." + } + ], + "description": "Defines the minimum severity that will be written to the log." + } + }, + "enabled": { + "default": true, + "rules": { + "type": "boolean", + "description": "If true, logging is active for the pumping station node." + } + } + } + }, + "functionality": { + "softwareType": { + "default": "pumpingStation", + "rules": { + "type": "string", + "description": "Specified software type used to locate the proper default configuration." + } + }, + "role": { + "default": "StationController", + "rules": { + "type": "string", + "description": "Describes the station's function within the EVOLV ecosystem." + } + }, + "positionVsParent": { + "default": "atEquipment", + "rules": { + "type": "enum", + "description": "Defines how the station is positioned relative to its parent process or site.", + "values": [ + { + "value": "atEquipment", + "description": "The station is controlled at the equipment level and represents the primary pumping asset." + }, + { + "value": "upstream", + "description": "The station governs flows entering upstream of the parent asset." + }, + { + "value": "downstream", + "description": "The station influences conditions downstream of the parent asset, such as discharge or transfer." + } + ] + } + }, + "tickIntervalMs": { + "default": 1000, + "rules": { + "type": "number", + "min": 100, + "description": "Interval in milliseconds between internal evaluation cycles and output refreshes." + } + }, + "supportsSimulation": { + "default": true, + "rules": { + "type": "boolean", + "description": "Indicates whether the station can operate using simulated inflow and level data." + } + }, + "supportedChildSoftwareTypes": { + "default": [ + "measurement" + ], + "rules": { + "type": "set", + "itemType": "string", + "description": "List of child node software types that may register with the station." + } + } + }, + "asset": { + "uuid": { + "default": null, + "rules": { + "type": "string", + "nullable": true, + "description": "Asset tag number which is a universally unique identifier for this pumping station." + } + }, + "tagCode": { + "default": null, + "rules": { + "type": "string", + "nullable": true, + "description": "Asset tag code which uniquely identifies the pumping station. May be null if not assigned." + } + }, + "category": { + "default": "station", + "rules": { + "type": "enum", + "values": [ + { + "value": "station", + "description": "Represents a dedicated pumping station asset." + } + ], + "description": "High level classification for asset reporting." + } + }, + "type": { + "default": "pumpingStation", + "rules": { + "type": "string", + "description": "Specific asset type used to identify this configuration." + } + }, + "model": { + "default": "Unknown", + "rules": { + "type": "string", + "description": "Manufacturer or integrator model designation for the station." + } + }, + "supplier": { + "default": "Unknown", + "rules": { + "type": "string", + "description": "Primary supplier or maintainer responsible for the station." + } + }, + "geoLocation": { + "default": { + "x": 0, + "y": 0, + "z": 0 + }, + "rules": { + "type": "object", + "description": "Coordinate reference for locating the pumping station.", + "schema": { + "x": { + "default": 0, + "rules": { + "type": "number", + "description": "X coordinate in meters or site units." + } + }, + "y": { + "default": 0, + "rules": { + "type": "number", + "description": "Y coordinate in meters or site units." + } + }, + "z": { + "default": 0, + "rules": { + "type": "number", + "description": "Z coordinate in meters or site units." + } + } + } + } + } + }, + "basin": { + "volume": { + "default": "1", + "rules": { + "type": "number", + "description": "Total volume of empty basin in m3" + } + }, + "height": { + "default": "1", + "rules": { + "type": "number", + "description": "Total height of basin in m" + } + }, + "levelUnit": { + "default": "m", + "rules": { + "type": "string", + "description": "Unit used for level related setpoints and thresholds." + } + }, + "heightInlet": { + "default": 2, + "rules": { + "type": "number", + "min": 0, + "description": "Height of the inlet pipe measured from the basin floor (m)." + } + }, + "heightOutlet": { + "default": 0.2, + "rules": { + "type": "number", + "min": 0, + "description": "Height of the outlet pipe measured from the basin floor (m)." + } + }, + "heightOverflow": { + "default": 2.5, + "rules": { + "type": "number", + "min": 0, + "description": "Height of the overflow point measured from the basin floor (m)." + } + }, + "inletPipeDiameter": { + "default": 0.4, + "rules": { + "type": "number", + "min": 0, + "description": "Nominal inlet pipe diameter (m)." + } + }, + "outletPipeDiameter": { + "default": 0.4, + "rules": { + "type": "number", + "min": 0, + "description": "Nominal outlet pipe diameter (m)." + } + } + }, + "hydraulics": { + "maxInflowRate": { + "default": 200, + "rules": { + "type": "number", + "min": 0, + "description": "Maximum expected inflow during peak events (m3/h)." + } + }, + "refHeight": { + "default": "NAP", + "rules": { + "type": "enum", + "values": [ + { + "value": "NAP", + "description": "NAP (Normaal Amsterdams Peil)" + }, + { + "value": "EVRF", + "description": "EVRF (European Vertical Reference Frame)" + }, + { + "value": "EGM2008", + "description": "EGM2008 / EGM96 (satellietmetingen) Geopotentieel model earth " + } + + ], + "description": "Reference height to use to identify the height vs other basins with. This will say something more about the expected pressure loss in m head" + } + }, + "staticHead": { + "default": 12, + "rules": { + "type": "number", + "min": 0, + "description": "Static head between station suction and discharge point (m)." + } + }, + "maxDischargeHead": { + "default": 24, + "rules": { + "type": "number", + "min": 0, + "description": "Maximum allowable discharge head before calling for alarms (m)." + } + }, + "pipelineLength": { + "default": 80, + "rules": { + "type": "number", + "min": 0, + "description": "Length of the discharge pipeline considered in calculations (m)." + } + }, + "defaultFluid": { + "default": "wastewater", + "rules": { + "type": "enum", + "values": [ + { + "value": "wastewater", + "description": "The wet well is primarily cylindrical." + }, + { + "value": "water", + "description": "The wet well is rectangular or box shaped." + } + ] + } + }, + "temperatureReferenceDegC": { + "default": 15, + "rules": { + "type": "number", + "description": "Reference fluid temperature for property lookups (degC)." + } + } + }, + "control": { + "controlStrategy": { + "default": "levelBased", + "rules": { + "type": "enum", + "values": [ + { + "value": "levelBased", + "description": "Lead and lag pumps are controlled by basin level thresholds." + }, + { + "value": "pressureBased", + "description": "Pumps target a discharge pressure setpoint." + }, + { + "value": "flowTracking", + "description": "Pumps modulate to match measured inflow or downstream demand." + }, + { + "value": "manual", + "description": "Pumps are operated manually or by an external controller." + } + ], + "description": "Primary control philosophy for pump actuation." + } + }, + "levelSetpoints": { + "default": { + "startLeadPump": 1.2, + "stopLeadPump": 0.8, + "startLagPump": 1.8, + "stopLagPump": 1.4, + "alarmHigh": 2.3, + "alarmLow": 0.3 + }, + "rules": { + "type": "object", + "description": "Level thresholds that govern pump staging and alarms (m).", + "schema": { + "startLeadPump": { + "default": 1.2, + "rules": { + "type": "number", + "description": "Level that starts the lead pump." + } + }, + "stopLeadPump": { + "default": 0.8, + "rules": { + "type": "number", + "description": "Level that stops the lead pump." + } + }, + "startLagPump": { + "default": 1.8, + "rules": { + "type": "number", + "description": "Level that starts the lag pump." + } + }, + "stopLagPump": { + "default": 1.4, + "rules": { + "type": "number", + "description": "Level that stops the lag pump." + } + }, + "alarmHigh": { + "default": 2.3, + "rules": { + "type": "number", + "description": "High level alarm threshold." + } + }, + "alarmLow": { + "default": 0.3, + "rules": { + "type": "number", + "description": "Low level alarm threshold." + } + } + } + } + }, + "pressureSetpoint": { + "default": 250, + "rules": { + "type": "number", + "min": 0, + "description": "Target discharge pressure when operating in pressure control (kPa)." + } + }, + "alarmDebounceSeconds": { + "default": 10, + "rules": { + "type": "number", + "min": 0, + "description": "Time a condition must persist before raising an alarm (seconds)." + } + }, + "equalizationTargetPercent": { + "default": 60, + "rules": { + "type": "number", + "min": 0, + "max": 100, + "description": "Target fill percentage of the basin when operating in equalization mode." + } + }, + "autoRestartAfterPowerLoss": { + "default": true, + "rules": { + "type": "boolean", + "description": "If true, pumps resume based on last known state after power restoration." + } + }, + "manualOverrideTimeoutMinutes": { + "default": 30, + "rules": { + "type": "number", + "min": 0, + "description": "Duration after which a manual override expires automatically (minutes)." + } + }, + "flowBalanceTolerance": { + "default": 5, + "rules": { + "type": "number", + "min": 0, + "description": "Allowable error between inflow and outflow before adjustments are triggered (m3/h)." + } + } + }, + "alarms": { + "default": { + "highLevel": { + "enabled": true, + "threshold": 2.3, + "delaySeconds": 30, + "severity": "critical", + "acknowledgmentRequired": true + }, + "lowLevel": { + "enabled": true, + "threshold": 0.2, + "delaySeconds": 15, + "severity": "warning", + "acknowledgmentRequired": false + } + }, + "rules": { + "type": "object", + "description": "Alarm configuration for the pumping station.", + "schema": { + "highLevel": { + "default": { + "enabled": true, + "threshold": 2.3, + "delaySeconds": 30, + "severity": "critical", + "acknowledgmentRequired": true + }, + "rules": { + "type": "object", + "schema": { + "enabled": { + "default": true, + "rules": { + "type": "boolean", + "description": "Enable or disable the high level alarm." + } + }, + "threshold": { + "default": 2.3, + "rules": { + "type": "number", + "description": "Level threshold that triggers the high level alarm (m)." + } + }, + "delaySeconds": { + "default": 30, + "rules": { + "type": "number", + "min": 0, + "description": "Delay before issuing the high level alarm (seconds)." + } + }, + "severity": { + "default": "critical", + "rules": { + "type": "enum", + "values": [ + { + "value": "info", + "description": "Informational notification." + }, + { + "value": "warning", + "description": "Warning condition requiring attention." + }, + { + "value": "critical", + "description": "Critical alarm requiring immediate intervention." + } + ], + "description": "Severity associated with the high level alarm." + } + }, + "acknowledgmentRequired": { + "default": true, + "rules": { + "type": "boolean", + "description": "If true, this alarm must be acknowledged by an operator." + } + } + } + } + }, + "lowLevel": { + "default": { + "enabled": true, + "threshold": 0.2, + "delaySeconds": 15, + "severity": "warning", + "acknowledgmentRequired": false + }, + "rules": { + "type": "object", + "schema": { + "enabled": { + "default": true, + "rules": { + "type": "boolean", + "description": "Enable or disable the low level alarm." + } + }, + "threshold": { + "default": 0.2, + "rules": { + "type": "number", + "description": "Level threshold that triggers the low level alarm (m)." + } + }, + "delaySeconds": { + "default": 15, + "rules": { + "type": "number", + "min": 0, + "description": "Delay before issuing the low level alarm (seconds)." + } + }, + "severity": { + "default": "warning", + "rules": { + "type": "enum", + "values": [ + { + "value": "info", + "description": "Informational notification." + }, + { + "value": "warning", + "description": "Warning condition requiring attention." + }, + { + "value": "critical", + "description": "Critical alarm requiring immediate intervention." + } + ], + "description": "Severity associated with the low level alarm." + } + }, + "acknowledgmentRequired": { + "default": false, + "rules": { + "type": "boolean", + "description": "If true, this alarm must be acknowledged by an operator." + } + } + } + } + } + } + } + }, + "simulation": { + "enabled": { + "default": false, + "rules": { + "type": "boolean", + "description": "If true, the station operates in simulation mode using generated inflow and level data." + } + }, + "mode": { + "default": "diurnal", + "rules": { + "type": "enum", + "values": [ + { + "value": "static", + "description": "Use constant inflow and level conditions." + }, + { + "value": "diurnal", + "description": "Use a typical diurnal inflow curve to drive simulation." + }, + { + "value": "storm", + "description": "Use an elevated inflow profile representing a storm event." + } + ], + "description": "Defines which synthetic profile drives the simulation." + } + }, + "seed": { + "default": 42, + "rules": { + "type": "number", + "description": "Seed used for pseudo-random components in simulation." + } + }, + "applyRandomNoise": { + "default": true, + "rules": { + "type": "boolean", + "description": "If true, adds small noise to simulated measurements." + } + }, + "inflowProfile": { + "default": [ + 80, + 110, + 160, + 120, + 90 + ], + "rules": { + "type": "array", + "itemType": "number", + "minLength": 1, + "description": "Relative inflow profile used when mode is set to diurnal or storm (percentage of design inflow)." + } + } + } +} diff --git a/src/coolprop-node/.gitattributes b/src/coolprop-node/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/src/coolprop-node/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/src/coolprop-node/LICENSE b/src/coolprop-node/LICENSE new file mode 100644 index 0000000..44aab52 --- /dev/null +++ b/src/coolprop-node/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Craig Zych + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/coolprop-node/README.md b/src/coolprop-node/README.md new file mode 100644 index 0000000..1f663e0 --- /dev/null +++ b/src/coolprop-node/README.md @@ -0,0 +1,253 @@ +# CoolProp-Node + +A Node.js wrapper for CoolProp providing an easy-to-use interface for thermodynamic calculations and refrigerant properties. Unlike all the other CoolProp npm packages I've seen, this one should actually work. Please report any issues. + +## Installation + +```bash +npm install coolprop-node +``` + +## Features + +- Easy-to-use async interface for CoolProp +- Unit conversion support (Temperature: K/C/F, Pressure: Pa/kPa/bar/psi) +- Automatic initialization +- Configurable defaults +- Comprehensive error handling + +## Dependencies + No External Dependencies, as CoolProp.js and CoolProp.wasm are bundled with the package. +- [CoolProp](https://github.com/CoolProp/CoolProp) for the powerful thermodynamic library + + +## Quick Start +```javascript +const nodeprop = require('coolprop-node'); +async function example() { + // Initialize with defaults (optional) + await nodeprop.init({ + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + // Calculate superheat + const result = await nodeprop.calculateSuperheat({ + temperature: 25, // 25°C + pressure: 10, // 10 bar + refrigerant: 'R404A' // optional if set in init + }); + console.log(result); + + // expected output: + { + type: 'success', + superheat: 5.2, + saturationTemperature: 19.8, + refrigerant: 'R404A', + units: { + temperature: 'C', + pressure: 'bar' + } + } +} +example(); +``` + +## API Reference + +### nodeprop.init(config) +Initializes the wrapper with optional configuration. +###### Note: Calling `init()` is optional. The library will initialize automatically when you make your first call to any function, but you must provide a `refrigerant` parameter in that first call. + +```javascript +await nodeprop.init({ + refrigerant: 'R404A', // Required on first init + tempUnit: 'C', // Optional, defaults to 'K' + pressureUnit: 'bar' // Optional, defaults to 'Pa' +}); +``` + +### nodeprop.calculateSuperheat(input) +Calculates superheat for a given refrigerant. + +```javascript +const result = await nodeprop.calculateSuperheat({ + temperature: 25, // 25°C + pressure: 10, // 10 bar + refrigerant: 'R404A' // optional if set in init +}); + + +returns: + { + type: 'success', + superheat: 5.2, + saturationTemperature: 19.8, + refrigerant: 'R404A', + units: { + temperature: 'C', + pressure: 'bar' + } + } +``` + +### nodeprop.getSaturationTemperature(input) +Calculates saturation temperature for a given refrigerant. + +```javascript +const result = await nodeprop.calculateSaturationTemperature({ + temperature: 25, // 25°C + pressure: 10, // 10 bar + refrigerant: 'R404A' // optional if set in init +}); + +returns: + { + type: 'success', + temperature: 19.8, + refrigerant: 'R404A', + units: { + temperature: 'C', + pressure: 'bar' + } + } +``` + +### nodeprop.getSaturationPressure(input) +Calculates saturation pressure for a given refrigerant. + +```javascript +const result = await nodeprop.calculateSaturationPressure({ + temperature: 25, // 25°C + refrigerant: 'R404A' // optional if set in init +}); + +returns: + { + type: 'success', + pressure: 10, + refrigerant: 'R404A', + units: { + temperature: 'C', + pressure: 'bar' + } + } +``` + +### nodeprop.calculateSubcooling(input) +Calculates subcooling for a given refrigerant. + +```javascript +const result = await nodeprop.calculateSubcooling({ + temperature: 25, // 25°C + pressure: 10, // 10 bar + refrigerant: 'R404A' // optional if set in init +}); + +returns: + { + type: 'success', + subcooling: 5.2, + saturationTemperature: 19.8, + refrigerant: 'R404A', + units: { + temperature: 'C', + pressure: 'bar' + } + } +``` + +### nodeprop.calculateSuperheat(input) +Calculates superheat for a given refrigerant. + +```javascript +const result = await nodeprop.calculateSuperheat({ + temperature: 25, // 25°C + pressure: 10, // 10 bar + refrigerant: 'R404A' // optional if set in init +}); + +returns: + { + type: 'success', + superheat: 5.2, + saturationTemperature: 19.8, + refrigerant: 'R404A', + units: { + temperature: 'C', + pressure: 'bar' + } + } +``` + +### nodeprop.getProperties(input) +Gets all properties for a given refrigerant. + +```javascript +const result = await nodeprop.getProperties({ + temperature: 25, // 25°C + pressure: 10, // 10 bar + refrigerant: 'R404A' // optional if set in init +}); + +returns: + { + type: 'success', + properties: { + temperature: 25, // in configured temperature unit (e.g., °C) + pressure: 10, // in configured pressure unit (e.g., bar) + density: 1234.56, // in kg/m³ + enthalpy: 400000, // in J/kg + entropy: 1750, // in J/kg/K + quality: 1, // dimensionless (0-1) + conductivity: 0.013, // in W/m/K + viscosity: 1.2e-5, // in Pa·s + specificHeat: 850 // in J/kg/K + }, + refrigerant: 'R404A', + units: { + temperature: 'C', + pressure: 'bar', + density: 'kg/m³', + enthalpy: 'J/kg', + entropy: 'J/kg/K', + quality: 'dimensionless', + conductivity: 'W/m/K', + viscosity: 'Pa·s', + specificHeat: 'J/kg/K' + } + } +``` + +### nodeprop.PropsSI +Direct access to CoolProp's PropsSI function. + +```javascript +const PropsSI = await nodeprop.getPropsSI(); +const result = PropsSI('H', 'T', 298.15, 'P', 101325, 'R134a'); +``` + +### Error Handling + +```javascript +const result = await nodeprop.calculateSuperheat({ + temperature: 25, // 25°C + pressure: 10, // 10 bar + refrigerant: 'R404' // Invalid refrigerant. Must be supported by CoolProp, but R404 is not even a valid refrigerant. +}); + +returns: + { + type: 'error', + message: 'Invalid refrigerant' + } +``` + +### Acknowledgements + +- [CoolProp](https://github.com/CoolProp/CoolProp) for the powerful thermodynamic library + + + + diff --git a/src/coolprop-node/benchmark.js b/src/coolprop-node/benchmark.js new file mode 100644 index 0000000..4577312 --- /dev/null +++ b/src/coolprop-node/benchmark.js @@ -0,0 +1,80 @@ +const coolprop = require('./src/index.js'); + +// Function to generate random number between min and max +function getRandomNumber(min, max) { + return min + Math.random() * (max - min); +} + +// Generate 1000 combinations of temperature and pressure +function generateCombinations(count) { + const combinations = []; + + // For R744 (CO2), using realistic ranges from test files + // Temperature range: -40°F to 32°F + // Pressure range: 131 psig to 491 psig + for (let i = 0; i < count; i++) { + const temperature = getRandomNumber(-40, 32); + const pressure = getRandomNumber(131, 491); + + combinations.push({ + temperature, + pressure, + refrigerant: 'R744', + tempUnit: 'F', + pressureUnit: 'psig' + }); + } + + return combinations; +} + +async function runBenchmark() { + console.log('Generating 1000 temperature and pressure combinations...'); + const combinations = generateCombinations(1000); + console.log('Combinations generated.'); + + // Pre-initialize the library + console.log('Initializing library...'); + await coolprop.init({ + refrigerant: 'R744', + tempUnit: 'F', + pressureUnit: 'psig' + }); + console.log('Library initialized.'); + + // Run benchmark + console.log('Starting benchmark...'); + const startTime = performance.now(); + + const results = []; + for (let i = 0; i < combinations.length; i++) { + const result = await coolprop.calculateSuperheat(combinations[i]); + results.push(result); + + // Show progress every 100 calculations + if ((i + 1) % 100 === 0) { + console.log(`Processed ${i + 1} / ${combinations.length} calculations`); + } + } + + const endTime = performance.now(); + const totalTime = endTime - startTime; + const avgTime = totalTime / combinations.length; + + // Report results + console.log('\nBenchmark Results:'); + console.log(`Total time: ${totalTime.toFixed(2)} ms`); + console.log(`Average time per calculation: ${avgTime.toFixed(2)} ms`); + console.log(`Calculations per second: ${(1000 / avgTime).toFixed(2)}`); + + // Count success and error results + const successful = results.filter(r => r.type === 'success').length; + const failed = results.filter(r => r.type === 'error').length; + console.log(`\nSuccessful calculations: ${successful}`); + console.log(`Failed calculations: ${failed}`); +} + +// Run the benchmark +runBenchmark().catch(error => { + console.error('Benchmark failed:', error); +}); \ No newline at end of file diff --git a/src/coolprop-node/coolprop/coolprop.js b/src/coolprop-node/coolprop/coolprop.js new file mode 100644 index 0000000..d8615d4 --- /dev/null +++ b/src/coolprop-node/coolprop/coolprop.js @@ -0,0 +1 @@ +var Module=typeof Module!="undefined"?Module:{};var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var 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, -sENVIRONMENT=web or -sENVIRONMENT=node)")}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary;if(ENVIRONMENT_IS_NODE){if(typeof process=="undefined"||!process.release||process.release.name!=="node")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");var nodeVersion=process.versions.node;var numericVersion=nodeVersion.split(".").slice(0,3);numericVersion=numericVersion[0]*1e4+numericVersion[1]*100+numericVersion[2].split("-")[0]*1;if(numericVersion<16e4){throw new Error("This emscripten-generated code requires node v16.0.0 (detected v"+nodeVersion+")")}var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)})};if(!Module["thisProgram"]&&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",ex=>{if(ex!=="unwind"&&!(ex instanceof ExitStatus)&&!(ex.context instanceof ExitStatus)){throw ex}});quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};Module["inspect"]=()=>"[Emscripten Module object]"}else if(ENVIRONMENT_IS_SHELL){if(typeof process=="object"&&typeof require==="function"||typeof window=="object"||typeof importScripts=="function")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(typeof read!="undefined"){read_=read}readBinary=f=>{if(typeof readbuffer=="function"){return new Uint8Array(readbuffer(f))}let data=read(f,"binary");assert(typeof data=="object");return data};readAsync=(f,onload,onerror)=>{setTimeout(()=>onload(readBinary(f)))};if(typeof clearTimeout=="undefined"){globalThis.clearTimeout=id=>{}}if(typeof setTimeout=="undefined"){globalThis.setTimeout=f=>typeof f=="function"?f():abort()}if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit=="function"){quit_=(status,toThrow)=>{setTimeout(()=>{if(!(toThrow instanceof ExitStatus)){let toLog=toThrow;if(toThrow&&typeof toThrow=="object"&&toThrow.stack){toLog=[toThrow,toThrow.stack]}err(`exiting due to exception: ${toLog}`)}quit(status)});throw toThrow}}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(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}if(!(typeof window=="object"||typeof importScripts=="function"))throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}}else{throw new Error("environment detection error")}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;checkIncomingModuleAPI();if(Module["arguments"])arguments_=Module["arguments"];legacyModuleProp("arguments","arguments_");if(Module["thisProgram"])thisProgram=Module["thisProgram"];legacyModuleProp("thisProgram","thisProgram");if(Module["quit"])quit_=Module["quit"];legacyModuleProp("quit","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 emscripten_set_window_title in JS)");assert(typeof Module["TOTAL_MEMORY"]=="undefined","Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");legacyModuleProp("asm","wasmExports");legacyModuleProp("read","read_");legacyModuleProp("readAsync","readAsync");legacyModuleProp("readBinary","readBinary");legacyModuleProp("setWindowTitle","setWindowTitle");assert(!ENVIRONMENT_IS_SHELL,"shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable.");var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];legacyModuleProp("wasmBinary","wasmBinary");if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed"+(text?": "+text:""))}}var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}assert(!Module["STACK_SIZE"],"STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time");assert(typeof Int32Array!="undefined"&&typeof Float64Array!=="undefined"&&Int32Array.prototype.subarray!=undefined&&Int32Array.prototype.set!=undefined,"JS engine does not provide full typed array support");assert(!Module["wasmMemory"],"Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally");assert(!Module["INITIAL_MEMORY"],"Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically");function writeStackCookie(){var max=_emscripten_stack_get_end();assert((max&3)==0);if(max==0){max+=4}HEAPU32[max>>2]=34821223;HEAPU32[max+4>>2]=2310721022;HEAPU32[0>>2]=1668509029}function checkStackCookie(){if(ABORT)return;var max=_emscripten_stack_get_end();if(max==0){max+=4}var cookie1=HEAPU32[max>>2];var cookie2=HEAPU32[max+4>>2];if(cookie1!=34821223||cookie2!=2310721022){abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`)}if(HEAPU32[0>>2]!=1668509029){abort("Runtime error: The application has corrupted its heap memory area (address zero)!")}}(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! (Run with -sSUPPORT_BIG_ENDIAN to bypass)"})();var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=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(){assert(!runtimeInitialized);runtimeInitialized=true;checkStackCookie();if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}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 addOnInit(cb){__ATINIT__.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 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()}}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(()=>{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()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;var e=new WebAssembly.RuntimeError(what);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);var isFileURI=filename=>filename.startsWith("file://");function createExportWrapper(name){return function(){assert(runtimeInitialized,`native function \`${name}\` called before runtime initialization`);var f=wasmExports[name];assert(f,`exported native function \`${name}\` not found`);return f.apply(null,arguments)}}class EmscriptenEH extends Error{}class EmscriptenSjLj extends EmscriptenEH{}class CppException extends EmscriptenEH{constructor(excPtr){super(excPtr);this.excPtr=excPtr;const excInfo=getExceptionMessage(excPtr);this.name=excInfo[0];this.message=excInfo[1]}}var wasmBinaryFile;wasmBinaryFile="coolprop.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"&&!isFileURI(binaryFile)){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{if(!response["ok"]){throw"failed to load wasm binary file at '"+binaryFile+"'"}return response["arrayBuffer"]()}).catch(()=>getBinarySync(binaryFile))}else if(readAsync){return new Promise((resolve,reject)=>{readAsync(binaryFile,response=>resolve(new Uint8Array(response)),reject)})}}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(instance=>instance).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);if(isFileURI(wasmBinaryFile)){err(`warning: Loading from a file URI (${wasmBinaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`)}abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"env":wasmImports,"wasi_snapshot_preview1":wasmImports};function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["memory"];assert(wasmMemory,"memory not found in wasm exports");updateMemoryViews();wasmTable=wasmExports["__indirect_function_table"];assert(wasmTable,"table not found in wasm exports");addOnInit(wasmExports["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");var trueModule=Module;function receiveInstantiationResult(result){assert(Module===trueModule,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");trueModule=null;receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);return false}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult);return{}}var tempDouble;var tempI64;function legacyModuleProp(prop,newName,incomming=true){if(!Object.getOwnPropertyDescriptor(Module,prop)){Object.defineProperty(Module,prop,{configurable:true,get(){let extra=incomming?" (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)":"";abort(`\`Module.${prop}\` has been replaced by \`${newName}\``+extra)}})}}function ignoredModuleProp(prop){if(Object.getOwnPropertyDescriptor(Module,prop)){abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`)}}function isExportedByForceFilesystem(name){return name==="FS_createPath"||name==="FS_createDataFile"||name==="FS_createPreloadedFile"||name==="FS_unlink"||name==="addRunDependency"||name==="FS_createLazyFile"||name==="FS_createDevice"||name==="removeRunDependency"}function missingGlobal(sym,msg){if(typeof globalThis!=="undefined"){Object.defineProperty(globalThis,sym,{configurable:true,get(){warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`);return undefined}})}}missingGlobal("buffer","Please use HEAP8.buffer or wasmMemory.buffer");missingGlobal("asm","Please use wasmExports instead");function missingLibrarySymbol(sym){if(typeof globalThis!=="undefined"&&!Object.getOwnPropertyDescriptor(globalThis,sym)){Object.defineProperty(globalThis,sym,{configurable:true,get(){var msg=`\`${sym}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`;var librarySymbol=sym;if(!librarySymbol.startsWith("_")){librarySymbol="$"+sym}msg+=` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`;if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}warnOnce(msg);return undefined}})}unexportedRuntimeSymbol(sym)}function unexportedRuntimeSymbol(sym){if(!Object.getOwnPropertyDescriptor(Module,sym)){Object.defineProperty(Module,sym,{configurable:true,get(){var msg=`'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}abort(msg)}})}}function ExitStatus(status){this.name="ExitStatus";this.message=`Program terminated with exit(${status})`;this.status=status}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var withStackSave=f=>{var stack=stackSave();var ret=f();stackRestore(stack);return ret};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>{assert(typeof ptr=="number",`UTF8ToString expects a number (got ${typeof ptr})`);return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""};var getExceptionMessageCommon=ptr=>withStackSave(()=>{var type_addr_addr=stackAlloc(4);var message_addr_addr=stackAlloc(4);___get_exception_message(ptr,type_addr_addr,message_addr_addr);var type_addr=HEAPU32[type_addr_addr>>2];var message_addr=HEAPU32[message_addr_addr>>2];var type=UTF8ToString(type_addr);_free(type_addr);var message;if(message_addr){message=UTF8ToString(message_addr);_free(message_addr)}return[type,message]});var getExceptionMessage=ptr=>getExceptionMessageCommon(ptr);Module["getExceptionMessage"]=getExceptionMessage;var noExitRuntime=Module["noExitRuntime"]||true;var ptrToString=ptr=>{assert(typeof ptr==="number");ptr>>>=0;return"0x"+ptr.toString(16).padStart(8,"0")};var warnOnce=text=>{if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;if(ENVIRONMENT_IS_NODE)text="warning: "+text;err(text)}};var ___assert_fail=(condition,filename,line,func)=>{abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])};var exceptionCaught=[];var uncaughtExceptionCount=0;var ___cxa_begin_catch=ptr=>{var info=new ExceptionInfo(ptr);if(!info.get_caught()){info.set_caught(true);uncaughtExceptionCount--}info.set_rethrown(false);exceptionCaught.push(info);___cxa_increment_exception_refcount(info.excPtr);return info.get_exception_ptr()};var ___cxa_call_unexpected=exception=>abort("Unexpected exception thrown, this is not properly supported - aborting");var exceptionLast=0;var ___cxa_end_catch=()=>{_setThrew(0,0);assert(exceptionCaught.length>0);var info=exceptionCaught.pop();___cxa_decrement_exception_refcount(info.excPtr);exceptionLast=0};function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24;this.set_type=function(type){HEAPU32[this.ptr+4>>2]=type};this.get_type=function(){return HEAPU32[this.ptr+4>>2]};this.set_destructor=function(destructor){HEAPU32[this.ptr+8>>2]=destructor};this.get_destructor=function(){return HEAPU32[this.ptr+8>>2]};this.set_caught=function(caught){caught=caught?1:0;HEAP8[this.ptr+12>>0]=caught};this.get_caught=function(){return HEAP8[this.ptr+12>>0]!=0};this.set_rethrown=function(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13>>0]=rethrown};this.get_rethrown=function(){return HEAP8[this.ptr+13>>0]!=0};this.init=function(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)};this.set_adjusted_ptr=function(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr};this.get_adjusted_ptr=function(){return HEAPU32[this.ptr+16>>2]};this.get_exception_ptr=function(){var isPointer=___cxa_is_pointer_type(this.get_type());if(isPointer){return HEAPU32[this.excPtr>>2]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.excPtr}}var ___resumeException=ptr=>{if(!exceptionLast){exceptionLast=new CppException(ptr)}throw exceptionLast};var findMatchingCatch=args=>{var thrown=exceptionLast&&exceptionLast.excPtr;if(!thrown){setTempRet0(0);return 0}var info=new ExceptionInfo(thrown);info.set_adjusted_ptr(thrown);var thrownType=info.get_type();if(!thrownType){setTempRet0(0);return thrown}for(var arg in args){var caughtType=args[arg];if(caughtType===0||caughtType===thrownType){break}var adjusted_ptr_addr=info.ptr+16;if(___cxa_can_catch(caughtType,thrownType,adjusted_ptr_addr)){setTempRet0(caughtType);return thrown}}setTempRet0(thrownType);return thrown};var ___cxa_find_matching_catch_2=()=>findMatchingCatch([]);var ___cxa_find_matching_catch_3=arg0=>findMatchingCatch([arg0]);var ___cxa_find_matching_catch_4=(arg0,arg1)=>findMatchingCatch([arg0,arg1]);var ___cxa_get_exception_ptr=ptr=>{var rtn=new ExceptionInfo(ptr).get_exception_ptr();return rtn};var ___cxa_rethrow=()=>{var info=exceptionCaught.pop();if(!info){abort("no exception to throw")}var ptr=info.excPtr;if(!info.get_rethrown()){exceptionCaught.push(info);info.set_rethrown(true);info.set_caught(false);uncaughtExceptionCount++}exceptionLast=new CppException(ptr);throw exceptionLast};var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=new CppException(ptr);uncaughtExceptionCount++;throw exceptionLast};var ___cxa_uncaught_exceptions=()=>uncaughtExceptionCount;var setErrNo=value=>{HEAP32[___errno_location()>>2]=value;return value};var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(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:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname: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:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:function(){var paths=Array.prototype.slice.call(arguments);return PATH.normalize(paths.join("/"))},join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };")};var randomFill=view=>(randomFill=initRandomFill())(view);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.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(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;i{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{assert(typeof str==="string",`stringToUTF8Array expects a string (got ${typeof str})`);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;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;if(u>1114111)warnOnce("Invalid Unicode code point "+ptrToString(u)+" encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).");heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};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}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){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}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var mmapAlloc=size=>{abort("internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported")};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(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;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=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+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url,arrayBuffer=>{assert(arrayBuffer,`Loading data file "${url}" failed (no arrayBuffer).`);onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)},event=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}});if(dep)addRunDependency(dep)};var FS_createDataFile=(parent,name,fileData,canRead,canWrite,canOwn)=>{FS.createDataFile(parent,name,fileData,canRead,canWrite,canOwn)};var preloadPlugins=Module["preloadPlugins"]||[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{if(onerror)onerror();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,byteArray=>processData(byteArray),onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={"r":0,"r+":2,"w":512|64|1,"w+":512|64|2,"a":1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var ERRNO_MESSAGES={0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};var ERRNO_CODES={"EPERM":63,"ENOENT":44,"ESRCH":71,"EINTR":27,"EIO":29,"ENXIO":60,"E2BIG":1,"ENOEXEC":45,"EBADF":8,"ECHILD":12,"EAGAIN":6,"EWOULDBLOCK":6,"ENOMEM":48,"EACCES":2,"EFAULT":21,"ENOTBLK":105,"EBUSY":10,"EEXIST":20,"EXDEV":75,"ENODEV":43,"ENOTDIR":54,"EISDIR":31,"EINVAL":28,"ENFILE":41,"EMFILE":33,"ENOTTY":59,"ETXTBSY":74,"EFBIG":22,"ENOSPC":51,"ESPIPE":70,"EROFS":69,"EMLINK":34,"EPIPE":64,"EDOM":18,"ERANGE":68,"ENOMSG":49,"EIDRM":24,"ECHRNG":106,"EL2NSYNC":156,"EL3HLT":107,"EL3RST":108,"ELNRNG":109,"EUNATCH":110,"ENOCSI":111,"EL2HLT":112,"EDEADLK":16,"ENOLCK":46,"EBADE":113,"EBADR":114,"EXFULL":115,"ENOANO":104,"EBADRQC":103,"EBADSLT":102,"EDEADLOCK":16,"EBFONT":101,"ENOSTR":100,"ENODATA":116,"ETIME":117,"ENOSR":118,"ENONET":119,"ENOPKG":120,"EREMOTE":121,"ENOLINK":47,"EADV":122,"ESRMNT":123,"ECOMM":124,"EPROTO":65,"EMULTIHOP":36,"EDOTDOT":125,"EBADMSG":9,"ENOTUNIQ":126,"EBADFD":127,"EREMCHG":128,"ELIBACC":129,"ELIBBAD":130,"ELIBSCN":131,"ELIBMAX":132,"ELIBEXEC":133,"ENOSYS":52,"ENOTEMPTY":55,"ENAMETOOLONG":37,"ELOOP":32,"EOPNOTSUPP":138,"EPFNOSUPPORT":139,"ECONNRESET":15,"ENOBUFS":42,"EAFNOSUPPORT":5,"EPROTOTYPE":67,"ENOTSOCK":57,"ENOPROTOOPT":50,"ESHUTDOWN":140,"ECONNREFUSED":14,"EADDRINUSE":3,"ECONNABORTED":13,"ENETUNREACH":40,"ENETDOWN":38,"ETIMEDOUT":73,"EHOSTDOWN":142,"EHOSTUNREACH":23,"EINPROGRESS":26,"EALREADY":7,"EDESTADDRREQ":17,"EMSGSIZE":35,"EPROTONOSUPPORT":66,"ESOCKTNOSUPPORT":137,"EADDRNOTAVAIL":4,"ENETRESET":39,"EISCONN":30,"ENOTCONN":53,"ETOOMANYREFS":141,"EUSERS":136,"EDQUOT":19,"ESTALE":72,"ENOTSUP":138,"ENOMEDIUM":148,"EILSEQ":25,"EOVERFLOW":61,"ECANCELED":11,"ENOTRECOVERABLE":56,"EOWNERDEAD":62,"ESTRPIPE":135};var demangle=func=>{warnOnce("warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling");return func};var 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+"]"})};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath(path,opts={}){path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath(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(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(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(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,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(parent,name,mode,rdev){assert(typeof parent=="object");var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}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(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(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get(){return this.node},set(val){this.node=val}},isRead:{get(){return(this.flags&2097155)!==1}},isWrite:{get(){return(this.flags&2097155)!==0}},isAppend:{get(){return this.flags&1024}},flags:{get(){return this.shared.flags},set(val){this.shared.flags=val}},position:{get(){return this.shared.position},set(val){this.shared.position=val}}})}stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},chrdev_stream_ops:{open(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(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(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(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`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(errCode){assert(FS.syncFSRequests>0);FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(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(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(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){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(parent,name){return parent.node_ops.lookup(parent,name)},mknod(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 errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var i=0;i=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){assert(offset>=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},allocate(stream,offset,length){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){assert(offset>=0);if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:stream=>0,ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams(){if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1);assert(stdin.fd===0,`invalid handle for stdin (${stdin.fd})`);assert(stdout.fd===1,`invalid handle for stdout (${stdout.fd})`);assert(stderr.fd===2,`invalid handle for stderr (${stderr.fd})`)},ensureErrnoError(){if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.name="ErrnoError";this.node=node;this.setErrno=function(errno){this.errno=errno;for(var key in ERRNO_CODES){if(ERRNO_CODES[key]===errno){this.code=key;break}}};this.setErrno(errno);this.message=ERRNO_MESSAGES[errno];if(this.stack){Object.defineProperty(this,"stack",{value:(new Error).stack,writable:true});this.stack=demangleAll(this.stack)}};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach(code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""})},staticInit(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS}},init(input,output,error){assert(!FS.init.initialized,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit(){FS.init.initialized=false;_fflush(0);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=(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);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||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(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;out("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(key=>{var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});function writeChunks(stream,buffer,offset,length,position){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{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node},absolutePath(){abort("FS.absolutePath has been removed; use PATH_FS.resolve instead")},createFolder(){abort("FS.createFolder has been removed; use FS.mkdir instead")},createLink(){abort("FS.createLink has been removed; use FS.symlink instead")},joinPath(){abort("FS.joinPath has been removed; use PATH.join instead")},mmapAlloc(){abort("FS.mmapAlloc has been replaced by the top level function mmapAlloc")},standardizePath(){abort("FS.standardizePath has been removed; use PATH.normalize instead")}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAP32[buf+12>>2]=stat.uid;HEAP32[buf+16>>2]=stat.gid;HEAP32[buf+20>>2]=stat.rdev;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>2]=tempI64[0],HEAP32[buf+28>>2]=tempI64[1];HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAPU32[buf+48>>2]=atime%1e3*1e3;tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>2]=tempI64[0],HEAP32[buf+60>>2]=tempI64[1];HEAPU32[buf+64>>2]=mtime%1e3*1e3;tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>2]=tempI64[0],HEAP32[buf+76>>2]=tempI64[1];HEAPU32[buf+80>>2]=ctime%1e3*1e3;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>2]=tempI64[0],HEAP32[buf+92>>2]=tempI64[1];return 0},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get(){assert(SYSCALLS.varargs!=undefined);var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret},getp(){return SYSCALLS.get()},getStr(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}while(FS.streams[arg]){arg++}var newStream;newStream=FS.createStream(stream,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 5:{var arg=SYSCALLS.getp();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fstat64(fd,buf){try{var stream=SYSCALLS.getStreamFromFD(fd);return SYSCALLS.doStat(FS.stat,stream.path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var 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 ___syscall_getdents64(fd,dirp,count){try{var stream=SYSCALLS.getStreamFromFD(fd);if(!stream.getdents){stream.getdents=FS.readdir(stream.path)}var struct_size=280;var pos=0;var off=FS.llseek(stream,0,1);var idx=Math.floor(off/struct_size);while(idx>>0,(tempDouble=id,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos>>2]=tempI64[0],HEAP32[dirp+pos+4>>2]=tempI64[1];tempI64=[(idx+1)*struct_size>>>0,(tempDouble=(idx+1)*struct_size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos+8>>2]=tempI64[0],HEAP32[dirp+pos+12>>2]=tempI64[1];HEAP16[dirp+pos+16>>1]=280;HEAP8[dirp+pos+18>>0]=type;stringToUTF8(name,dirp+pos+19,256);pos+=struct_size;idx+=1}FS.llseek(stream,idx*struct_size,0);return pos}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=SYSCALLS.getp();HEAP32[argp>>2]=termios.c_iflag||0;HEAP32[argp+4>>2]=termios.c_oflag||0;HEAP32[argp+8>>2]=termios.c_cflag||0;HEAP32[argp+12>>2]=termios.c_lflag||0;for(var i=0;i<32;i++){HEAP8[argp+i+17>>0]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=SYSCALLS.getp();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17>>0])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.getp();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.getp();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=SYSCALLS.getp();HEAP16[argp>>1]=winsize[0];HEAP16[argp+2>>1]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_lstat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.lstat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_mkdirat(dirfd,path,mode){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_newfstatat(dirfd,path,buf,flags){try{path=SYSCALLS.getStr(path);var nofollow=flags&256;var allowEmpty=flags&4096;flags=flags&~6400;assert(!flags,`unknown flags in __syscall_newfstatat: ${flags}`);path=SYSCALLS.calculateAt(dirfd,path,allowEmpty);return SYSCALLS.doStat(nofollow?FS.lstat:FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var structRegistrations={};var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAP32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var InternalError;var throwInternalError=message=>{throw new InternalError(message)};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}};var __embind_finalize_value_object=structType=>{var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map(field=>field.getterReturnType).concat(fieldRecords.map(field=>field.setterArgumentType));whenDependentTypesAreResolved([structType],fieldTypes,fieldTypes=>{var fields={};fieldRecords.forEach((field,i)=>{var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:ptr=>getterReturnType["fromWireType"](getter(getterContext,ptr)),write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}});return[{name:reg.name,"fromWireType":ptr=>{var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":(destructors,o)=>{for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError(`Missing field: "${fieldName}"`)}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]})};var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{};var embind_init_charCodes=()=>{var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes};var embind_charCodes;var readLatin1String=ptr=>{var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret};var BindingError;var throwBindingError=message=>{throw new BindingError(message)};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}return sharedRegisterType(rawType,registeredInstance,options)}var GenericWireTypeSize=8;var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":function(pointer){return this["fromWireType"](HEAPU8[pointer])},destructorFunction:null})};var shallowCopyInternalPointer=o=>({count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType});var throwInstanceAlreadyDeleted=obj=>{function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")};var finalizationRegistry=false;var detachFinalizer=handle=>{};var runDestructor=$$=>{if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}};var releaseClassHandle=$$=>{$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}};var downcastPointer=(ptr,ptrClass,desiredClass)=>{if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)};var registeredPointers={};var getInheritedInstanceCount=()=>Object.keys(registeredInstances).length;var getLiveInheritedInstances=()=>{var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv};var deletionQueue=[];var flushPendingDeletes=()=>{while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}};var delayFunction;var setDelayFunction=fn=>{delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}};var init_embind=()=>{Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction};var registeredInstances={};var getBasestPointer=(class_,ptr)=>{if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr};var getInheritedInstance=(class_,ptr)=>{ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]};var makeClassHandle=(prototype,record)=>{if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))};function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}var attachFinalizer=handle=>{if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{console.warn(info.leakWarning.stack.replace(/^Error: /,""));releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};var cls=$$.ptrType.registeredClass;info.leakWarning=new Error(`Embind found a leaked C++ instance ${cls.name} <${ptrToString($$.ptr)}>.\n`+"We'll free it automatically in this case, but this functionality is not reliable across various environments.\n"+"Make sure to invoke .delete() manually once you're done with the instance instead.\n"+"Originally allocated");if("captureStackTrace"in Error){Error.captureStackTrace(info.leakWarning,RegisteredPointer_fromWireType)}finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)};var init_ClassHandle=()=>{Object.assign(ClassHandle.prototype,{"isAliasOf"(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;other.$$=other.$$;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right},"clone"(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}},"delete"(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}},"isDeleted"(){return!this.$$.ptr},"deleteLater"(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}})};function ClassHandle(){}var createNamedFunction=(name,body)=>Object.defineProperty(body,"name",{value:name});var ensureOverloadTable=(proto,methodName,humanName)=>{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}};var char_0=48;var char_9=57;var makeLegalFunctionName=name=>{if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name};function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}var upcastPointer=(ptr,ptrClass,desiredClass)=>{while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr};function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle(()=>clonedHandle["delete"]()));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function readPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var init_RegisteredPointer=()=>{Object.assign(RegisteredPointer.prototype,{getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr},destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":readPointer,"deleteObject"(handle){if(handle!==null){handle["delete"]()}},"fromWireType":RegisteredPointer_fromWireType})};function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var dynCallLegacy=(sig,ptr,args)=>{assert("dynCall_"+sig in Module,`bad function pointer type - dynCall function not found for sig '${sig}'`);if(args&&args.length){assert(args.length===sig.substring(1).replace(/j/g,"--").length)}else{assert(sig.length==1)}var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)};var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}assert(wasmTable.get(funcPtr)==func,"JavaScript-side Wasm function table mirror is out of date!");return func};var dynCall=(sig,ptr,args)=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}assert(getWasmTableEntry(ptr),`missing table entry in dynCall: ${ptr}`);var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn};var getDynCaller=(sig,ptr)=>{assert(sig.includes("j")||sig.includes("p"),"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}};var embind__requireFunction=(signature,rawFunction)=>{signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};var extendError=(baseErrorType,errorName)=>{var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass};var UnboundTypeError;var getTypeName=type=>{var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv};var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))};var __embind_register_class=(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor)=>{name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError(`Cannot construct ${name} due to unbound types`,[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(name,function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${arguments.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`)}return body.apply(this,arguments)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);if(registeredClass.baseClass){if(registeredClass.baseClass.__derivedClasses===undefined){registeredClass.baseClass.__derivedClasses=[]}registeredClass.baseClass.__derivedClasses.push(registeredClass)}var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})};var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i>2])}return array};function newFunc(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError(`new_ called with constructor type ${typeof constructor} which is not a function`)}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc,isAsync){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}assert(!isAsync,"Async bindings are only supported with JSPI.");var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns||isAsync?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i{assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=`constructor ${classType.name}`;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`)}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`,rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})};var getFunctionName=signature=>{signature=signature.trim();const argsIndex=signature.indexOf("(");if(argsIndex!==-1){assert(signature[signature.length-1]==")","Parentheses for argument names should match.");return signature.substr(0,argsIndex)}else{return signature}};var __embind_register_class_function=(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual,isAsync)=>{var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);methodName=getFunctionName(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=`${classType.name}.${methodName}`;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`,rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context,isAsync);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})};function handleAllocatorInit(){Object.assign(HandleAllocator.prototype,{get(id){assert(this.allocated[id]!==undefined,`invalid handle: ${id}`);return this.allocated[id]},has(id){return this.allocated[id]!==undefined},allocate(handle){var id=this.freelist.pop()||this.allocated.length;this.allocated[id]=handle;return id},free(id){assert(this.allocated[id]!==undefined);this.allocated[id]=undefined;this.freelist.push(id)}})}function HandleAllocator(){this.allocated=[undefined];this.freelist=[]}var emval_handles=new HandleAllocator;var __emval_decref=handle=>{if(handle>=emval_handles.reserved&&0===--emval_handles.get(handle).refcount){emval_handles.free(handle)}};var count_emval_handles=()=>{var count=0;for(var i=emval_handles.reserved;i{emval_handles.allocated.push({value:undefined},{value:null},{value:true},{value:false});emval_handles.reserved=emval_handles.allocated.length;Module["count_emval_handles"]=count_emval_handles};var Emval={toValue:handle=>{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles.get(handle).value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{return emval_handles.allocate({refcount:1,value:value})}}}};var __embind_register_emval=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":(destructors,value)=>Emval.toHandle(value),"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})};var enumReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?function(pointer){return this["fromWireType"](HEAP8[pointer>>0])}:function(pointer){return this["fromWireType"](HEAPU8[pointer>>0])};case 2:return signed?function(pointer){return this["fromWireType"](HEAP16[pointer>>1])}:function(pointer){return this["fromWireType"](HEAPU16[pointer>>1])};case 4:return signed?function(pointer){return this["fromWireType"](HEAP32[pointer>>2])}:function(pointer){return this["fromWireType"](HEAPU32[pointer>>2])};default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_enum=(rawType,name,size,isSigned)=>{name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":(destructors,c)=>c.value,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":enumReadValueFromPointer(name,size,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)};var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl};var __embind_register_enum_value=(rawEnumType,name,enumValue)=>{var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(`${enumType.name}_${name}`,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value};var embindRepr=v=>{if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}};var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 8:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":value=>value,"toWireType":(destructors,value)=>{if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert ${embindRepr(value)} to ${this.name}`)}return value},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":floatReadValueFromPointer(name,size),destructorFunction:null})};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);name=getFunctionName(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>HEAP8[pointer>>0]:pointer=>HEAPU8[pointer>>0];case 2:return signed?pointer=>HEAP16[pointer>>1]:pointer=>HEAPU16[pointer>>1];case 4:return signed?pointer=>HEAP32[pointer>>2]:pointer=>HEAPU32[pointer>>2];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`)}if(valuemaxRange){throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`)}};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=HEAPU32[handle+4>>2];return new TA(HEAP8.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})};var __embind_register_std_string=(rawType,name)=>{name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType"(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i{assert(ptr%2==0,"Pointer passed to UTF16ToString must be aligned to two bytes!");var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%2==0,"Pointer passed to stringToUTF16 must be aligned to two bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{assert(ptr%4==0,"Pointer passed to UTF32ToString must be aligned to four bytes!");var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%4==0,"Pointer passed to stringToUTF32 must be aligned to four bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>HEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,"fromWireType":value=>{var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":(destructors,value)=>{if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction(ptr){_free(ptr)}})};var __embind_register_value_object=(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor)=>{structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}};var __embind_register_value_object_field=(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext)=>{structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})};var __embind_register_void=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":()=>undefined,"toWireType":(destructors,o)=>undefined})};var __emval_incref=handle=>{if(handle>4){emval_handles.get(handle).refcount+=1}};var __emval_take_value=(type,arg)=>{type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)};var _abort=()=>{abort("native code called abort()")};var _emscripten_date_now=()=>Date.now();var _emscripten_memcpy_js=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var abortOnCannotGrowMemory=requestedSize=>{abort(`Cannot enlarge memory arrays to size ${requestedSize} bytes (OOM). Either (1) compile with -sINITIAL_MEMORY=X with X higher than the current value ${HEAP8.length}, (2) compile with -sALLOW_MEMORY_GROWTH which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -sABORTING_MALLOC=0`)};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i>0]=str.charCodeAt(i)}HEAP8[buffer>>0]=0};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;getEnvStrings().forEach((string,i)=>{var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;stringToAscii(string,ptr);bufSize+=string.length+1});return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(string=>bufSize+=string.length+1);HEAPU32[penviron_buf_size>>2]=bufSize;return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var convertI32PairToI53Checked=(lo,hi)=>{assert(lo==lo>>>0||lo==(lo|0));assert(hi===(hi|0));return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN};function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>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.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!=="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var _llvm_eh_typeid_for=type=>type;var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var 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];var 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};var writeArrayToMemory=(array,buffer)=>{assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)};var _strftime=(s,maxsize,format,tm)=>{var tm_zone=HEAPU32[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}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":date=>getWeekBasedYear(date),"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1};var _strftime_l=(s,maxsize,format,tm,loc)=>_strftime(s,maxsize,format,tm);var 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};var readMode=292|73;var writeMode=146;Object.defineProperties(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)}}});FS.FSNode=FSNode;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");handleAllocatorInit();init_emval();function checkIncomingModuleAPI(){ignoredModuleProp("fetchSettings")}var wasmImports={__assert_fail:___assert_fail,__cxa_begin_catch:___cxa_begin_catch,__cxa_call_unexpected:___cxa_call_unexpected,__cxa_end_catch:___cxa_end_catch,__cxa_find_matching_catch_2:___cxa_find_matching_catch_2,__cxa_find_matching_catch_3:___cxa_find_matching_catch_3,__cxa_find_matching_catch_4:___cxa_find_matching_catch_4,__cxa_get_exception_ptr:___cxa_get_exception_ptr,__cxa_rethrow:___cxa_rethrow,__cxa_throw:___cxa_throw,__cxa_uncaught_exceptions:___cxa_uncaught_exceptions,__resumeException:___resumeException,__syscall_fcntl64:___syscall_fcntl64,__syscall_fstat64:___syscall_fstat64,__syscall_getdents64:___syscall_getdents64,__syscall_ioctl:___syscall_ioctl,__syscall_lstat64:___syscall_lstat64,__syscall_mkdirat:___syscall_mkdirat,__syscall_newfstatat:___syscall_newfstatat,__syscall_openat:___syscall_openat,__syscall_stat64:___syscall_stat64,_embind_finalize_value_object:__embind_finalize_value_object,_embind_register_bigint:__embind_register_bigint,_embind_register_bool:__embind_register_bool,_embind_register_class:__embind_register_class,_embind_register_class_constructor:__embind_register_class_constructor,_embind_register_class_function:__embind_register_class_function,_embind_register_emval:__embind_register_emval,_embind_register_enum:__embind_register_enum,_embind_register_enum_value:__embind_register_enum_value,_embind_register_float:__embind_register_float,_embind_register_function:__embind_register_function,_embind_register_integer:__embind_register_integer,_embind_register_memory_view:__embind_register_memory_view,_embind_register_std_string:__embind_register_std_string,_embind_register_std_wstring:__embind_register_std_wstring,_embind_register_value_object:__embind_register_value_object,_embind_register_value_object_field:__embind_register_value_object_field,_embind_register_void:__embind_register_void,_emval_decref:__emval_decref,_emval_incref:__emval_incref,_emval_take_value:__emval_take_value,abort:_abort,emscripten_date_now:_emscripten_date_now,emscripten_memcpy_js:_emscripten_memcpy_js,emscripten_resize_heap:_emscripten_resize_heap,environ_get:_environ_get,environ_sizes_get:_environ_sizes_get,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write,invoke_dd:invoke_dd,invoke_dddd:invoke_dddd,invoke_ddddd:invoke_ddddd,invoke_dddid:invoke_dddid,invoke_ddi:invoke_ddi,invoke_di:invoke_di,invoke_did:invoke_did,invoke_didd:invoke_didd,invoke_diddd:invoke_diddd,invoke_didddd:invoke_didddd,invoke_didddddi:invoke_didddddi,invoke_diddddi:invoke_diddddi,invoke_didddi:invoke_didddi,invoke_diddi:invoke_diddi,invoke_diddid:invoke_diddid,invoke_diddiid:invoke_diddiid,invoke_diddiii:invoke_diddiii,invoke_didi:invoke_didi,invoke_didii:invoke_didii,invoke_dii:invoke_dii,invoke_diidd:invoke_diidd,invoke_diididi:invoke_diididi,invoke_diididid:invoke_diididid,invoke_diii:invoke_diii,invoke_diiidi:invoke_diiidi,invoke_diiii:invoke_diiii,invoke_diiiid:invoke_diiiid,invoke_diiiii:invoke_diiiii,invoke_diiiiid:invoke_diiiiid,invoke_diiiiii:invoke_diiiiii,invoke_diiiiiiii:invoke_diiiiiiii,invoke_fiii:invoke_fiii,invoke_i:invoke_i,invoke_idiii:invoke_idiii,invoke_ii:invoke_ii,invoke_iid:invoke_iid,invoke_iidddd:invoke_iidddd,invoke_iii:invoke_iii,invoke_iiidi:invoke_iiidi,invoke_iiii:invoke_iiii,invoke_iiiid:invoke_iiiid,invoke_iiiidd:invoke_iiiidd,invoke_iiiii:invoke_iiiii,invoke_iiiiid:invoke_iiiiid,invoke_iiiiidddiii:invoke_iiiiidddiii,invoke_iiiiidi:invoke_iiiiidi,invoke_iiiiidiii:invoke_iiiiidiii,invoke_iiiiii:invoke_iiiiii,invoke_iiiiiidi:invoke_iiiiiidi,invoke_iiiiiii:invoke_iiiiiii,invoke_iiiiiiii:invoke_iiiiiiii,invoke_iiiiiiiiii:invoke_iiiiiiiiii,invoke_iiiiiiiiiii:invoke_iiiiiiiiiii,invoke_iiiiiiiiiiii:invoke_iiiiiiiiiiii,invoke_iiiiiiiiiiiii:invoke_iiiiiiiiiiiii,invoke_iiji:invoke_iiji,invoke_iijiii:invoke_iijiii,invoke_iijjiii:invoke_iijjiii,invoke_ijjiii:invoke_ijjiii,invoke_ji:invoke_ji,invoke_jiiii:invoke_jiiii,invoke_v:invoke_v,invoke_vddddiiii:invoke_vddddiiii,invoke_vdiii:invoke_vdiii,invoke_vdiiii:invoke_vdiiii,invoke_vi:invoke_vi,invoke_vid:invoke_vid,invoke_vidd:invoke_vidd,invoke_viddd:invoke_viddd,invoke_vidddddddd:invoke_vidddddddd,invoke_viddddddddii:invoke_viddddddddii,invoke_viddddddddiii:invoke_viddddddddiii,invoke_vidddiii:invoke_vidddiii,invoke_viddi:invoke_viddi,invoke_vidi:invoke_vidi,invoke_vidid:invoke_vidid,invoke_vii:invoke_vii,invoke_viid:invoke_viid,invoke_viidd:invoke_viidd,invoke_viiddd:invoke_viiddd,invoke_viidddi:invoke_viidddi,invoke_viiddi:invoke_viiddi,invoke_viidi:invoke_viidi,invoke_viii:invoke_viii,invoke_viiidid:invoke_viiidid,invoke_viiidiii:invoke_viiidiii,invoke_viiii:invoke_viiii,invoke_viiiid:invoke_viiiid,invoke_viiiidi:invoke_viiiidi,invoke_viiiidiii:invoke_viiiidiii,invoke_viiiii:invoke_viiiii,invoke_viiiiii:invoke_viiiiii,invoke_viiiiiid:invoke_viiiiiid,invoke_viiiiiii:invoke_viiiiiii,invoke_viiiiiiidiiii:invoke_viiiiiiidiiii,invoke_viiiiiiii:invoke_viiiiiiii,invoke_viiiiiiiii:invoke_viiiiiiiii,invoke_viiiiiiiiidii:invoke_viiiiiiiiidii,invoke_viiiiiiiiii:invoke_viiiiiiiiii,invoke_viiiiiiiiiii:invoke_viiiiiiiiiii,invoke_viiiiiiiiiiiii:invoke_viiiiiiiiiiiii,invoke_viiiiiiiiiiiiiii:invoke_viiiiiiiiiiiiiii,invoke_viijii:invoke_viijii,invoke_vjjiii:invoke_vjjiii,llvm_eh_typeid_for:_llvm_eh_typeid_for,strftime_l:_strftime_l};var wasmExports=createWasm();var ___wasm_call_ctors=createExportWrapper("__wasm_call_ctors");var ___cxa_free_exception=createExportWrapper("__cxa_free_exception");var _free=Module["_free"]=createExportWrapper("free");var ___errno_location=createExportWrapper("__errno_location");var _malloc=createExportWrapper("malloc");var _fflush=Module["_fflush"]=createExportWrapper("fflush");var ___getTypeName=createExportWrapper("__getTypeName");var _setThrew=createExportWrapper("setThrew");var setTempRet0=createExportWrapper("setTempRet0");var _emscripten_stack_init=()=>(_emscripten_stack_init=wasmExports["emscripten_stack_init"])();var _emscripten_stack_get_free=()=>(_emscripten_stack_get_free=wasmExports["emscripten_stack_get_free"])();var _emscripten_stack_get_base=()=>(_emscripten_stack_get_base=wasmExports["emscripten_stack_get_base"])();var _emscripten_stack_get_end=()=>(_emscripten_stack_get_end=wasmExports["emscripten_stack_get_end"])();var stackSave=createExportWrapper("stackSave");var stackRestore=createExportWrapper("stackRestore");var stackAlloc=createExportWrapper("stackAlloc");var _emscripten_stack_get_current=()=>(_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"])();var ___cxa_decrement_exception_refcount=createExportWrapper("__cxa_decrement_exception_refcount");var ___cxa_increment_exception_refcount=createExportWrapper("__cxa_increment_exception_refcount");var ___get_exception_message=Module["___get_exception_message"]=createExportWrapper("__get_exception_message");var ___cxa_can_catch=createExportWrapper("__cxa_can_catch");var ___cxa_is_pointer_type=createExportWrapper("__cxa_is_pointer_type");var dynCall_ji=Module["dynCall_ji"]=createExportWrapper("dynCall_ji");var dynCall_vjjiii=Module["dynCall_vjjiii"]=createExportWrapper("dynCall_vjjiii");var dynCall_ijjiii=Module["dynCall_ijjiii"]=createExportWrapper("dynCall_ijjiii");var dynCall_iijiii=Module["dynCall_iijiii"]=createExportWrapper("dynCall_iijiii");var dynCall_iijjiii=Module["dynCall_iijjiii"]=createExportWrapper("dynCall_iijjiii");var dynCall_iiji=Module["dynCall_iiji"]=createExportWrapper("dynCall_iiji");var dynCall_jii=Module["dynCall_jii"]=createExportWrapper("dynCall_jii");var dynCall_viji=Module["dynCall_viji"]=createExportWrapper("dynCall_viji");var dynCall_vijii=Module["dynCall_vijii"]=createExportWrapper("dynCall_vijii");var dynCall_jiji=Module["dynCall_jiji"]=createExportWrapper("dynCall_jiji");var dynCall_viijii=Module["dynCall_viijii"]=createExportWrapper("dynCall_viijii");var dynCall_jiiii=Module["dynCall_jiiii"]=createExportWrapper("dynCall_jiiii");var dynCall_iiiiij=Module["dynCall_iiiiij"]=createExportWrapper("dynCall_iiiiij");var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=createExportWrapper("dynCall_iiiiijj");var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=createExportWrapper("dynCall_iiiiiijj");function invoke_viii(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vii(index,a1,a2){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iii(index,a1,a2){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_i(index){var sp=stackSave();try{return getWasmTableEntry(index)()}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vi(index,a1){var sp=stackSave();try{getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiii(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_di(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iid(index,a1,a2){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_v(index){var sp=stackSave();try{getWasmTableEntry(index)()}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiii(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vdiii(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_idiii(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiiii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_dd(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiidi(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiidiii(index,a1,a2,a3,a4,a5,a6,a7,a8){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiidddiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiidi(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiid(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viidd(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiddi(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_dii(index,a1,a2){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diiii(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diii(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diiiiii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diididi(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diiiid(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viddi(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_ddi(index,a1,a2){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diddiii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diddddi(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_dddd(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_ddddd(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vdiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diddd(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_didddi(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_dddid(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_didddd(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_did(index,a1,a2){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vidd(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iidddd(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiddd(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_didddddi(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_didii(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiii(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiidd(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiid(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiiidi(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diddi(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diddid(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diddiid(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vidddiii(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vidi(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_didd(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vidid(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viidddi(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiid(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viid(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiidid(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiiiiidii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiiidiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viddddddddii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diiiiid(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viddddddddiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vidddddddd(index,a1,a2,a3,a4,a5,a6,a7,a8,a9){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vddddiiii(index,a1,a2,a3,a4,a5,a6,a7,a8){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diiidi(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viddd(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diidd(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viidi(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiidi(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiidiii(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiidiii(index,a1,a2,a3,a4,a5,a6,a7,a8){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_didi(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vid(index,a1,a2){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_diididid(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiid(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiiiii(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_fiii(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiiiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viiiiiiiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_ji(index,a1){var sp=stackSave();try{return dynCall_ji(index,a1)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iijiii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{return dynCall_iijiii(index,a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iijjiii(index,a1,a2,a3,a4,a5,a6,a7,a8){var sp=stackSave();try{return dynCall_iijjiii(index,a1,a2,a3,a4,a5,a6,a7,a8)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_vjjiii(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{dynCall_vjjiii(index,a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_ijjiii(index,a1,a2,a3,a4,a5,a6,a7){var sp=stackSave();try{return dynCall_ijjiii(index,a1,a2,a3,a4,a5,a6,a7)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_iiji(index,a1,a2,a3,a4){var sp=stackSave();try{return dynCall_iiji(index,a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_viijii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{dynCall_viijii(index,a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}function invoke_jiiii(index,a1,a2,a3,a4){var sp=stackSave();try{return dynCall_jiiii(index,a1,a2,a3,a4)}catch(e){stackRestore(sp);if(!(e instanceof EmscriptenEH))throw e;_setThrew(1,0)}}var missingLibrarySymbols=["writeI53ToI64","writeI53ToI64Clamped","writeI53ToI64Signaling","writeI53ToU64Clamped","writeI53ToU64Signaling","readI53FromI64","readI53FromU64","convertI32PairToI53","convertU32PairToI53","exitJS","growMemory","ydayFromDate","inetPton4","inetNtop4","inetPton6","inetNtop6","readSockaddr","writeSockaddr","getHostByName","getCallstack","emscriptenLog","convertPCtoSourceLocation","readEmAsmArgs","jstoi_q","jstoi_s","listenOnce","autoResumeAudioContext","handleException","keepRuntimeAlive","runtimeKeepalivePush","runtimeKeepalivePop","callUserCallback","maybeExit","asmjsMangle","getNativeTypeSize","STACK_SIZE","STACK_ALIGN","POINTER_SIZE","ASSERTIONS","getCFunc","ccall","cwrap","uleb128Encode","sigToWasmTypes","generateFuncType","convertJsFunctionToWasm","getEmptyTableSlot","updateTableMap","getFunctionAddress","addFunction","removeFunction","reallyNegative","unSign","strLen","reSign","formatString","intArrayToString","AsciiToString","stringToNewUTF8","stringToUTF8OnStack","registerKeyEventCallback","maybeCStringToJsString","findEventTarget","findCanvasEventTarget","getBoundingClientRect","fillMouseEventData","registerMouseEventCallback","registerWheelEventCallback","registerUiEventCallback","registerFocusEventCallback","fillDeviceOrientationEventData","registerDeviceOrientationEventCallback","fillDeviceMotionEventData","registerDeviceMotionEventCallback","screenOrientation","fillOrientationChangeEventData","registerOrientationChangeEventCallback","fillFullscreenChangeEventData","registerFullscreenChangeEventCallback","JSEvents_requestFullscreen","JSEvents_resizeCanvasForFullscreen","registerRestoreOldStyle","hideEverythingExceptGivenElement","restoreHiddenElements","setLetterbox","softFullscreenResizeWebGLRenderTarget","doRequestFullscreen","fillPointerlockChangeEventData","registerPointerlockChangeEventCallback","registerPointerlockErrorEventCallback","requestPointerLock","fillVisibilityChangeEventData","registerVisibilityChangeEventCallback","registerTouchEventCallback","fillGamepadEventData","registerGamepadEventCallback","registerBeforeUnloadEventCallback","fillBatteryEventData","battery","registerBatteryEventCallback","setCanvasElementSize","getCanvasElementSize","jsStackTrace","stackTrace","checkWasiClock","wasiRightsToMuslOFlags","wasiOFlagsToMuslOFlags","createDyncallWrapper","safeSetTimeout","setImmediateWrapped","clearImmediateWrapped","polyfillSetImmediate","getPromise","makePromise","idsToPromises","makePromiseCallback","setMainLoop","getSocketFromFD","getSocketAddress","FS_unlink","FS_mkdirTree","_setNetworkCallback","heapObjectForWebGLType","heapAccessShiftForWebGLHeap","webgl_enable_ANGLE_instanced_arrays","webgl_enable_OES_vertex_array_object","webgl_enable_WEBGL_draw_buffers","webgl_enable_WEBGL_multi_draw","emscriptenWebGLGet","computeUnpackAlignedImageSize","colorChannelsInGlTextureFormat","emscriptenWebGLGetTexPixelData","__glGenObject","emscriptenWebGLGetUniform","webglGetUniformLocation","webglPrepareUniformLocationsBeforeFirstUse","webglGetLeftBracePos","emscriptenWebGLGetVertexAttrib","__glGetActiveAttribOrUniform","writeGLArray","registerWebGlEventCallback","runAndAbortIfError","SDL_unicode","SDL_ttfContext","SDL_audio","ALLOC_NORMAL","ALLOC_STACK","allocate","writeStringToMemory","writeAsciiToMemory","getFunctionArgsName","registerInheritedInstance","unregisterInheritedInstance","validateThis","getStringOrSymbol","emval_get_global","emval_returnValue","emval_lookupTypes","emval_addMethodCaller"];missingLibrarySymbols.forEach(missingLibrarySymbol);var unexportedSymbols=["run","addOnPreRun","addOnInit","addOnPreMain","addOnExit","addOnPostRun","addRunDependency","removeRunDependency","FS_createFolder","FS_createPath","FS_createLazyFile","FS_createLink","FS_createDevice","FS_readFile","out","err","callMain","abort","wasmMemory","wasmExports","stackAlloc","stackSave","stackRestore","getTempRet0","setTempRet0","writeStackCookie","checkStackCookie","convertI32PairToI53Checked","ptrToString","zeroMemory","getHeapMax","abortOnCannotGrowMemory","ENV","MONTH_DAYS_REGULAR","MONTH_DAYS_LEAP","MONTH_DAYS_REGULAR_CUMULATIVE","MONTH_DAYS_LEAP_CUMULATIVE","isLeapYear","arraySum","addDays","ERRNO_CODES","ERRNO_MESSAGES","setErrNo","DNS","Protocols","Sockets","initRandomFill","randomFill","timers","warnOnce","UNWIND_CACHE","readEmAsmArgsArray","getExecutableName","dynCallLegacy","getDynCaller","dynCall","asyncLoad","alignMemory","mmapAlloc","handleAllocatorInit","HandleAllocator","wasmTable","noExitRuntime","freeTableIndexes","functionsInTableMap","setValue","getValue","PATH","PATH_FS","UTF8Decoder","UTF8ArrayToString","UTF8ToString","stringToUTF8Array","stringToUTF8","lengthBytesUTF8","intArrayFromString","stringToAscii","UTF16Decoder","UTF16ToString","stringToUTF16","lengthBytesUTF16","UTF32ToString","stringToUTF32","lengthBytesUTF32","writeArrayToMemory","JSEvents","specialHTMLTargets","currentFullscreenStrategy","restoreOldWindowedStyle","demangle","demangleAll","ExitStatus","getEnvStrings","doReadv","doWritev","promiseMap","uncaughtExceptionCount","exceptionLast","exceptionCaught","ExceptionInfo","findMatchingCatch","getExceptionMessageCommon","incrementExceptionRefcount","decrementExceptionRefcount","getExceptionMessage","Browser","wget","SYSCALLS","preloadPlugins","FS_createPreloadedFile","FS_modeStringToFlags","FS_getMode","FS_stdin_getChar_buffer","FS_stdin_getChar","FS","FS_createDataFile","MEMFS","TTY","PIPEFS","SOCKFS","tempFixedLengthArray","miniTempWebGLFloatBuffers","miniTempWebGLIntBuffers","GL","emscripten_webgl_power_preferences","AL","GLUT","EGL","GLEW","IDBStore","SDL","SDL_gfx","allocateUTF8","allocateUTF8OnStack","InternalError","BindingError","throwInternalError","throwBindingError","registeredTypes","awaitingDependencies","typeDependencies","tupleRegistrations","structRegistrations","sharedRegisterType","whenDependentTypesAreResolved","embind_charCodes","embind_init_charCodes","readLatin1String","getTypeName","getFunctionName","heap32VectorToArray","requireRegisteredType","UnboundTypeError","PureVirtualError","GenericWireTypeSize","init_embind","throwUnboundTypeError","ensureOverloadTable","exposePublicSymbol","replacePublicSymbol","extendError","createNamedFunction","embindRepr","registeredInstances","getBasestPointer","getInheritedInstance","getInheritedInstanceCount","getLiveInheritedInstances","registeredPointers","registerType","integerReadValueFromPointer","enumReadValueFromPointer","floatReadValueFromPointer","simpleReadValueFromPointer","readPointer","runDestructors","newFunc","craftInvokerFunction","embind__requireFunction","genericPointerToWireType","constNoSmartPtrRawPointerToWireType","nonConstNoSmartPtrRawPointerToWireType","init_RegisteredPointer","RegisteredPointer","RegisteredPointer_fromWireType","runDestructor","releaseClassHandle","finalizationRegistry","detachFinalizer_deps","detachFinalizer","attachFinalizer","makeClassHandle","init_ClassHandle","ClassHandle","throwInstanceAlreadyDeleted","deletionQueue","flushPendingDeletes","delayFunction","setDelayFunction","RegisteredClass","shallowCopyInternalPointer","downcastPointer","upcastPointer","char_0","char_9","makeLegalFunctionName","emval_handles","emval_symbols","init_emval","count_emval_handles","Emval","emval_methodCallers","reflectConstruct"];unexportedSymbols.forEach(unexportedRuntimeSymbol);var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function stackCheckInit(){_emscripten_stack_init();writeStackCookie()}function run(){if(runDependencies>0){return}stackCheckInit();preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();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()}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); diff --git a/src/coolprop-node/coolprop/coolprop.wasm b/src/coolprop-node/coolprop/coolprop.wasm new file mode 100644 index 0000000..651964a Binary files /dev/null and b/src/coolprop-node/coolprop/coolprop.wasm differ diff --git a/src/coolprop-node/package.json b/src/coolprop-node/package.json new file mode 100644 index 0000000..6a7bcec --- /dev/null +++ b/src/coolprop-node/package.json @@ -0,0 +1,31 @@ +{ + "name": "coolprop-node", + "version": "1.0.20", + "main": "src/index.js", + "scripts": { + "test": "jest", + "test:watch": "jest --watch" + }, + "keywords": [ + "coolprop", + "thermodynamics", + "fluid properties", + "refrigerant", + "refrigeration", + "refprop" + ], + "author": "Craig Zych", + "license": "MIT", + "description": "A Node.js wrapper for CoolProp providing an easy-to-use interface for thermodynamic calculations and refrigerant properties. Unlike all the other CoolProp npm packages I've seen, this one should actually work. Please report any issues. ", + "devDependencies": { + "jest": "^29.7.0" + }, + "jest": { + "testEnvironment": "node", + "verbose": true + }, + "repository": { + "type": "git", + "url": "https://github.com/Craigzyc/coolprop-node.git" + } +} diff --git a/src/coolprop-node/src/cp.js b/src/coolprop-node/src/cp.js new file mode 100644 index 0000000..80d64dd --- /dev/null +++ b/src/coolprop-node/src/cp.js @@ -0,0 +1,92 @@ +// Load and configure the CoolProp module +const fs = require('fs'); +const path = require('path'); +const vm = require('vm'); + +// Mock XMLHttpRequest +class XMLHttpRequest { + open(method, url) { + this.method = method; + this.url = url; + } + + send() { + try { + // Convert the URL to a local file path + const localPath = path.join(__dirname, '..', 'coolprop', path.basename(this.url)); + const data = fs.readFileSync(localPath); + + this.status = 200; + this.response = data; + this.responseType = 'arraybuffer'; + + if (this.onload) { + this.onload(); + } + } catch (error) { + if (this.onerror) { + this.onerror(error); + } + } + } +} + +// Read the coolprop.js file +const coolpropJs = fs.readFileSync(path.join(__dirname, '../coolprop/coolprop.js'), 'utf8'); + +// Create a context for the module +const context = { + window: {}, + self: {}, + Module: { + onRuntimeInitialized: function() { + context.Module.initialized = true; + } + }, + importScripts: () => {}, + console: console, + location: { + href: 'file://' + __dirname, + pathname: __dirname, + }, + document: { + currentScript: { src: '' } + }, + XMLHttpRequest: XMLHttpRequest +}; + +// Make self reference the context itself +context.self = context; +// Make window reference the context itself +context.window = context; + +// Execute coolprop.js in our custom context +vm.createContext(context); +vm.runInContext(coolpropJs, context); + +// Wait for initialization +function waitForInit(timeout = 5000) { + return new Promise((resolve, reject) => { + const start = Date.now(); + const check = () => { + if (context.Module.initialized) { + resolve(context.Module); + } else if (Date.now() - start > timeout) { + reject(new Error('CoolProp initialization timed out')); + } else { + setTimeout(check, 100); + } + }; + check(); + }); +} + +module.exports = { + init: () => waitForInit(), + PropsSI: (...args) => { + if (!context.Module.initialized) { + throw new Error('CoolProp not initialized. Call init() first'); + } + return context.Module.PropsSI(...args); + } +}; diff --git a/src/coolprop-node/src/index.js b/src/coolprop-node/src/index.js new file mode 100644 index 0000000..c5b98ed --- /dev/null +++ b/src/coolprop-node/src/index.js @@ -0,0 +1,419 @@ +const coolprop = require('./cp.js'); +const customRefs = require('./refData.js'); + +class CoolPropWrapper { + constructor() { + this.initialized = false; + this.defaultRefrigerant = null; + this.defaultTempUnit = 'K'; // K, C, F + this.defaultPressureUnit = 'Pa' // Pa, kPa, bar, psi + this.customRef = false; + } + + // Temperature conversion helpers + _convertTempToK(value, unit = this.defaultTempUnit) { + switch(unit.toUpperCase()) { + case 'K': return value; + case 'C': return value + 273.15; + case 'F': return (value + 459.67) * 5/9; + default: throw new Error('Unsupported temperature unit'); + } + } + + _convertTempFromK(value, unit = this.defaultTempUnit) { + switch(unit.toUpperCase()) { + case 'K': return value; + case 'C': return value - 273.15; + case 'F': return value * 9/5 - 459.67; + default: throw new Error('Unsupported temperature unit'); + } + } + + _convertDeltaTempFromK(value, unit = this.defaultTempUnit) { + switch(unit.toUpperCase()) { + case 'K': return value; + case 'C': return value; + case 'F': return (value * 1.8); + default: throw new Error('Unsupported temperature unit'); + } + } + + // Pressure conversion helpers + _convertPressureToPa(value, unit = this.defaultPressureUnit) { + switch(unit.toUpperCase()) { + case 'PAA': return value; // Absolute Pascal + case 'PAG': + case 'PA': return value + 101325; // Gauge Pascal + case 'KPAA': return value * 1000; // Absolute kiloPascal + case 'KPAG': + case 'KPA': return value * 1000 + 101325; // Gauge kiloPascal + case 'BARA': return value * 100000; // Absolute bar + case 'BARG': + case 'BAR': return value * 100000 + 101325; // Gauge bar + case 'PSIA': return value * 6894.76; // Absolute PSI + case 'PSIG': + case 'PSI': return value * 6894.76 + 101325;// Gauge PSI + default: throw new Error('Unsupported pressure unit'); + } + } + + _convertPressureFromPa(value, unit = this.defaultPressureUnit) { + switch(unit.toUpperCase()) { + case 'PAA': return value; // Absolute Pascal + case 'PAG': + case 'PA': return value - 101325; // Gauge Pascal + case 'KPAA': return value / 1000; // Absolute kiloPascal + case 'KPAG': + case 'KPA': return (value - 101325) / 1000; // Gauge kiloPascal + case 'BARA': return value / 100000; // Absolute bar + case 'BARG': + case 'BAR': return (value - 101325) / 100000;// Gauge bar + case 'PSIA': return value / 6894.76; // Absolute PSI + case 'PSIG': + case 'PSI': return (value - 101325) / 6894.76;// Gauge PSI + default: throw new Error('Unsupported pressure unit'); + } + } + + async init(config = {}) { + try { + // If already initialized, only update defaults if provided + if (this.initialized) { + if (config.refrigerant) this.defaultRefrigerant = config.refrigerant; + if (config.tempUnit) { + if (!['K', 'C', 'F'].includes(config.tempUnit.toUpperCase())) { + return { type: 'error', message: 'Invalid temperature unit. Must be K, C, or F' }; + } + this.defaultTempUnit = config.tempUnit; + } + if (config.pressureUnit) { + if (!['PA', 'PAA', 'KPA', 'KPAA', 'BAR', 'BARA', 'PSI', 'PSIA'].includes(config.pressureUnit.toUpperCase())) { + return { type: 'error', message: 'Invalid pressure unit. Must be Pa, Paa, kPa, kPaa, bar, bara, psi, or psia' }; + } + this.defaultPressureUnit = config.pressureUnit; + } + return { type: 'success', message: 'Default settings updated' }; + } + + // First time initialization + if (!config.refrigerant) { + throw new Error('Refrigerant must be specified during initialization'); + } + + // Validate temperature unit if provided + if (config.tempUnit && !['K', 'C', 'F'].includes(config.tempUnit.toUpperCase())) { + throw new Error('Invalid temperature unit. Must be K, C, or F'); + } + + // Validate pressure unit if provided + if (config.pressureUnit && !['PA', 'PAA', 'KPA', 'KPAA', 'BAR', 'BARA', 'PSI', 'PSIA'].includes(config.pressureUnit.toUpperCase())) { + throw new Error('Invalid pressure unit. Must be Pa, Paa, kPa, kPaa, bar, bara, psi, or psia'); + } + + await coolprop.init(); + this.initialized = true; + this.defaultRefrigerant = config.refrigerant; + this.defaultTempUnit = config.tempUnit || this.defaultTempUnit; + this.defaultPressureUnit = config.pressureUnit || this.defaultPressureUnit; + return { type: 'success', message: 'Initialized successfully' }; + } catch (error) { + return { type: 'error', message: error.message }; + } + } + + async _ensureInit(config = {}) { + // Initialize CoolProp if not already done + if (!this.initialized) { + if (!config.refrigerant && !this.defaultRefrigerant) { + throw new Error('Refrigerant must be specified either during initialization or in the method call'); + } + await coolprop.init(); + this.initialized = true; + } + + // Validate temperature unit if provided + if (config.tempUnit && !['K', 'C', 'F'].includes(config.tempUnit.toUpperCase())) { + throw new Error('Invalid temperature unit. Must be K, C, or F'); + } + + // Validate pressure unit if provided + if (config.pressureUnit && !['PA', 'PAA', 'PAG', 'KPA', 'KPAA', 'KPAG', 'BAR', 'BARA', 'BARG', 'PSI', 'PSIA', 'PSIG'].includes(config.pressureUnit.toUpperCase())) { + throw new Error('Invalid pressure unit. Must be Pa, Paa, Pag, kPa, kPaa, kPag, bar, bara, barg, psi, psia, or psig'); + } + + // Validate refrigerant if provided + if (config.refrigerant && typeof config.refrigerant !== 'string') { + throw new Error('Invalid refrigerant type'); + } + if (config.refrigerant && Object.keys(customRefs).includes(config.refrigerant)) { + this.customRef = true; + this.defaultRefrigerant = config.refrigerant; + //console.log(`Using custom refrigerant flag for ${this.defaultRefrigerant}`); + }else if(this.customRef && config.refrigerant){ + this.customRef = false; + //console.log(`Cleared custom refrigerant flag`); + } + + // Update instance variables with new config values if provided + if (config.refrigerant) this.defaultRefrigerant = config.refrigerant; + if (config.tempUnit) this.defaultTempUnit = config.tempUnit.toUpperCase(); + if (config.pressureUnit) this.defaultPressureUnit = config.pressureUnit.toUpperCase(); + } + + async getConfig() { + return { + refrigerant: this.defaultRefrigerant, + tempUnit: this.defaultTempUnit, + pressureUnit: this.defaultPressureUnit + }; + } + + async setConfig(config) { + await this.init(config); + return { + type: 'success', + message: 'Config updated successfully', + config: await this.getConfig() + }; + } + + // Helper method for linear interpolation/extrapolation + _interpolateSaturationTemperature(pressurePa, saturationData, pressureType = 'liquid') { + const data = saturationData.sort((a, b) => a[pressureType] - b[pressureType]); // Sort by specified pressure type + + // If pressure is below the lowest data point, extrapolate using first two points + if (pressurePa <= data[0][pressureType]) { + if (data.length < 2) return data[0].K; + const p1 = data[0], p2 = data[1]; + const slope = (p2.K - p1.K) / (p2[pressureType] - p1[pressureType]); + return p1.K + slope * (pressurePa - p1[pressureType]); + } + + // If pressure is above the highest data point, extrapolate using last two points + if (pressurePa >= data[data.length - 1][pressureType]) { + if (data.length < 2) return data[data.length - 1].K; + const p1 = data[data.length - 2], p2 = data[data.length - 1]; + const slope = (p2.K - p1.K) / (p2[pressureType] - p1[pressureType]); + return p1.K + slope * (pressurePa - p1[pressureType]); + } + + // Find the two adjacent points for interpolation + for (let i = 0; i < data.length - 1; i++) { + if (pressurePa >= data[i][pressureType] && pressurePa <= data[i + 1][pressureType]) { + const p1 = data[i], p2 = data[i + 1]; + + // Linear interpolation + const slope = (p2.K - p1.K) / (p2[pressureType] - p1[pressureType]); + return p1.K + slope * (pressurePa - p1[pressureType]); + } + } + + // Fallback (shouldn't reach here) + return data[0].K; + } + + // Helper method for linear interpolation/extrapolation of saturation pressure + _interpolateSaturationPressure(tempK, saturationData, pressureType = 'liquid') { + const data = saturationData.sort((a, b) => a.K - b.K); // Sort by temperature + + // If temperature is below the lowest data point, extrapolate using first two points + if (tempK <= data[0].K) { + if (data.length < 2) return data[0][pressureType]; + const p1 = data[0], p2 = data[1]; + const slope = (p2[pressureType] - p1[pressureType]) / (p2.K - p1.K); + return p1[pressureType] + slope * (tempK - p1.K); + } + + // If temperature is above the highest data point, extrapolate using last two points + if (tempK >= data[data.length - 1].K) { + if (data.length < 2) return data[data.length - 1][pressureType]; + const p1 = data[data.length - 2], p2 = data[data.length - 1]; + const slope = (p2[pressureType] - p1[pressureType]) / (p2.K - p1.K); + return p1[pressureType] + slope * (tempK - p1.K); + } + + // Find the two adjacent points for interpolation + for (let i = 0; i < data.length - 1; i++) { + if (tempK >= data[i].K && tempK <= data[i + 1].K) { + const p1 = data[i], p2 = data[i + 1]; + + // Linear interpolation + const slope = (p2[pressureType] - p1[pressureType]) / (p2.K - p1.K); + return p1[pressureType] + slope * (tempK - p1.K); + } + } + + // Fallback (shouldn't reach here) + return data[0][pressureType]; + } + + async getSaturationTemperature({ pressure, refrigerant = this.defaultRefrigerant, pressureUnit = this.defaultPressureUnit, tempUnit = this.defaultTempUnit }) { + try { + await this._ensureInit({ refrigerant, pressureUnit, tempUnit }); + const pressurePa = this._convertPressureToPa(pressure, pressureUnit); + let tempK; + if(this.customRef){ + tempK = this._interpolateSaturationTemperature(pressurePa, customRefs[refrigerant].saturation); + }else{ + tempK = coolprop.PropsSI('T', 'P', pressurePa, 'Q', 0, this.customRefString || refrigerant); + } + + return { + type: 'success', + temperature: this._convertTempFromK(tempK, tempUnit), + refrigerant, + units: { + temperature: tempUnit, + pressure: pressureUnit + } + }; + } catch (error) { + return { type: 'error', message: error.message }; + } + } + + + async getSaturationPressure({ temperature, refrigerant = this.defaultRefrigerant, tempUnit = this.defaultTempUnit, pressureUnit = this.defaultPressureUnit }) { + try { + await this._ensureInit({ refrigerant, tempUnit, pressureUnit }); + const tempK = this._convertTempToK(temperature, tempUnit); + let pressurePa; + + if(this.customRef){ + pressurePa = this._interpolateSaturationPressure(tempK, customRefs[refrigerant].saturation); + }else{ + pressurePa = coolprop.PropsSI('P', 'T', tempK, 'Q', 0, this.customRefString || refrigerant); + } + + return { + type: 'success', + pressure: this._convertPressureFromPa(pressurePa, pressureUnit), + refrigerant, + units: { + temperature: tempUnit, + pressure: pressureUnit + } + }; + } catch (error) { + return { type: 'error', message: error.message }; + } + } + + async calculateSubcooling({ temperature, pressure, refrigerant = this.defaultRefrigerant, tempUnit = this.defaultTempUnit, pressureUnit = this.defaultPressureUnit }) { + try { + await this._ensureInit({ refrigerant, tempUnit, pressureUnit }); + const tempK = this._convertTempToK(temperature, tempUnit); + const pressurePa = this._convertPressureToPa(pressure, pressureUnit); + let satTempK; + if(this.customRef){ + // Use liquid pressure for subcooling + satTempK = this._interpolateSaturationTemperature(pressurePa, customRefs[refrigerant].saturation, 'liquid'); + }else{ + satTempK = coolprop.PropsSI('T', 'P', pressurePa, 'Q', 0, this.customRefString || refrigerant); + } + const subcooling = satTempK - tempK; + const result = { + type: 'success', + subcooling: Math.max(0, this._convertDeltaTempFromK(subcooling, tempUnit)), // can't have less than 0 degrees subcooling + saturationTemperature: this._convertTempFromK(satTempK, tempUnit), + refrigerant, + units: { + temperature: tempUnit, + pressure: pressureUnit + } + }; + if(result.subcooling == Infinity && result.saturationTemperature == Infinity) { + return { type: 'error', message: 'Subcooling is infinity', note: 'If the pressures are in an expected range that this should work, please check your refrigerant type works in coolprop. "R507" for example is not supported, as it needs to be "R507a"'}; + } + return result; + } catch (error) { + return { type: 'error', message: error.message }; + } + } + + async calculateSuperheat({ temperature, pressure, refrigerant = this.defaultRefrigerant, tempUnit = this.defaultTempUnit, pressureUnit = this.defaultPressureUnit }) { + try { + await this._ensureInit({ refrigerant, tempUnit, pressureUnit }); + const tempK = this._convertTempToK(temperature, tempUnit); + const pressurePa = this._convertPressureToPa(pressure, pressureUnit); + //console.log(`In calculateSuperheat, pressurePa: ${pressurePa}, pressure: ${pressure}, pressureUnit: ${pressureUnit}, refrigerant: ${this.customRefString || refrigerant}`); + let satTempK; + if(this.customRef){ + // Use vapor pressure for superheat + satTempK = this._interpolateSaturationTemperature(pressurePa, customRefs[refrigerant].saturation, 'vapor'); + }else{ + satTempK = coolprop.PropsSI('T', 'P', pressurePa, 'Q', 1, this.customRefString || refrigerant); + } + const superheat = tempK - satTempK; + //console.log(`superheat: ${superheat}, calculatedSuperheat: ${this._convertDeltaTempFromK(superheat, tempUnit)}, calculatedSatTempK: ${this._convertTempFromK(satTempK, tempUnit)}, tempK: ${tempK}, tempUnit: ${tempUnit}, pressurePa: ${pressurePa}, pressureUnit: ${pressureUnit}`); + const result = { + type: 'success', + superheat: Math.max(0, this._convertDeltaTempFromK(superheat, tempUnit)), // can't have less than 0 degrees superheat + saturationTemperature: this._convertTempFromK(satTempK, tempUnit), + refrigerant, + units: { + temperature: tempUnit, + pressure: pressureUnit + } + }; + if(result.superheat == Infinity && result.saturationTemperature == Infinity) { + return { type: 'error', message: 'Superheat is infinity', note: 'If the pressures are in an expected range that this should work, please check your refrigerant type works in coolprop. "R507" for example is not supported, as it needs to be "R507a"'}; + } + return result; + } catch (error) { + return { type: 'error', message: error.message }; + } + } + + async getProperties({ temperature, pressure, refrigerant = this.defaultRefrigerant, tempUnit = this.defaultTempUnit, pressureUnit = this.defaultPressureUnit }) { + try { + await this._ensureInit({ refrigerant, tempUnit, pressureUnit }); + const tempK = this._convertTempToK(temperature, tempUnit); + const pressurePa = this._convertPressureToPa(pressure, pressureUnit); + if(this.customRef){ + return { type: 'error', message: 'Custom refrigerants are not supported for getProperties' }; + } + + const props = { + temperature: this._convertTempFromK(tempK, tempUnit), + pressure: this._convertPressureFromPa(pressurePa, pressureUnit), + density: coolprop.PropsSI('D', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant), + enthalpy: coolprop.PropsSI('H', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant), + entropy: coolprop.PropsSI('S', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant), + quality: coolprop.PropsSI('Q', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant), + conductivity: coolprop.PropsSI('L', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant), + viscosity: coolprop.PropsSI('V', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant), + specificHeat: coolprop.PropsSI('C', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant) + }; + + return { + type: 'success', + properties: props, + refrigerant, + units: { + temperature: tempUnit, + pressure: pressureUnit, + density: 'kg/m³', + enthalpy: 'J/kg', + entropy: 'J/kg/K', + quality: 'dimensionless', + conductivity: 'W/m/K', + viscosity: 'Pa·s', + specificHeat: 'J/kg/K' + } + }; + } catch (error) { + return { type: 'error', message: error.message }; + } + } + + // Direct access to CoolProp functions + async getPropsSI() { + if(!this.initialized) { + await coolprop.init(); + } + return coolprop.PropsSI; + } +} + +module.exports = new CoolPropWrapper(); diff --git a/src/coolprop-node/src/refData.js b/src/coolprop-node/src/refData.js new file mode 100644 index 0000000..79a89f9 --- /dev/null +++ b/src/coolprop-node/src/refData.js @@ -0,0 +1,308 @@ +module.exports.R448a = { + saturation: [{ + //values in kelvin, pascal + "K": 233.15, + "liquid": 135137.24, + "vapor": 101352.93 + }, + { + "K": 238.71, + "liquid": 173058.40, + "vapor": 131689.86 + }, + { + "K": 244.26, + "liquid": 218563.80, + "vapor": 168921.55 + }, + { + "K": 249.82, + "liquid": 273032.38, + "vapor": 214426.94 + }, + { + "K": 255.37, + "liquid": 337153.62, + "vapor": 268895.52 + }, + { + "K": 260.93, + "liquid": 412306.47, + "vapor": 333016.76 + }, + { + "K": 266.48, + "liquid": 499869.88, + "vapor": 408859.09 + }, + { + "K": 272.04, + "liquid": 599843.86, + "vapor": 496422.50 + }, + { + "K": 277.59, + "liquid": 714986.30, + "vapor": 598464.91 + }, + { + "K": 283.15, + "liquid": 845986.68, + "vapor": 714986.30 + }, + { + "K": 288.71, + "liquid": 990776.58, + "vapor": 845986.68 + }, + { + "K": 294.26, + "liquid": 1163145.51, + "vapor": 997671.34 + }, + { + "K": 299.82, + "liquid": 1349303.94, + "vapor": 1170040.26 + }, + { + "K": 305.37, + "liquid": 1556146.65, + "vapor": 1363093.46 + }, + { + "K": 310.93, + "liquid": 1783673.64, + "vapor": 1576830.93 + }, + { + "K": 316.48, + "liquid": 2038779.64, + "vapor": 1818147.42 + }, + { + "K": 322.04, + "liquid": 2314569.92, + "vapor": 2087042.94 + }, + { + "K": 327.59, + "liquid": 2617939.23, + "vapor": 2383517.49 + }, + { + "K": 333.15, + "liquid": 2955782.33, + "vapor": 2714465.83 + }, + { + "K": 338.71, + "liquid": 3321204.45, + "vapor": 3086782.71 + }] +} + + +module.exports.R448A = module.exports.R448a; + +module.exports.R449A = { + saturation: [ + { + // values in kelvin, pascal + "K": 233.15, + "liquid": 134447.82, + "vapor": 101352.97 + }, + { + "K": 235.93, + "liquid": 152374.20, + "vapor": 115121.57 + }, + { + "K": 238.71, + "liquid": 171679.52, + "vapor": 131689.92 + }, + { + "K": 241.48, + "liquid": 193052.21, + "vapor": 148949.73 + }, + { + "K": 244.26, + "liquid": 216503.85, + "vapor": 168255.05 + }, + { + "K": 247.04, + "liquid": 242702.42, + "vapor": 189627.74 + }, + { + "K": 249.82, + "liquid": 270979.90, + "vapor": 213768.86 + }, + { + "K": 252.59, + "liquid": 301336.31, + "vapor": 240051.48 + }, + { + "K": 255.37, + "liquid": 334440.63, + "vapor": 267609.92 + }, + { + "K": 258.15, + "liquid": 370292.86, + "vapor": 298655.80 + }, + { + "K": 260.93, + "liquid": 408892.90, + "vapor": 331760.12 + }, + { + "K": 263.71, + "liquid": 450240.76, + "vapor": 367612.35 + }, + { + "K": 266.48, + "liquid": 495036.08, + "vapor": 406831.32 + }, + { + "K": 269.26, + "liquid": 542579.32, + "vapor": 448868.64 + }, + { + "K": 272.04, + "liquid": 594279.82, + "vapor": 493663.96 + }, + { + "K": 274.82, + "liquid": 649728.18, + "vapor": 542579.32 + }, + { + "K": 277.59, + "liquid": 708053.32, + "vapor": 594969.28 + }, + { + "K": 280.37, + "liquid": 770873.08, + "vapor": 650767.64 + }, + { + "K": 283.15, + "liquid": 839126.92, + "vapor": 710801.16 + }, + { + "K": 285.93, + "liquid": 912814.72, + "vapor": 774989.44 + }, + { + "K": 288.71, + "liquid": 983940.92, + "vapor": 845977.32 + }, + { + "K": 291.48, + "liquid": 1066606.52, + "vapor": 914889.32 + }, + { + "K": 294.26, + "liquid": 1151351.00, + "vapor": 990835.62 + }, + { + "K": 297.04, + "liquid": 1238843.30, + "vapor": 1073501.22 + }, + { + "K": 299.82, + "liquid": 1335552.20, + "vapor": 1165089.32 + }, + { + "K": 302.59, + "liquid": 1432261.10, + "vapor": 1256677.42 + }, + { + "K": 305.37, + "liquid": 1535864.72, + "vapor": 1357134.12 + }, + { + "K": 308.15, + "liquid": 1646363.00, + "vapor": 1457590.92 + }, + { + "K": 310.93, + "liquid": 1763756.02, + "vapor": 1568089.12 + }, + { + "K": 313.71, + "liquid": 1887043.62, + "vapor": 1678587.32 + }, + { + "K": 316.48, + "liquid": 2017225.92, + "vapor": 1802217.02 + }, + { + "K": 319.26, + "liquid": 2147408.22, + "vapor": 1934952.12 + }, + { + "K": 322.04, + "liquid": 2291329.82, + "vapor": 2072621.52 + }, + { + "K": 324.82, + "liquid": 2435251.42, + "vapor": 2217185.62 + }, + { + "K": 327.59, + "liquid": 2592912.32, + "vapor": 2368644.42 + }, + { + "K": 330.37, + "liquid": 2750573.22, + "vapor": 2526305.32 + }, + { + "K": 333.15, + "liquid": 2925424.52, + "vapor": 2690860.82 + }, + { + "K": 335.93, + "liquid": 3100275.92, + "vapor": 2871668.52 + }, + { + "K": 338.71, + "liquid": 3288922.02, + "vapor": 3059370.92 + } + ]} + + module.exports.R449a = module.exports.R449A; \ No newline at end of file diff --git a/src/coolprop-node/test/R448a.test.js b/src/coolprop-node/test/R448a.test.js new file mode 100644 index 0000000..8b442cd --- /dev/null +++ b/src/coolprop-node/test/R448a.test.js @@ -0,0 +1,94 @@ +const coolprop = require('../src/index.js'); + +describe('R448a Real Values', () => { + it('should calculate superheat correctly at -40°C saturation', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -35, // 5K above saturation temp of -40°C + pressure: 0, // saturation pressure at -40°C (from chart) + refrigerant: 'R448a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat - 5)).toBeLessThan(0.2); // Should be ~5K superheat + }); + + it('should calculate superheat correctly at -20°C saturation', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -15, // 5K above saturation temp of -20°C + pressure: 21.0, // saturation pressure at -20°C (from chart) + refrigerant: 'R448a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + //console.log(result); + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat - 5)).toBeLessThan(0.2); // Should be ~5K superheat + }); + + it('should calculate subcooling correctly at 30°C saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 25, // 5K below saturation temp of 30°C + pressure: 198.1, // saturation pressure at 30°C (from chart) + refrigerant: 'R448a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.2); // Should be ~5K subcooling + }); + + it('should calculate subcooling correctly at 40°C saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 35, // 5K below saturation temp of 40°C + pressure: 258.0, // saturation pressure at 40°C (from chart) + refrigerant: 'R448a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.2); // Should be ~5K subcooling + }); + + it('should calculate zero superheat at saturation point', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 0, // Exact saturation temperature + pressure: 60.1, // Matching saturation pressure from chart + refrigerant: 'R448a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat)).toBeLessThan(0.2); // Should be ~0K superheat + }); + + it('should calculate zero subcooling at saturation point', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 20, // Exact saturation temperature + pressure: 148.5, // Matching saturation pressure from chart + refrigerant: 'R448a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling)).toBeLessThan(0.2); // Should be ~0K subcooling + }); + + + it('It should also work with R448A (capital A)', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 20, // Exact saturation temperature + pressure: 148.5, // Matching saturation pressure from chart + refrigerant: 'R448A', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling)).toBeLessThan(0.2); // Should be ~0K subcooling + }); +}); \ No newline at end of file diff --git a/src/coolprop-node/test/R449a.test.js b/src/coolprop-node/test/R449a.test.js new file mode 100644 index 0000000..bbb4f51 --- /dev/null +++ b/src/coolprop-node/test/R449a.test.js @@ -0,0 +1,94 @@ +const coolprop = require('../src/index.js'); + +describe('R449a Real Values', () => { + it('should calculate superheat correctly at -40°C saturation', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -35, // 5K above saturation temp of -40°C + pressure: 0, // saturation pressure at -40°C (from chart) + refrigerant: 'R449a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat - 5)).toBeLessThan(0.2); // Should be ~5K superheat + }); + + it('should calculate superheat correctly at -20°C saturation', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -15, // 5K above saturation temp of -20°C + pressure: 20.96, // saturation pressure at -20°C (from chart) + refrigerant: 'R449a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + //console.log(result); + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat - 5)).toBeLessThan(0.2); // Should be ~5K superheat + }); + + it('should calculate subcooling correctly at 30°C saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 25, // 5K below saturation temp of 30°C + pressure: 195, // saturation pressure at 30°C (from chart) + refrigerant: 'R449a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.2); // Should be ~5K subcooling + }); + + it('should calculate subcooling correctly at 40°C saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 35, // 5K below saturation temp of 40°C + pressure: 254.2, // saturation pressure at 40°C (from chart) + refrigerant: 'R449a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.2); // Should be ~5K subcooling + }); + + it('should calculate zero superheat at saturation point', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 0, // Exact saturation temperature + pressure: 74.05, // Matching saturation pressure from chart + refrigerant: 'R449a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat)).toBeLessThan(0.2); // Should be ~0K superheat + }); + + it('should calculate zero subcooling at saturation point', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 20, // Exact saturation temperature + pressure: 146.0, // Matching saturation pressure from chart + refrigerant: 'R449a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling)).toBeLessThan(0.2); // Should be ~0K subcooling + }); + + + it('It should also work with R449A (capital A)', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 20, // Exact saturation temperature + pressure: 146.0, // Matching saturation pressure from chart + refrigerant: 'R449A', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling)).toBeLessThan(0.2); // Should be ~0K subcooling + }); +}); \ No newline at end of file diff --git a/src/coolprop-node/test/R507.test.js b/src/coolprop-node/test/R507.test.js new file mode 100644 index 0000000..0cd9dc5 --- /dev/null +++ b/src/coolprop-node/test/R507.test.js @@ -0,0 +1,97 @@ +const coolprop = require('../src/index.js'); + +describe('R507 Real Values', () => { + it('should calculate superheat correctly at -40°C saturation', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -35, // 5K above saturation temp of -40°C + pressure: 5.4, // saturation pressure at -40°C (from chart) + refrigerant: 'R507a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat - 5)).toBeLessThan(0.1); // Should be ~5K superheat + }); + + it('should calculate superheat correctly at -20°C saturation', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -15, // 5K above saturation temp of -20°C + pressure: 30.9, // saturation pressure at -20°C (from chart) + refrigerant: 'R507a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat - 5)).toBeLessThan(0.1); // Should be ~5K superheat + }); + + it('should calculate subcooling correctly at 30°C saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 25, // 5K below saturation temp of 30°C + pressure: 196.9, // saturation pressure at 30°C (from chart) + refrigerant: 'R507a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.1); // Should be ~5K subcooling + }); + + + + it('should calculate subcooling correctly at 40°C saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 35, // 5K below saturation temp of 40°C + pressure: 256.2, // saturation pressure at 40°C (from chart) + refrigerant: 'R507a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.1); // Should be ~5K subcooling + }); + + it('should calculate zero superheat at saturation point', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 0, // Exact saturation temperature + pressure: 75.8, // Matching saturation pressure from chart + refrigerant: 'R507a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat)).toBeLessThan(0.1); // Should be ~0K superheat + }); + + it('should calculate zero subcooling at saturation point', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 20, // Exact saturation temperature + pressure: 148, // Matching saturation pressure from chart + refrigerant: 'R507a', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling)).toBeLessThan(0.1); // Should be ~0K subcooling + }); + + it('should calculate subcooling correctly at 30°C saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 25, // 5K below saturation temp of 30°C + pressure: 196.9, // saturation pressure at 30°C (from chart) + refrigerant: 'R507', + tempUnit: 'C', + pressureUnit: 'psig' + }); + + expect(result.type).toBe('error'); + expect(result.message).toBe('Subcooling is infinity'); + expect(result.note).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/src/coolprop-node/test/R744.C..test.js b/src/coolprop-node/test/R744.C..test.js new file mode 100644 index 0000000..fb48468 --- /dev/null +++ b/src/coolprop-node/test/R744.C..test.js @@ -0,0 +1,55 @@ +const coolprop = require('../src/index.js'); + +describe('R744 (CO2) Real Values', () => { + it('should calculate superheat correctly at -40°C saturation', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -35, // 5K above saturation temp of -40°C + pressure: 9.03, // saturation pressure at -40°C (from chart) + refrigerant: 'R744', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat - 5)).toBeLessThan(0.1); // Should be ~5K superheat + }); + + it('should calculate subcooling correctly at 0°C saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: -5, // 5K below saturation temp of 0°C + pressure: 33.84, // saturation pressure at 0°C (from chart) + refrigerant: 'R744', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.1); // Should be ~5K subcooling + }); + + it('should calculate zero superheat at saturation point', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -20, // Exact saturation temperature + pressure: 18.68, // Matching saturation pressure from chart + refrigerant: 'R744', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat)).toBeLessThan(0.1); // Should be ~0K superheat + }); + + it('should calculate zero subcooling at saturation point', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 10, // Exact saturation temperature + pressure: 44.01, // Matching saturation pressure from chart + refrigerant: 'R744', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling)).toBeLessThan(0.1); // Should be ~0K subcooling + }); +}); \ No newline at end of file diff --git a/src/coolprop-node/test/R744.F.test.js b/src/coolprop-node/test/R744.F.test.js new file mode 100644 index 0000000..202665b --- /dev/null +++ b/src/coolprop-node/test/R744.F.test.js @@ -0,0 +1,55 @@ +const coolprop = require('../src/index.js'); + +describe('R744 (CO2) Real Values', () => { + it('should calculate superheat correctly at -40°F saturation', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: -35, // 5°F above saturation temp of -40°F + pressure: 131, // saturation pressure at -40°F (from chart) + refrigerant: 'R744', + tempUnit: 'F', // Changed to F + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat - 5)).toBeLessThan(0.1); // Should be ~5°F superheat + }); + + it('should calculate subcooling correctly at 32°F saturation', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 27, // 5°F below saturation temp of 32°F + pressure: 490.8, // saturation pressure at 32°F (from chart) + refrigerant: 'R744', + tempUnit: 'F', // Changed to F + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.1); // Should be ~5°F subcooling + }); + + it('should calculate zero superheat at saturation point', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 32, // Exact saturation temperature + pressure: 490.8, // Matching saturation pressure from chart + refrigerant: 'R744', + tempUnit: 'F', // Changed to F + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.superheat)).toBeLessThan(0.1); // Should be ~0°F superheat + }); + + it('should calculate zero subcooling at saturation point', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 32, // Exact saturation temperature + pressure: 490.8, // Matching saturation pressure from chart + refrigerant: 'R744', + tempUnit: 'F', // Changed to F + pressureUnit: 'psig' + }); + + expect(result.type).toBe('success'); + expect(Math.abs(result.subcooling)).toBeLessThan(0.1); // Should be ~0°F subcooling + }); +}); \ No newline at end of file diff --git a/src/coolprop-node/test/nodeprop.test.js b/src/coolprop-node/test/nodeprop.test.js new file mode 100644 index 0000000..fed8032 --- /dev/null +++ b/src/coolprop-node/test/nodeprop.test.js @@ -0,0 +1,296 @@ +const coolprop = require('../src/index.js'); + +describe('CoolProp Wrapper', () => { + describe('Initialization', () => { + it('should fail without refrigerant', async () => { + const result = await coolprop.init({}); + expect(result.type).toBe('error'); + expect(result.message).toContain('Refrigerant must be specified'); + }); + + it('should fail with invalid temperature unit', async () => { + const result = await coolprop.init({ refrigerant: 'R404A', tempUnit: 'X' }); + expect(result.type).toBe('error'); + expect(result.message).toContain('Invalid temperature unit'); + }); + + it('should fail with invalid pressure unit', async () => { + const result = await coolprop.init({ refrigerant: 'R404A', pressureUnit: 'X' }); + expect(result.type).toBe('error'); + expect(result.message).toContain('Invalid pressure unit'); + }); + + it('should succeed with valid config', async () => { + const result = await coolprop.init({ + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + console.log(result); + expect(result.type).toBe('success'); + }); + }); + + describe('Auto-initialization', () => { + it('should work without explicit init', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 25, + pressure: 10, + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + expect(result.type).toBe('success'); + expect(result.superheat).toBeDefined(); + }); + }); + + describe('Unit Conversions', () => { + it('should correctly convert temperature units', async () => { + const resultC = await coolprop.getSaturationTemperature({ + pressure: 10, + refrigerant: 'R404A', + pressureUnit: 'bar', + tempUnit: 'C' + }); + + const resultF = await coolprop.getSaturationTemperature({ + pressure: 10, + refrigerant: 'R404A', + pressureUnit: 'bar', + tempUnit: 'F' + }); + + const resultK = await coolprop.getSaturationTemperature({ + pressure: 10, + refrigerant: 'R404A', + pressureUnit: 'bar', + tempUnit: 'K' + }); + + expect(Math.abs((resultC.temperature * 9/5 + 32) - resultF.temperature)).toBeLessThan(0.01); + expect(Math.abs((resultC.temperature + 273.15) - resultK.temperature)).toBeLessThan(0.01); + }); + + it('should correctly convert pressure units', async () => { + const resultBar = await coolprop.getSaturationPressure({ + temperature: 25, + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + const resultPsi = await coolprop.getSaturationPressure({ + temperature: 25, + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'psi' + }); + + expect(Math.abs((resultBar.pressure * 14.5038) - resultPsi.pressure)).toBeLessThan(0.1); + }); + }); + + describe('Refrigerant Calculations', () => { + const refrigerants = ['R404A', 'R134a', 'R507A', 'R744']; + + refrigerants.forEach(refrigerant => { + describe(refrigerant, () => { + it('should calculate superheat', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 25, + pressure: 10, + refrigerant, + tempUnit: 'C', + pressureUnit: 'bar' + }); + expect(result.type).toBe('success'); + expect(result.superheat).toBeDefined(); + expect(result.refrigerant).toBe(refrigerant); + expect(result.units).toEqual(expect.objectContaining({ + temperature: 'C', + pressure: 'bar' + })); + }); + + it('should calculate subcooling', async () => { + const result = await coolprop.calculateSubcooling({ + temperature: 20, + pressure: 20, + refrigerant, + tempUnit: 'C', + pressureUnit: 'bar' + }); + expect(result.type).toBe('success'); + expect(result.subcooling).toBeDefined(); + expect(result.refrigerant).toBe(refrigerant); + }); + + it('should get all properties', async () => { + const result = await coolprop.getProperties({ + temperature: 25, + pressure: 10, + refrigerant, + tempUnit: 'C', + pressureUnit: 'bar' + }); + expect(result.type).toBe('success'); + expect(result.properties).toBeDefined(); + expect(result.refrigerant).toBe(refrigerant); + + // Check all required properties exist + const requiredProps = [ + 'temperature', 'pressure', 'density', 'enthalpy', + 'entropy', 'quality', 'conductivity', 'viscosity', 'specificHeat' + ]; + requiredProps.forEach(prop => { + expect(result.properties[prop]).toBeDefined(); + expect(typeof result.properties[prop]).toBe('number'); + }); + }); + }); + }); + }); + + describe('Default Override Behavior', () => { + beforeAll(async () => { + await coolprop.init({ + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + }); + + it('should use defaults when no overrides provided', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 25, + pressure: 10 + }); + expect(result.refrigerant).toBe('R404A'); + expect(result.units.temperature).toBe('C'); + expect(result.units.pressure).toBe('bar'); + }); + + it('should allow refrigerant override', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 25, + pressure: 10, + refrigerant: 'R134a' + }); + expect(result.refrigerant).toBe('R134a'); + }); + + it('should allow unit overrides', async () => { + const result = await coolprop.calculateSuperheat({ + temperature: 77, + pressure: 145, + tempUnit: 'F', + pressureUnit: 'psi' + }); + expect(result.units.temperature).toBe('F'); + expect(result.units.pressure).toBe('psi'); + }); + }); + + describe('Default Settings Management', () => { + it('should allow updating defaults after initialization', async () => { + // Initial setup + await coolprop.init({ + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + // Update defaults + const updateResult = await coolprop.init({ + refrigerant: 'R134a', + tempUnit: 'F', + pressureUnit: 'psi' + }); + + expect(updateResult.type).toBe('success'); + expect(updateResult.message).toBe('Default settings updated'); + + // Verify new defaults are used + const result = await coolprop.calculateSuperheat({ + temperature: 77, + pressure: 145 + }); + + expect(result.refrigerant).toBe('R134a'); + expect(result.units.temperature).toBe('F'); + expect(result.units.pressure).toBe('psi'); + }); + + it('should update the coolprop instance if refrigerant is changed', async () => { + // Set initial defaults + await coolprop.init({ + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + const config = await coolprop.getConfig(); + + // First call with overrides + const result1 = await coolprop.calculateSuperheat({ + temperature: 25, + pressure: 10, + refrigerant: 'R507A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + // Second call using defaults + const result2 = await coolprop.calculateSuperheat({ + temperature: 25, + pressure: 10 + }); + const config2 = await coolprop.getConfig(); + expect(config.refrigerant).toBe('R404A'); + expect(config2.refrigerant).toBe('R507A'); + expect(result1.refrigerant).toBe('R507A'); + expect(result2.refrigerant).toBe('R507A'); + }); + + it('should allow partial updates of defaults', async () => { + // Initial setup + await coolprop.init({ + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + // Update only temperature unit + await coolprop.init({ + tempUnit: 'F' + }); + + const result = await coolprop.calculateSuperheat({ + temperature: 77, + pressure: 10 + }); + + expect(result.refrigerant).toBe('R404A'); // unchanged + expect(result.units.temperature).toBe('F'); // updated + expect(result.units.pressure).toBe('bar'); // unchanged + }); + + it('should validate units when updating defaults', async () => { + await coolprop.init({ + refrigerant: 'R404A', + tempUnit: 'C', + pressureUnit: 'bar' + }); + + const result = await coolprop.init({ + tempUnit: 'X' // invalid unit + }); + + expect(result.type).toBe('error'); + expect(result.message).toContain('Invalid temperature unit'); + }); + }); + + +}); \ No newline at end of file diff --git a/src/coolprop-node/test/pressure-conversions.test.js b/src/coolprop-node/test/pressure-conversions.test.js new file mode 100644 index 0000000..5c50994 --- /dev/null +++ b/src/coolprop-node/test/pressure-conversions.test.js @@ -0,0 +1,58 @@ +const coolprop = require('../src/index.js'); + +describe('Pressure Conversion Chain Tests', () => { + + test('bar -> pa -> bara -> pa -> bar conversion chain', () => { + const startValue = 2; // 2 bar gauge + + const toPa = coolprop._convertPressureToPa(startValue, 'bar'); + // console.log('bar to Pa:', toPa); + + const toBara = coolprop._convertPressureFromPa(toPa, 'bara'); + // console.log('Pa to bara:', toBara); + + const backToPa = coolprop._convertPressureToPa(toBara, 'bara'); + // console.log('bara to Pa:', backToPa); + + const backToBar = coolprop._convertPressureFromPa(backToPa, 'bar'); + // console.log('Pa to bar:', backToBar); + + expect(Math.round(backToBar * 1000) / 1000).toBe(startValue); + }); + + test('psi -> pa -> psia -> pa -> psi conversion chain', () => { + const startValue = 30; // 30 psi gauge + + const toPa = coolprop._convertPressureToPa(startValue, 'psi'); + // console.log('psi to Pa:', toPa); + + const toPsia = coolprop._convertPressureFromPa(toPa, 'psia'); + // console.log('Pa to psia:', toPsia); + + const backToPa = coolprop._convertPressureToPa(toPsia, 'psia'); + // console.log('psia to Pa:', backToPa); + + const backToPsi = coolprop._convertPressureFromPa(backToPa, 'psi'); + // console.log('Pa to psi:', backToPsi); + + expect(Math.round(backToPsi * 1000) / 1000).toBe(startValue); + }); + + test('kpa -> pa -> kpaa -> pa -> kpa conversion chain', () => { + const startValue = 200; // 200 kPa gauge + + const toPa = coolprop._convertPressureToPa(startValue, 'kpa'); + // console.log('kpa to Pa:', toPa); + + const toKpaa = coolprop._convertPressureFromPa(toPa, 'kpaa'); + // console.log('Pa to kpaa:', toKpaa); + + const backToPa = coolprop._convertPressureToPa(toKpaa, 'kpaa'); + // console.log('kpaa to Pa:', backToPa); + + const backToKpa = coolprop._convertPressureFromPa(backToPa, 'kpa'); + // console.log('Pa to kpa:', backToKpa); + + expect(Math.round(backToKpa * 1000) / 1000).toBe(startValue); + }); +}); \ No newline at end of file diff --git a/src/coolprop-node/test/propsSI.test.js b/src/coolprop-node/test/propsSI.test.js new file mode 100644 index 0000000..fc0f264 --- /dev/null +++ b/src/coolprop-node/test/propsSI.test.js @@ -0,0 +1,50 @@ +const coolProp = require('../src/index.js'); + +describe('PropsSI Direct Access', () => { + let PropsSI; + + beforeAll(async () => { + // Get the PropsSI function + PropsSI = await coolProp.getPropsSI(); + }); + + test('should initialize and return PropsSI function', async () => { + expect(typeof PropsSI).toBe('function'); + }); + + test('should calculate saturation temperature of R134a at 1 bar', () => { + const pressure = 100000; // 1 bar in Pa + const temp = PropsSI('T', 'P', pressure, 'Q', 0, 'R134a'); + expect(temp).toBeCloseTo(246.79, 1); // ~246.79 K at 1 bar + }); + + test('should calculate density of R134a at specific conditions', () => { + const temp = 300; // 300 K + const pressure = 100000; // 1 bar in Pa + const density = PropsSI('D', 'T', temp, 'P', pressure, 'R134a'); + expect(density).toBeGreaterThan(0) + expect(density).toBeLessThan(Infinity); + }); + + test('should throw error for invalid refrigerant', () => { + const temp = 300; + const pressure = 100000; + expect(() => { + let result = PropsSI('D', 'T', temp, 'P', pressure, 'INVALID_REFRIGERANT'); + if(result == Infinity) { + throw new Error('Infinity due to invalid refrigerant'); + } + }).toThrow(); + }); + + test('should throw error for invalid input parameter', () => { + const temp = 300; + const pressure = 100000; + expect(() => { + let result = PropsSI('INVALID_PARAM', 'T', temp, 'P', pressure, 'R134a'); + if(result == Infinity) { + throw new Error('Infinity due to invalid input parameter'); + } + }).toThrow(); + }); +}); \ No newline at end of file diff --git a/src/coolprop-node/test/temperature-conversions.test.js b/src/coolprop-node/test/temperature-conversions.test.js new file mode 100644 index 0000000..578f5b7 --- /dev/null +++ b/src/coolprop-node/test/temperature-conversions.test.js @@ -0,0 +1,128 @@ +const coolprop = require('../src/index.js'); + +describe('Temperature Conversion Tests', () => { + + describe('Regular Temperature Conversions', () => { + const testCases = [ + { + startUnit: 'C', + startValue: 25, + expectedK: 298.15, + conversions: { + F: 77, + K: 298.15, + C: 25 + } + }, + { + startUnit: 'F', + startValue: 77, + expectedK: 298.15, + conversions: { + F: 77, + K: 298.15, + C: 25 + } + }, + { + startUnit: 'K', + startValue: 298.15, + expectedK: 298.15, + conversions: { + F: 77, + K: 298.15, + C: 25 + } + } + ]; + + testCases.forEach(({ startUnit, startValue, expectedK, conversions }) => { + test(`${startValue}${startUnit} conversion chain`, () => { + // First convert to Kelvin + const toK = coolprop._convertTempToK(startValue, startUnit); + expect(Math.round(toK * 100) / 100).toBe(expectedK); + + // Then convert from Kelvin to each unit + Object.entries(conversions).forEach(([unit, expected]) => { + const converted = coolprop._convertTempFromK(toK, unit); + expect(Math.round(converted * 100) / 100).toBe(expected); + }); + }); + }); + }); + + describe('Delta Temperature Conversions', () => { + const testCases = [ + { + startValue: 10, // 10K temperature difference + expected: { + K: 10, + C: 10, + F: 18 // 10K = 18°F difference + } + } + ]; + + testCases.forEach(({ startValue, expected }) => { + test(`${startValue}K delta conversion to all units`, () => { + Object.entries(expected).forEach(([unit, expectedValue]) => { + const converted = coolprop._convertDeltaTempFromK(startValue, unit); + expect(Math.round(converted * 100) / 100).toBe(expectedValue); + }); + }); + }); + }); + + describe('Common Temperature Points', () => { + const commonPoints = [ + { + description: 'Water freezing point', + C: 0, + F: 32, + K: 273.15 + }, + { + description: 'Water boiling point', + C: 100, + F: 212, + K: 373.15 + }, + { + description: 'Room temperature', + C: 20, + F: 68, + K: 293.15 + }, + { + description: 'Typical refrigeration evaporator', + C: 5, + F: 41, + K: 278.15 + }, + { + description: 'Typical refrigeration condenser', + C: 35, + F: 95, + K: 308.15 + } + ]; + + commonPoints.forEach(point => { + test(`${point.description} conversions`, () => { + // Test conversion to Kelvin from each unit + const fromC = coolprop._convertTempToK(point.C, 'C'); + const fromF = coolprop._convertTempToK(point.F, 'F'); + + expect(Math.round(fromC * 100) / 100).toBe(point.K); + expect(Math.round(fromF * 100) / 100).toBe(point.K); + + // Test conversion from Kelvin to each unit + const toC = coolprop._convertTempFromK(point.K, 'C'); + const toF = coolprop._convertTempFromK(point.K, 'F'); + + expect(Math.round(toC * 100) / 100).toBe(point.C); + expect(Math.round(toF * 100) / 100).toBe(point.F); + }); + }); + }); +}); \ No newline at end of file diff --git a/src/measurements/Measurement.js b/src/measurements/Measurement.js index f175546..761432b 100644 --- a/src/measurements/Measurement.js +++ b/src/measurements/Measurement.js @@ -67,6 +67,23 @@ class Measurement { if (this.values.length === 0) return null; return this.values[this.values.length - 1]; } + + getLaggedValue(lag){ + if(this.values.length <= lag) return null; + return this.values[this.values.length - lag]; + } + + getLaggedSample(lag){ + if (lag < 0) throw new Error('lag must be >= 0'); + const index = this.values.length - 1 - lag; + if (index < 0) return null; + + return { + value: this.values[index], + timestamp: this.timestamps[index], + unit: this.unit, + }; + } getAverage() { if (this.values.length === 0) return null; diff --git a/src/measurements/MeasurementContainer.js b/src/measurements/MeasurementContainer.js index 88cbdd3..cc09839 100644 --- a/src/measurements/MeasurementContainer.js +++ b/src/measurements/MeasurementContainer.js @@ -94,7 +94,8 @@ class MeasurementContainer { throw new Error('Variant must be specified before position'); } - this._currentPosition = positionValue; + + this._currentPosition = positionValue.toString().toLowerCase();; return this; } @@ -163,7 +164,7 @@ class MeasurementContainer { // Emit the exact event your parent expects this.emitter.emit(`${this._currentType}.${this._currentVariant}.${this._currentPosition}`, eventData); - console.log(`Emitted event: ${this._currentType}.${this._currentVariant}.${this._currentPosition}`); + //console.log(`Emitted event: ${this._currentType}.${this._currentVariant}.${this._currentPosition}`, eventData); return this; } @@ -247,38 +248,65 @@ class MeasurementContainer { return measurement ? measurement.getAllValues() : null; } + getLaggedValue(lag = 1,requestedUnit = null ){ + const measurement = this.get(); + if (!measurement) return null; + + const value = measurement.getLaggedSample(lag); + if (value === null) return null; + + // Return as-is if no unit conversion requested + if (!requestedUnit) { + return value; + } + + // Convert if needed + if (measurement.unit && requestedUnit !== measurement.unit) { + try { + return convertModule(value).from(measurement.unit).to(requestedUnit); + } catch (error) { + if (this.logger) { + this.logger.error(`Unit conversion failed: ${error.message}`); + } + return value; // Return original value if conversion fails + } + } + + return value; + } // Difference calculations between positions - difference(requestedUnit = null) { - - if (!this._currentType || !this._currentVariant) { - throw new Error('Type and variant must be specified for difference calculation'); - } - const upstream = this.measurements?.[this._currentType]?.[this._currentVariant]?.['upstream'] || null; - const downstream = this.measurements?.[this._currentType]?.[this._currentVariant]?.['downstream'] || null; - - if (!upstream || !downstream || upstream.values.length === 0 || downstream.values.length === 0) { - return null; - } - - // Get target unit for conversion - const targetUnit = requestedUnit || upstream.unit || downstream.unit; - - // Get values in the same unit - const upstreamValue = this._convertValueToUnit(upstream.getCurrentValue(), upstream.unit, targetUnit); - const downstreamValue = this._convertValueToUnit(downstream.getCurrentValue(), downstream.unit, targetUnit); - - const upstreamAvg = this._convertValueToUnit(upstream.getAverage(), upstream.unit, targetUnit); - const downstreamAvg = this._convertValueToUnit(downstream.getAverage(), downstream.unit, targetUnit); - - return { - value: downstreamValue - upstreamValue, - avgDiff: downstreamAvg - upstreamAvg, - unit: targetUnit - }; +difference({ from = "downstream", to = "upstream", unit: requestedUnit } = {}) { + if (!this._currentType || !this._currentVariant) { + throw new Error("Type and variant must be specified for difference calculation"); } + const get = pos => + this.measurements?.[this._currentType]?.[this._currentVariant]?.[pos] || null; + + const a = get(from); + const b = get(to); + if (!a || !b || a.values.length === 0 || b.values.length === 0) { + return null; + } + + const targetUnit = requestedUnit || a.unit || b.unit; + const aVal = this._convertValueToUnit(a.getCurrentValue(), a.unit, targetUnit); + const bVal = this._convertValueToUnit(b.getCurrentValue(), b.unit, targetUnit); + + const aAvg = this._convertValueToUnit(a.getAverage(), a.unit, targetUnit); + const bAvg = this._convertValueToUnit(b.getAverage(), b.unit, targetUnit); + + return { + value: aVal - bVal, + avgDiff: aAvg - bAvg, + unit: targetUnit, + from, + to, + }; +} + // Helper methods _ensureChainIsValid() { if (!this._currentType || !this._currentVariant || !this._currentPosition) { diff --git a/src/measurements/examples.js b/src/measurements/examples.js index bc756f5..9521a7a 100644 --- a/src/measurements/examples.js +++ b/src/measurements/examples.js @@ -213,6 +213,10 @@ const pressureDiff = basicContainer console.log(`Pressure difference: ${pressureDiff.value} ${pressureDiff.unit}\n`); +//reversable difference +const deltaP = basicContainer.type("pressure").variant("measured").difference(); // defaults to downstream - upstream +const netFlow = basicContainer.type("flow").variant("measured").difference({ from: "upstream", to: "downstream" }); + // ==================================== // ADVANCED STATISTICS & HISTORY // ==================================== @@ -248,6 +252,28 @@ const allValues = stats.getAllValues(); console.log(` Samples: ${allValues.values.length}`); console.log(` History: [${allValues.values.join(', ')}]\n`); +console.log('--- Lagged sample comparison ---'); + +const latest = stats.getCurrentValue(); // existing helper +const prevSample = stats.getLaggedValue(1); // new helper +const prevPrevSample = stats.getLaggedValue(2); // optional + +if (prevSample) { + const delta = latest - prevSample.value; + console.log( + `Current vs previous: ${latest} ${statsData.unit} (t=${stats.get().getLatestTimestamp()}) vs ` + + `${prevSample.value} ${prevSample.unit} (t=${prevSample.timestamp})` + ); + console.log(`Δ = ${delta.toFixed(2)} ${statsData.unit}`); +} + +if (prevPrevSample) { + console.log( + `Previous vs 2-steps-back timestamps: ${new Date(prevSample.timestamp).toISOString()} vs ` + + `${new Date(prevPrevSample.timestamp).toISOString()}` + ); +} + // ==================================== // DYNAMIC UNIT MANAGEMENT // ==================================== @@ -299,8 +325,11 @@ basicContainer.getTypes().forEach(type => { } }); + + console.log('\n✅ All examples complete!\n'); + // ==================================== // BEST PRACTICES // ====================================