From cc08de9c64017b07a91f0556b6c0a4986dd38ddf Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 11 Aug 2016 01:13:52 +0100 Subject: [PATCH 01/30] Make sure we actually stop the sync loop on logout I think this was only a problem in the edgiest of edge conditions, but it certainly didn't look right. --- lib/sync.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sync.js b/lib/sync.js index 24c77a2ca..fcc992746 100644 --- a/lib/sync.js +++ b/lib/sync.js @@ -455,6 +455,7 @@ SyncApi.prototype._sync = function(syncOptions) { self._connectionReturnedDefer = null; } this._updateSyncState("STOPPED"); + return; } var filterId = syncOptions.filterId; From bc5621301031543e09ec13987b1fde4d0b409497 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Tue, 9 Aug 2016 17:23:30 +0100 Subject: [PATCH 02/30] Add status_msg to setPresence --- lib/client.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/client.js b/lib/client.js index a150fb79a..773b440aa 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1417,23 +1417,28 @@ MatrixClient.prototype.mxcUrlToHttp = }; /** - * @param {string} presence + * @param {Object} opts Options to apply + * @param {string} opts.presence One of "online", "offline" or "unavailable" + * @param {string} opts.status_msg The status message to attach. * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. * @throws If 'presence' isn't a valid presence enum value. */ -MatrixClient.prototype.setPresence = function(presence, callback) { +MatrixClient.prototype.setPresence = function(opts, callback) { var path = utils.encodeUri("/presence/$userId/status", { $userId: this.credentials.userId }); - var validStates = ["offline", "online", "unavailable"]; - if (validStates.indexOf(presence) == -1) { - throw new Error("Bad presence value: " + presence); + + var content; + if (typeof opts === "string") { + content = { presence: opts } + } + + var validStates = ["offline", "online", "unavailable"]; + if (validStates.indexOf(content.presence) == -1) { + throw new Error("Bad presence value: " + content.presence); } - var content = { - presence: presence - }; return this._http.authedRequest( callback, "PUT", path, undefined, content ); From 02de5e96babbb773d5f27b8f550a89e147ce8f46 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 10 Aug 2016 11:35:01 +0100 Subject: [PATCH 03/30] Add presenceStatusMsg to User --- lib/models/user.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/models/user.js b/lib/models/user.js index 515f0c806..a02e30c95 100644 --- a/lib/models/user.js +++ b/lib/models/user.js @@ -30,6 +30,7 @@ limitations under the License. * @prop {string} displayName The 'displayname' of the user if known. * @prop {string} avatarUrl The 'avatar_url' of the user if known. * @prop {string} presence The presence enum if known. + * @prop {string} presenceStatusMsg The presence status message if known. * @prop {Number} lastActiveAgo The time elapsed in ms since the user interacted * proactively with the server, or we saw a message from the user * @prop {Number} lastPresenceTs Timestamp (ms since the epoch) for when we last @@ -44,6 +45,7 @@ limitations under the License. function User(userId) { this.userId = userId; this.presence = "offline"; + this.presenceStatusMsg = null; this.displayName = userId; this.avatarUrl = null; this.lastActiveAgo = 0; @@ -95,7 +97,9 @@ User.prototype.setPresenceEvent = function(event) { this.presence = event.getContent().presence; eventsToFire.push("User.lastPresenceTs"); - + if (event.getContent().status_msg) { + this.presenceStatusMsg = event.getContent().status_msg; + } if (event.getContent().displayname) { this.displayName = event.getContent().displayname; } From 1bd5d126652b8e4bb47e5e03c91b544e5598ea13 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Thu, 11 Aug 2016 13:37:53 +0100 Subject: [PATCH 04/30] Fixed setPresence opts --- lib/client.js | 9 ++++----- lib/models/user.js | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/client.js b/lib/client.js index 773b440aa..72ec0f25c 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1430,17 +1430,16 @@ MatrixClient.prototype.setPresence = function(opts, callback) { $userId: this.credentials.userId }); - var content; if (typeof opts === "string") { - content = { presence: opts } + opts = { presence: opts } } var validStates = ["offline", "online", "unavailable"]; - if (validStates.indexOf(content.presence) == -1) { - throw new Error("Bad presence value: " + content.presence); + if (validStates.indexOf(opts.presence) == -1) { + throw new Error("Bad presence value: " + opts.presence); } return this._http.authedRequest( - callback, "PUT", path, undefined, content + callback, "PUT", path, undefined, opts ); }; diff --git a/lib/models/user.js b/lib/models/user.js index a02e30c95..9a33e6e21 100644 --- a/lib/models/user.js +++ b/lib/models/user.js @@ -97,6 +97,7 @@ User.prototype.setPresenceEvent = function(event) { this.presence = event.getContent().presence; eventsToFire.push("User.lastPresenceTs"); + if (event.getContent().status_msg) { this.presenceStatusMsg = event.getContent().status_msg; } From 2fd569a61aa157df9900e1eb2fe66d8ac5b56770 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Aug 2016 17:17:28 +0100 Subject: [PATCH 05/30] Prepare changelog for v0.5.5 --- CHANGELOG.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9702efb3..6fcb6a149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,75 @@ -Changes in \ -======================= +Changes in [0.5.5](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.5.5) (2016-08-11) +================================================================================================ +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.5.4...v0.5.5) * Add room.getAliases() and room.getCanonicalAlias * Add API calls `/register/email/requestToken`, `/account/password/email/requestToken` and `/account/3pid/email/requestToken` * Add `User.currentlyActive` and `User.lastPresenceTs` events for changes in fields on the User object * Add `logout` and `deactivateAccount` + * Make sure we actually stop the sync loop on logout + [\#166](https://github.com/matrix-org/matrix-js-sdk/pull/166) + * Zero is a valid power level + [\#164](https://github.com/matrix-org/matrix-js-sdk/pull/164) + * Verify e2e keys on download + [\#163](https://github.com/matrix-org/matrix-js-sdk/pull/163) + * Factor crypto stuff out of MatrixClient + [\#162](https://github.com/matrix-org/matrix-js-sdk/pull/162) + * Refactor device key upload + [\#161](https://github.com/matrix-org/matrix-js-sdk/pull/161) + * Wrappers for devices API + [\#158](https://github.com/matrix-org/matrix-js-sdk/pull/158) + * Add deactivate account function + [\#160](https://github.com/matrix-org/matrix-js-sdk/pull/160) + * client.listDeviceKeys: Expose device display name + [\#159](https://github.com/matrix-org/matrix-js-sdk/pull/159) + * Add `logout` + [\#157](https://github.com/matrix-org/matrix-js-sdk/pull/157) + * Fix email registration + [\#156](https://github.com/matrix-org/matrix-js-sdk/pull/156) + * Factor out MatrixClient methods to MatrixBaseApis + [\#155](https://github.com/matrix-org/matrix-js-sdk/pull/155) + * Fix some broken tests + [\#154](https://github.com/matrix-org/matrix-js-sdk/pull/154) + * make jenkins fail the build if the tests fail + [\#153](https://github.com/matrix-org/matrix-js-sdk/pull/153) + * deviceId-related fixes + [\#152](https://github.com/matrix-org/matrix-js-sdk/pull/152) + * /login, /register: Add device_id and initial_device_display_name + [\#151](https://github.com/matrix-org/matrix-js-sdk/pull/151) + * Support global account_data + [\#150](https://github.com/matrix-org/matrix-js-sdk/pull/150) + * Add more events to User + [\#149](https://github.com/matrix-org/matrix-js-sdk/pull/149) + * Add API calls for other requestToken endpoints + [\#148](https://github.com/matrix-org/matrix-js-sdk/pull/148) + * Add register-specific request token endpoint + [\#147](https://github.com/matrix-org/matrix-js-sdk/pull/147) + * Set a valid SPDX license identifier in package.json + [\#139](https://github.com/matrix-org/matrix-js-sdk/pull/139) + * Configure encryption on m.room.encryption events + [\#145](https://github.com/matrix-org/matrix-js-sdk/pull/145) + * Implement device blocking + [\#146](https://github.com/matrix-org/matrix-js-sdk/pull/146) + * Clearer doc for setRoomDirectoryVisibility + [\#144](https://github.com/matrix-org/matrix-js-sdk/pull/144) + * crypto: use memberlist to derive recipient list + [\#143](https://github.com/matrix-org/matrix-js-sdk/pull/143) + * Support for marking devices as unverified + [\#142](https://github.com/matrix-org/matrix-js-sdk/pull/142) + * Add Olm as an optionalDependency + [\#141](https://github.com/matrix-org/matrix-js-sdk/pull/141) + * Add room.getAliases() and room.getCanonicalAlias() + [\#140](https://github.com/matrix-org/matrix-js-sdk/pull/140) + * Change how MatrixEvent manages encrypted events + [\#138](https://github.com/matrix-org/matrix-js-sdk/pull/138) + * Catch exceptions when encrypting events + [\#137](https://github.com/matrix-org/matrix-js-sdk/pull/137) + * Support for marking devices as verified + [\#136](https://github.com/matrix-org/matrix-js-sdk/pull/136) + * Various matrix-client refactorings and fixes + [\#134](https://github.com/matrix-org/matrix-js-sdk/pull/134) + Changes in [0.5.4](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.5.4) (2016-06-02) ================================================================================================ [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.5.3...v0.5.4) From d9318a60e41578674ff900d2c77b4bb39dff88fe Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 11 Aug 2016 17:24:20 +0100 Subject: [PATCH 06/30] 0.5.5 --- dist/0.5.5/browser-matrix-0.5.5.js | 37345 +++++++++++++++++++++++ dist/0.5.5/browser-matrix-0.5.5.min.js | 38 + package.json | 2 +- 3 files changed, 37384 insertions(+), 1 deletion(-) create mode 100644 dist/0.5.5/browser-matrix-0.5.5.js create mode 100644 dist/0.5.5/browser-matrix-0.5.5.min.js diff --git a/dist/0.5.5/browser-matrix-0.5.5.js b/dist/0.5.5/browser-matrix-0.5.5.js new file mode 100644 index 000000000..362e61465 --- /dev/null +++ b/dist/0.5.5/browser-matrix-0.5.5.js @@ -0,0 +1,37345 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;ocurve25519, which is itself an object mapping key id to Curve25519 + * key. + */ +OlmDevice.prototype.getOneTimeKeys = function() { + return this._getAccount(function(account) { + return JSON.parse(account.one_time_keys()); + }); +}; + + +/** + * Get the maximum number of one-time keys we can store. + * + * @return {number} number of keys + */ +OlmDevice.prototype.maxNumberOfOneTimeKeys = function() { + return this._getAccount(function(account) { + return account.max_number_of_one_time_keys(); + }); +}; + +/** + * Marks all of the one-time keys as published. + */ +OlmDevice.prototype.markKeysAsPublished = function() { + var self = this; + this._getAccount(function(account) { + account.mark_keys_as_published(); + self._saveAccount(account); + }); +}; + +/** + * Generate some new one-time keys + * + * @param {number} numKeys number of keys to generate + */ +OlmDevice.prototype.generateOneTimeKeys = function(numKeys) { + var self = this; + this._getAccount(function(account) { + account.generate_one_time_keys(numKeys); + self._saveAccount(account); + }); +}; + +/** + * Generate a new outbound session + * + * The new session will be stored in the sessionStore. + * + * @param {string} theirIdentityKey remote user's Curve25519 identity key + * @param {string} theirOneTimeKey remote user's one-time Curve25519 key + * @return {string} sessionId for the outbound session. + */ +OlmDevice.prototype.createOutboundSession = function( + theirIdentityKey, theirOneTimeKey +) { + var self = this; + return this._getAccount(function(account) { + var session = new Olm.Session(); + try { + session.create_outbound(account, theirIdentityKey, theirOneTimeKey); + self._saveSession(theirIdentityKey, session); + return session.session_id(); + } finally { + session.free(); + } + }); +}; + + +/** + * Generate a new inbound session, given an incoming message + * + * @param {string} theirDeviceIdentityKey remote user's Curve25519 identity key + * @param {number} message_type message_type field from the received message (must be 0) + * @param {string} ciphertext base64-encoded body from the received message + * + * @return {string} decrypted payload + * + * @raises {Error} if the received message was not valid (for instance, it + * didn't use a valid one-time key). + */ +OlmDevice.prototype.createInboundSession = function( + theirDeviceIdentityKey, message_type, ciphertext +) { + if (message_type !== 0) { + throw new Error("Need message_type == 0 to create inbound session"); + } + + var self = this; + return this._getAccount(function(account) { + var session = new Olm.Session(); + try { + session.create_inbound_from(account, theirDeviceIdentityKey, ciphertext); + account.remove_one_time_keys(session); + self._saveAccount(account); + + var payloadString = session.decrypt(message_type, ciphertext); + + self._saveSession(theirDeviceIdentityKey, session); + + return payloadString; + } finally { + session.free(); + } + }); +}; + + +/** + * Get a list of known session IDs for the given device + * + * @param {string} theirDeviceIdentityKey Curve25519 identity key for the + * remote device + * @return {string[]} a list of known session ids for the device + */ +OlmDevice.prototype.getSessionIdsForDevice = function(theirDeviceIdentityKey) { + var sessions = this._sessionStore.getEndToEndSessions( + theirDeviceIdentityKey + ); + return utils.keys(sessions); +}; + + +/** + * Encrypt an outgoing message using an existing session + * + * @param {string} theirDeviceIdentityKey Curve25519 identity key for the + * remote device + * @param {string} sessionId the id of the active session + * @param {string} payloadString payload to be encrypted and sent + * + * @return {string} ciphertext + */ +OlmDevice.prototype.encryptMessage = function( + theirDeviceIdentityKey, sessionId, payloadString +) { + var self = this; + + return this._getSession(theirDeviceIdentityKey, sessionId, function(session) { + var res = session.encrypt(payloadString); + self._saveSession(theirDeviceIdentityKey, session); + return res; + }); +}; + +/** + * Decrypt an incoming message using an existing session + * + * @param {string} theirDeviceIdentityKey Curve25519 identity key for the + * remote device + * @param {string} sessionId the id of the active session + * @param {number} message_type message_type field from the received message + * @param {string} ciphertext base64-encoded body from the received message + * + * @return {object} Result, with keys
    + *
  • matchesInbound: (boolean): true if the message was a pre-key + * message which matched an existing inbound session.
  • + *
  • payload: (string): decrypted payload; null if the received + * message was not valid (for instance, it did not match this session).
  • + *
+ */ +OlmDevice.prototype.decryptMessage = function( + theirDeviceIdentityKey, sessionId, message_type, ciphertext +) { + var self = this; + + return this._getSession(theirDeviceIdentityKey, sessionId, function(session) { + var matchesInbound = (message_type === 0 && + session.matches_inbound(ciphertext)); + + var payloadString = null; + try { + payloadString = session.decrypt(message_type, ciphertext); + } catch (e) { + console.log( + "Failed to decrypt with an existing session: " + e.message + ); + // return null as the payload + } + + self._saveSession(theirDeviceIdentityKey, session); + + return { + matchesInbound: matchesInbound, + payload: payloadString, + }; + }); +}; + + +/** + * Verify an ed25519 signature. + * + * @param {string} key ed25519 key + * @param {string} message message which was signed + * @param {string} signature base64-encoded signature to be checked + * + * @raises {Error} if there is a problem with the verification. If the key was + * too small then the message will be "OLM.INVALID_BASE64". If the signature + * was invalid then the message will be "OLM.BAD_MESSAGE_MAC". + */ +OlmDevice.prototype.verifySignature = function( + key, message, signature +) { + this._getUtility(function(util) { + util.ed25519_verify(key, message, signature); + }); +}; + +/** */ +module.exports = OlmDevice; + +},{"./utils":28,"olm":204}],3:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/** + * This is an internal module. MatrixBaseApis is currently only meant to be used + * by {@link client~MatrixClient}. + * + * @module base-apis + */ + +var httpApi = require("./http-api"); +var utils = require("./utils"); + +/** + * Low-level wrappers for the Matrix APIs + * + * @constructor + * + * @param {Object} opts Configuration options + * + * @param {string} opts.baseUrl Required. The base URL to the client-server + * HTTP API. + * + * @param {string} opts.idBaseUrl Optional. The base identity server URL for + * identity server requests. + * + * @param {Function} opts.request Required. The function to invoke for HTTP + * requests. The value of this property is typically require("request") + * as it returns a function which meets the required interface. See + * {@link requestFunction} for more information. + * + * @param {string} opts.accessToken The access_token for this user. + * + * @param {Object} opts.queryParams Optional. Extra query parameters to append + * to all requests with this client. Useful for application services which require + * ?user_id=. + * + */ +function MatrixBaseApis(opts) { + utils.checkObjectHasKeys(opts, ["baseUrl", "request"]); + + this.baseUrl = opts.baseUrl; + this.idBaseUrl = opts.idBaseUrl; + + var httpOpts = { + baseUrl: opts.baseUrl, + idBaseUrl: opts.idBaseUrl, + accessToken: opts.accessToken, + request: opts.request, + prefix: httpApi.PREFIX_R0, + onlyData: true, + extraParams: opts.queryParams + }; + this._http = new httpApi.MatrixHttpApi(this, httpOpts); +} + + +/** + * Get the Homeserver URL of this client + * @return {string} Homeserver URL of this client + */ +MatrixBaseApis.prototype.getHomeserverUrl = function() { + return this.baseUrl; +}; + +/** + * Get the Identity Server URL of this client + * @return {string} Identity Server URL of this client + */ +MatrixBaseApis.prototype.getIdentityServerUrl = function() { + return this.idBaseUrl; +}; + +/** + * Get the access token associated with this account. + * @return {?String} The access_token or null + */ +MatrixBaseApis.prototype.getAccessToken = function() { + return this._http.opts.accessToken || null; +}; + +/** + * @return {boolean} true if there is a valid access_token for this client. + */ +MatrixBaseApis.prototype.isLoggedIn = function() { + return this._http.opts.accessToken !== undefined; +}; + + +// Registration/Login operations +// ============================= + +/** + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.loginFlows = function(callback) { + return this._http.request(callback, "GET", "/login"); +}; + +/** + * Logs out the current session. + * Obviously, further calls that require authorisation should fail after this + * method is called. The state of the MatrixClient object is not affected: + * it is up to the caller to either reset or destroy the MatrixClient after + * this method succeeds. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: On success, the empty object + */ +MatrixBaseApis.prototype.logout = function(callback) { + return this._http.authedRequest( + callback, "POST", '/logout' + ); +}; + +/** + * Deactivates the logged-in account. + * Obviously, further calls that require authorisation should fail after this + * method is called. The state of the MatrixClient object is not affected: + * it is up to the caller to either reset or destroy the MatrixClient after + * this method succeeds. + * @param {object} auth Optional. Auth data to supply for User-Interactive auth. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: On success, the empty object + */ +MatrixBaseApis.prototype.deactivateAccount = function(auth, callback) { + var body = {}; + if (auth) { + body = { + auth: auth, + }; + } + return this._http.authedRequestWithPrefix( + callback, "POST", '/account/deactivate', undefined, body, httpApi.PREFIX_UNSTABLE + ); +}; + + +// Room operations +// =============== + +/** + * Create a new room. + * @param {Object} options a list of options to pass to the /createRoom API. + * @param {string} options.room_alias_name The alias localpart to assign to + * this room. + * @param {string} options.visibility Either 'public' or 'private'. + * @param {string[]} options.invite A list of user IDs to invite to this room. + * @param {string} options.name The name to give this room. + * @param {string} options.topic The topic to give this room. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: {room_id: {string}, + * room_alias: {string(opt)}} + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.createRoom = function(options, callback) { + // valid options include: room_alias_name, visibility, invite + return this._http.authedRequest( + callback, "POST", "/createRoom", undefined, options + ); +}; + +/** + * @param {string} roomId + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.roomState = function(roomId, callback) { + var path = utils.encodeUri("/rooms/$roomId/state", {$roomId: roomId}); + return this._http.authedRequest(callback, "GET", path); +}; + +/** + * Retrieve a state event. + * @param {string} roomId + * @param {string} eventType + * @param {string} stateKey + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.getStateEvent = function(roomId, eventType, stateKey, callback) { + var pathParams = { + $roomId: roomId, + $eventType: eventType, + $stateKey: stateKey + }; + var path = utils.encodeUri("/rooms/$roomId/state/$eventType", pathParams); + if (stateKey !== undefined) { + path = utils.encodeUri(path + "/$stateKey", pathParams); + } + return this._http.authedRequest( + callback, "GET", path + ); +}; + +/** + * @param {string} roomId + * @param {string} eventType + * @param {Object} content + * @param {string} stateKey + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.sendStateEvent = function(roomId, eventType, content, stateKey, + callback) { + var pathParams = { + $roomId: roomId, + $eventType: eventType, + $stateKey: stateKey + }; + var path = utils.encodeUri("/rooms/$roomId/state/$eventType", pathParams); + if (stateKey !== undefined) { + path = utils.encodeUri(path + "/$stateKey", pathParams); + } + return this._http.authedRequest( + callback, "PUT", path, undefined, content + ); +}; + +/** + * @param {string} roomId + * @param {string} eventId + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.redactEvent = function(roomId, eventId, callback) { + var path = utils.encodeUri("/rooms/$roomId/redact/$eventId", { + $roomId: roomId, + $eventId: eventId + }); + return this._http.authedRequest(callback, "POST", path, undefined, {}); +}; + +/** + * @param {string} roomId + * @param {Number} limit + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.roomInitialSync = function(roomId, limit, callback) { + if (utils.isFunction(limit)) { callback = limit; limit = undefined; } + var path = utils.encodeUri("/rooms/$roomId/initialSync", + {$roomId: roomId} + ); + if (!limit) { + limit = 30; + } + return this._http.authedRequest( + callback, "GET", path, { limit: limit } + ); +}; + + +// Room Directory operations +// ========================= + +/** + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.publicRooms = function(callback) { + return this._http.authedRequest(callback, "GET", "/publicRooms"); +}; + +/** + * Create an alias to room ID mapping. + * @param {string} alias The room alias to create. + * @param {string} roomId The room ID to link the alias to. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO. + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.createAlias = function(alias, roomId, callback) { + var path = utils.encodeUri("/directory/room/$alias", { + $alias: alias + }); + var data = { + room_id: roomId + }; + return this._http.authedRequest( + callback, "PUT", path, undefined, data + ); +}; + +/** + * Delete an alias to room ID mapping. This alias must be on your local server + * and you must have sufficient access to do this operation. + * @param {string} alias The room alias to delete. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO. + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.deleteAlias = function(alias, callback) { + var path = utils.encodeUri("/directory/room/$alias", { + $alias: alias + }); + return this._http.authedRequest( + callback, "DELETE", path, undefined, undefined + ); +}; + +/** + * Get room info for the given alias. + * @param {string} alias The room alias to resolve. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: Object with room_id and servers. + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.getRoomIdForAlias = function(alias, callback) { + // TODO: deprecate this or resolveRoomAlias + var path = utils.encodeUri("/directory/room/$alias", { + $alias: alias + }); + return this._http.authedRequest( + callback, "GET", path + ); +}; + +/** + * @param {string} roomAlias + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.resolveRoomAlias = function(roomAlias, callback) { + // TODO: deprecate this or getRoomIdForAlias + var path = utils.encodeUri("/directory/room/$alias", {$alias: roomAlias}); + return this._http.request(callback, "GET", path); +}; + +/** + * Get the visibility of a room in the current HS's room directory + * @param {string} roomId + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.getRoomDirectoryVisibility = + function(roomId, callback) { + var path = utils.encodeUri("/directory/list/room/$roomId", { + $roomId: roomId + }); + return this._http.authedRequest(callback, "GET", path); +}; + +/** + * Set the visbility of a room in the current HS's room directory + * @param {string} roomId + * @param {string} visibility "public" to make the room visible + * in the public directory, or "private" to make + * it invisible. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: result object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.setRoomDirectoryVisibility = + function(roomId, visibility, callback) { + var path = utils.encodeUri("/directory/list/room/$roomId", { + $roomId: roomId + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, { "visibility": visibility } + ); +}; + + +// Media operations +// ================ + +/** + * Upload a file to the media repository on the home server. + * @param {File} file object + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.uploadContent = function(file, callback) { + return this._http.uploadContent(file, callback); +}; + +/** + * Cancel a file upload in progress + * @param {module:client.Promise} promise The promise returned from uploadContent + * @return {boolean} true if canceled, otherwise false + */ +MatrixBaseApis.prototype.cancelUpload = function(promise) { + return this._http.cancelUpload(promise); +}; + +/** + * Get a list of all file uploads in progress + * @return {array} Array of objects representing current uploads. + * Currently in progress is element 0. Keys: + * - promise: The promise associated with the upload + * - loaded: Number of bytes uploaded + * - total: Total number of bytes to upload + */ +MatrixBaseApis.prototype.getCurrentUploads = function() { + return this._http.getCurrentUploads(); +}; + + +// Profile operations +// ================== + +/** + * @param {string} userId + * @param {string} info The kind of info to retrieve (e.g. 'displayname', + * 'avatar_url'). + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.getProfileInfo = function(userId, info, callback) { + if (utils.isFunction(info)) { callback = info; info = undefined; } + + var path = info ? + utils.encodeUri("/profile/$userId/$info", + { $userId: userId, $info: info }) : + utils.encodeUri("/profile/$userId", + { $userId: userId }); + return this._http.authedRequest(callback, "GET", path); +}; + + +// Account operations +// ================== + +/** + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.getThreePids = function(callback) { + var path = "/account/3pid"; + return this._http.authedRequest( + callback, "GET", path, undefined, undefined + ); +}; + +/** + * @param {Object} creds + * @param {boolean} bind + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) { + var path = "/account/3pid"; + var data = { + 'threePidCreds': creds, + 'bind': bind + }; + return this._http.authedRequest( + callback, "POST", path, null, data + ); +}; + +/** + * Make a request to change your password. + * @param {Object} authDict + * @param {string} newPassword The new desired password. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.setPassword = function(authDict, newPassword, callback) { + var path = "/account/password"; + var data = { + 'auth': authDict, + 'new_password': newPassword + }; + + return this._http.authedRequest( + callback, "POST", path, null, data + ); +}; + + +// Device operations +// ================= + +/** + * Gets all devices recorded for the logged-in user + * @return {module:client.Promise} Resolves: result object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.getDevices = function() { + var path = "/devices"; + return this._http.authedRequestWithPrefix( + undefined, "GET", path, undefined, undefined, + httpApi.PREFIX_UNSTABLE + ); +}; + +/** + * Update the given device + * + * @param {string} device_id device to update + * @param {Object} body body of request + * @return {module:client.Promise} Resolves: result object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.setDeviceDetails = function(device_id, body) { + var path = utils.encodeUri("/devices/$device_id", { + $device_id: device_id, + }); + + + return this._http.authedRequestWithPrefix( + undefined, "PUT", path, undefined, body, + httpApi.PREFIX_UNSTABLE + ); +}; + +/** + * Delete the given device + * + * @param {string} device_id device to delete + * @return {module:client.Promise} Resolves: result object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.deleteDevice = function(device_id) { + var path = utils.encodeUri("/devices/$device_id", { + $device_id: device_id, + }); + + return this._http.authedRequestWithPrefix( + undefined, "DELETE", path, undefined, undefined, + httpApi.PREFIX_UNSTABLE + ); +}; + + +// Push operations +// =============== + +/** + * Gets all pushers registered for the logged-in user + * + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: Array of objects representing pushers + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.getPushers = function(callback) { + var path = "/pushers"; + return this._http.authedRequest( + callback, "GET", path, undefined, undefined + ); +}; + +/** + * Adds a new pusher or updates an existing pusher + * + * @param {Object} pusher Object representing a pusher + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: Empty json object on success + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.setPusher = function(pusher, callback) { + var path = "/pushers/set"; + return this._http.authedRequest( + callback, "POST", path, null, pusher + ); +}; + +/** + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.getPushRules = function(callback) { + return this._http.authedRequest(callback, "GET", "/pushrules/"); +}; + +/** + * @param {string} scope + * @param {string} kind + * @param {string} ruleId + * @param {Object} body + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.addPushRule = function(scope, kind, ruleId, body, callback) { + // NB. Scope not uri encoded because devices need the '/' + var path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { + $kind: kind, + $ruleId: ruleId + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, body + ); +}; + +/** + * @param {string} scope + * @param {string} kind + * @param {string} ruleId + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.deletePushRule = function(scope, kind, ruleId, callback) { + // NB. Scope not uri encoded because devices need the '/' + var path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { + $kind: kind, + $ruleId: ruleId + }); + return this._http.authedRequest(callback, "DELETE", path); +}; + +/** + * Enable or disable a push notification rule. + * @param {string} scope + * @param {string} kind + * @param {string} ruleId + * @param {boolean} enabled + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: result object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.setPushRuleEnabled = function(scope, kind, + ruleId, enabled, callback) { + var path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/enabled", { + $kind: kind, + $ruleId: ruleId + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, {"enabled": enabled} + ); +}; + +/** + * Set the actions for a push notification rule. + * @param {string} scope + * @param {string} kind + * @param {string} ruleId + * @param {array} actions + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: result object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.setPushRuleActions = function(scope, kind, + ruleId, actions, callback) { + var path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", { + $kind: kind, + $ruleId: ruleId + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, {"actions": actions} + ); +}; + + +// Search +// ====== + +/** + * Perform a server-side search. + * @param {Object} opts + * @param {string} opts.next_batch the batch token to pass in the query string + * @param {Object} opts.body the JSON object to pass to the request body. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.search = function(opts, callback) { + var queryparams = {}; + if (opts.next_batch) { + queryparams.next_batch = opts.next_batch; + } + return this._http.authedRequest( + callback, "POST", "/search", queryparams, opts.body + ); +}; + +// Crypto +// ====== + +/** + * Upload keys + * + * @param {Object} content body of upload request + * + * @param {Object=} opts + * + * @param {string=} opts.device_id explicit device_id to use for upload + * (default is to use the same as that used during auth). + * + * @param {module:client.callback=} callback + * + * @return {module:client.Promise} Resolves: result object. Rejects: with + * an error response ({@link module:http-api.MatrixError}). + */ +MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) { + opts = opts || {}; + var deviceId = opts.device_id; + var path; + if (deviceId) { + path = utils.encodeUri("/keys/upload/$deviceId", { + $deviceId: deviceId, + }); + } else { + path = "/keys/upload"; + } + return this._http.authedRequestWithPrefix( + callback, "POST", path, undefined, content, httpApi.PREFIX_UNSTABLE + ); +}; + +/** + * Download device keys + * + * @param {string[]} userIds list of users to get keys for + * + * @param {module:client.callback=} callback + * + * @return {module:client.Promise} Resolves: result object. Rejects: with + * an error response ({@link module:http-api.MatrixError}). + */ +MatrixBaseApis.prototype.downloadKeysForUsers = function(userIds, callback) { + var downloadQuery = {}; + + for (var i = 0; i < userIds.length; ++i) { + downloadQuery[userIds[i]] = {}; + } + var content = {device_keys: downloadQuery}; + return this._http.authedRequestWithPrefix( + callback, "POST", "/keys/query", undefined, content, + httpApi.PREFIX_UNSTABLE + ); +}; + +/** + * Claim one-time keys + * + * @param {string[][]} devices a list of [userId, deviceId] pairs + * + * @param {module:client.callback=} callback + * + * @return {module:client.Promise} Resolves: result object. Rejects: with + * an error response ({@link module:http-api.MatrixError}). + */ +MatrixBaseApis.prototype.claimOneTimeKeys = function(devices, callback) { + var queries = {}; + + for (var i = 0; i < devices.length; ++i) { + var userId = devices[i][0]; + var deviceId = devices[i][1]; + var query = queries[userId] || {}; + queries[userId] = query; + query[deviceId] = "curve25519"; + } + var content = {one_time_keys: queries}; + return this._http.authedRequestWithPrefix( + callback, "POST", "/keys/claim", undefined, content, + httpApi.PREFIX_UNSTABLE + ); +}; + + +// Identity Server Operations +// ========================== + +/** + * Requests an email verification token directly from an Identity Server. + * + * Note that the Home Server offers APIs to proxy this API for specific + * situations, allowing for better feedback to the user. + * + * @param {string} email The email address to request a token for + * @param {string} clientSecret A secret binary string generated by the client. + * It is recommended this be around 16 ASCII characters. + * @param {number} sendAttempt If an identity server sees a duplicate request + * with the same sendAttempt, it will not send another email. + * To request another email to be sent, use a larger value for + * the sendAttempt param as was used in the previous request. + * @param {string} nextLink Optional If specified, the client will be redirected + * to this link after validation. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + * @throws Error if No ID server is set + */ +MatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret, + sendAttempt, nextLink, callback) { + var params = { + client_secret: clientSecret, + email: email, + send_attempt: sendAttempt, + next_link: nextLink + }; + return this._http.idServerRequest( + callback, "POST", "/validate/email/requestToken", + params, httpApi.PREFIX_IDENTITY_V1 + ); +}; + +/** + * Looks up the public Matrix ID mapping for a given 3rd party + * identifier from the Identity Server + * @param {string} medium The medium of the threepid, eg. 'email' + * @param {string} address The textual address of the threepid + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: A threepid mapping + * object or the empty object if no mapping + * exists + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixBaseApis.prototype.lookupThreePid = function(medium, address, callback) { + var params = { + medium: medium, + address: address, + }; + return this._http.idServerRequest( + callback, "GET", "/lookup", + params, httpApi.PREFIX_IDENTITY_V1 + ); +}; + +/** + * MatrixBaseApis object + */ +module.exports = MatrixBaseApis; + +},{"./http-api":8,"./utils":28}],4:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +var PushProcessor = require('./pushprocessor'); + +/** + * This is an internal module. See {@link MatrixClient} for the public class. + * @module client + */ +var EventEmitter = require("events").EventEmitter; +var q = require("q"); +var url = require('url'); + +var httpApi = require("./http-api"); +var MatrixEvent = require("./models/event").MatrixEvent; +var EventStatus = require("./models/event").EventStatus; +var EventTimeline = require("./models/event-timeline"); +var SearchResult = require("./models/search-result"); +var StubStore = require("./store/stub"); +var webRtcCall = require("./webrtc/call"); +var utils = require("./utils"); +var contentRepo = require("./content-repo"); +var Filter = require("./filter"); +var SyncApi = require("./sync"); +var MatrixBaseApis = require("./base-apis"); +var MatrixError = httpApi.MatrixError; + +var SCROLLBACK_DELAY_MS = 3000; +var CRYPTO_ENABLED = false; + +try { + var Crypto = require("./crypto"); + CRYPTO_ENABLED = true; +} catch (e) { + // Olm not installed. +} + +/** + * Construct a Matrix Client. Only directly construct this if you want to use + * custom modules. Normally, {@link createClient} should be used + * as it specifies 'sensible' defaults for these modules. + * @constructor + * @extends {external:EventEmitter} + * @extends {module:base-apis~MatrixBaseApis} + * + * @param {Object} opts The configuration options for this client. + * @param {string} opts.baseUrl Required. The base URL to the client-server + * HTTP API. + * @param {string} opts.idBaseUrl Optional. The base identity server URL for + * identity server requests. + * @param {Function} opts.request Required. The function to invoke for HTTP + * requests. The value of this property is typically require("request") + * as it returns a function which meets the required interface. See + * {@link requestFunction} for more information. + * + * @param {string} opts.accessToken The access_token for this user. + * + * @param {string} opts.userId The user ID for this user. + * + * @param {Object=} opts.store The data store to use. If not specified, + * this client will not store any HTTP responses. + * + * @param {string=} opts.deviceId A unique identifier for this device; used for + * tracking things like crypto keys and access tokens. If not specified, + * end-to-end crypto will be disabled. + * + * @param {string=} opts.defaultDeviceDisplayName Initial display name to set + * on new devices + * + * @param {Object=} opts.sessionStore A store to be used for end-to-end crypto + * session data. This should be a {@link + * module:store/session/webstorage~WebStorageSessionStore|WebStorageSessionStore}, + * or an object implementing the same interface. If not specified, + * end-to-end crypto will be disabled. + * + * @param {Object} opts.scheduler Optional. The scheduler to use. If not + * specified, this client will not retry requests on failure. This client + * will supply its own processing function to + * {@link module:scheduler~MatrixScheduler#setProcessFunction}. + * + * @param {Object} opts.queryParams Optional. Extra query parameters to append + * to all requests with this client. Useful for application services which require + * ?user_id=. + * + * @param {boolean} [opts.timelineSupport = false] Set to true to enable + * improved timeline support ({@link + * module:client~MatrixClient#getEventTimeline getEventTimeline}). It is + * disabled by default for compatibility with older clients - in particular to + * maintain support for back-paginating the live timeline after a '/sync' + * result with a gap. + */ +function MatrixClient(opts) { + MatrixBaseApis.call(this, opts); + + this.store = opts.store || new StubStore(); + + this.deviceId = opts.deviceId || null; + this.defaultDeviceDisplayName = opts.defaultDeviceDisplayName || "js-sdk device"; + + var userId = (opts.userId || null); + this.credentials = { + userId: userId, + }; + + this.scheduler = opts.scheduler; + if (this.scheduler) { + var self = this; + this.scheduler.setProcessFunction(function(eventToSend) { + var room = self.getRoom(eventToSend.getRoomId()); + if (eventToSend.status !== EventStatus.SENDING) { + _updatePendingEventStatus(room, eventToSend, + EventStatus.SENDING); + } + return _sendEventHttpRequest(self, eventToSend); + }); + } + this.clientRunning = false; + + this.callList = { + // callId: MatrixCall + }; + + // try constructing a MatrixCall to see if we are running in an environment + // which has WebRTC. If we are, listen for and handle m.call.* events. + var call = webRtcCall.createNewMatrixCall(this); + this._supportsVoip = false; + if (call) { + setupCallEventHandler(this); + this._supportsVoip = true; + } + this._syncingRetry = null; + this._syncApi = null; + this._peekSync = null; + this._isGuest = false; + this._ongoingScrollbacks = {}; + this._txnCtr = 0; + this.timelineSupport = Boolean(opts.timelineSupport); + this.urlPreviewCache = {}; + + this._crypto = null; + if (CRYPTO_ENABLED && opts.sessionStore !== null && + userId !== null && this.deviceId !== null) { + this._crypto = new Crypto( + this, + opts.sessionStore, + userId, this.deviceId + ); + + setupCryptoEventHandler(this); + } +} +utils.inherits(MatrixClient, EventEmitter); +utils.extend(MatrixClient.prototype, MatrixBaseApis.prototype); + +/** + * Get the domain for this client's MXID + * @return {?string} Domain of this MXID + */ +MatrixClient.prototype.getDomain = function() { + if (this.credentials && this.credentials.userId) { + return this.credentials.userId.replace(/^.*?:/, ''); + } + return null; +}; + +/** + * Get the local part of the current user ID e.g. "foo" in "@foo:bar". + * @return {?string} The user ID localpart or null. + */ +MatrixClient.prototype.getUserIdLocalpart = function() { + if (this.credentials && this.credentials.userId) { + return this.credentials.userId.split(":")[0].substring(1); + } + return null; +}; + +/** + * Get the device ID of this client + * @return {?string} device ID + */ +MatrixClient.prototype.getDeviceId = function() { + return this.deviceId; +}; + + +/** + * Check if the runtime environment supports VoIP calling. + * @return {boolean} True if VoIP is supported. + */ +MatrixClient.prototype.supportsVoip = function() { + return this._supportsVoip; +}; + +/** + * Get the current sync state. + * @return {?string} the sync state, which may be null. + * @see module:client~MatrixClient#event:"sync" + */ +MatrixClient.prototype.getSyncState = function() { + if (!this._syncApi) { return null; } + return this._syncApi.getSyncState(); +}; + +/** + * Return whether the client is configured for a guest account. + * @return {boolean} True if this is a guest access_token (or no token is supplied). + */ +MatrixClient.prototype.isGuest = function() { + return this._isGuest; +}; + +/** + * Return the provided scheduler, if any. + * @return {?module:scheduler~MatrixScheduler} The scheduler or null + */ +MatrixClient.prototype.getScheduler = function() { + return this.scheduler; +}; + +/** + * Set whether this client is a guest account. This method is experimental + * and may change without warning. + * @param {boolean} isGuest True if this is a guest account. + */ +MatrixClient.prototype.setGuest = function(isGuest) { + // EXPERIMENTAL: + // If the token is a macaroon, it should be encoded in it that it is a 'guest' + // access token, which means that the SDK can determine this entirely without + // the dev manually flipping this flag. + this._isGuest = isGuest; +}; + +/** + * Retry a backed off syncing request immediately. This should only be used when + * the user explicitly attempts to retry their lost connection. + * @return {boolean} True if this resulted in a request being retried. + */ +MatrixClient.prototype.retryImmediately = function() { + return this._syncApi.retryImmediately(); +}; + +// Crypto bits +// =========== + +/** + * Is end-to-end crypto enabled for this client. + * @return {boolean} True if end-to-end is enabled. + */ +MatrixClient.prototype.isCryptoEnabled = function() { + return this._crypto !== null; +}; + + +/** + * Get the Ed25519 key for this device + * + * @return {?string} base64-encoded ed25519 key. Null if crypto is + * disabled. + */ +MatrixClient.prototype.getDeviceEd25519Key = function() { + if (!this._crypto) { + return null; + } + return this._crypto.getDeviceEd25519Key(); +}; + +/** + * Upload the device keys to the homeserver and ensure that the + * homeserver has enough one-time keys. + * @param {number} maxKeys The maximum number of keys to generate + * @return {object} A promise that will resolve when the keys are uploaded. + */ +MatrixClient.prototype.uploadKeys = function(maxKeys) { + if (this._crypto === null) { + throw new Error("End-to-end encryption disabled"); + } + + return this._crypto.uploadKeys(maxKeys); +}; + +/** + * Download the keys for a list of users and stores the keys in the session + * store. + * @param {Array} userIds The users to fetch. + * @param {bool} forceDownload Always download the keys even if cached. + * + * @return {Promise} A promise which resolves to a map userId->deviceId->{@link + * module:crypto~DeviceInfo|DeviceInfo}. + */ +MatrixClient.prototype.downloadKeys = function(userIds, forceDownload) { + if (this._crypto === null) { + return q.reject(new Error("End-to-end encryption disabled")); + } + return this._crypto.downloadKeys(userIds, forceDownload); +}; + +/** + * List the stored device keys for a user id + * + * @param {string} userId the user to list keys for. + * + * @return {object[]} list of devices with "id", "verified", "blocked", + * "key", and "display_name" parameters. + */ +MatrixClient.prototype.listDeviceKeys = function(userId) { + if (this._crypto === null) { + throw new Error("End-to-end encryption disabled"); + } + return this._crypto.listDeviceKeys(userId); +}; + +/** + * Mark the given device as verified + * + * @param {string} userId owner of the device + * @param {string} deviceId unique identifier for the device + * + * @param {boolean=} verified whether to mark the device as verified. defaults + * to 'true'. + * + * @fires module:client~event:MatrixClient"deviceVerificationChanged" + */ +MatrixClient.prototype.setDeviceVerified = function(userId, deviceId, verified) { + if (verified === undefined) { + verified = true; + } + _setDeviceVerification(this, userId, deviceId, verified, null); +}; + + +/** + * Mark the given device as blocked/unblocked + * + * @param {string} userId owner of the device + * @param {string} deviceId unique identifier for the device + * + * @param {boolean=} blocked whether to mark the device as blocked. defaults + * to 'true'. + * + * @fires module:client~event:MatrixClient"deviceVerificationChanged" + */ +MatrixClient.prototype.setDeviceBlocked = function(userId, deviceId, blocked) { + if (blocked === undefined) { + blocked = true; + } + _setDeviceVerification(this, userId, deviceId, null, blocked); +}; + +function _setDeviceVerification(client, userId, deviceId, verified, blocked) { + if (!client._crypto) { + throw new Error("End-to-End encryption disabled"); + } + client._crypto.setDeviceVerification(userId, deviceId, verified, blocked); + client.emit("deviceVerificationChanged", userId, deviceId); +} + +/** + * Check if the sender of an event is verified + * + * @param {MatrixEvent} event event to be checked + * + * @return {boolean} true if the sender of this event has been verified using + * {@link module:client~MatrixClient#setDeviceVerified|setDeviceVerified}. + */ +MatrixClient.prototype.isEventSenderVerified = function(event) { + if (!this._crypto) { + return false; + } + + var cryptoContent = event.getWireContent(); + var sender_key = cryptoContent.sender_key; + + if (!sender_key) { + return false; + } + + var algorithm = cryptoContent.algorithm; + + return this._crypto.isSenderKeyVerified( + event.getSender(), algorithm, sender_key + ); +}; + +/** + * Register a listener for m.room.encryption events which will enable encryption + * for a room. + * + * @param {MatrixClient} client + */ +function setupCryptoEventHandler(client) { + client.on("event", function(event) { + if (!event.isState() || event.getType() != "m.room.encryption") { + return; + } + onCryptoEvent(client, event); + }); +} + +function onCryptoEvent(client, event) { + var roomId = event.getRoomId(); + var content = event.getContent(); + + try { + client.setRoomEncryption(roomId, content).done(); + } catch (e) { + console.error("Error configuring encryption in room " + roomId + + ":", e); + } +} + +/** + * Enable end-to-end encryption for a room. + * @param {string} roomId The room ID to enable encryption in. + * @param {object} config The encryption config for the room. + * @return {Object} A promise that will resolve when encryption is setup. + */ +MatrixClient.prototype.setRoomEncryption = function(roomId, config) { + if (!this._crypto) { + throw new Error("End-to-End encryption disabled"); + } + + var roomMembers = []; + var room = this.getRoom(roomId); + if (!room) { + console.warn("Enabling encryption in unknown room " + roomId); + } else { + roomMembers = utils.map(room.getJoinedMembers(), function(u) { + return u.userId; + }); + } + + return this._crypto.setRoomEncryption(roomId, config, roomMembers); +}; + +/** + * Whether encryption is enabled for a room. + * @param {string} roomId the room id to query. + * @return {bool} whether encryption is enabled. + */ +MatrixClient.prototype.isRoomEncrypted = function(roomId) { + if (!this._crypto) { + return false; + } + + return this._crypto.isRoomEncrypted(roomId); +}; + +/** + * Decrypt a received event according to the algorithm specified in the event. + * + * @param {MatrixClient} client + * @param {object} raw event + * + * @return {object} decrypted payload (with properties 'type', 'content') + */ +function _decryptMessage(client, event) { + if (!client._crypto) { + return _badEncryptedMessage(event, "**Encryption not enabled**"); + } + + try { + return client._crypto.decryptEvent(event); + } catch (e) { + if (!(e instanceof Crypto.DecryptionError)) { + throw e; + } + return _badEncryptedMessage(event, "**" + e.message + "**"); + } +} + +function _badEncryptedMessage(event, reason) { + return { + type: "m.room.message", + content: { + msgtype: "m.bad.encrypted", + body: reason, + content: event.content, + }, + }; +} + +// Room ops +// ======== + +/** + * Get the room for the given room ID. + * This function will return a valid room for any room for which a Room event + * has been emitted. Note in particular that other events, eg. RoomState.members + * will be emitted for a room before this function will return the given room. + * @param {string} roomId The room ID + * @return {Room} The Room or null if it doesn't exist or there is no data store. + */ +MatrixClient.prototype.getRoom = function(roomId) { + return this.store.getRoom(roomId); +}; + +/** + * Retrieve all known rooms. + * @return {Room[]} A list of rooms, or an empty list if there is no data store. + */ +MatrixClient.prototype.getRooms = function() { + return this.store.getRooms(); +}; + +/** + * Retrieve a user. + * @param {string} userId The user ID to retrieve. + * @return {?User} A user or null if there is no data store or the user does + * not exist. + */ +MatrixClient.prototype.getUser = function(userId) { + return this.store.getUser(userId); +}; + +/** + * Retrieve all known users. + * @return {User[]} A list of users, or an empty list if there is no data store. + */ +MatrixClient.prototype.getUsers = function() { + return this.store.getUsers(); +}; + +// User Account Data operations +// ============================ + +/** + * Set account data event for the current user. + * @param {string} eventType The event type + * @param {Object} content the contents object for the event + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setAccountData = function(eventType, contents, callback) { + var path = utils.encodeUri("/user/$userId/account_data/$type", { + $userId: this.credentials.userId, + $type: eventType, + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, contents + ); +}; + +/** + * Get account data event of given type for the current user. + * @param {string} eventType The event type + * @param {module:client.callback} callback Optional. + * @return {?object} The contents of the given account data event + */ +MatrixClient.prototype.getAccountData = function(eventType) { + return this.store.getAccountData(eventType); +}; + +// Room operations +// =============== + +/** + * Join a room. If you have already joined the room, this will no-op. + * @param {string} roomIdOrAlias The room ID or room alias to join. + * @param {Object} opts Options when joining the room. + * @param {boolean} opts.syncRoom True to do a room initial sync on the resulting + * room. If false, the returned Room object will have no current state. + * Default: true. + * @param {boolean} opts.inviteSignUrl If the caller has a keypair 3pid invite, + * the signing URL is passed in this parameter. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: Room object. + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.joinRoom = function(roomIdOrAlias, opts, callback) { + // to help people when upgrading.. + if (utils.isFunction(opts)) { + throw new Error("Expected 'opts' object, got function."); + } + opts = opts || {}; + if (opts.syncRoom === undefined) { opts.syncRoom = true; } + + var room = this.getRoom(roomIdOrAlias); + if (room && room.hasMembershipState(this.credentials.userId, "join")) { + return q(room); + } + + var sign_promise = q(); + + if (opts.inviteSignUrl) { + sign_promise = this._http.requestOtherUrl( + undefined, 'POST', + opts.inviteSignUrl, { mxid: this.credentials.userId } + ); + } + + var defer = q.defer(); + + var self = this; + sign_promise.then(function(signed_invite_object) { + var data = {}; + if (signed_invite_object) { + data.third_party_signed = signed_invite_object; + } + + var path = utils.encodeUri("/join/$roomid", { $roomid: roomIdOrAlias}); + return self._http.authedRequest(undefined, "POST", path, undefined, data); + }).then(function(res) { + var roomId = res.room_id; + var syncApi = new SyncApi(self, self._clientOpts); + var room = syncApi.createRoom(roomId); + if (opts.syncRoom) { + // v2 will do this for us + // return syncApi.syncRoom(room); + } + return q(room); + }).done(function(room) { + _resolve(callback, defer, room); + }, function(err) { + _reject(callback, defer, err); + }); + return defer.promise; +}; + +/** + * Resend an event. + * @param {MatrixEvent} event The event to resend. + * @param {Room} room Optional. The room the event is in. Will update the + * timeline entry if provided. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.resendEvent = function(event, room) { + _updatePendingEventStatus(room, event, EventStatus.SENDING); + return _sendEvent(this, room, event); +}; + +/** + * Cancel a queued or unsent event. + * + * @param {MatrixEvent} event Event to cancel + * @throws Error if the event is not in QUEUED or NOT_SENT state + */ +MatrixClient.prototype.cancelPendingEvent = function(event) { + if ([EventStatus.QUEUED, EventStatus.NOT_SENT].indexOf(event.status) < 0) { + throw new Error("cannot cancel an event with status " + event.status); + } + + // first tell the scheduler to forget about it, if it's queued + if (this.scheduler) { + this.scheduler.removeEventFromQueue(event); + } + + // then tell the room about the change of state, which will remove it + // from the room's list of pending events. + var room = this.getRoom(event.getRoomId()); + _updatePendingEventStatus(room, event, EventStatus.CANCELLED); +}; + +/** + * @param {string} roomId + * @param {string} name + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setRoomName = function(roomId, name, callback) { + return this.sendStateEvent(roomId, "m.room.name", {name: name}, + undefined, callback); +}; + +/** + * @param {string} roomId + * @param {string} topic + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setRoomTopic = function(roomId, topic, callback) { + return this.sendStateEvent(roomId, "m.room.topic", {topic: topic}, + undefined, callback); +}; + +/** + * @param {string} roomId + * @param {string} tagName name of room tag to be set + * @param {object} metadata associated with that tag to be stored + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setRoomTag = function(roomId, tagName, metadata, callback) { + var path = utils.encodeUri("/user/$userId/rooms/$roomId/tags/$tag", { + $userId: this.credentials.userId, + $roomId: roomId, + $tag: tagName, + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, metadata + ); +}; + +/** + * @param {string} roomId + * @param {string} tagName name of room tag to be removed + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.deleteRoomTag = function(roomId, tagName, callback) { + var path = utils.encodeUri("/user/$userId/rooms/$roomId/tags/$tag", { + $userId: this.credentials.userId, + $roomId: roomId, + $tag: tagName, + }); + return this._http.authedRequest( + callback, "DELETE", path, undefined, undefined + ); +}; + +/** + * @param {string} roomId + * @param {string} eventType event type to be set + * @param {object} content event content + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setRoomAccountData = function(roomId, eventType, + content, callback) { + var path = utils.encodeUri("/user/$userId/rooms/$roomId/account_data/$type", { + $userId: this.credentials.userId, + $roomId: roomId, + $type: eventType, + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, content + ); +}; + +/** + * Set a user's power level. + * @param {string} roomId + * @param {string} userId + * @param {Number} powerLevel + * @param {MatrixEvent} event + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setPowerLevel = function(roomId, userId, powerLevel, + event, callback) { + var content = { + users: {} + }; + if (event && event.getType() === "m.room.power_levels") { + // take a copy of the content to ensure we don't corrupt + // existing client state with a failed power level change + content = utils.deepCopy(event.getContent()); + } + content.users[userId] = powerLevel; + var path = utils.encodeUri("/rooms/$roomId/state/m.room.power_levels", { + $roomId: roomId + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, content + ); +}; + +/** + * @param {string} roomId + * @param {string} eventType + * @param {Object} content + * @param {string} txnId Optional. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendEvent = function(roomId, eventType, content, txnId, + callback) { + if (utils.isFunction(txnId)) { callback = txnId; txnId = undefined; } + + if (!txnId) { + txnId = "m" + new Date().getTime() + "." + (this._txnCtr++); + } + + // we always construct a MatrixEvent when sending because the store and + // scheduler use them. We'll extract the params back out if it turns out + // the client has no scheduler or store. + var room = this.getRoom(roomId); + var localEvent = new MatrixEvent({ + event_id: "~" + roomId + ":" + txnId, + user_id: this.credentials.userId, + room_id: roomId, + type: eventType, + origin_server_ts: new Date().getTime(), + content: content + }); + localEvent._txnId = txnId; + localEvent.status = EventStatus.SENDING; + + // add this event immediately to the local store as 'sending'. + if (room) { + room.addPendingEvent(localEvent, txnId); + } + + return _sendEvent(this, room, localEvent, callback); +}; + + +// encrypts the event if necessary +// adds the event to the queue, or sends it +// marks the event as sent/unsent +// returns a promise which resolves with the result of the send request +function _sendEvent(client, room, event, callback) { + // Add an extra q() to turn synchronous exceptions into promise rejections, + // so that we can handle synchronous and asynchronous exceptions with the + // same code path. + return q().then(function() { + if (client._crypto) { + client._crypto.encryptEventIfNeeded(event, room); + } + + var promise; + // this event may be queued + if (client.scheduler) { + // if this returns a promsie then the scheduler has control now and will + // resolve/reject when it is done. Internally, the scheduler will invoke + // processFn which is set to this._sendEventHttpRequest so the same code + // path is executed regardless. + promise = client.scheduler.queueEvent(event); + if (promise && client.scheduler.getQueueForEvent(event).length > 1) { + // event is processed FIFO so if the length is 2 or more we know + // this event is stuck behind an earlier event. + _updatePendingEventStatus(room, event, EventStatus.QUEUED); + } + } + + if (!promise) { + promise = _sendEventHttpRequest(client, event); + } + return promise; + }).then(function(res) { // the request was sent OK + if (room) { + room.updatePendingEvent(event, EventStatus.SENT, res.event_id); + } + if (callback) { + callback(null, res); + } + return res; + }, function(err) { + // the request failed to send. + console.error("Error sending event", err.stack || err); + + _updatePendingEventStatus(room, event, EventStatus.NOT_SENT); + + if (callback) { + callback(err); + } + throw err; + }); +} + +function _updatePendingEventStatus(room, event, newStatus) { + if (room) { + room.updatePendingEvent(event, newStatus); + } else { + event.status = newStatus; + } +} + +function _sendEventHttpRequest(client, event) { + var pathParams = { + $roomId: event.getRoomId(), + $eventType: event.getWireType(), + $stateKey: event.getStateKey(), + $txnId: event._txnId ? event._txnId : new Date().getTime() + }; + + var path; + + if (event.isState()) { + var pathTemplate = "/rooms/$roomId/state/$eventType"; + if (event.getStateKey() && event.getStateKey().length > 0) { + pathTemplate = "/rooms/$roomId/state/$eventType/$stateKey"; + } + path = utils.encodeUri(pathTemplate, pathParams); + } + else { + path = utils.encodeUri( + "/rooms/$roomId/send/$eventType/$txnId", pathParams + ); + } + + return client._http.authedRequest( + undefined, "PUT", path, undefined, event.getWireContent() + ); +} + +/** + * @param {string} roomId + * @param {Object} content + * @param {string} txnId Optional. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendMessage = function(roomId, content, txnId, callback) { + if (utils.isFunction(txnId)) { callback = txnId; txnId = undefined; } + return this.sendEvent( + roomId, "m.room.message", content, txnId, callback + ); +}; + +/** + * @param {string} roomId + * @param {string} body + * @param {string} txnId Optional. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendTextMessage = function(roomId, body, txnId, callback) { + var content = { + msgtype: "m.text", + body: body + }; + return this.sendMessage(roomId, content, txnId, callback); +}; + +/** + * @param {string} roomId + * @param {string} body + * @param {string} txnId Optional. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendNotice = function(roomId, body, txnId, callback) { + var content = { + msgtype: "m.notice", + body: body + }; + return this.sendMessage(roomId, content, txnId, callback); +}; + +/** + * @param {string} roomId + * @param {string} body + * @param {string} txnId Optional. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendEmoteMessage = function(roomId, body, txnId, callback) { + var content = { + msgtype: "m.emote", + body: body + }; + return this.sendMessage(roomId, content, txnId, callback); +}; + +/** + * @param {string} roomId + * @param {string} url + * @param {Object} info + * @param {string} text + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendImageMessage = function(roomId, url, info, text, callback) { + if (utils.isFunction(text)) { callback = text; text = undefined; } + if (!text) { text = "Image"; } + var content = { + msgtype: "m.image", + url: url, + info: info, + body: text + }; + return this.sendMessage(roomId, content, callback); +}; + +/** + * @param {string} roomId + * @param {string} body + * @param {string} htmlBody + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendHtmlMessage = function(roomId, body, htmlBody, callback) { + var content = { + msgtype: "m.text", + format: "org.matrix.custom.html", + body: body, + formatted_body: htmlBody + }; + return this.sendMessage(roomId, content, callback); +}; + +/** + * @param {string} roomId + * @param {string} body + * @param {string} htmlBody + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendHtmlNotice = function(roomId, body, htmlBody, callback) { + var content = { + msgtype: "m.notice", + format: "org.matrix.custom.html", + body: body, + formatted_body: htmlBody + }; + return this.sendMessage(roomId, content, callback); +}; + +/** + * @param {string} roomId + * @param {string} body + * @param {string} htmlBody + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendHtmlEmote = function(roomId, body, htmlBody, callback) { + var content = { + msgtype: "m.emote", + format: "org.matrix.custom.html", + body: body, + formatted_body: htmlBody + }; + return this.sendMessage(roomId, content, callback); +}; + +/** + * Send a receipt. + * @param {Event} event The event being acknowledged + * @param {string} receiptType The kind of receipt e.g. "m.read" + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendReceipt = function(event, receiptType, callback) { + if (this.isGuest()) { + return q({}); // guests cannot send receipts so don't bother. + } + + var path = utils.encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", { + $roomId: event.getRoomId(), + $receiptType: receiptType, + $eventId: event.getId() + }); + var promise = this._http.authedRequest( + callback, "POST", path, undefined, {} + ); + + var room = this.getRoom(event.getRoomId()); + if (room) { + room._addLocalEchoReceipt(this.credentials.userId, event, receiptType); + } + return promise; +}; + +/** + * Send a read receipt. + * @param {Event} event The event that has been read. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendReadReceipt = function(event, callback) { + return this.sendReceipt(event, "m.read", callback); +}; + + +/** + * Get a preview of the given URL as of (roughly) the given point in time, + * described as an object with OpenGraph keys and associated values. + * Attributes may be synthesized where actual OG metadata is lacking. + * Caches results to prevent hammering the server. + * @param {string} url The URL to get preview data for + * @param {Number} ts The preferred point in time that the preview should + * describe (ms since epoch). The preview returned will either be the most + * recent one preceding this timestamp if available, or failing that the next + * most recent available preview. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: Object of OG metadata. + * @return {module:http-api.MatrixError} Rejects: with an error response. + * May return synthesized attributes if the URL lacked OG meta. + */ +MatrixClient.prototype.getUrlPreview = function(url, ts, callback) { + var key = ts + "_" + url; + var og = this.urlPreviewCache[key]; + if (og) { + return q(og); + } + + var self = this; + return this._http.authedRequestWithPrefix( + callback, "GET", "/preview_url", { + url: url, + ts: ts, + }, undefined, httpApi.PREFIX_MEDIA_R0 + ).then(function(response) { + // TODO: expire cache occasionally + self.urlPreviewCache[key] = response; + return response; + }); +}; + +/** + * @param {string} roomId + * @param {boolean} isTyping + * @param {Number} timeoutMs + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.sendTyping = function(roomId, isTyping, timeoutMs, callback) { + if (this.isGuest()) { + return q({}); // guests cannot send typing notifications so don't bother. + } + + var path = utils.encodeUri("/rooms/$roomId/typing/$userId", { + $roomId: roomId, + $userId: this.credentials.userId + }); + var data = { + typing: isTyping + }; + if (isTyping) { + data.timeout = timeoutMs ? timeoutMs : 20000; + } + return this._http.authedRequest( + callback, "PUT", path, undefined, data + ); +}; + +/** + * @param {string} roomId + * @param {string} userId + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.invite = function(roomId, userId, callback) { + return _membershipChange(this, roomId, userId, "invite", undefined, + callback); +}; + +/** + * Invite a user to a room based on their email address. + * @param {string} roomId The room to invite the user to. + * @param {string} email The email address to invite. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.inviteByEmail = function(roomId, email, callback) { + return this.inviteByThreePid( + roomId, "email", email, callback + ); +}; + +/** + * Invite a user to a room based on a third-party identifier. + * @param {string} roomId The room to invite the user to. + * @param {string} medium The medium to invite the user e.g. "email". + * @param {string} address The address for the specified medium. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.inviteByThreePid = function(roomId, medium, address, callback) { + var path = utils.encodeUri( + "/rooms/$roomId/invite", + { $roomId: roomId } + ); + + var identityServerUrl = this.getIdentityServerUrl(); + if (!identityServerUrl) { + return q.reject(new MatrixError({ + error: "No supplied identity server URL", + errcode: "ORG.MATRIX.JSSDK_MISSING_PARAM" + })); + } + if (identityServerUrl.indexOf("http://") === 0 || + identityServerUrl.indexOf("https://") === 0) { + // this request must not have the protocol part because reasons + identityServerUrl = identityServerUrl.split("://")[1]; + } + + return this._http.authedRequest(callback, "POST", path, undefined, { + id_server: identityServerUrl, + medium: medium, + address: address + }); +}; + +/** + * @param {string} roomId + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.leave = function(roomId, callback) { + return _membershipChange(this, roomId, undefined, "leave", undefined, + callback); +}; + +/** + * @param {string} roomId + * @param {string} userId + * @param {string} reason Optional. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.ban = function(roomId, userId, reason, callback) { + return _membershipChange(this, roomId, userId, "ban", reason, + callback); +}; + +/** + * @param {string} roomId + * @param {boolean} deleteRoom True to delete the room from the store on success. + * Default: true. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.forget = function(roomId, deleteRoom, callback) { + if (deleteRoom === undefined) { + deleteRoom = true; + } + var promise = _membershipChange(this, roomId, undefined, "forget", undefined, + callback); + if (!deleteRoom) { + return promise; + } + var self = this; + return promise.then(function(response) { + self.store.removeRoom(roomId); + self.emit("deleteRoom", roomId); + return response; + }); +}; + +/** + * @param {string} roomId + * @param {string} userId + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.unban = function(roomId, userId, callback) { + // unbanning = set their state to leave + return _setMembershipState( + this, roomId, userId, "leave", undefined, callback + ); +}; + +/** + * @param {string} roomId + * @param {string} userId + * @param {string} reason Optional. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.kick = function(roomId, userId, reason, callback) { + return _setMembershipState( + this, roomId, userId, "leave", reason, callback + ); +}; + +/** + * This is an internal method. + * @param {MatrixClient} client + * @param {string} roomId + * @param {string} userId + * @param {string} membershipValue + * @param {string} reason + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +function _setMembershipState(client, roomId, userId, membershipValue, reason, + callback) { + if (utils.isFunction(reason)) { callback = reason; reason = undefined; } + + var path = utils.encodeUri( + "/rooms/$roomId/state/m.room.member/$userId", + { $roomId: roomId, $userId: userId} + ); + + return client._http.authedRequest(callback, "PUT", path, undefined, { + membership: membershipValue, + reason: reason + }); +} + +/** + * This is an internal method. + * @param {MatrixClient} client + * @param {string} roomId + * @param {string} userId + * @param {string} membership + * @param {string} reason + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +function _membershipChange(client, roomId, userId, membership, reason, callback) { + if (utils.isFunction(reason)) { callback = reason; reason = undefined; } + + var path = utils.encodeUri("/rooms/$room_id/$membership", { + $room_id: roomId, + $membership: membership + }); + return client._http.authedRequest( + callback, "POST", path, undefined, { + user_id: userId, // may be undefined e.g. on leave + reason: reason + } + ); +} + +/** + * Obtain a dict of actions which should be performed for this event according + * to the push rules for this user. + * @param {MatrixEvent} event The event to get push actions for. + * @return {module:pushprocessor~PushAction} A dict of actions to perform. + */ +MatrixClient.prototype.getPushActionsForEvent = function(event) { + if (event._pushActions === undefined) { + var pushProcessor = new PushProcessor(this); + event._pushActions = pushProcessor.actionsForEvent(event); + } + return event._pushActions; +}; + +// Profile operations +// ================== + +/** + * @param {string} info The kind of info to set (e.g. 'avatar_url') + * @param {Object} data The JSON object to set. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setProfileInfo = function(info, data, callback) { + var path = utils.encodeUri("/profile/$userId/$info", { + $userId: this.credentials.userId, + $info: info + }); + return this._http.authedRequest( + callback, "PUT", path, undefined, data + ); +}; + +/** + * @param {string} name + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setDisplayName = function(name, callback) { + return this.setProfileInfo( + "displayname", { displayname: name }, callback + ); +}; + +/** + * @param {string} url + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setAvatarUrl = function(url, callback) { + return this.setProfileInfo( + "avatar_url", { avatar_url: url }, callback + ); +}; + +/** + * Turn an MXC URL into an HTTP one. This method is experimental and + * may change. + * @param {string} mxcUrl The MXC URL + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs + * directly. Fetching such URLs will leak information about the user to + * anyone they share a room with. If false, will return null for such URLs. + * @return {?string} the avatar URL or null. + */ +MatrixClient.prototype.mxcUrlToHttp = + function(mxcUrl, width, height, resizeMethod, allowDirectLinks) { + return contentRepo.getHttpUriForMxc( + this.baseUrl, mxcUrl, width, height, resizeMethod, allowDirectLinks + ); +}; + +/** + * @param {string} presence + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + * @throws If 'presence' isn't a valid presence enum value. + */ +MatrixClient.prototype.setPresence = function(presence, callback) { + var path = utils.encodeUri("/presence/$userId/status", { + $userId: this.credentials.userId + }); + var validStates = ["offline", "online", "unavailable"]; + if (validStates.indexOf(presence) == -1) { + throw new Error("Bad presence value: " + presence); + } + var content = { + presence: presence + }; + return this._http.authedRequest( + callback, "PUT", path, undefined, content + ); +}; + +/** + * Retrieve older messages from the given room and put them in the timeline. + * + * If this is called multiple times whilst a request is ongoing, the same + * Promise will be returned. If there was a problem requesting scrollback, there + * will be a small delay before another request can be made (to prevent tight-looping + * when there is no connection). + * + * @param {Room} room The room to get older messages in. + * @param {Integer} limit Optional. The maximum number of previous events to + * pull in. Default: 30. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: Room. If you are at the beginning + * of the timeline, Room.oldState.paginationToken will be + * null. + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.scrollback = function(room, limit, callback) { + if (utils.isFunction(limit)) { callback = limit; limit = undefined; } + limit = limit || 30; + var timeToWaitMs = 0; + + var info = this._ongoingScrollbacks[room.roomId] || {}; + if (info.promise) { + return info.promise; + } + else if (info.errorTs) { + var timeWaitedMs = Date.now() - info.errorTs; + timeToWaitMs = Math.max(SCROLLBACK_DELAY_MS - timeWaitedMs, 0); + } + + if (room.oldState.paginationToken === null) { + return q(room); // already at the start. + } + // attempt to grab more events from the store first + var numAdded = this.store.scrollback(room, limit).length; + if (numAdded === limit) { + // store contained everything we needed. + return q(room); + } + // reduce the required number of events appropriately + limit = limit - numAdded; + + var path = utils.encodeUri( + "/rooms/$roomId/messages", {$roomId: room.roomId} + ); + var params = { + from: room.oldState.paginationToken, + limit: limit, + dir: 'b' + }; + var defer = q.defer(); + info = { + promise: defer.promise, + errorTs: null + }; + var self = this; + // wait for a time before doing this request + // (which may be 0 in order not to special case the code paths) + q.delay(timeToWaitMs).then(function() { + return self._http.authedRequest(callback, "GET", path, params); + }).done(function(res) { + var matrixEvents = utils.map(res.chunk, _PojoToMatrixEventMapper(self)); + room.addEventsToTimeline(matrixEvents, true, room.getLiveTimeline()); + room.oldState.paginationToken = res.end; + if (res.chunk.length === 0) { + room.oldState.paginationToken = null; + } + self.store.storeEvents(room, matrixEvents, res.end, true); + self._ongoingScrollbacks[room.roomId] = null; + _resolve(callback, defer, room); + }, function(err) { + self._ongoingScrollbacks[room.roomId] = { + errorTs: Date.now() + }; + _reject(callback, defer, err); + }); + this._ongoingScrollbacks[room.roomId] = info; + return defer.promise; +}; + +/** + * Take an EventContext, and back/forward-fill results. + * + * @param {module:models/event-context.EventContext} eventContext context + * object to be updated + * @param {Object} opts + * @param {boolean} opts.backwards true to fill backwards, false to go forwards + * @param {boolean} opts.limit number of events to request + * + * @return {module:client.Promise} Resolves: updated EventContext object + * @return {Error} Rejects: with an error response. + */ +MatrixClient.prototype.paginateEventContext = function(eventContext, opts) { + // TODO: we should implement a backoff (as per scrollback()) to deal more + // nicely with HTTP errors. + opts = opts || {}; + var backwards = opts.backwards || false; + + var token = eventContext.getPaginateToken(backwards); + if (!token) { + // no more results. + return q.reject(new Error("No paginate token")); + } + + var dir = backwards ? 'b' : 'f'; + var pendingRequest = eventContext._paginateRequests[dir]; + + if (pendingRequest) { + // already a request in progress - return the existing promise + return pendingRequest; + } + + var path = utils.encodeUri( + "/rooms/$roomId/messages", {$roomId: eventContext.getEvent().getRoomId()} + ); + var params = { + from: token, + limit: ('limit' in opts) ? opts.limit : 30, + dir: dir + }; + + var self = this; + var promise = + self._http.authedRequest(undefined, "GET", path, params + ).then(function(res) { + var token = res.end; + if (res.chunk.length === 0) { + token = null; + } else { + var matrixEvents = utils.map(res.chunk, self.getEventMapper()); + if (backwards) { + // eventContext expects the events in timeline order, but + // back-pagination returns them in reverse order. + matrixEvents.reverse(); + } + eventContext.addEvents(matrixEvents, backwards); + } + eventContext.setPaginateToken(token, backwards); + return eventContext; + }).finally(function() { + eventContext._paginateRequests[dir] = null; + }); + eventContext._paginateRequests[dir] = promise; + + return promise; +}; + +/** + * Get an EventTimeline for the given event + * + *

If the room object already has the given event in its store, the + * corresponding timeline will be returned. Otherwise, a /context request is + * made, and used to construct an EventTimeline. + * + * @param {Room} room The room to look for the event in + * @param {string} eventId The ID of the event to look for + * + * @return {module:client.Promise} Resolves: + * {@link module:models/event-timeline~EventTimeline} including the given + * event + */ +MatrixClient.prototype.getEventTimeline = function(room, eventId) { + // don't allow any timeline support unless it's been enabled. + if (!this.timelineSupport) { + throw new Error("timeline support is disabled. Set the 'timelineSupport'" + + " parameter to true when creating MatrixClient to enable" + + " it."); + } + + if (room.getTimelineForEvent(eventId)) { + return q(room.getTimelineForEvent(eventId)); + } + + var path = utils.encodeUri( + "/rooms/$roomId/context/$eventId", { + $roomId: room.roomId, + $eventId: eventId, + } + ); + + // TODO: we should implement a backoff (as per scrollback()) to deal more + // nicely with HTTP errors. + var self = this; + var promise = + self._http.authedRequest(undefined, "GET", path + ).then(function(res) { + if (!res.event) { + throw new Error("'event' not in '/context' result - homeserver too old?"); + } + + // by the time the request completes, the event might have ended up in + // the timeline. + if (room.getTimelineForEvent(eventId)) { + return room.getTimelineForEvent(eventId); + } + + // we start with the last event, since that's the point at which we + // have known state. + // events_after is already backwards; events_before is forwards. + res.events_after.reverse(); + var events = res.events_after + .concat([res.event]) + .concat(res.events_before); + var matrixEvents = utils.map(events, self.getEventMapper()); + + var timeline = room.getTimelineForEvent(matrixEvents[0].getId()); + if (!timeline) { + timeline = room.addTimeline(); + timeline.initialiseState(utils.map(res.state, + self.getEventMapper())); + timeline.getState(EventTimeline.FORWARDS).paginationToken = res.end; + } + room.addEventsToTimeline(matrixEvents, true, timeline, res.start); + + // there is no guarantee that the event ended up in "timeline" (we + // might have switched to a neighbouring timeline) - so check the + // room's index again. On the other hand, there's no guarantee the + // event ended up anywhere, if it was later redacted, so we just + // return the timeline we first thought of. + return room.getTimelineForEvent(eventId) || timeline; + }); + return promise; +}; + + +/** + * Take an EventTimeline, and back/forward-fill results. + * + * @param {module:models/event-timeline~EventTimeline} eventTimeline timeline + * object to be updated + * @param {Object} [opts] + * @param {boolean} [opts.backwards = false] true to fill backwards, + * false to go forwards + * @param {number} [opts.limit = 30] number of events to request + * + * @return {module:client.Promise} Resolves to a boolean: false if there are no + * events and we reached either end of the timeline; else true. + */ +MatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) { + // TODO: we should implement a backoff (as per scrollback()) to deal more + // nicely with HTTP errors. + opts = opts || {}; + var backwards = opts.backwards || false; + + var room = this.getRoom(eventTimeline.getRoomId()); + if (!room) { + throw new Error("Unknown room " + eventTimeline.getRoomId()); + } + + var dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS; + + var token = eventTimeline.getPaginationToken(dir); + if (!token) { + // no token - no results. + return q(false); + } + + var pendingRequest = eventTimeline._paginationRequests[dir]; + + if (pendingRequest) { + // already a request in progress - return the existing promise + return pendingRequest; + } + + var path = utils.encodeUri( + "/rooms/$roomId/messages", {$roomId: eventTimeline.getRoomId()} + ); + var params = { + from: token, + limit: ('limit' in opts) ? opts.limit : 30, + dir: dir + }; + + var self = this; + + var promise = + this._http.authedRequest(undefined, "GET", path, params + ).then(function(res) { + var token = res.end; + var matrixEvents = utils.map(res.chunk, self.getEventMapper()); + room.addEventsToTimeline(matrixEvents, backwards, eventTimeline, token); + + // if we've hit the end of the timeline, we need to stop trying to + // paginate. We need to keep the 'forwards' token though, to make sure + // we can recover from gappy syncs. + if (backwards && res.end == res.start) { + eventTimeline.setPaginationToken(null, dir); + } + return res.end != res.start; + }).finally(function() { + eventTimeline._paginationRequests[dir] = null; + }); + eventTimeline._paginationRequests[dir] = promise; + + return promise; +}; + +// Registration/Login operations +// ============================= + +/** + * @param {string} loginType + * @param {Object} data + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.login = function(loginType, data, callback) { + var login_data = { + type: loginType, + device_id: this.deviceId, + initial_device_display_name: this.defaultDeviceDisplayName, + }; + + // merge data into login_data + for (var k in data) { + if (data.hasOwnProperty(k)) { login_data[k] = data[k]; } + } + + return this._http.authedRequest( + callback, "POST", "/login", undefined, login_data + ); +}; + +/** + * Register a guest account. + * @param {Object=} opts Registration options + * @param {Object} opts.body JSON HTTP body to provide. + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.registerGuest = function(opts, callback) { + opts = opts || {}; + opts.body = opts.body || {}; + return this.registerRequest(opts.body, "guest", callback); +}; + +/** + * Peek into a room and receive updates about the room. This only works if the + * history visibility for the room is world_readable. + * @param {String} roomId The room to attempt to peek into. + * @return {module:client.Promise} Resolves: Room object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.peekInRoom = function(roomId) { + if (this._peekSync) { + this._peekSync.stopPeeking(); + } + this._peekSync = new SyncApi(this, this._clientOpts); + return this._peekSync.peek(roomId); +}; + +/** + * Stop any ongoing room peeking. + */ +MatrixClient.prototype.stopPeeking = function() { + if (this._peekSync) { + this._peekSync.stopPeeking(); + this._peekSync = null; + } +}; + +/** + * Set r/w flags for guest access in a room. + * @param {string} roomId The room to configure guest access in. + * @param {Object} opts Options + * @param {boolean} opts.allowJoin True to allow guests to join this room. This + * implicitly gives guests write access. If false or not given, guests are + * explicitly forbidden from joining the room. + * @param {boolean} opts.allowRead True to set history visibility to + * be world_readable. This gives guests read access *from this point forward*. + * If false or not given, history visibility is not modified. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setGuestAccess = function(roomId, opts) { + var writePromise = this.sendStateEvent(roomId, "m.room.guest_access", { + guest_access: opts.allowJoin ? "can_join" : "forbidden" + }); + + var readPromise = q(); + if (opts.allowRead) { + readPromise = this.sendStateEvent(roomId, "m.room.history_visibility", { + history_visibility: "world_readable" + }); + } + + return q.all(readPromise, writePromise); +}; + +/** + * @param {string} username + * @param {string} password + * @param {string} sessionId + * @param {Object} auth + * @param {boolean} bindEmail + * @param {string} guestAccessToken + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.register = function(username, password, + sessionId, auth, bindEmail, guestAccessToken, + callback) { + if (auth === undefined) { auth = {}; } + if (sessionId) { auth.session = sessionId; } + + var params = { + auth: auth + }; + if (username !== undefined) { params.username = username; } + if (password !== undefined) { params.password = password; } + if (bindEmail !== undefined) { params.bind_email = bindEmail; } + if (guestAccessToken !== undefined) { params.guest_access_token = guestAccessToken; } + + return this.registerRequest(params, undefined, callback); +}; + +/** + * @param {Object} data parameters for registration request + * @param {string=} kind type of user to register. may be "guest" + * @param {module:client.callback=} callback + * @return {module:client.Promise} Resolves: to the /register response + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.registerRequest = function(data, kind, callback) { + var params = {}; + if (kind) { params.kind = kind; } + + return this._http.request( + callback, "POST", "/register", params, data + ); +}; + +/** + * Requests an email verification token for the purposes of registration. + * This API proxies the Identity Server /validate/email/requestToken API, + * adding registration-specific behaviour. Specifically, if an account with + * the given email address already exists, it will either send an email + * to the address informing them of this or return M_THREEPID_IN_USE + * (which one is up to the Home Server). + * + * requestEmailToken calls the equivalent API directly on the ID server, + * therefore bypassing the registration-specific logic. + * + * Parameters and return value are as for requestEmailToken + + * @param {string} email As requestEmailToken + * @param {string} clientSecret As requestEmailToken + * @param {number} sendAttempt As requestEmailToken + * @param {string} nextLink As requestEmailToken + * @param {module:client.callback} callback Optional. As requestEmailToken + * @return {module:client.Promise} Resolves: As requestEmailToken + */ +MatrixClient.prototype.requestRegisterEmailToken = function(email, clientSecret, + sendAttempt, nextLink, callback) { + return this._requestTokenFromEndpoint( + "/register/email/requestToken", + email, clientSecret, sendAttempt, nextLink, callback + ); +}; + +/** + * Requests an email verification token for the purposes of adding a + * third party identifier to an account. + * This API proxies the Identity Server /validate/email/requestToken API, + * adding specific behaviour for the addition of email addresses to an + * account. Specifically, if an account with + * the given email address already exists, it will either send an email + * to the address informing them of this or return M_THREEPID_IN_USE + * (which one is up to the Home Server). + * + * requestEmailToken calls the equivalent API directly on the ID server, + * therefore bypassing the email addition specific logic. + * + * @param {string} email As requestEmailToken + * @param {string} clientSecret As requestEmailToken + * @param {number} sendAttempt As requestEmailToken + * @param {string} nextLink As requestEmailToken + * @param {module:client.callback} callback Optional. As requestEmailToken + * @return {module:client.Promise} Resolves: As requestEmailToken + */ +MatrixClient.prototype.requestAdd3pidEmailToken = function(email, clientSecret, + sendAttempt, nextLink, callback) { + return this._requestTokenFromEndpoint( + "/account/3pid/email/requestToken", + email, clientSecret, sendAttempt, nextLink, callback + ); +}; + +/** + * Requests an email verification token for the purposes of resetting + * the password on an account. + * This API proxies the Identity Server /validate/email/requestToken API, + * adding specific behaviour for the password resetting. Specifically, + * if no account with the given email address exists, it may either + * return M_THREEPID_NOT_FOUND or send an email + * to the address informing them of this (which one is up to the Home Server). + * + * requestEmailToken calls the equivalent API directly on the ID server, + * therefore bypassing the password reset specific logic. + * + * @param {string} email As requestEmailToken + * @param {string} clientSecret As requestEmailToken + * @param {number} sendAttempt As requestEmailToken + * @param {string} nextLink As requestEmailToken + * @param {module:client.callback} callback Optional. As requestEmailToken + * @return {module:client.Promise} Resolves: As requestEmailToken + */ +MatrixClient.prototype.requestPasswordEmailToken = function(email, clientSecret, + sendAttempt, nextLink, callback) { + return this._requestTokenFromEndpoint( + "/account/password/email/requestToken", + email, clientSecret, sendAttempt, nextLink, callback + ); +}; + +/** + * Internal utility function for requesting validation tokens from usage-specific + * requestToken endpoints. + * + * @param {string} endpoint The endpoint to send the request to + * @param {string} email As requestEmailToken + * @param {string} clientSecret As requestEmailToken + * @param {number} sendAttempt As requestEmailToken + * @param {string} nextLink As requestEmailToken + * @param {module:client.callback} callback Optional. As requestEmailToken + * @return {module:client.Promise} Resolves: As requestEmailToken + */ +MatrixClient.prototype._requestTokenFromEndpoint = function(endpoint, + email, clientSecret, + sendAttempt, nextLink, callback) { + var id_server_url = url.parse(this.idBaseUrl); + if (id_server_url.host === null) { + throw new Error("Invalid ID server URL: " + this.idBaseUrl); + } + + var params = { + client_secret: clientSecret, + email: email, + send_attempt: sendAttempt, + next_link: nextLink, + id_server: id_server_url.host, + }; + return this._http.request( + callback, "POST", endpoint, undefined, + params + ); +}; + +/** + * @param {string} user + * @param {string} password + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.loginWithPassword = function(user, password, callback) { + return this.login("m.login.password", { + user: user, + password: password + }, callback); +}; + +/** + * @param {string} relayState URL Callback after SAML2 Authentication + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.loginWithSAML2 = function(relayState, callback) { + return this.login("m.login.saml2", { + relay_state: relayState + }, callback); +}; + +/** + * @param {string} redirectUrl The URL to redirect to after the HS + * authenticates with CAS. + * @return {string} The HS URL to hit to begin the CAS login process. + */ +MatrixClient.prototype.getCasLoginUrl = function(redirectUrl) { + return this._http.getUrl("/login/cas/redirect", { + "redirectUrl": redirectUrl + }, httpApi.PREFIX_UNSTABLE); +}; + +/** + * @param {string} token Login token previously received from homeserver + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.loginWithToken = function(token, callback) { + return this.login("m.login.token", { + token: token + }, callback); +}; + +// Push operations +// =============== + +/** + * Get the room-kind push rule associated with a room. + * @param {string} scope "global" or device-specific. + * @param {string} roomId the id of the room. + * @return {object} the rule or undefined. + */ +MatrixClient.prototype.getRoomPushRule = function(scope, roomId) { + // There can be only room-kind push rule per room + // and its id is the room id. + if (this.pushRules) { + for (var i = 0; i < this.pushRules[scope].room.length; i++) { + var rule = this.pushRules[scope].room[i]; + if (rule.rule_id === roomId) { + return rule; + } + } + } + else { + throw new Error( + "SyncApi.sync() must be done before accessing to push rules." + ); + } +}; + +/** + * Set a room-kind muting push rule in a room. + * The operation also updates MatrixClient.pushRules at the end. + * @param {string} scope "global" or device-specific. + * @param {string} roomId the id of the room. + * @param {string} mute the mute state. + * @return {module:client.Promise} Resolves: result object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.setRoomMutePushRule = function(scope, roomId, mute) { + var self = this; + var deferred, hasDontNotifyRule; + + // Get the existing room-kind push rule if any + var roomPushRule = this.getRoomPushRule(scope, roomId); + if (roomPushRule) { + if (0 <= roomPushRule.actions.indexOf("dont_notify")) { + hasDontNotifyRule = true; + } + } + + if (!mute) { + // Remove the rule only if it is a muting rule + if (hasDontNotifyRule) { + deferred = this.deletePushRule(scope, "room", roomPushRule.rule_id); + } + } + else { + if (!roomPushRule) { + deferred = this.addPushRule(scope, "room", roomId, { + actions: ["dont_notify"] + }); + } + else if (!hasDontNotifyRule) { + // Remove the existing one before setting the mute push rule + // This is a workaround to SYN-590 (Push rule update fails) + deferred = q.defer(); + this.deletePushRule(scope, "room", roomPushRule.rule_id) + .done(function() { + self.addPushRule(scope, "room", roomId, { + actions: ["dont_notify"] + }).done(function() { + deferred.resolve(); + }, function(err) { + deferred.reject(err); + }); + }, function(err) { + deferred.reject(err); + }); + + deferred = deferred.promise; + } + } + + if (deferred) { + // Update this.pushRules when the operation completes + var ruleRefreshDeferred = q.defer(); + deferred.done(function() { + self.getPushRules().done(function(result) { + self.pushRules = result; + ruleRefreshDeferred.resolve(); + }, function(err) { + ruleRefreshDeferred.reject(err); + }); + }, function(err) { + // Update it even if the previous operation fails. This can help the + // app to recover when push settings has been modifed from another client + self.getPushRules().done(function(result) { + self.pushRules = result; + ruleRefreshDeferred.reject(err); + }, function(err2) { + ruleRefreshDeferred.reject(err); + }); + }); + return ruleRefreshDeferred.promise; + } +}; + +// Search +// ====== + +/** + * Perform a server-side search for messages containing the given text. + * @param {Object} opts Options for the search. + * @param {string} opts.query The text to query. + * @param {string=} opts.keys The keys to search on. Defaults to all keys. One + * of "content.body", "content.name", "content.topic". + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.searchMessageText = function(opts, callback) { + return this.search({ + body: { + search_categories: { + room_events: { + keys: opts.keys, + search_term: opts.query + } + } + } + }, callback); +}; + +/** + * Perform a server-side search for room events. + * + * The returned promise resolves to an object containing the fields: + * + * * {number} count: estimate of the number of results + * * {string} next_batch: token for back-pagination; if undefined, there are + * no more results + * * {Array} highlights: a list of words to highlight from the stemming + * algorithm + * * {Array} results: a list of results + * + * Each entry in the results list is a {module:models/search-result.SearchResult}. + * + * @param {Object} opts + * @param {string} opts.term the term to search for + * @param {Object} opts.filter a JSON filter object to pass in the request + * @return {module:client.Promise} Resolves: result object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.searchRoomEvents = function(opts) { + // TODO: support groups + + var body = { + search_categories: { + room_events: { + search_term: opts.term, + filter: opts.filter, + order_by: "recent", + event_context: { + before_limit: 1, + after_limit: 1, + include_profile: true, + } + } + } + }; + + var searchResults = { + _query: body, + results: [], + highlights: [], + }; + + return this.search({body: body}).then( + this._processRoomEventsSearch.bind(this, searchResults) + ); +}; + +/** + * Take a result from an earlier searchRoomEvents call, and backfill results. + * + * @param {object} searchResults the results object to be updated + * @return {module:client.Promise} Resolves: updated result object + * @return {Error} Rejects: with an error response. + */ +MatrixClient.prototype.backPaginateRoomEventsSearch = function(searchResults) { + // TODO: we should implement a backoff (as per scrollback()) to deal more + // nicely with HTTP errors. + + if (!searchResults.next_batch) { + return q.reject(new Error("Cannot backpaginate event search any further")); + } + + if (searchResults.pendingRequest) { + // already a request in progress - return the existing promise + return searchResults.pendingRequest; + } + + var searchOpts = { + body: searchResults._query, + next_batch: searchResults.next_batch, + }; + + var promise = this.search(searchOpts).then( + this._processRoomEventsSearch.bind(this, searchResults) + ).finally(function() { + searchResults.pendingRequest = null; + }); + searchResults.pendingRequest = promise; + + return promise; +}; + +/** + * helper for searchRoomEvents and backPaginateRoomEventsSearch. Processes the + * response from the API call and updates the searchResults + * + * @param {Object} searchResults + * @param {Object} response + * @return {Object} searchResults + * @private + */ +MatrixClient.prototype._processRoomEventsSearch = function(searchResults, response) { + var room_events = response.search_categories.room_events; + + searchResults.count = room_events.count; + searchResults.next_batch = room_events.next_batch; + + // combine the highlight list with our existing list; build an object + // to avoid O(N^2) fail + var highlights = {}; + room_events.highlights.forEach(function(hl) { highlights[hl] = 1; }); + searchResults.highlights.forEach(function(hl) { highlights[hl] = 1; }); + + // turn it back into a list. + searchResults.highlights = Object.keys(highlights); + + // append the new results to our existing results + for (var i = 0; i < room_events.results.length; i++) { + var sr = SearchResult.fromJson(room_events.results[i], this.getEventMapper()); + searchResults.results.push(sr); + } + return searchResults; +}; + + +/** + * Populate the store with rooms the user has left. + * @return {module:client.Promise} Resolves: TODO - Resolved when the rooms have + * been added to the data store. + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.syncLeftRooms = function() { + // Guard against multiple calls whilst ongoing and multiple calls post success + if (this._syncedLeftRooms) { + return q([]); // don't call syncRooms again if it succeeded. + } + if (this._syncLeftRoomsPromise) { + return this._syncLeftRoomsPromise; // return the ongoing request + } + var self = this; + var syncApi = new SyncApi(this, this._clientOpts); + this._syncLeftRoomsPromise = syncApi.syncLeftRooms(); + + // cleanup locks + this._syncLeftRoomsPromise.then(function(res) { + console.log("Marking success of sync left room request"); + self._syncedLeftRooms = true; // flip the bit on success + }).finally(function() { + self._syncLeftRoomsPromise = null; // cleanup ongoing request state + }); + + return this._syncLeftRoomsPromise; +}; + +// Filters +// ======= + +/** + * Create a new filter. + * @param {Object} content The HTTP body for the request + * @return {Filter} Resolves to a Filter object. + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.createFilter = function(content) { + var self = this; + var path = utils.encodeUri("/user/$userId/filter", { + $userId: this.credentials.userId + }); + return this._http.authedRequest( + undefined, "POST", path, undefined, content + ).then(function(response) { + // persist the filter + var filter = Filter.fromJson( + self.credentials.userId, response.filter_id, content + ); + self.store.storeFilter(filter); + return filter; + }); +}; + +/** + * Retrieve a filter. + * @param {string} userId The user ID of the filter owner + * @param {string} filterId The filter ID to retrieve + * @param {boolean} allowCached True to allow cached filters to be returned. + * Default: True. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.getFilter = function(userId, filterId, allowCached) { + if (allowCached) { + var filter = this.store.getFilter(userId, filterId); + if (filter) { + return q(filter); + } + } + + var self = this; + var path = utils.encodeUri("/user/$userId/filter/$filterId", { + $userId: userId, + $filterId: filterId + }); + + return this._http.authedRequest( + undefined, "GET", path, undefined, undefined + ).then(function(response) { + // persist the filter + var filter = Filter.fromJson( + userId, filterId, response + ); + self.store.storeFilter(filter); + return filter; + }); +}; + +/** + * Gets a bearer token from the Home Server that the user can + * present to a third party in order to prove their ownership + * of the Matrix account they are logged into. + * @return {module:client.Promise} Resolves: Token object + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.getOpenIdToken = function() { + var path = utils.encodeUri("/user/$userId/openid/request_token", { + $userId: this.credentials.userId, + }); + + return this._http.authedRequest( + undefined, "POST", path, undefined, {} + ); +}; + + +// VoIP operations +// =============== + +/** + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.turnServer = function(callback) { + return this._http.authedRequest(callback, "GET", "/voip/turnServer"); +}; + +/** + * Get the TURN servers for this home server. + * @return {Array} The servers or an empty list. + */ +MatrixClient.prototype.getTurnServers = function() { + return this._turnServers || []; +}; + +// Higher level APIs +// ================= + +// TODO: stuff to handle: +// local echo +// event dup suppression? - apparently we should still be doing this +// tracking current display name / avatar per-message +// pagination +// re-sending (including persisting pending messages to be sent) +// - Need a nice way to callback the app for arbitrary events like +// displayname changes +// due to ambiguity (or should this be on a chat-specific layer)? +// reconnect after connectivity outages + + +/** + * High level helper method to call initialSync, emit the resulting events, + * and then start polling the eventStream for new events. To listen for these + * events, add a listener for {@link module:client~MatrixClient#event:"event"} + * via {@link module:client~MatrixClient#on}. + * @param {Object=} opts Options to apply when syncing. + * @param {Number=} opts.initialSyncLimit The event limit= to apply + * to initial sync. Default: 8. + * @param {Boolean=} opts.includeArchivedRooms True to put archived=true + * on the /initialSync request. Default: false. + * @param {Boolean=} opts.resolveInvitesToProfiles True to do /profile requests + * on every invite event if the displayname/avatar_url is not known for this user ID. + * Default: false. + * + * @param {String=} opts.pendingEventOrdering Controls where pending messages + * appear in a room's timeline. If "chronological", messages will appear + * in the timeline when the call to sendEvent was made. If + * "detached", pending messages will appear in a separate list, + * accessbile via {@link module:models/room~Room#getPendingEvents}. Default: + * "chronological". + * + * @param {Number=} opts.pollTimeout The number of milliseconds to wait on /events. + * Default: 30000 (30 seconds). + */ +MatrixClient.prototype.startClient = function(opts) { + if (this.clientRunning) { + // client is already running. + return; + } + this.clientRunning = true; + // backwards compat for when 'opts' was 'historyLen'. + if (typeof opts === "number") { + opts = { + initialSyncLimit: opts + }; + } + + this._clientOpts = opts; + + if (this._crypto) { + this._crypto.uploadKeys(5).done(); + } + + // periodically poll for turn servers if we support voip + checkTurnServers(this); + + if (this._syncApi) { + // This shouldn't happen since we thought the client was not running + console.error("Still have sync object whilst not running: stopping old one"); + this._syncApi.stop(); + } + this._syncApi = new SyncApi(this, opts); + this._syncApi.sync(); +}; + +/** + * High level helper method to stop the client from polling and allow a + * clean shutdown. + */ +MatrixClient.prototype.stopClient = function() { + this.clientRunning = false; + // TODO: f.e. Room => self.store.storeRoom(room) ? + if (this._syncApi) { + this._syncApi.stop(); + this._syncApi = null; + } +}; + +function setupCallEventHandler(client) { + var candidatesByCall = { + // callId: [Candidate] + }; + + // Maintain a buffer of events before the client has synced for the first time. + // This buffer will be inspected to see if we should send incoming call + // notifications. It needs to be buffered to correctly determine if an + // incoming call has had a matching answer/hangup. + var callEventBuffer = []; + var isClientPrepared = false; + client.on("sync", function(state) { + if (state === "PREPARED") { + isClientPrepared = true; + var ignoreCallIds = {}; // Set + // inspect the buffer and mark all calls which have been answered + // or hung up before passing them to the call event handler. + for (var i = callEventBuffer.length - 1; i >= 0; i--) { + var ev = callEventBuffer[i]; + if (ev.getType() === "m.call.answer" || + ev.getType() === "m.call.hangup") { + ignoreCallIds[ev.getContent().call_id] = "yep"; + } + } + // now loop through the buffer chronologically and inject them + callEventBuffer.forEach(function(e) { + if (ignoreCallIds[e.getContent().call_id]) { + return; + } + callEventHandler(e); + }); + callEventBuffer = []; + } + }); + + client.on("event", function(event) { + if (!isClientPrepared) { + if (event.getType().indexOf("m.call.") === 0) { + callEventBuffer.push(event); + } + return; + } + callEventHandler(event); + }); + + function callEventHandler(event) { + if (event.getType().indexOf("m.call.") !== 0) { + return; // not a call event + } + var content = event.getContent(); + var call = content.call_id ? client.callList[content.call_id] : undefined; + var i; + //console.log("RECV %s content=%s", event.getType(), JSON.stringify(content)); + + if (event.getType() === "m.call.invite") { + if (event.getSender() === client.credentials.userId) { + return; // ignore invites you send + } + + if (event.getAge() > content.lifetime) { + return; // expired call + } + + if (call && call.state === "ended") { + return; // stale/old invite event + } + if (call) { + console.log( + "WARN: Already have a MatrixCall with id %s but got an " + + "invite. Clobbering.", + content.call_id + ); + } + + call = webRtcCall.createNewMatrixCall(client, event.getRoomId()); + if (!call) { + console.log( + "Incoming call ID " + content.call_id + " but this client " + + "doesn't support WebRTC" + ); + // don't hang up the call: there could be other clients + // connected that do support WebRTC and declining the + // the call on their behalf would be really annoying. + return; + } + + call.callId = content.call_id; + call._initWithInvite(event); + client.callList[call.callId] = call; + + // if we stashed candidate events for that call ID, play them back now + if (candidatesByCall[call.callId]) { + for (i = 0; i < candidatesByCall[call.callId].length; i++) { + call._gotRemoteIceCandidate( + candidatesByCall[call.callId][i] + ); + } + } + + // Were we trying to call that user (room)? + var existingCall; + var existingCalls = utils.values(client.callList); + for (i = 0; i < existingCalls.length; ++i) { + var thisCall = existingCalls[i]; + if (call.room_id === thisCall.room_id && + thisCall.direction === 'outbound' && + (["wait_local_media", "create_offer", "invite_sent"].indexOf( + thisCall.state) !== -1)) { + existingCall = thisCall; + break; + } + } + + if (existingCall) { + // If we've only got to wait_local_media or create_offer and + // we've got an invite, pick the incoming call because we know + // we haven't sent our invite yet otherwise, pick whichever + // call has the lowest call ID (by string comparison) + if (existingCall.state === 'wait_local_media' || + existingCall.state === 'create_offer' || + existingCall.callId > call.callId) { + console.log( + "Glare detected: answering incoming call " + call.callId + + " and canceling outgoing call " + existingCall.callId + ); + existingCall._replacedBy(call); + call.answer(); + } + else { + console.log( + "Glare detected: rejecting incoming call " + call.callId + + " and keeping outgoing call " + existingCall.callId + ); + call.hangup(); + } + } + else { + client.emit("Call.incoming", call); + } + } + else if (event.getType() === 'm.call.answer') { + if (!call) { + return; + } + if (event.getSender() === client.credentials.userId) { + if (call.state === 'ringing') { + call._onAnsweredElsewhere(content); + } + } + else { + call._receivedAnswer(content); + } + } + else if (event.getType() === 'm.call.candidates') { + if (event.getSender() === client.credentials.userId) { + return; + } + if (!call) { + // store the candidates; we may get a call eventually. + if (!candidatesByCall[content.call_id]) { + candidatesByCall[content.call_id] = []; + } + candidatesByCall[content.call_id] = candidatesByCall[ + content.call_id + ].concat(content.candidates); + } + else { + for (i = 0; i < content.candidates.length; i++) { + call._gotRemoteIceCandidate(content.candidates[i]); + } + } + } + else if (event.getType() === 'm.call.hangup') { + // Note that we also observe our own hangups here so we can see + // if we've already rejected a call that would otherwise be valid + if (!call) { + // if not live, store the fact that the call has ended because + // we're probably getting events backwards so + // the hangup will come before the invite + call = webRtcCall.createNewMatrixCall(client, event.getRoomId()); + if (call) { + call.callId = content.call_id; + call._initWithHangup(event); + client.callList[content.call_id] = call; + } + } + else { + if (call.state !== 'ended') { + call._onHangupReceived(content); + delete client.callList[content.call_id]; + } + } + } + } +} + +function checkTurnServers(client) { + if (!client._supportsVoip) { + return; + } + if (client.isGuest()) { + return; // guests can't access TURN servers + } + + client.turnServer().done(function(res) { + if (res.uris) { + console.log("Got TURN URIs: " + res.uris + " refresh in " + + res.ttl + " secs"); + // map the response to a format that can be fed to + // RTCPeerConnection + var servers = { + urls: res.uris, + username: res.username, + credential: res.password + }; + client._turnServers = [servers]; + // re-fetch when we're about to reach the TTL + setTimeout(function() { checkTurnServers(client); }, + (res.ttl || (60 * 60)) * 1000 * 0.9 + ); + } + }, function(err) { + console.error("Failed to get TURN URIs"); + setTimeout(function() { checkTurnServers(client); }, 60000); + }); +} + +function _reject(callback, defer, err) { + if (callback) { + callback(err); + } + defer.reject(err); +} + +function _resolve(callback, defer, res) { + if (callback) { + callback(null, res); + } + defer.resolve(res); +} + +function _PojoToMatrixEventMapper(client) { + function mapper(plainOldJsObject) { + var clearData; + if (plainOldJsObject.type === "m.room.encrypted") { + clearData = _decryptMessage(client, plainOldJsObject); + } + return new MatrixEvent(plainOldJsObject, clearData); + } + return mapper; +} + +/** + * @return {Function} + */ +MatrixClient.prototype.getEventMapper = function() { + return _PojoToMatrixEventMapper(this); +}; + +// Identity Server Operations +// ========================== + +/** + * Generates a random string suitable for use as a client secret. This + * method is experimental and may change. + * @return {string} A new client secret + */ +MatrixClient.prototype.generateClientSecret = function() { + var ret = ""; + var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + for (var i = 0; i < 32; i++) { + ret += chars.charAt(Math.floor(Math.random() * chars.length)); + } + + return ret; +}; + +/** */ +module.exports.MatrixClient = MatrixClient; +/** */ +module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED; + +// MatrixClient Event JSDocs + +/** + * Fires whenever the SDK receives a new event. + * @event module:client~MatrixClient#"event" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @example + * matrixClient.on("event", function(event){ + * var sender = event.getSender(); + * }); + */ + +/** + * Fires whenever the SDK's syncing state is updated. The state can be one of: + *
    + *
  • PREPARED : The client has synced with the server at least once and is + * ready for methods to be called on it. This will be immediately followed by + * a state of SYNCING. This is the equivalent of "syncComplete" in the + * previous API.
  • + *
  • SYNCING : The client is currently polling for new events from the server. + * This will be called after processing latest events from a sync.
  • + *
  • ERROR : The client has had a problem syncing with the server. If this is + * called before PREPARED then there was a problem performing the initial + * sync. If this is called after PREPARED then there was a problem polling + * the server for updates. This may be called multiple times even if the state is + * already ERROR. This is the equivalent of "syncError" in the previous + * API.
  • + *
  • STOPPED: The client has stopped syncing with server due to stopClient + * being called. + *
  • + *
+ * State transition diagram: + *
+ *                                          +---->STOPPED
+ *                                          |
+ *              +----->PREPARED -------> SYNCING <--+
+ *              |        ^                  |       |
+ *   null ------+        |  +---------------+       |
+ *              |        |  V                       |
+ *              +------->ERROR ---------------------+
+ *
+ * NB: 'null' will never be emitted by this event.
+ * 
+ * Transitions: + *
    + *
  • null -> PREPARED : Occurs when the initial sync is completed + * first time. This involves setting up filters and obtaining push rules. + *
  • null -> ERROR : Occurs when the initial sync failed first time. + *
  • ERROR -> PREPARED : Occurs when the initial sync succeeds + * after previously failing. + *
  • PREPARED -> SYNCING : Occurs immediately after transitioning + * to PREPARED. Starts listening for live updates rather than catching up. + *
  • SYNCING -> ERROR : Occurs the first time a client cannot perform a + * live update. + *
  • ERROR -> SYNCING : Occurs when the client has performed a + * live update after having previously failed. + *
  • ERROR -> ERROR : Occurs when the client has failed to sync + * for a second time or more.
  • + *
  • SYNCING -> SYNCING : Occurs when the client has performed a live + * update. This is called after processing.
  • + *
  • * -> STOPPED : Occurs once the client has stopped syncing or + * trying to sync after stopClient has been called.
  • + *
+ * + * @event module:client~MatrixClient#"sync" + * @param {string} state An enum representing the syncing state. One of "PREPARED", + * "SYNCING", "ERROR", "STOPPED". + * @param {?string} prevState An enum representing the previous syncing state. + * One of "PREPARED", "SYNCING", "ERROR", "STOPPED" or null. + * @param {?Object} data Data about this transition. + * @param {MatrixError} data.err The matrix error if state=ERROR. + * @example + * matrixClient.on("sync", function(state, prevState, data) { + * switch (state) { + * case "ERROR": + * // update UI to say "Connection Lost" + * break; + * case "SYNCING": + * // update UI to remove any "Connection Lost" message + * break; + * case "PREPARED": + * // the client instance is ready to be queried. + * var rooms = matrixClient.getRooms(); + * break; + * } + * }); + */ + + /** + * Fires whenever a new Room is added. This will fire when you are invited to a + * room, as well as when you join a room. This event is experimental and + * may change. + * @event module:client~MatrixClient#"Room" + * @param {Room} room The newly created, fully populated room. + * @example + * matrixClient.on("Room", function(room){ + * var roomId = room.roomId; + * }); + */ + + /** + * Fires whenever a Room is removed. This will fire when you forget a room. + * This event is experimental and may change. + * @event module:client~MatrixClient#"deleteRoom" + * @param {string} roomId The deleted room ID. + * @example + * matrixClient.on("deleteRoom", function(roomId){ + * // update UI from getRooms() + * }); + */ + +/** + * Fires whenever an incoming call arrives. + * @event module:client~MatrixClient#"Call.incoming" + * @param {module:webrtc/call~MatrixCall} call The incoming call. + * @example + * matrixClient.on("Call.incoming", function(call){ + * call.answer(); // auto-answer + * }); + */ + +/** + * Fires whenever the login session the JS SDK is using is no + * longer valid and the user must log in again. + * NB. This only fires when action is required from the user, not + * when then login session can be renewed by using a refresh token. + * @event module:client~MatrixClient#"Session.logged_out" + * @example + * matrixClient.on("Session.logged_out", function(call){ + * // show the login screen + * }); + */ + +/** + * Fires when a device is marked as verified/unverified/blocked/unblocked by + * {@link module:client~MatrixClient#setDeviceVerified|MatrixClient.setDeviceVerified} or + * {@link module:client~MatrixClient#setDeviceBlocked|MatrixClient.setDeviceBlocked}. + * + * @event module:client~MatrixClient#"deviceVerificationChanged" + * @param {string} userId the owner of the verified device + * @param {string} deviceId the id of the verified device + */ + +/** + * Fires whenever new user-scoped account_data is added. + * @event module:client~MatrixClient#"Room" + * @param {MatrixEvent} event The event describing the account_data just added + * @example + * matrixClient.on("accountData", function(event){ + * myAccountData[event.type] = event.content; + * }); + */ + + +// EventEmitter JSDocs + +/** + * The {@link https://nodejs.org/api/events.html|EventEmitter} class. + * @external EventEmitter + * @see {@link https://nodejs.org/api/events.html} + */ + +/** + * Adds a listener to the end of the listeners array for the specified event. + * No checks are made to see if the listener has already been added. Multiple + * calls passing the same combination of event and listener will result in the + * listener being added multiple times. + * @function external:EventEmitter#on + * @param {string} event The event to listen for. + * @param {Function} listener The function to invoke. + * @return {EventEmitter} for call chaining. + */ + +/** + * Alias for {@link external:EventEmitter#on}. + * @function external:EventEmitter#addListener + * @param {string} event The event to listen for. + * @param {Function} listener The function to invoke. + * @return {EventEmitter} for call chaining. + */ + +/** + * Adds a one time listener for the event. This listener is invoked only + * the next time the event is fired, after which it is removed. + * @function external:EventEmitter#once + * @param {string} event The event to listen for. + * @param {Function} listener The function to invoke. + * @return {EventEmitter} for call chaining. + */ + +/** + * Remove a listener from the listener array for the specified event. + * Caution: changes array indices in the listener array behind the + * listener. + * @function external:EventEmitter#removeListener + * @param {string} event The event to listen for. + * @param {Function} listener The function to invoke. + * @return {EventEmitter} for call chaining. + */ + +/** + * Removes all listeners, or those of the specified event. It's not a good idea + * to remove listeners that were added elsewhere in the code, especially when + * it's on an emitter that you didn't create (e.g. sockets or file streams). + * @function external:EventEmitter#removeAllListeners + * @param {string} event Optional. The event to remove listeners for. + * @return {EventEmitter} for call chaining. + */ + +/** + * Execute each of the listeners in order with the supplied arguments. + * @function external:EventEmitter#emit + * @param {string} event The event to emit. + * @param {Function} listener The function to invoke. + * @return {boolean} true if event had listeners, false otherwise. + */ + +/** + * By default EventEmitters will print a warning if more than 10 listeners are + * added for a particular event. This is a useful default which helps finding + * memory leaks. Obviously not all Emitters should be limited to 10. This + * function allows that to be increased. Set to zero for unlimited. + * @function external:EventEmitter#setMaxListeners + * @param {Number} n The max number of listeners. + * @return {EventEmitter} for call chaining. + */ + +// MatrixClient Callback JSDocs + +/** + * The standard MatrixClient callback interface. Functions which accept this + * will specify 2 return arguments. These arguments map to the 2 parameters + * specified in this callback. + * @callback module:client.callback + * @param {Object} err The error value, the "rejected" value or null. + * @param {Object} data The data returned, the "resolved" value. + */ + + /** + * {@link https://github.com/kriskowal/q|A promise implementation (Q)}. Functions + * which return this will specify 2 return arguments. These arguments map to the + * "onFulfilled" and "onRejected" values of the Promise. + * @typedef {Object} Promise + * @static + * @property {Function} then promise.then(onFulfilled, onRejected, onProgress) + * @property {Function} catch promise.catch(onRejected) + * @property {Function} finally promise.finally(callback) + * @property {Function} done promise.done(onFulfilled, onRejected, onProgress) + */ + +},{"./base-apis":3,"./content-repo":5,"./crypto":6,"./filter":7,"./http-api":8,"./models/event":12,"./models/event-timeline":11,"./models/search-result":17,"./pushprocessor":19,"./store/stub":24,"./sync":26,"./utils":28,"./webrtc/call":29,"events":179,"q":205,"url":201}],5:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/** + * @module content-repo + */ +var utils = require("./utils"); + +/** Content Repo utility functions */ +module.exports = { + /** + * Get the HTTP URL for an MXC URI. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} mxc The mxc:// URI. + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs + * directly. Fetching such URLs will leak information about the user to + * anyone they share a room with. If false, will return the emptry string + * for such URLs. + * @return {string} The complete URL to the content. + */ + getHttpUriForMxc: function(baseUrl, mxc, width, height, + resizeMethod, allowDirectLinks) { + if (typeof mxc !== "string" || !mxc) { + return ''; + } + if (mxc.indexOf("mxc://") !== 0) { + if (allowDirectLinks) { + return mxc; + } else { + return ''; + } + } + var serverAndMediaId = mxc.slice(6); // strips mxc:// + var prefix = "/_matrix/media/v1/download/"; + var params = {}; + + if (width) { + params.width = width; + } + if (height) { + params.height = height; + } + if (resizeMethod) { + params.method = resizeMethod; + } + if (utils.keys(params).length > 0) { + // these are thumbnailing params so they probably want the + // thumbnailing API... + prefix = "/_matrix/media/v1/thumbnail/"; + } + + var fragmentOffset = serverAndMediaId.indexOf("#"), + fragment = ""; + if (fragmentOffset >= 0) { + fragment = serverAndMediaId.substr(fragmentOffset); + serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); + } + return baseUrl + prefix + serverAndMediaId + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))) + fragment; + }, + + /** + * Get an identicon URL from an arbitrary string. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} identiconString The string to create an identicon for. + * @param {Number} width The desired width of the image in pixels. Default: 96. + * @param {Number} height The desired height of the image in pixels. Default: 96. + * @return {string} The complete URL to the identicon. + */ + getIdenticonUri: function(baseUrl, identiconString, width, height) { + if (!identiconString) { + return null; + } + if (!width) { width = 96; } + if (!height) { height = 96; } + var params = { + width: width, + height: height + }; + + var path = utils.encodeUri("/_matrix/media/v1/identicon/$ident", { + $ident: identiconString + }); + return baseUrl + path + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))); + } +}; + +},{"./utils":28}],6:[function(require,module,exports){ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/** + * Internal module + * + * @module crypto + */ + +var anotherjson = require('another-json'); +var q = require("q"); + +var utils = require("./utils"); +var OlmDevice = require("./OlmDevice"); + +var OLM_ALGORITHM = "m.olm.v1.curve25519-aes-sha2"; + +var DeviceVerification = { + VERIFIED: 1, + UNVERIFIED: 0, + BLOCKED: -1, +}; + +/** + * Stored information about a user's device + * + * @typedef {Object} DeviceInfo + * + * @property {string[]} altorithms list of algorithms supported by this device + * + * @property {Object} keys a map from <key type>:<id> -> key + * + * @property {DeviceVerification} verified whether the device has been + * verified by the user + * + * @property {Object} unsigned additional data from the homeserver + */ + +/** + * Cryptography bits + * + * @constructor + * + * @param {module:base-apis~MatrixBaseApis} baseApis base matrix api interface + * + * @param {module:store/session/webstorage~WebStorageSessionStore} sessionStore + * Store to be used for end-to-end crypto session data + * + * @param {string} userId The user ID for the local user + * + * @param {string} deviceId The identifier for this device. + */ +function Crypto(baseApis, sessionStore, userId, deviceId) { + this._baseApis = baseApis; + this._sessionStore = sessionStore; + this._userId = userId; + this._deviceId = deviceId; + + this._cryptoAlgorithms = []; + + this._olmDevice = new OlmDevice(sessionStore); + this._cryptoAlgorithms = [OLM_ALGORITHM]; + + // build our device keys: these will later be uploaded + this._deviceKeys = {}; + this._deviceKeys["ed25519:" + this._deviceId] = + this._olmDevice.deviceEd25519Key; + this._deviceKeys["curve25519:" + this._deviceId] = + this._olmDevice.deviceCurve25519Key; + + // add our own deviceinfo to the sessionstore + var deviceInfo = { + keys: this._deviceKeys, + algorithms: this._cryptoAlgorithms, + verified: DeviceVerification.VERIFIED, + }; + var myDevices = this._sessionStore.getEndToEndDevicesForUser( + this._userId + ) || {}; + myDevices[this._deviceId] = deviceInfo; + this._sessionStore.storeEndToEndDevicesForUser( + this._userId, myDevices + ); +} + +/** + * Get the Ed25519 key for this device + * + * @return {string} base64-encoded ed25519 key. + */ +Crypto.prototype.getDeviceEd25519Key = function() { + return this._olmDevice.deviceEd25519Key; +}; + +/** + * Upload the device keys to the homeserver and ensure that the + * homeserver has enough one-time keys. + * @param {number} maxKeys The maximum number of keys to generate + * @return {object} A promise that will resolve when the keys are uploaded. + */ +Crypto.prototype.uploadKeys = function(maxKeys) { + var self = this; + return _uploadDeviceKeys(this).then(function(res) { + var keyCount = res.one_time_key_counts.curve25519 || 0; + var maxOneTimeKeys = self._olmDevice.maxNumberOfOneTimeKeys(); + var keyLimit = Math.floor(maxOneTimeKeys / 2); + var numberToGenerate = Math.max(keyLimit - keyCount, 0); + if (maxKeys !== undefined) { + numberToGenerate = Math.min(numberToGenerate, maxKeys); + } + + if (numberToGenerate <= 0) { + return; + } + + self._olmDevice.generateOneTimeKeys(numberToGenerate); + return _uploadOneTimeKeys(self); + }); +}; + +// returns a promise which resolves to the response +function _uploadDeviceKeys(crypto) { + var userId = crypto._userId; + var deviceId = crypto._deviceId; + + var deviceKeys = { + algorithms: crypto._cryptoAlgorithms, + device_id: deviceId, + keys: crypto._deviceKeys, + user_id: userId, + }; + + var sig = crypto._olmDevice.sign(anotherjson.stringify(deviceKeys)); + deviceKeys.signatures = {}; + deviceKeys.signatures[userId] = {}; + deviceKeys.signatures[userId]["ed25519:" + deviceId] = sig; + + return crypto._baseApis.uploadKeysRequest({ + device_keys: deviceKeys, + }, { + // for now, we set the device id explicitly, as we may not be using the + // same one as used in login. + device_id: deviceId, + }); +} + +// returns a promise which resolves to the response +function _uploadOneTimeKeys(crypto) { + var oneTimeKeys = crypto._olmDevice.getOneTimeKeys(); + var oneTimeJson = {}; + + for (var keyId in oneTimeKeys.curve25519) { + if (oneTimeKeys.curve25519.hasOwnProperty(keyId)) { + oneTimeJson["curve25519:" + keyId] = oneTimeKeys.curve25519[keyId]; + } + } + return crypto._baseApis.uploadKeysRequest({ + one_time_keys: oneTimeJson + }, { + // for now, we set the device id explicitly, as we may not be using the + // same one as used in login. + device_id: crypto._deviceId, + }).then(function(res) { + crypto._olmDevice.markKeysAsPublished(); + return res; + }); +} + +/** + * Download the keys for a list of users and stores the keys in the session + * store. + * @param {Array} userIds The users to fetch. + * @param {bool} forceDownload Always download the keys even if cached. + * + * @return {Promise} A promise which resolves to a map userId->deviceId->{@link + * module:crypto~DeviceInfo|DeviceInfo}. + */ +Crypto.prototype.downloadKeys = function(userIds, forceDownload) { + var self = this; + var stored = {}; + var downloadUsers = []; + + for (var i = 0; i < userIds.length; ++i) { + var userId = userIds[i]; + var devices = this._sessionStore.getEndToEndDevicesForUser(userId); + + stored[userId] = devices || {}; + if (devices && !forceDownload) { + continue; + } + downloadUsers.push(userId); + } + + if (downloadUsers.length === 0) { + return q(stored); + } + + return this._baseApis.downloadKeysForUsers( + downloadUsers + ).then(function(res) { + for (var userId in res.device_keys) { + if (!stored.hasOwnProperty(userId)) { + // spurious result + continue; + } + + var userStore = stored[userId]; + var updated = _updateStoredDeviceKeysForUser( + self._olmDevice, userId, userStore, res.device_keys[userId] + ); + + if (updated) { + self._sessionStore.storeEndToEndDevicesForUser( + userId, userStore + ); + } + } + return stored; + }); +}; + +function _updateStoredDeviceKeysForUser(_olmDevice, userId, userStore, + userResult) { + var updated = false; + + // remove any devices in the store which aren't in the response + for (var deviceId in userStore) { + if (!userStore.hasOwnProperty(deviceId)) { + continue; + } + + if (!(deviceId in userResult)) { + console.log("Device " + userId + ":" + deviceId + + " has been removed"); + delete userStore[deviceId]; + updated = true; + } + } + + for (deviceId in userResult) { + if (!userResult.hasOwnProperty(deviceId)) { + continue; + } + + if (_storeDeviceKeys( + _olmDevice, userId, deviceId, userStore, userResult[deviceId] + )) { + updated = true; + } + } + + return updated; +} + +/* + * Process a device in a /query response, and add it to the userStore + * + * returns true if a change was made, else false + */ +function _storeDeviceKeys(_olmDevice, userId, deviceId, userStore, deviceResult) { + if (!deviceResult.keys) { + // no keys? + return false; + } + + var signKeyId = "ed25519:" + deviceId; + var signKey = deviceResult.keys[signKeyId]; + if (!signKey) { + console.log("Device " + userId + ":" + deviceId + + " has no ed25519 key"); + return false; + } + + var unsigned = deviceResult.unsigned; + var signatures = deviceResult.signatures || {}; + var userSigs = signatures[userId] || {}; + var signature = userSigs[signKeyId]; + if (!signature) { + console.log("Device " + userId + ":" + deviceId + + " is not signed"); + return false; + } + + // prepare the canonical json: remove 'unsigned' and sigxsnatures, and + // stringify with anotherjson + delete deviceResult.unsigned; + delete deviceResult.signatures; + var json = anotherjson.stringify(deviceResult); + + console.log("msg:", json); + try { + _olmDevice.verifySignature(signKey, json, signature); + } catch (e) { + console.log("Unable to verify signature on device " + + userId + ":" + deviceId + ":", e); + return false; + } + + var deviceStore; + if (deviceId in userStore) { + // already have this device. + deviceStore = userStore[deviceId]; + + if (deviceStore.keys["ed25519:" + deviceId] != signKey) { + // this should only happen if the list has been MITMed; we are + // best off sticking with the original keys. + // + // Should we warn the user about it somehow? + console.warn("Ed25519 key for device" + userId + ": " + + deviceId + " has changed"); + return false; + } + } else { + userStore[deviceId] = deviceStore = { + verified: DeviceVerification.UNVERIFIED + }; + } + + deviceStore.keys = deviceResult.keys; + deviceStore.algorithms = deviceResult.algorithms; + deviceStore.unsigned = unsigned; + return true; +} + + +/** + * List the stored device keys for a user id + * + * @param {string} userId the user to list keys for. + * + * @return {object[]} list of devices with "id", "verified", "blocked", + * "key", and "display_name" parameters. + */ +Crypto.prototype.listDeviceKeys = function(userId) { + var devices = this._sessionStore.getEndToEndDevicesForUser(userId); + var result = []; + if (devices) { + var deviceId; + var deviceIds = []; + for (deviceId in devices) { + if (devices.hasOwnProperty(deviceId)) { + deviceIds.push(deviceId); + } + } + deviceIds.sort(); + for (var i = 0; i < deviceIds.length; ++i) { + deviceId = deviceIds[i]; + var device = devices[deviceId]; + var ed25519Key = device.keys["ed25519:" + deviceId]; + var unsigned = device.unsigned || {}; + if (ed25519Key) { + result.push({ + id: deviceId, + key: ed25519Key, + verified: Boolean(device.verified == DeviceVerification.VERIFIED), + blocked: Boolean(device.verified == DeviceVerification.BLOCKED), + display_name: unsigned.device_display_name, + }); + } + } + } + return result; +}; + +/** + * Find a device by curve25519 identity key + * + * @param {string} userId owner of the device + * @param {string} algorithm encryption algorithm + * @param {string} sender_key curve25519 key to match + * + * @return {module:crypto~DeviceInfo?} + */ +Crypto.prototype.getDeviceByIdentityKey = function(userId, algorithm, sender_key) { + if (algorithm !== OLM_ALGORITHM) { + // we only deal in olm keys + return null; + } + + var devices = this._sessionStore.getEndToEndDevicesForUser(userId); + if (!devices) { + return null; + } + + for (var deviceId in devices) { + if (!devices.hasOwnProperty(deviceId)) { + continue; + } + + var device = devices[deviceId]; + for (var keyId in device.keys) { + if (!device.keys.hasOwnProperty(keyId)) { + continue; + } + if (keyId.indexOf("curve25519:") !== 0) { + continue; + } + var deviceKey = device.keys[keyId]; + if (deviceKey == sender_key) { + return device; + } + } + } + + // doesn't match a known device + return null; +}; + + +/** + * Update the blocked/verified state of the given device + * + * @param {string} userId owner of the device + * @param {string} deviceId unique identifier for the device + * + * @param {?boolean} verified whether to mark the device as verified. Null to + * leave unchanged. + * + * @param {?boolean} blocked whether to mark the device as blocked. Null to + * leave unchanged. + */ +Crypto.prototype.setDeviceVerification = function(userId, deviceId, verified, blocked) { + var devices = this._sessionStore.getEndToEndDevicesForUser(userId); + if (!devices || !devices[deviceId]) { + throw new Error("Unknown device " + userId + ":" + deviceId); + } + + var dev = devices[deviceId]; + var verificationStatus = dev.verified; + + if (verified) { + verificationStatus = DeviceVerification.VERIFIED; + } else if (verified !== null && verificationStatus == DeviceVerification.VERIFIED) { + verificationStatus = DeviceVerification.UNVERIFIED; + } + + if (blocked) { + verificationStatus = DeviceVerification.BLOCKED; + } else if (blocked !== null && verificationStatus == DeviceVerification.BLOCKED) { + verificationStatus = DeviceVerification.UNVERIFIED; + } + + if (dev.verified === verificationStatus) { + return; + } + dev.verified = verificationStatus; + this._sessionStore.storeEndToEndDevicesForUser(userId, devices); +}; + + +/** + * Identify a device by curve25519 identity key and determine its verification state + * + * @param {string} userId owner of the device + * @param {string} algorithm encryption algorithm + * @param {string} sender_key curve25519 key to match + * + * @return {boolean} true if the device is verified + */ +Crypto.prototype.isSenderKeyVerified = function(userId, algorithm, sender_key) { + var device = this.getDeviceByIdentityKey(userId, algorithm, sender_key); + if (!device) { + return false; + } + return device.verified == DeviceVerification.VERIFIED; +}; + + +/** + * Configure a room to use encryption (ie, save a flag in the sessionstore). + * + * @param {string} roomId The room ID to enable encryption in. + * @param {object} config The encryption config for the room. + * @param {string[]} roomMembers userIds of room members to start sessions with + * + * @return {Object} A promise that will resolve when encryption is setup. + */ +Crypto.prototype.setRoomEncryption = function(roomId, config, roomMembers) { + var self = this; + + // if we already have encryption in this room, we should ignore this event + // (for now at least. maybe we should alert the user somehow?) + var existingConfig = this._sessionStore.getEndToEndRoom(roomId); + if (existingConfig) { + if (JSON.stringify(existingConfig) != JSON.stringify(config)) { + console.error("Ignoring m.room.encryption event which requests " + + "a change of config in " + roomId); + return; + } + } + + if (config.algorithm !== OLM_ALGORITHM) { + throw new Error("Unknown algorithm: " + config.algorithm); + } + + // remove spurious keys + config = { + algorithm: OLM_ALGORITHM, + }; + this._sessionStore.storeEndToEndRoom(roomId, config); + + return self.downloadKeys(roomMembers, true).then(function(res) { + return self._ensureOlmSessionsForUsers(roomMembers); + }); +}; + +/** + * Try to make sure we have established olm sessions for the given users. + * + * @param {string[]} users list of user ids + * + * @return {module:client.Promise} resolves once the sessions are complete, to + * an object with keys missingUsers (a list of users with no known + * olm devices), and missingDevices a list of olm devices with no + * known one-time keys. + * + * @private + */ +Crypto.prototype._ensureOlmSessionsForUsers = function(users) { + var devicesWithoutSession = []; + var userWithoutDevices = []; + for (var i = 0; i < users.length; ++i) { + var userId = users[i]; + var devices = this._sessionStore.getEndToEndDevicesForUser(userId); + if (!devices) { + userWithoutDevices.push(userId); + } else { + for (var deviceId in devices) { + if (devices.hasOwnProperty(deviceId)) { + var keys = devices[deviceId]; + var key = keys.keys["curve25519:" + deviceId]; + if (key == this._olmDevice.deviceCurve25519Key) { + continue; + } + if (!this._sessionStore.getEndToEndSessions(key)) { + devicesWithoutSession.push([userId, deviceId, key]); + } + } + } + } + } + + if (devicesWithoutSession.length === 0) { + return q({ + missingUsers: userWithoutDevices, + missingDevices: [] + }); + } + + var self = this; + return this._baseApis.claimOneTimeKeys( + devicesWithoutSession + ).then(function(res) { + var missing = {}; + for (i = 0; i < devicesWithoutSession.length; ++i) { + var device = devicesWithoutSession[i]; + var userRes = res.one_time_keys[device[0]] || {}; + var deviceRes = userRes[device[1]]; + var oneTimeKey; + for (var keyId in deviceRes) { + if (keyId.indexOf("curve25519:") === 0) { + oneTimeKey = deviceRes[keyId]; + } + } + if (oneTimeKey) { + var sid = self._olmDevice.createOutboundSession( + device[2], oneTimeKey + ); + console.log("Started new sessionid " + sid + + " for device " + device[2]); + } else { + missing[device[0]] = missing[device[0]] || []; + missing[device[0]].push([device[1]]); + } + } + + return { + missingUsers: userWithoutDevices, + missingDevices: missing + }; + }); +}; + +/** + * Whether encryption is enabled for a room. + * @param {string} roomId the room id to query. + * @return {bool} whether encryption is enabled. + */ +Crypto.prototype.isRoomEncrypted = function(roomId) { + return (this._sessionStore.getEndToEndRoom(roomId) && true) || false; +}; + + +/** + * Encrypt an event according to the configuration of the room, if necessary. + * + * @param {module:models/event.MatrixEvent} event event to be sent + * @param {module:models/room.Room} room destination room + */ +Crypto.prototype.encryptEventIfNeeded = function(event, room) { + if (event.isEncrypted()) { + // this event has already been encrypted; this happens if the + // encryption step succeeded, but the send step failed on the first + // attempt. + return; + } + + if (event.getType() !== "m.room.message") { + // we only encrypt m.room.message + return; + } + + var roomId = event.getRoomId(); + + var e2eRoomInfo = this._sessionStore.getEndToEndRoom(roomId); + if (!e2eRoomInfo || !e2eRoomInfo.algorithm) { + // not encrypting messages in this room + return; + } + + var encryptedContent = this._encryptMessage( + room, e2eRoomInfo, event.getType(), event.getContent() + ); + event.makeEncrypted("m.room.encrypted", encryptedContent); +}; + +/** + * + * @param {module:models/room.Room} room + * @param {object} e2eRoomInfo + * @param {string} eventType + * @param {object} content + * + * @return {object} new event body + * + * @private + */ +Crypto.prototype._encryptMessage = function(room, e2eRoomInfo, eventType, content) { + if (e2eRoomInfo.algorithm !== OLM_ALGORITHM) { + throw new Error("Unknown end-to-end algorithm: " + e2eRoomInfo.algorithm); + } + + if (!room) { + throw new Error("Cannot send encrypted messages in unknown rooms"); + } + + // pick the list of recipients based on the membership list. + // + // TODO: there is a race condition here! What if a new user turns up + // just as you are sending a secret message? + + var users = utils.map(room.getJoinedMembers(), function(u) { + return u.userId; + }); + + var participantKeys = []; + for (var i = 0; i < users.length; ++i) { + var userId = users[i]; + var devices = this._sessionStore.getEndToEndDevicesForUser(userId); + for (var deviceId in devices) { + if (devices.hasOwnProperty(deviceId)) { + var dev = devices[deviceId]; + if (dev.verified === DeviceVerification.BLOCKED) { + continue; + } + + for (var keyId in dev.keys) { + if (keyId.indexOf("curve25519:") === 0) { + participantKeys.push(dev.keys[keyId]); + } + } + } + } + } + participantKeys.sort(); + var participantHash = ""; // Olm.sha256(participantKeys.join()); + var payloadJson = { + room_id: room.roomId, + type: eventType, + fingerprint: participantHash, + sender_device: this._deviceId, + content: content + }; + var ciphertext = {}; + var payloadString = JSON.stringify(payloadJson); + for (i = 0; i < participantKeys.length; ++i) { + var deviceKey = participantKeys[i]; + if (deviceKey == this._olmDevice.deviceCurve25519Key) { + continue; + } + var sessionIds = this._olmDevice.getSessionIdsForDevice(deviceKey); + // Use the session with the lowest ID. + sessionIds.sort(); + if (sessionIds.length === 0) { + // If we don't have a session for a device then + // we can't encrypt a message for it. + continue; + } + var sessionId = sessionIds[0]; + console.log("Using sessionid " + sessionId + " for device " + deviceKey); + ciphertext[deviceKey] = this._olmDevice.encryptMessage( + deviceKey, sessionId, payloadString + ); + } + var encryptedContent = { + algorithm: e2eRoomInfo.algorithm, + sender_key: this._olmDevice.deviceCurve25519Key, + ciphertext: ciphertext + }; + return encryptedContent; +}; + +function DecryptionError(msg) { + this.message = msg; +} +utils.inherits(DecryptionError, Error); + +/** + * Exception thrown when decryption fails + */ +Crypto.DecryptionError = DecryptionError; + +/** + * Decrypt a received event + * + * @param {object} event raw event + * + * @return {object} decrypted payload (with properties 'type', 'content') + * + * @raises {DecryptionError} if there is a problem decrypting the event + */ +Crypto.prototype.decryptEvent = function(event) { + var content = event.content; + if (content.algorithm !== OLM_ALGORITHM) { + throw new DecryptionError("Unknown algorithm"); + } + + var deviceKey = content.sender_key; + var ciphertext = content.ciphertext; + + if (!ciphertext) { + throw new DecryptionError("Missing ciphertext"); + } + + if (!(this._olmDevice.deviceCurve25519Key in content.ciphertext)) { + throw new DecryptionError("Not included in recipients"); + } + + var message = content.ciphertext[this._olmDevice.deviceCurve25519Key]; + var sessionIds = this._olmDevice.getSessionIdsForDevice(deviceKey); + var payloadString = null; + var foundSession = false; + for (var i = 0; i < sessionIds.length; i++) { + var sessionId = sessionIds[i]; + var res = this._olmDevice.decryptMessage( + deviceKey, sessionId, message.type, message.body + ); + payloadString = res.payload; + if (payloadString) { + console.log("decrypted with sessionId " + sessionId); + break; + } + + if (res.matchesInbound) { + // this was a prekey message which matched this session; don't + // create a new session. + foundSession = true; + break; + } + } + + if (message.type === 0 && !foundSession && payloadString === null) { + try { + payloadString = this._olmDevice.createInboundSession( + deviceKey, message.type, message.body + ); + console.log("created new inbound sesion"); + } catch (e) { + // Failed to decrypt with a new session. + } + } + + // TODO: Check the sender user id matches the sender key. + if (payloadString !== null) { + return JSON.parse(payloadString); + } else { + throw new DecryptionError("Bad Encrypted Message"); + } +}; + +/** */ +module.exports = Crypto; + +},{"./OlmDevice":2,"./utils":28,"another-json":30,"q":205}],7:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * @module filter + */ + +/** + * @param {Object} obj + * @param {string} keyNesting + * @param {*} val + */ +function setProp(obj, keyNesting, val) { + var nestedKeys = keyNesting.split("."); + var currentObj = obj; + for (var i = 0; i < (nestedKeys.length - 1); i++) { + if (!currentObj[nestedKeys[i]]) { + currentObj[nestedKeys[i]] = {}; + } + currentObj = currentObj[nestedKeys[i]]; + } + currentObj[nestedKeys[nestedKeys.length - 1]] = val; +} + +/** + * Construct a new Filter. + * @constructor + * @param {string} userId The user ID for this filter. + * @param {string=} filterId The filter ID if known. + * @prop {string} userId The user ID of the filter + * @prop {?string} filterId The filter ID + */ +function Filter(userId, filterId) { + this.userId = userId; + this.filterId = filterId; + this.definition = {}; +} + +/** + * Get the JSON body of the filter. + * @return {Object} The filter definition + */ +Filter.prototype.getDefinition = function() { + return this.definition; +}; + +/** + * Set the JSON body of the filter + * @param {Object} definition The filter definition + */ +Filter.prototype.setDefinition = function(definition) { + this.definition = definition; +}; + +/** + * Set the max number of events to return for each room's timeline. + * @param {Number} limit The max number of events to return for each room. + */ +Filter.prototype.setTimelineLimit = function(limit) { + setProp(this.definition, "room.timeline.limit", limit); +}; + +/** + * Control whether left rooms should be included in responses. + * @param {boolean} includeLeave True to make rooms the user has left appear + * in responses. + */ +Filter.prototype.setIncludeLeaveRooms = function(includeLeave) { + setProp(this.definition, "room.include_leave", includeLeave); +}; + +/** + * Create a filter from existing data. + * @static + * @param {string} userId + * @param {string} filterId + * @param {Object} jsonObj + * @return {Filter} + */ +Filter.fromJson = function(userId, filterId, jsonObj) { + var filter = new Filter(userId, filterId); + filter.setDefinition(jsonObj); + return filter; +}; + +/** The Filter class */ +module.exports = Filter; + +},{}],8:[function(require,module,exports){ +(function (global){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * This is an internal module. See {@link MatrixHttpApi} for the public class. + * @module http-api + */ +var q = require("q"); +var utils = require("./utils"); + +// we use our own implementation of setTimeout, so that if we get suspended in +// the middle of a /sync, we cancel the sync as soon as we awake, rather than +// waiting for the delay to elapse. +var callbacks = require("./realtime-callbacks"); + +/* +TODO: +- CS: complete register function (doing stages) +- Identity server: linkEmail, authEmail, bindEmail, lookup3pid +*/ + +/** + * A constant representing the URI path for release 0 of the Client-Server HTTP API. + */ +module.exports.PREFIX_R0 = "/_matrix/client/r0"; + +/** + * A constant representing the URI path for as-yet unspecified Client-Server HTTP APIs. + */ +module.exports.PREFIX_UNSTABLE = "/_matrix/client/unstable"; + +/** + * URI path for the identity API + */ +module.exports.PREFIX_IDENTITY_V1 = "/_matrix/identity/api/v1"; + +/** + * URI path for the media repo API + */ +module.exports.PREFIX_MEDIA_R0 = "/_matrix/media/r0"; + +/** + * Construct a MatrixHttpApi. + * @constructor + * @param {EventEmitter} event_emitter The event emitter to use for emitting events + * @param {Object} opts The options to use for this HTTP API. + * @param {string} opts.baseUrl Required. The base client-server URL e.g. + * 'http://localhost:8008'. + * @param {Function} opts.request Required. The function to call for HTTP + * requests. This function must look like function(opts, callback){ ... }. + * @param {string} opts.prefix Required. The matrix client prefix to use, e.g. + * '/_matrix/client/r0'. See PREFIX_R0 and PREFIX_UNSTABLE for constants. + * @param {bool} opts.onlyData True to return only the 'data' component of the + * response (e.g. the parsed HTTP body). If false, requests will return status + * codes and headers in addition to data. Default: false. + * @param {string} opts.accessToken The access_token to send with requests. Can be + * null to not send an access token. + * @param {Object} opts.extraParams Optional. Extra query parameters to send on + * requests. + */ +module.exports.MatrixHttpApi = function MatrixHttpApi(event_emitter, opts) { + utils.checkObjectHasKeys(opts, ["baseUrl", "request", "prefix"]); + opts.onlyData = opts.onlyData || false; + this.event_emitter = event_emitter; + this.opts = opts; + this.uploads = []; +}; + +module.exports.MatrixHttpApi.prototype = { + + /** + * Get the content repository url with query parameters. + * @return {Object} An object with a 'base', 'path' and 'params' for base URL, + * path and query parameters respectively. + */ + getContentUri: function() { + var params = { + access_token: this.opts.accessToken + }; + return { + base: this.opts.baseUrl, + path: "/_matrix/media/v1/upload", + params: params + }; + }, + + /** + * Upload content to the Home Server + * @param {File} file A File object (in a browser) or in Node, + an object with properties: + name: The file's name + stream: A read stream + * @param {Function} callback Optional. The callback to invoke on + * success/failure. See the promise return values for more information. + * @return {module:client.Promise} Resolves to {data: {Object}, + */ + uploadContent: function(file, callback) { + if (callback !== undefined && !utils.isFunction(callback)) { + throw Error( + "Expected callback to be a function but got " + typeof callback + ); + } + var defer = q.defer(); + var url = this.opts.baseUrl + "/_matrix/media/v1/upload"; + // browser-request doesn't support File objects because it deep-copies + // the options using JSON.parse(JSON.stringify(options)). Instead of + // loading the whole file into memory as a string and letting + // browser-request base64 encode and then decode it again, we just + // use XMLHttpRequest directly. + // (browser-request doesn't support progress either, which is also kind + // of important here) + + var upload = { loaded: 0, total: 0 }; + + if (global.XMLHttpRequest) { + var xhr = new global.XMLHttpRequest(); + upload.xhr = xhr; + var cb = requestCallback(defer, callback, this.opts.onlyData); + + var timeout_fn = function() { + xhr.abort(); + cb(new Error('Timeout')); + }; + + xhr.timeout_timer = callbacks.setTimeout(timeout_fn, 30000); + + xhr.onreadystatechange = function() { + switch (xhr.readyState) { + case global.XMLHttpRequest.DONE: + callbacks.clearTimeout(xhr.timeout_timer); + var err; + if (!xhr.responseText) { + err = new Error('No response body.'); + err.http_status = xhr.status; + cb(err); + return; + } + + var resp = JSON.parse(xhr.responseText); + if (resp.content_uri === undefined) { + err = Error('Bad response'); + err.http_status = xhr.status; + cb(err); + return; + } + + cb(undefined, xhr, resp.content_uri); + break; + } + }; + xhr.upload.addEventListener("progress", function(ev) { + callbacks.clearTimeout(xhr.timeout_timer); + upload.loaded = ev.loaded; + upload.total = ev.total; + xhr.timeout_timer = callbacks.setTimeout(timeout_fn, 30000); + defer.notify(ev); + }); + url += "?access_token=" + encodeURIComponent(this.opts.accessToken); + url += "&filename=" + encodeURIComponent(file.name); + + xhr.open("POST", url); + if (file.type) { + xhr.setRequestHeader("Content-Type", file.type); + } else { + // if the file doesn't have a mime type, use a default since + // the HS errors if we don't supply one. + xhr.setRequestHeader("Content-Type", 'application/octet-stream'); + } + xhr.send(file); + } else { + var queryParams = { + filename: file.name, + access_token: this.opts.accessToken + }; + upload.request = this.opts.request({ + uri: url, + qs: queryParams, + method: "POST", + headers: {"Content-Type": file.type}, + body: file.stream + }, requestCallback(defer, callback, this.opts.onlyData)); + } + + this.uploads.push(upload); + + var self = this; + upload.promise = defer.promise.finally(function() { + var uploadsKeys = Object.keys(self.uploads); + for (var i = 0; i < uploadsKeys.length; ++i) { + if (self.uploads[uploadsKeys[i]].promise === defer.promise) { + self.uploads.splice(uploadsKeys[i], 1); + } + } + }); + return upload.promise; + }, + + cancelUpload: function(promise) { + var uploadsKeys = Object.keys(this.uploads); + for (var i = 0; i < uploadsKeys.length; ++i) { + var upload = this.uploads[uploadsKeys[i]]; + if (upload.promise === promise) { + if (upload.xhr !== undefined) { + upload.xhr.abort(); + return true; + } else if (upload.request !== undefined) { + upload.request.abort(); + return true; + } + } + } + return false; + }, + + getCurrentUploads: function() { + return this.uploads; + }, + + idServerRequest: function(callback, method, path, params, prefix) { + var fullUri = this.opts.idBaseUrl + prefix + path; + + if (callback !== undefined && !utils.isFunction(callback)) { + throw Error( + "Expected callback to be a function but got " + typeof callback + ); + } + + var opts = { + uri: fullUri, + method: method, + withCredentials: false, + json: false, + _matrix_opts: this.opts + }; + if (method == 'GET') { + opts.qs = params; + } else { + opts.form = params; + } + + var defer = q.defer(); + this.opts.request( + opts, + requestCallback(defer, callback, this.opts.onlyData) + ); + // ID server does not always take JSON, so we can't use requests' 'json' + // option as we do with the home server, but it does return JSON, so + // parse it manually + return defer.promise.then(function(response) { + return JSON.parse(response); + }); + }, + + /** + * Perform an authorised request to the homeserver. + * @param {Function} callback Optional. The callback to invoke on + * success/failure. See the promise return values for more information. + * @param {string} method The HTTP method e.g. "GET". + * @param {string} path The HTTP path after the supplied prefix e.g. + * "/createRoom". + * @param {Object} queryParams A dict of query params (these will NOT be + * urlencoded). + * @param {Object} data The HTTP JSON body. + * @param {Number=} localTimeoutMs The maximum amount of time to wait before + * timing out the request. If not specified, there is no timeout. + * @return {module:client.Promise} Resolves to {data: {Object}, + * headers: {Object}, code: {Number}}. + * If onlyData is set, this will resolve to the data + * object only. + * @return {module:http-api.MatrixError} Rejects with an error if a problem + * occurred. This includes network problems and Matrix-specific error JSON. + */ + authedRequest: function(callback, method, path, queryParams, data, localTimeoutMs) { + if (!queryParams) { queryParams = {}; } + queryParams.access_token = this.opts.accessToken; + var self = this; + var request_promise = this.request( + callback, method, path, queryParams, data, localTimeoutMs + ); + request_promise.catch(function(err) { + if (err.errcode == 'M_UNKNOWN_TOKEN') { + self.event_emitter.emit("Session.logged_out"); + } + }); + // return the original promise, otherwise tests break due to it having to + // go around the event loop one more time to process the result of the request + return request_promise; + }, + + /** + * Perform a request to the homeserver without any credentials. + * @param {Function} callback Optional. The callback to invoke on + * success/failure. See the promise return values for more information. + * @param {string} method The HTTP method e.g. "GET". + * @param {string} path The HTTP path after the supplied prefix e.g. + * "/createRoom". + * @param {Object} queryParams A dict of query params (these will NOT be + * urlencoded). + * @param {Object} data The HTTP JSON body. + * @param {Number=} localTimeoutMs The maximum amount of time to wait before + * timing out the request. If not specified, there is no timeout. + * @return {module:client.Promise} Resolves to {data: {Object}, + * headers: {Object}, code: {Number}}. + * If onlyData is set, this will resolve to the data + * object only. + * @return {module:http-api.MatrixError} Rejects with an error if a problem + * occurred. This includes network problems and Matrix-specific error JSON. + */ + request: function(callback, method, path, queryParams, data, localTimeoutMs) { + return this.requestWithPrefix( + callback, method, path, queryParams, data, this.opts.prefix, localTimeoutMs + ); + }, + + /** + * Perform an authorised request to the homeserver with a specific path + * prefix which overrides the default for this call only. Useful for hitting + * different Matrix Client-Server versions. + * @param {Function} callback Optional. The callback to invoke on + * success/failure. See the promise return values for more information. + * @param {string} method The HTTP method e.g. "GET". + * @param {string} path The HTTP path after the supplied prefix e.g. + * "/createRoom". + * @param {Object} queryParams A dict of query params (these will NOT be + * urlencoded). + * @param {Object} data The HTTP JSON body. + * @param {string} prefix The full prefix to use e.g. + * "/_matrix/client/v2_alpha". + * @param {Number=} localTimeoutMs The maximum amount of time to wait before + * timing out the request. If not specified, there is no timeout. + * @return {module:client.Promise} Resolves to {data: {Object}, + * headers: {Object}, code: {Number}}. + * If onlyData is set, this will resolve to the data + * object only. + * @return {module:http-api.MatrixError} Rejects with an error if a problem + * occurred. This includes network problems and Matrix-specific error JSON. + */ + authedRequestWithPrefix: function(callback, method, path, queryParams, data, + prefix, localTimeoutMs) { + var fullUri = this.opts.baseUrl + prefix + path; + if (!queryParams) { + queryParams = {}; + } + queryParams.access_token = this.opts.accessToken; + return this._request( + callback, method, fullUri, queryParams, data, localTimeoutMs + ); + }, + + /** + * Perform a request to the homeserver without any credentials but with a + * specific path prefix which overrides the default for this call only. + * Useful for hitting different Matrix Client-Server versions. + * @param {Function} callback Optional. The callback to invoke on + * success/failure. See the promise return values for more information. + * @param {string} method The HTTP method e.g. "GET". + * @param {string} path The HTTP path after the supplied prefix e.g. + * "/createRoom". + * @param {Object} queryParams A dict of query params (these will NOT be + * urlencoded). + * @param {Object} data The HTTP JSON body. + * @param {string} prefix The full prefix to use e.g. + * "/_matrix/client/v2_alpha". + * @param {Number=} localTimeoutMs The maximum amount of time to wait before + * timing out the request. If not specified, there is no timeout. + * @return {module:client.Promise} Resolves to {data: {Object}, + * headers: {Object}, code: {Number}}. + * If onlyData is set, this will resolve to the data + * object only. + * @return {module:http-api.MatrixError} Rejects with an error if a problem + * occurred. This includes network problems and Matrix-specific error JSON. + */ + requestWithPrefix: function(callback, method, path, queryParams, data, prefix, + localTimeoutMs) { + var fullUri = this.opts.baseUrl + prefix + path; + if (!queryParams) { + queryParams = {}; + } + return this._request( + callback, method, fullUri, queryParams, data, localTimeoutMs + ); + }, + + /** + * Perform a request to an arbitrary URL. + * @param {Function} callback Optional. The callback to invoke on + * success/failure. See the promise return values for more information. + * @param {string} method The HTTP method e.g. "GET". + * @param {string} uri The HTTP URI + * @param {Object} queryParams A dict of query params (these will NOT be + * urlencoded). + * @param {Object} data The HTTP JSON body. + * @param {Number=} localTimeoutMs The maximum amount of time to wait before + * timing out the request. If not specified, there is no timeout. + * @return {module:client.Promise} Resolves to {data: {Object}, + * headers: {Object}, code: {Number}}. + * If onlyData is set, this will resolve to the data + * object only. + * @return {module:http-api.MatrixError} Rejects with an error if a problem + * occurred. This includes network problems and Matrix-specific error JSON. + */ + requestOtherUrl: function(callback, method, uri, queryParams, data, + localTimeoutMs) { + if (!queryParams) { + queryParams = {}; + } + return this._request( + callback, method, uri, queryParams, data, localTimeoutMs + ); + }, + + /** + * Form and return a homeserver request URL based on the given path + * params and prefix. + * @param {string} path The HTTP path after the supplied prefix e.g. + * "/createRoom". + * @param {Object} queryParams A dict of query params (these will NOT be + * urlencoded). + * @param {string} prefix The full prefix to use e.g. + * "/_matrix/client/v2_alpha". + * @return {string} URL + */ + getUrl: function(path, queryParams, prefix) { + var queryString = ""; + if (queryParams) { + queryString = "?" + utils.encodeParams(queryParams); + } + return this.opts.baseUrl + prefix + path + queryString; + }, + + _request: function(callback, method, uri, queryParams, data, localTimeoutMs) { + if (callback !== undefined && !utils.isFunction(callback)) { + throw Error( + "Expected callback to be a function but got " + typeof callback + ); + } + var self = this; + if (!queryParams) { + queryParams = {}; + } + if (this.opts.extraParams) { + for (var key in this.opts.extraParams) { + if (!this.opts.extraParams.hasOwnProperty(key)) { continue; } + queryParams[key] = this.opts.extraParams[key]; + } + } + var defer = q.defer(); + + var timeoutId; + var timedOut = false; + var req; + if (localTimeoutMs) { + timeoutId = callbacks.setTimeout(function() { + timedOut = true; + if (req && req.abort) { + req.abort(); + } + defer.reject(new module.exports.MatrixError({ + error: "Locally timed out waiting for a response", + errcode: "ORG.MATRIX.JSSDK_TIMEOUT", + timeout: localTimeoutMs + })); + }, localTimeoutMs); + } + + var reqPromise = defer.promise; + + try { + req = this.opts.request( + { + uri: uri, + method: method, + withCredentials: false, + qs: queryParams, + body: data, + json: true, + timeout: localTimeoutMs, + _matrix_opts: this.opts + }, + function(err, response, body) { + if (localTimeoutMs) { + callbacks.clearTimeout(timeoutId); + if (timedOut) { + return; // already rejected promise + } + } + var handlerFn = requestCallback(defer, callback, self.opts.onlyData); + handlerFn(err, response, body); + } + ); + if (req && req.abort) { + // FIXME: This is EVIL, but I can't think of a better way to expose + // abort() operations on underlying HTTP requests :( + reqPromise.abort = req.abort.bind(req); + } + } + catch (ex) { + defer.reject(ex); + if (callback) { + callback(ex); + } + } + return reqPromise; + } +}; + +/* + * Returns a callback that can be invoked by an HTTP request on completion, + * that will either resolve or reject the given defer as well as invoke the + * given userDefinedCallback (if any). + * + * If onlyData is true, the defer/callback is invoked with the body of the + * response, otherwise the result code. + */ +var requestCallback = function(defer, userDefinedCallback, onlyData) { + userDefinedCallback = userDefinedCallback || function() {}; + + return function(err, response, body) { + if (!err && response.statusCode >= 400) { + err = new module.exports.MatrixError(body); + err.httpStatus = response.statusCode; + } + + if (err) { + defer.reject(err); + userDefinedCallback(err); + } + else { + var res = { + code: response.statusCode, + headers: response.headers, + data: body + }; + defer.resolve(onlyData ? body : res); + userDefinedCallback(null, onlyData ? body : res); + } + }; +}; + +/** + * Construct a Matrix error. This is a JavaScript Error with additional + * information specific to the standard Matrix error response. + * @constructor + * @param {Object} errorJson The Matrix error JSON returned from the homeserver. + * @prop {string} errcode The Matrix 'errcode' value, e.g. "M_FORBIDDEN". + * @prop {string} name Same as MatrixError.errcode but with a default unknown string. + * @prop {string} message The Matrix 'error' value, e.g. "Missing token." + * @prop {Object} data The raw Matrix error JSON used to construct this object. + * @prop {integer} httpStatus The numeric HTTP status code given + */ +module.exports.MatrixError = function MatrixError(errorJson) { + errorJson = errorJson || {}; + this.errcode = errorJson.errcode; + this.name = errorJson.errcode || "Unknown error code"; + this.message = errorJson.error || "Unknown message"; + this.data = errorJson; +}; +module.exports.MatrixError.prototype = Object.create(Error.prototype); +/** */ +module.exports.MatrixError.prototype.constructor = module.exports.MatrixError; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./realtime-callbacks":20,"./utils":28,"q":205}],9:[function(require,module,exports){ +(function (global){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/** The {@link module:models/event.MatrixEvent|MatrixEvent} class. */ +module.exports.MatrixEvent = require("./models/event").MatrixEvent; +/** The {@link module:models/event.EventStatus|EventStatus} enum. */ +module.exports.EventStatus = require("./models/event").EventStatus; +/** The {@link module:store/memory.MatrixInMemoryStore|MatrixInMemoryStore} class. */ +module.exports.MatrixInMemoryStore = require("./store/memory").MatrixInMemoryStore; +/** The {@link module:store/webstorage~WebStorageStore|WebStorageStore} class. + * Work in progress; unstable. */ +module.exports.WebStorageStore = require("./store/webstorage"); +/** The {@link module:http-api.MatrixHttpApi|MatrixHttpApi} class. */ +module.exports.MatrixHttpApi = require("./http-api").MatrixHttpApi; +/** The {@link module:http-api.MatrixError|MatrixError} class. */ +module.exports.MatrixError = require("./http-api").MatrixError; +/** The {@link module:client.MatrixClient|MatrixClient} class. */ +module.exports.MatrixClient = require("./client").MatrixClient; +/** The {@link module:models/room~Room|Room} class. */ +module.exports.Room = require("./models/room"); +/** The {@link module:models/event-timeline~EventTimeline} class. */ +module.exports.EventTimeline = require("./models/event-timeline"); +/** The {@link module:models/room-member~RoomMember|RoomMember} class. */ +module.exports.RoomMember = require("./models/room-member"); +/** The {@link module:models/room-state~RoomState|RoomState} class. */ +module.exports.RoomState = require("./models/room-state"); +/** The {@link module:models/user~User|User} class. */ +module.exports.User = require("./models/user"); +/** The {@link module:scheduler~MatrixScheduler|MatrixScheduler} class. */ +module.exports.MatrixScheduler = require("./scheduler"); +/** The {@link module:store/session/webstorage~WebStorageSessionStore| + * WebStorageSessionStore} class. Work in progress; unstable. */ +module.exports.WebStorageSessionStore = require("./store/session/webstorage"); +/** True if crypto libraries are being used on this client. */ +module.exports.CRYPTO_ENABLED = require("./client").CRYPTO_ENABLED; +/** {@link module:content-repo|ContentRepo} utility functions. */ +module.exports.ContentRepo = require("./content-repo"); +/** The {@link module:filter~Filter|Filter} class. */ +module.exports.Filter = require("./filter"); +/** The {@link module:timeline-window~TimelineWindow} class. */ +module.exports.TimelineWindow = require("./timeline-window").TimelineWindow; + +/** + * Create a new Matrix Call. + * @function + * @param {module:client.MatrixClient} client The MatrixClient instance to use. + * @param {string} roomId The room the call is in. + * @return {module:webrtc/call~MatrixCall} The Matrix call or null if the browser + * does not support WebRTC. + */ +module.exports.createNewMatrixCall = require("./webrtc/call").createNewMatrixCall; + +// expose the underlying request object so different environments can use +// different request libs (e.g. request or browser-request) +var request; +/** + * The function used to perform HTTP requests. Only use this if you want to + * use a different HTTP library, e.g. Angular's $http. This should + * be set prior to calling {@link createClient}. + * @param {requestFunction} r The request function to use. + */ +module.exports.request = function(r) { + request = r; +}; + +/** + * Construct a Matrix Client. Similar to {@link module:client~MatrixClient} + * except that the 'request', 'store' and 'scheduler' dependencies are satisfied. + * @param {(Object|string)} opts The configuration options for this client. If + * this is a string, it is assumed to be the base URL. These configuration + * options will be passed directly to {@link module:client~MatrixClient}. + * @param {Object} opts.store If not set, defaults to + * {@link module:store/memory.MatrixInMemoryStore}. + * @param {Object} opts.scheduler If not set, defaults to + * {@link module:scheduler~MatrixScheduler}. + * @param {requestFunction} opts.request If not set, defaults to the function + * supplied to {@link request} which defaults to the request module from NPM. + * @return {MatrixClient} A new matrix client. + * @see {@link module:client~MatrixClient} for the full list of options for + * opts. + */ +module.exports.createClient = function(opts) { + if (typeof opts === "string") { + opts = { + "baseUrl": opts + }; + } + opts.request = opts.request || request; + opts.store = opts.store || new module.exports.MatrixInMemoryStore({ + localStorage: global.localStorage + }); + opts.scheduler = opts.scheduler || new module.exports.MatrixScheduler(); + return new module.exports.MatrixClient(opts); +}; + +/** + * The request function interface for performing HTTP requests. This matches the + * API for the {@link https://github.com/request/request#requestoptions-callback| + * request NPM module}. The SDK will attempt to call this function in order to + * perform an HTTP request. + * @callback requestFunction + * @param {Object} opts The options for this HTTP request. + * @param {string} opts.uri The complete URI. + * @param {string} opts.method The HTTP method. + * @param {Object} opts.qs The query parameters to append to the URI. + * @param {Object} opts.body The JSON-serializable object. + * @param {boolean} opts.json True if this is a JSON request. + * @param {Object} opts._matrix_opts The underlying options set for + * {@link MatrixHttpApi}. + * @param {requestCallback} callback The request callback. + */ + + /** + * The request callback interface for performing HTTP requests. This matches the + * API for the {@link https://github.com/request/request#requestoptions-callback| + * request NPM module}. The SDK will implement a callback which meets this + * interface in order to handle the HTTP response. + * @callback requestCallback + * @param {Error} err The error if one occurred, else falsey. + * @param {Object} response The HTTP response which consists of + * {statusCode: {Number}, headers: {Object}} + * @param {Object} body The parsed HTTP response body. + */ + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./client":4,"./content-repo":5,"./filter":7,"./http-api":8,"./models/event":12,"./models/event-timeline":11,"./models/room":16,"./models/room-member":13,"./models/room-state":14,"./models/user":18,"./scheduler":21,"./store/memory":22,"./store/session/webstorage":23,"./store/webstorage":25,"./timeline-window":27,"./webrtc/call":29}],10:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/** + * @module models/event-context + */ + +/** + * Construct a new EventContext + * + * An eventcontext is used for circumstances such as search results, when we + * have a particular event of interest, and a bunch of events before and after + * it. + * + * It also stores pagination tokens for going backwards and forwards in the + * timeline. + * + * @param {MatrixEvent} ourEvent the event at the centre of this context + * + * @constructor + */ +function EventContext(ourEvent) { + this._timeline = [ourEvent]; + this._ourEventIndex = 0; + this._paginateTokens = {b: null, f: null}; + + // this is used by MatrixClient to keep track of active requests + this._paginateRequests = {b: null, f: null}; +} + +/** + * Get the main event of interest + * + * This is a convenience function for getTimeline()[getOurEventIndex()]. + * + * @return {MatrixEvent} The event at the centre of this context. + */ +EventContext.prototype.getEvent = function() { + return this._timeline[this._ourEventIndex]; +}; + +/** + * Get the list of events in this context + * + * @return {Array} An array of MatrixEvents + */ +EventContext.prototype.getTimeline = function() { + return this._timeline; +}; + +/** + * Get the index in the timeline of our event + * + * @return {Number} + */ +EventContext.prototype.getOurEventIndex = function() { + return this._ourEventIndex; +}; + +/** + * Get a pagination token. + * + * @param {boolean} backwards true to get the pagination token for going + * backwards in time + * @return {string} + */ +EventContext.prototype.getPaginateToken = function(backwards) { + return this._paginateTokens[backwards ? 'b' : 'f']; +}; + +/** + * Set a pagination token. + * + * Generally this will be used only by the matrix js sdk. + * + * @param {string} token pagination token + * @param {boolean} backwards true to set the pagination token for going + * backwards in time + */ +EventContext.prototype.setPaginateToken = function(token, backwards) { + this._paginateTokens[backwards ? 'b' : 'f'] = token; +}; + +/** + * Add more events to the timeline + * + * @param {Array} events new events, in timeline order + * @param {boolean} atStart true to insert new events at the start + */ +EventContext.prototype.addEvents = function(events, atStart) { + // TODO: should we share logic with Room.addEventsToTimeline? + // Should Room even use EventContext? + + if (atStart) { + this._timeline = events.concat(this._timeline); + this._ourEventIndex += events.length; + } else { + this._timeline = this._timeline.concat(events); + } +}; + +/** + * The EventContext class + */ +module.exports = EventContext; + +},{}],11:[function(require,module,exports){ +"use strict"; + +/** + * @module models/event-timeline + */ + +var RoomState = require("./room-state"); +var utils = require("../utils"); +var MatrixEvent = require("./event").MatrixEvent; + +/** + * Construct a new EventTimeline + * + *

An EventTimeline represents a contiguous sequence of events in a room. + * + *

As well as keeping track of the events themselves, it stores the state of + * the room at the beginning and end of the timeline, and pagination tokens for + * going backwards and forwards in the timeline. + * + *

In order that clients can meaningfully maintain an index into a timeline, + * the EventTimeline object tracks a 'baseIndex'. This starts at zero, but is + * incremented when events are prepended to the timeline. The index of an event + * relative to baseIndex therefore remains constant. + * + *

Once a timeline joins up with its neighbour, they are linked together into a + * doubly-linked list. + * + * @param {string} roomId the ID of the room where this timeline came from + * @constructor + */ +function EventTimeline(roomId) { + this._roomId = roomId; + this._events = []; + this._baseIndex = 0; + this._startState = new RoomState(roomId); + this._startState.paginationToken = null; + this._endState = new RoomState(roomId); + this._endState.paginationToken = null; + + this._prevTimeline = null; + this._nextTimeline = null; + + // this is used by client.js + this._paginationRequests = {'b': null, 'f': null}; + + this._name = roomId + ":" + new Date().toISOString(); +} + +/** + * Symbolic constant for methods which take a 'direction' argument: + * refers to the start of the timeline, or backwards in time. + */ +EventTimeline.BACKWARDS = "b"; + +/** + * Symbolic constant for methods which take a 'direction' argument: + * refers to the end of the timeline, or forwards in time. + */ +EventTimeline.FORWARDS = "f"; + +/** + * Initialise the start and end state with the given events + * + *

This can only be called before any events are added. + * + * @param {MatrixEvent[]} stateEvents list of state events to initialise the + * state with. + * @throws {Error} if an attempt is made to call this after addEvent is called. + */ +EventTimeline.prototype.initialiseState = function(stateEvents) { + if (this._events.length > 0) { + throw new Error("Cannot initialise state after events are added"); + } + + // we deep-copy the events here, in case they get changed later - we don't + // want changes to the start state leaking through to the end state. + var oldStateEvents = utils.map( + utils.deepCopy( + stateEvents.map(function(mxEvent) { return mxEvent.event; }) + ), function(ev) { return new MatrixEvent(ev); }); + + this._startState.setStateEvents(oldStateEvents); + this._endState.setStateEvents(stateEvents); +}; + +/** + * Get the ID of the room for this timeline + * @return {string} room ID + */ +EventTimeline.prototype.getRoomId = function() { + return this._roomId; +}; + +/** + * Get the base index. + * + *

This is an index which is incremented when events are prepended to the + * timeline. An individual event therefore stays at the same index in the array + * relative to the base index (although note that a given event's index may + * well be less than the base index, thus giving that event a negative relative + * index). + * + * @return {number} + */ +EventTimeline.prototype.getBaseIndex = function() { + return this._baseIndex; +}; + +/** + * Get the list of events in this context + * + * @return {MatrixEvent[]} An array of MatrixEvents + */ +EventTimeline.prototype.getEvents = function() { + return this._events; +}; + +/** + * Get the room state at the start/end of the timeline + * + * @param {string} direction EventTimeline.BACKWARDS to get the state at the + * start of the timeline; EventTimeline.FORWARDS to get the state at the end + * of the timeline. + * + * @return {RoomState} state at the start/end of the timeline + */ +EventTimeline.prototype.getState = function(direction) { + if (direction == EventTimeline.BACKWARDS) { + return this._startState; + } else if (direction == EventTimeline.FORWARDS) { + return this._endState; + } else { + throw new Error("Invalid direction '" + direction + "'"); + } +}; + +/** + * Get a pagination token + * + * @param {string} direction EventTimeline.BACKWARDS to get the pagination + * token for going backwards in time; EventTimeline.FORWARDS to get the + * pagination token for going forwards in time. + * + * @return {?string} pagination token + */ +EventTimeline.prototype.getPaginationToken = function(direction) { + return this.getState(direction).paginationToken; +}; + +/** + * Set a pagination token + * + * @param {?string} token pagination token + * + * @param {string} direction EventTimeline.BACKWARDS to set the pagination + * token for going backwards in time; EventTimeline.FORWARDS to set the + * pagination token for going forwards in time. + */ +EventTimeline.prototype.setPaginationToken = function(token, direction) { + this.getState(direction).paginationToken = token; +}; + +/** + * Get the next timeline in the series + * + * @param {string} direction EventTimeline.BACKWARDS to get the previous + * timeline; EventTimeline.FORWARDS to get the next timeline. + * + * @return {?EventTimeline} previous or following timeline, if they have been + * joined up. + */ +EventTimeline.prototype.getNeighbouringTimeline = function(direction) { + if (direction == EventTimeline.BACKWARDS) { + return this._prevTimeline; + } else if (direction == EventTimeline.FORWARDS) { + return this._nextTimeline; + } else { + throw new Error("Invalid direction '" + direction + "'"); + } +}; + +/** + * Set the next timeline in the series + * + * @param {EventTimeline} neighbour previous/following timeline + * + * @param {string} direction EventTimeline.BACKWARDS to set the previous + * timeline; EventTimeline.FORWARDS to set the next timeline. + * + * @throws {Error} if an attempt is made to set the neighbouring timeline when + * it is already set. + */ +EventTimeline.prototype.setNeighbouringTimeline = function(neighbour, direction) { + if (this.getNeighbouringTimeline(direction)) { + throw new Error("timeline already has a neighbouring timeline - " + + "cannot reset neighbour"); + } + + if (direction == EventTimeline.BACKWARDS) { + this._prevTimeline = neighbour; + } else if (direction == EventTimeline.FORWARDS) { + this._nextTimeline = neighbour; + } else { + throw new Error("Invalid direction '" + direction + "'"); + } + + // make sure we don't try to paginate this timeline + this.setPaginationToken(null, direction); +}; + +/** + * Add a new event to the timeline, and update the state + * + * @param {MatrixEvent} event new event + * @param {boolean} atStart true to insert new event at the start + */ +EventTimeline.prototype.addEvent = function(event, atStart) { + var stateContext = atStart ? this._startState : this._endState; + + setEventMetadata(event, stateContext, atStart); + + // modify state + if (event.isState()) { + stateContext.setStateEvents([event]); + // it is possible that the act of setting the state event means we + // can set more metadata (specifically sender/target props), so try + // it again if the prop wasn't previously set. It may also mean that + // the sender/target is updated (if the event set was a room member event) + // so we want to use the *updated* member (new avatar/name) instead. + // + // However, we do NOT want to do this on member events if we're going + // back in time, else we'll set the .sender value for BEFORE the given + // member event, whereas we want to set the .sender value for the ACTUAL + // member event itself. + if (!event.sender || (event.getType() === "m.room.member" && !atStart)) { + setEventMetadata(event, stateContext, atStart); + } + } + + var insertIndex; + + if (atStart) { + insertIndex = 0; + } else { + insertIndex = this._events.length; + } + + this._events.splice(insertIndex, 0, event); // insert element + if (atStart) { + this._baseIndex++; + } +}; + +function setEventMetadata(event, stateContext, toStartOfTimeline) { + // set sender and target properties + event.sender = stateContext.getSentinelMember( + event.getSender() + ); + if (event.getType() === "m.room.member") { + event.target = stateContext.getSentinelMember( + event.getStateKey() + ); + } + if (event.isState()) { + // room state has no concept of 'old' or 'current', but we want the + // room state to regress back to previous values if toStartOfTimeline + // is set, which means inspecting prev_content if it exists. This + // is done by toggling the forwardLooking flag. + if (toStartOfTimeline) { + event.forwardLooking = false; + } + } +} + +/** + * Remove an event from the timeline + * + * @param {string} eventId ID of event to be removed + * @return {?MatrixEvent} removed event, or null if not found + */ +EventTimeline.prototype.removeEvent = function(eventId) { + for (var i = this._events.length - 1; i >= 0; i--) { + var ev = this._events[i]; + if (ev.getId() == eventId) { + this._events.splice(i, 1); + if (i < this._baseIndex) { + this._baseIndex--; + } + return ev; + } + } + return null; +}; + +/** + * Return a string to identify this timeline, for debugging + * + * @return {string} name for this timeline + */ +EventTimeline.prototype.toString = function() { + return this._name; +}; + + +/** + * The EventTimeline class + */ +module.exports = EventTimeline; + +},{"../utils":28,"./event":12,"./room-state":14}],12:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/** + * This is an internal module. See {@link MatrixEvent} and {@link RoomEvent} for + * the public classes. + * @module models/event + */ + +/** + * Enum for event statuses. + * @readonly + * @enum {string} + */ +module.exports.EventStatus = { + /** The event was not sent and will no longer be retried. */ + NOT_SENT: "not_sent", + /** The event is in the process of being sent. */ + SENDING: "sending", + /** The event is in a queue waiting to be sent. */ + QUEUED: "queued", + /** The event has been sent to the server, but we have not yet received the + * echo. */ + SENT: "sent", + + /** The event was cancelled before it was successfully sent. */ + CANCELLED: "cancelled", +}; + +/** + * Construct a Matrix Event object + * @constructor + * + * @param {Object} event The raw event to be wrapped in this DAO + * + * @param {Object=} clearEvent For encrypted events, the plaintext payload for + * the event (typically containing type and content fields). + * + * @prop {Object} event The raw (possibly encrypted) event. Do not access + * this property directly unless you absolutely have to. Prefer the getter + * methods defined on this class. Using the getter methods shields your app + * from changes to event JSON between Matrix versions. + * + * @prop {RoomMember} sender The room member who sent this event, or null e.g. + * this is a presence event. + * @prop {RoomMember} target The room member who is the target of this event, e.g. + * the invitee, the person being banned, etc. + * @prop {EventStatus} status The sending status of the event. + * @prop {boolean} forwardLooking True if this event is 'forward looking', meaning + * that getDirectionalContent() will return event.content and not event.prev_content. + * Default: true. This property is experimental and may change. + */ +module.exports.MatrixEvent = function MatrixEvent(event, clearEvent) { + this.event = event || {}; + this.sender = null; + this.target = null; + this.status = null; + this.forwardLooking = true; + + this._clearEvent = clearEvent || {}; +}; + +module.exports.MatrixEvent.prototype = { + + /** + * Get the event_id for this event. + * @return {string} The event ID, e.g. $143350589368169JsLZx:localhost + * + */ + getId: function() { + return this.event.event_id; + }, + + /** + * Get the user_id for this event. + * @return {string} The user ID, e.g. @alice:matrix.org + */ + getSender: function() { + return this.event.sender || this.event.user_id; // v2 / v1 + }, + + /** + * Get the (decrypted, if necessary) type of event. + * + * @return {string} The event type, e.g. m.room.message + */ + getType: function() { + return this._clearEvent.type || this.event.type; + }, + + /** + * Get the (possibly encrypted) type of the event that will be sent to the + * homeserver. + * + * @return {string} The event type. + */ + getWireType: function() { + return this.event.type; + }, + + /** + * Get the room_id for this event. This will return undefined + * for m.presence events. + * @return {string} The room ID, e.g. !cURbafjkfsMDVwdRDQ:matrix.org + * + */ + getRoomId: function() { + return this.event.room_id; + }, + + /** + * Get the timestamp of this event. + * @return {Number} The event timestamp, e.g. 1433502692297 + */ + getTs: function() { + return this.event.origin_server_ts; + }, + + /** + * Get the (decrypted, if necessary) event content JSON. + * + * @return {Object} The event content JSON, or an empty object. + */ + getContent: function() { + return this._clearEvent.content || this.event.content || {}; + }, + + /** + * Get the (possibly encrypted) event content JSON that will be sent to the + * homeserver. + * + * @return {Object} The event content JSON, or an empty object. + */ + getWireContent: function() { + return this.event.content || {}; + }, + + /** + * Get the previous event content JSON. This will only return something for + * state events which exist in the timeline. + * @return {Object} The previous event content JSON, or an empty object. + */ + getPrevContent: function() { + // v2 then v1 then default + return this.getUnsigned().prev_content || this.event.prev_content || {}; + }, + + /** + * Get either 'content' or 'prev_content' depending on if this event is + * 'forward-looking' or not. This can be modified via event.forwardLooking. + * In practice, this means we get the chronologically earlier content value + * for this event (this method should surely be called getEarlierContent) + * This method is experimental and may change. + * @return {Object} event.content if this event is forward-looking, else + * event.prev_content. + */ + getDirectionalContent: function() { + return this.forwardLooking ? this.getContent() : this.getPrevContent(); + }, + + /** + * Get the age of this event. This represents the age of the event when the + * event arrived at the device, and not the age of the event when this + * function was called. + * @return {Number} The age of this event in milliseconds. + */ + getAge: function() { + return this.getUnsigned().age || this.event.age; // v2 / v1 + }, + + /** + * Get the event state_key if it has one. This will return undefined + * for message events. + * @return {string} The event's state_key. + */ + getStateKey: function() { + return this.event.state_key; + }, + + /** + * Check if this event is a state event. + * @return {boolean} True if this is a state event. + */ + isState: function() { + return this.event.state_key !== undefined; + }, + + /** + * Replace the content of this event with encrypted versions. + * (This is used when sending an event; it should not be used by applications). + * + * @internal + * + * @param {string} crypto_type type of the encrypted event - typically + * "m.room.encrypted" + * + * @param {object} crypto_content raw 'content' for the encrypted event. + */ + makeEncrypted: function(crypto_type, crypto_content) { + // keep the plain-text data for 'view source' + this._clearEvent = { + type: this.event.type, + content: this.event.content, + }; + this.event.type = crypto_type; + this.event.content = crypto_content; + }, + + /** + * Check if the event is encrypted. + * @return {boolean} True if this event is encrypted. + */ + isEncrypted: function() { + return Boolean(this._clearEvent.type); + }, + + getUnsigned: function() { + return this.event.unsigned || {}; + }, + + /** + * Update the content of an event in the same way it would be by the server + * if it were redacted before it was sent to us + * + * @param {Object} the raw event causing the redaction + */ + makeRedacted: function(redaction_event) { + if (!this.event.unsigned) { + this.event.unsigned = {}; + } + this.event.unsigned.redacted_because = redaction_event; + + var key; + for (key in this.event) { + if (!this.event.hasOwnProperty(key)) { continue; } + if (!_REDACT_KEEP_KEY_MAP[key]) { + delete this.event[key]; + } + } + + var keeps = _REDACT_KEEP_CONTENT_MAP[this.getType()] || {}; + var content = this.getContent(); + for (key in content) { + if (!content.hasOwnProperty(key)) { continue; } + if (!keeps[key]) { + delete content[key]; + } + } + }, + + /** + * Check if this event has been redacted + * + * @return {boolean} True if this event has been redacted + */ + isRedacted: function() { + return Boolean(this.getUnsigned().redacted_because); + }, +}; + + +/* http://matrix.org/docs/spec/r0.0.1/client_server.html#redactions says: + * + * the server should strip off any keys not in the following list: + * event_id + * type + * room_id + * user_id + * state_key + * prev_state + * content + * [we keep 'unsigned' as well, since that is created by the local server] + * + * The content object should also be stripped of all keys, unless it is one of + * one of the following event types: + * m.room.member allows key membership + * m.room.create allows key creator + * m.room.join_rules allows key join_rule + * m.room.power_levels allows keys ban, events, events_default, kick, + * redact, state_default, users, users_default. + * m.room.aliases allows key aliases + */ +// a map giving the keys we keep when an event is redacted +var _REDACT_KEEP_KEY_MAP = [ + 'event_id', 'type', 'room_id', 'user_id', 'state_key', 'prev_state', + 'content', 'unsigned', +].reduce(function(ret, val) { ret[val] = 1; return ret; }, {}); + +// a map from event type to the .content keys we keep when an event is redacted +var _REDACT_KEEP_CONTENT_MAP = { + 'm.room.member': {'membership': 1}, + 'm.room.create': {'creator': 1}, + 'm.room.join_rules': {'join_rule': 1}, + 'm.room.power_levels': {'ban': 1, 'events': 1, 'events_default': 1, + 'kick': 1, 'redact': 1, 'state_default': 1, + 'users': 1, 'users_default': 1, + }, + 'm.room.aliases': {'aliases': 1}, +}; + +},{}],13:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * @module models/room-member + */ +var EventEmitter = require("events").EventEmitter; +var ContentRepo = require("../content-repo"); + +var utils = require("../utils"); + +/** + * Construct a new room member. + * @constructor + * @param {string} roomId The room ID of the member. + * @param {string} userId The user ID of the member. + * @prop {string} roomId The room ID for this member. + * @prop {string} userId The user ID of this member. + * @prop {boolean} typing True if the room member is currently typing. + * @prop {string} name The human-readable name for this room member. + * @prop {Number} powerLevel The power level for this room member. + * @prop {Number} powerLevelNorm The normalised power level (0-100) for this + * room member. + * @prop {User} user The User object for this room member, if one exists. + * @prop {string} membership The membership state for this room member e.g. 'join'. + * @prop {Object} events The events describing this RoomMember. + * @prop {MatrixEvent} events.member The m.room.member event for this RoomMember. + */ +function RoomMember(roomId, userId) { + this.roomId = roomId; + this.userId = userId; + this.typing = false; + this.name = userId; + this.powerLevel = 0; + this.powerLevelNorm = 0; + this.user = null; + this.membership = null; + this.events = { + member: null + }; + this._updateModifiedTime(); +} +utils.inherits(RoomMember, EventEmitter); + +/** + * Update this room member's membership event. May fire "RoomMember.name" if + * this event updates this member's name. + * @param {MatrixEvent} event The m.room.member event + * @param {RoomState} roomState Optional. The room state to take into account + * when calculating (e.g. for disambiguating users with the same name). + * @fires module:client~MatrixClient#event:"RoomMember.name" + * @fires module:client~MatrixClient#event:"RoomMember.membership" + */ +RoomMember.prototype.setMembershipEvent = function(event, roomState) { + if (event.getType() !== "m.room.member") { + return; + } + this.events.member = event; + + var oldMembership = this.membership; + this.membership = event.getDirectionalContent().membership; + + var oldName = this.name; + this.name = calculateDisplayName(this, event, roomState); + if (oldMembership !== this.membership) { + this._updateModifiedTime(); + this.emit("RoomMember.membership", event, this); + } + if (oldName !== this.name) { + this._updateModifiedTime(); + this.emit("RoomMember.name", event, this); + } +}; + +/** + * Update this room member's power level event. May fire + * "RoomMember.powerLevel" if this event updates this member's power levels. + * @param {MatrixEvent} powerLevelEvent The m.room.power_levels + * event + * @fires module:client~MatrixClient#event:"RoomMember.powerLevel" + */ +RoomMember.prototype.setPowerLevelEvent = function(powerLevelEvent) { + if (powerLevelEvent.getType() !== "m.room.power_levels") { + return; + } + var maxLevel = powerLevelEvent.getContent().users_default || 0; + utils.forEach(utils.values(powerLevelEvent.getContent().users), function(lvl) { + maxLevel = Math.max(maxLevel, lvl); + }); + var oldPowerLevel = this.powerLevel; + var oldPowerLevelNorm = this.powerLevelNorm; + + if (powerLevelEvent.getContent().users[this.userId] !== undefined) { + this.powerLevel = powerLevelEvent.getContent().users[this.userId]; + } else if (powerLevelEvent.getContent().users_default !== undefined) { + this.powerLevel = powerLevelEvent.getContent().users_default; + } else { + this.powerLevel = 0; + } + this.powerLevelNorm = 0; + if (maxLevel > 0) { + this.powerLevelNorm = (this.powerLevel * 100) / maxLevel; + } + + // emit for changes in powerLevelNorm as well (since the app will need to + // redraw everyone's level if the max has changed) + if (oldPowerLevel !== this.powerLevel || oldPowerLevelNorm !== this.powerLevelNorm) { + this._updateModifiedTime(); + this.emit("RoomMember.powerLevel", powerLevelEvent, this); + } +}; + +/** + * Update this room member's typing event. May fire "RoomMember.typing" if + * this event changes this member's typing state. + * @param {MatrixEvent} event The typing event + * @fires module:client~MatrixClient#event:"RoomMember.typing" + */ +RoomMember.prototype.setTypingEvent = function(event) { + if (event.getType() !== "m.typing") { + return; + } + var oldTyping = this.typing; + this.typing = false; + var typingList = event.getContent().user_ids; + if (!utils.isArray(typingList)) { + // malformed event :/ bail early. TODO: whine? + return; + } + if (typingList.indexOf(this.userId) !== -1) { + this.typing = true; + } + if (oldTyping !== this.typing) { + this._updateModifiedTime(); + this.emit("RoomMember.typing", event, this); + } +}; + +/** + * Update the last modified time to the current time. + */ +RoomMember.prototype._updateModifiedTime = function() { + this._modified = Date.now(); +}; + +/** + * Get the timestamp when this RoomMember was last updated. This timestamp is + * updated when properties on this RoomMember are updated. + * It is updated before firing events. + * @return {number} The timestamp + */ +RoomMember.prototype.getLastModifiedTime = function() { + return this._modified; +}; + +/** + * Get the avatar URL for a room member. + * @param {string} baseUrl The base homeserver URL See + * {@link module:client~MatrixClient#getHomeserverUrl}. + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {Boolean} allowDefault (optional) Passing false causes this method to + * return null if the user has no avatar image. Otherwise, a default image URL + * will be returned. Default: true. + * @param {Boolean} allowDirectLinks (optional) If true, the avatar URL will be + * returned even if it is a direct hyperlink rather than a matrix content URL. + * If false, any non-matrix content URLs will be ignored. Setting this option to + * true will expose URLs that, if fetched, will leak information about the user + * to anyone who they share a room with. + * @return {?string} the avatar URL or null. + */ +RoomMember.prototype.getAvatarUrl = + function(baseUrl, width, height, resizeMethod, allowDefault, allowDirectLinks) { + if (allowDefault === undefined) { allowDefault = true; } + if (!this.events.member && !allowDefault) { + return null; + } + var rawUrl = this.events.member ? this.events.member.getContent().avatar_url : null; + var httpUrl = ContentRepo.getHttpUriForMxc( + baseUrl, rawUrl, width, height, resizeMethod, allowDirectLinks + ); + if (httpUrl) { + return httpUrl; + } + else if (allowDefault) { + return ContentRepo.getIdenticonUri( + baseUrl, this.userId, width, height + ); + } + return null; +}; + +function calculateDisplayName(member, event, roomState) { + var displayName = event.getDirectionalContent().displayname; + var selfUserId = member.userId; + + /* + // FIXME: this would be great but still needs to use the + // full userId to disambiguate if needed... + + if (!displayName) { + var matches = selfUserId.match(/^@(.*?):/); + if (matches) { + return matches[1]; + } + else { + return selfUserId; + } + } + */ + + if (!displayName) { + return selfUserId; + } + + if (!roomState) { + return displayName; + } + + var userIds = roomState.getUserIdsWithDisplayName(displayName); + var otherUsers = userIds.filter(function(u) { + return u !== selfUserId; + }); + if (otherUsers.length > 0) { + return displayName + " (" + selfUserId + ")"; + } + return displayName; +} + +/** + * The RoomMember class. + */ +module.exports = RoomMember; + +/** + * Fires whenever any room member's name changes. + * @event module:client~MatrixClient#"RoomMember.name" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {RoomMember} member The member whose RoomMember.name changed. + * @example + * matrixClient.on("RoomMember.name", function(event, member){ + * var newName = member.name; + * }); + */ + +/** + * Fires whenever any room member's membership state changes. + * @event module:client~MatrixClient#"RoomMember.membership" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {RoomMember} member The member whose RoomMember.membership changed. + * @example + * matrixClient.on("RoomMember.membership", function(event, member){ + * var newState = member.membership; + * }); + */ + +/** + * Fires whenever any room member's typing state changes. + * @event module:client~MatrixClient#"RoomMember.typing" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {RoomMember} member The member whose RoomMember.typing changed. + * @example + * matrixClient.on("RoomMember.typing", function(event, member){ + * var isTyping = member.typing; + * }); + */ + +/** + * Fires whenever any room member's power level changes. + * @event module:client~MatrixClient#"RoomMember.powerLevel" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {RoomMember} member The member whose RoomMember.powerLevel changed. + * @example + * matrixClient.on("RoomMember.powerLevel", function(event, member){ + * var newPowerLevel = member.powerLevel; + * var newNormPowerLevel = member.powerLevelNorm; + * }); + */ + +},{"../content-repo":5,"../utils":28,"events":179}],14:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * @module models/room-state + */ +var EventEmitter = require("events").EventEmitter; + +var utils = require("../utils"); +var RoomMember = require("./room-member"); + +/** + * Construct room state. + * @constructor + * @param {string} roomId Required. The ID of the room which has this state. + * @prop {Object.} members The room member dictionary, keyed + * on the user's ID. + * @prop {Object.>} events The state + * events dictionary, keyed on the event type and then the state_key value. + * @prop {string} paginationToken The pagination token for this state. + */ +function RoomState(roomId) { + this.roomId = roomId; + this.members = { + // userId: RoomMember + }; + this.events = { + // eventType: { stateKey: MatrixEvent } + }; + this.paginationToken = null; + + this._sentinels = { + // userId: RoomMember + }; + this._updateModifiedTime(); + this._displayNameToUserIds = {}; + this._userIdsToDisplayNames = {}; + this._tokenToInvite = {}; // 3pid invite state_key to m.room.member invite +} +utils.inherits(RoomState, EventEmitter); + +/** + * Get all RoomMembers in this room. + * @return {Array} A list of RoomMembers. + */ +RoomState.prototype.getMembers = function() { + return utils.values(this.members); +}; + +/** + * Get a room member by their user ID. + * @param {string} userId The room member's user ID. + * @return {RoomMember} The member or null if they do not exist. + */ +RoomState.prototype.getMember = function(userId) { + return this.members[userId] || null; +}; + +/** + * Get a room member whose properties will not change with this room state. You + * typically want this if you want to attach a RoomMember to a MatrixEvent which + * may no longer be represented correctly by Room.currentState or Room.oldState. + * The term 'sentinel' refers to the fact that this RoomMember is an unchanging + * guardian for state at this particular point in time. + * @param {string} userId The room member's user ID. + * @return {RoomMember} The member or null if they do not exist. + */ +RoomState.prototype.getSentinelMember = function(userId) { + return this._sentinels[userId] || null; +}; + +/** + * Get state events from the state of the room. + * @param {string} eventType The event type of the state event. + * @param {string} stateKey Optional. The state_key of the state event. If + * this is undefined then all matching state events will be + * returned. + * @return {MatrixEvent[]|MatrixEvent} A list of events if state_key was + * undefined, else a single event (or null if no match found). + */ +RoomState.prototype.getStateEvents = function(eventType, stateKey) { + if (!this.events[eventType]) { + // no match + return stateKey === undefined ? [] : null; + } + if (stateKey === undefined) { // return all values + return utils.values(this.events[eventType]); + } + var event = this.events[eventType][stateKey]; + return event ? event : null; +}; + +/** + * Add an array of one or more state MatrixEvents, overwriting + * any existing state with the same {type, stateKey} tuple. Will fire + * "RoomState.events" for every event added. May fire "RoomState.members" + * if there are m.room.member events. + * @param {MatrixEvent[]} stateEvents a list of state events for this room. + * @fires module:client~MatrixClient#event:"RoomState.members" + * @fires module:client~MatrixClient#event:"RoomState.newMember" + * @fires module:client~MatrixClient#event:"RoomState.events" + */ +RoomState.prototype.setStateEvents = function(stateEvents) { + var self = this; + this._updateModifiedTime(); + + // update the core event dict + utils.forEach(stateEvents, function(event) { + if (event.getRoomId() !== self.roomId) { return; } + if (!event.isState()) { return; } + + if (self.events[event.getType()] === undefined) { + self.events[event.getType()] = {}; + } + self.events[event.getType()][event.getStateKey()] = event; + if (event.getType() === "m.room.member") { + _updateDisplayNameCache( + self, event.getStateKey(), event.getContent().displayname + ); + _updateThirdPartyTokenCache(self, event); + } + self.emit("RoomState.events", event, self); + }); + + // update higher level data structures. This needs to be done AFTER the + // core event dict as these structures may depend on other state events in + // the given array (e.g. disambiguating display names in one go to do both + // clashing names rather than progressively which only catches 1 of them). + utils.forEach(stateEvents, function(event) { + if (event.getRoomId() !== self.roomId) { return; } + if (!event.isState()) { return; } + + if (event.getType() === "m.room.member") { + var userId = event.getStateKey(); + + // leave events apparently elide the displayname or avatar_url, + // so let's fake one up so that we don't leak user ids + // into the timeline + if (event.getContent().membership === "leave" || + event.getContent().membership === "ban") + { + event.getContent().avatar_url = + event.getContent().avatar_url || + event.getPrevContent().avatar_url; + event.getContent().displayname = + event.getContent().displayname || + event.getPrevContent().displayname; + } + + var member = self.members[userId]; + if (!member) { + member = new RoomMember(event.getRoomId(), userId); + self.emit("RoomState.newMember", event, self, member); + } + // Add a new sentinel for this change. We apply the same + // operations to both sentinel and member rather than deep copying + // so we don't make assumptions about the properties of RoomMember + // (e.g. and manage to break it because deep copying doesn't do + // everything). + var sentinel = new RoomMember(event.getRoomId(), userId); + utils.forEach([member, sentinel], function(roomMember) { + roomMember.setMembershipEvent(event, self); + // this member may have a power level already, so set it. + var pwrLvlEvent = self.getStateEvents("m.room.power_levels", ""); + if (pwrLvlEvent) { + roomMember.setPowerLevelEvent(pwrLvlEvent); + } + }); + + self._sentinels[userId] = sentinel; + self.members[userId] = member; + self.emit("RoomState.members", event, self, member); + } + else if (event.getType() === "m.room.power_levels") { + var members = utils.values(self.members); + utils.forEach(members, function(member) { + member.setPowerLevelEvent(event); + self.emit("RoomState.members", event, self, member); + }); + } + }); +}; + +/** + * Set the current typing event for this room. + * @param {MatrixEvent} event The typing event + */ +RoomState.prototype.setTypingEvent = function(event) { + utils.forEach(utils.values(this.members), function(member) { + member.setTypingEvent(event); + }); +}; + +/** + * Get the m.room.member event which has the given third party invite token. + * + * @param {string} token The token + * @return {?MatrixEvent} The m.room.member event or null + */ +RoomState.prototype.getInviteForThreePidToken = function(token) { + return this._tokenToInvite[token] || null; +}; + +/** + * Update the last modified time to the current time. + */ +RoomState.prototype._updateModifiedTime = function() { + this._modified = Date.now(); +}; + +/** + * Get the timestamp when this room state was last updated. This timestamp is + * updated when this object has received new state events. + * @return {number} The timestamp + */ +RoomState.prototype.getLastModifiedTime = function() { + return this._modified; +}; + +/** + * Get user IDs with the specified display name. + * @param {string} displayName The display name to get user IDs from. + * @return {string[]} An array of user IDs or an empty array. + */ +RoomState.prototype.getUserIdsWithDisplayName = function(displayName) { + return this._displayNameToUserIds[displayName] || []; +}; + +/** + * Short-form for maySendEvent('m.room.message', userId) + * @param {string} userId The user ID of the user to test permission for + * @return {boolean} true if the given user ID should be permitted to send + * message events into the given room. + */ +RoomState.prototype.maySendMessage = function(userId) { + return this._maySendEventOfType('m.room.message', userId, false); +}; + +/** + * Returns true if the given user ID has permission to send a normal + * event of type `eventType` into this room. + * @param {string} type The type of event to test + * @param {string} userId The user ID of the user to test permission for + * @return {boolean} true if the given user ID should be permitted to send + * the given type of event into this room, + * according to the room's state. + */ +RoomState.prototype.maySendEvent = function(eventType, userId) { + return this._maySendEventOfType(eventType, userId, false); +}; + + +/** + * Returns true if the given MatrixClient has permission to send a state + * event of type `stateEventType` into this room. + * @param {string} type The type of state events to test + * @param {MatrixClient} The client to test permission for + * @return {boolean} true if the given client should be permitted to send + * the given type of state event into this room, + * according to the room's state. + */ +RoomState.prototype.mayClientSendStateEvent = function(stateEventType, cli) { + if (cli.isGuest()) { + return false; + } + return this.maySendStateEvent(stateEventType, cli.credentials.userId); +}; + +/** + * Returns true if the given user ID has permission to send a state + * event of type `stateEventType` into this room. + * @param {string} type The type of state events to test + * @param {string} userId The user ID of the user to test permission for + * @return {boolean} true if the given user ID should be permitted to send + * the given type of state event into this room, + * according to the room's state. + */ +RoomState.prototype.maySendStateEvent = function(stateEventType, userId) { + return this._maySendEventOfType(stateEventType, userId, true); +}; + +/** + * Returns true if the given user ID has permission to send a normal or state + * event of type `eventType` into this room. + * @param {string} type The type of event to test + * @param {string} userId The user ID of the user to test permission for + * @param {boolean} state If true, tests if the user may send a state + event of this type. Otherwise tests whether + they may send a regular event. + * @return {boolean} true if the given user ID should be permitted to send + * the given type of event into this room, + * according to the room's state. + */ +RoomState.prototype._maySendEventOfType = function(eventType, userId, state) { + var member = this.getMember(userId); + if (!member || member.membership == 'leave') { return false; } + + var power_levels_event = this.getStateEvents('m.room.power_levels', ''); + + var power_levels; + var events_levels = {}; + + var default_user_level = 0; + var user_levels = []; + + var state_default = 0; + var events_default = 0; + if (power_levels_event) { + power_levels = power_levels_event.getContent(); + events_levels = power_levels.events || {}; + + default_user_level = parseInt(power_levels.users_default || 0); + user_levels = power_levels.users || {}; + + if (power_levels.state_default !== undefined) { + state_default = power_levels.state_default; + } else { + state_default = 50; + } + if (power_levels.events_default !== undefined) { + events_default = power_levels.events_default; + } + } + + var required_level = state ? state_default : events_default; + if (events_levels[eventType] !== undefined) { + required_level = events_levels[eventType]; + } + return member.powerLevel >= required_level; +}; + +/** + * The RoomState class. + */ +module.exports = RoomState; + + +function _updateThirdPartyTokenCache(roomState, memberEvent) { + if (!memberEvent.getContent().third_party_invite) { + return; + } + var token = (memberEvent.getContent().third_party_invite.signed || {}).token; + if (!token) { + return; + } + var threePidInvite = roomState.getStateEvents( + "m.room.third_party_invite", token + ); + if (!threePidInvite) { + return; + } + roomState._tokenToInvite[token] = memberEvent; +} + +function _updateDisplayNameCache(roomState, userId, displayName) { + var oldName = roomState._userIdsToDisplayNames[userId]; + delete roomState._userIdsToDisplayNames[userId]; + if (oldName) { + // Remove the old name from the cache. + // We clobber the user_id > name lookup but the name -> [user_id] lookup + // means we need to remove that user ID from that array rather than nuking + // the lot. + var existingUserIds = roomState._displayNameToUserIds[oldName] || []; + for (var i = 0; i < existingUserIds.length; i++) { + if (existingUserIds[i] === userId) { + // remove this user ID from this array + existingUserIds.splice(i, 1); + i--; + } + } + roomState._displayNameToUserIds[oldName] = existingUserIds; + } + + roomState._userIdsToDisplayNames[userId] = displayName; + if (!roomState._displayNameToUserIds[displayName]) { + roomState._displayNameToUserIds[displayName] = []; + } + roomState._displayNameToUserIds[displayName].push(userId); +} + +/** + * Fires whenever the event dictionary in room state is updated. + * @event module:client~MatrixClient#"RoomState.events" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {RoomState} state The room state whose RoomState.events dictionary + * was updated. + * @example + * matrixClient.on("RoomState.events", function(event, state){ + * var newStateEvent = event; + * }); + */ + +/** + * Fires whenever a member in the members dictionary is updated in any way. + * @event module:client~MatrixClient#"RoomState.members" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {RoomState} state The room state whose RoomState.members dictionary + * was updated. + * @param {RoomMember} member The room member that was updated. + * @example + * matrixClient.on("RoomState.members", function(event, state, member){ + * var newMembershipState = member.membership; + * }); + */ + + /** + * Fires whenever a member is added to the members dictionary. The RoomMember + * will not be fully populated yet (e.g. no membership state). + * @event module:client~MatrixClient#"RoomState.newMember" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {RoomState} state The room state whose RoomState.members dictionary + * was updated with a new entry. + * @param {RoomMember} member The room member that was added. + * @example + * matrixClient.on("RoomState.newMember", function(event, state, member){ + * // add event listeners on 'member' + * }); + */ + +},{"../utils":28,"./room-member":13,"events":179}],15:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * @module models/room-summary + */ + +/** + * Construct a new Room Summary. A summary can be used for display on a recent + * list, without having to load the entire room list into memory. + * @constructor + * @param {string} roomId Required. The ID of this room. + * @param {Object} info Optional. The summary info. Additional keys are supported. + * @param {string} info.title The title of the room (e.g. m.room.name) + * @param {string} info.desc The description of the room (e.g. + * m.room.topic) + * @param {Number} info.numMembers The number of joined users. + * @param {string[]} info.aliases The list of aliases for this room. + * @param {Number} info.timestamp The timestamp for this room. + */ +function RoomSummary(roomId, info) { + this.roomId = roomId; + this.info = info; +} + +/** + * The RoomSummary class. + */ +module.exports = RoomSummary; + +},{}],16:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * @module models/room + */ +var EventEmitter = require("events").EventEmitter; + +var EventStatus = require("./event").EventStatus; +var RoomSummary = require("./room-summary"); +var MatrixEvent = require("./event").MatrixEvent; +var utils = require("../utils"); +var ContentRepo = require("../content-repo"); +var EventTimeline = require("./event-timeline"); + + +// var DEBUG = false; +var DEBUG = true; + +if (DEBUG) { + // using bind means that we get to keep useful line numbers in the console + var debuglog = console.log.bind(console); +} else { + var debuglog = function() {}; +} + + +function synthesizeReceipt(userId, event, receiptType) { + // console.log("synthesizing receipt for "+event.getId()); + // This is really ugly because JS has no way to express an object literal + // where the name of a key comes from an expression + var fakeReceipt = { + content: {}, + type: "m.receipt", + room_id: event.getRoomId() + }; + fakeReceipt.content[event.getId()] = {}; + fakeReceipt.content[event.getId()][receiptType] = {}; + fakeReceipt.content[event.getId()][receiptType][userId] = { + ts: event.getTs() + }; + return new MatrixEvent(fakeReceipt); +} + + +/** + * Construct a new Room. + * + *

For a room, we store an ordered sequence of timelines, which may or may not + * be continuous. Each timeline lists a series of events, as well as tracking + * the room state at the start and the end of the timeline. It also tracks + * forward and backward pagination tokens, as well as containing links to the + * next timeline in the sequence. + * + *

There is one special timeline - the 'live' timeline, which represents the + * timeline to which events are being added in real-time as they are received + * from the /sync API. Note that you should not retain references to this + * timeline - even if it is the current timeline right now, it may not remain + * so if the server gives us a timeline gap in /sync. + * + *

In order that we can find events from their ids later, we also maintain a + * map from event_id to timeline and index. + * + * @constructor + * @param {string} roomId Required. The ID of this room. + * @param {Object=} opts Configuration options + * @param {*} opts.storageToken Optional. The token which a data store can use + * to remember the state of the room. What this means is dependent on the store + * implementation. + * + * @param {String=} opts.pendingEventOrdering Controls where pending messages + * appear in a room's timeline. If "chronological", messages will appear + * in the timeline when the call to sendEvent was made. If + * "detached", pending messages will appear in a separate list, + * accessbile via {@link module:models/room~Room#getPendingEvents}. Default: + * "chronological". + * + * @param {boolean} [opts.timelineSupport = false] Set to true to enable improved + * timeline support. + * + * @prop {string} roomId The ID of this room. + * @prop {string} name The human-readable display name for this room. + * @prop {Array} timeline The live event timeline for this room, + * with the oldest event at index 0. Present for backwards compatibility - + * prefer getLiveTimeline().getEvents(). + * @prop {object} tags Dict of room tags; the keys are the tag name and the values + * are any metadata associated with the tag - e.g. { "fav" : { order: 1 } } + * @prop {object} accountData Dict of per-room account_data events; the keys are the + * event type and the values are the events. + * @prop {RoomState} oldState The state of the room at the time of the oldest + * event in the live timeline. Present for backwards compatibility - + * prefer getLiveTimeline().getState(true). + * @prop {RoomState} currentState The state of the room at the time of the + * newest event in the timeline. Present for backwards compatibility - + * prefer getLiveTimeline().getState(false). + * @prop {RoomSummary} summary The room summary. + * @prop {*} storageToken A token which a data store can use to remember + * the state of the room. + */ +function Room(roomId, opts) { + opts = opts || {}; + opts.pendingEventOrdering = opts.pendingEventOrdering || "chronological"; + + if (["chronological", "detached"].indexOf(opts.pendingEventOrdering) === -1) { + throw new Error( + "opts.pendingEventOrdering MUST be either 'chronological' or " + + "'detached'. Got: '" + opts.pendingEventOrdering + "'" + ); + } + + this.roomId = roomId; + this.name = roomId; + this.tags = { + // $tagName: { $metadata: $value }, + // $tagName: { $metadata: $value }, + }; + this.accountData = { + // $eventType: $event + }; + this.summary = null; + this.storageToken = opts.storageToken; + this._opts = opts; + this._txnToEvent = {}; // Pending in-flight requests { string: MatrixEvent } + // receipts should clobber based on receipt_type and user_id pairs hence + // the form of this structure. This is sub-optimal for the exposed APIs + // which pass in an event ID and get back some receipts, so we also store + // a pre-cached list for this purpose. + this._receipts = { + // receipt_type: { + // user_id: { + // eventId: , + // data: + // } + // } + }; + this._receiptCacheByEventId = { + // $event_id: [{ + // type: $type, + // userId: $user_id, + // data: + // }] + }; + // only receipts that came from the server, not synthesized ones + this._realReceipts = {}; + + this._notificationCounts = {}; + + this._liveTimeline = new EventTimeline(this.roomId); + this._fixUpLegacyTimelineFields(); + + // just a list - *not* ordered. + this._timelines = [this._liveTimeline]; + this._eventIdToTimeline = {}; + this._timelineSupport = Boolean(opts.timelineSupport); + + if (this._opts.pendingEventOrdering == "detached") { + this._pendingEventList = []; + } +} +utils.inherits(Room, EventEmitter); + +/** + * Get the list of pending sent events for this room + * + * @return {module:models/event.MatrixEvent[]} A list of the sent events + * waiting for remote echo. + * + * @throws If opts.pendingEventOrdering was not 'detached' + */ +Room.prototype.getPendingEvents = function() { + if (this._opts.pendingEventOrdering !== "detached") { + throw new Error( + "Cannot call getPendingEventList with pendingEventOrdering == " + + this._opts.pendingEventOrdering); + } + + return this._pendingEventList; +}; + + +/** + * Get the live timeline for this room. + * + * @return {module:models/event-timeline~EventTimeline} live timeline + */ +Room.prototype.getLiveTimeline = function() { + return this._liveTimeline; +}; + +/** + * Reset the live timeline, and start a new one. + * + *

This is used when /sync returns a 'limited' timeline. + * + * @param {string=} backPaginationToken token for back-paginating the new timeline + * + * @fires module:client~MatrixClient#event:"Room.timelineReset" + */ +Room.prototype.resetLiveTimeline = function(backPaginationToken) { + var newTimeline; + + if (!this._timelineSupport) { + // if timeline support is disabled, forget about the old timelines + newTimeline = new EventTimeline(this.roomId); + this._timelines = [newTimeline]; + this._eventIdToTimeline = {}; + } else { + newTimeline = this.addTimeline(); + } + + // initialise the state in the new timeline from our last known state + var evMap = this._liveTimeline.getState(EventTimeline.FORWARDS).events; + var events = []; + for (var evtype in evMap) { + if (!evMap.hasOwnProperty(evtype)) { continue; } + for (var stateKey in evMap[evtype]) { + if (!evMap[evtype].hasOwnProperty(stateKey)) { continue; } + events.push(evMap[evtype][stateKey]); + } + } + newTimeline.initialiseState(events); + + // make sure we set the pagination token before firing timelineReset, + // otherwise clients which start back-paginating will fail, and then get + // stuck without realising that they *can* back-paginate. + newTimeline.setPaginationToken(backPaginationToken, EventTimeline.BACKWARDS); + + this._liveTimeline = newTimeline; + this._fixUpLegacyTimelineFields(); + this.emit("Room.timelineReset", this); +}; + +/** + * Fix up this.timeline, this.oldState and this.currentState + * + * @private + */ +Room.prototype._fixUpLegacyTimelineFields = function() { + // maintain this.timeline as a reference to the live timeline, + // and this.oldState and this.currentState as references to the + // state at the start and end of that timeline. These are more + // for backwards-compatibility than anything else. + this.timeline = this._liveTimeline.getEvents(); + this.oldState = this._liveTimeline.getState(EventTimeline.BACKWARDS); + this.currentState = this._liveTimeline.getState(EventTimeline.FORWARDS); +}; + +/** + * Get the timeline which contains the given event, if any + * + * @param {string} eventId event ID to look for + * @return {?module:models/event-timeline~EventTimeline} timeline containing + * the given event, or null if unknown + */ +Room.prototype.getTimelineForEvent = function(eventId) { + var res = this._eventIdToTimeline[eventId]; + return (res === undefined) ? null : res; +}; + +/** + * Get an event which is stored in our timelines + * + * @param {string} eventId event ID to look for + * @return {?module:models/event~MatrixEvent} the given event, or undefined if unknown + */ +Room.prototype.findEventById = function(eventId) { + var tl = this.getTimelineForEvent(eventId); + if (!tl) { + return undefined; + } + return utils.findElement(tl.getEvents(), + function(ev) { return ev.getId() == eventId; }); +}; + + +/** + * Get one of the notification counts for this room + * @param {String} type The type of notification count to get. default: 'total' + * @return {Number} The notification count, or undefined if there is no count + * for this type. + */ +Room.prototype.getUnreadNotificationCount = function(type) { + type = type || 'total'; + return this._notificationCounts[type]; +}; + +/** + * Set one of the notification counts for this room + * @param {String} type The type of notification count to set. + * @param {Number} count The new count + */ +Room.prototype.setUnreadNotificationCount = function(type, count) { + this._notificationCounts[type] = count; +}; + +/** + * Get the avatar URL for a room if one was set. + * @param {String} baseUrl The homeserver base URL. See + * {@link module:client~MatrixClient#getHomeserverUrl}. + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {boolean} allowDefault True to allow an identicon for this room if an + * avatar URL wasn't explicitly set. Default: true. + * @return {?string} the avatar URL or null. + */ +Room.prototype.getAvatarUrl = function(baseUrl, width, height, resizeMethod, + allowDefault) { + var roomAvatarEvent = this.currentState.getStateEvents("m.room.avatar", ""); + if (allowDefault === undefined) { allowDefault = true; } + if (!roomAvatarEvent && !allowDefault) { + return null; + } + + var mainUrl = roomAvatarEvent ? roomAvatarEvent.getContent().url : null; + if (mainUrl) { + return ContentRepo.getHttpUriForMxc( + baseUrl, mainUrl, width, height, resizeMethod + ); + } + else if (allowDefault) { + return ContentRepo.getIdenticonUri( + baseUrl, this.roomId, width, height + ); + } + + return null; +}; + +/** + * Get the aliases this room has according to the room's state + * The aliases returned by this function may not necessarily + * still point to this room. + * @return {array} The room's alias as an array of strings + */ +Room.prototype.getAliases = function() { + var alias_strings = []; + + var alias_events = this.currentState.getStateEvents("m.room.aliases"); + if (alias_events) { + for (var i = 0; i < alias_events.length; ++i) { + var alias_event = alias_events[i]; + if (utils.isArray(alias_event.getContent().aliases)) { + Array.prototype.push.apply( + alias_strings, alias_event.getContent().aliases + ); + } + } + } + return alias_strings; +}; + +/** + * Get this room's canonical alias + * The alias returned by this function may not necessarily + * still point to this room. + * @return {?string} The room's canonical alias, or null if there is none + */ +Room.prototype.getCanonicalAlias = function() { + var canonicalAlias = this.currentState.getStateEvents("m.room.canonical_alias", ""); + if (canonicalAlias) { + return canonicalAlias.getContent().alias; + } + return null; +}; + +/** + * Get a member from the current room state. + * @param {string} userId The user ID of the member. + * @return {RoomMember} The member or null. + */ + Room.prototype.getMember = function(userId) { + var member = this.currentState.members[userId]; + if (!member) { + return null; + } + return member; + }; + +/** + * Get a list of members whose membership state is "join". + * @return {RoomMember[]} A list of currently joined members. + */ + Room.prototype.getJoinedMembers = function() { + return this.getMembersWithMembership("join"); + }; + +/** + * Get a list of members with given membership state. + * @param {string} membership The membership state. + * @return {RoomMember[]} A list of members with the given membership state. + */ + Room.prototype.getMembersWithMembership = function(membership) { + return utils.filter(this.currentState.getMembers(), function(m) { + return m.membership === membership; + }); + }; + + /** + * Get the default room name (i.e. what a given user would see if the + * room had no m.room.name) + * @param {string} userId The userId from whose perspective we want + * to calculate the default name + * @return {string} The default room name + */ + Room.prototype.getDefaultRoomName = function(userId) { + return calculateRoomName(this, userId, true); + }; + + + /** + * Check if the given user_id has the given membership state. + * @param {string} userId The user ID to check. + * @param {string} membership The membership e.g. 'join' + * @return {boolean} True if this user_id has the given membership state. + */ + Room.prototype.hasMembershipState = function(userId, membership) { + var member = this.getMember(userId); + if (!member) { + return false; + } + return member.membership === membership; + }; + +/** + * Add a new timeline to this room + * + * @return {module:models/event-timeline~EventTimeline} newly-created timeline + */ +Room.prototype.addTimeline = function() { + if (!this._timelineSupport) { + throw new Error("timeline support is disabled. Set the 'timelineSupport'" + + " parameter to true when creating MatrixClient to enable" + + " it."); + } + + var timeline = new EventTimeline(this.roomId); + this._timelines.push(timeline); + return timeline; +}; + + +/** + * Add events to a timeline + * + *

Will fire "Room.timeline" for each event added. + * + * @param {MatrixEvent[]} events A list of events to add. + * + * @param {boolean} toStartOfTimeline True to add these events to the start + * (oldest) instead of the end (newest) of the timeline. If true, the oldest + * event will be the last element of 'events'. + * + * @param {module:models/event-timeline~EventTimeline} timeline timeline to + * add events to. + * + * @param {string=} paginationToken token for the next batch of events + * + * @fires module:client~MatrixClient#event:"Room.timeline" + * + */ +Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline, + timeline, paginationToken) { + if (!timeline) { + throw new Error( + "'timeline' not specified for Room.addEventsToTimeline" + ); + } + + if (!toStartOfTimeline && timeline == this._liveTimeline) { + throw new Error( + "Room.addEventsToTimeline cannot be used for adding events to " + + "the live timeline - use Room.addLiveEvents instead" + ); + } + + var direction = toStartOfTimeline ? EventTimeline.BACKWARDS : + EventTimeline.FORWARDS; + var inverseDirection = toStartOfTimeline ? EventTimeline.FORWARDS : + EventTimeline.BACKWARDS; + + // Adding events to timelines can be quite complicated. The following + // illustrates some of the corner-cases. + // + // Let's say we start by knowing about four timelines. timeline3 and + // timeline4 are neighbours: + // + // timeline1 timeline2 timeline3 timeline4 + // [M] [P] [S] <------> [T] + // + // Now we paginate timeline1, and get the following events from the server: + // [M, N, P, R, S, T, U]. + // + // 1. First, we ignore event M, since we already know about it. + // + // 2. Next, we append N to timeline 1. + // + // 3. Next, we don't add event P, since we already know about it, + // but we do link together the timelines. We now have: + // + // timeline1 timeline2 timeline3 timeline4 + // [M, N] <---> [P] [S] <------> [T] + // + // 4. Now we add event R to timeline2: + // + // timeline1 timeline2 timeline3 timeline4 + // [M, N] <---> [P, R] [S] <------> [T] + // + // Note that we have switched the timeline we are working on from + // timeline1 to timeline2. + // + // 5. We ignore event S, but again join the timelines: + // + // timeline1 timeline2 timeline3 timeline4 + // [M, N] <---> [P, R] <---> [S] <------> [T] + // + // 6. We ignore event T, and the timelines are already joined, so there + // is nothing to do. + // + // 7. Finally, we add event U to timeline4: + // + // timeline1 timeline2 timeline3 timeline4 + // [M, N] <---> [P, R] <---> [S] <------> [T, U] + // + // The important thing to note in the above is what happened when we + // already knew about a given event: + // + // - if it was appropriate, we joined up the timelines (steps 3, 5). + // - in any case, we started adding further events to the timeline which + // contained the event we knew about (steps 3, 5, 6). + // + // + // So much for adding events to the timeline. But what do we want to do + // with the pagination token? + // + // In the case above, we will be given a pagination token which tells us how to + // get events beyond 'U' - in this case, it makes sense to store this + // against timeline4. But what if timeline4 already had 'U' and beyond? in + // that case, our best bet is to throw away the pagination token we were + // given and stick with whatever token timeline4 had previously. In short, + // we want to only store the pagination token if the last event we receive + // is one we didn't previously know about. + // + // We make an exception for this if it turns out that we already knew about + // *all* of the events, and we weren't able to join up any timelines. When + // that happens, it means our existing pagination token is faulty, since it + // is only telling us what we already know. Rather than repeatedly + // paginating with the same token, we might as well use the new pagination + // token in the hope that we eventually work our way out of the mess. + + var didUpdate = false; + var lastEventWasNew = false; + for (var i = 0; i < events.length; i++) { + var event = events[i]; + var eventId = event.getId(); + + var existingTimeline = this._eventIdToTimeline[eventId]; + + if (!existingTimeline) { + // we don't know about this event yet. Just add it to the timeline. + this._addEventToTimeline(event, timeline, toStartOfTimeline); + lastEventWasNew = true; + didUpdate = true; + continue; + } + + lastEventWasNew = false; + + if (existingTimeline == timeline) { + debuglog("Event " + eventId + " already in timeline " + timeline); + continue; + } + + var neighbour = timeline.getNeighbouringTimeline(direction); + if (neighbour) { + // this timeline already has a neighbour in the relevant direction; + // let's assume the timelines are already correctly linked up, and + // skip over to it. + // + // there's probably some edge-case here where we end up with an + // event which is in a timeline a way down the chain, and there is + // a break in the chain somewhere. But I can't really imagine how + // that would happen, so I'm going to ignore it for now. + // + if (existingTimeline == neighbour) { + debuglog("Event " + eventId + " in neighbouring timeline - " + + "switching to " + existingTimeline); + } else { + debuglog("Event " + eventId + " already in a different " + + "timeline " + existingTimeline); + } + timeline = existingTimeline; + continue; + } + + // time to join the timelines. + console.info("Already have timeline for " + eventId + + " - joining timeline " + timeline + " to " + + existingTimeline); + timeline.setNeighbouringTimeline(existingTimeline, direction); + existingTimeline.setNeighbouringTimeline(timeline, inverseDirection); + timeline = existingTimeline; + didUpdate = true; + } + + // see above - if the last event was new to us, or if we didn't find any + // new information, we update the pagination token for whatever + // timeline we ended up on. + if (lastEventWasNew || !didUpdate) { + timeline.setPaginationToken(paginationToken, direction); + } +}; + +/** + * Add event to the given timeline, and emit Room.timeline. Assumes + * we have already checked we don't know about this event. + * + * Will fire "Room.timeline" for each event added. + * + * @param {MatrixEvent} event + * @param {EventTimeline} timeline + * @param {boolean} toStartOfTimeline + * + * @fires module:client~MatrixClient#event:"Room.timeline" + * + * @private + */ +Room.prototype._addEventToTimeline = function(event, timeline, toStartOfTimeline) { + var eventId = event.getId(); + timeline.addEvent(event, toStartOfTimeline); + this._eventIdToTimeline[eventId] = timeline; + + var data = { + timeline: timeline, + liveEvent: !toStartOfTimeline && timeline == this._liveTimeline, + }; + this.emit("Room.timeline", event, this, Boolean(toStartOfTimeline), false, data); +}; + + +/** + * Add an event to the end of this room's live timeline. Will fire + * "Room.timeline".. + * + * @param {MatrixEvent} event Event to be added + * @param {string?} duplicateStrategy 'ignore' or 'replace' + * @fires module:client~MatrixClient#event:"Room.timeline" + * @private + */ +Room.prototype._addLiveEvent = function(event, duplicateStrategy) { + if (event.getType() === "m.room.redaction") { + var redactId = event.event.redacts; + + // if we know about this event, redact its contents now. + var redactedEvent = this.findEventById(redactId); + if (redactedEvent) { + redactedEvent.makeRedacted(event); + this.emit("Room.redaction", event, this); + + // TODO: we stash user displaynames (among other things) in + // RoomMember objects which are then attached to other events + // (in the sender and target fields). We should get those + // RoomMember objects to update themselves when the events that + // they are based on are changed. + } + + // NB: We continue to add the redaction event to the timeline so + // clients can say "so and so redacted an event" if they wish to. Also + // this may be needed to trigger an update. + } + + if (event.getUnsigned().transaction_id) { + var existingEvent = this._txnToEvent[event.getUnsigned().transaction_id]; + if (existingEvent) { + // remote echo of an event we sent earlier + this._handleRemoteEcho(event, existingEvent); + return; + } + } + + var timeline = this._eventIdToTimeline[event.getId()]; + if (timeline) { + if (duplicateStrategy === "replace") { + debuglog("Room._addLiveEvent: replacing duplicate event " + + event.getId()); + var tlEvents = timeline.getEvents(); + for (var j = 0; j < tlEvents.length; j++) { + if (tlEvents[j].getId() === event.getId()) { + // still need to set the right metadata on this event + setEventMetadata( + event, + timeline.getState(EventTimeline.FORWARDS), + false + ); + + if (!tlEvents[j].encryptedType) { + tlEvents[j] = event; + } + + // XXX: we need to fire an event when this happens. + break; + } + } + } else { + debuglog("Room._addLiveEvent: ignoring duplicate event " + + event.getId()); + } + return; + } + + // TODO: pass through filter to see if this should be added to the timeline. + this._addEventToTimeline(event, this._liveTimeline, false); + + // synthesize and inject implicit read receipts + // Done after adding the event because otherwise the app would get a read receipt + // pointing to an event that wasn't yet in the timeline + if (event.sender) { + this.addReceipt(synthesizeReceipt( + event.sender.userId, event, "m.read" + ), true); + + // Any live events from a user could be taken as implicit + // presence information: evidence that they are currently active. + // ...except in a world where we use 'user.currentlyActive' to reduce + // presence spam, this isn't very useful - we'll get a transition when + // they are no longer currently active anyway. So don't bother to + // reset the lastActiveAgo and lastPresenceTs from the RoomState's user. + } +}; + + +/** + * Add a pending outgoing event to this room. + * + *

The event is added to either the pendingEventList, or the live timeline, + * depending on the setting of opts.pendingEventOrdering. + * + *

This is an internal method, intended for use by MatrixClient. + * + * @param {module:models/event.MatrixEvent} event The event to add. + * + * @param {string} txnId Transaction id for this outgoing event + * + * @fires module:client~MatrixClient#event:"Room.localEchoUpdated" + * + * @throws if the event doesn't have status SENDING, or we aren't given a + * unique transaction id. + */ +Room.prototype.addPendingEvent = function(event, txnId) { + if (event.status !== EventStatus.SENDING) { + throw new Error("addPendingEvent called on an event with status " + + event.status); + } + + if (this._txnToEvent[txnId]) { + throw new Error("addPendingEvent called on an event with known txnId " + + txnId); + } + + // call setEventMetadata to set up event.sender etc + setEventMetadata( + event, + this._liveTimeline.getState(EventTimeline.FORWARDS), + false + ); + + this._txnToEvent[txnId] = event; + + if (this._opts.pendingEventOrdering == "detached") { + this._pendingEventList.push(event); + } else { + this._addEventToTimeline(event, this._liveTimeline, false); + } + + this.emit("Room.localEchoUpdated", event, this, null, null); +}; + +/** + * Deal with the echo of a message we sent. + * + *

We move the event to the live timeline if it isn't there already, and + * update it. + * + * @param {module:models/event~MatrixEvent} remoteEvent The event received from + * /sync + * @param {module:models/event~MatrixEvent} localEvent The local echo, which + * should be either in the _pendingEventList or the timeline. + * + * @fires module:client~MatrixClient#event:"Room.localEchoUpdated" + * @private + */ +Room.prototype._handleRemoteEcho = function(remoteEvent, localEvent) { + var oldEventId = localEvent.getId(); + var newEventId = remoteEvent.getId(); + var oldStatus = localEvent.status; + + // no longer pending + delete this._txnToEvent[remoteEvent.transaction_id]; + + // if it's in the pending list, remove it + if (this._pendingEventList) { + utils.removeElement( + this._pendingEventList, + function(ev) { return ev.getId() == oldEventId; }, + false + ); + } + + // replace the event source (this will preserve the plaintext payload if + // any, which is good, because we don't want to try decoding it again). + localEvent.event = remoteEvent.event; + + // successfully sent. + localEvent.status = null; + + // if it's already in the timeline, update the timeline map. If it's not, add it. + var existingTimeline = this._eventIdToTimeline[oldEventId]; + if (existingTimeline) { + delete this._eventIdToTimeline[oldEventId]; + this._eventIdToTimeline[newEventId] = existingTimeline; + } else { + this._addEventToTimeline(localEvent, this._liveTimeline, false); + } + + this.emit("Room.localEchoUpdated", localEvent, this, + oldEventId, oldStatus); +}; + +/* a map from current event status to a list of allowed next statuses + */ +var ALLOWED_TRANSITIONS = {}; + +ALLOWED_TRANSITIONS[EventStatus.SENDING] = + [EventStatus.QUEUED, EventStatus.NOT_SENT, EventStatus.SENT]; + +ALLOWED_TRANSITIONS[EventStatus.QUEUED] = + [EventStatus.SENDING, EventStatus.CANCELLED]; + +ALLOWED_TRANSITIONS[EventStatus.SENT] = + []; + +ALLOWED_TRANSITIONS[EventStatus.NOT_SENT] = + [EventStatus.SENDING, EventStatus.QUEUED, EventStatus.CANCELLED]; + +ALLOWED_TRANSITIONS[EventStatus.CANCELLED] = + []; + +/** + * Update the status / event id on a pending event, to reflect its transmission + * progress. + * + *

This is an internal method. + * + * @param {MatrixEvent} event local echo event + * @param {EventStatus} newStatus status to assign + * @param {string} newEventId new event id to assign. Ignored unless + * newStatus == EventStatus.SENT. + * @fires module:client~MatrixClient#event:"Room.localEchoUpdated" + */ +Room.prototype.updatePendingEvent = function(event, newStatus, newEventId) { + // if the message was sent, we expect an event id + if (newStatus == EventStatus.SENT && !newEventId) { + throw new Error("updatePendingEvent called with status=SENT, " + + "but no new event id"); + } + + // SENT races against /sync, so we have to special-case it. + if (newStatus == EventStatus.SENT) { + var timeline = this._eventIdToTimeline[newEventId]; + if (timeline) { + // we've already received the event via the event stream. + // nothing more to do here. + return; + } + } + + var oldStatus = event.status; + var oldEventId = event.getId(); + + if (!oldStatus) { + throw new Error("updatePendingEventStatus called on an event which is " + + "not a local echo."); + } + + var allowed = ALLOWED_TRANSITIONS[oldStatus]; + if (!allowed || allowed.indexOf(newStatus) < 0) { + throw new Error("Invalid EventStatus transition " + oldStatus + "->" + + newStatus); + } + + event.status = newStatus; + + if (newStatus == EventStatus.SENT) { + // update the event id + event.event.event_id = newEventId; + + // if the event was already in the timeline (which will be the case if + // opts.pendingEventOrdering==chronological), we need to update the + // timeline map. + var existingTimeline = this._eventIdToTimeline[oldEventId]; + if (existingTimeline) { + delete this._eventIdToTimeline[oldEventId]; + this._eventIdToTimeline[newEventId] = existingTimeline; + } + } + else if (newStatus == EventStatus.CANCELLED) { + // remove it from the pending event list, or the timeline. + if (this._pendingEventList) { + utils.removeElement( + this._pendingEventList, + function(ev) { return ev.getId() == oldEventId; }, + false + ); + } + this.removeEvent(oldEventId); + } + + this.emit("Room.localEchoUpdated", event, this, event.getId(), oldStatus); +}; + + +/** + * Add some events to this room. This can include state events, message + * events and typing notifications. These events are treated as "live" so + * they will go to the end of the timeline. + * + * @param {MatrixEvent[]} events A list of events to add. + * + * @param {string} duplicateStrategy Optional. Applies to events in the + * timeline only. If this is 'replace' then if a duplicate is encountered, the + * event passed to this function will replace the existing event in the + * timeline. If this is not specified, or is 'ignore', then the event passed to + * this function will be ignored entirely, preserving the existing event in the + * timeline. Events are identical based on their event ID only. + * + * @throws If duplicateStrategy is not falsey, 'replace' or 'ignore'. + */ +Room.prototype.addLiveEvents = function(events, duplicateStrategy) { + if (duplicateStrategy && ["replace", "ignore"].indexOf(duplicateStrategy) === -1) { + throw new Error("duplicateStrategy MUST be either 'replace' or 'ignore'"); + } + + // sanity check that the live timeline is still live + if (this._liveTimeline.getPaginationToken(EventTimeline.FORWARDS)) { + throw new Error( + "live timeline is no longer live - it has a pagination token (" + + this._liveTimeline.getPaginationToken(EventTimeline.FORWARDS) + ")" + ); + } + if (this._liveTimeline.getNeighbouringTimeline(EventTimeline.FORWARDS)) { + throw new Error( + "live timeline is no longer live - it has a neighbouring timeline" + ); + } + + for (var i = 0; i < events.length; i++) { + if (events[i].getType() === "m.typing") { + this.currentState.setTypingEvent(events[i]); + } + else if (events[i].getType() === "m.receipt") { + this.addReceipt(events[i]); + } + // N.B. account_data is added directly by /sync to avoid + // having to maintain an event.isAccountData() here + else { + // TODO: We should have a filter to say "only add state event + // types X Y Z to the timeline". + this._addLiveEvent(events[i], duplicateStrategy); + } + } +}; + +/** + * Removes events from this room. + * @param {String[]} event_ids A list of event_ids to remove. + */ +Room.prototype.removeEvents = function(event_ids) { + for (var i = 0; i < event_ids.length; ++i) { + this.removeEvent(event_ids[i]); + } +}; + +/** + * Removes a single event from this room. + * + * @param {String} eventId The id of the event to remove + * + * @return {?MatrixEvent} the removed event, or null if the event was not found + * in this room. + */ +Room.prototype.removeEvent = function(eventId) { + var timeline = this._eventIdToTimeline[eventId]; + if (!timeline) { + return null; + } + + var removed = timeline.removeEvent(eventId); + if (removed) { + delete this._eventIdToTimeline[eventId]; + var data = { + timeline: timeline, + }; + this.emit("Room.timeline", removed, this, undefined, true, data); + } + return removed; +}; + +/** + * Determine where two events appear in the timeline relative to one another + * + * @param {string} eventId1 The id of the first event + * @param {string} eventId2 The id of the second event + + * @return {?number} a number less than zero if eventId1 precedes eventId2, and + * greater than zero if eventId1 succeeds eventId2. zero if they are the + * same event; null if we can't tell (either because we don't know about one + * of the events, or because they are in separate timelines which don't join + * up). + */ +Room.prototype.compareEventOrdering = function(eventId1, eventId2) { + if (eventId1 == eventId2) { + // optimise this case + return 0; + } + + var timeline1 = this._eventIdToTimeline[eventId1]; + var timeline2 = this._eventIdToTimeline[eventId2]; + + if (timeline1 === undefined) { + return null; + } + if (timeline2 === undefined) { + return null; + } + + if (timeline1 === timeline2) { + // both events are in the same timeline - figure out their + // relative indices + var idx1, idx2; + var events = timeline1.getEvents(); + for (var idx = 0; idx < events.length && + (idx1 === undefined || idx2 === undefined); idx++) { + var evId = events[idx].getId(); + if (evId == eventId1) { + idx1 = idx; + } + if (evId == eventId2) { + idx2 = idx; + } + } + return idx1 - idx2; + } + + // the events are in different timelines. Iterate through the + // linkedlist to see which comes first. + + // first work forwards from timeline1 + var tl = timeline1; + while (tl) { + if (tl === timeline2) { + // timeline1 is before timeline2 + return -1; + } + tl = tl.getNeighbouringTimeline(EventTimeline.FORWARDS); + } + + // now try backwards from timeline1 + tl = timeline1; + while (tl) { + if (tl === timeline2) { + // timeline2 is before timeline1 + return 1; + } + tl = tl.getNeighbouringTimeline(EventTimeline.BACKWARDS); + } + + // the timelines are not contiguous. + return null; +}; + +/** + * Recalculate various aspects of the room, including the room name and + * room summary. Call this any time the room's current state is modified. + * May fire "Room.name" if the room name is updated. + * @param {string} userId The client's user ID. + * @fires module:client~MatrixClient#event:"Room.name" + */ +Room.prototype.recalculate = function(userId) { + // set fake stripped state events if this is an invite room so logic remains + // consistent elsewhere. + var self = this; + var membershipEvent = this.currentState.getStateEvents( + "m.room.member", userId + ); + if (membershipEvent && membershipEvent.getContent().membership === "invite") { + var strippedStateEvents = membershipEvent.event.invite_room_state || []; + utils.forEach(strippedStateEvents, function(strippedEvent) { + var existingEvent = self.currentState.getStateEvents( + strippedEvent.type, strippedEvent.state_key + ); + if (!existingEvent) { + // set the fake stripped event instead + self.currentState.setStateEvents([new MatrixEvent({ + type: strippedEvent.type, + state_key: strippedEvent.state_key, + content: strippedEvent.content, + event_id: "$fake" + Date.now(), + room_id: self.roomId, + user_id: userId // technically a lie + })]); + } + }); + } + + + + var oldName = this.name; + this.name = calculateRoomName(this, userId); + this.summary = new RoomSummary(this.roomId, { + title: this.name + }); + + if (oldName !== this.name) { + this.emit("Room.name", this); + } +}; + + +/** + * Get a list of user IDs who have read up to the given event. + * @param {MatrixEvent} event the event to get read receipts for. + * @return {String[]} A list of user IDs. + */ +Room.prototype.getUsersReadUpTo = function(event) { + return this.getReceiptsForEvent(event).filter(function(receipt) { + return receipt.type === "m.read"; + }).map(function(receipt) { + return receipt.userId; + }); +}; + +/** + * Get the ID of the event that a given user has read up to, or null if we + * have received no read receipts from them. + * @param {String} userId The user ID to get read receipt event ID for + * @param {Boolean} ignoreSynthesized If true, return only receipts that have been + * sent by the server, not implicit ones generated + * by the JS SDK. + * @return {String} ID of the latest event that the given user has read, or null. + */ +Room.prototype.getEventReadUpTo = function(userId, ignoreSynthesized) { + var receipts = this._receipts; + if (ignoreSynthesized) { + receipts = this._realReceipts; + } + + if ( + receipts["m.read"] === undefined || + receipts["m.read"][userId] === undefined + ) { + return null; + } + + return receipts["m.read"][userId].eventId; +}; + +/** + * Get a list of receipts for the given event. + * @param {MatrixEvent} event the event to get receipts for + * @return {Object[]} A list of receipts with a userId, type and data keys or + * an empty list. + */ +Room.prototype.getReceiptsForEvent = function(event) { + return this._receiptCacheByEventId[event.getId()] || []; +}; + +/** + * Add a receipt event to the room. + * @param {MatrixEvent} event The m.receipt event. + * @param {Boolean} fake True if this event is implicit + */ +Room.prototype.addReceipt = function(event, fake) { + // event content looks like: + // content: { + // $event_id: { + // $receipt_type: { + // $user_id: { + // ts: $timestamp + // } + // } + // } + // } + if (fake === undefined) { fake = false; } + if (!fake) { + this._addReceiptsToStructure(event, this._realReceipts); + // we don't bother caching real receipts by event ID + // as there's nothing that would read it. + } + this._addReceiptsToStructure(event, this._receipts); + this._receiptCacheByEventId = this._buildReciptCache(this._receipts); + + // send events after we've regenerated the cache, otherwise things that + // listened for the event would read from a stale cache + this.emit("Room.receipt", event, this); +}; + +/** + * Add a receipt event to the room. + * @param {MatrixEvent} event The m.receipt event. + * @param {Object} receipts The object to add receipts to + */ +Room.prototype._addReceiptsToStructure = function(event, receipts) { + var self = this; + utils.keys(event.getContent()).forEach(function(eventId) { + utils.keys(event.getContent()[eventId]).forEach(function(receiptType) { + utils.keys(event.getContent()[eventId][receiptType]).forEach( + function(userId) { + var receipt = event.getContent()[eventId][receiptType][userId]; + + if (!receipts[receiptType]) { + receipts[receiptType] = {}; + } + + var existingReceipt = receipts[receiptType][userId]; + + if (!existingReceipt) { + receipts[receiptType][userId] = {}; + } else { + // we only want to add this receipt if we think it is later + // than the one we already have. (This is managed + // server-side, but because we synthesize RRs locally we + // have to do it here too.) + var ordering = self.compareEventOrdering( + existingReceipt.eventId, eventId); + if (ordering !== null && ordering >= 0) { + return; + } + } + + receipts[receiptType][userId] = { + eventId: eventId, + data: receipt + }; + }); + }); + }); +}; + +/** + * Build and return a map of receipts by event ID + * @param {Object} receipts A map of receipts + * @return {Object} Map of receipts by event ID + */ +Room.prototype._buildReciptCache = function(receipts) { + var receiptCacheByEventId = {}; + utils.keys(receipts).forEach(function(receiptType) { + utils.keys(receipts[receiptType]).forEach(function(userId) { + var receipt = receipts[receiptType][userId]; + if (!receiptCacheByEventId[receipt.eventId]) { + receiptCacheByEventId[receipt.eventId] = []; + } + receiptCacheByEventId[receipt.eventId].push({ + userId: userId, + type: receiptType, + data: receipt.data + }); + }); + }); + return receiptCacheByEventId; +}; + + +/** + * Add a temporary local-echo receipt to the room to reflect in the + * client the fact that we've sent one. + * @param {string} userId The user ID if the receipt sender + * @param {MatrixEvent} e The event that is to be acknowledged + * @param {string} receiptType The type of receipt + */ +Room.prototype._addLocalEchoReceipt = function(userId, e, receiptType) { + this.addReceipt(synthesizeReceipt(userId, e, receiptType), true); +}; + +/** + * Update the room-tag event for the room. The previous one is overwritten. + * @param {MatrixEvent} event the m.tag event + */ +Room.prototype.addTags = function(event) { + // event content looks like: + // content: { + // tags: { + // $tagName: { $metadata: $value }, + // $tagName: { $metadata: $value }, + // } + // } + + // XXX: do we need to deep copy here? + this.tags = event.getContent().tags; + + // XXX: we could do a deep-comparison to see if the tags have really + // changed - but do we want to bother? + this.emit("Room.tags", event, this); +}; + +/** + * Update the account_data events for this room, overwriting events of the same type. + * @param {Array} events an array of account_data events to add + */ +Room.prototype.addAccountData = function(events) { + for (var i = 0; i < events.length; i++) { + var event = events[i]; + if (event.getType() === "m.tag") { + this.addTags(event); + } + this.accountData[event.getType()] = event; + this.emit("Room.accountData", event, this); + } +}; + +/** + * Access account_data event of given event type for this room + * @param {string} type the type of account_data event to be accessed + * @return {?MatrixEvent} the account_data event in question + */ +Room.prototype.getAccountData = function(type) { + return this.accountData[type]; +}; + +function setEventMetadata(event, stateContext, toStartOfTimeline) { + // set sender and target properties + event.sender = stateContext.getSentinelMember( + event.getSender() + ); + if (event.getType() === "m.room.member") { + event.target = stateContext.getSentinelMember( + event.getStateKey() + ); + } + if (event.isState()) { + // room state has no concept of 'old' or 'current', but we want the + // room state to regress back to previous values if toStartOfTimeline + // is set, which means inspecting prev_content if it exists. This + // is done by toggling the forwardLooking flag. + if (toStartOfTimeline) { + event.forwardLooking = false; + } + } +} + +/** + * This is an internal method. Calculates the name of the room from the current + * room state. + * @param {Room} room The matrix room. + * @param {string} userId The client's user ID. Used to filter room members + * correctly. + * @param {bool} ignoreRoomNameEvent Return the implicit room name that we'd see if there + * was no m.room.name event. + * @return {string} The calculated room name. + */ +function calculateRoomName(room, userId, ignoreRoomNameEvent) { + if (!ignoreRoomNameEvent) { + // check for an alias, if any. for now, assume first alias is the + // official one. + var mRoomName = room.currentState.getStateEvents("m.room.name", ""); + if (mRoomName && mRoomName.getContent() && mRoomName.getContent().name) { + return mRoomName.getContent().name; + } + } + + var alias = room.getCanonicalAlias(); + + if (!alias) { + var aliases = room.getAliases(); + + if (aliases.length) { + alias = aliases[0]; + } + } + if (alias) { + return alias; + } + + // get members that are NOT ourselves and are actually in the room. + var otherMembers = utils.filter(room.currentState.getMembers(), function(m) { + return (m.userId !== userId && m.membership !== "leave"); + }); + var allMembers = utils.filter(room.currentState.getMembers(), function(m) { + return (m.membership !== "leave"); + }); + var myMemberEventArray = utils.filter(room.currentState.getMembers(), function(m) { + return (m.userId == userId); + }); + var myMemberEvent = ( + (myMemberEventArray.length && myMemberEventArray[0].events) ? + myMemberEventArray[0].events.member.event : undefined + ); + + // TODO: Localisation + if (myMemberEvent && myMemberEvent.content.membership == "invite") { + if (room.currentState.getMember(myMemberEvent.sender)) { + // extract who invited us to the room + return "Invite from " + room.currentState.getMember( + myMemberEvent.sender + ).name; + } else if (allMembers[0].events.member) { + // use the sender field from the invite event, although this only + // gets us the mxid + return "Invite from " + myMemberEvent.sender; + } else { + return "Room Invite"; + } + } + + + if (otherMembers.length === 0) { + if (allMembers.length === 1) { + // self-chat, peeked room with 1 participant, + // or inbound invite, or outbound 3PID invite. + if (allMembers[0].userId === userId) { + var thirdPartyInvites = + room.currentState.getStateEvents("m.room.third_party_invite"); + if (thirdPartyInvites && thirdPartyInvites.length > 0) { + var name = "Inviting " + + thirdPartyInvites[0].getContent().display_name; + if (thirdPartyInvites.length > 1) { + if (thirdPartyInvites.length == 2) { + name += " and " + + thirdPartyInvites[1].getContent().display_name; + } + else { + name += " and " + + thirdPartyInvites.length + " others"; + } + } + return name; + } + else { + return "Empty room"; + } + } + else { + return allMembers[0].name; + } + } + else { + // there really isn't anyone in this room... + return "Empty room"; + } + } + else if (otherMembers.length === 1) { + return otherMembers[0].name; + } + else if (otherMembers.length === 2) { + return ( + otherMembers[0].name + " and " + otherMembers[1].name + ); + } + else { + return ( + otherMembers[0].name + " and " + (otherMembers.length - 1) + " others" + ); + } +} + +/** + * The Room class. + */ +module.exports = Room; + +/** + * Fires whenever the timeline in a room is updated. + * @event module:client~MatrixClient#"Room.timeline" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {Room} room The room whose Room.timeline was updated. + * @param {boolean} toStartOfTimeline True if this event was added to the start + * @param {boolean} removed True if this event has just been removed from the timeline + * (beginning; oldest) of the timeline e.g. due to pagination. + * + * @param {object} data more data about the event + * + * @param {module:event-timeline.EventTimeline} data.timeline the timeline the + * event was added to/removed from + * + * @param {boolean} data.liveEvent true if the event was a real-time event + * added to the end of the live timeline + * + * @example + * matrixClient.on("Room.timeline", function(event, room, toStartOfTimeline, data){ + * if (!toStartOfTimeline && data.liveEvent) { + * var messageToAppend = room.timeline.[room.timeline.length - 1]; + * } + * }); + */ + +/** + * Fires whenever the live timeline in a room is reset. + * + * When we get a 'limited' sync (for example, after a network outage), we reset + * the live timeline to be empty before adding the recent events to the new + * timeline. This event is fired after the timeline is reset, and before the + * new events are added. + * + * @event module:client~MatrixClient#"Room.timelineReset" + * @param {Room} room The room whose live timeline was reset. + */ + +/** + * Fires when an event we had previously received is redacted. + * + * (Note this is *not* fired when the redaction happens before we receive the + * event). + * + * @event module:client~MatrixClient#"Room.redaction" + * @param {MatrixEvent} event The matrix event which was redacted + * @param {Room} room The room containing the redacted event + */ + +/** + * Fires whenever the name of a room is updated. + * @event module:client~MatrixClient#"Room.name" + * @param {Room} room The room whose Room.name was updated. + * @example + * matrixClient.on("Room.name", function(room){ + * var newName = room.name; + * }); + */ + +/** + * Fires whenever a receipt is received for a room + * @event module:client~MatrixClient#"Room.receipt" + * @param {event} event The receipt event + * @param {Room} room The room whose receipts was updated. + * @example + * matrixClient.on("Room.receipt", function(event, room){ + * var receiptContent = event.getContent(); + * }); + */ + +/** + * Fires whenever a room's tags are updated. + * @event module:client~MatrixClient#"Room.tags" + * @param {event} event The tags event + * @param {Room} room The room whose Room.tags was updated. + * @example + * matrixClient.on("Room.tags", function(event, room){ + * var newTags = event.getContent().tags; + * if (newTags["favourite"]) showStar(room); + * }); + */ + +/** + * Fires whenever a room's account_data is updated. + * @event module:client~MatrixClient#"Room.accountData" + * @param {event} event The account_data event + * @param {Room} room The room whose account_data was updated. + * @example + * matrixClient.on("Room.accountData", function(event, room){ + * if (event.getType() === "m.room.colorscheme") { + * applyColorScheme(event.getContents()); + * } + * }); + */ + +/** + * Fires when the status of a transmitted event is updated. + * + *

When an event is first transmitted, a temporary copy of the event is + * inserted into the timeline, with a temporary event id, and a status of + * 'SENDING'. + * + *

Once the echo comes back from the server, the content of the event + * (MatrixEvent.event) is replaced by the complete event from the homeserver, + * thus updating its event id, as well as server-generated fields such as the + * timestamp. Its status is set to null. + * + *

Once the /send request completes, if the remote echo has not already + * arrived, the event is updated with a new event id and the status is set to + * 'SENT'. The server-generated fields are of course not updated yet. + * + *

If the /send fails, In this case, the event's status is set to + * 'NOT_SENT'. If it is later resent, the process starts again, setting the + * status to 'SENDING'. Alternatively, the message may be cancelled, which + * removes the event from the room, and sets the status to 'CANCELLED'. + * + *

This event is raised to reflect each of the transitions above. + * + * @event module:client~MatrixClient#"Room.localEchoUpdated" + * + * @param {MatrixEvent} event The matrix event which has been updated + * + * @param {Room} room The room containing the redacted event + * + * @param {string} oldEventId The previous event id (the temporary event id, + * except when updating a successfully-sent event when its echo arrives) + * + * @param {EventStatus} oldStatus The previous event status. + */ + +},{"../content-repo":5,"../utils":28,"./event":12,"./event-timeline":11,"./room-summary":15,"events":179}],17:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/** + * @module models/search-result + */ + +var EventContext = require("./event-context"); +var utils = require("../utils"); + +/** + * Construct a new SearchResult + * + * @param {number} rank where this SearchResult ranks in the results + * @param {event-context.EventContext} eventContext the matching event and its + * context + * + * @constructor + */ +function SearchResult(rank, eventContext) { + this.rank = rank; + this.context = eventContext; +} + +/** + * Create a SearchResponse from the response to /search + * @static + * @param {Object} jsonObj + * @param {function} eventMapper + * @return {SearchResult} + */ + +SearchResult.fromJson = function(jsonObj, eventMapper) { + var jsonContext = jsonObj.context || {}; + var events_before = jsonContext.events_before || []; + var events_after = jsonContext.events_after || []; + + var context = new EventContext(eventMapper(jsonObj.result)); + + context.setPaginateToken(jsonContext.start, true); + context.addEvents(utils.map(events_before, eventMapper), true); + context.addEvents(utils.map(events_after, eventMapper), false); + context.setPaginateToken(jsonContext.end, false); + + return new SearchResult(jsonObj.rank, context); +}; + + +/** + * The SearchResult class + */ +module.exports = SearchResult; + +},{"../utils":28,"./event-context":10}],18:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * @module models/user + */ + var EventEmitter = require("events").EventEmitter; + var utils = require("../utils"); + +/** + * Construct a new User. A User must have an ID and can optionally have extra + * information associated with it. + * @constructor + * @param {string} userId Required. The ID of this user. + * @prop {string} userId The ID of the user. + * @prop {Object} info The info object supplied in the constructor. + * @prop {string} displayName The 'displayname' of the user if known. + * @prop {string} avatarUrl The 'avatar_url' of the user if known. + * @prop {string} presence The presence enum if known. + * @prop {Number} lastActiveAgo The time elapsed in ms since the user interacted + * proactively with the server, or we saw a message from the user + * @prop {Number} lastPresenceTs Timestamp (ms since the epoch) for when we last + * received presence data for this user. We can subtract + * lastActiveAgo from this to approximate an absolute value for + * when a user was last active. + * @prop {Boolean} currentlyActive Whether we should consider lastActiveAgo to be + * an approximation and that the user should be seen as active 'now' + * @prop {Object} events The events describing this user. + * @prop {MatrixEvent} events.presence The m.presence event for this user. + */ +function User(userId) { + this.userId = userId; + this.presence = "offline"; + this.displayName = userId; + this.avatarUrl = null; + this.lastActiveAgo = 0; + this.lastPresenceTs = 0; + this.currentlyActive = false; + this.events = { + presence: null, + profile: null + }; + this._updateModifiedTime(); +} +utils.inherits(User, EventEmitter); + +/** + * Update this User with the given presence event. May fire "User.presence", + * "User.avatarUrl" and/or "User.displayName" if this event updates this user's + * properties. + * @param {MatrixEvent} event The m.presence event. + * @fires module:client~MatrixClient#event:"User.presence" + * @fires module:client~MatrixClient#event:"User.displayName" + * @fires module:client~MatrixClient#event:"User.avatarUrl" + */ +User.prototype.setPresenceEvent = function(event) { + if (event.getType() !== "m.presence") { + return; + } + var firstFire = this.events.presence === null; + this.events.presence = event; + + var eventsToFire = []; + if (event.getContent().presence !== this.presence || firstFire) { + eventsToFire.push("User.presence"); + } + if (event.getContent().avatar_url && + event.getContent().avatar_url !== this.avatarUrl) + { + eventsToFire.push("User.avatarUrl"); + } + if (event.getContent().displayname && + event.getContent().displayname !== this.displayName) + { + eventsToFire.push("User.displayName"); + } + if (event.getContent().currently_active !== undefined && + event.getContent().currently_active !== this.currentlyActive) + { + eventsToFire.push("User.currentlyActive"); + } + + this.presence = event.getContent().presence; + eventsToFire.push("User.lastPresenceTs"); + + if (event.getContent().displayname) { + this.displayName = event.getContent().displayname; + } + if (event.getContent().avatar_url) { + this.avatarUrl = event.getContent().avatar_url; + } + this.lastActiveAgo = event.getContent().last_active_ago; + this.lastPresenceTs = Date.now(); + this.currentlyActive = event.getContent().currently_active; + + this._updateModifiedTime(); + + for (var i = 0; i < eventsToFire.length; i++) { + this.emit(eventsToFire[i], event, this); + } +}; + +/** + * Manually set this user's display name. No event is emitted in response to this + * as there is no underlying MatrixEvent to emit with. + * @param {string} name The new display name. + */ +User.prototype.setDisplayName = function(name) { + var oldName = this.displayName; + this.displayName = name; + if (name !== oldName) { + this._updateModifiedTime(); + } +}; + +/** + * Manually set this user's avatar URL. No event is emitted in response to this + * as there is no underlying MatrixEvent to emit with. + * @param {string} url The new avatar URL. + */ +User.prototype.setAvatarUrl = function(url) { + var oldUrl = this.avatarUrl; + this.avatarUrl = url; + if (url !== oldUrl) { + this._updateModifiedTime(); + } +}; + +/** + * Update the last modified time to the current time. + */ +User.prototype._updateModifiedTime = function() { + this._modified = Date.now(); +}; + +/** + * Get the timestamp when this User was last updated. This timestamp is + * updated when this User receives a new Presence event which has updated a + * property on this object. It is updated before firing events. + * @return {number} The timestamp + */ +User.prototype.getLastModifiedTime = function() { + return this._modified; +}; + +/** + * Get the absolute timestamp when this User was last known active on the server. + * It is *NOT* accurate if this.currentlyActive is true. + * @return {number} The timestamp + */ +User.prototype.getLastActiveTs = function() { + return this.lastPresenceTs - this.lastActiveAgo; +}; + +/** + * The User class. + */ +module.exports = User; + +/** + * Fires whenever any user's lastPresenceTs changes, + * ie. whenever any presence event is received for a user. + * @event module:client~MatrixClient#"User.lastPresenceTs" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {User} user The user whose User.lastPresenceTs changed. + * @example + * matrixClient.on("User.lastPresenceTs", function(event, user){ + * var newlastPresenceTs = user.lastPresenceTs; + * }); + */ + +/** + * Fires whenever any user's presence changes. + * @event module:client~MatrixClient#"User.presence" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {User} user The user whose User.presence changed. + * @example + * matrixClient.on("User.presence", function(event, user){ + * var newPresence = user.presence; + * }); + */ + +/** + * Fires whenever any user's currentlyActive changes. + * @event module:client~MatrixClient#"User.currentlyActive" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {User} user The user whose User.currentlyActive changed. + * @example + * matrixClient.on("User.currentlyActive", function(event, user){ + * var newCurrentlyActive = user.currentlyActive; + * }); + */ + +/** + * Fires whenever any user's display name changes. + * @event module:client~MatrixClient#"User.displayName" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {User} user The user whose User.displayName changed. + * @example + * matrixClient.on("User.displayName", function(event, user){ + * var newName = user.displayName; + * }); + */ + +/** + * Fires whenever any user's avatar URL changes. + * @event module:client~MatrixClient#"User.avatarUrl" + * @param {MatrixEvent} event The matrix event which caused this event to fire. + * @param {User} user The user whose User.avatarUrl changed. + * @example + * matrixClient.on("User.avatarUrl", function(event, user){ + * var newUrl = user.avatarUrl; + * }); + */ + +},{"../utils":28,"events":179}],19:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/** + * @module pushprocessor + */ + +/** + * Construct a Push Processor. + * @constructor + * @param {Object} client The Matrix client object to use + */ +function PushProcessor(client) { + var escapeRegExp = function(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + }; + + var matchingRuleFromKindSet = function(ev, kindset, device) { + var rulekinds_in_order = ['override', 'content', 'room', 'sender', 'underride']; + for (var ruleKindIndex = 0; + ruleKindIndex < rulekinds_in_order.length; + ++ruleKindIndex) { + var kind = rulekinds_in_order[ruleKindIndex]; + var ruleset = kindset[kind]; + + for (var ruleIndex = 0; ruleIndex < ruleset.length; ++ruleIndex) { + var rule = ruleset[ruleIndex]; + if (!rule.enabled) { continue; } + + var rawrule = templateRuleToRaw(kind, rule, device); + if (!rawrule) { continue; } + + if (ruleMatchesEvent(rawrule, ev)) { + rule.kind = kind; + return rule; + } + } + } + return null; + }; + + var templateRuleToRaw = function(kind, tprule, device) { + var rawrule = { + 'rule_id': tprule.rule_id, + 'actions': tprule.actions, + 'conditions': [] + }; + switch (kind) { + case 'underride': + case 'override': + rawrule.conditions = tprule.conditions; + break; + case 'room': + if (!tprule.rule_id) { return null; } + rawrule.conditions.push({ + 'kind': 'event_match', + 'key': 'room_id', + 'pattern': tprule.rule_id + }); + break; + case 'sender': + if (!tprule.rule_id) { return null; } + rawrule.conditions.push({ + 'kind': 'event_match', + 'key': 'user_id', + 'pattern': tprule.rule_id + }); + break; + case 'content': + if (!tprule.pattern) { return null; } + rawrule.conditions.push({ + 'kind': 'event_match', + 'key': 'content.body', + 'pattern': tprule.pattern + }); + break; + } + if (device) { + rawrule.conditions.push({ + 'kind': 'device', + 'profile_tag': device + }); + } + return rawrule; + }; + + var ruleMatchesEvent = function(rule, ev) { + var ret = true; + for (var i = 0; i < rule.conditions.length; ++i) { + var cond = rule.conditions[i]; + ret &= eventFulfillsCondition(cond, ev); + } + //console.log("Rule "+rule.rule_id+(ret ? " matches" : " doesn't match")); + return ret; + }; + + var eventFulfillsCondition = function(cond, ev) { + var condition_functions = { + "event_match": eventFulfillsEventMatchCondition, + "device": eventFulfillsDeviceCondition, + "contains_display_name": eventFulfillsDisplayNameCondition, + "room_member_count": eventFulfillsRoomMemberCountCondition + }; + if (condition_functions[cond.kind]) { + return condition_functions[cond.kind](cond, ev); + } + return true; + }; + + var eventFulfillsRoomMemberCountCondition = function(cond, ev) { + if (!cond.is) { return false; } + + var room = client.getRoom(ev.getRoomId()); + if (!room || !room.currentState || !room.currentState.members) { return false; } + + var memberCount = Object.keys(room.currentState.members).filter(function(m) { + return room.currentState.members[m].membership == 'join'; + }).length; + + var m = cond.is.match(/^([=<>]*)([0-9]*)$/); + if (!m) { return false; } + var ineq = m[1]; + var rhs = parseInt(m[2]); + if (isNaN(rhs)) { return false; } + switch (ineq) { + case '': + case '==': + return memberCount == rhs; + case '<': + return memberCount < rhs; + case '>': + return memberCount > rhs; + case '<=': + return memberCount <= rhs; + case '>=': + return memberCount >= rhs; + default: + return false; + } + }; + + var eventFulfillsDisplayNameCondition = function(cond, ev) { + var content = ev.getContent(); + if (!content || !content.body || typeof content.body != 'string') { + return false; + } + + var room = client.getRoom(ev.getRoomId()); + if (!room || !room.currentState || !room.currentState.members || + !room.currentState.getMember(client.credentials.userId)) { return false; } + + var displayName = room.currentState.getMember(client.credentials.userId).name; + + // N.B. we can't use \b as it chokes on unicode. however \W seems to be okay + // as shorthand for [^0-9A-Za-z_]. + var pat = new RegExp("(^|\\W)" + escapeRegExp(displayName) + "(\\W|$)", 'i'); + return content.body.search(pat) > -1; + }; + + var eventFulfillsDeviceCondition = function(cond, ev) { + return false; // XXX: Allow a profile tag to be set for the web client instance + }; + + var eventFulfillsEventMatchCondition = function(cond, ev) { + var val = valueForDottedKey(cond.key, ev); + if (!val || typeof val != 'string') { return false; } + + var pat; + if (cond.key == 'content.body') { + pat = '(^|\\W)' + globToRegexp(cond.pattern) + '(\\W|$)'; + } else { + pat = '^' + globToRegexp(cond.pattern) + '$'; + } + var regex = new RegExp(pat, 'i'); + return !!val.match(regex); + }; + + var globToRegexp = function(glob) { + // From + // https://github.com/matrix-org/synapse/blob/abbee6b29be80a77e05730707602f3bbfc3f38cb/synapse/push/__init__.py#L132 + // Because micromatch is about 130KB with dependencies, + // and minimatch is not much better. + var pat = escapeRegExp(glob); + pat = pat.replace(/\\\*/, '.*'); + pat = pat.replace(/\?/, '.'); + pat = pat.replace(/\\\[(!|)(.*)\\]/, function(match, p1, p2, offset, string) { + var first = p1 && '^' || ''; + var second = p2.replace(/\\\-/, '-'); + return '[' + first + second + ']'; + }); + return pat; + }; + + var valueForDottedKey = function(key, ev) { + var parts = key.split('.'); + var val; + + // special-case the first component to deal with encrypted messages + var firstPart = parts[0]; + if (firstPart == 'content') { + val = ev.getContent(); + parts.shift(); + } else if (firstPart == 'type') { + val = ev.getType(); + parts.shift(); + } else { + // use the raw event for any other fields + val = ev.event; + } + + while (parts.length > 0) { + var thispart = parts.shift(); + if (!val[thispart]) { return null; } + val = val[thispart]; + } + return val; + }; + + var matchingRuleForEventWithRulesets = function(ev, rulesets) { + if (!rulesets || !rulesets.device) { return null; } + if (ev.getSender() == client.credentials.userId) { return null; } + + var allDevNames = Object.keys(rulesets.device); + for (var i = 0; i < allDevNames.length; ++i) { + var devname = allDevNames[i]; + var devrules = rulesets.device[devname]; + + var matchingRule = matchingRuleFromKindSet(devrules, devname); + if (matchingRule) { return matchingRule; } + } + return matchingRuleFromKindSet(ev, rulesets.global); + }; + + var actionListToActionsObject = function(actionlist) { + var actionobj = { 'notify': false, 'tweaks': {} }; + for (var i = 0; i < actionlist.length; ++i) { + var action = actionlist[i]; + if (action === 'notify') { + actionobj.notify = true; + } else if (typeof action === 'object') { + if (action.value === undefined) { action.value = true; } + actionobj.tweaks[action.set_tweak] = action.value; + } + } + return actionobj; + }; + + var pushActionsForEventAndRulesets = function(ev, rulesets) { + var rule = matchingRuleForEventWithRulesets(ev, rulesets); + if (!rule) { return {}; } + + var actionObj = actionListToActionsObject(rule.actions); + + // Some actions are implicit in some situations: we add those here + if (actionObj.tweaks.highlight === undefined) { + // if it isn't specified, highlight if it's a content + // rule but otherwise not + actionObj.tweaks.highlight = (rule.kind == 'content'); + } + + return actionObj; + }; + + /** + * Get the user's push actions for the given event + * + * @param {module:models/event.MatrixEvent} ev + * + * @return {PushAction} + */ + this.actionsForEvent = function(ev) { + return pushActionsForEventAndRulesets(ev, client.pushRules); + }; +} + +/** + * @typedef {Object} PushAction + * @type {Object} + * @property {boolean} notify Whether this event should notify the user or not. + * @property {Object} tweaks How this event should be notified. + * @property {boolean} tweaks.highlight Whether this event should be highlighted + * on the UI. + * @property {boolean} tweaks.sound Whether this notification should produce a + * noise. + */ + +/** The PushProcessor class. */ +module.exports = PushProcessor; + +},{}],20:[function(require,module,exports){ +(function (global){ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* A re-implementation of the javascript callback functions (setTimeout, + * clearTimeout; setInterval and clearInterval are not yet implemented) which + * try to improve handling of large clock jumps (as seen when + * suspending/resuming the system). + * + * In particular, if a timeout would have fired while the system was suspended, + * it will instead fire as soon as possible after resume. + */ + +"use strict"; + +// we schedule a callback at least this often, to check if we've missed out on +// some wall-clock time due to being suspended. +var TIMER_CHECK_PERIOD_MS = 1000; + +// counter, for making up ids to return from setTimeout +var _count = 0; + +// the key for our callback with the real global.setTimeout +var _realCallbackKey; + +// a sorted list of the callbacks to be run. +// each is an object with keys [runAt, func, params, key]. +var _callbackList = []; + +// var debuglog = console.log.bind(console); +var debuglog = function() {}; + +/** + * Replace the function used by this module to get the current time. + * + * Intended for use by the unit tests. + * + * @param {function} f function which should return a millisecond counter + * + * @internal + */ +module.exports.setNow = function(f) { + _now = f || Date.now; +}; +var _now = Date.now; + +/** + * reimplementation of window.setTimeout, which will call the callback if + * the wallclock time goes past the deadline. + * + * @param {function} func callback to be called after a delay + * @param {Number} delayMs number of milliseconds to delay by + * + * @return {Number} an identifier for this callback, which may be passed into + * clearTimeout later. + */ +module.exports.setTimeout = function(func, delayMs) { + delayMs = delayMs || 0; + if (delayMs < 0) { + delayMs = 0; + } + + var params = Array.prototype.slice.call(arguments, 2); + var runAt = _now() + delayMs; + var key = _count++; + debuglog("setTimeout: scheduling cb", key, "at", runAt, + "(delay", delayMs, ")"); + var data = { + runAt: runAt, + func: func, + params: params, + key: key, + }; + + // figure out where it goes in the list + var idx = binarySearch( + _callbackList, function(el) { + return el.runAt - runAt; + } + ); + + _callbackList.splice(idx, 0, data); + _scheduleRealCallback(); + + return key; +}; + +/** + * reimplementation of window.clearTimeout, which mirrors setTimeout + * + * @param {Number} key result from an earlier setTimeout call + */ +module.exports.clearTimeout = function(key) { + if (_callbackList.length === 0) { + return; + } + + // remove the element from the list + var i; + for (i = 0; i < _callbackList.length; i++) { + var cb = _callbackList[i]; + if (cb.key == key) { + _callbackList.splice(i, 1); + break; + } + } + + // iff it was the first one in the list, reschedule our callback. + if (i === 0) { + _scheduleRealCallback(); + } +}; + +// use the real global.setTimeout to schedule a callback to _runCallbacks. +function _scheduleRealCallback() { + if (_realCallbackKey) { + global.clearTimeout(_realCallbackKey); + } + + var first = _callbackList[0]; + + if (!first) { + debuglog("_scheduleRealCallback: no more callbacks, not rescheduling"); + return; + } + + var now = _now(); + var delayMs = Math.min(first.runAt - now, TIMER_CHECK_PERIOD_MS); + + debuglog("_scheduleRealCallback: now:", now, "delay:", delayMs); + _realCallbackKey = global.setTimeout(_runCallbacks, delayMs); +} + +function _runCallbacks() { + var cb; + var now = _now(); + debuglog("_runCallbacks: now:", now); + + // get the list of things to call + var callbacksToRun = []; + while (true) { + var first = _callbackList[0]; + if (!first || first.runAt > now) { + break; + } + cb = _callbackList.shift(); + debuglog("_runCallbacks: popping", cb.key); + callbacksToRun.push(cb); + } + + // reschedule the real callback before running our functions, to + // keep the codepaths the same whether or not our functions + // register their own setTimeouts. + _scheduleRealCallback(); + + for (var i = 0; i < callbacksToRun.length; i++) { + cb = callbacksToRun[i]; + try { + cb.func.apply(null, cb.params); + } catch (e) { + console.error("Uncaught exception in callback function", + e.stack || e); + } + } +} + + +/* search in a sorted array. + * + * returns the index of the last element for which func returns + * greater than zero, or array.length if no such element exists. + */ +function binarySearch(array, func) { + // min is inclusive, max exclusive. + var min = 0, + max = array.length; + + while (min < max) { + var mid = (min + max) >> 1; + var res = func(array[mid]); + if (res > 0) { + // the element at 'mid' is too big; set it as the new max. + max = mid; + } else { + // the element at 'mid' is too small. 'min' is inclusive, so +1. + min = mid + 1; + } + } + // presumably, min==max now. + return min; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],21:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * This is an internal module which manages queuing, scheduling and retrying + * of requests. + * @module scheduler + */ +var utils = require("./utils"); +var q = require("q"); + +var DEBUG = false; // set true to enable console logging. + +/** + * Construct a scheduler for Matrix. Requires + * {@link module:scheduler~MatrixScheduler#setProcessFunction} to be provided + * with a way of processing events. + * @constructor + * @param {module:scheduler~retryAlgorithm} retryAlgorithm Optional. The retry + * algorithm to apply when determining when to try to send an event again. + * Defaults to {@link module:scheduler~MatrixScheduler.RETRY_BACKOFF_RATELIMIT}. + * @param {module:scheduler~queueAlgorithm} queueAlgorithm Optional. The queuing + * algorithm to apply when determining which events should be sent before the + * given event. Defaults to {@link module:scheduler~MatrixScheduler.QUEUE_MESSAGES}. + */ +function MatrixScheduler(retryAlgorithm, queueAlgorithm) { + this.retryAlgorithm = retryAlgorithm || MatrixScheduler.RETRY_BACKOFF_RATELIMIT; + this.queueAlgorithm = queueAlgorithm || MatrixScheduler.QUEUE_MESSAGES; + this._queues = { + // queueName: [{ + // event: MatrixEvent, // event to send + // defer: Deferred, // defer to resolve/reject at the END of the retries + // attempts: Number // number of times we've called processFn + // }, ...] + }; + this._activeQueues = []; + this._procFn = null; +} + +/** + * Retrieve a queue based on an event. The event provided does not need to be in + * the queue. + * @param {MatrixEvent} event An event to get the queue for. + * @return {?Array} A shallow copy of events in the queue or null. + * Modifying this array will not modify the list itself. Modifying events in + * this array will modify the underlying event in the queue. + * @see MatrixScheduler.removeEventFromQueue To remove an event from the queue. + */ +MatrixScheduler.prototype.getQueueForEvent = function(event) { + var name = this.queueAlgorithm(event); + if (!name || !this._queues[name]) { + return null; + } + return utils.map(this._queues[name], function(obj) { + return obj.event; + }); +}; + +/** + * Remove this event from the queue. The event is equal to another event if they + * have the same ID returned from event.getId(). + * @param {MatrixEvent} event The event to remove. + * @return {boolean} True if this event was removed. + */ +MatrixScheduler.prototype.removeEventFromQueue = function(event) { + var name = this.queueAlgorithm(event); + if (!name || !this._queues[name]) { + return false; + } + var removed = false; + utils.removeElement(this._queues[name], function(element) { + if (element.event.getId() === event.getId()) { + removed = true; + return true; + } + }); + return removed; +}; + + +/** + * Set the process function. Required for events in the queue to be processed. + * If set after events have been added to the queue, this will immediately start + * processing them. + * @param {module:scheduler~processFn} fn The function that can process events + * in the queue. + */ +MatrixScheduler.prototype.setProcessFunction = function(fn) { + this._procFn = fn; + _startProcessingQueues(this); +}; + +/** + * Queue an event if it is required and start processing queues. + * @param {MatrixEvent} event The event that may be queued. + * @return {?Promise} A promise if the event was queued, which will be + * resolved or rejected in due time, else null. + */ +MatrixScheduler.prototype.queueEvent = function(event) { + var queueName = this.queueAlgorithm(event); + if (!queueName) { + return null; + } + // add the event to the queue and make a deferred for it. + if (!this._queues[queueName]) { + this._queues[queueName] = []; + } + var defer = q.defer(); + this._queues[queueName].push({ + event: event, + defer: defer, + attempts: 0 + }); + debuglog( + "Queue algorithm dumped event %s into queue '%s'", + event.getId(), queueName + ); + _startProcessingQueues(this); + return defer.promise; +}; + +/** + * Retries events up to 4 times using exponential backoff. This produces wait + * times of 2, 4, 8, and 16 seconds (30s total) after which we give up. If the + * failure was due to a rate limited request, the time specified in the error is + * waited before being retried. + * @param {MatrixEvent} event + * @param {Number} attempts + * @param {MatrixError} err + * @return {Number} + * @see module:scheduler~retryAlgorithm + */ +MatrixScheduler.RETRY_BACKOFF_RATELIMIT = function(event, attempts, err) { + if (err.httpStatus === 400 || err.httpStatus === 403 || err.httpStatus === 401) { + // client error; no amount of retrying with save you now. + return -1; + } + // we ship with browser-request which returns { cors: rejected } when trying + // with no connection, so if we match that, give up since they have no conn. + if (err.cors === "rejected") { + return -1; + } + + if (err.name === "M_LIMIT_EXCEEDED") { + var waitTime = err.data.retry_after_ms; + if (waitTime) { + return waitTime; + } + } + if (attempts > 4) { + return -1; // give up + } + return (1000 * Math.pow(2, attempts)); +}; + +/** + * Queues m.room.message events and lets other events continue + * concurrently. + * @param {MatrixEvent} event + * @return {string} + * @see module:scheduler~queueAlgorithm + */ +MatrixScheduler.QUEUE_MESSAGES = function(event) { + if (event.getType() === "m.room.message") { + // put these events in the 'message' queue. + return "message"; + } + // allow all other events continue concurrently. + return null; +}; + +function _startProcessingQueues(scheduler) { + if (!scheduler._procFn) { + return; + } + // for each inactive queue with events in them + utils.forEach(utils.filter(utils.keys(scheduler._queues), function(queueName) { + return scheduler._activeQueues.indexOf(queueName) === -1 && + scheduler._queues[queueName].length > 0; + }), function(queueName) { + // mark the queue as active + scheduler._activeQueues.push(queueName); + // begin processing the head of the queue + debuglog("Spinning up queue: '%s'", queueName); + _processQueue(scheduler, queueName); + }); +} + +function _processQueue(scheduler, queueName) { + // get head of queue + var obj = _peekNextEvent(scheduler, queueName); + if (!obj) { + // queue is empty. Mark as inactive and stop recursing. + var index = scheduler._activeQueues.indexOf(queueName); + if (index >= 0) { + scheduler._activeQueues.splice(index, 1); + } + debuglog("Stopping queue '%s' as it is now empty", queueName); + return; + } + debuglog( + "Queue '%s' has %s pending events", + queueName, scheduler._queues[queueName].length + ); + // fire the process function and if it resolves, resolve the deferred. Else + // invoke the retry algorithm. + scheduler._procFn(obj.event).done(function(res) { + // remove this from the queue + _removeNextEvent(scheduler, queueName); + debuglog("Queue '%s' sent event %s", queueName, obj.event.getId()); + obj.defer.resolve(res); + // keep processing + _processQueue(scheduler, queueName); + }, function(err) { + obj.attempts += 1; + // ask the retry algorithm when/if we should try again + var waitTimeMs = scheduler.retryAlgorithm(obj.event, obj.attempts, err); + debuglog( + "retry(%s) err=%s event_id=%s waitTime=%s", + obj.attempts, err, obj.event.getId(), waitTimeMs + ); + if (waitTimeMs === -1) { // give up (you quitter!) + debuglog( + "Queue '%s' giving up on event %s", queueName, obj.event.getId() + ); + // remove this from the queue + _removeNextEvent(scheduler, queueName); + obj.defer.reject(err); + // process next event + _processQueue(scheduler, queueName); + } + else { + setTimeout(function() { + _processQueue(scheduler, queueName); + }, waitTimeMs); + } + }); +} + +function _peekNextEvent(scheduler, queueName) { + var queue = scheduler._queues[queueName]; + if (!utils.isArray(queue)) { + return null; + } + return queue[0]; +} + +function _removeNextEvent(scheduler, queueName) { + var queue = scheduler._queues[queueName]; + if (!utils.isArray(queue)) { + return null; + } + return queue.shift(); +} + +function debuglog() { + if (DEBUG) { + console.log.apply(console, arguments); + } +} + +/** + * The retry algorithm to apply when retrying events. To stop retrying, return + * -1. If this event was part of a queue, it will be removed from + * the queue. + * @callback retryAlgorithm + * @param {MatrixEvent} event The event being retried. + * @param {Number} attempts The number of failed attempts. This will always be + * >= 1. + * @param {MatrixError} err The most recent error message received when trying + * to send this event. + * @return {Number} The number of milliseconds to wait before trying again. If + * this is 0, the request will be immediately retried. If this is + * -1, the event will be marked as + * {@link module:models/event.EventStatus.NOT_SENT} and will not be retried. + */ + +/** + * The queuing algorithm to apply to events. This function must be idempotent as + * it may be called multiple times with the same event. All queues created are + * serviced in a FIFO manner. To send the event ASAP, return null + * which will not put this event in a queue. Events that fail to send that form + * part of a queue will be removed from the queue and the next event in the + * queue will be sent. + * @callback queueAlgorithm + * @param {MatrixEvent} event The event to be sent. + * @return {string} The name of the queue to put the event into. If a queue with + * this name does not exist, it will be created. If this is null, + * the event is not put into a queue and will be sent concurrently. + */ + + /** + * The function to invoke to process (send) events in the queue. + * @callback processFn + * @param {MatrixEvent} event The event to send. + * @return {Promise} Resolved/rejected depending on the outcome of the request. + */ + +/** + * The MatrixScheduler class. + */ +module.exports = MatrixScheduler; + +},{"./utils":28,"q":205}],22:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * This is an internal module. See {@link MatrixInMemoryStore} for the public class. + * @module store/memory + */ + var utils = require("../utils"); + var User = require("../models/user"); + +/** + * Construct a new in-memory data store for the Matrix Client. + * @constructor + * @param {Object=} opts Config options + * @param {LocalStorage} opts.localStorage The local storage instance to persist + * some forms of data such as tokens. Rooms will NOT be stored. See + * {@link WebStorageStore} to persist rooms. + */ +module.exports.MatrixInMemoryStore = function MatrixInMemoryStore(opts) { + opts = opts || {}; + this.rooms = { + // roomId: Room + }; + this.users = { + // userId: User + }; + this.syncToken = null; + this.filters = { + // userId: { + // filterId: Filter + // } + }; + this.accountData = { + // type : content + }; + this.localStorage = opts.localStorage; +}; + +module.exports.MatrixInMemoryStore.prototype = { + + /** + * Retrieve the token to stream from. + * @return {string} The token or null. + */ + getSyncToken: function() { + return this.syncToken; + }, + + + /** + * Set the token to stream from. + * @param {string} token The token to stream from. + */ + setSyncToken: function(token) { + this.syncToken = token; + }, + + /** + * Store the given room. + * @param {Room} room The room to be stored. All properties must be stored. + */ + storeRoom: function(room) { + this.rooms[room.roomId] = room; + // add listeners for room member changes so we can keep the room member + // map up-to-date. + room.currentState.on("RoomState.members", this._onRoomMember.bind(this)); + // add existing members + var self = this; + room.currentState.getMembers().forEach(function(m) { + self._onRoomMember(null, room.currentState, m); + }); + }, + + /** + * Called when a room member in a room being tracked by this store has been + * updated. + * @param {MatrixEvent} event + * @param {RoomState} state + * @param {RoomMember} member + */ + _onRoomMember: function(event, state, member) { + if (member.membership === "invite") { + // We do NOT add invited members because people love to typo user IDs + // which would then show up in these lists (!) + return; + } + + var user = this.users[member.userId] || new User(member.userId); + if (member.name) { + user.setDisplayName(member.name); + } + if (member.events.member && member.events.member.getContent().avatar_url) { + user.setAvatarUrl(member.events.member.getContent().avatar_url); + } + this.users[user.userId] = user; + }, + + /** + * Retrieve a room by its' room ID. + * @param {string} roomId The room ID. + * @return {Room} The room or null. + */ + getRoom: function(roomId) { + return this.rooms[roomId] || null; + }, + + /** + * Retrieve all known rooms. + * @return {Room[]} A list of rooms, which may be empty. + */ + getRooms: function() { + return utils.values(this.rooms); + }, + + /** + * Permanently delete a room. + * @param {string} roomId + */ + removeRoom: function(roomId) { + if (this.rooms[roomId]) { + this.rooms[roomId].removeListener("RoomState.members", this._onRoomMember); + } + delete this.rooms[roomId]; + }, + + /** + * Retrieve a summary of all the rooms. + * @return {RoomSummary[]} A summary of each room. + */ + getRoomSummaries: function() { + return utils.map(utils.values(this.rooms), function(room) { + return room.summary; + }); + }, + + /** + * Store a User. + * @param {User} user The user to store. + */ + storeUser: function(user) { + this.users[user.userId] = user; + }, + + /** + * Retrieve a User by its' user ID. + * @param {string} userId The user ID. + * @return {User} The user or null. + */ + getUser: function(userId) { + return this.users[userId] || null; + }, + + /** + * Retrieve all known users. + * @return {User[]} A list of users, which may be empty. + */ + getUsers: function() { + return utils.values(this.users); + }, + + /** + * Retrieve scrollback for this room. + * @param {Room} room The matrix room + * @param {integer} limit The max number of old events to retrieve. + * @return {Array} An array of objects which will be at most 'limit' + * length and at least 0. The objects are the raw event JSON. + */ + scrollback: function(room, limit) { + return []; + }, + + /** + * Store events for a room. The events have already been added to the timeline + * @param {Room} room The room to store events for. + * @param {Array} events The events to store. + * @param {string} token The token associated with these events. + * @param {boolean} toStart True if these are paginated results. + */ + storeEvents: function(room, events, token, toStart) { + // no-op because they've already been added to the room instance. + }, + + /** + * Store a filter. + * @param {Filter} filter + */ + storeFilter: function(filter) { + if (!filter) { return; } + if (!this.filters[filter.userId]) { + this.filters[filter.userId] = {}; + } + this.filters[filter.userId][filter.filterId] = filter; + }, + + /** + * Retrieve a filter. + * @param {string} userId + * @param {string} filterId + * @return {?Filter} A filter or null. + */ + getFilter: function(userId, filterId) { + if (!this.filters[userId] || !this.filters[userId][filterId]) { + return null; + } + return this.filters[userId][filterId]; + }, + + /** + * Retrieve a filter ID with the given name. + * @param {string} filterName The filter name. + * @return {?string} The filter ID or null. + */ + getFilterIdByName: function(filterName) { + if (!this.localStorage) { + return null; + } + try { + return this.localStorage.getItem("mxjssdk_memory_filter_" + filterName); + } + catch (e) {} + return null; + }, + + /** + * Set a filter name to ID mapping. + * @param {string} filterName + * @param {string} filterId + */ + setFilterIdByName: function(filterName, filterId) { + if (!this.localStorage) { + return; + } + try { + this.localStorage.setItem("mxjssdk_memory_filter_" + filterName, filterId); + } + catch (e) {} + }, + + /** + * Store user-scoped account data events. + * N.B. that account data only allows a single event per type, so multiple + * events with the same type will replace each other. + * @param {Array} events The events to store. + */ + storeAccountDataEvents: function(events) { + var self = this; + events.forEach(function(event) { + self.accountData[event.getType()] = event; + }); + }, + + /** + * Get account data event by event type + * @param {string} eventType The event type being queried + * @return {?MatrixEvent} the user account_data event of given type, if any + */ + getAccountData: function(eventType) { + return this.accountData[eventType]; + }, + + // TODO + //setMaxHistoryPerRoom: function(maxHistory) {}, + + // TODO + //reapOldMessages: function() {}, +}; + +},{"../models/user":18,"../utils":28}],23:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/** + * @module store/session/webstorage + */ + +var utils = require("../../utils"); + +var DEBUG = false; // set true to enable console logging. +var E2E_PREFIX = "session.e2e."; + +/** + * Construct a web storage session store, capable of storing account keys, + * session keys and access tokens. + * @constructor + * @param {WebStorage} webStore A web storage implementation, e.g. + * 'window.localStorage' or 'window.sessionStorage' or a custom implementation. + * @throws if the supplied 'store' does not meet the Storage interface of the + * WebStorage API. + */ +function WebStorageSessionStore(webStore) { + this.store = webStore; + if (!utils.isFunction(webStore.getItem) || + !utils.isFunction(webStore.setItem) || + !utils.isFunction(webStore.removeItem)) { + throw new Error( + "Supplied webStore does not meet the WebStorage API interface" + ); + } +} + +WebStorageSessionStore.prototype = { + + /** + * Store the end to end account for the logged-in user. + * @param {string} account Base64 encoded account. + */ + storeEndToEndAccount: function(account) { + this.store.setItem(KEY_END_TO_END_ACCOUNT, account); + }, + + /** + * Load the end to end account for the logged-in user. + * @return {?string} Base64 encoded account. + */ + getEndToEndAccount: function() { + return this.store.getItem(KEY_END_TO_END_ACCOUNT); + }, + + /** + * Stores the known devices for a user. + * @param {string} userId The user's ID. + * @param {object} devices A map from device ID to keys for the device. + */ + storeEndToEndDevicesForUser: function(userId, devices) { + setJsonItem(this.store, keyEndToEndDevicesForUser(userId), devices); + }, + + /** + * Retrieves the known devices for a user. + * @param {string} userId The user's ID. + * @return {object} A map from device ID to keys for the device. + */ + getEndToEndDevicesForUser: function(userId) { + return getJsonItem(this.store, keyEndToEndDevicesForUser(userId)); + }, + + /** + * Store a session between the logged-in user and another device + * @param {string} deviceKey The public key of the other device. + * @param {string} sessionId The ID for this end-to-end session. + * @param {string} session Base64 encoded end-to-end session. + */ + storeEndToEndSession: function(deviceKey, sessionId, session) { + var sessions = this.getEndToEndSessions(deviceKey) || {}; + sessions[sessionId] = session; + setJsonItem( + this.store, keyEndToEndSessions(deviceKey), sessions + ); + }, + + /** + * Retrieve the end-to-end sessions between the logged-in user and another + * device. + * @param {string} deviceKey The public key of the other device. + * @return {object} A map from sessionId to Base64 end-to-end session. + */ + getEndToEndSessions: function(deviceKey) { + return getJsonItem(this.store, keyEndToEndSessions(deviceKey)); + }, + + /** + * Store the end-to-end state for a room. + * @param {string} roomId The room's ID. + * @param {object} roomInfo The end-to-end info for the room. + */ + storeEndToEndRoom: function(roomId, roomInfo) { + setJsonItem(this.store, keyEndToEndRoom(roomId), roomInfo); + }, + + /** + * Get the end-to-end state for a room + * @param {string} roomId The room's ID. + * @return {object} The end-to-end info for the room. + */ + getEndToEndRoom: function(roomId) { + return getJsonItem(this.store, keyEndToEndRoom(roomId)); + } +}; + +var KEY_END_TO_END_ACCOUNT = E2E_PREFIX + "account"; + +function keyEndToEndDevicesForUser(userId) { + return E2E_PREFIX + "devices/" + userId; +} + +function keyEndToEndSessions(deviceKey) { + return E2E_PREFIX + "sessions/" + deviceKey; +} + +function keyEndToEndRoom(roomId) { + return E2E_PREFIX + "rooms/" + roomId; +} + +function getJsonItem(store, key) { + try { + return JSON.parse(store.getItem(key)); + } + catch (e) { + debuglog("Failed to get key %s: %s", key, e); + debuglog(e.stack); + } + return null; +} + +function setJsonItem(store, key, val) { + store.setItem(key, JSON.stringify(val)); +} + +function debuglog() { + if (DEBUG) { + console.log.apply(console, arguments); + } +} + +/** */ +module.exports = WebStorageSessionStore; + +},{"../../utils":28}],24:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * This is an internal module. + * @module store/stub + */ + +/** + * Construct a stub store. This does no-ops on most store methods. + * @constructor + */ +function StubStore() { + this.fromToken = null; +} + +StubStore.prototype = { + + /** + * Get the sync token. + * @return {string} + */ + getSyncToken: function() { + return this.fromToken; + }, + + /** + * Set the sync token. + * @param {string} token + */ + setSyncToken: function(token) { + this.fromToken = token; + }, + + /** + * No-op. + * @param {Room} room + */ + storeRoom: function(room) { + }, + + /** + * No-op. + * @param {string} roomId + * @return {null} + */ + getRoom: function(roomId) { + return null; + }, + + /** + * No-op. + * @return {Array} An empty array. + */ + getRooms: function() { + return []; + }, + + /** + * Permanently delete a room. + * @param {string} roomId + */ + removeRoom: function(roomId) { + return; + }, + + /** + * No-op. + * @return {Array} An empty array. + */ + getRoomSummaries: function() { + return []; + }, + + /** + * No-op. + * @param {User} user + */ + storeUser: function(user) { + }, + + /** + * No-op. + * @param {string} userId + * @return {null} + */ + getUser: function(userId) { + return null; + }, + + /** + * No-op. + * @return {User[]} + */ + getUsers: function() { + return []; + }, + + /** + * No-op. + * @param {Room} room + * @param {integer} limit + * @return {Array} + */ + scrollback: function(room, limit) { + return []; + }, + + /** + * Store events for a room. + * @param {Room} room The room to store events for. + * @param {Array} events The events to store. + * @param {string} token The token associated with these events. + * @param {boolean} toStart True if these are paginated results. + */ + storeEvents: function(room, events, token, toStart) { + }, + + /** + * Store a filter. + * @param {Filter} filter + */ + storeFilter: function(filter) { + }, + + /** + * Retrieve a filter. + * @param {string} userId + * @param {string} filterId + * @return {?Filter} A filter or null. + */ + getFilter: function(userId, filterId) { + return null; + }, + + /** + * Retrieve a filter ID with the given name. + * @param {string} filterName The filter name. + * @return {?string} The filter ID or null. + */ + getFilterIdByName: function(filterName) { + return null; + }, + + /** + * Set a filter name to ID mapping. + * @param {string} filterName + * @param {string} filterId + */ + setFilterIdByName: function(filterName, filterId) { + + }, + + /** + * Store user-scoped account data events + * @param {Array} events The events to store. + */ + storeAccountDataEvents: function(events) { + + }, + + /** + * Get account data event by event type + * @param {string} eventType The event type being queried + */ + getAccountData: function(eventType) { + + }, + + // TODO + //setMaxHistoryPerRoom: function(maxHistory) {}, + + // TODO + //reapOldMessages: function() {}, +}; + +/** Stub Store class. */ +module.exports = StubStore; + +},{}],25:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * This is an internal module. Implementation details: + *
+ * Room data is stored as follows:
+ *   room_$ROOMID_timeline_$INDEX : [ Event, Event, Event ]
+ *   room_$ROOMID_state : {
+ *                          pagination_token: ,
+ *                          events: {
+ *                            : {  : {JSON} }
+ *                          }
+ *                        }
+ * User data is stored as follows:
+ *   user_$USERID : User
+ * Sync token:
+ *   sync_token : $TOKEN
+ *
+ * Room Retrieval
+ * --------------
+ * Retrieving a room requires the $ROOMID which then pulls out the current state
+ * from room_$ROOMID_state. A defined starting batch of timeline events are then
+ * extracted from the highest numbered $INDEX for room_$ROOMID_timeline_$INDEX
+ * (more indices as required). The $INDEX may be negative. These are
+ * added to the timeline in the same way as /initialSync (old state will diverge).
+ * If there exists a room_$ROOMID_timeline_live key, then a timeline sync should
+ * be performed before retrieving.
+ *
+ * Retrieval of earlier messages
+ * -----------------------------
+ * The earliest event the Room instance knows about is E. Retrieving earlier
+ * messages requires a Room which has a storageToken defined.
+ * This token maps to the index I where the Room is at. Events are then retrieved from
+ * room_$ROOMID_timeline_{I} and elements before E are extracted. If the limit
+ * demands more events, I-1 is retrieved, up until I=min $INDEX where it gives
+ * less than the limit. Index may go negative if you have paginated in the past.
+ *
+ * Full Insertion
+ * --------------
+ * Storing a room requires the timeline and state keys for $ROOMID to
+ * be blown away and completely replaced, which is computationally expensive.
+ * Room.timeline is batched according to the given batch size B. These batches
+ * are then inserted into storage as room_$ROOMID_timeline_$INDEX. Finally,
+ * the current room state is persisted to room_$ROOMID_state.
+ *
+ * Incremental Insertion
+ * ---------------------
+ * As events arrive, the store can quickly persist these new events. This
+ * involves pushing the events to room_$ROOMID_timeline_live. If the
+ * current room state has been modified by the new event, then
+ * room_$ROOMID_state should be updated in addition to the timeline.
+ *
+ * Timeline sync
+ * -------------
+ * Retrieval of events from the timeline depends on the proper batching of
+ * events. This is computationally expensive to perform on every new event, so
+ * is deferred by inserting live events to room_$ROOMID_timeline_live. A
+ * timeline sync reconciles timeline_live and timeline_$INDEX. This involves
+ * retrieving _live and the highest numbered $INDEX batch. If the batch is < B,
+ * the earliest entries from _live are inserted into the $INDEX until the
+ * batch == B. Then, the remaining entries in _live are batched to $INDEX+1,
+ * $INDEX+2, and so on. The easiest way to visualise this is that the timeline
+ * goes from old to new, left to right:
+ *          -2         -1         0         1
+ * <--OLD---------------------------------------NEW-->
+ *        [a,b,c]    [d,e,f]   [g,h,i]   [j,k,l]
+ *
+ * Purging
+ * -------
+ * Events from the timeline can be purged by removing the lowest
+ * timeline_$INDEX in the store.
+ *
+ * Example
+ * -------
+ * A room with room_id !foo:bar has 9 messages (M1->9 where 9=newest) with a
+ * batch size of 4. The very first time, there is no entry for !foo:bar until
+ * storeRoom() is called, which results in the keys: [Full Insert]
+ *   room_!foo:bar_timeline_0 : [M1, M2, M3, M4]
+ *   room_!foo:bar_timeline_1 : [M5, M6, M7, M8]
+ *   room_!foo:bar_timeline_2 : [M9]
+ *   room_!foo:bar_state: { ... }
+ *
+ * 5 new messages (N1-5, 5=newest) arrive and are then added: [Incremental Insert]
+ *   room_!foo:bar_timeline_live: [N1]
+ *   room_!foo:bar_timeline_live: [N1, N2]
+ *   room_!foo:bar_timeline_live: [N1, N2, N3]
+ *   room_!foo:bar_timeline_live: [N1, N2, N3, N4]
+ *   room_!foo:bar_timeline_live: [N1, N2, N3, N4, N5]
+ *
+ * App is shutdown. Restarts. The timeline is synced [Timeline Sync]
+ *   room_!foo:bar_timeline_2 : [M9, N1, N2, N3]
+ *   room_!foo:bar_timeline_3 : [N4, N5]
+ *   room_!foo:bar_timeline_live: []
+ *
+ * And the room is retrieved with 8 messages: [Room Retrieval]
+ *   Room.timeline: [M7, M8, M9, N1, N2, N3, N4, N5]
+ *   Room.storageToken: => early_index = 1 because that's where M7 is.
+ *
+ * 3 earlier messages are requested: [Earlier retrieval]
+ *   Use storageToken to find batch index 1. Scan batch for earliest event ID.
+ *   earliest event = M7
+ *   events = room_!foo:bar_timeline_1 where event < M7 = [M5, M6]
+ * Too few events, use next index (0) and get 1 more:
+ *   events = room_!foo:bar_timeline_0 = [M1, M2, M3, M4] => [M4]
+ * Return concatentation:
+ *   [M4, M5, M6]
+ *
+ * Purge oldest events: [Purge]
+ *   del room_!foo:bar_timeline_0
+ * 
+ * @module store/webstorage + */ +var DEBUG = false; // set true to enable console logging. +var utils = require("../utils"); +var Room = require("../models/room"); +var User = require("../models/user"); +var MatrixEvent = require("../models/event").MatrixEvent; + +/** + * Construct a web storage store, capable of storing rooms and users. + * @constructor + * @param {WebStorage} webStore A web storage implementation, e.g. + * 'window.localStorage' or 'window.sessionStorage' or a custom implementation. + * @param {integer} batchSize The number of events to store per key/value (room + * scoped). Use -1 to store all events for a room under one key/value. + * @throws if the supplied 'store' does not meet the Storage interface of the + * WebStorage API. + */ +function WebStorageStore(webStore, batchSize) { + this.store = webStore; + this.batchSize = batchSize; + if (!utils.isFunction(webStore.getItem) || !utils.isFunction(webStore.setItem) || + !utils.isFunction(webStore.removeItem) || !utils.isFunction(webStore.key)) { + throw new Error( + "Supplied webStore does not meet the WebStorage API interface" + ); + } + if (!parseInt(webStore.length) && webStore.length !== 0) { + throw new Error( + "Supplied webStore does not meet the WebStorage API interface (length)" + ); + } + // cached list of room_ids this is storing. + this._roomIds = []; + this._syncedWithStore = false; + // tokens used to remember which index the room instance is at. + this._tokens = [ + // { earliestIndex: -4 } + ]; +} + + +/** + * Retrieve the token to stream from. + * @return {string} The token or null. + */ +WebStorageStore.prototype.getSyncToken = function() { + return this.store.getItem("sync_token"); +}; + +/** + * Set the token to stream from. + * @param {string} token The token to stream from. + */ +WebStorageStore.prototype.setSyncToken = function(token) { + this.store.setItem("sync_token", token); +}; + +/** + * Store a room in web storage. + * @param {Room} room + */ +WebStorageStore.prototype.storeRoom = function(room) { + var serRoom = SerialisedRoom.fromRoom(room, this.batchSize); + persist(this.store, serRoom); + if (this._roomIds.indexOf(room.roomId) === -1) { + this._roomIds.push(room.roomId); + } +}; + +/** + * Retrieve a room from web storage. + * @param {string} roomId + * @return {?Room} + */ +WebStorageStore.prototype.getRoom = function(roomId) { + // probe if room exists; break early if not. Every room should have state. + if (!getItem(this.store, keyName(roomId, "state"))) { + debuglog("getRoom: No room with id %s found.", roomId); + return null; + } + var timelineKeys = getTimelineIndices(this.store, roomId); + if (timelineKeys.indexOf("live") !== -1) { + debuglog("getRoom: Live events found. Syncing timeline for %s", roomId); + this._syncTimeline(roomId, timelineKeys); + } + return loadRoom(this.store, roomId, this.batchSize, this._tokens); +}; + +/** + * Get a list of all rooms from web storage. + * @return {Array} An empty array. + */ +WebStorageStore.prototype.getRooms = function() { + var rooms = []; + var i; + if (!this._syncedWithStore) { + // sync with the store to set this._roomIds correctly. We know there is + // exactly one 'state' key for each room, so we grab them. + this._roomIds = []; + for (i = 0; i < this.store.length; i++) { + if (this.store.key(i).indexOf("room_") === 0 && + this.store.key(i).indexOf("_state") !== -1) { + // grab the middle bit which is the room ID + var k = this.store.key(i); + this._roomIds.push( + k.substring("room_".length, k.length - "_state".length) + ); + } + } + this._syncedWithStore = true; + } + // call getRoom on each room_id + for (i = 0; i < this._roomIds.length; i++) { + var rm = this.getRoom(this._roomIds[i]); + if (rm) { + rooms.push(rm); + } + } + return rooms; +}; + +/** + * Get a list of summaries from web storage. + * @return {Array} An empty array. + */ +WebStorageStore.prototype.getRoomSummaries = function() { + return []; +}; + +/** + * Store a user in web storage. + * @param {User} user + */ +WebStorageStore.prototype.storeUser = function(user) { + // persist the events used to make the user, we can reconstruct on demand. + setItem(this.store, "user_" + user.userId, { + presence: user.events.presence ? user.events.presence.event : null + }); +}; + +/** + * Get a user from web storage. + * @param {string} userId + * @return {User} + */ +WebStorageStore.prototype.getUser = function(userId) { + var userData = getItem(this.store, "user_" + userId); + if (!userData) { + return null; + } + var user = new User(userId); + if (userData.presence) { + user.setPresenceEvent(new MatrixEvent(userData.presence)); + } + return user; +}; + +/** + * Retrieve scrollback for this room. Automatically adds events to the timeline. + * @param {Room} room The matrix room to add the events to the start of the timeline. + * @param {integer} limit The max number of old events to retrieve. + * @return {Array} An array of objects which will be at most 'limit' + * length and at least 0. The objects are the raw event JSON. The last element + * is the 'oldest' (for parity with homeserver scrollback APIs). + */ +WebStorageStore.prototype.scrollback = function(room, limit) { + if (room.storageToken === undefined || room.storageToken >= this._tokens.length) { + return []; + } + // find the index of the earliest event in this room's timeline + var storeData = this._tokens[room.storageToken] || {}; + var i; + var earliestIndex = storeData.earliestIndex; + var earliestEventId = room.timeline[0] ? room.timeline[0].getId() : null; + debuglog( + "scrollback in %s (timeline=%s msgs) i=%s, timeline[0].id=%s - req %s events", + room.roomId, room.timeline.length, earliestIndex, earliestEventId, limit + ); + var batch = getItem( + this.store, keyName(room.roomId, "timeline", earliestIndex) + ); + if (!batch) { + // bad room or already at start, either way we have nothing to give. + debuglog("No batch with index %s found.", earliestIndex); + return []; + } + // populate from this batch first + var scrollback = []; + var foundEventId = false; + for (i = batch.length - 1; i >= 0; i--) { + // go back and find the earliest event ID, THEN start adding entries. + // Make a MatrixEvent so we don't assume .event_id exists + // (e.g v2/v3 JSON may be different) + var matrixEvent = new MatrixEvent(batch[i]); + if (matrixEvent.getId() === earliestEventId) { + foundEventId = true; + debuglog( + "Found timeline[0] event at position %s in batch %s", + i, earliestIndex + ); + continue; + } + if (!foundEventId) { + continue; + } + // add entry + debuglog("Add event at position %s in batch %s", i, earliestIndex); + scrollback.push(batch[i]); + if (scrollback.length === limit) { + break; + } + } + if (scrollback.length === limit) { + debuglog("Batch has enough events to satisfy request."); + return scrollback; + } + if (!foundEventId) { + // the earliest index batch didn't contain the event. In other words, + // this timeline is at a state we don't know, so bail. + debuglog( + "Failed to find event ID %s in batch %s", earliestEventId, earliestIndex + ); + return []; + } + + // get the requested earlier events from earlier batches + while (scrollback.length < limit) { + earliestIndex--; + batch = getItem( + this.store, keyName(room.roomId, "timeline", earliestIndex) + ); + if (!batch) { + // no more events + debuglog("No batch found at index %s", earliestIndex); + break; + } + for (i = batch.length - 1; i >= 0; i--) { + debuglog("Add event at position %s in batch %s", i, earliestIndex); + scrollback.push(batch[i]); + if (scrollback.length === limit) { + break; + } + } + } + debuglog( + "Out of %s requested events, returning %s. New index=%s", + limit, scrollback.length, earliestIndex + ); + room.addEventsToTimeline(utils.map(scrollback, function(e) { + return new MatrixEvent(e); + }), true, room.getLiveTimeline()); + + this._tokens[room.storageToken] = { + earliestIndex: earliestIndex + }; + return scrollback; +}; + +/** + * Store events for a room. The events have already been added to the timeline. + * @param {Room} room The room to store events for. + * @param {Array} events The events to store. + * @param {string} token The token associated with these events. + * @param {boolean} toStart True if these are paginated results. The last element + * is the 'oldest' (for parity with homeserver scrollback APIs). + */ +WebStorageStore.prototype.storeEvents = function(room, events, token, toStart) { + if (toStart) { + // add paginated events to lowest batch indexes (can go -ve) + var lowIndex = getIndexExtremity( + getTimelineIndices(this.store, room.roomId), true + ); + var i, key, batch; + for (i = 0; i < events.length; i++) { // loop events to be stored + key = keyName(room.roomId, "timeline", lowIndex); + batch = getItem(this.store, key) || []; + while (batch.length < this.batchSize && i < events.length) { + batch.unshift(events[i].event); + i++; // increment to insert next event into this batch + } + i--; // decrement to avoid skipping one (for loop ++s) + setItem(this.store, key, batch); + lowIndex--; // decrement index to get a new batch. + } + } + else { + // dump as live events + var liveEvents = getItem( + this.store, keyName(room.roomId, "timeline", "live") + ) || []; + debuglog( + "Adding %s events to %s live list (which has %s already)", + events.length, room.roomId, liveEvents.length + ); + var updateState = false; + liveEvents = liveEvents.concat(utils.map(events, function(me) { + // cheeky check to avoid looping twice + if (me.isState()) { + updateState = true; + } + return me.event; + })); + setItem( + this.store, keyName(room.roomId, "timeline", "live"), liveEvents + ); + if (updateState) { + debuglog("Storing state for %s as new events updated state", room.roomId); + // use 0 batch size; we don't care about batching right now. + var serRoom = SerialisedRoom.fromRoom(room, 0); + setItem(this.store, keyName(serRoom.roomId, "state"), serRoom.state); + } + } +}; + +/** + * Sync the 'live' timeline, batching live events according to 'batchSize'. + * @param {string} roomId The room to sync the timeline. + * @param {Array} timelineIndices Optional. The indices in the timeline + * if known already. + */ +WebStorageStore.prototype._syncTimeline = function(roomId, timelineIndices) { + timelineIndices = timelineIndices || getTimelineIndices(this.store, roomId); + var liveEvents = getItem(this.store, keyName(roomId, "timeline", "live")) || []; + + // get the highest numbered $INDEX batch + var highestIndex = getIndexExtremity(timelineIndices); + var hiKey = keyName(roomId, "timeline", highestIndex); + var hiBatch = getItem(this.store, hiKey) || []; + // fill up the existing batch first. + while (hiBatch.length < this.batchSize && liveEvents.length > 0) { + hiBatch.push(liveEvents.shift()); + } + setItem(this.store, hiKey, hiBatch); + + // start adding new batches as required + var batch = []; + while (liveEvents.length > 0) { + batch.push(liveEvents.shift()); + if (batch.length === this.batchSize || liveEvents.length === 0) { + // persist the full batch and make another + highestIndex++; + hiKey = keyName(roomId, "timeline", highestIndex); + setItem(this.store, hiKey, batch); + batch = []; + } + } + // reset live array + setItem(this.store, keyName(roomId, "timeline", "live"), []); +}; + + +/** + * Store a filter. + * @param {Filter} filter + */ +WebStorageStore.prototype.storeFilter = function(filter) { +}; + +/** + * Retrieve a filter. + * @param {string} userId + * @param {string} filterId + * @return {?Filter} A filter or null. + */ +WebStorageStore.prototype.getFilter = function(userId, filterId) { + return null; +}; + +function SerialisedRoom(roomId) { + this.state = { + events: {} + }; + this.timeline = { + // $INDEX: [] + }; + this.roomId = roomId; +} + +/** + * Convert a Room instance into a SerialisedRoom instance which can be stored + * in the key value store. + * @param {Room} room The matrix room to convert + * @param {integer} batchSize The number of events per timeline batch + * @return {SerialisedRoom} A serialised room representation of 'room'. + */ +SerialisedRoom.fromRoom = function(room, batchSize) { + var self = new SerialisedRoom(room.roomId); + var index; + self.state.pagination_token = room.oldState.paginationToken; + // [room_$ROOMID_state] downcast to POJO from MatrixEvent + utils.forEach(utils.keys(room.currentState.events), function(eventType) { + utils.forEach(utils.keys(room.currentState.events[eventType]), function(skey) { + if (!self.state.events[eventType]) { + self.state.events[eventType] = {}; + } + self.state.events[eventType][skey] = ( + room.currentState.events[eventType][skey].event + ); + }); + }); + + // [room_$ROOMID_timeline_$INDEX] + if (batchSize > 0) { + index = 0; + while (index * batchSize < room.timeline.length) { + self.timeline[index] = room.timeline.slice( + index * batchSize, (index + 1) * batchSize + ); + self.timeline[index] = utils.map(self.timeline[index], function(me) { + // use POJO not MatrixEvent + return me.event; + }); + index++; + } + } + else { // don't batch + self.timeline[0] = utils.map(room.timeline, function(matrixEvent) { + return matrixEvent.event; + }); + } + return self; +}; + +function loadRoom(store, roomId, numEvents, tokenArray) { + var room = new Room(roomId, { + storageToken: tokenArray.length + }); + + // populate state (flatten nested struct to event array) + var currentStateMap = getItem(store, keyName(roomId, "state")); + var stateEvents = []; + utils.forEach(utils.keys(currentStateMap.events), function(eventType) { + utils.forEach(utils.keys(currentStateMap.events[eventType]), function(skey) { + stateEvents.push(currentStateMap.events[eventType][skey]); + }); + }); + // TODO: Fix logic dupe with MatrixClient._processRoomEvents + var oldStateEvents = utils.map( + utils.deepCopy(stateEvents), function(e) { + return new MatrixEvent(e); + } + ); + var currentStateEvents = utils.map(stateEvents, function(e) { + return new MatrixEvent(e); + } + ); + room.oldState.setStateEvents(oldStateEvents); + room.currentState.setStateEvents(currentStateEvents); + + // add most recent numEvents + var recentEvents = []; + var index = getIndexExtremity(getTimelineIndices(store, roomId)); + var eventIndex = index; + var i, key, batch; + while (recentEvents.length < numEvents) { + key = keyName(roomId, "timeline", index); + batch = getItem(store, key) || []; + if (batch.length === 0) { + // nothing left in the store. + break; + } + for (i = batch.length - 1; i >= 0; i--) { + recentEvents.unshift(new MatrixEvent(batch[i])); + if (recentEvents.length === numEvents) { + eventIndex = index; + break; + } + } + index--; + } + // add events backwards to diverge old state correctly. + room.addEventsToTimeline(recentEvents.reverse(), true, room.getLiveTimeline()); + room.oldState.paginationToken = currentStateMap.pagination_token; + // set the token data to let us know which index this room instance is at + // for scrollback. + tokenArray.push({ + earliestIndex: eventIndex + }); + return room; +} + +function persist(store, serRoom) { + setItem(store, keyName(serRoom.roomId, "state"), serRoom.state); + utils.forEach(utils.keys(serRoom.timeline), function(index) { + setItem(store, + keyName(serRoom.roomId, "timeline", index), + serRoom.timeline[index] + ); + }); +} + +function getTimelineIndices(store, roomId) { + var keys = []; + for (var i = 0; i < store.length; i++) { + if (store.key(i).indexOf(keyName(roomId, "timeline_")) !== -1) { + // e.g. room_$ROOMID_timeline_0 => 0 + keys.push( + store.key(i).replace(keyName(roomId, "timeline_"), "") + ); + } + } + return keys; +} + +function getIndexExtremity(timelineIndices, getLowest) { + var extremity, index; + for (var i = 0; i < timelineIndices.length; i++) { + index = parseInt(timelineIndices[i]); + if (!isNaN(index) && ( + extremity === undefined || + !getLowest && index > extremity || + getLowest && index < extremity)) { + extremity = index; + } + } + return extremity; +} + +function keyName(roomId, key, index) { + return "room_" + roomId + "_" + key + ( + index === undefined ? "" : ("_" + index) + ); +} + +function getItem(store, key) { + try { + return JSON.parse(store.getItem(key)); + } + catch (e) { + debuglog("Failed to get key %s: %s", key, e); + debuglog(e.stack); + } + return null; +} + +function setItem(store, key, val) { + store.setItem(key, JSON.stringify(val)); +} + +function debuglog() { + if (DEBUG) { + console.log.apply(console, arguments); + } +} + +/* +function delRoomStruct(store, roomId) { + var prefix = "room_" + roomId; + var keysToRemove = []; + for (var i = 0; i < store.length; i++) { + if (store.key(i).indexOf(prefix) !== -1) { + keysToRemove.push(store.key(i)); + } + } + utils.forEach(keysToRemove, function(key) { + store.removeItem(key); + }); +} */ + +/** Web Storage Store class. */ +module.exports = WebStorageStore; + +},{"../models/event":12,"../models/room":16,"../models/user":18,"../utils":28}],26:[function(require,module,exports){ +(function (global){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/* + * TODO: + * This class mainly serves to take all the syncing logic out of client.js and + * into a separate file. It's all very fluid, and this class gut wrenches a lot + * of MatrixClient props (e.g. _http). Given we want to support WebSockets as + * an alternative syncing API, we may want to have a proper syncing interface + * for HTTP and WS at some point. + */ +var q = require("q"); +var User = require("./models/user"); +var Room = require("./models/room"); +var utils = require("./utils"); +var Filter = require("./filter"); +var EventTimeline = require("./models/event-timeline"); + +var DEBUG = true; + +// /sync requests allow you to set a timeout= but the request may continue +// beyond that and wedge forever, so we need to track how long we are willing +// to keep open the connection. This constant is *ADDED* to the timeout= value +// to determine the max time we're willing to wait. +var BUFFER_PERIOD_MS = 80 * 1000; + +function getFilterName(userId, suffix) { + // scope this on the user ID because people may login on many accounts + // and they all need to be stored! + return "FILTER_SYNC_" + userId + (suffix ? "_" + suffix : ""); +} + +function debuglog() { + if (!DEBUG) { return; } + console.log.apply(console, arguments); +} + + +/** + * Internal class - unstable. + * Construct an entity which is able to sync with a homeserver. + * @constructor + * @param {MatrixClient} client The matrix client instance to use. + * @param {Object} opts Config options + */ +function SyncApi(client, opts) { + this.client = client; + opts = opts || {}; + opts.initialSyncLimit = opts.initialSyncLimit || 8; + opts.resolveInvitesToProfiles = opts.resolveInvitesToProfiles || false; + opts.pollTimeout = opts.pollTimeout || (30 * 1000); + opts.pendingEventOrdering = opts.pendingEventOrdering || "chronological"; + this.opts = opts; + this._peekRoomId = null; + this._syncConnectionLost = false; + this._currentSyncRequest = null; + this._syncState = null; + this._running = false; + this._keepAliveTimer = null; + this._connectionReturnedDefer = null; +} + +/** + * @param {string} roomId + * @return {Room} + */ +SyncApi.prototype.createRoom = function(roomId) { + var client = this.client; + var room = new Room(roomId, { + pendingEventOrdering: this.opts.pendingEventOrdering, + timelineSupport: client.timelineSupport, + }); + reEmit(client, room, ["Room.name", "Room.timeline", "Room.redaction", + "Room.receipt", "Room.tags", + "Room.timelineReset", + "Room.localEchoUpdated", + "Room.accountData", + ]); + this._registerStateListeners(room); + return room; +}; + +/** + * @param {Room} room + * @private + */ +SyncApi.prototype._registerStateListeners = function(room) { + var client = this.client; + // we need to also re-emit room state and room member events, so hook it up + // to the client now. We need to add a listener for RoomState.members in + // order to hook them correctly. (TODO: find a better way?) + reEmit(client, room.currentState, [ + "RoomState.events", "RoomState.members", "RoomState.newMember" + ]); + room.currentState.on("RoomState.newMember", function(event, state, member) { + member.user = client.getUser(member.userId); + reEmit( + client, member, + [ + "RoomMember.name", "RoomMember.typing", "RoomMember.powerLevel", + "RoomMember.membership" + ] + ); + }); +}; + +/** + * @param {Room} room + * @private + */ +SyncApi.prototype._deregisterStateListeners = function(room) { + // could do with a better way of achieving this. + room.currentState.removeAllListeners("RoomState.events"); + room.currentState.removeAllListeners("RoomState.members"); + room.currentState.removeAllListeners("RoomState.newMember"); +}; + + +/** + * Sync rooms the user has left. + * @return {Promise} Resolved when they've been added to the store. + */ +SyncApi.prototype.syncLeftRooms = function() { + var client = this.client; + var self = this; + + // grab a filter with limit=1 and include_leave=true + var filter = new Filter(this.client.credentials.userId); + filter.setTimelineLimit(1); + filter.setIncludeLeaveRooms(true); + + var localTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS; + var qps = { + timeout: 0 // don't want to block since this is a single isolated req + }; + + return this._getOrCreateFilter( + getFilterName(client.credentials.userId, "LEFT_ROOMS"), filter + ).then(function(filterId) { + qps.filter = filterId; + return client._http.authedRequest( + undefined, "GET", "/sync", qps, undefined, localTimeoutMs + ); + }).then(function(data) { + var leaveRooms = []; + if (data.rooms && data.rooms.leave) { + leaveRooms = self._mapSyncResponseToRoomArray(data.rooms.leave); + } + var rooms = []; + leaveRooms.forEach(function(leaveObj) { + var room = leaveObj.room; + rooms.push(room); + if (!leaveObj.isBrandNewRoom) { + // the intention behind syncLeftRooms is to add in rooms which were + // *omitted* from the initial /sync. Rooms the user were joined to + // but then left whilst the app is running will appear in this list + // and we do not want to bother with them since they will have the + // current state already (and may get dupe messages if we add + // yet more timeline events!), so skip them. + // NB: When we persist rooms to localStorage this will be more + // complicated... + return; + } + leaveObj.timeline = leaveObj.timeline || {}; + var timelineEvents = + self._mapSyncEventsFormat(leaveObj.timeline, room); + var stateEvents = self._mapSyncEventsFormat(leaveObj.state, room); + + // set the back-pagination token. Do this *before* adding any + // events so that clients can start back-paginating. + room.getLiveTimeline().setPaginationToken(leaveObj.timeline.prev_batch, + EventTimeline.BACKWARDS); + + self._processRoomEvents(room, stateEvents, timelineEvents); + + room.recalculate(client.credentials.userId); + client.store.storeRoom(room); + client.emit("Room", room); + }); + return rooms; + }); +}; + +/** + * Peek into a room. This will result in the room in question being synced so it + * is accessible via getRooms(). Live updates for the room will be provided. + * @param {string} roomId The room ID to peek into. + * @return {Promise} A promise which resolves once the room has been added to the + * store. + */ +SyncApi.prototype.peek = function(roomId) { + var self = this; + var client = this.client; + this._peekRoomId = roomId; + return this.client.roomInitialSync(roomId, 20).then(function(response) { + // make sure things are init'd + response.messages = response.messages || {}; + response.messages.chunk = response.messages.chunk || []; + response.state = response.state || []; + + var peekRoom = self.createRoom(roomId); + + // FIXME: Mostly duplicated from _processRoomEvents but not entirely + // because "state" in this API is at the BEGINNING of the chunk + var oldStateEvents = utils.map( + utils.deepCopy(response.state), client.getEventMapper() + ); + var stateEvents = utils.map( + response.state, client.getEventMapper() + ); + var messages = utils.map( + response.messages.chunk, client.getEventMapper() + ); + + // XXX: copypasted from /sync until we kill off this + // minging v1 API stuff) + // handle presence events (User objects) + if (response.presence && utils.isArray(response.presence)) { + response.presence.map(client.getEventMapper()).forEach( + function(presenceEvent) { + var user = client.store.getUser(presenceEvent.getContent().user_id); + if (user) { + user.setPresenceEvent(presenceEvent); + } + else { + user = createNewUser(client, presenceEvent.getContent().user_id); + user.setPresenceEvent(presenceEvent); + client.store.storeUser(user); + } + client.emit("event", presenceEvent); + }); + } + + // set the pagination token before adding the events in case people + // fire off pagination requests in response to the Room.timeline + // events. + if (response.messages.start) { + peekRoom.oldState.paginationToken = response.messages.start; + } + + // set the state of the room to as it was after the timeline executes + peekRoom.oldState.setStateEvents(oldStateEvents); + peekRoom.currentState.setStateEvents(stateEvents); + + self._resolveInvites(peekRoom); + peekRoom.recalculate(self.client.credentials.userId); + + // roll backwards to diverge old state. addEventsToTimeline + // will overwrite the pagination token, so make sure it overwrites + // it with the right thing. + peekRoom.addEventsToTimeline(messages.reverse(), true, + peekRoom.getLiveTimeline(), + response.messages.start); + + client.store.storeRoom(peekRoom); + client.emit("Room", peekRoom); + + self._peekPoll(roomId); + return peekRoom; + }); +}; + +/** + * Stop polling for updates in the peeked room. NOPs if there is no room being + * peeked. + */ +SyncApi.prototype.stopPeeking = function() { + this._peekRoomId = null; +}; + +/** + * Do a peek room poll. + * @param {string} roomId + * @param {string} token from= token + */ +SyncApi.prototype._peekPoll = function(roomId, token) { + if (this._peekRoomId !== roomId) { + debuglog("Stopped peeking in room %s", roomId); + return; + } + + var self = this; + // FIXME: gut wrenching; hard-coded timeout values + this.client._http.authedRequest(undefined, "GET", "/events", { + room_id: roomId, + timeout: 30 * 1000, + from: token + }, undefined, 50 * 1000).done(function(res) { + + // We have a problem that we get presence both from /events and /sync + // however, /sync only returns presence for users in rooms + // you're actually joined to. + // in order to be sure to get presence for all of the users in the + // peeked room, we handle presence explicitly here. This may result + // in duplicate presence events firing for some users, which is a + // performance drain, but such is life. + // XXX: copypasted from /sync until we can kill this minging v1 stuff. + + res.chunk.filter(function(e) { + return e.type === "m.presence"; + }).map(self.client.getEventMapper()).forEach(function(presenceEvent) { + var user = self.client.store.getUser(presenceEvent.getContent().user_id); + if (user) { + user.setPresenceEvent(presenceEvent); + } + else { + user = createNewUser(self.client, presenceEvent.getContent().user_id); + user.setPresenceEvent(presenceEvent); + self.client.store.storeUser(user); + } + self.client.emit("event", presenceEvent); + }); + + // strip out events which aren't for the given room_id (e.g presence) + var events = res.chunk.filter(function(e) { + return e.room_id === roomId; + }).map(self.client.getEventMapper()); + var room = self.client.getRoom(roomId); + room.addLiveEvents(events); + self._peekPoll(roomId, res.end); + }, function(err) { + console.error("[%s] Peek poll failed: %s", roomId, err); + setTimeout(function() { + self._peekPoll(roomId, token); + }, 30 * 1000); + }); +}; + +/** + * Returns the current state of this sync object + * @see module:client~MatrixClient#event:"sync" + * @return {?String} + */ +SyncApi.prototype.getSyncState = function() { + return this._syncState; +}; + +/** + * Main entry point + */ +SyncApi.prototype.sync = function() { + debuglog("SyncApi.sync: starting with sync token " + + this.client.store.getSyncToken()); + + var client = this.client; + var self = this; + + this._running = true; + + if (global.document) { + this._onOnlineBound = this._onOnline.bind(this); + global.document.addEventListener("online", this._onOnlineBound, false); + } + + // We need to do one-off checks before we can begin the /sync loop. + // These are: + // 1) We need to get push rules so we can check if events should bing as we get + // them from /sync. + // 2) We need to get/create a filter which we can use for /sync. + + function getPushRules() { + client.getPushRules().done(function(result) { + debuglog("Got push rules"); + client.pushRules = result; + getFilter(); // Now get the filter + }, function(err) { + self._startKeepAlives().done(function() { + getPushRules(); + }); + self._updateSyncState("ERROR", { error: err }); + }); + } + + function getFilter() { + var filter = new Filter(client.credentials.userId); + filter.setTimelineLimit(self.opts.initialSyncLimit); + + self._getOrCreateFilter( + getFilterName(client.credentials.userId), filter + ).done(function(filterId) { + self._sync({ filterId: filterId }); + }, function(err) { + self._startKeepAlives().done(function() { + getFilter(); + }); + self._updateSyncState("ERROR", { error: err }); + }); + } + + if (client.isGuest()) { + // no push rules for guests, no access to POST filter for guests. + self._sync({}); + } + else { + getPushRules(); + } +}; + +/** + * Stops the sync object from syncing. + */ +SyncApi.prototype.stop = function() { + debuglog("SyncApi.stop"); + if (global.document) { + global.document.removeEventListener("online", this._onOnlineBound, false); + this._onOnlineBound = undefined; + } + this._running = false; + if (this._currentSyncRequest) { this._currentSyncRequest.abort(); } + if (this._keepAliveTimer) { + clearTimeout(this._keepAliveTimer); + this._keepAliveTimer = null; + } +}; + +/** + * Retry a backed off syncing request immediately. This should only be used when + * the user explicitly attempts to retry their lost connection. + * @return {boolean} True if this resulted in a request being retried. + */ +SyncApi.prototype.retryImmediately = function() { + if (!this._connectionReturnedDefer) { return false; } + this._startKeepAlives(0); + return true; +}; + +/** + * Invoke me to do /sync calls + * @param {Object} syncOptions + * @param {string} syncOptions.filterId + * @param {boolean} syncOptions.hasSyncedBefore + */ +SyncApi.prototype._sync = function(syncOptions) { + var client = this.client; + var self = this; + + if (!this._running) { + debuglog("Sync no longer running: exiting."); + if (self._connectionReturnedDefer) { + self._connectionReturnedDefer.reject(); + self._connectionReturnedDefer = null; + } + this._updateSyncState("STOPPED"); + return; + } + + var filterId = syncOptions.filterId; + if (client.isGuest() && !filterId) { + filterId = this._getGuestFilter(); + } + + var syncToken = client.store.getSyncToken(); + + var qps = { + filter: filterId, + timeout: this.opts.pollTimeout, + }; + + if (syncToken) { + qps.since = syncToken; + } else { + // use a cachebuster for initialsyncs, to make sure that + // we don't get a stale sync + // (https://github.com/vector-im/vector-web/issues/1354) + qps._cacheBuster = Date.now(); + } + + if (self._syncConnectionLost) { + // we think the connection is dead. If it comes back up, we won't know + // about it till /sync returns. If the timeout= is high, this could + // be a long time. Set it to 0 when doing retries so we don't have to wait + // for an event or a timeout before emiting the SYNCING event. + qps.timeout = 0; + } + + // normal timeout= plus buffer time + var clientSideTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS; + + this._currentSyncRequest = client._http.authedRequest( + undefined, "GET", "/sync", qps, undefined, clientSideTimeoutMs + ); + + this._currentSyncRequest.done(function(data) { + self._syncConnectionLost = false; + // data looks like: + // { + // next_batch: $token, + // presence: { events: [] }, + // rooms: { + // invite: { + // $roomid: { + // invite_state: { events: [] } + // } + // }, + // join: { + // $roomid: { + // state: { events: [] }, + // timeline: { events: [], prev_batch: $token, limited: true }, + // ephemeral: { events: [] }, + // account_data: { events: [] }, + // unread_notifications: { + // highlight_count: 0, + // notification_count: 0, + // } + // } + // }, + // leave: { + // $roomid: { + // state: { events: [] }, + // timeline: { events: [], prev_batch: $token } + // } + // } + // } + // } + + // set the sync token NOW *before* processing the events. We do this so + // if something barfs on an event we can skip it rather than constantly + // polling with the same token. + client.store.setSyncToken(data.next_batch); + + try { + self._processSyncResponse(syncToken, data); + } + catch (e) { + // log the exception with stack if we have it, else fall back + // to the plain description + console.error("Caught /sync error", e.stack || e); + } + + // emit synced events + if (!syncOptions.hasSyncedBefore) { + self._updateSyncState("PREPARED"); + syncOptions.hasSyncedBefore = true; + } + + // keep emitting SYNCING -> SYNCING for clients who want to do bulk updates + self._updateSyncState("SYNCING"); + + self._sync(syncOptions); + }, function(err) { + if (!self._running) { + debuglog("Sync no longer running: exiting"); + if (self._connectionReturnedDefer) { + self._connectionReturnedDefer.reject(); + self._connectionReturnedDefer = null; + } + return; + } + console.error("/sync error %s", err); + console.error(err); + + debuglog("Starting keep-alive"); + self._syncConnectionLost = true; + self._startKeepAlives().done(function() { + self._sync(syncOptions); + }); + self._currentSyncRequest = null; + self._updateSyncState("ERROR", { error: err }); + }); +}; + +/** + * Process data returned from a sync response and propagate it + * into the model objects + * + * @param {string} syncToken the old next_batch token sent to this + * sync request. + * @param {Object} data The response from /sync + */ +SyncApi.prototype._processSyncResponse = function(syncToken, data) { + var client = this.client; + var self = this; + + // TODO-arch: + // - Each event we pass through needs to be emitted via 'event', can we + // do this in one place? + // - The isBrandNewRoom boilerplate is boilerplatey. + + // handle presence events (User objects) + if (data.presence && utils.isArray(data.presence.events)) { + data.presence.events.map(client.getEventMapper()).forEach( + function(presenceEvent) { + var user = client.store.getUser(presenceEvent.getSender()); + if (user) { + user.setPresenceEvent(presenceEvent); + } + else { + user = createNewUser(client, presenceEvent.getSender()); + user.setPresenceEvent(presenceEvent); + client.store.storeUser(user); + } + client.emit("event", presenceEvent); + }); + } + + // handle non-room account_data + if (data.account_data && utils.isArray(data.account_data.events)) { + var events = data.account_data.events.map(client.getEventMapper()); + client.store.storeAccountDataEvents(events); + events.forEach( + function(accountDataEvent) { + client.emit("accountData", accountDataEvent); + return accountDataEvent; + } + ); + } + + // the returned json structure is a bit crap, so make it into a + // nicer form (array) after applying sanity to make sure we don't fail + // on missing keys (on the off chance) + var inviteRooms = []; + var joinRooms = []; + var leaveRooms = []; + + if (data.rooms) { + if (data.rooms.invite) { + inviteRooms = this._mapSyncResponseToRoomArray(data.rooms.invite); + } + if (data.rooms.join) { + joinRooms = this._mapSyncResponseToRoomArray(data.rooms.join); + } + if (data.rooms.leave) { + leaveRooms = this._mapSyncResponseToRoomArray(data.rooms.leave); + } + } + + // Handle invites + inviteRooms.forEach(function(inviteObj) { + var room = inviteObj.room; + var stateEvents = + self._mapSyncEventsFormat(inviteObj.invite_state, room); + self._processRoomEvents(room, stateEvents); + if (inviteObj.isBrandNewRoom) { + room.recalculate(client.credentials.userId); + client.store.storeRoom(room); + client.emit("Room", room); + } + stateEvents.forEach(function(e) { client.emit("event", e); }); + }); + + // Handle joins + joinRooms.forEach(function(joinObj) { + var room = joinObj.room; + var stateEvents = self._mapSyncEventsFormat(joinObj.state, room); + var timelineEvents = self._mapSyncEventsFormat(joinObj.timeline, room); + var ephemeralEvents = self._mapSyncEventsFormat(joinObj.ephemeral); + var accountDataEvents = self._mapSyncEventsFormat(joinObj.account_data); + + // we do this first so it's correct when any of the events fire + if (joinObj.unread_notifications) { + room.setUnreadNotificationCount( + 'total', joinObj.unread_notifications.notification_count + ); + room.setUnreadNotificationCount( + 'highlight', joinObj.unread_notifications.highlight_count + ); + } + + joinObj.timeline = joinObj.timeline || {}; + + if (joinObj.isBrandNewRoom) { + // set the back-pagination token. Do this *before* adding any + // events so that clients can start back-paginating. + room.getLiveTimeline().setPaginationToken( + joinObj.timeline.prev_batch, EventTimeline.BACKWARDS); + } + else if (joinObj.timeline.limited) { + var limited = true; + + // we've got a limited sync, so we *probably* have a gap in the + // timeline, so should reset. But we might have been peeking or + // paginating and already have some of the events, in which + // case we just want to append any subsequent events to the end + // of the existing timeline. + // + // This is particularly important in the case that we already have + // *all* of the events in the timeline - in that case, if we reset + // the timeline, we'll end up with an entirely empty timeline, + // which we'll try to paginate but not get any new events (which + // will stop us linking the empty timeline into the chain). + // + for (var i = timelineEvents.length - 1; i >= 0; i--) { + var eventId = timelineEvents[i].getId(); + if (room.getTimelineForEvent(eventId)) { + debuglog("Already have event " + eventId + " in limited " + + "sync - not resetting"); + limited = false; + + // we might still be missing some of the events before i; + // we don't want to be adding them to the end of the + // timeline because that would put them out of order. + timelineEvents.splice(0, i); + + // XXX: there's a problem here if the skipped part of the + // timeline modifies the state set in stateEvents, because + // we'll end up using the state from stateEvents rather + // than the later state from timelineEvents. We probably + // need to wind stateEvents forward over the events we're + // skipping. + + break; + } + } + + if (limited) { + // save the old 'next_batch' token as the + // forward-pagination token for the previously-active + // timeline. + room.currentState.paginationToken = syncToken; + self._deregisterStateListeners(room); + room.resetLiveTimeline(joinObj.timeline.prev_batch); + self._registerStateListeners(room); + } + } + + self._processRoomEvents(room, stateEvents, timelineEvents); + + // XXX: should we be adding ephemeralEvents to the timeline? + // It feels like that for symmetry with room.addAccountData() + // there should be a room.addEphemeralEvents() or similar. + room.addLiveEvents(ephemeralEvents); + + // we deliberately don't add accountData to the timeline + room.addAccountData(accountDataEvents); + + room.recalculate(client.credentials.userId); + if (joinObj.isBrandNewRoom) { + client.store.storeRoom(room); + client.emit("Room", room); + } + stateEvents.forEach(function(e) { client.emit("event", e); }); + timelineEvents.forEach(function(e) { client.emit("event", e); }); + ephemeralEvents.forEach(function(e) { client.emit("event", e); }); + accountDataEvents.forEach(function(e) { client.emit("event", e); }); + }); + + // Handle leaves (e.g. kicked rooms) + leaveRooms.forEach(function(leaveObj) { + var room = leaveObj.room; + var stateEvents = + self._mapSyncEventsFormat(leaveObj.state, room); + var timelineEvents = + self._mapSyncEventsFormat(leaveObj.timeline, room); + var accountDataEvents = + self._mapSyncEventsFormat(leaveObj.account_data); + + self._processRoomEvents(room, stateEvents, timelineEvents); + room.addAccountData(accountDataEvents); + + room.recalculate(client.credentials.userId); + if (leaveObj.isBrandNewRoom) { + client.store.storeRoom(room); + client.emit("Room", room); + } + + stateEvents.forEach(function(e) { client.emit("event", e); }); + timelineEvents.forEach(function(e) { client.emit("event", e); }); + accountDataEvents.forEach(function(e) { client.emit("event", e); }); + }); +}; + +/** + * Starts polling the connectivity check endpoint + * @param {number} delay How long to delay until the first poll. + * defaults to a short, randomised interval (to prevent + * tightlooping if /versions succeeds but /sync etc. fail). + * @return {promise} + */ +SyncApi.prototype._startKeepAlives = function(delay) { + if (delay === undefined) { + delay = 5000 + Math.floor(Math.random() * 5000); + } + + if (this._keepAliveTimer !== null) { + clearTimeout(this._keepAliveTimer); + } + var self = this; + self._keepAliveTimer = setTimeout( + self._pokeKeepAlive.bind(self), + delay + ); + if (!this._connectionReturnedDefer) { + this._connectionReturnedDefer = q.defer(); + } + return this._connectionReturnedDefer.promise; +}; + +/** + * + */ +SyncApi.prototype._pokeKeepAlive = function() { + var self = this; + function success() { + clearTimeout(self._keepAliveTimer); + if (self._connectionReturnedDefer) { + self._connectionReturnedDefer.resolve(); + self._connectionReturnedDefer = null; + } + } + + this.client._http.requestWithPrefix( + undefined, "GET", "/_matrix/client/versions", undefined, + undefined, "", 15 * 1000 + ).done(function() { + success(); + }, function(err) { + if (err.httpStatus == 400) { + // treat this as a success because the server probably just doesn't + // support /versions: point is, we're getting a response. + // We wait a short time though, just in case somehow the server + // is in a mode where it 400s /versions responses and sync etc. + // responses fail, this will mean we don't hammer in a loop. + self._keepAliveTimer = setTimeout(success, 2000); + } else { + self._keepAliveTimer = setTimeout( + self._pokeKeepAlive.bind(self), + 5000 + Math.floor(Math.random() * 5000) + ); + } + }); +}; + +/** + * @param {string} filterName + * @param {Filter} filter + * @return {Promise} Filter ID + */ +SyncApi.prototype._getOrCreateFilter = function(filterName, filter) { + var client = this.client; + + var filterId = client.store.getFilterIdByName(filterName); + var promise = q(); + + if (filterId) { + // check that the existing filter matches our expectations + promise = client.getFilter(client.credentials.userId, + filterId, true + ).then(function(existingFilter) { + var oldDef = existingFilter.getDefinition(); + var newDef = filter.getDefinition(); + + if (utils.deepCompare(oldDef, newDef)) { + // super, just use that. + debuglog("Using existing filter ID %s: %s", filterId, + JSON.stringify(oldDef)); + return q(filterId); + } + debuglog("Existing filter ID %s: %s; new filter: %s", + filterId, JSON.stringify(oldDef), JSON.stringify(newDef)); + return; + }); + } + + return promise.then(function(existingId) { + if (existingId) { + return existingId; + } + + // create a new filter + return client.createFilter(filter.getDefinition() + ).then(function(createdFilter) { + debuglog("Created new filter ID %s: %s", createdFilter.filterId, + JSON.stringify(createdFilter.getDefinition())); + client.store.setFilterIdByName(filterName, createdFilter.filterId); + return createdFilter.filterId; + }); + }); +}; + +/** + * @param {Object} obj + * @return {Object[]} + */ +SyncApi.prototype._mapSyncResponseToRoomArray = function(obj) { + // Maps { roomid: {stuff}, roomid: {stuff} } + // to + // [{stuff+Room+isBrandNewRoom}, {stuff+Room+isBrandNewRoom}] + var client = this.client; + var self = this; + return utils.keys(obj).map(function(roomId) { + var arrObj = obj[roomId]; + var room = client.store.getRoom(roomId); + var isBrandNewRoom = false; + if (!room) { + room = self.createRoom(roomId); + isBrandNewRoom = true; + } + arrObj.room = room; + arrObj.isBrandNewRoom = isBrandNewRoom; + return arrObj; + }); +}; + +/** + * @param {Object} obj + * @param {Room} room + * @return {MatrixEvent[]} + */ +SyncApi.prototype._mapSyncEventsFormat = function(obj, room) { + if (!obj || !utils.isArray(obj.events)) { + return []; + } + var mapper = this.client.getEventMapper(); + return obj.events.map(function(e) { + if (room) { + e.room_id = room.roomId; + } + return mapper(e); + }); +}; + +/** + * @param {Room} room + */ +SyncApi.prototype._resolveInvites = function(room) { + if (!room || !this.opts.resolveInvitesToProfiles) { + return; + } + var client = this.client; + // For each invited room member we want to give them a displayname/avatar url + // if they have one (the m.room.member invites don't contain this). + room.getMembersWithMembership("invite").forEach(function(member) { + if (member._requestedProfileInfo) { + return; + } + member._requestedProfileInfo = true; + // try to get a cached copy first. + var user = client.getUser(member.userId); + var promise; + if (user) { + promise = q({ + avatar_url: user.avatarUrl, + displayname: user.displayName + }); + } + else { + promise = client.getProfileInfo(member.userId); + } + promise.done(function(info) { + // slightly naughty by doctoring the invite event but this means all + // the code paths remain the same between invite/join display name stuff + // which is a worthy trade-off for some minor pollution. + var inviteEvent = member.events.member; + if (inviteEvent.getContent().membership !== "invite") { + // between resolving and now they have since joined, so don't clobber + return; + } + inviteEvent.getContent().avatar_url = info.avatar_url; + inviteEvent.getContent().displayname = info.displayname; + // fire listeners + member.setMembershipEvent(inviteEvent, room.currentState); + }, function(err) { + // OH WELL. + }); + }); +}; + +/** + * @param {Room} room + * @param {MatrixEvent[]} stateEventList A list of state events. This is the state + * at the *START* of the timeline list if it is supplied. + * @param {?MatrixEvent[]} timelineEventList A list of timeline events. Lower index + * is earlier in time. Higher index is later. + */ +SyncApi.prototype._processRoomEvents = function(room, stateEventList, + timelineEventList) { + timelineEventList = timelineEventList || []; + var client = this.client; + // "old" and "current" state are the same initially; they + // start diverging if the user paginates. + // We must deep copy otherwise membership changes in old state + // will leak through to current state! + var oldStateEvents = utils.map( + utils.deepCopy( + stateEventList.map(function(mxEvent) { return mxEvent.event; }) + ), client.getEventMapper() + ); + var stateEvents = stateEventList; + + // set the state of the room to as it was before the timeline executes + // + // XXX: what if we've already seen (some of) the events in the timeline, + // and they modify some of the state set in stateEvents? In that case we'll + // end up with the state from stateEvents, instead of the more recent state + // from the timeline. + room.oldState.setStateEvents(oldStateEvents); + room.currentState.setStateEvents(stateEvents); + + this._resolveInvites(room); + + // recalculate the room name at this point as adding events to the timeline + // may make notifications appear which should have the right name. + room.recalculate(this.client.credentials.userId); + + // execute the timeline events, this will begin to diverge the current state + // if the timeline has any state events in it. + room.addLiveEvents(timelineEventList); +}; + +/** + * @return {string} + */ +SyncApi.prototype._getGuestFilter = function() { + var guestRooms = this.client._guestRooms; // FIXME: horrible gut-wrenching + if (!guestRooms) { + return "{}"; + } + // we just need to specify the filter inline if we're a guest because guests + // can't create filters. + return JSON.stringify({ + room: { + timeline: { + limit: 20 + } + } + }); +}; + +/** + * Sets the sync state and emits an event to say so + * @param {String} newState The new state string + * @param {Object} data Object of additional data to emit in the event + */ +SyncApi.prototype._updateSyncState = function(newState, data) { + var old = this._syncState; + this._syncState = newState; + this.client.emit("sync", this._syncState, old, data); +}; + +/** + * Event handler for the 'online' event + * This event is generally unreliable and precise behaviour + * varies between browsers, so we poll for connectivity too, + * but this might help us reconnect a little faster. + */ +SyncApi.prototype._onOnline = function() { + debuglog("Browser thinks we are back online"); + this._startKeepAlives(0); +}; + +function createNewUser(client, userId) { + var user = new User(userId); + reEmit(client, user, [ + "User.avatarUrl", "User.displayName", "User.presence", + "User.currentlyActive", "User.lastPresenceTs" + ]); + return user; +} + +function reEmit(reEmitEntity, emittableEntity, eventNames) { + utils.forEach(eventNames, function(eventName) { + // setup a listener on the entity (the Room, User, etc) for this event + emittableEntity.on(eventName, function() { + // take the args from the listener and reuse them, adding the + // event name to the arg list so it works with .emit() + // Transformation Example: + // listener on "foo" => function(a,b) { ... } + // Re-emit on "thing" => thing.emit("foo", a, b) + var newArgs = [eventName]; + for (var i = 0; i < arguments.length; i++) { + newArgs.push(arguments[i]); + } + reEmitEntity.emit.apply(reEmitEntity, newArgs); + }); + }); +} + +/** */ +module.exports = SyncApi; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./filter":7,"./models/event-timeline":11,"./models/room":16,"./models/user":18,"./utils":28,"q":205}],27:[function(require,module,exports){ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; + +/** @module timeline-window */ + +var q = require("q"); +var EventTimeline = require("./models/event-timeline"); + +/** + * @private + */ +var DEBUG = false; + +/** + * @private + */ +var debuglog = DEBUG ? console.log.bind(console) : function() {}; + +/** + * the number of times we ask the server for more events before giving up + * + * @private + */ +var DEFAULT_PAGINATE_LOOP_LIMIT = 5; + +/** + * Construct a TimelineWindow. + * + *

This abstracts the separate timelines in a Matrix {@link + * module:models/room~Room|Room} into a single iterable thing. It keeps track of + * the start and endpoints of the window, which can be advanced with the help + * of pagination requests. + * + *

Before the window is useful, it must be initialised by calling {@link + * module:timeline-window~TimelineWindow#load|load}. + * + *

Note that the window will not automatically extend itself when new events + * are received from /sync; you should arrange to call {@link + * module:timeline-window~TimelineWindow#paginate|paginate} on {@link + * module:client~MatrixClient.event:"Room.timeline"|Room.timeline} events. + * + * @param {MatrixClient} client MatrixClient to be used for context/pagination + * requests. + * + * @param {Room} room The room to track + * + * @param {Object} [opts] Configuration options for this window + * + * @param {number} [opts.windowLimit = 1000] maximum number of events to keep + * in the window. If more events are retrieved via pagination requests, + * excess events will be dropped from the other end of the window. + * + * @constructor + */ +function TimelineWindow(client, room, opts) { + opts = opts || {}; + this._client = client; + this._room = room; + + // these will be TimelineIndex objects; they delineate the 'start' and + // 'end' of the window. + // + // _start.index is inclusive; _end.index is exclusive. + this._start = null; + this._end = null; + + this._eventCount = 0; + this._windowLimit = opts.windowLimit || 1000; +} + +/** + * Initialise the window to point at a given event, or the live timeline + * + * @param {string} [initialEventId] If given, the window will contain the + * given event + * @param {number} [initialWindowSize = 20] Size of the initial window + * + * @return {module:client.Promise} + */ +TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) { + var self = this; + initialWindowSize = initialWindowSize || 20; + + // given an EventTimeline, and an event index within it, initialise our + // fields so that the event in question is in the middle of the window. + var initFields = function(timeline, eventIndex) { + var endIndex = Math.min(timeline.getEvents().length, + eventIndex + Math.ceil(initialWindowSize / 2)); + var startIndex = Math.max(0, endIndex - initialWindowSize); + self._start = new TimelineIndex(timeline, startIndex - timeline.getBaseIndex()); + self._end = new TimelineIndex(timeline, endIndex - timeline.getBaseIndex()); + self._eventCount = endIndex - startIndex; + }; + + // We avoid delaying the resolution of the promise by a reactor tick if + // we already have the data we need, which is important to keep room-switching + // feeling snappy. + // + // TODO: ideally we'd spot getEventTimeline returning a resolved promise and + // skip straight to the find-event loop. + if (initialEventId) { + return this._client.getEventTimeline(this._room, initialEventId) + .then(function(tl) { + // make sure that our window includes the event + for (var i = 0; i < tl.getEvents().length; i++) { + if (tl.getEvents()[i].getId() == initialEventId) { + initFields(tl, i); + return; + } + } + throw new Error("getEventTimeline result didn't include requested event"); + }); + } else { + // start with the most recent events + var tl = this._room.getLiveTimeline(); + initFields(tl, tl.getEvents().length); + return q(); + } +}; + +/** + * Check if this window can be extended + * + *

This returns true if we either have more events, or if we have a + * pagination token which means we can paginate in that direction. It does not + * necessarily mean that there are more events available in that direction at + * this time. + * + * @param {string} direction EventTimeline.BACKWARDS to check if we can + * paginate backwards; EventTimeline.FORWARDS to check if we can go forwards + * + * @return {boolean} true if we can paginate in the given direction + */ +TimelineWindow.prototype.canPaginate = function(direction) { + var tl; + if (direction == EventTimeline.BACKWARDS) { + tl = this._start; + } else if (direction == EventTimeline.FORWARDS) { + tl = this._end; + } else { + throw new Error("Invalid direction '" + direction + "'"); + } + + if (!tl) { + debuglog("TimelineWindow: no timeline yet"); + return false; + } + + if (direction == EventTimeline.BACKWARDS) { + if (tl.index > tl.minIndex()) { return true; } + } else { + if (tl.index < tl.maxIndex()) { return true; } + } + + return Boolean(tl.timeline.getNeighbouringTimeline(direction) || + tl.timeline.getPaginationToken(direction)); +}; + +/** + * Attempt to extend the window + * + * @param {string} direction EventTimeline.BACKWARDS to extend the window + * backwards (towards older events); EventTimeline.FORWARDS to go forwards. + * + * @param {number} size number of events to try to extend by. If fewer than this + * number are immediately available, then we return immediately rather than + * making an API call. + * + * @param {boolean} [makeRequest = true] whether we should make API calls to + * fetch further events if we don't have any at all. (This has no effect if + * the room already knows about additional events in the relevant direction, + * even if there are fewer than 'size' of them, as we will just return those + * we already know about.) + * + * @param {number} [requestLimit = 5] limit for the number of API requests we + * should make. + * + * @return {module:client.Promise} Resolves to a boolean which is true if more events + * were successfully retrieved. + */ +TimelineWindow.prototype.paginate = function(direction, size, makeRequest, + requestLimit) { + // Either wind back the message cap (if there are enough events in the + // timeline to do so), or fire off a pagination request. + + if (makeRequest === undefined) { + makeRequest = true; + } + + if (requestLimit === undefined) { + requestLimit = DEFAULT_PAGINATE_LOOP_LIMIT; + } + + var tl; + if (direction == EventTimeline.BACKWARDS) { + tl = this._start; + } else if (direction == EventTimeline.FORWARDS) { + tl = this._end; + } else { + throw new Error("Invalid direction '" + direction + "'"); + } + + if (!tl) { + debuglog("TimelineWindow: no timeline yet"); + return q(false); + } + + if (tl.pendingPaginate) { + return tl.pendingPaginate; + } + + // try moving the cap + var count = (direction == EventTimeline.BACKWARDS) ? + tl.retreat(size) : tl.advance(size); + + if (count) { + this._eventCount += count; + debuglog("TimelineWindow: increased cap by " + count + + " (now " + this._eventCount + ")"); + // remove some events from the other end, if necessary + var excess = this._eventCount - this._windowLimit; + if (excess > 0) { + this._unpaginate(excess, direction != EventTimeline.BACKWARDS); + } + return q(true); + } + + if (!makeRequest || requestLimit === 0) { + // todo: should we return something different to indicate that there + // might be more events out there, but we haven't found them yet? + return q(false); + } + + // try making a pagination request + var token = tl.timeline.getPaginationToken(direction); + if (!token) { + debuglog("TimelineWindow: no token"); + return q(false); + } + + debuglog("TimelineWindow: starting request"); + var self = this; + var prom = this._client.paginateEventTimeline(tl.timeline, { + backwards: direction == EventTimeline.BACKWARDS, + limit: size + }).finally(function() { + tl.pendingPaginate = null; + }).then(function(r) { + debuglog("TimelineWindow: request completed with result " + r); + if (!r) { + // end of timeline + return false; + } + + // recurse to advance the index into the results. + // + // If we don't get any new events, we want to make sure we keep asking + // the server for events for as long as we have a valid pagination + // token. In particular, we want to know if we've actually hit the + // start of the timeline, or if we just happened to know about all of + // the events thanks to https://matrix.org/jira/browse/SYN-645. + // + // On the other hand, we necessarily want to wait forever for the + // server to make its mind up about whether there are other events, + // because it gives a bad user experience + // (https://github.com/vector-im/vector-web/issues/1204). + return self.paginate(direction, size, true, requestLimit - 1); + }); + tl.pendingPaginate = prom; + return prom; +}; + + +/** + * Trim the window to the windowlimit + * + * @param {number} delta number of events to remove from the timeline + * @param {boolean} startOfTimeline if events should be removed from the start + * of the timeline. + * + * @private + */ +TimelineWindow.prototype._unpaginate = function(delta, startOfTimeline) { + var tl = startOfTimeline ? this._start : this._end; + + // sanity-check the delta + if (delta > this._eventCount || delta < 0) { + throw new Error("Attemting to unpaginate " + delta + " events, but " + + "only have " + this._eventCount + " in the timeline"); + } + + while (delta > 0) { + var count = startOfTimeline ? tl.advance(delta) : tl.retreat(delta); + if (count <= 0) { + // sadness. This shouldn't be possible. + throw new Error( + "Unable to unpaginate any further, but still have " + + this._eventCount + " events"); + } + + delta -= count; + this._eventCount -= count; + debuglog("TimelineWindow.unpaginate: dropped " + count + + " (now " + this._eventCount + ")"); + } +}; + + +/** + * Get a list of the events currently in the window + * + * @return {MatrixEvent[]} the events in the window + */ +TimelineWindow.prototype.getEvents = function() { + if (!this._start) { + // not yet loaded + return []; + } + + var result = []; + + // iterate through each timeline between this._start and this._end + // (inclusive). + var timeline = this._start.timeline; + while (true) { + var events = timeline.getEvents(); + + // For the first timeline in the chain, we want to start at + // this._start.index. For the last timeline in the chain, we want to + // stop before this._end.index. Otherwise, we want to copy all of the + // events in the timeline. + // + // (Note that both this._start.index and this._end.index are relative + // to their respective timelines' BaseIndex). + // + var startIndex = 0, endIndex = events.length; + if (timeline === this._start.timeline) { + startIndex = this._start.index + timeline.getBaseIndex(); + } + if (timeline === this._end.timeline) { + endIndex = this._end.index + timeline.getBaseIndex(); + } + + for (var i = startIndex; i < endIndex; i++) { + result.push(events[i]); + } + + // if we're not done, iterate to the next timeline. + if (timeline === this._end.timeline) { + break; + } else { + timeline = timeline.getNeighbouringTimeline(EventTimeline.FORWARDS); + } + } + + return result; +}; + + +/** + * a thing which contains a timeline reference, and an index into it. + * + * @constructor + * @param {EventTimeline} timeline + * @param {number} index + * @private + */ +function TimelineIndex(timeline, index) { + this.timeline = timeline; + + // the indexes are relative to BaseIndex, so could well be negative. + this.index = index; +} + +/** + * @return {number} the minimum possible value for the index in the current + * timeline + */ +TimelineIndex.prototype.minIndex = function() { + return this.timeline.getBaseIndex() * -1; +}; + +/** + * @return {number} the maximum possible value for the index in the current + * timeline (exclusive - ie, it actually returns one more than the index + * of the last element). + */ +TimelineIndex.prototype.maxIndex = function() { + return this.timeline.getEvents().length - this.timeline.getBaseIndex(); +}; + +/** + * Try move the index forward, or into the neighbouring timeline + * + * @param {number} delta number of events to advance by + * @return {number} number of events successfully advanced by + */ +TimelineIndex.prototype.advance = function(delta) { + if (!delta) { + return 0; + } + + // first try moving the index in the current timeline. See if there is room + // to do so. + var cappedDelta; + if (delta < 0) { + // we want to wind the index backwards. + // + // (this.minIndex() - this.index) is a negative number whose magnitude + // is the amount of room we have to wind back the index in the current + // timeline. We cap delta to this quantity. + cappedDelta = Math.max(delta, this.minIndex() - this.index); + if (cappedDelta < 0) { + this.index += cappedDelta; + return cappedDelta; + } + } else { + // we want to wind the index forwards. + // + // (this.maxIndex() - this.index) is a (positive) number whose magnitude + // is the amount of room we have to wind forward the index in the current + // timeline. We cap delta to this quantity. + cappedDelta = Math.min(delta, this.maxIndex() - this.index); + if (cappedDelta > 0) { + this.index += cappedDelta; + return cappedDelta; + } + } + + // the index is already at the start/end of the current timeline. + // + // next see if there is a neighbouring timeline to switch to. + var neighbour = this.timeline.getNeighbouringTimeline( + delta < 0 ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS); + if (neighbour) { + this.timeline = neighbour; + if (delta < 0) { + this.index = this.maxIndex(); + } else { + this.index = this.minIndex(); + } + + debuglog("paginate: switched to new neighbour"); + + // recurse, using the next timeline + return this.advance(delta); + } + + return 0; +}; + +/** + * Try move the index backwards, or into the neighbouring timeline + * + * @param {number} delta number of events to retreat by + * @return {number} number of events successfully retreated by + */ +TimelineIndex.prototype.retreat = function(delta) { + return this.advance(delta * -1) * -1; +}; + +/** + * The TimelineWindow class. + */ +module.exports.TimelineWindow = TimelineWindow; + +/** + * The TimelineIndex class. exported here for unit testing. + */ +module.exports.TimelineIndex = TimelineIndex; + +},{"./models/event-timeline":11,"q":205}],28:[function(require,module,exports){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * This is an internal module. + * @module utils + */ + +/** + * Encode a dictionary of query parameters. + * @param {Object} params A dict of key/values to encode e.g. + * {"foo": "bar", "baz": "taz"} + * @return {string} The encoded string e.g. foo=bar&baz=taz + */ +module.exports.encodeParams = function(params) { + var qs = ""; + for (var key in params) { + if (!params.hasOwnProperty(key)) { continue; } + qs += "&" + encodeURIComponent(key) + "=" + + encodeURIComponent(params[key]); + } + return qs.substring(1); +}; + +/** + * Encodes a URI according to a set of template variables. Variables will be + * passed through encodeURIComponent. + * @param {string} pathTemplate The path with template variables e.g. '/foo/$bar'. + * @param {Object} variables The key/value pairs to replace the template + * variables with. E.g. { "$bar": "baz" }. + * @return {string} The result of replacing all template variables e.g. '/foo/baz'. + */ +module.exports.encodeUri = function(pathTemplate, variables) { + for (var key in variables) { + if (!variables.hasOwnProperty(key)) { continue; } + pathTemplate = pathTemplate.replace( + key, encodeURIComponent(variables[key]) + ); + } + return pathTemplate; +}; + +/** + * Applies a map function to the given array. + * @param {Array} array The array to apply the function to. + * @param {Function} fn The function that will be invoked for each element in + * the array with the signature fn(element){...} + * @return {Array} A new array with the results of the function. + */ +module.exports.map = function(array, fn) { + var results = new Array(array.length); + for (var i = 0; i < array.length; i++) { + results[i] = fn(array[i]); + } + return results; +}; + +/** + * Applies a filter function to the given array. + * @param {Array} array The array to apply the function to. + * @param {Function} fn The function that will be invoked for each element in + * the array. It should return true to keep the element. The function signature + * looks like fn(element, index, array){...}. + * @return {Array} A new array with the results of the function. + */ +module.exports.filter = function(array, fn) { + var results = []; + for (var i = 0; i < array.length; i++) { + if (fn(array[i], i, array)) { + results.push(array[i]); + } + } + return results; +}; + +/** + * Get the keys for an object. Same as Object.keys(). + * @param {Object} obj The object to get the keys for. + * @return {string[]} The keys of the object. + */ +module.exports.keys = function(obj) { + var keys = []; + for (var key in obj) { + if (!obj.hasOwnProperty(key)) { continue; } + keys.push(key); + } + return keys; +}; + +/** + * Get the values for an object. + * @param {Object} obj The object to get the values for. + * @return {Array<*>} The values of the object. + */ +module.exports.values = function(obj) { + var values = []; + for (var key in obj) { + if (!obj.hasOwnProperty(key)) { continue; } + values.push(obj[key]); + } + return values; +}; + +/** + * Invoke a function for each item in the array. + * @param {Array} array The array. + * @param {Function} fn The function to invoke for each element. Has the + * function signature fn(element, index). + */ +module.exports.forEach = function(array, fn) { + for (var i = 0; i < array.length; i++) { + fn(array[i], i); + } +}; + +/** + * The findElement() method returns a value in the array, if an element in the array + * satisfies (returns true) the provided testing function. Otherwise undefined + * is returned. + * @param {Array} array The array. + * @param {Function} fn Function to execute on each value in the array, with the + * function signature fn(element, index, array) + * @param {boolean} reverse True to search in reverse order. + * @return {*} The first value in the array which returns true for + * the given function. + */ +module.exports.findElement = function(array, fn, reverse) { + var i; + if (reverse) { + for (i = array.length - 1; i >= 0; i--) { + if (fn(array[i], i, array)) { + return array[i]; + } + } + } + else { + for (i = 0; i < array.length; i++) { + if (fn(array[i], i, array)) { + return array[i]; + } + } + } +}; + +/** + * The removeElement() method removes the first element in the array that + * satisfies (returns true) the provided testing function. + * @param {Array} array The array. + * @param {Function} fn Function to execute on each value in the array, with the + * function signature fn(element, index, array). Return true to + * remove this element and break. + * @param {boolean} reverse True to search in reverse order. + * @return {boolean} True if an element was removed. + */ +module.exports.removeElement = function(array, fn, reverse) { + var i; + var removed; + if (reverse) { + for (i = array.length - 1; i >= 0; i--) { + if (fn(array[i], i, array)) { + removed = array[i]; + array.splice(i, 1); + return removed; + } + } + } + else { + for (i = 0; i < array.length; i++) { + if (fn(array[i], i, array)) { + removed = array[i]; + array.splice(i, 1); + return removed; + } + } + } + return false; +}; + +/** + * Checks if the given thing is a function. + * @param {*} value The thing to check. + * @return {boolean} True if it is a function. + */ +module.exports.isFunction = function(value) { + return Object.prototype.toString.call(value) == "[object Function]"; +}; + +/** + * Checks if the given thing is an array. + * @param {*} value The thing to check. + * @return {boolean} True if it is an array. + */ +module.exports.isArray = function(value) { + return Boolean(value && value.constructor === Array); +}; + +/** + * Checks that the given object has the specified keys. + * @param {Object} obj The object to check. + * @param {string[]} keys The list of keys that 'obj' must have. + * @throws If the object is missing keys. + */ +module.exports.checkObjectHasKeys = function(obj, keys) { + for (var i = 0; i < keys.length; i++) { + if (!obj.hasOwnProperty(keys[i])) { + throw new Error("Missing required key: " + keys[i]); + } + } +}; + +/** + * Checks that the given object has no extra keys other than the specified ones. + * @param {Object} obj The object to check. + * @param {string[]} allowedKeys The list of allowed key names. + * @throws If there are extra keys. + */ +module.exports.checkObjectHasNoAdditionalKeys = function(obj, allowedKeys) { + for (var key in obj) { + if (!obj.hasOwnProperty(key)) { continue; } + if (allowedKeys.indexOf(key) === -1) { + throw new Error("Unknown key: " + key); + } + } +}; + +/** + * Deep copy the given object. The object MUST NOT have circular references and + * MUST NOT have functions. + * @param {Object} obj The object to deep copy. + * @return {Object} A copy of the object without any references to the original. + */ +module.exports.deepCopy = function(obj) { + return JSON.parse(JSON.stringify(obj)); +}; + +/** + * Compare two objects for equality. The objects MUST NOT have circular references. + * + * @param {Object} x The first object to compare. + * @param {Object} y The second object to compare. + * + * @return {boolean} true if the two objects are equal + */ +var deepCompare = module.exports.deepCompare = function(x, y) { + // Inspired by + // http://stackoverflow.com/questions/1068834/object-comparison-in-javascript#1144249 + + // Compare primitives and functions. + // Also check if both arguments link to the same object. + if (x === y) { + return true; + } + + if (typeof x !== typeof y) { + return false; + } + + // special-case NaN (since NaN !== NaN) + if (typeof x === 'number' && isNaN(x) && isNaN(y)) { + return true; + } + + // special-case null (since typeof null == 'object', but null.constructor + // throws) + if (x === null || y === null) { + return x === y; + } + + // everything else is either an unequal primitive, or an object + if (!(x instanceof Object)) { + return false; + } + + // check they are the same type of object + if (x.constructor !== y.constructor || x.prototype !== y.prototype) { + return false; + } + + // special-casing for some special types of object + if (x instanceof RegExp || x instanceof Date) { + return x.toString() === y.toString(); + } + + // the object algorithm works for Array, but it's sub-optimal. + if (x instanceof Array) { + if (x.length !== y.length) { + return false; + } + + for (var i = 0; i < x.length; i++) { + if (!deepCompare(x[i], y[i])) { + return false; + } + } + } else { + // disable jshint "The body of a for in should be wrapped in an if + // statement" + /* jshint -W089 */ + + // check that all of y's direct keys are in x + var p; + for (p in y) { + if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { + return false; + } + } + + // finally, compare each of x's keys with y + for (p in y) { + if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { + return false; + } + if (!deepCompare(x[p], y[p])) { + return false; + } + } + } + /* jshint +W089 */ + return true; +}; + +/** + * Copy properties from one object to another. + * + * All enumerable properties, included inherited ones, are copied. + * + * @param {Object} target The object that will receive new properties + * @param {...Object} source Objects from which to copy properties + * + * @return {Object} target + */ +module.exports.extend = function() { + var target = arguments[0] || {}; + // disable jshint "The body of a for in should be wrapped in an if + // statement" + /* jshint -W089 */ + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var propName in source) { + target[propName] = source[propName]; + } + } + /* jshint +W089 */ + return target; +}; + +/** + * Run polyfills to add Array.map and Array.filter if they are missing. + */ +module.exports.runPolyfills = function() { + // Array.prototype.filter + // ======================================================== + // SOURCE: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter + if (!Array.prototype.filter) { + Array.prototype.filter = function(fun/*, thisArg*/) { + + if (this === void 0 || this === null) { + throw new TypeError(); + } + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun !== 'function') { + throw new TypeError(); + } + + var res = []; + var thisArg = arguments.length >= 2 ? arguments[1] : void 0; + for (var i = 0; i < len; i++) { + if (i in t) { + var val = t[i]; + + // NOTE: Technically this should Object.defineProperty at + // the next index, as push can be affected by + // properties on Object.prototype and Array.prototype. + // But that method's new, and collisions should be + // rare, so use the more-compatible alternative. + if (fun.call(thisArg, val, i, t)) { + res.push(val); + } + } + } + + return res; + }; + } + + // Array.prototype.map + // ======================================================== + // SOURCE: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map + // Production steps of ECMA-262, Edition 5, 15.4.4.19 + // Reference: http://es5.github.io/#x15.4.4.19 + if (!Array.prototype.map) { + + Array.prototype.map = function(callback, thisArg) { + + var T, A, k; + + if (this === null || this === undefined) { + throw new TypeError(' this is null or not defined'); + } + + // 1. Let O be the result of calling ToObject passing the |this| + // value as the argument. + var O = Object(this); + + // 2. Let lenValue be the result of calling the Get internal + // method of O with the argument "length". + // 3. Let len be ToUint32(lenValue). + var len = O.length >>> 0; + + // 4. If IsCallable(callback) is false, throw a TypeError exception. + // See: http://es5.github.com/#x9.11 + if (typeof callback !== 'function') { + throw new TypeError(callback + ' is not a function'); + } + + // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. + if (arguments.length > 1) { + T = thisArg; + } + + // 6. Let A be a new array created as if by the expression new Array(len) + // where Array is the standard built-in constructor with that name and + // len is the value of len. + A = new Array(len); + + // 7. Let k be 0 + k = 0; + + // 8. Repeat, while k < len + while (k < len) { + + var kValue, mappedValue; + + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the HasProperty internal + // method of O with argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + if (k in O) { + + // i. Let kValue be the result of calling the Get internal + // method of O with argument Pk. + kValue = O[k]; + + // ii. Let mappedValue be the result of calling the Call internal + // method of callback with T as the this value and argument + // list containing kValue, k, and O. + mappedValue = callback.call(T, kValue, k, O); + + // iii. Call the DefineOwnProperty internal method of A with arguments + // Pk, Property Descriptor + // { Value: mappedValue, + // Writable: true, + // Enumerable: true, + // Configurable: true }, + // and false. + + // In browsers that support Object.defineProperty, use the following: + // Object.defineProperty(A, k, { + // value: mappedValue, + // writable: true, + // enumerable: true, + // configurable: true + // }); + + // For best browser support, use the following: + A[k] = mappedValue; + } + // d. Increase k by 1. + k++; + } + + // 9. return A + return A; + }; + } + + // Array.prototype.forEach + // ======================================================== + // SOURCE: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach + // Production steps of ECMA-262, Edition 5, 15.4.4.18 + // Reference: http://es5.github.io/#x15.4.4.18 + if (!Array.prototype.forEach) { + + Array.prototype.forEach = function(callback, thisArg) { + + var T, k; + + if (this === null || this === undefined) { + throw new TypeError(' this is null or not defined'); + } + + // 1. Let O be the result of calling ToObject passing the |this| value as the + // argument. + var O = Object(this); + + // 2. Let lenValue be the result of calling the Get internal method of O with the + // argument "length". + // 3. Let len be ToUint32(lenValue). + var len = O.length >>> 0; + + // 4. If IsCallable(callback) is false, throw a TypeError exception. + // See: http://es5.github.com/#x9.11 + if (typeof callback !== "function") { + throw new TypeError(callback + ' is not a function'); + } + + // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. + if (arguments.length > 1) { + T = thisArg; + } + + // 6. Let k be 0 + k = 0; + + // 7. Repeat, while k < len + while (k < len) { + + var kValue; + + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the HasProperty internal + // method of O with + // argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + if (k in O) { + + // i. Let kValue be the result of calling the Get internal method of O with + // argument Pk + kValue = O[k]; + + // ii. Call the Call internal method of callback with T as the this value and + // argument list containing kValue, k, and O. + callback.call(T, kValue, k, O); + } + // d. Increase k by 1. + k++; + } + // 8. return undefined + }; + } +}; + +/** + * Inherit the prototype methods from one constructor into another. This is a + * port of the Node.js implementation with an Object.create polyfill. + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +module.exports.inherits = function(ctor, superCtor) { + // Add Object.create polyfill for IE8 + // Source: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript + // /Reference/Global_Objects/Object/create#Polyfill + if (typeof Object.create != 'function') { + // Production steps of ECMA-262, Edition 5, 15.2.3.5 + // Reference: http://es5.github.io/#x15.2.3.5 + Object.create = (function() { + // To save on memory, use a shared constructor + function Temp() {} + + // make a safe reference to Object.prototype.hasOwnProperty + var hasOwn = Object.prototype.hasOwnProperty; + + return function(O) { + // 1. If Type(O) is not Object or Null throw a TypeError exception. + if (typeof O != 'object') { + throw new TypeError('Object prototype may only be an Object or null'); + } + + // 2. Let obj be the result of creating a new object as if by the + // expression new Object() where Object is the standard built-in + // constructor with that name + // 3. Set the [[Prototype]] internal property of obj to O. + Temp.prototype = O; + var obj = new Temp(); + Temp.prototype = null; // Let's not keep a stray reference to O... + + // 4. If the argument Properties is present and not undefined, add + // own properties to obj as if by calling the standard built-in + // function Object.defineProperties with arguments obj and + // Properties. + if (arguments.length > 1) { + // Object.defineProperties does ToObject on its first argument. + var Properties = Object(arguments[1]); + for (var prop in Properties) { + if (hasOwn.call(Properties, prop)) { + obj[prop] = Properties[prop]; + } + } + } + + // 5. Return obj + return obj; + }; + })(); + } + // END polyfill + + // Add util.inherits from Node.js + // Source: + // https://github.com/joyent/node/blob/master/lib/util.js + // Copyright Joyent, Inc. and other Node contributors. + // + // 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. + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); +}; + +},{}],29:[function(require,module,exports){ +(function (global){ +/* +Copyright 2015, 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +"use strict"; +/** + * This is an internal module. See {@link createNewMatrixCall} for the public API. + * @module webrtc/call + */ +var utils = require("../utils"); +var EventEmitter = require("events").EventEmitter; +var DEBUG = true; // set true to enable console logging. + +// events: hangup, error(err), replaced(call), state(state, oldState) + +/** + * Construct a new Matrix Call. + * @constructor + * @param {Object} opts Config options. + * @param {string} opts.roomId The room ID for this call. + * @param {Object} opts.webRtc The WebRTC globals from the browser. + * @param {Object} opts.URL The URL global. + * @param {Array} opts.turnServers Optional. A list of TURN servers. + * @param {MatrixClient} opts.client The Matrix Client instance to send events to. + */ +function MatrixCall(opts) { + this.roomId = opts.roomId; + this.client = opts.client; + this.webRtc = opts.webRtc; + this.URL = opts.URL; + // Array of Objects with urls, username, credential keys + this.turnServers = opts.turnServers || []; + if (this.turnServers.length === 0) { + this.turnServers.push({ + urls: [MatrixCall.FALLBACK_STUN_SERVER] + }); + } + utils.forEach(this.turnServers, function(server) { + utils.checkObjectHasKeys(server, ["urls"]); + }); + + this.callId = "c" + new Date().getTime(); + this.state = 'fledgling'; + this.didConnect = false; + + // A queue for candidates waiting to go out. + // We try to amalgamate candidates into a single candidate message where + // possible + this.candidateSendQueue = []; + this.candidateSendTries = 0; + + this.screenSharingStream = null; +} +/** The length of time a call can be ringing for. */ +MatrixCall.CALL_TIMEOUT_MS = 60000; +/** The fallback server to use for STUN. */ +MatrixCall.FALLBACK_STUN_SERVER = 'stun:stun.l.google.com:19302'; +/** An error code when the local client failed to create an offer. */ +MatrixCall.ERR_LOCAL_OFFER_FAILED = "local_offer_failed"; +/** + * An error code when there is no local mic/camera to use. This may be because + * the hardware isn't plugged in, or the user has explicitly denied access. + */ +MatrixCall.ERR_NO_USER_MEDIA = "no_user_media"; + +utils.inherits(MatrixCall, EventEmitter); + +/** + * Place a voice call to this room. + * @throws If you have not specified a listener for 'error' events. + */ +MatrixCall.prototype.placeVoiceCall = function() { + debuglog("placeVoiceCall"); + checkForErrorListener(this); + _placeCallWithConstraints(this, _getUserMediaVideoContraints('voice')); + this.type = 'voice'; +}; + +/** + * Place a video call to this room. + * @param {Element} remoteVideoElement a <video> DOM element + * to render video to. + * @param {Element} localVideoElement a <video> DOM element + * to render the local camera preview. + * @throws If you have not specified a listener for 'error' events. + */ +MatrixCall.prototype.placeVideoCall = function(remoteVideoElement, localVideoElement) { + debuglog("placeVideoCall"); + checkForErrorListener(this); + this.localVideoElement = localVideoElement; + this.remoteVideoElement = remoteVideoElement; + _placeCallWithConstraints(this, _getUserMediaVideoContraints('video')); + this.type = 'video'; + _tryPlayRemoteStream(this); +}; + +/** + * Place a screen-sharing call to this room. This includes audio. + * This method is EXPERIMENTAL and subject to change without warning. It + * only works in Google Chrome. + * @param {Element} remoteVideoElement a <video> DOM element + * to render video to. + * @param {Element} localVideoElement a <video> DOM element + * to render the local camera preview. + * @throws If you have not specified a listener for 'error' events. + */ +MatrixCall.prototype.placeScreenSharingCall = + function(remoteVideoElement, localVideoElement) +{ + debuglog("placeScreenSharingCall"); + checkForErrorListener(this); + var screenConstraints = _getChromeScreenSharingConstraints(this); + if (!screenConstraints) { + return; + } + this.localVideoElement = localVideoElement; + this.remoteVideoElement = remoteVideoElement; + var self = this; + this.webRtc.getUserMedia(screenConstraints, function(stream) { + self.screenSharingStream = stream; + debuglog("Got screen stream, requesting audio stream..."); + var audioConstraints = _getUserMediaVideoContraints('voice'); + _placeCallWithConstraints(self, audioConstraints); + }, function(err) { + self.emit("error", + callError( + MatrixCall.ERR_NO_USER_MEDIA, + "Failed to get screen-sharing stream: " + err + ) + ); + }); + this.type = 'video'; + _tryPlayRemoteStream(this); +}; + +/** + * Retrieve the local <video> DOM element. + * @return {Element} The dom element + */ +MatrixCall.prototype.getLocalVideoElement = function() { + return this.localVideoElement; +}; + +/** + * Retrieve the remote <video> DOM element + * used for playing back video capable streams. + * @return {Element} The dom element + */ +MatrixCall.prototype.getRemoteVideoElement = function() { + return this.remoteVideoElement; +}; + +/** + * Retrieve the remote <audio> DOM element + * used for playing back audio only streams. + * @return {Element} The dom element + */ +MatrixCall.prototype.getRemoteAudioElement = function() { + return this.remoteAudioElement; +}; + +/** + * Set the local <video> DOM element. If this call is active, + * video will be rendered to it immediately. + * @param {Element} element The <video> DOM element. + */ +MatrixCall.prototype.setLocalVideoElement = function(element) { + this.localVideoElement = element; + + if (element && this.localAVStream && this.type === 'video') { + element.autoplay = true; + element.src = this.URL.createObjectURL(this.localAVStream); + element.muted = true; + var self = this; + setTimeout(function() { + var vel = self.getLocalVideoElement(); + if (vel.play) { + vel.play(); + } + }, 0); + } +}; + +/** + * Set the remote <video> DOM element. If this call is active, + * the first received video-capable stream will be rendered to it immediately. + * @param {Element} element The <video> DOM element. + */ +MatrixCall.prototype.setRemoteVideoElement = function(element) { + this.remoteVideoElement = element; + _tryPlayRemoteStream(this); +}; + +/** + * Set the remote <audio> DOM element. If this call is active, + * the first received audio-only stream will be rendered to it immediately. + * @param {Element} element The <video> DOM element. + */ +MatrixCall.prototype.setRemoteAudioElement = function(element) { + this.remoteAudioElement = element; + _tryPlayRemoteAudioStream(this); +}; + +/** + * Configure this call from an invite event. Used by MatrixClient. + * @protected + * @param {MatrixEvent} event The m.call.invite event + */ +MatrixCall.prototype._initWithInvite = function(event) { + this.msg = event.getContent(); + this.peerConn = _createPeerConnection(this); + var self = this; + if (this.peerConn) { + this.peerConn.setRemoteDescription( + new this.webRtc.RtcSessionDescription(this.msg.offer), + hookCallback(self, self._onSetRemoteDescriptionSuccess), + hookCallback(self, self._onSetRemoteDescriptionError) + ); + } + setState(this, 'ringing'); + this.direction = 'inbound'; + + // firefox and OpenWebRTC's RTCPeerConnection doesn't add streams until it + // starts getting media on them so we need to figure out whether a video + // channel has been offered by ourselves. + if ( + this.msg.offer && + this.msg.offer.sdp && + this.msg.offer.sdp.indexOf('m=video') > -1 + ) { + this.type = 'video'; + } + else { + this.type = 'voice'; + } + + if (event.getAge()) { + setTimeout(function() { + if (self.state == 'ringing') { + debuglog("Call invite has expired. Hanging up."); + self.hangupParty = 'remote'; // effectively + setState(self, 'ended'); + stopAllMedia(self); + if (self.peerConn.signalingState != 'closed') { + self.peerConn.close(); + } + self.emit("hangup", self); + } + }, this.msg.lifetime - event.getAge()); + } +}; + +/** + * Configure this call from a hangup event. Used by MatrixClient. + * @protected + * @param {MatrixEvent} event The m.call.hangup event + */ +MatrixCall.prototype._initWithHangup = function(event) { + // perverse as it may seem, sometimes we want to instantiate a call with a + // hangup message (because when getting the state of the room on load, events + // come in reverse order and we want to remember that a call has been hung up) + this.msg = event.getContent(); + setState(this, 'ended'); +}; + +/** + * Answer a call. + */ +MatrixCall.prototype.answer = function() { + debuglog("Answering call %s of type %s", this.callId, this.type); + var self = this; + + if (!this.localAVStream && !this.waitForLocalAVStream) { + this.webRtc.getUserMedia( + _getUserMediaVideoContraints(this.type), + hookCallback(self, self._gotUserMediaForAnswer), + hookCallback(self, self._getUserMediaFailed) + ); + setState(this, 'wait_local_media'); + } else if (this.localAVStream) { + this._gotUserMediaForAnswer(this.localAVStream); + } else if (this.waitForLocalAVStream) { + setState(this, 'wait_local_media'); + } +}; + +/** + * Replace this call with a new call, e.g. for glare resolution. Used by + * MatrixClient. + * @protected + * @param {MatrixCall} newCall The new call. + */ +MatrixCall.prototype._replacedBy = function(newCall) { + debuglog(this.callId + " being replaced by " + newCall.callId); + if (this.state == 'wait_local_media') { + debuglog("Telling new call to wait for local media"); + newCall.waitForLocalAVStream = true; + } else if (this.state == 'create_offer') { + debuglog("Handing local stream to new call"); + newCall._gotUserMediaForAnswer(this.localAVStream); + delete(this.localAVStream); + } else if (this.state == 'invite_sent') { + debuglog("Handing local stream to new call"); + newCall._gotUserMediaForAnswer(this.localAVStream); + delete(this.localAVStream); + } + newCall.localVideoElement = this.localVideoElement; + newCall.remoteVideoElement = this.remoteVideoElement; + newCall.remoteAudioElement = this.remoteAudioElement; + this.successor = newCall; + this.emit("replaced", newCall); + this.hangup(true); +}; + +/** + * Hangup a call. + * @param {string} reason The reason why the call is being hung up. + * @param {boolean} suppressEvent True to suppress emitting an event. + */ +MatrixCall.prototype.hangup = function(reason, suppressEvent) { + debuglog("Ending call " + this.callId); + terminate(this, "local", reason, !suppressEvent); + var content = { + version: 0, + call_id: this.callId, + reason: reason + }; + sendEvent(this, 'm.call.hangup', content); +}; + +/** + * Set whether the local video preview should be muted or not. + * @param {boolean} muted True to mute the local video. + */ +MatrixCall.prototype.setLocalVideoMuted = function(muted) { + if (!this.localAVStream) { + return; + } + setTracksEnabled(this.localAVStream.getVideoTracks(), !muted); +}; + +/** + * Check if local video is muted. + * + * If there are multiple video tracks, all of the tracks need to be muted + * for this to return true. This means if there are no video tracks, this will + * return true. + * @return {Boolean} True if the local preview video is muted, else false + * (including if the call is not set up yet). + */ +MatrixCall.prototype.isLocalVideoMuted = function() { + if (!this.localAVStream) { + return false; + } + return !isTracksEnabled(this.localAVStream.getVideoTracks()); +}; + +/** + * Set whether the microphone should be muted or not. + * @param {boolean} muted True to mute the mic. + */ +MatrixCall.prototype.setMicrophoneMuted = function(muted) { + if (!this.localAVStream) { + return; + } + setTracksEnabled(this.localAVStream.getAudioTracks(), !muted); +}; + +/** + * Check if the microphone is muted. + * + * If there are multiple audio tracks, all of the tracks need to be muted + * for this to return true. This means if there are no audio tracks, this will + * return true. + * @return {Boolean} True if the mic is muted, else false (including if the call + * is not set up yet). + */ +MatrixCall.prototype.isMicrophoneMuted = function() { + if (!this.localAVStream) { + return false; + } + return !isTracksEnabled(this.localAVStream.getAudioTracks()); +}; + +/** + * Internal + * @private + * @param {Object} stream + */ +MatrixCall.prototype._gotUserMediaForInvite = function(stream) { + if (this.successor) { + this.successor._gotUserMediaForAnswer(stream); + return; + } + if (this.state == 'ended') { + return; + } + debuglog("_gotUserMediaForInvite -> " + this.type); + var self = this; + var videoEl = this.getLocalVideoElement(); + + if (videoEl && this.type == 'video') { + videoEl.autoplay = true; + if (this.screenSharingStream) { + debuglog("Setting screen sharing stream to the local video element"); + videoEl.src = this.URL.createObjectURL(this.screenSharingStream); + } + else { + videoEl.src = this.URL.createObjectURL(stream); + } + videoEl.muted = true; + setTimeout(function() { + var vel = self.getLocalVideoElement(); + if (vel.play) { + vel.play(); + } + }, 0); + } + + this.localAVStream = stream; + // why do we enable audio (and only audio) tracks here? -- matthew + setTracksEnabled(stream.getAudioTracks(), true); + this.peerConn = _createPeerConnection(this); + this.peerConn.addStream(stream); + if (this.screenSharingStream) { + console.log("Adding screen-sharing stream to peer connection"); + this.peerConn.addStream(this.screenSharingStream); + // let's use this for the local preview... + this.localAVStream = this.screenSharingStream; + } + this.peerConn.createOffer( + hookCallback(self, self._gotLocalOffer), + hookCallback(self, self._getLocalOfferFailed) + ); + setState(self, 'create_offer'); +}; + +/** + * Internal + * @private + * @param {Object} stream + */ +MatrixCall.prototype._gotUserMediaForAnswer = function(stream) { + var self = this; + if (self.state == 'ended') { + return; + } + var localVidEl = self.getLocalVideoElement(); + + if (localVidEl && self.type == 'video') { + localVidEl.autoplay = true; + localVidEl.src = self.URL.createObjectURL(stream); + localVidEl.muted = true; + setTimeout(function() { + var vel = self.getLocalVideoElement(); + if (vel.play) { + vel.play(); + } + }, 0); + } + + self.localAVStream = stream; + setTracksEnabled(stream.getAudioTracks(), true); + self.peerConn.addStream(stream); + + var constraints = { + 'mandatory': { + 'OfferToReceiveAudio': true, + 'OfferToReceiveVideo': self.type == 'video' + } + }; + self.peerConn.createAnswer(function(description) { + debuglog("Created answer: " + description); + self.peerConn.setLocalDescription(description, function() { + var content = { + version: 0, + call_id: self.callId, + answer: { + sdp: self.peerConn.localDescription.sdp, + type: self.peerConn.localDescription.type + } + }; + sendEvent(self, 'm.call.answer', content); + setState(self, 'connecting'); + }, function() { + debuglog("Error setting local description!"); + }, constraints); + }, function(err) { + debuglog("Failed to create answer: " + err); + }); + setState(self, 'create_answer'); +}; + +/** + * Internal + * @private + * @param {Object} event + */ +MatrixCall.prototype._gotLocalIceCandidate = function(event) { + if (event.candidate) { + debuglog( + "Got local ICE " + event.candidate.sdpMid + " candidate: " + + event.candidate.candidate + ); + // As with the offer, note we need to make a copy of this object, not + // pass the original: that broke in Chrome ~m43. + var c = { + candidate: event.candidate.candidate, + sdpMid: event.candidate.sdpMid, + sdpMLineIndex: event.candidate.sdpMLineIndex + }; + sendCandidate(this, c); + } +}; + +/** + * Used by MatrixClient. + * @protected + * @param {Object} cand + */ +MatrixCall.prototype._gotRemoteIceCandidate = function(cand) { + if (this.state == 'ended') { + //debuglog("Ignoring remote ICE candidate because call has ended"); + return; + } + debuglog("Got remote ICE " + cand.sdpMid + " candidate: " + cand.candidate); + this.peerConn.addIceCandidate( + new this.webRtc.RtcIceCandidate(cand), + function() {}, + function(e) {} + ); +}; + +/** + * Used by MatrixClient. + * @protected + * @param {Object} msg + */ +MatrixCall.prototype._receivedAnswer = function(msg) { + if (this.state == 'ended') { + return; + } + + var self = this; + this.peerConn.setRemoteDescription( + new this.webRtc.RtcSessionDescription(msg.answer), + hookCallback(self, self._onSetRemoteDescriptionSuccess), + hookCallback(self, self._onSetRemoteDescriptionError) + ); + setState(self, 'connecting'); +}; + +/** + * Internal + * @private + * @param {Object} description + */ +MatrixCall.prototype._gotLocalOffer = function(description) { + var self = this; + debuglog("Created offer: " + description); + + if (self.state == 'ended') { + debuglog("Ignoring newly created offer on call ID " + self.callId + + " because the call has ended"); + return; + } + + self.peerConn.setLocalDescription(description, function() { + var content = { + version: 0, + call_id: self.callId, + // OpenWebRTC appears to add extra stuff (like the DTLS fingerprint) + // to the description when setting it on the peerconnection. + // According to the spec it should only add ICE + // candidates. Any ICE candidates that have already been generated + // at this point will probably be sent both in the offer and separately. + // Also, note that we have to make a new object here, copying the + // type and sdp properties. + // Passing the RTCSessionDescription object as-is doesn't work in + // Chrome (as of about m43). + offer: { + sdp: self.peerConn.localDescription.sdp, + type: self.peerConn.localDescription.type + }, + lifetime: MatrixCall.CALL_TIMEOUT_MS + }; + sendEvent(self, 'm.call.invite', content); + + setTimeout(function() { + if (self.state == 'invite_sent') { + self.hangup('invite_timeout'); + } + }, MatrixCall.CALL_TIMEOUT_MS); + setState(self, 'invite_sent'); + }, function() { + debuglog("Error setting local description!"); + }); +}; + +/** + * Internal + * @private + * @param {Object} error + */ +MatrixCall.prototype._getLocalOfferFailed = function(error) { + this.emit( + "error", + callError(MatrixCall.ERR_LOCAL_OFFER_FAILED, "Failed to start audio for call!") + ); +}; + +/** + * Internal + * @private + * @param {Object} error + */ +MatrixCall.prototype._getUserMediaFailed = function(error) { + this.emit( + "error", + callError( + MatrixCall.ERR_NO_USER_MEDIA, + "Couldn't start capturing media! Is your microphone set up and " + + "does this app have permission?" + ) + ); + this.hangup("user_media_failed"); +}; + +/** + * Internal + * @private + */ +MatrixCall.prototype._onIceConnectionStateChanged = function() { + if (this.state == 'ended') { + return; // because ICE can still complete as we're ending the call + } + debuglog( + "Ice connection state changed to: " + this.peerConn.iceConnectionState + ); + // ideally we'd consider the call to be connected when we get media but + // chrome doesn't implement any of the 'onstarted' events yet + if (this.peerConn.iceConnectionState == 'completed' || + this.peerConn.iceConnectionState == 'connected') { + setState(this, 'connected'); + this.didConnect = true; + } else if (this.peerConn.iceConnectionState == 'failed') { + this.hangup('ice_failed'); + } +}; + +/** + * Internal + * @private + */ +MatrixCall.prototype._onSignallingStateChanged = function() { + debuglog( + "call " + this.callId + ": Signalling state changed to: " + + this.peerConn.signalingState + ); +}; + +/** + * Internal + * @private + */ +MatrixCall.prototype._onSetRemoteDescriptionSuccess = function() { + debuglog("Set remote description"); +}; + +/** + * Internal + * @private + * @param {Object} e + */ +MatrixCall.prototype._onSetRemoteDescriptionError = function(e) { + debuglog("Failed to set remote description" + e); +}; + +/** + * Internal + * @private + * @param {Object} event + */ +MatrixCall.prototype._onAddStream = function(event) { + debuglog("Stream id " + event.stream.id + " added"); + + var s = event.stream; + + if (s.getVideoTracks().length > 0) { + this.type = 'video'; + this.remoteAVStream = s; + } else { + this.type = 'voice'; + this.remoteAStream = s; + } + + var self = this; + forAllTracksOnStream(s, function(t) { + debuglog("Track id " + t.id + " added"); + // not currently implemented in chrome + t.onstarted = hookCallback(self, self._onRemoteStreamTrackStarted); + }); + + event.stream.onended = hookCallback(self, self._onRemoteStreamEnded); + // not currently implemented in chrome + event.stream.onstarted = hookCallback(self, self._onRemoteStreamStarted); + + if (this.type === 'video') { + _tryPlayRemoteStream(this); + } + else { + _tryPlayRemoteAudioStream(this); + } +}; + +/** + * Internal + * @private + * @param {Object} event + */ +MatrixCall.prototype._onRemoteStreamStarted = function(event) { + setState(this, 'connected'); +}; + +/** + * Internal + * @private + * @param {Object} event + */ +MatrixCall.prototype._onRemoteStreamEnded = function(event) { + debuglog("Remote stream ended"); + this.hangupParty = 'remote'; + setState(this, 'ended'); + stopAllMedia(this); + if (this.peerConn.signalingState != 'closed') { + this.peerConn.close(); + } + this.emit("hangup", this); +}; + +/** + * Internal + * @private + * @param {Object} event + */ +MatrixCall.prototype._onRemoteStreamTrackStarted = function(event) { + setState(this, 'connected'); +}; + +/** + * Used by MatrixClient. + * @protected + * @param {Object} msg + */ +MatrixCall.prototype._onHangupReceived = function(msg) { + debuglog("Hangup received"); + terminate(this, "remote", msg.reason, true); +}; + +/** + * Used by MatrixClient. + * @protected + * @param {Object} msg + */ +MatrixCall.prototype._onAnsweredElsewhere = function(msg) { + debuglog("Answered elsewhere"); + terminate(this, "remote", "answered_elsewhere", true); +}; + +var setTracksEnabled = function(tracks, enabled) { + for (var i = 0; i < tracks.length; i++) { + tracks[i].enabled = enabled; + } +}; + +var isTracksEnabled = function(tracks) { + for (var i = 0; i < tracks.length; i++) { + if (tracks[i].enabled) { + return true; // at least one track is enabled + } + } + return false; +}; + +var setState = function(self, state) { + var oldState = self.state; + self.state = state; + self.emit("state", state, oldState); +}; + +/** + * Internal + * @param {MatrixCall} self + * @param {string} eventType + * @param {Object} content + * @return {Promise} + */ +var sendEvent = function(self, eventType, content) { + return self.client.sendEvent(self.roomId, eventType, content); +}; + +var sendCandidate = function(self, content) { + // Sends candidates with are sent in a special way because we try to amalgamate + // them into one message + self.candidateSendQueue.push(content); + if (self.candidateSendTries === 0) { + setTimeout(function() { + _sendCandidateQueue(self); + }, 100); + } +}; + +var terminate = function(self, hangupParty, hangupReason, shouldEmit) { + if (self.getRemoteVideoElement()) { + if (self.getRemoteVideoElement().pause) { + self.getRemoteVideoElement().pause(); + } + self.getRemoteVideoElement().src = ""; + } + if (self.getRemoteAudioElement()) { + if (self.getRemoteAudioElement().pause) { + self.getRemoteAudioElement().pause(); + } + self.getRemoteAudioElement().src = ""; + } + if (self.getLocalVideoElement()) { + if (self.getLocalVideoElement().pause) { + self.getLocalVideoElement().pause(); + } + self.getLocalVideoElement().src = ""; + } + self.hangupParty = hangupParty; + self.hangupReason = hangupReason; + setState(self, 'ended'); + stopAllMedia(self); + if (self.peerConn && self.peerConn.signalingState !== 'closed') { + self.peerConn.close(); + } + if (shouldEmit) { + self.emit("hangup", self); + } +}; + +var stopAllMedia = function(self) { + debuglog("stopAllMedia (stream=%s)", self.localAVStream); + if (self.localAVStream) { + forAllTracksOnStream(self.localAVStream, function(t) { + if (t.stop) { + t.stop(); + } + }); + // also call stop on the main stream so firefox will stop sharing + // the mic + if (self.localAVStream.stop) { + self.localAVStream.stop(); + } + } + if (self.screenSharingStream) { + forAllTracksOnStream(self.screenSharingStream, function(t) { + if (t.stop) { + t.stop(); + } + }); + if (self.screenSharingStream.stop) { + self.screenSharingStream.stop(); + } + } + if (self.remoteAVStream) { + forAllTracksOnStream(self.remoteAVStream, function(t) { + if (t.stop) { + t.stop(); + } + }); + } + if (self.remoteAStream) { + forAllTracksOnStream(self.remoteAStream, function(t) { + if (t.stop) { + t.stop(); + } + }); + } +}; + +var _tryPlayRemoteStream = function(self) { + if (self.getRemoteVideoElement() && self.remoteAVStream) { + var player = self.getRemoteVideoElement(); + player.autoplay = true; + player.src = self.URL.createObjectURL(self.remoteAVStream); + setTimeout(function() { + var vel = self.getRemoteVideoElement(); + if (vel.play) { + vel.play(); + } + // OpenWebRTC does not support oniceconnectionstatechange yet + if (self.webRtc.isOpenWebRTC()) { + setState(self, 'connected'); + } + }, 0); + } +}; + +var _tryPlayRemoteAudioStream = function(self) { + if (self.getRemoteAudioElement() && self.remoteAStream) { + var player = self.getRemoteAudioElement(); + player.autoplay = true; + player.src = self.URL.createObjectURL(self.remoteAStream); + setTimeout(function() { + var ael = self.getRemoteAudioElement(); + if (ael.play) { + ael.play(); + } + // OpenWebRTC does not support oniceconnectionstatechange yet + if (self.webRtc.isOpenWebRTC()) { + setState(self, 'connected'); + } + }, 0); + } +}; + +var checkForErrorListener = function(self) { + if (self.listeners("error").length === 0) { + throw new Error( + "You MUST attach an error listener using call.on('error', function() {})" + ); + } +}; + +var callError = function(code, msg) { + var e = new Error(msg); + e.code = code; + return e; +}; + +var debuglog = function() { + if (DEBUG) { + console.log.apply(console, arguments); + } +}; + +var _sendCandidateQueue = function(self) { + if (self.candidateSendQueue.length === 0) { + return; + } + + var cands = self.candidateSendQueue; + self.candidateSendQueue = []; + ++self.candidateSendTries; + var content = { + version: 0, + call_id: self.callId, + candidates: cands + }; + debuglog("Attempting to send " + cands.length + " candidates"); + sendEvent(self, 'm.call.candidates', content).then(function() { + self.candidateSendTries = 0; + _sendCandidateQueue(self); + }, function(error) { + for (var i = 0; i < cands.length; i++) { + self.candidateSendQueue.push(cands[i]); + } + + if (self.candidateSendTries > 5) { + debuglog( + "Failed to send candidates on attempt %s. Giving up for now.", + self.candidateSendTries + ); + self.candidateSendTries = 0; + return; + } + + var delayMs = 500 * Math.pow(2, self.candidateSendTries); + ++self.candidateSendTries; + debuglog("Failed to send candidates. Retrying in " + delayMs + "ms"); + setTimeout(function() { + _sendCandidateQueue(self); + }, delayMs); + }); +}; + +var _placeCallWithConstraints = function(self, constraints) { + self.client.callList[self.callId] = self; + self.webRtc.getUserMedia( + constraints, + hookCallback(self, self._gotUserMediaForInvite), + hookCallback(self, self._getUserMediaFailed) + ); + setState(self, 'wait_local_media'); + self.direction = 'outbound'; + self.config = constraints; +}; + +var _createPeerConnection = function(self) { + var servers = self.turnServers; + if (self.webRtc.vendor === "mozilla") { + // modify turnServers struct to match what mozilla expects. + servers = []; + for (var i = 0; i < self.turnServers.length; i++) { + for (var j = 0; j < self.turnServers[i].urls.length; j++) { + servers.push({ + url: self.turnServers[i].urls[j], + username: self.turnServers[i].username, + credential: self.turnServers[i].credential + }); + } + } + } + + var pc = new self.webRtc.RtcPeerConnection({ + iceServers: servers + }); + pc.oniceconnectionstatechange = hookCallback(self, self._onIceConnectionStateChanged); + pc.onsignalingstatechange = hookCallback(self, self._onSignallingStateChanged); + pc.onicecandidate = hookCallback(self, self._gotLocalIceCandidate); + pc.onaddstream = hookCallback(self, self._onAddStream); + return pc; +}; + +var _getChromeScreenSharingConstraints = function(call) { + var screen = global.screen; + if (!screen) { + call.emit("error", callError( + MatrixCall.ERR_NO_USER_MEDIA, + "Couldn't determine screen sharing constaints." + )); + return; + } + // it won't work at all if you're not on HTTPS so whine whine whine + if (!global.window || global.window.location.protocol !== "https:") { + call.emit("error", callError( + MatrixCall.ERR_NO_USER_MEDIA, + "You need to be using HTTPS to place a screen-sharing call." + )); + return; + } + + return { + video: { + mandatory: { + chromeMediaSource: "screen", + chromeMediaSourceId: "" + Date.now(), + maxWidth: screen.width, + maxHeight: screen.height, + minFrameRate: 1, + maxFrameRate: 10 + } + } + }; +}; + +var _getUserMediaVideoContraints = function(callType) { + switch (callType) { + case 'voice': + return ({audio: true, video: false}); + case 'video': + return ({audio: true, video: { + mandatory: { + minWidth: 640, + maxWidth: 640, + minHeight: 360, + maxHeight: 360 + } + }}); + } +}; + +var hookCallback = function(call, fn) { + return function() { + return fn.apply(call, arguments); + }; +}; + +var forAllVideoTracksOnStream = function(s, f) { + var tracks = s.getVideoTracks(); + for (var i = 0; i < tracks.length; i++) { + f(tracks[i]); + } +}; + +var forAllAudioTracksOnStream = function(s, f) { + var tracks = s.getAudioTracks(); + for (var i = 0; i < tracks.length; i++) { + f(tracks[i]); + } +}; + +var forAllTracksOnStream = function(s, f) { + forAllVideoTracksOnStream(s, f); + forAllAudioTracksOnStream(s, f); +}; + +/** The MatrixCall class. */ +module.exports.MatrixCall = MatrixCall; + +/** + * Create a new Matrix call for the browser. + * @param {MatrixClient} client The client instance to use. + * @param {string} roomId The room the call is in. + * @return {MatrixCall} the call or null if the browser doesn't support calling. + */ +module.exports.createNewMatrixCall = function(client, roomId) { + var w = global.window; + var doc = global.document; + if (!w || !doc) { + return null; + } + var webRtc = {}; + webRtc.isOpenWebRTC = function() { + var scripts = doc.getElementById("script"); + if (!scripts || !scripts.length) { + return false; + } + for (var i = 0; i < scripts.length; i++) { + if (scripts[i].src.indexOf("owr.js") > -1) { + return true; + } + } + return false; + }; + var getUserMedia = ( + w.navigator.getUserMedia || w.navigator.webkitGetUserMedia || + w.navigator.mozGetUserMedia + ); + if (getUserMedia) { + webRtc.getUserMedia = function() { + return getUserMedia.apply(w.navigator, arguments); + }; + } + webRtc.RtcPeerConnection = ( + w.RTCPeerConnection || w.webkitRTCPeerConnection || w.mozRTCPeerConnection + ); + webRtc.RtcSessionDescription = ( + w.RTCSessionDescription || w.webkitRTCSessionDescription || + w.mozRTCSessionDescription + ); + webRtc.RtcIceCandidate = ( + w.RTCIceCandidate || w.webkitRTCIceCandidate || w.mozRTCIceCandidate + ); + webRtc.vendor = null; + if (w.mozRTCPeerConnection) { + webRtc.vendor = "mozilla"; + } + else if (w.webkitRTCPeerConnection) { + webRtc.vendor = "webkit"; + } + else if (w.RTCPeerConnection) { + webRtc.vendor = "generic"; + } + if (!webRtc.RtcIceCandidate || !webRtc.RtcSessionDescription || + !webRtc.RtcPeerConnection || !webRtc.getUserMedia) { + return null; // WebRTC is not supported. + } + var opts = { + webRtc: webRtc, + client: client, + URL: w.URL, + roomId: roomId, + turnServers: client.getTurnServers() + }; + return new MatrixCall(opts); +}; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"../utils":28,"events":179}],30:[function(require,module,exports){ +/* Copyright 2015 Mark Haines + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +var escaped = /[\\\"\x00-\x1F]/g; +var escapes = {}; +for (var i = 0; i < 0x20; ++i) { + escapes[String.fromCharCode(i)] = ( + '\\U' + ('0000' + i.toString(16)).slice(-4).toUpperCase() + ); +} +escapes['\b'] = '\\b'; +escapes['\t'] = '\\t'; +escapes['\n'] = '\\n'; +escapes['\f'] = '\\f'; +escapes['\r'] = '\\r'; +escapes['\"'] = '\\\"'; +escapes['\\'] = '\\\\'; + +function escapeString(value) { + escaped.lastIndex = 0; + return value.replace(escaped, function(c) { return escapes[c]; }); +} + +function stringify(value) { + switch (typeof value) { + case 'string': + return '"' + escapeString(value) + '"'; + case 'number': + return isFinite(value) ? value : 'null'; + case 'boolean': + return value; + case 'object': + if (value === null) { + return 'null'; + } + if (Array.isArray(value)) { + return stringifyArray(value); + } + return stringifyObject(value); + default: + throw new Error('Cannot stringify: ' + typeof value); + } +} + +function stringifyArray(array) { + var sep = '['; + var result = ''; + for (var i = 0; i < array.length; ++i) { + result += sep; + sep = ','; + result += stringify(array[i]); + } + if (sep != ',') { + return '[]'; + } else { + return result + ']'; + } +} + +function stringifyObject(object) { + var sep = '{'; + var result = ''; + var keys = Object.keys(object); + keys.sort(); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + result += sep + '"' + escapeString(key) + '":'; + sep = ','; + result += stringify(object[key]); + } + if (sep != ',') { + return '{}'; + } else { + return result + '}'; + } +} + +/** */ +module.exports = {stringify: stringify}; + +},{}],31:[function(require,module,exports){ +// Browser Request +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// UMD HEADER START +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like enviroments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.returnExports = factory(); + } +}(this, function () { +// UMD HEADER END + +var XHR = XMLHttpRequest +if (!XHR) throw new Error('missing XMLHttpRequest') +request.log = { + 'trace': noop, 'debug': noop, 'info': noop, 'warn': noop, 'error': noop +} + +var DEFAULT_TIMEOUT = 3 * 60 * 1000 // 3 minutes + +// +// request +// + +function request(options, callback) { + // The entry-point to the API: prep the options object and pass the real work to run_xhr. + if(typeof callback !== 'function') + throw new Error('Bad callback given: ' + callback) + + if(!options) + throw new Error('No options given') + + var options_onResponse = options.onResponse; // Save this for later. + + if(typeof options === 'string') + options = {'uri':options}; + else + options = JSON.parse(JSON.stringify(options)); // Use a duplicate for mutating. + + options.onResponse = options_onResponse // And put it back. + + if (options.verbose) request.log = getLogger(); + + if(options.url) { + options.uri = options.url; + delete options.url; + } + + if(!options.uri && options.uri !== "") + throw new Error("options.uri is a required argument"); + + if(typeof options.uri != "string") + throw new Error("options.uri must be a string"); + + var unsupported_options = ['proxy', '_redirectsFollowed', 'maxRedirects', 'followRedirect'] + for (var i = 0; i < unsupported_options.length; i++) + if(options[ unsupported_options[i] ]) + throw new Error("options." + unsupported_options[i] + " is not supported") + + options.callback = callback + options.method = options.method || 'GET'; + options.headers = options.headers || {}; + options.body = options.body || null + options.timeout = options.timeout || request.DEFAULT_TIMEOUT + + if(options.headers.host) + throw new Error("Options.headers.host is not supported"); + + if(options.json) { + options.headers.accept = options.headers.accept || 'application/json' + if(options.method !== 'GET') + options.headers['content-type'] = 'application/json' + + if(typeof options.json !== 'boolean') + options.body = JSON.stringify(options.json) + else if(typeof options.body !== 'string') + options.body = JSON.stringify(options.body) + } + + //BEGIN QS Hack + var serialize = function(obj) { + var str = []; + for(var p in obj) + if (obj.hasOwnProperty(p)) { + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); + } + return str.join("&"); + } + + if(options.qs){ + var qs = (typeof options.qs == 'string')? options.qs : serialize(options.qs); + if(options.uri.indexOf('?') !== -1){ //no get params + options.uri = options.uri+'&'+qs; + }else{ //existing get params + options.uri = options.uri+'?'+qs; + } + } + //END QS Hack + + //BEGIN FORM Hack + var multipart = function(obj) { + //todo: support file type (useful?) + var result = {}; + result.boundry = '-------------------------------'+Math.floor(Math.random()*1000000000); + var lines = []; + for(var p in obj){ + if (obj.hasOwnProperty(p)) { + lines.push( + '--'+result.boundry+"\n"+ + 'Content-Disposition: form-data; name="'+p+'"'+"\n"+ + "\n"+ + obj[p]+"\n" + ); + } + } + lines.push( '--'+result.boundry+'--' ); + result.body = lines.join(''); + result.length = result.body.length; + result.type = 'multipart/form-data; boundary='+result.boundry; + return result; + } + + if(options.form){ + if(typeof options.form == 'string') throw('form name unsupported'); + if(options.method === 'POST'){ + var encoding = (options.encoding || 'application/x-www-form-urlencoded').toLowerCase(); + options.headers['content-type'] = encoding; + switch(encoding){ + case 'application/x-www-form-urlencoded': + options.body = serialize(options.form).replace(/%20/g, "+"); + break; + case 'multipart/form-data': + var multi = multipart(options.form); + //options.headers['content-length'] = multi.length; + options.body = multi.body; + options.headers['content-type'] = multi.type; + break; + default : throw new Error('unsupported encoding:'+encoding); + } + } + } + //END FORM Hack + + // If onResponse is boolean true, call back immediately when the response is known, + // not when the full request is complete. + options.onResponse = options.onResponse || noop + if(options.onResponse === true) { + options.onResponse = callback + options.callback = noop + } + + // XXX Browsers do not like this. + //if(options.body) + // options.headers['content-length'] = options.body.length; + + // HTTP basic authentication + if(!options.headers.authorization && options.auth) + options.headers.authorization = 'Basic ' + b64_enc(options.auth.username + ':' + options.auth.password); + + return run_xhr(options) +} + +var req_seq = 0 +function run_xhr(options) { + var xhr = new XHR + , timed_out = false + , is_cors = is_crossDomain(options.uri) + , supports_cors = ('withCredentials' in xhr) + + req_seq += 1 + xhr.seq_id = req_seq + xhr.id = req_seq + ': ' + options.method + ' ' + options.uri + xhr._id = xhr.id // I know I will type "_id" from habit all the time. + + if(is_cors && !supports_cors) { + var cors_err = new Error('Browser does not support cross-origin request: ' + options.uri) + cors_err.cors = 'unsupported' + return options.callback(cors_err, xhr) + } + + xhr.timeoutTimer = setTimeout(too_late, options.timeout) + function too_late() { + timed_out = true + var er = new Error('ETIMEDOUT') + er.code = 'ETIMEDOUT' + er.duration = options.timeout + + request.log.error('Timeout', { 'id':xhr._id, 'milliseconds':options.timeout }) + return options.callback(er, xhr) + } + + // Some states can be skipped over, so remember what is still incomplete. + var did = {'response':false, 'loading':false, 'end':false} + + xhr.onreadystatechange = on_state_change + xhr.open(options.method, options.uri, true) // asynchronous + if(is_cors) + xhr.withCredentials = !! options.withCredentials + xhr.send(options.body) + return xhr + + function on_state_change(event) { + if(timed_out) + return request.log.debug('Ignoring timed out state change', {'state':xhr.readyState, 'id':xhr.id}) + + request.log.debug('State change', {'state':xhr.readyState, 'id':xhr.id, 'timed_out':timed_out}) + + if(xhr.readyState === XHR.OPENED) { + request.log.debug('Request started', {'id':xhr.id}) + for (var key in options.headers) + xhr.setRequestHeader(key, options.headers[key]) + } + + else if(xhr.readyState === XHR.HEADERS_RECEIVED) + on_response() + + else if(xhr.readyState === XHR.LOADING) { + on_response() + on_loading() + } + + else if(xhr.readyState === XHR.DONE) { + on_response() + on_loading() + on_end() + } + } + + function on_response() { + if(did.response) + return + + did.response = true + request.log.debug('Got response', {'id':xhr.id, 'status':xhr.status}) + clearTimeout(xhr.timeoutTimer) + xhr.statusCode = xhr.status // Node request compatibility + + // Detect failed CORS requests. + if(is_cors && xhr.statusCode == 0) { + var cors_err = new Error('CORS request rejected: ' + options.uri) + cors_err.cors = 'rejected' + + // Do not process this request further. + did.loading = true + did.end = true + + return options.callback(cors_err, xhr) + } + + options.onResponse(null, xhr) + } + + function on_loading() { + if(did.loading) + return + + did.loading = true + request.log.debug('Response body loading', {'id':xhr.id}) + // TODO: Maybe simulate "data" events by watching xhr.responseText + } + + function on_end() { + if(did.end) + return + + did.end = true + request.log.debug('Request done', {'id':xhr.id}) + + xhr.body = xhr.responseText + if(options.json) { + try { xhr.body = JSON.parse(xhr.responseText) } + catch (er) { return options.callback(er, xhr) } + } + + options.callback(null, xhr, xhr.body) + } + +} // request + +request.withCredentials = false; +request.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT; + +// +// defaults +// + +request.defaults = function(options, requester) { + var def = function (method) { + var d = function (params, callback) { + if(typeof params === 'string') + params = {'uri': params}; + else { + params = JSON.parse(JSON.stringify(params)); + } + for (var i in options) { + if (params[i] === undefined) params[i] = options[i] + } + return method(params, callback) + } + return d + } + var de = def(request) + de.get = def(request.get) + de.post = def(request.post) + de.put = def(request.put) + de.head = def(request.head) + return de +} + +// +// HTTP method shortcuts +// + +var shortcuts = [ 'get', 'put', 'post', 'head' ]; +shortcuts.forEach(function(shortcut) { + var method = shortcut.toUpperCase(); + var func = shortcut.toLowerCase(); + + request[func] = function(opts) { + if(typeof opts === 'string') + opts = {'method':method, 'uri':opts}; + else { + opts = JSON.parse(JSON.stringify(opts)); + opts.method = method; + } + + var args = [opts].concat(Array.prototype.slice.apply(arguments, [1])); + return request.apply(this, args); + } +}) + +// +// CouchDB shortcut +// + +request.couch = function(options, callback) { + if(typeof options === 'string') + options = {'uri':options} + + // Just use the request API to do JSON. + options.json = true + if(options.body) + options.json = options.body + delete options.body + + callback = callback || noop + + var xhr = request(options, couch_handler) + return xhr + + function couch_handler(er, resp, body) { + if(er) + return callback(er, resp, body) + + if((resp.statusCode < 200 || resp.statusCode > 299) && body.error) { + // The body is a Couch JSON object indicating the error. + er = new Error('CouchDB error: ' + (body.error.reason || body.error.error)) + for (var key in body) + er[key] = body[key] + return callback(er, resp, body); + } + + return callback(er, resp, body); + } +} + +// +// Utility +// + +function noop() {} + +function getLogger() { + var logger = {} + , levels = ['trace', 'debug', 'info', 'warn', 'error'] + , level, i + + for(i = 0; i < levels.length; i++) { + level = levels[i] + + logger[level] = noop + if(typeof console !== 'undefined' && console && console[level]) + logger[level] = formatted(console, level) + } + + return logger +} + +function formatted(obj, method) { + return formatted_logger + + function formatted_logger(str, context) { + if(typeof context === 'object') + str += ' ' + JSON.stringify(context) + + return obj[method].call(obj, str) + } +} + +// Return whether a URL is a cross-domain request. +function is_crossDomain(url) { + var rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/ + + // jQuery #8138, IE may throw an exception when accessing + // a field from window.location if document.domain has been set + var ajaxLocation + try { ajaxLocation = location.href } + catch (e) { + // Use the href attribute of an A element since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; + } + + var ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [] + , parts = rurl.exec(url.toLowerCase() ) + + var result = !!( + parts && + ( parts[1] != ajaxLocParts[1] + || parts[2] != ajaxLocParts[2] + || (parts[3] || (parts[1] === "http:" ? 80 : 443)) != (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? 80 : 443)) + ) + ) + + //console.debug('is_crossDomain('+url+') -> ' + result) + return result +} + +// MIT License from http://phpjs.org/functions/base64_encode:358 +function b64_enc (data) { + // Encodes string using MIME base64 algorithm + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, enc="", tmp_arr = []; + + if (!data) { + return data; + } + + // assume utf8 data + // data = this.utf8_encode(data+''); + + do { // pack three octets into four hexets + o1 = data.charCodeAt(i++); + o2 = data.charCodeAt(i++); + o3 = data.charCodeAt(i++); + + bits = o1<<16 | o2<<8 | o3; + + h1 = bits>>18 & 0x3f; + h2 = bits>>12 & 0x3f; + h3 = bits>>6 & 0x3f; + h4 = bits & 0x3f; + + // use hexets to index into b64, and append result to encoded string + tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); + } while (i < data.length); + + enc = tmp_arr.join(''); + + switch (data.length % 3) { + case 1: + enc = enc.slice(0, -2) + '=='; + break; + case 2: + enc = enc.slice(0, -1) + '='; + break; + } + + return enc; +} + return request; +//UMD FOOTER START +})); +//UMD FOOTER END + +},{}],32:[function(require,module,exports){ + +},{}],33:[function(require,module,exports){ +arguments[4][32][0].apply(exports,arguments) +},{"dup":32}],34:[function(require,module,exports){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('is-array') + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 // not used by this implementation + +var rootParent = {} + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Note: + * + * - Implementation must support adding new properties to `Uint8Array` instances. + * Firefox 4-29 lacked support, fixed in Firefox 30+. + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + * + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will + * get the Object implementation, which is slower but will work correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = (function () { + try { + var buf = new ArrayBuffer(0) + var arr = new Uint8Array(buf) + arr.foo = function () { return 42 } + return arr.foo() === 42 && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +})() + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (arg) { + if (!(this instanceof Buffer)) { + // Avoid going through an ArgumentsAdaptorTrampoline in the common case. + if (arguments.length > 1) return new Buffer(arg, arguments[1]) + return new Buffer(arg) + } + + this.length = 0 + this.parent = undefined + + // Common case. + if (typeof arg === 'number') { + return fromNumber(this, arg) + } + + // Slightly less common case. + if (typeof arg === 'string') { + return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') + } + + // Unusual. + return fromObject(this, arg) +} + +function fromNumber (that, length) { + that = allocate(that, length < 0 ? 0 : checked(length) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < length; i++) { + that[i] = 0 + } + } + return that +} + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' + + // Assumption: byteLength() return value is always < kMaxLength. + var length = byteLength(string, encoding) | 0 + that = allocate(that, length) + + that.write(string, encoding) + return that +} + +function fromObject (that, object) { + if (Buffer.isBuffer(object)) return fromBuffer(that, object) + + if (isArray(object)) return fromArray(that, object) + + if (object == null) { + throw new TypeError('must start with number, buffer, array or string') + } + + if (typeof ArrayBuffer !== 'undefined' && object.buffer instanceof ArrayBuffer) { + return fromTypedArray(that, object) + } + + if (object.length) return fromArrayLike(that, object) + + return fromJsonObject(that, object) +} + +function fromBuffer (that, buffer) { + var length = checked(buffer.length) | 0 + that = allocate(that, length) + buffer.copy(that, 0, 0, length) + return that +} + +function fromArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +// Duplicate of fromArray() to keep fromArray() monomorphic. +function fromTypedArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + // Truncating the elements is probably not what people expect from typed + // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior + // of the old Buffer constructor. + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayLike (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. +// Returns a zero-length buffer for inputs that don't conform to the spec. +function fromJsonObject (that, object) { + var array + var length = 0 + + if (object.type === 'Buffer' && isArray(object.data)) { + array = object.data + length = checked(array.length) | 0 + } + that = allocate(that, length) + + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function allocate (that, length) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return an object instance of the Buffer class + that.length = length + that._isBuffer = true + } + + var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 + if (fromPool) that.parent = rootParent + + return that +} + +function checked (length) { + // Note: cannot use `length < kMaxLength` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (subject, encoding) { + if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) + + var buf = new Buffer(subject, encoding) + delete buf.parent + return buf +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + var i = 0 + var len = Math.min(x, y) + while (i < len) { + if (a[i] !== b[i]) break + + ++i + } + + if (i !== len) { + x = a[i] + y = b[i] + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') + + if (list.length === 0) { + return new Buffer(0) + } else if (list.length === 1) { + return list[0] + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; i++) { + length += list[i].length + } + } + + var buf = new Buffer(length) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +function byteLength (string, encoding) { + if (typeof string !== 'string') string = '' + string + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'binary': + // Deprecated + case 'raw': + case 'raws': + return len + case 'utf8': + case 'utf-8': + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +// pre-set for values that may exist in the future +Buffer.prototype.length = undefined +Buffer.prototype.parent = undefined + +function slowToString (encoding, start, end) { + var loweredCase = false + + start = start | 0 + end = end === undefined || end === Infinity ? this.length : end | 0 + + if (!encoding) encoding = 'utf8' + if (start < 0) start = 0 + if (end > this.length) end = this.length + if (end <= start) return '' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'binary': + return binarySlice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '' +} + +Buffer.prototype.compare = function compare (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return 0 + return Buffer.compare(this, b) +} + +Buffer.prototype.indexOf = function indexOf (val, byteOffset) { + if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff + else if (byteOffset < -0x80000000) byteOffset = -0x80000000 + byteOffset >>= 0 + + if (this.length === 0) return -1 + if (byteOffset >= this.length) return -1 + + // Negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) + + if (typeof val === 'string') { + if (val.length === 0) return -1 // special case: looking for empty string always fails + return String.prototype.indexOf.call(this, val, byteOffset) + } + if (Buffer.isBuffer(val)) { + return arrayIndexOf(this, val, byteOffset) + } + if (typeof val === 'number') { + if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { + return Uint8Array.prototype.indexOf.call(this, val, byteOffset) + } + return arrayIndexOf(this, [ val ], byteOffset) + } + + function arrayIndexOf (arr, val, byteOffset) { + var foundIndex = -1 + for (var i = 0; byteOffset + i < arr.length; i++) { + if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex + } else { + foundIndex = -1 + } + } + return -1 + } + + throw new TypeError('val must be string, number or Buffer') +} + +// `get` will be removed in Node 0.13+ +Buffer.prototype.get = function get (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` will be removed in Node 0.13+ +Buffer.prototype.set = function set (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new Error('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) throw new Error('Invalid hex string') + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function binaryWrite (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + var swap = encoding + encoding = offset + offset = length | 0 + length = swap + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'binary': + return binaryWrite(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } + + return res + decodeUtf8Char(tmp) +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function binarySlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + } + + if (newBuf.length) newBuf.parent = this.parent || this + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = value + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = value + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = value + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') + if (offset < 0) throw new RangeError('index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + + if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < len; i++) { + target[i + targetStart] = this[i + start] + } + } else { + target._set(this.subarray(start, start + len), targetStart) + } + + return len +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function fill (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (end < start) throw new RangeError('end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') + if (end < 0 || end > this.length) throw new RangeError('end out of bounds') + + var i + if (typeof value === 'number') { + for (i = start; i < end; i++) { + this[i] = value + } + } else { + var bytes = utf8ToBytes(value.toString()) + var len = bytes.length + for (i = start; i < end; i++) { + this[i] = bytes[i % len] + } + } + + return this +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function toArrayBuffer () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer.TYPED_ARRAY_SUPPORT) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) { + buf[i] = this[i] + } + return buf.buffer + } + } else { + throw new TypeError('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function _augment (arr) { + arr.constructor = Buffer + arr._isBuffer = true + + // save reference to original Uint8Array set method before overwriting + arr._set = arr.set + + // deprecated, will be removed in node 0.13+ + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.equals = BP.equals + arr.compare = BP.compare + arr.indexOf = BP.indexOf + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUIntLE = BP.readUIntLE + arr.readUIntBE = BP.readUIntBE + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readIntLE = BP.readIntLE + arr.readIntBE = BP.readIntBE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUIntLE = BP.writeUIntLE + arr.writeUIntBE = BP.writeUIntBE + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeIntLE = BP.writeIntLE + arr.writeIntBE = BP.writeIntBE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + var i = 0 + + for (; i < length; i++) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (leadSurrogate) { + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } else { + // valid surrogate pair + codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 + leadSurrogate = null + } + } else { + // no lead yet + + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else { + // valid lead + leadSurrogate = codePoint + continue + } + } + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = null + } + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x200000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} + +},{"base64-js":35,"ieee754":36,"is-array":37}],35:[function(require,module,exports){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +;(function (exports) { + 'use strict'; + + var Arr = (typeof Uint8Array !== 'undefined') + ? Uint8Array + : Array + + var PLUS = '+'.charCodeAt(0) + var SLASH = '/'.charCodeAt(0) + var NUMBER = '0'.charCodeAt(0) + var LOWER = 'a'.charCodeAt(0) + var UPPER = 'A'.charCodeAt(0) + var PLUS_URL_SAFE = '-'.charCodeAt(0) + var SLASH_URL_SAFE = '_'.charCodeAt(0) + + function decode (elt) { + var code = elt.charCodeAt(0) + if (code === PLUS || + code === PLUS_URL_SAFE) + return 62 // '+' + if (code === SLASH || + code === SLASH_URL_SAFE) + return 63 // '/' + if (code < NUMBER) + return -1 //no match + if (code < NUMBER + 10) + return code - NUMBER + 26 + 26 + if (code < UPPER + 26) + return code - UPPER + if (code < LOWER + 26) + return code - LOWER + 26 + } + + function b64ToByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + + if (b64.length % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push (v) { + arr[L++] = v + } + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } + + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } + + return arr + } + + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length + + function encode (num) { + return lookup.charAt(num) + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +},{}],36:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + +},{}],37:[function(require,module,exports){ + +/** + * isArray + */ + +var isArray = Array.isArray; + +/** + * toString + */ + +var str = Object.prototype.toString; + +/** + * Whether or not the given `val` + * is an array. + * + * example: + * + * isArray([]); + * // > true + * isArray(arguments); + * // > false + * isArray(''); + * // > false + * + * @param {mixed} val + * @return {bool} + */ + +module.exports = isArray || function (val) { + return !! val && '[object Array]' == str.call(val); +}; + +},{}],38:[function(require,module,exports){ +'use strict'; + +exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = require('randombytes') + +exports.createHash = exports.Hash = require('create-hash') + +exports.createHmac = exports.Hmac = require('create-hmac') + +var hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(Object.keys(require('browserify-sign/algos'))) +exports.getHashes = function () { + return hashes; +} + +var p = require('pbkdf2') +exports.pbkdf2 = p.pbkdf2 +exports.pbkdf2Sync = p.pbkdf2Sync + +var aes = require('browserify-aes'); +[ + 'Cipher', + 'createCipher', + 'Cipheriv', + 'createCipheriv', + 'Decipher', + 'createDecipher', + 'Decipheriv', + 'createDecipheriv', + 'getCiphers', + 'listCiphers' +].forEach(function (key) { + exports[key] = aes[key]; +}) + +var dh = require('diffie-hellman'); +[ + 'DiffieHellmanGroup', + 'createDiffieHellmanGroup', + 'getDiffieHellman', + 'createDiffieHellman', + 'DiffieHellman' +].forEach(function (key) { + exports[key] = dh[key]; +}) + +var sign = require('browserify-sign'); +[ + 'createSign', + 'Sign', + 'createVerify', + 'Verify' +].forEach(function (key) { + exports[key] = sign[key]; +}) + +exports.createECDH = require('create-ecdh') + +var publicEncrypt = require('public-encrypt'); + +[ + 'publicEncrypt', + 'privateEncrypt', + 'publicDecrypt', + 'privateDecrypt' +].forEach(function (key) { + exports[key] = publicEncrypt[key]; +}) + +// the least I can do is make error messages for the rest of the node.js/crypto api. +;[ + 'createCredentials' +].forEach(function (name) { + exports[name] = function () { + throw new Error([ + 'sorry, ' + name + ' is not implemented yet', + 'we accept pull requests', + 'https://github.com/crypto-browserify/crypto-browserify' + ].join('\n')); + } +}) + +},{"browserify-aes":42,"browserify-sign":58,"browserify-sign/algos":57,"create-ecdh":106,"create-hash":129,"create-hmac":141,"diffie-hellman":142,"pbkdf2":149,"public-encrypt":150,"randombytes":178}],39:[function(require,module,exports){ +(function (Buffer){ +var md5 = require('create-hash/md5') +module.exports = EVP_BytesToKey +function EVP_BytesToKey (password, keyLen, ivLen) { + if (!Buffer.isBuffer(password)) { + password = new Buffer(password, 'binary') + } + keyLen = keyLen / 8 + ivLen = ivLen || 0 + var ki = 0 + var ii = 0 + var key = new Buffer(keyLen) + var iv = new Buffer(ivLen) + var addmd = 0 + var md_buf + var i + var bufs = [] + while (true) { + if (addmd++ > 0) { + bufs.push(md_buf) + } + bufs.push(password) + md_buf = md5(Buffer.concat(bufs)) + bufs = [] + i = 0 + if (keyLen > 0) { + while (true) { + if (keyLen === 0) { + break + } + if (i === md_buf.length) { + break + } + key[ki++] = md_buf[i] + keyLen-- + i++ + } + } + if (ivLen > 0 && i !== md_buf.length) { + while (true) { + if (ivLen === 0) { + break + } + if (i === md_buf.length) { + break + } + iv[ii++] = md_buf[i] + ivLen-- + i++ + } + } + if (keyLen === 0 && ivLen === 0) { + break + } + } + for (i = 0; i < md_buf.length; i++) { + md_buf[i] = 0 + } + return { + key: key, + iv: iv + } +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34,"create-hash/md5":131}],40:[function(require,module,exports){ +(function (Buffer){ +// based on the aes implimentation in triple sec +// https://github.com/keybase/triplesec + +// which is in turn based on the one from crypto-js +// https://code.google.com/p/crypto-js/ + +var uint_max = Math.pow(2, 32) +function fixup_uint32 (x) { + var ret, x_pos + ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x + return ret +} +function scrub_vec (v) { + for (var i = 0; i < v.length; v++) { + v[i] = 0 + } + return false +} + +function Global () { + this.SBOX = [] + this.INV_SBOX = [] + this.SUB_MIX = [[], [], [], []] + this.INV_SUB_MIX = [[], [], [], []] + this.init() + this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36] +} + +Global.prototype.init = function () { + var d, i, sx, t, x, x2, x4, x8, xi, _i + d = (function () { + var _i, _results + _results = [] + for (i = _i = 0; _i < 256; i = ++_i) { + if (i < 128) { + _results.push(i << 1) + } else { + _results.push((i << 1) ^ 0x11b) + } + } + return _results + })() + x = 0 + xi = 0 + for (i = _i = 0; _i < 256; i = ++_i) { + sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4) + sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63 + this.SBOX[x] = sx + this.INV_SBOX[sx] = x + x2 = d[x] + x4 = d[x2] + x8 = d[x4] + t = (d[sx] * 0x101) ^ (sx * 0x1010100) + this.SUB_MIX[0][x] = (t << 24) | (t >>> 8) + this.SUB_MIX[1][x] = (t << 16) | (t >>> 16) + this.SUB_MIX[2][x] = (t << 8) | (t >>> 24) + this.SUB_MIX[3][x] = t + t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100) + this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8) + this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16) + this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24) + this.INV_SUB_MIX[3][sx] = t + if (x === 0) { + x = xi = 1 + } else { + x = x2 ^ d[d[d[x8 ^ x2]]] + xi ^= d[d[xi]] + } + } + return true +} + +var G = new Global() + +AES.blockSize = 4 * 4 + +AES.prototype.blockSize = AES.blockSize + +AES.keySize = 256 / 8 + +AES.prototype.keySize = AES.keySize + +function bufferToArray (buf) { + var len = buf.length / 4 + var out = new Array(len) + var i = -1 + while (++i < len) { + out[i] = buf.readUInt32BE(i * 4) + } + return out +} +function AES (key) { + this._key = bufferToArray(key) + this._doReset() +} + +AES.prototype._doReset = function () { + var invKsRow, keySize, keyWords, ksRow, ksRows, t + keyWords = this._key + keySize = keyWords.length + this._nRounds = keySize + 6 + ksRows = (this._nRounds + 1) * 4 + this._keySchedule = [] + for (ksRow = 0; ksRow < ksRows; ksRow++) { + this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % keySize) === 0 ? (t = (t << 8) | (t >>> 24), t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff], t ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t) + } + this._invKeySchedule = [] + for (invKsRow = 0; invKsRow < ksRows; invKsRow++) { + ksRow = ksRows - invKsRow + t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)] + this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]] + } + return true +} + +AES.prototype.encryptBlock = function (M) { + M = bufferToArray(new Buffer(M)) + var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX) + var buf = new Buffer(16) + buf.writeUInt32BE(out[0], 0) + buf.writeUInt32BE(out[1], 4) + buf.writeUInt32BE(out[2], 8) + buf.writeUInt32BE(out[3], 12) + return buf +} + +AES.prototype.decryptBlock = function (M) { + M = bufferToArray(new Buffer(M)) + var temp = [M[3], M[1]] + M[1] = temp[0] + M[3] = temp[1] + var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX) + var buf = new Buffer(16) + buf.writeUInt32BE(out[0], 0) + buf.writeUInt32BE(out[3], 4) + buf.writeUInt32BE(out[2], 8) + buf.writeUInt32BE(out[1], 12) + return buf +} + +AES.prototype.scrub = function () { + scrub_vec(this._keySchedule) + scrub_vec(this._invKeySchedule) + scrub_vec(this._key) +} + +AES.prototype._doCryptBlock = function (M, keySchedule, SUB_MIX, SBOX) { + var ksRow, s0, s1, s2, s3, t0, t1, t2, t3 + + s0 = M[0] ^ keySchedule[0] + s1 = M[1] ^ keySchedule[1] + s2 = M[2] ^ keySchedule[2] + s3 = M[3] ^ keySchedule[3] + ksRow = 4 + for (var round = 1; round < this._nRounds; round++) { + t0 = SUB_MIX[0][s0 >>> 24] ^ SUB_MIX[1][(s1 >>> 16) & 0xff] ^ SUB_MIX[2][(s2 >>> 8) & 0xff] ^ SUB_MIX[3][s3 & 0xff] ^ keySchedule[ksRow++] + t1 = SUB_MIX[0][s1 >>> 24] ^ SUB_MIX[1][(s2 >>> 16) & 0xff] ^ SUB_MIX[2][(s3 >>> 8) & 0xff] ^ SUB_MIX[3][s0 & 0xff] ^ keySchedule[ksRow++] + t2 = SUB_MIX[0][s2 >>> 24] ^ SUB_MIX[1][(s3 >>> 16) & 0xff] ^ SUB_MIX[2][(s0 >>> 8) & 0xff] ^ SUB_MIX[3][s1 & 0xff] ^ keySchedule[ksRow++] + t3 = SUB_MIX[0][s3 >>> 24] ^ SUB_MIX[1][(s0 >>> 16) & 0xff] ^ SUB_MIX[2][(s1 >>> 8) & 0xff] ^ SUB_MIX[3][s2 & 0xff] ^ keySchedule[ksRow++] + s0 = t0 + s1 = t1 + s2 = t2 + s3 = t3 + } + t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++] + t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++] + t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++] + t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++] + return [ + fixup_uint32(t0), + fixup_uint32(t1), + fixup_uint32(t2), + fixup_uint32(t3) + ] +} + +exports.AES = AES + +}).call(this,require("buffer").Buffer) +},{"buffer":34}],41:[function(require,module,exports){ +(function (Buffer){ +var aes = require('./aes') +var Transform = require('./cipherBase') +var inherits = require('inherits') +var GHASH = require('./ghash') +var xor = require('./xor') +inherits(StreamCipher, Transform) +module.exports = StreamCipher + +function StreamCipher (mode, key, iv, decrypt) { + if (!(this instanceof StreamCipher)) { + return new StreamCipher(mode, key, iv) + } + Transform.call(this) + this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])]) + iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])]) + this._cipher = new aes.AES(key) + this._prev = new Buffer(iv.length) + this._cache = new Buffer('') + this._secCache = new Buffer('') + this._decrypt = decrypt + this._alen = 0 + this._len = 0 + iv.copy(this._prev) + this._mode = mode + var h = new Buffer(4) + h.fill(0) + this._ghash = new GHASH(this._cipher.encryptBlock(h)) + this._authTag = null + this._called = false +} +StreamCipher.prototype._update = function (chunk) { + if (!this._called && this._alen) { + var rump = 16 - (this._alen % 16) + if (rump < 16) { + rump = new Buffer(rump) + rump.fill(0) + this._ghash.update(rump) + } + } + this._called = true + var out = this._mode.encrypt(this, chunk) + if (this._decrypt) { + this._ghash.update(chunk) + } else { + this._ghash.update(out) + } + this._len += chunk.length + return out +} +StreamCipher.prototype._final = function () { + if (this._decrypt && !this._authTag) { + throw new Error('Unsupported state or unable to authenticate data') + } + var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID)) + if (this._decrypt) { + if (xorTest(tag, this._authTag)) { + throw new Error('Unsupported state or unable to authenticate data') + } + } else { + this._authTag = tag + } + this._cipher.scrub() +} +StreamCipher.prototype.getAuthTag = function getAuthTag () { + if (!this._decrypt && Buffer.isBuffer(this._authTag)) { + return this._authTag + } else { + throw new Error('Attempting to get auth tag in unsupported state') + } +} +StreamCipher.prototype.setAuthTag = function setAuthTag (tag) { + if (this._decrypt) { + this._authTag = tag + } else { + throw new Error('Attempting to set auth tag in unsupported state') + } +} +StreamCipher.prototype.setAAD = function setAAD (buf) { + if (!this._called) { + this._ghash.update(buf) + this._alen += buf.length + } else { + throw new Error('Attempting to set AAD in unsupported state') + } +} +function xorTest (a, b) { + var out = 0 + if (a.length !== b.length) { + out++ + } + var len = Math.min(a.length, b.length) + var i = -1 + while (++i < len) { + out += (a[i] ^ b[i]) + } + return out +} + +}).call(this,require("buffer").Buffer) +},{"./aes":40,"./cipherBase":43,"./ghash":46,"./xor":56,"buffer":34,"inherits":180}],42:[function(require,module,exports){ +var ciphers = require('./encrypter') +exports.createCipher = exports.Cipher = ciphers.createCipher +exports.createCipheriv = exports.Cipheriv = ciphers.createCipheriv +var deciphers = require('./decrypter') +exports.createDecipher = exports.Decipher = deciphers.createDecipher +exports.createDecipheriv = exports.Decipheriv = deciphers.createDecipheriv +var modes = require('./modes') +function getCiphers () { + return Object.keys(modes) +} +exports.listCiphers = exports.getCiphers = getCiphers + +},{"./decrypter":44,"./encrypter":45,"./modes":47}],43:[function(require,module,exports){ +(function (Buffer){ +var Transform = require('stream').Transform +var inherits = require('inherits') + +module.exports = CipherBase +inherits(CipherBase, Transform) +function CipherBase () { + Transform.call(this) +} +CipherBase.prototype.update = function (data, inputEnc, outputEnc) { + if (typeof data === 'string') { + data = new Buffer(data, inputEnc) + } + var outData = this._update(data) + if (outputEnc) { + outData = outData.toString(outputEnc) + } + return outData +} +CipherBase.prototype._transform = function (data, _, next) { + this.push(this._update(data)) + next() +} +CipherBase.prototype._flush = function (next) { + try { + this.push(this._final()) + } catch(e) { + return next(e) + } + next() +} +CipherBase.prototype.final = function (outputEnc) { + var outData = this._final() || new Buffer('') + if (outputEnc) { + outData = outData.toString(outputEnc) + } + return outData +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34,"inherits":180,"stream":199}],44:[function(require,module,exports){ +(function (Buffer){ +var aes = require('./aes') +var Transform = require('./cipherBase') +var inherits = require('inherits') +var modes = require('./modes') +var StreamCipher = require('./streamCipher') +var AuthCipher = require('./authCipher') +var ebtk = require('./EVP_BytesToKey') + +inherits(Decipher, Transform) +function Decipher (mode, key, iv) { + if (!(this instanceof Decipher)) { + return new Decipher(mode, key, iv) + } + Transform.call(this) + this._cache = new Splitter() + this._last = void 0 + this._cipher = new aes.AES(key) + this._prev = new Buffer(iv.length) + iv.copy(this._prev) + this._mode = mode + this._autopadding = true +} +Decipher.prototype._update = function (data) { + this._cache.add(data) + var chunk + var thing + var out = [] + while ((chunk = this._cache.get(this._autopadding))) { + thing = this._mode.decrypt(this, chunk) + out.push(thing) + } + return Buffer.concat(out) +} +Decipher.prototype._final = function () { + var chunk = this._cache.flush() + if (this._autopadding) { + return unpad(this._mode.decrypt(this, chunk)) + } else if (chunk) { + throw new Error('data not multiple of block length') + } +} +Decipher.prototype.setAutoPadding = function (setTo) { + this._autopadding = !!setTo +} +function Splitter () { + if (!(this instanceof Splitter)) { + return new Splitter() + } + this.cache = new Buffer('') +} +Splitter.prototype.add = function (data) { + this.cache = Buffer.concat([this.cache, data]) +} + +Splitter.prototype.get = function (autoPadding) { + var out + if (autoPadding) { + if (this.cache.length > 16) { + out = this.cache.slice(0, 16) + this.cache = this.cache.slice(16) + return out + } + } else { + if (this.cache.length >= 16) { + out = this.cache.slice(0, 16) + this.cache = this.cache.slice(16) + return out + } + } + return null +} +Splitter.prototype.flush = function () { + if (this.cache.length) { + return this.cache + } +} +function unpad (last) { + var padded = last[15] + var i = -1 + while (++i < padded) { + if (last[(i + (16 - padded))] !== padded) { + throw new Error('unable to decrypt data') + } + } + if (padded === 16) { + return + } + return last.slice(0, 16 - padded) +} + +var modelist = { + ECB: require('./modes/ecb'), + CBC: require('./modes/cbc'), + CFB: require('./modes/cfb'), + CFB8: require('./modes/cfb8'), + CFB1: require('./modes/cfb1'), + OFB: require('./modes/ofb'), + CTR: require('./modes/ctr'), + GCM: require('./modes/ctr') +} + +function createDecipheriv (suite, password, iv) { + var config = modes[suite.toLowerCase()] + if (!config) { + throw new TypeError('invalid suite type') + } + if (typeof iv === 'string') { + iv = new Buffer(iv) + } + if (typeof password === 'string') { + password = new Buffer(password) + } + if (password.length !== config.key / 8) { + throw new TypeError('invalid key length ' + password.length) + } + if (iv.length !== config.iv) { + throw new TypeError('invalid iv length ' + iv.length) + } + if (config.type === 'stream') { + return new StreamCipher(modelist[config.mode], password, iv, true) + } else if (config.type === 'auth') { + return new AuthCipher(modelist[config.mode], password, iv, true) + } + return new Decipher(modelist[config.mode], password, iv) +} + +function createDecipher (suite, password) { + var config = modes[suite.toLowerCase()] + if (!config) { + throw new TypeError('invalid suite type') + } + var keys = ebtk(password, config.key, config.iv) + return createDecipheriv(suite, keys.key, keys.iv) +} +exports.createDecipher = createDecipher +exports.createDecipheriv = createDecipheriv + +}).call(this,require("buffer").Buffer) +},{"./EVP_BytesToKey":39,"./aes":40,"./authCipher":41,"./cipherBase":43,"./modes":47,"./modes/cbc":48,"./modes/cfb":49,"./modes/cfb1":50,"./modes/cfb8":51,"./modes/ctr":52,"./modes/ecb":53,"./modes/ofb":54,"./streamCipher":55,"buffer":34,"inherits":180}],45:[function(require,module,exports){ +(function (Buffer){ +var aes = require('./aes') +var Transform = require('./cipherBase') +var inherits = require('inherits') +var modes = require('./modes') +var ebtk = require('./EVP_BytesToKey') +var StreamCipher = require('./streamCipher') +var AuthCipher = require('./authCipher') +inherits(Cipher, Transform) +function Cipher (mode, key, iv) { + if (!(this instanceof Cipher)) { + return new Cipher(mode, key, iv) + } + Transform.call(this) + this._cache = new Splitter() + this._cipher = new aes.AES(key) + this._prev = new Buffer(iv.length) + iv.copy(this._prev) + this._mode = mode + this._autopadding = true +} +Cipher.prototype._update = function (data) { + this._cache.add(data) + var chunk + var thing + var out = [] + while ((chunk = this._cache.get())) { + thing = this._mode.encrypt(this, chunk) + out.push(thing) + } + return Buffer.concat(out) +} +Cipher.prototype._final = function () { + var chunk = this._cache.flush() + if (this._autopadding) { + chunk = this._mode.encrypt(this, chunk) + this._cipher.scrub() + return chunk + } else if (chunk.toString('hex') !== '10101010101010101010101010101010') { + this._cipher.scrub() + throw new Error('data not multiple of block length') + } +} +Cipher.prototype.setAutoPadding = function (setTo) { + this._autopadding = !!setTo +} + +function Splitter () { + if (!(this instanceof Splitter)) { + return new Splitter() + } + this.cache = new Buffer('') +} +Splitter.prototype.add = function (data) { + this.cache = Buffer.concat([this.cache, data]) +} + +Splitter.prototype.get = function () { + if (this.cache.length > 15) { + var out = this.cache.slice(0, 16) + this.cache = this.cache.slice(16) + return out + } + return null +} +Splitter.prototype.flush = function () { + var len = 16 - this.cache.length + var padBuff = new Buffer(len) + + var i = -1 + while (++i < len) { + padBuff.writeUInt8(len, i) + } + var out = Buffer.concat([this.cache, padBuff]) + return out +} +var modelist = { + ECB: require('./modes/ecb'), + CBC: require('./modes/cbc'), + CFB: require('./modes/cfb'), + CFB8: require('./modes/cfb8'), + CFB1: require('./modes/cfb1'), + OFB: require('./modes/ofb'), + CTR: require('./modes/ctr'), + GCM: require('./modes/ctr') +} + +function createCipheriv (suite, password, iv) { + var config = modes[suite.toLowerCase()] + if (!config) { + throw new TypeError('invalid suite type') + } + if (typeof iv === 'string') { + iv = new Buffer(iv) + } + if (typeof password === 'string') { + password = new Buffer(password) + } + if (password.length !== config.key / 8) { + throw new TypeError('invalid key length ' + password.length) + } + if (iv.length !== config.iv) { + throw new TypeError('invalid iv length ' + iv.length) + } + if (config.type === 'stream') { + return new StreamCipher(modelist[config.mode], password, iv) + } else if (config.type === 'auth') { + return new AuthCipher(modelist[config.mode], password, iv) + } + return new Cipher(modelist[config.mode], password, iv) +} +function createCipher (suite, password) { + var config = modes[suite.toLowerCase()] + if (!config) { + throw new TypeError('invalid suite type') + } + var keys = ebtk(password, config.key, config.iv) + return createCipheriv(suite, keys.key, keys.iv) +} + +exports.createCipheriv = createCipheriv +exports.createCipher = createCipher + +}).call(this,require("buffer").Buffer) +},{"./EVP_BytesToKey":39,"./aes":40,"./authCipher":41,"./cipherBase":43,"./modes":47,"./modes/cbc":48,"./modes/cfb":49,"./modes/cfb1":50,"./modes/cfb8":51,"./modes/ctr":52,"./modes/ecb":53,"./modes/ofb":54,"./streamCipher":55,"buffer":34,"inherits":180}],46:[function(require,module,exports){ +(function (Buffer){ +var zeros = new Buffer(16) +zeros.fill(0) +module.exports = GHASH +function GHASH (key) { + this.h = key + this.state = new Buffer(16) + this.state.fill(0) + this.cache = new Buffer('') +} +// from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html +// by Juho Vähä-Herttua +GHASH.prototype.ghash = function (block) { + var i = -1 + while (++i < block.length) { + this.state[i] ^= block[i] + } + this._multiply() +} + +GHASH.prototype._multiply = function () { + var Vi = toArray(this.h) + var Zi = [0, 0, 0, 0] + var j, xi, lsb_Vi + var i = -1 + while (++i < 128) { + xi = (this.state[~~(i / 8)] & (1 << (7 - i % 8))) !== 0 + if (xi) { + // Z_i+1 = Z_i ^ V_i + Zi = xor(Zi, Vi) + } + + // Store the value of LSB(V_i) + lsb_Vi = (Vi[3] & 1) !== 0 + + // V_i+1 = V_i >> 1 + for (j = 3; j > 0; j--) { + Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31) + } + Vi[0] = Vi[0] >>> 1 + + // If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R + if (lsb_Vi) { + Vi[0] = Vi[0] ^ (0xe1 << 24) + } + } + this.state = fromArray(Zi) +} +GHASH.prototype.update = function (buf) { + this.cache = Buffer.concat([this.cache, buf]) + var chunk + while (this.cache.length >= 16) { + chunk = this.cache.slice(0, 16) + this.cache = this.cache.slice(16) + this.ghash(chunk) + } +} +GHASH.prototype.final = function (abl, bl) { + if (this.cache.length) { + this.ghash(Buffer.concat([this.cache, zeros], 16)) + } + this.ghash(fromArray([ + 0, abl, + 0, bl + ])) + return this.state +} + +function toArray (buf) { + return [ + buf.readUInt32BE(0), + buf.readUInt32BE(4), + buf.readUInt32BE(8), + buf.readUInt32BE(12) + ] +} +function fromArray (out) { + out = out.map(fixup_uint32) + var buf = new Buffer(16) + buf.writeUInt32BE(out[0], 0) + buf.writeUInt32BE(out[1], 4) + buf.writeUInt32BE(out[2], 8) + buf.writeUInt32BE(out[3], 12) + return buf +} +var uint_max = Math.pow(2, 32) +function fixup_uint32 (x) { + var ret, x_pos + ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x + return ret +} +function xor (a, b) { + return [ + a[0] ^ b[0], + a[1] ^ b[1], + a[2] ^ b[2], + a[3] ^ b[3] + ] +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34}],47:[function(require,module,exports){ +exports['aes-128-ecb'] = { + cipher: 'AES', + key: 128, + iv: 0, + mode: 'ECB', + type: 'block' +} +exports['aes-192-ecb'] = { + cipher: 'AES', + key: 192, + iv: 0, + mode: 'ECB', + type: 'block' +} +exports['aes-256-ecb'] = { + cipher: 'AES', + key: 256, + iv: 0, + mode: 'ECB', + type: 'block' +} +exports['aes-128-cbc'] = { + cipher: 'AES', + key: 128, + iv: 16, + mode: 'CBC', + type: 'block' +} +exports['aes-192-cbc'] = { + cipher: 'AES', + key: 192, + iv: 16, + mode: 'CBC', + type: 'block' +} +exports['aes-256-cbc'] = { + cipher: 'AES', + key: 256, + iv: 16, + mode: 'CBC', + type: 'block' +} +exports['aes128'] = exports['aes-128-cbc'] +exports['aes192'] = exports['aes-192-cbc'] +exports['aes256'] = exports['aes-256-cbc'] +exports['aes-128-cfb'] = { + cipher: 'AES', + key: 128, + iv: 16, + mode: 'CFB', + type: 'stream' +} +exports['aes-192-cfb'] = { + cipher: 'AES', + key: 192, + iv: 16, + mode: 'CFB', + type: 'stream' +} +exports['aes-256-cfb'] = { + cipher: 'AES', + key: 256, + iv: 16, + mode: 'CFB', + type: 'stream' +} +exports['aes-128-cfb8'] = { + cipher: 'AES', + key: 128, + iv: 16, + mode: 'CFB8', + type: 'stream' +} +exports['aes-192-cfb8'] = { + cipher: 'AES', + key: 192, + iv: 16, + mode: 'CFB8', + type: 'stream' +} +exports['aes-256-cfb8'] = { + cipher: 'AES', + key: 256, + iv: 16, + mode: 'CFB8', + type: 'stream' +} +exports['aes-128-cfb1'] = { + cipher: 'AES', + key: 128, + iv: 16, + mode: 'CFB1', + type: 'stream' +} +exports['aes-192-cfb1'] = { + cipher: 'AES', + key: 192, + iv: 16, + mode: 'CFB1', + type: 'stream' +} +exports['aes-256-cfb1'] = { + cipher: 'AES', + key: 256, + iv: 16, + mode: 'CFB1', + type: 'stream' +} +exports['aes-128-ofb'] = { + cipher: 'AES', + key: 128, + iv: 16, + mode: 'OFB', + type: 'stream' +} +exports['aes-192-ofb'] = { + cipher: 'AES', + key: 192, + iv: 16, + mode: 'OFB', + type: 'stream' +} +exports['aes-256-ofb'] = { + cipher: 'AES', + key: 256, + iv: 16, + mode: 'OFB', + type: 'stream' +} +exports['aes-128-ctr'] = { + cipher: 'AES', + key: 128, + iv: 16, + mode: 'CTR', + type: 'stream' +} +exports['aes-192-ctr'] = { + cipher: 'AES', + key: 192, + iv: 16, + mode: 'CTR', + type: 'stream' +} +exports['aes-256-ctr'] = { + cipher: 'AES', + key: 256, + iv: 16, + mode: 'CTR', + type: 'stream' +} +exports['aes-128-gcm'] = { + cipher: 'AES', + key: 128, + iv: 12, + mode: 'GCM', + type: 'auth' +} +exports['aes-192-gcm'] = { + cipher: 'AES', + key: 192, + iv: 12, + mode: 'GCM', + type: 'auth' +} +exports['aes-256-gcm'] = { + cipher: 'AES', + key: 256, + iv: 12, + mode: 'GCM', + type: 'auth' +} + +},{}],48:[function(require,module,exports){ +var xor = require('../xor') +exports.encrypt = function (self, block) { + var data = xor(block, self._prev) + self._prev = self._cipher.encryptBlock(data) + return self._prev +} +exports.decrypt = function (self, block) { + var pad = self._prev + self._prev = block + var out = self._cipher.decryptBlock(block) + return xor(out, pad) +} + +},{"../xor":56}],49:[function(require,module,exports){ +(function (Buffer){ +var xor = require('../xor') +exports.encrypt = function (self, data, decrypt) { + var out = new Buffer('') + var len + while (data.length) { + if (self._cache.length === 0) { + self._cache = self._cipher.encryptBlock(self._prev) + self._prev = new Buffer('') + } + if (self._cache.length <= data.length) { + len = self._cache.length + out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)]) + data = data.slice(len) + } else { + out = Buffer.concat([out, encryptStart(self, data, decrypt)]) + break + } + } + return out +} +function encryptStart (self, data, decrypt) { + var len = data.length + var out = xor(data, self._cache) + self._cache = self._cache.slice(len) + self._prev = Buffer.concat([self._prev, decrypt ? data : out]) + return out +} + +}).call(this,require("buffer").Buffer) +},{"../xor":56,"buffer":34}],50:[function(require,module,exports){ +(function (Buffer){ +function encryptByte (self, byteParam, decrypt) { + var pad + var i = -1 + var len = 8 + var out = 0 + var bit, value + while (++i < len) { + pad = self._cipher.encryptBlock(self._prev) + bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0 + value = pad[0] ^ bit + out += ((value & 0x80) >> (i % 8)) + self._prev = shiftIn(self._prev, decrypt ? bit : value) + } + return out +} +exports.encrypt = function (self, chunk, decrypt) { + var len = chunk.length + var out = new Buffer(len) + var i = -1 + while (++i < len) { + out[i] = encryptByte(self, chunk[i], decrypt) + } + return out +} +function shiftIn (buffer, value) { + var len = buffer.length + var i = -1 + var out = new Buffer(buffer.length) + buffer = Buffer.concat([buffer, new Buffer([value])]) + while (++i < len) { + out[i] = buffer[i] << 1 | buffer[i + 1] >> (7) + } + return out +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34}],51:[function(require,module,exports){ +(function (Buffer){ +function encryptByte (self, byteParam, decrypt) { + var pad = self._cipher.encryptBlock(self._prev) + var out = pad[0] ^ byteParam + self._prev = Buffer.concat([self._prev.slice(1), new Buffer([decrypt ? byteParam : out])]) + return out +} +exports.encrypt = function (self, chunk, decrypt) { + var len = chunk.length + var out = new Buffer(len) + var i = -1 + while (++i < len) { + out[i] = encryptByte(self, chunk[i], decrypt) + } + return out +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34}],52:[function(require,module,exports){ +(function (Buffer){ +var xor = require('../xor') +function getBlock (self) { + var out = self._cipher.encryptBlock(self._prev) + incr32(self._prev) + return out +} +exports.encrypt = function (self, chunk) { + while (self._cache.length < chunk.length) { + self._cache = Buffer.concat([self._cache, getBlock(self)]) + } + var pad = self._cache.slice(0, chunk.length) + self._cache = self._cache.slice(chunk.length) + return xor(chunk, pad) +} +function incr32 (iv) { + var len = iv.length + var item + while (len--) { + item = iv.readUInt8(len) + if (item === 255) { + iv.writeUInt8(0, len) + } else { + item++ + iv.writeUInt8(item, len) + break + } + } +} + +}).call(this,require("buffer").Buffer) +},{"../xor":56,"buffer":34}],53:[function(require,module,exports){ +exports.encrypt = function (self, block) { + return self._cipher.encryptBlock(block) +} +exports.decrypt = function (self, block) { + return self._cipher.decryptBlock(block) +} + +},{}],54:[function(require,module,exports){ +(function (Buffer){ +var xor = require('../xor') +function getBlock (self) { + self._prev = self._cipher.encryptBlock(self._prev) + return self._prev +} +exports.encrypt = function (self, chunk) { + while (self._cache.length < chunk.length) { + self._cache = Buffer.concat([self._cache, getBlock(self)]) + } + var pad = self._cache.slice(0, chunk.length) + self._cache = self._cache.slice(chunk.length) + return xor(chunk, pad) +} + +}).call(this,require("buffer").Buffer) +},{"../xor":56,"buffer":34}],55:[function(require,module,exports){ +(function (Buffer){ +var aes = require('./aes') +var Transform = require('./cipherBase') +var inherits = require('inherits') + +inherits(StreamCipher, Transform) +module.exports = StreamCipher +function StreamCipher (mode, key, iv, decrypt) { + if (!(this instanceof StreamCipher)) { + return new StreamCipher(mode, key, iv) + } + Transform.call(this) + this._cipher = new aes.AES(key) + this._prev = new Buffer(iv.length) + this._cache = new Buffer('') + this._secCache = new Buffer('') + this._decrypt = decrypt + iv.copy(this._prev) + this._mode = mode +} +StreamCipher.prototype._update = function (chunk) { + return this._mode.encrypt(this, chunk, this._decrypt) +} +StreamCipher.prototype._final = function () { + this._cipher.scrub() +} + +}).call(this,require("buffer").Buffer) +},{"./aes":40,"./cipherBase":43,"buffer":34,"inherits":180}],56:[function(require,module,exports){ +(function (Buffer){ +module.exports = xor +function xor (a, b) { + var len = Math.min(a.length, b.length) + var out = new Buffer(len) + var i = -1 + while (++i < len) { + out.writeUInt8(a[i] ^ b[i], i) + } + return out +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34}],57:[function(require,module,exports){ +(function (Buffer){ +'use strict' +exports['RSA-SHA224'] = exports.sha224WithRSAEncryption = { + sign: 'rsa', + hash: 'sha224', + id: new Buffer('302d300d06096086480165030402040500041c', 'hex') +} +exports['RSA-SHA256'] = exports.sha256WithRSAEncryption = { + sign: 'rsa', + hash: 'sha256', + id: new Buffer('3031300d060960864801650304020105000420', 'hex') +} +exports['RSA-SHA384'] = exports.sha384WithRSAEncryption = { + sign: 'rsa', + hash: 'sha384', + id: new Buffer('3041300d060960864801650304020205000430', 'hex') +} +exports['RSA-SHA512'] = exports.sha512WithRSAEncryption = { + sign: 'rsa', + hash: 'sha512', + id: new Buffer('3051300d060960864801650304020305000440', 'hex') +} +exports['RSA-SHA1'] = { + sign: 'rsa', + hash: 'sha1', + id: new Buffer('3021300906052b0e03021a05000414', 'hex') +} +exports['ecdsa-with-SHA1'] = { + sign: 'ecdsa', + hash: 'sha1', + id: new Buffer('', 'hex') +} +exports.DSA = exports['DSA-SHA1'] = exports['DSA-SHA'] = { + sign: 'dsa', + hash: 'sha1', + id: new Buffer('', 'hex') +} +exports['DSA-SHA224'] = exports['DSA-WITH-SHA224'] = { + sign: 'dsa', + hash: 'sha224', + id: new Buffer('', 'hex') +} +exports['DSA-SHA256'] = exports['DSA-WITH-SHA256'] = { + sign: 'dsa', + hash: 'sha256', + id: new Buffer('', 'hex') +} +exports['DSA-SHA384'] = exports['DSA-WITH-SHA384'] = { + sign: 'dsa', + hash: 'sha384', + id: new Buffer('', 'hex') +} +exports['DSA-SHA512'] = exports['DSA-WITH-SHA512'] = { + sign: 'dsa', + hash: 'sha512', + id: new Buffer('', 'hex') +} +exports['DSA-RIPEMD160'] = { + sign: 'dsa', + hash: 'rmd160', + id: new Buffer('', 'hex') +} +exports['RSA-RIPEMD160'] = exports.ripemd160WithRSA = { + sign: 'rsa', + hash: 'rmd160', + id: new Buffer('3021300906052b2403020105000414', 'hex') +} +exports['RSA-MD5'] = exports.md5WithRSAEncryption = { + sign: 'rsa', + hash: 'md5', + id: new Buffer('3020300c06082a864886f70d020505000410', 'hex') +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34}],58:[function(require,module,exports){ +(function (Buffer){ +'use strict' +var sign = require('./sign') +var verify = require('./verify') +var stream = require('stream') +var inherits = require('inherits') +var _algos = require('./algos') +var createHash = require('create-hash') +var algos = {} +Object.keys(_algos).forEach(function (key) { + algos[key] = algos[key.toLowerCase()] = _algos[key] +}) + +exports.createSign = exports.Sign = createSign + +function createSign (algorithm) { + return new Sign(algorithm) +} + +exports.createVerify = exports.Verify = createVerify + +function createVerify (algorithm) { + return new Verify(algorithm) +} + +inherits(Sign, stream.Writable) + +function Sign (algorithm) { + stream.Writable.call(this) + var data = algos[algorithm] + if (!data) + throw new Error('Unknown message digest') + + this._hashType = data.hash + this._hash = createHash(data.hash) + this._tag = data.id + this._signType = data.sign +} + +Sign.prototype._write = function _write (data, _, done) { + this._hash.update(data) + done() +} + +Sign.prototype.update = function update (data, enc) { + if (typeof data === 'string') + data = new Buffer(data, enc) + this._hash.update(data) + return this +} + +Sign.prototype.sign = function signMethod (key, enc) { + this.end() + var hash = this._hash.digest() + var sig = sign(Buffer.concat([this._tag, hash]), key, this._hashType, this._signType) + if (enc) { + sig = sig.toString(enc) + } + return sig +} + +inherits(Verify, stream.Writable) +function Verify (algorithm) { + stream.Writable.call(this) + var data = algos[algorithm] + if (!data) + throw new Error('Unknown message digest') + + this._hash = createHash(data.hash) + this._tag = data.id + this._signType = data.sign +} + +Verify.prototype._write = function _write (data, _, done) { + this._hash.update(data) + done() +} + +Verify.prototype.update = function update (data, enc) { + if (typeof data === 'string') + data = new Buffer(data, enc) + + this._hash.update(data) + return this +} + +Verify.prototype.verify = function verifyMethod (key, sig, enc) { + this.end() + var hash = this._hash.digest() + if (typeof sig === 'string') + sig = new Buffer(sig, enc) + + return verify(sig, Buffer.concat([this._tag, hash]), key, this._signType) +} + +}).call(this,require("buffer").Buffer) +},{"./algos":57,"./sign":103,"./verify":104,"buffer":34,"create-hash":129,"inherits":180,"stream":199}],59:[function(require,module,exports){ +'use strict' +exports['1.3.132.0.10'] = 'secp256k1' + +exports['1.3.132.0.33'] = 'p224' + +exports['1.2.840.10045.3.1.1'] = 'p192' + +exports['1.2.840.10045.3.1.7'] = 'p256' + +},{}],60:[function(require,module,exports){ +(function (module, exports) { + +'use strict'; + +// Utils + +function assert(val, msg) { + if (!val) + throw new Error(msg || 'Assertion failed'); +} + +// Could use `inherits` module, but don't want to move from single file +// architecture yet. +function inherits(ctor, superCtor) { + ctor.super_ = superCtor; + var TempCtor = function () {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; +} + +// BN + +function BN(number, base, endian) { + // May be `new BN(bn)` ? + if (number !== null && + typeof number === 'object' && + Array.isArray(number.words)) { + return number; + } + + this.sign = false; + this.words = null; + this.length = 0; + + // Reduction context + this.red = null; + + if (base === 'le' || base === 'be') { + endian = base; + base = 10; + } + + if (number !== null) + this._init(number || 0, base || 10, endian || 'be'); +} +if (typeof module === 'object') + module.exports = BN; +else + exports.BN = BN; + +BN.BN = BN; +BN.wordSize = 26; + +BN.prototype._init = function init(number, base, endian) { + if (typeof number === 'number') { + return this._initNumber(number, base, endian); + } else if (typeof number === 'object') { + return this._initArray(number, base, endian); + } + if (base === 'hex') + base = 16; + assert(base === (base | 0) && base >= 2 && base <= 36); + + number = number.toString().replace(/\s+/g, ''); + var start = 0; + if (number[0] === '-') + start++; + + if (base === 16) + this._parseHex(number, start); + else + this._parseBase(number, base, start); + + if (number[0] === '-') + this.sign = true; + + this.strip(); + + if (endian !== 'le') + return; + + this._initArray(this.toArray(), base, endian); +}; + +BN.prototype._initNumber = function _initNumber(number, base, endian) { + if (number < 0) { + this.sign = true; + number = -number; + } + if (number < 0x4000000) { + this.words = [ number & 0x3ffffff ]; + this.length = 1; + } else if (number < 0x10000000000000) { + this.words = [ + number & 0x3ffffff, + (number / 0x4000000) & 0x3ffffff + ]; + this.length = 2; + } else { + assert(number < 0x20000000000000); // 2 ^ 53 (unsafe) + this.words = [ + number & 0x3ffffff, + (number / 0x4000000) & 0x3ffffff, + 1 + ]; + this.length = 3; + } + + if (endian !== 'le') + return; + + // Reverse the bytes + this._initArray(this.toArray(), base, endian); +}; + +BN.prototype._initArray = function _initArray(number, base, endian) { + // Perhaps a Uint8Array + assert(typeof number.length === 'number'); + if (number.length <= 0) { + this.words = [ 0 ]; + this.length = 1; + return this; + } + + this.length = Math.ceil(number.length / 3); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + this.words[i] = 0; + + var off = 0; + if (endian === 'be') { + for (var i = number.length - 1, j = 0; i >= 0; i -= 3) { + var w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + } else if (endian === 'le') { + for (var i = 0, j = 0; i < number.length; i += 3) { + var w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + } + return this.strip(); +}; + +function parseHex(str, start, end) { + var r = 0; + var len = Math.min(str.length, end); + for (var i = start; i < len; i++) { + var c = str.charCodeAt(i) - 48; + + r <<= 4; + + // 'a' - 'f' + if (c >= 49 && c <= 54) + r |= c - 49 + 0xa; + + // 'A' - 'F' + else if (c >= 17 && c <= 22) + r |= c - 17 + 0xa; + + // '0' - '9' + else + r |= c & 0xf; + } + return r; +} + +BN.prototype._parseHex = function _parseHex(number, start) { + // Create possibly bigger array to ensure that it fits the number + this.length = Math.ceil((number.length - start) / 6); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + this.words[i] = 0; + + // Scan 24-bit chunks and add them to the number + var off = 0; + for (var i = number.length - 6, j = 0; i >= start; i -= 6) { + var w = parseHex(number, i, i + 6); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + if (i + 6 !== start) { + var w = parseHex(number, start, i + 6); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; + } + this.strip(); +}; + +function parseBase(str, start, end, mul) { + var r = 0; + var len = Math.min(str.length, end); + for (var i = start; i < len; i++) { + var c = str.charCodeAt(i) - 48; + + r *= mul; + + // 'a' + if (c >= 49) + r += c - 49 + 0xa; + + // 'A' + else if (c >= 17) + r += c - 17 + 0xa; + + // '0' - '9' + else + r += c; + } + return r; +} + +BN.prototype._parseBase = function _parseBase(number, base, start) { + // Initialize as zero + this.words = [ 0 ]; + this.length = 1; + + // Find length of limb in base + for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) + limbLen++; + limbLen--; + limbPow = (limbPow / base) | 0; + + var total = number.length - start; + var mod = total % limbLen; + var end = Math.min(total, total - mod) + start; + + var word = 0; + for (var i = start; i < end; i += limbLen) { + word = parseBase(number, i, i + limbLen, base); + + this.imuln(limbPow); + if (this.words[0] + word < 0x4000000) + this.words[0] += word; + else + this._iaddn(word); + } + + if (mod !== 0) { + var pow = 1; + var word = parseBase(number, i, number.length, base); + + for (var i = 0; i < mod; i++) + pow *= base; + this.imuln(pow); + if (this.words[0] + word < 0x4000000) + this.words[0] += word; + else + this._iaddn(word); + } +}; + +BN.prototype.copy = function copy(dest) { + dest.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + dest.words[i] = this.words[i]; + dest.length = this.length; + dest.sign = this.sign; + dest.red = this.red; +}; + +BN.prototype.clone = function clone() { + var r = new BN(null); + this.copy(r); + return r; +}; + +// Remove leading `0` from `this` +BN.prototype.strip = function strip() { + while (this.length > 1 && this.words[this.length - 1] === 0) + this.length--; + return this._normSign(); +}; + +BN.prototype._normSign = function _normSign() { + // -0 = 0 + if (this.length === 1 && this.words[0] === 0) + this.sign = false; + return this; +}; + +BN.prototype.inspect = function inspect() { + return (this.red ? ''; +}; + +/* + +var zeros = []; +var groupSizes = []; +var groupBases = []; + +var s = ''; +var i = -1; +while (++i < BN.wordSize) { + zeros[i] = s; + s += '0'; +} +groupSizes[0] = 0; +groupSizes[1] = 0; +groupBases[0] = 0; +groupBases[1] = 0; +var base = 2 - 1; +while (++base < 36 + 1) { + var groupSize = 0; + var groupBase = 1; + while (groupBase < (1 << BN.wordSize) / base) { + groupBase *= base; + groupSize += 1; + } + groupSizes[base] = groupSize; + groupBases[base] = groupBase; +} + +*/ + +var zeros = [ + '', + '0', + '00', + '000', + '0000', + '00000', + '000000', + '0000000', + '00000000', + '000000000', + '0000000000', + '00000000000', + '000000000000', + '0000000000000', + '00000000000000', + '000000000000000', + '0000000000000000', + '00000000000000000', + '000000000000000000', + '0000000000000000000', + '00000000000000000000', + '000000000000000000000', + '0000000000000000000000', + '00000000000000000000000', + '000000000000000000000000', + '0000000000000000000000000' +]; + +var groupSizes = [ + 0, 0, + 25, 16, 12, 11, 10, 9, 8, + 8, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 +]; + +var groupBases = [ + 0, 0, + 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, + 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, + 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, + 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, + 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 +]; + +BN.prototype.toString = function toString(base, padding) { + base = base || 10; + if (base === 16 || base === 'hex') { + var out = ''; + var off = 0; + var padding = padding | 0 || 1; + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = this.words[i]; + var word = (((w << off) | carry) & 0xffffff).toString(16); + carry = (w >>> (24 - off)) & 0xffffff; + if (carry !== 0 || i !== this.length - 1) + out = zeros[6 - word.length] + word + out; + else + out = word + out; + off += 2; + if (off >= 26) { + off -= 26; + i--; + } + } + if (carry !== 0) + out = carry.toString(16) + out; + while (out.length % padding !== 0) + out = '0' + out; + if (this.sign) + out = '-' + out; + return out; + } else if (base === (base | 0) && base >= 2 && base <= 36) { + // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); + var groupSize = groupSizes[base]; + // var groupBase = Math.pow(base, groupSize); + var groupBase = groupBases[base]; + var out = ''; + var c = this.clone(); + c.sign = false; + while (c.cmpn(0) !== 0) { + var r = c.modn(groupBase).toString(base); + c = c.idivn(groupBase); + + if (c.cmpn(0) !== 0) + out = zeros[groupSize - r.length] + r + out; + else + out = r + out; + } + if (this.cmpn(0) === 0) + out = '0' + out; + if (this.sign) + out = '-' + out; + return out; + } else { + assert(false, 'Base should be between 2 and 36'); + } +}; + +BN.prototype.toJSON = function toJSON() { + return this.toString(16); +}; + +BN.prototype.toArray = function toArray(endian) { + this.strip(); + var res = new Array(this.byteLength()); + res[0] = 0; + + var q = this.clone(); + if (endian !== 'le') { + // Assume big-endian + for (var i = 0; q.cmpn(0) !== 0; i++) { + var b = q.andln(0xff); + q.ishrn(8); + + res[res.length - i - 1] = b; + } + } else { + // Assume little-endian + for (var i = 0; q.cmpn(0) !== 0; i++) { + var b = q.andln(0xff); + q.ishrn(8); + + res[i] = b; + } + } + + return res; +}; + +if (Math.clz32) { + BN.prototype._countBits = function _countBits(w) { + return 32 - Math.clz32(w); + }; +} else { + BN.prototype._countBits = function _countBits(w) { + var t = w; + var r = 0; + if (t >= 0x1000) { + r += 13; + t >>>= 13; + } + if (t >= 0x40) { + r += 7; + t >>>= 7; + } + if (t >= 0x8) { + r += 4; + t >>>= 4; + } + if (t >= 0x02) { + r += 2; + t >>>= 2; + } + return r + t; + }; +} + +BN.prototype._zeroBits = function _zeroBits(w) { + // Short-cut + if (w === 0) + return 26; + + var t = w; + var r = 0; + if ((t & 0x1fff) === 0) { + r += 13; + t >>>= 13; + } + if ((t & 0x7f) === 0) { + r += 7; + t >>>= 7; + } + if ((t & 0xf) === 0) { + r += 4; + t >>>= 4; + } + if ((t & 0x3) === 0) { + r += 2; + t >>>= 2; + } + if ((t & 0x1) === 0) + r++; + return r; +}; + +// Return number of used bits in a BN +BN.prototype.bitLength = function bitLength() { + var hi = 0; + var w = this.words[this.length - 1]; + var hi = this._countBits(w); + return (this.length - 1) * 26 + hi; +}; + +// Number of trailing zero bits +BN.prototype.zeroBits = function zeroBits() { + if (this.cmpn(0) === 0) + return 0; + + var r = 0; + for (var i = 0; i < this.length; i++) { + var b = this._zeroBits(this.words[i]); + r += b; + if (b !== 26) + break; + } + return r; +}; + +BN.prototype.byteLength = function byteLength() { + return Math.ceil(this.bitLength() / 8); +}; + +// Return negative clone of `this` +BN.prototype.neg = function neg() { + if (this.cmpn(0) === 0) + return this.clone(); + + var r = this.clone(); + r.sign = !this.sign; + return r; +}; + + +// Or `num` with `this` in-place +BN.prototype.ior = function ior(num) { + this.sign = this.sign || num.sign; + + while (this.length < num.length) + this.words[this.length++] = 0; + + for (var i = 0; i < num.length; i++) + this.words[i] = this.words[i] | num.words[i]; + + return this.strip(); +}; + + +// Or `num` with `this` +BN.prototype.or = function or(num) { + if (this.length > num.length) + return this.clone().ior(num); + else + return num.clone().ior(this); +}; + + +// And `num` with `this` in-place +BN.prototype.iand = function iand(num) { + this.sign = this.sign && num.sign; + + // b = min-length(num, this) + var b; + if (this.length > num.length) + b = num; + else + b = this; + + for (var i = 0; i < b.length; i++) + this.words[i] = this.words[i] & num.words[i]; + + this.length = b.length; + + return this.strip(); +}; + + +// And `num` with `this` +BN.prototype.and = function and(num) { + if (this.length > num.length) + return this.clone().iand(num); + else + return num.clone().iand(this); +}; + + +// Xor `num` with `this` in-place +BN.prototype.ixor = function ixor(num) { + this.sign = this.sign || num.sign; + + // a.length > b.length + var a; + var b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; + } + + for (var i = 0; i < b.length; i++) + this.words[i] = a.words[i] ^ b.words[i]; + + if (this !== a) + for (; i < a.length; i++) + this.words[i] = a.words[i]; + + this.length = a.length; + + return this.strip(); +}; + + +// Xor `num` with `this` +BN.prototype.xor = function xor(num) { + if (this.length > num.length) + return this.clone().ixor(num); + else + return num.clone().ixor(this); +}; + + +// Set `bit` of `this` +BN.prototype.setn = function setn(bit, val) { + assert(typeof bit === 'number' && bit >= 0); + + var off = (bit / 26) | 0; + var wbit = bit % 26; + + while (this.length <= off) + this.words[this.length++] = 0; + + if (val) + this.words[off] = this.words[off] | (1 << wbit); + else + this.words[off] = this.words[off] & ~(1 << wbit); + + return this.strip(); +}; + + +// Add `num` to `this` in-place +BN.prototype.iadd = function iadd(num) { + // negative + positive + if (this.sign && !num.sign) { + this.sign = false; + var r = this.isub(num); + this.sign = !this.sign; + return this._normSign(); + + // positive + negative + } else if (!this.sign && num.sign) { + num.sign = false; + var r = this.isub(num); + num.sign = true; + return r._normSign(); + } + + // a.length > b.length + var a; + var b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; + } + + var carry = 0; + for (var i = 0; i < b.length; i++) { + var r = a.words[i] + b.words[i] + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } + for (; carry !== 0 && i < a.length; i++) { + var r = a.words[i] + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } + + this.length = a.length; + if (carry !== 0) { + this.words[this.length] = carry; + this.length++; + // Copy the rest of the words + } else if (a !== this) { + for (; i < a.length; i++) + this.words[i] = a.words[i]; + } + + return this; +}; + +// Add `num` to `this` +BN.prototype.add = function add(num) { + if (num.sign && !this.sign) { + num.sign = false; + var res = this.sub(num); + num.sign = true; + return res; + } else if (!num.sign && this.sign) { + this.sign = false; + var res = num.sub(this); + this.sign = true; + return res; + } + + if (this.length > num.length) + return this.clone().iadd(num); + else + return num.clone().iadd(this); +}; + +// Subtract `num` from `this` in-place +BN.prototype.isub = function isub(num) { + // this - (-num) = this + num + if (num.sign) { + num.sign = false; + var r = this.iadd(num); + num.sign = true; + return r._normSign(); + + // -this - num = -(this + num) + } else if (this.sign) { + this.sign = false; + this.iadd(num); + this.sign = true; + return this._normSign(); + } + + // At this point both numbers are positive + var cmp = this.cmp(num); + + // Optimization - zeroify + if (cmp === 0) { + this.sign = false; + this.length = 1; + this.words[0] = 0; + return this; + } + + // a > b + var a; + var b; + if (cmp > 0) { + a = this; + b = num; + } else { + a = num; + b = this; + } + + var carry = 0; + for (var i = 0; i < b.length; i++) { + var r = a.words[i] - b.words[i] + carry; + carry = r >> 26; + this.words[i] = r & 0x3ffffff; + } + for (; carry !== 0 && i < a.length; i++) { + var r = a.words[i] + carry; + carry = r >> 26; + this.words[i] = r & 0x3ffffff; + } + + // Copy rest of the words + if (carry === 0 && i < a.length && a !== this) + for (; i < a.length; i++) + this.words[i] = a.words[i]; + this.length = Math.max(this.length, i); + + if (a !== this) + this.sign = true; + + return this.strip(); +}; + +// Subtract `num` from `this` +BN.prototype.sub = function sub(num) { + return this.clone().isub(num); +}; + +/* +// NOTE: This could be potentionally used to generate loop-less multiplications +function _genCombMulTo(alen, blen) { + var len = alen + blen - 1; + var src = [ + 'var a = this.words, b = num.words, o = out.words, c = 0, w, ' + + 'mask = 0x3ffffff, shift = 0x4000000;', + 'out.length = ' + len + ';' + ]; + for (var k = 0; k < len; k++) { + var minJ = Math.max(0, k - alen + 1); + var maxJ = Math.min(k, blen - 1); + + for (var j = minJ; j <= maxJ; j++) { + var i = k - j; + var mul = 'a[' + i + '] * b[' + j + ']'; + + if (j === minJ) { + src.push('w = ' + mul + ' + c;'); + src.push('c = (w / shift) | 0;'); + } else { + src.push('w += ' + mul + ';'); + src.push('c += (w / shift) | 0;'); + } + src.push('w &= mask;'); + } + src.push('o[' + k + '] = w;'); + } + src.push('if (c !== 0) {', + ' o[' + k + '] = c;', + ' out.length++;', + '}', + 'return out;'); + + return src.join('\n'); +} +*/ + +BN.prototype._smallMulTo = function _smallMulTo(num, out) { + out.sign = num.sign !== this.sign; + out.length = this.length + num.length; + + var carry = 0; + for (var k = 0; k < out.length - 1; k++) { + // Sum all words with the same `i + j = k` and accumulate `ncarry`, + // note that ncarry could be >= 0x3ffffff + var ncarry = carry >>> 26; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { + var i = k - j; + var a = this.words[i] | 0; + var b = num.words[j] | 0; + var r = a * b; + + var lo = r & 0x3ffffff; + ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; + lo = (lo + rword) | 0; + rword = lo & 0x3ffffff; + ncarry = (ncarry + (lo >>> 26)) | 0; + } + out.words[k] = rword; + carry = ncarry; + } + if (carry !== 0) { + out.words[k] = carry; + } else { + out.length--; + } + + return out.strip(); +}; + +BN.prototype._bigMulTo = function _bigMulTo(num, out) { + out.sign = num.sign !== this.sign; + out.length = this.length + num.length; + + var carry = 0; + var hncarry = 0; + for (var k = 0; k < out.length - 1; k++) { + // Sum all words with the same `i + j = k` and accumulate `ncarry`, + // note that ncarry could be >= 0x3ffffff + var ncarry = hncarry; + hncarry = 0; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { + var i = k - j; + var a = this.words[i] | 0; + var b = num.words[j] | 0; + var r = a * b; + + var lo = r & 0x3ffffff; + ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; + lo = (lo + rword) | 0; + rword = lo & 0x3ffffff; + ncarry = (ncarry + (lo >>> 26)) | 0; + + hncarry += ncarry >>> 26; + ncarry &= 0x3ffffff; + } + out.words[k] = rword; + carry = ncarry; + ncarry = hncarry; + } + if (carry !== 0) { + out.words[k] = carry; + } else { + out.length--; + } + + return out.strip(); +}; + +BN.prototype.mulTo = function mulTo(num, out) { + var res; + if (this.length + num.length < 63) + res = this._smallMulTo(num, out); + else + res = this._bigMulTo(num, out); + return res; +}; + +// Multiply `this` by `num` +BN.prototype.mul = function mul(num) { + var out = new BN(null); + out.words = new Array(this.length + num.length); + return this.mulTo(num, out); +}; + +// In-place Multiplication +BN.prototype.imul = function imul(num) { + if (this.cmpn(0) === 0 || num.cmpn(0) === 0) { + this.words[0] = 0; + this.length = 1; + return this; + } + + var tlen = this.length; + var nlen = num.length; + + this.sign = num.sign !== this.sign; + this.length = this.length + num.length; + this.words[this.length - 1] = 0; + + for (var k = this.length - 2; k >= 0; k--) { + // Sum all words with the same `i + j = k` and accumulate `carry`, + // note that carry could be >= 0x3ffffff + var carry = 0; + var rword = 0; + var maxJ = Math.min(k, nlen - 1); + for (var j = Math.max(0, k - tlen + 1); j <= maxJ; j++) { + var i = k - j; + var a = this.words[i]; + var b = num.words[j]; + var r = a * b; + + var lo = r & 0x3ffffff; + carry += (r / 0x4000000) | 0; + lo += rword; + rword = lo & 0x3ffffff; + carry += lo >>> 26; + } + this.words[k] = rword; + this.words[k + 1] += carry; + carry = 0; + } + + // Propagate overflows + var carry = 0; + for (var i = 1; i < this.length; i++) { + var w = this.words[i] + carry; + this.words[i] = w & 0x3ffffff; + carry = w >>> 26; + } + + return this.strip(); +}; + +BN.prototype.imuln = function imuln(num) { + assert(typeof num === 'number'); + + // Carry + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = this.words[i] * num; + var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); + carry >>= 26; + carry += (w / 0x4000000) | 0; + // NOTE: lo is 27bit maximum + carry += lo >>> 26; + this.words[i] = lo & 0x3ffffff; + } + + if (carry !== 0) { + this.words[i] = carry; + this.length++; + } + + return this; +}; + +// `this` * `this` +BN.prototype.sqr = function sqr() { + return this.mul(this); +}; + +// `this` * `this` in-place +BN.prototype.isqr = function isqr() { + return this.mul(this); +}; + +// Shift-left in-place +BN.prototype.ishln = function ishln(bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); + + if (r !== 0) { + var carry = 0; + for (var i = 0; i < this.length; i++) { + var newCarry = this.words[i] & carryMask; + var c = (this.words[i] - newCarry) << r; + this.words[i] = c | carry; + carry = newCarry >>> (26 - r); + } + if (carry) { + this.words[i] = carry; + this.length++; + } + } + + if (s !== 0) { + for (var i = this.length - 1; i >= 0; i--) + this.words[i + s] = this.words[i]; + for (var i = 0; i < s; i++) + this.words[i] = 0; + this.length += s; + } + + return this.strip(); +}; + +// Shift-right in-place +// NOTE: `hint` is a lowest bit before trailing zeroes +// NOTE: if `extended` is present - it will be filled with destroyed bits +BN.prototype.ishrn = function ishrn(bits, hint, extended) { + assert(typeof bits === 'number' && bits >= 0); + var h; + if (hint) + h = (hint - (hint % 26)) / 26; + else + h = 0; + + var r = bits % 26; + var s = Math.min((bits - r) / 26, this.length); + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + var maskedWords = extended; + + h -= s; + h = Math.max(0, h); + + // Extended mode, copy masked part + if (maskedWords) { + for (var i = 0; i < s; i++) + maskedWords.words[i] = this.words[i]; + maskedWords.length = s; + } + + if (s === 0) { + // No-op, we should not move anything at all + } else if (this.length > s) { + this.length -= s; + for (var i = 0; i < this.length; i++) + this.words[i] = this.words[i + s]; + } else { + this.words[0] = 0; + this.length = 1; + } + + var carry = 0; + for (var i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { + var word = this.words[i]; + this.words[i] = (carry << (26 - r)) | (word >>> r); + carry = word & mask; + } + + // Push carried bits as a mask + if (maskedWords && carry !== 0) + maskedWords.words[maskedWords.length++] = carry; + + if (this.length === 0) { + this.words[0] = 0; + this.length = 1; + } + + this.strip(); + + return this; +}; + +// Shift-left +BN.prototype.shln = function shln(bits) { + return this.clone().ishln(bits); +}; + +// Shift-right +BN.prototype.shrn = function shrn(bits) { + return this.clone().ishrn(bits); +}; + +// Test if n bit is set +BN.prototype.testn = function testn(bit) { + assert(typeof bit === 'number' && bit >= 0); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; + + // Fast case: bit is much higher than all existing words + if (this.length <= s) { + return false; + } + + // Check bit and return + var w = this.words[s]; + + return !!(w & q); +}; + +// Return only lowers bits of number (in-place) +BN.prototype.imaskn = function imaskn(bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + + assert(!this.sign, 'imaskn works only with positive numbers'); + + if (r !== 0) + s++; + this.length = Math.min(s, this.length); + + if (r !== 0) { + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + this.words[this.length - 1] &= mask; + } + + return this.strip(); +}; + +// Return only lowers bits of number +BN.prototype.maskn = function maskn(bits) { + return this.clone().imaskn(bits); +}; + +// Add plain number `num` to `this` +BN.prototype.iaddn = function iaddn(num) { + assert(typeof num === 'number'); + if (num < 0) + return this.isubn(-num); + + // Possible sign change + if (this.sign) { + if (this.length === 1 && this.words[0] < num) { + this.words[0] = num - this.words[0]; + this.sign = false; + return this; + } + + this.sign = false; + this.isubn(num); + this.sign = true; + return this; + } + + // Add without checks + return this._iaddn(num); +}; + +BN.prototype._iaddn = function _iaddn(num) { + this.words[0] += num; + + // Carry + for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { + this.words[i] -= 0x4000000; + if (i === this.length - 1) + this.words[i + 1] = 1; + else + this.words[i + 1]++; + } + this.length = Math.max(this.length, i + 1); + + return this; +}; + +// Subtract plain number `num` from `this` +BN.prototype.isubn = function isubn(num) { + assert(typeof num === 'number'); + if (num < 0) + return this.iaddn(-num); + + if (this.sign) { + this.sign = false; + this.iaddn(num); + this.sign = true; + return this; + } + + this.words[0] -= num; + + // Carry + for (var i = 0; i < this.length && this.words[i] < 0; i++) { + this.words[i] += 0x4000000; + this.words[i + 1] -= 1; + } + + return this.strip(); +}; + +BN.prototype.addn = function addn(num) { + return this.clone().iaddn(num); +}; + +BN.prototype.subn = function subn(num) { + return this.clone().isubn(num); +}; + +BN.prototype.iabs = function iabs() { + this.sign = false; + + return this; +}; + +BN.prototype.abs = function abs() { + return this.clone().iabs(); +}; + +BN.prototype._ishlnsubmul = function _ishlnsubmul(num, mul, shift) { + // Bigger storage is needed + var len = num.length + shift; + var i; + if (this.words.length < len) { + var t = new Array(len); + for (var i = 0; i < this.length; i++) + t[i] = this.words[i]; + this.words = t; + } else { + i = this.length; + } + + // Zeroify rest + this.length = Math.max(this.length, len); + for (; i < this.length; i++) + this.words[i] = 0; + + var carry = 0; + for (var i = 0; i < num.length; i++) { + var w = this.words[i + shift] + carry; + var right = num.words[i] * mul; + w -= right & 0x3ffffff; + carry = (w >> 26) - ((right / 0x4000000) | 0); + this.words[i + shift] = w & 0x3ffffff; + } + for (; i < this.length - shift; i++) { + var w = this.words[i + shift] + carry; + carry = w >> 26; + this.words[i + shift] = w & 0x3ffffff; + } + + if (carry === 0) + return this.strip(); + + // Subtraction overflow + assert(carry === -1); + carry = 0; + for (var i = 0; i < this.length; i++) { + var w = -this.words[i] + carry; + carry = w >> 26; + this.words[i] = w & 0x3ffffff; + } + this.sign = true; + + return this.strip(); +}; + +BN.prototype._wordDiv = function _wordDiv(num, mode) { + var shift = this.length - num.length; + + var a = this.clone(); + var b = num; + + // Normalize + var bhi = b.words[b.length - 1]; + var bhiBits = this._countBits(bhi); + shift = 26 - bhiBits; + if (shift !== 0) { + b = b.shln(shift); + a.ishln(shift); + bhi = b.words[b.length - 1]; + } + + // Initialize quotient + var m = a.length - b.length; + var q; + + if (mode !== 'mod') { + q = new BN(null); + q.length = m + 1; + q.words = new Array(q.length); + for (var i = 0; i < q.length; i++) + q.words[i] = 0; + } + + var diff = a.clone()._ishlnsubmul(b, 1, m); + if (!diff.sign) { + a = diff; + if (q) + q.words[m] = 1; + } + + for (var j = m - 1; j >= 0; j--) { + var qj = a.words[b.length + j] * 0x4000000 + a.words[b.length + j - 1]; + + // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max + // (0x7ffffff) + qj = Math.min((qj / bhi) | 0, 0x3ffffff); + + a._ishlnsubmul(b, qj, j); + while (a.sign) { + qj--; + a.sign = false; + a._ishlnsubmul(b, 1, j); + if (a.cmpn(0) !== 0) + a.sign = !a.sign; + } + if (q) + q.words[j] = qj; + } + if (q) + q.strip(); + a.strip(); + + // Denormalize + if (mode !== 'div' && shift !== 0) + a.ishrn(shift); + return { div: q ? q : null, mod: a }; +}; + +BN.prototype.divmod = function divmod(num, mode) { + assert(num.cmpn(0) !== 0); + + if (this.sign && !num.sign) { + var res = this.neg().divmod(num, mode); + var div; + var mod; + if (mode !== 'mod') + div = res.div.neg(); + if (mode !== 'div') + mod = res.mod.cmpn(0) === 0 ? res.mod : num.sub(res.mod); + return { + div: div, + mod: mod + }; + } else if (!this.sign && num.sign) { + var res = this.divmod(num.neg(), mode); + var div; + if (mode !== 'mod') + div = res.div.neg(); + return { div: div, mod: res.mod }; + } else if (this.sign && num.sign) { + return this.neg().divmod(num.neg(), mode); + } + + // Both numbers are positive at this point + + // Strip both numbers to approximate shift value + if (num.length > this.length || this.cmp(num) < 0) + return { div: new BN(0), mod: this }; + + // Very short reduction + if (num.length === 1) { + if (mode === 'div') + return { div: this.divn(num.words[0]), mod: null }; + else if (mode === 'mod') + return { div: null, mod: new BN(this.modn(num.words[0])) }; + return { + div: this.divn(num.words[0]), + mod: new BN(this.modn(num.words[0])) + }; + } + + return this._wordDiv(num, mode); +}; + +// Find `this` / `num` +BN.prototype.div = function div(num) { + return this.divmod(num, 'div').div; +}; + +// Find `this` % `num` +BN.prototype.mod = function mod(num) { + return this.divmod(num, 'mod').mod; +}; + +// Find Round(`this` / `num`) +BN.prototype.divRound = function divRound(num) { + var dm = this.divmod(num); + + // Fast case - exact division + if (dm.mod.cmpn(0) === 0) + return dm.div; + + var mod = dm.div.sign ? dm.mod.isub(num) : dm.mod; + + var half = num.shrn(1); + var r2 = num.andln(1); + var cmp = mod.cmp(half); + + // Round down + if (cmp < 0 || r2 === 1 && cmp === 0) + return dm.div; + + // Round up + return dm.div.sign ? dm.div.isubn(1) : dm.div.iaddn(1); +}; + +BN.prototype.modn = function modn(num) { + assert(num <= 0x3ffffff); + var p = (1 << 26) % num; + + var acc = 0; + for (var i = this.length - 1; i >= 0; i--) + acc = (p * acc + this.words[i]) % num; + + return acc; +}; + +// In-place division by number +BN.prototype.idivn = function idivn(num) { + assert(num <= 0x3ffffff); + + var carry = 0; + for (var i = this.length - 1; i >= 0; i--) { + var w = this.words[i] + carry * 0x4000000; + this.words[i] = (w / num) | 0; + carry = w % num; + } + + return this.strip(); +}; + +BN.prototype.divn = function divn(num) { + return this.clone().idivn(num); +}; + +BN.prototype.egcd = function egcd(p) { + assert(!p.sign); + assert(p.cmpn(0) !== 0); + + var x = this; + var y = p.clone(); + + if (x.sign) + x = x.mod(p); + else + x = x.clone(); + + // A * x + B * y = x + var A = new BN(1); + var B = new BN(0); + + // C * x + D * y = y + var C = new BN(0); + var D = new BN(1); + + var g = 0; + + while (x.isEven() && y.isEven()) { + x.ishrn(1); + y.ishrn(1); + ++g; + } + + var yp = y.clone(); + var xp = x.clone(); + + while (x.cmpn(0) !== 0) { + while (x.isEven()) { + x.ishrn(1); + if (A.isEven() && B.isEven()) { + A.ishrn(1); + B.ishrn(1); + } else { + A.iadd(yp).ishrn(1); + B.isub(xp).ishrn(1); + } + } + + while (y.isEven()) { + y.ishrn(1); + if (C.isEven() && D.isEven()) { + C.ishrn(1); + D.ishrn(1); + } else { + C.iadd(yp).ishrn(1); + D.isub(xp).ishrn(1); + } + } + + if (x.cmp(y) >= 0) { + x.isub(y); + A.isub(C); + B.isub(D); + } else { + y.isub(x); + C.isub(A); + D.isub(B); + } + } + + return { + a: C, + b: D, + gcd: y.ishln(g) + }; +}; + +// This is reduced incarnation of the binary EEA +// above, designated to invert members of the +// _prime_ fields F(p) at a maximal speed +BN.prototype._invmp = function _invmp(p) { + assert(!p.sign); + assert(p.cmpn(0) !== 0); + + var a = this; + var b = p.clone(); + + if (a.sign) + a = a.mod(p); + else + a = a.clone(); + + var x1 = new BN(1); + var x2 = new BN(0); + + var delta = b.clone(); + + while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { + while (a.isEven()) { + a.ishrn(1); + if (x1.isEven()) + x1.ishrn(1); + else + x1.iadd(delta).ishrn(1); + } + while (b.isEven()) { + b.ishrn(1); + if (x2.isEven()) + x2.ishrn(1); + else + x2.iadd(delta).ishrn(1); + } + if (a.cmp(b) >= 0) { + a.isub(b); + x1.isub(x2); + } else { + b.isub(a); + x2.isub(x1); + } + } + if (a.cmpn(1) === 0) + return x1; + else + return x2; +}; + +BN.prototype.gcd = function gcd(num) { + if (this.cmpn(0) === 0) + return num.clone(); + if (num.cmpn(0) === 0) + return this.clone(); + + var a = this.clone(); + var b = num.clone(); + a.sign = false; + b.sign = false; + + // Remove common factor of two + for (var shift = 0; a.isEven() && b.isEven(); shift++) { + a.ishrn(1); + b.ishrn(1); + } + + do { + while (a.isEven()) + a.ishrn(1); + while (b.isEven()) + b.ishrn(1); + + var r = a.cmp(b); + if (r < 0) { + // Swap `a` and `b` to make `a` always bigger than `b` + var t = a; + a = b; + b = t; + } else if (r === 0 || b.cmpn(1) === 0) { + break; + } + + a.isub(b); + } while (true); + + return b.ishln(shift); +}; + +// Invert number in the field F(num) +BN.prototype.invm = function invm(num) { + return this.egcd(num).a.mod(num); +}; + +BN.prototype.isEven = function isEven() { + return (this.words[0] & 1) === 0; +}; + +BN.prototype.isOdd = function isOdd() { + return (this.words[0] & 1) === 1; +}; + +// And first word and num +BN.prototype.andln = function andln(num) { + return this.words[0] & num; +}; + +// Increment at the bit position in-line +BN.prototype.bincn = function bincn(bit) { + assert(typeof bit === 'number'); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; + + // Fast case: bit is much higher than all existing words + if (this.length <= s) { + for (var i = this.length; i < s + 1; i++) + this.words[i] = 0; + this.words[s] |= q; + this.length = s + 1; + return this; + } + + // Add bit and propagate, if needed + var carry = q; + for (var i = s; carry !== 0 && i < this.length; i++) { + var w = this.words[i]; + w += carry; + carry = w >>> 26; + w &= 0x3ffffff; + this.words[i] = w; + } + if (carry !== 0) { + this.words[i] = carry; + this.length++; + } + return this; +}; + +BN.prototype.cmpn = function cmpn(num) { + var sign = num < 0; + if (sign) + num = -num; + + if (this.sign && !sign) + return -1; + else if (!this.sign && sign) + return 1; + + num &= 0x3ffffff; + this.strip(); + + var res; + if (this.length > 1) { + res = 1; + } else { + var w = this.words[0]; + res = w === num ? 0 : w < num ? -1 : 1; + } + if (this.sign) + res = -res; + return res; +}; + +// Compare two numbers and return: +// 1 - if `this` > `num` +// 0 - if `this` == `num` +// -1 - if `this` < `num` +BN.prototype.cmp = function cmp(num) { + if (this.sign && !num.sign) + return -1; + else if (!this.sign && num.sign) + return 1; + + var res = this.ucmp(num); + if (this.sign) + return -res; + else + return res; +}; + +// Unsigned comparison +BN.prototype.ucmp = function ucmp(num) { + // At this point both numbers have the same sign + if (this.length > num.length) + return 1; + else if (this.length < num.length) + return -1; + + var res = 0; + for (var i = this.length - 1; i >= 0; i--) { + var a = this.words[i]; + var b = num.words[i]; + + if (a === b) + continue; + if (a < b) + res = -1; + else if (a > b) + res = 1; + break; + } + return res; +}; + +// +// A reduce context, could be using montgomery or something better, depending +// on the `m` itself. +// +BN.red = function red(num) { + return new Red(num); +}; + +BN.prototype.toRed = function toRed(ctx) { + assert(!this.red, 'Already a number in reduction context'); + assert(!this.sign, 'red works only with positives'); + return ctx.convertTo(this)._forceRed(ctx); +}; + +BN.prototype.fromRed = function fromRed() { + assert(this.red, 'fromRed works only with numbers in reduction context'); + return this.red.convertFrom(this); +}; + +BN.prototype._forceRed = function _forceRed(ctx) { + this.red = ctx; + return this; +}; + +BN.prototype.forceRed = function forceRed(ctx) { + assert(!this.red, 'Already a number in reduction context'); + return this._forceRed(ctx); +}; + +BN.prototype.redAdd = function redAdd(num) { + assert(this.red, 'redAdd works only with red numbers'); + return this.red.add(this, num); +}; + +BN.prototype.redIAdd = function redIAdd(num) { + assert(this.red, 'redIAdd works only with red numbers'); + return this.red.iadd(this, num); +}; + +BN.prototype.redSub = function redSub(num) { + assert(this.red, 'redSub works only with red numbers'); + return this.red.sub(this, num); +}; + +BN.prototype.redISub = function redISub(num) { + assert(this.red, 'redISub works only with red numbers'); + return this.red.isub(this, num); +}; + +BN.prototype.redShl = function redShl(num) { + assert(this.red, 'redShl works only with red numbers'); + return this.red.shl(this, num); +}; + +BN.prototype.redMul = function redMul(num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.mul(this, num); +}; + +BN.prototype.redIMul = function redIMul(num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.imul(this, num); +}; + +BN.prototype.redSqr = function redSqr() { + assert(this.red, 'redSqr works only with red numbers'); + this.red._verify1(this); + return this.red.sqr(this); +}; + +BN.prototype.redISqr = function redISqr() { + assert(this.red, 'redISqr works only with red numbers'); + this.red._verify1(this); + return this.red.isqr(this); +}; + +// Square root over p +BN.prototype.redSqrt = function redSqrt() { + assert(this.red, 'redSqrt works only with red numbers'); + this.red._verify1(this); + return this.red.sqrt(this); +}; + +BN.prototype.redInvm = function redInvm() { + assert(this.red, 'redInvm works only with red numbers'); + this.red._verify1(this); + return this.red.invm(this); +}; + +// Return negative clone of `this` % `red modulo` +BN.prototype.redNeg = function redNeg() { + assert(this.red, 'redNeg works only with red numbers'); + this.red._verify1(this); + return this.red.neg(this); +}; + +BN.prototype.redPow = function redPow(num) { + assert(this.red && !num.red, 'redPow(normalNum)'); + this.red._verify1(this); + return this.red.pow(this, num); +}; + +// Prime numbers with efficient reduction +var primes = { + k256: null, + p224: null, + p192: null, + p25519: null +}; + +// Pseudo-Mersenne prime +function MPrime(name, p) { + // P = 2 ^ N - K + this.name = name; + this.p = new BN(p, 16); + this.n = this.p.bitLength(); + this.k = new BN(1).ishln(this.n).isub(this.p); + + this.tmp = this._tmp(); +} + +MPrime.prototype._tmp = function _tmp() { + var tmp = new BN(null); + tmp.words = new Array(Math.ceil(this.n / 13)); + return tmp; +}; + +MPrime.prototype.ireduce = function ireduce(num) { + // Assumes that `num` is less than `P^2` + // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) + var r = num; + var rlen; + + do { + this.split(r, this.tmp); + r = this.imulK(r); + r = r.iadd(this.tmp); + rlen = r.bitLength(); + } while (rlen > this.n); + + var cmp = rlen < this.n ? -1 : r.ucmp(this.p); + if (cmp === 0) { + r.words[0] = 0; + r.length = 1; + } else if (cmp > 0) { + r.isub(this.p); + } else { + r.strip(); + } + + return r; +}; + +MPrime.prototype.split = function split(input, out) { + input.ishrn(this.n, 0, out); +}; + +MPrime.prototype.imulK = function imulK(num) { + return num.imul(this.k); +}; + +function K256() { + MPrime.call( + this, + 'k256', + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); +} +inherits(K256, MPrime); + +K256.prototype.split = function split(input, output) { + // 256 = 9 * 26 + 22 + var mask = 0x3fffff; + + var outLen = Math.min(input.length, 9); + for (var i = 0; i < outLen; i++) + output.words[i] = input.words[i]; + output.length = outLen; + + if (input.length <= 9) { + input.words[0] = 0; + input.length = 1; + return; + } + + // Shift by 9 limbs + var prev = input.words[9]; + output.words[output.length++] = prev & mask; + + for (var i = 10; i < input.length; i++) { + var next = input.words[i]; + input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); + prev = next; + } + input.words[i - 10] = prev >>> 22; + input.length -= 9; +}; + +K256.prototype.imulK = function imulK(num) { + // K = 0x1000003d1 = [ 0x40, 0x3d1 ] + num.words[num.length] = 0; + num.words[num.length + 1] = 0; + num.length += 2; + + // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390 + var hi; + var lo = 0; + for (var i = 0; i < num.length; i++) { + var w = num.words[i]; + hi = w * 0x40; + lo += w * 0x3d1; + hi += (lo / 0x4000000) | 0; + lo &= 0x3ffffff; + + num.words[i] = lo; + + lo = hi; + } + + // Fast length reduction + if (num.words[num.length - 1] === 0) { + num.length--; + if (num.words[num.length - 1] === 0) + num.length--; + } + return num; +}; + +function P224() { + MPrime.call( + this, + 'p224', + 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); +} +inherits(P224, MPrime); + +function P192() { + MPrime.call( + this, + 'p192', + 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); +} +inherits(P192, MPrime); + +function P25519() { + // 2 ^ 255 - 19 + MPrime.call( + this, + '25519', + '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); +} +inherits(P25519, MPrime); + +P25519.prototype.imulK = function imulK(num) { + // K = 0x13 + var carry = 0; + for (var i = 0; i < num.length; i++) { + var hi = num.words[i] * 0x13 + carry; + var lo = hi & 0x3ffffff; + hi >>>= 26; + + num.words[i] = lo; + carry = hi; + } + if (carry !== 0) + num.words[num.length++] = carry; + return num; +}; + +// Exported mostly for testing purposes, use plain name instead +BN._prime = function prime(name) { + // Cached version of prime + if (primes[name]) + return primes[name]; + + var prime; + if (name === 'k256') + prime = new K256(); + else if (name === 'p224') + prime = new P224(); + else if (name === 'p192') + prime = new P192(); + else if (name === 'p25519') + prime = new P25519(); + else + throw new Error('Unknown prime ' + name); + primes[name] = prime; + + return prime; +}; + +// +// Base reduction engine +// +function Red(m) { + if (typeof m === 'string') { + var prime = BN._prime(m); + this.m = prime.p; + this.prime = prime; + } else { + this.m = m; + this.prime = null; + } +} + +Red.prototype._verify1 = function _verify1(a) { + assert(!a.sign, 'red works only with positives'); + assert(a.red, 'red works only with red numbers'); +}; + +Red.prototype._verify2 = function _verify2(a, b) { + assert(!a.sign && !b.sign, 'red works only with positives'); + assert(a.red && a.red === b.red, + 'red works only with red numbers'); +}; + +Red.prototype.imod = function imod(a) { + if (this.prime) + return this.prime.ireduce(a)._forceRed(this); + return a.mod(this.m)._forceRed(this); +}; + +Red.prototype.neg = function neg(a) { + var r = a.clone(); + r.sign = !r.sign; + return r.iadd(this.m)._forceRed(this); +}; + +Red.prototype.add = function add(a, b) { + this._verify2(a, b); + + var res = a.add(b); + if (res.cmp(this.m) >= 0) + res.isub(this.m); + return res._forceRed(this); +}; + +Red.prototype.iadd = function iadd(a, b) { + this._verify2(a, b); + + var res = a.iadd(b); + if (res.cmp(this.m) >= 0) + res.isub(this.m); + return res; +}; + +Red.prototype.sub = function sub(a, b) { + this._verify2(a, b); + + var res = a.sub(b); + if (res.cmpn(0) < 0) + res.iadd(this.m); + return res._forceRed(this); +}; + +Red.prototype.isub = function isub(a, b) { + this._verify2(a, b); + + var res = a.isub(b); + if (res.cmpn(0) < 0) + res.iadd(this.m); + return res; +}; + +Red.prototype.shl = function shl(a, num) { + this._verify1(a); + return this.imod(a.shln(num)); +}; + +Red.prototype.imul = function imul(a, b) { + this._verify2(a, b); + return this.imod(a.imul(b)); +}; + +Red.prototype.mul = function mul(a, b) { + this._verify2(a, b); + return this.imod(a.mul(b)); +}; + +Red.prototype.isqr = function isqr(a) { + return this.imul(a, a); +}; + +Red.prototype.sqr = function sqr(a) { + return this.mul(a, a); +}; + +Red.prototype.sqrt = function sqrt(a) { + if (a.cmpn(0) === 0) + return a.clone(); + + var mod3 = this.m.andln(3); + assert(mod3 % 2 === 1); + + // Fast case + if (mod3 === 3) { + var pow = this.m.add(new BN(1)).ishrn(2); + var r = this.pow(a, pow); + return r; + } + + // Tonelli-Shanks algorithm (Totally unoptimized and slow) + // + // Find Q and S, that Q * 2 ^ S = (P - 1) + var q = this.m.subn(1); + var s = 0; + while (q.cmpn(0) !== 0 && q.andln(1) === 0) { + s++; + q.ishrn(1); + } + assert(q.cmpn(0) !== 0); + + var one = new BN(1).toRed(this); + var nOne = one.redNeg(); + + // Find quadratic non-residue + // NOTE: Max is such because of generalized Riemann hypothesis. + var lpow = this.m.subn(1).ishrn(1); + var z = this.m.bitLength(); + z = new BN(2 * z * z).toRed(this); + while (this.pow(z, lpow).cmp(nOne) !== 0) + z.redIAdd(nOne); + + var c = this.pow(z, q); + var r = this.pow(a, q.addn(1).ishrn(1)); + var t = this.pow(a, q); + var m = s; + while (t.cmp(one) !== 0) { + var tmp = t; + for (var i = 0; tmp.cmp(one) !== 0; i++) + tmp = tmp.redSqr(); + assert(i < m); + var b = this.pow(c, new BN(1).ishln(m - i - 1)); + + r = r.redMul(b); + c = b.redSqr(); + t = t.redMul(c); + m = i; + } + + return r; +}; + +Red.prototype.invm = function invm(a) { + var inv = a._invmp(this.m); + if (inv.sign) { + inv.sign = false; + return this.imod(inv).redNeg(); + } else { + return this.imod(inv); + } +}; + +Red.prototype.pow = function pow(a, num) { + var w = []; + + if (num.cmpn(0) === 0) + return new BN(1); + + var q = num.clone(); + + while (q.cmpn(0) !== 0) { + w.push(q.andln(1)); + q.ishrn(1); + } + + // Skip leading zeroes + var res = a; + for (var i = 0; i < w.length; i++, res = this.sqr(res)) + if (w[i] !== 0) + break; + + if (++i < w.length) { + for (var q = this.sqr(res); i < w.length; i++, q = this.sqr(q)) { + if (w[i] === 0) + continue; + res = this.mul(res, q); + } + } + + return res; +}; + +Red.prototype.convertTo = function convertTo(num) { + var r = num.mod(this.m); + if (r === num) + return r.clone(); + else + return r; +}; + +Red.prototype.convertFrom = function convertFrom(num) { + var res = num.clone(); + res.red = null; + return res; +}; + +// +// Montgomery method engine +// + +BN.mont = function mont(num) { + return new Mont(num); +}; + +function Mont(m) { + Red.call(this, m); + + this.shift = this.m.bitLength(); + if (this.shift % 26 !== 0) + this.shift += 26 - (this.shift % 26); + this.r = new BN(1).ishln(this.shift); + this.r2 = this.imod(this.r.sqr()); + this.rinv = this.r._invmp(this.m); + + this.minv = this.rinv.mul(this.r).isubn(1).div(this.m); + this.minv.sign = true; + this.minv = this.minv.mod(this.r); +} +inherits(Mont, Red); + +Mont.prototype.convertTo = function convertTo(num) { + return this.imod(num.shln(this.shift)); +}; + +Mont.prototype.convertFrom = function convertFrom(num) { + var r = this.imod(num.mul(this.rinv)); + r.red = null; + return r; +}; + +Mont.prototype.imul = function imul(a, b) { + if (a.cmpn(0) === 0 || b.cmpn(0) === 0) { + a.words[0] = 0; + a.length = 1; + return a; + } + + var t = a.imul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).ishrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) + res = u.isub(this.m); + else if (u.cmpn(0) < 0) + res = u.iadd(this.m); + + return res._forceRed(this); +}; + +Mont.prototype.mul = function mul(a, b) { + if (a.cmpn(0) === 0 || b.cmpn(0) === 0) + return new BN(0)._forceRed(this); + + var t = a.mul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).ishrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) + res = u.isub(this.m); + else if (u.cmpn(0) < 0) + res = u.iadd(this.m); + + return res._forceRed(this); +}; + +Mont.prototype.invm = function invm(a) { + // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R + var res = this.imod(a._invmp(this.m).mul(this.r2)); + return res._forceRed(this); +}; + +})(typeof module === 'undefined' || module, this); + +},{}],61:[function(require,module,exports){ +(function (Buffer){ +var bn = require('bn.js'); +var randomBytes = require('randombytes'); +module.exports = crt; +function blind(priv) { + var r = getr(priv); + var blinder = r.toRed(bn.mont(priv.modulus)) + .redPow(new bn(priv.publicExponent)).fromRed(); + return { + blinder: blinder, + unblinder:r.invm(priv.modulus) + }; +} +function crt(msg, priv) { + var blinds = blind(priv); + var len = priv.modulus.byteLength(); + var mod = bn.mont(priv.modulus); + var blinded = new bn(msg).mul(blinds.blinder).mod(priv.modulus); + var c1 = blinded.toRed(bn.mont(priv.prime1)); + var c2 = blinded.toRed(bn.mont(priv.prime2)); + var qinv = priv.coefficient; + var p = priv.prime1; + var q = priv.prime2; + var m1 = c1.redPow(priv.exponent1); + var m2 = c2.redPow(priv.exponent2); + m1 = m1.fromRed(); + m2 = m2.fromRed(); + var h = m1.isub(m2).imul(qinv).mod(p); + h.imul(q); + m2.iadd(h); + var out = new Buffer(m2.imul(blinds.unblinder).mod(priv.modulus).toArray()); + if (out.length < len) { + var prefix = new Buffer(len - out.length); + prefix.fill(0); + out = Buffer.concat([prefix, out], len); + } + return out; +} +crt.getr = getr; +function getr(priv) { + var len = priv.modulus.byteLength(); + var r = new bn(randomBytes(len)); + while (r.cmp(priv.modulus) >= 0 || !r.mod(priv.prime1) || !r.mod(priv.prime2)) { + r = new bn(randomBytes(len)); + } + return r; +} +}).call(this,require("buffer").Buffer) +},{"bn.js":60,"buffer":34,"randombytes":178}],62:[function(require,module,exports){ +'use strict'; + +var elliptic = exports; + +elliptic.version = require('../package.json').version; +elliptic.utils = require('./elliptic/utils'); +elliptic.rand = require('brorand'); +elliptic.hmacDRBG = require('./elliptic/hmac-drbg'); +elliptic.curve = require('./elliptic/curve'); +elliptic.curves = require('./elliptic/curves'); + +// Protocols +elliptic.ec = require('./elliptic/ec'); + +},{"../package.json":82,"./elliptic/curve":65,"./elliptic/curves":68,"./elliptic/ec":69,"./elliptic/hmac-drbg":72,"./elliptic/utils":74,"brorand":75}],63:[function(require,module,exports){ +'use strict'; + +var bn = require('bn.js'); +var elliptic = require('../../elliptic'); + +var getNAF = elliptic.utils.getNAF; +var getJSF = elliptic.utils.getJSF; +var assert = elliptic.utils.assert; + +function BaseCurve(type, conf) { + this.type = type; + this.p = new bn(conf.p, 16); + + // Use Montgomery, when there is no fast reduction for the prime + this.red = conf.prime ? bn.red(conf.prime) : bn.mont(this.p); + + // Useful for many curves + this.zero = new bn(0).toRed(this.red); + this.one = new bn(1).toRed(this.red); + this.two = new bn(2).toRed(this.red); + + // Curve configuration, optional + this.n = conf.n && new bn(conf.n, 16); + this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed); + + // Temporary arrays + this._wnafT1 = new Array(4); + this._wnafT2 = new Array(4); + this._wnafT3 = new Array(4); + this._wnafT4 = new Array(4); +} +module.exports = BaseCurve; + +BaseCurve.prototype.point = function point() { + throw new Error('Not implemented'); +}; + +BaseCurve.prototype.validate = function validate() { + throw new Error('Not implemented'); +}; + +BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { + assert(p.precomputed); + var doubles = p._getDoubles(); + + var naf = getNAF(k, 1); + var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1); + I /= 3; + + // Translate into more windowed form + var repr = []; + for (var j = 0; j < naf.length; j += doubles.step) { + var nafW = 0; + for (var k = j + doubles.step - 1; k >= j; k--) + nafW = (nafW << 1) + naf[k]; + repr.push(nafW); + } + + var a = this.jpoint(null, null, null); + var b = this.jpoint(null, null, null); + for (var i = I; i > 0; i--) { + for (var j = 0; j < repr.length; j++) { + var nafW = repr[j]; + if (nafW === i) + b = b.mixedAdd(doubles.points[j]); + else if (nafW === -i) + b = b.mixedAdd(doubles.points[j].neg()); + } + a = a.add(b); + } + return a.toP(); +}; + +BaseCurve.prototype._wnafMul = function _wnafMul(p, k) { + var w = 4; + + // Precompute window + var nafPoints = p._getNAFPoints(w); + w = nafPoints.wnd; + var wnd = nafPoints.points; + + // Get NAF form + var naf = getNAF(k, w); + + // Add `this`*(N+1) for every w-NAF index + var acc = this.jpoint(null, null, null); + for (var i = naf.length - 1; i >= 0; i--) { + // Count zeroes + for (var k = 0; i >= 0 && naf[i] === 0; i--) + k++; + if (i >= 0) + k++; + acc = acc.dblp(k); + + if (i < 0) + break; + var z = naf[i]; + assert(z !== 0); + if (p.type === 'affine') { + // J +- P + if (z > 0) + acc = acc.mixedAdd(wnd[(z - 1) >> 1]); + else + acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg()); + } else { + // J +- J + if (z > 0) + acc = acc.add(wnd[(z - 1) >> 1]); + else + acc = acc.add(wnd[(-z - 1) >> 1].neg()); + } + } + return p.type === 'affine' ? acc.toP() : acc; +}; + +BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, + points, + coeffs, + len) { + var wndWidth = this._wnafT1; + var wnd = this._wnafT2; + var naf = this._wnafT3; + + // Fill all arrays + var max = 0; + for (var i = 0; i < len; i++) { + var p = points[i]; + var nafPoints = p._getNAFPoints(defW); + wndWidth[i] = nafPoints.wnd; + wnd[i] = nafPoints.points; + } + + // Comb small window NAFs + for (var i = len - 1; i >= 1; i -= 2) { + var a = i - 1; + var b = i; + if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { + naf[a] = getNAF(coeffs[a], wndWidth[a]); + naf[b] = getNAF(coeffs[b], wndWidth[b]); + max = Math.max(naf[a].length, max); + max = Math.max(naf[b].length, max); + continue; + } + + var comb = [ + points[a], /* 1 */ + null, /* 3 */ + null, /* 5 */ + points[b] /* 7 */ + ]; + + // Try to avoid Projective points, if possible + if (points[a].y.cmp(points[b].y) === 0) { + comb[1] = points[a].add(points[b]); + comb[2] = points[a].toJ().mixedAdd(points[b].neg()); + } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) { + comb[1] = points[a].toJ().mixedAdd(points[b]); + comb[2] = points[a].add(points[b].neg()); + } else { + comb[1] = points[a].toJ().mixedAdd(points[b]); + comb[2] = points[a].toJ().mixedAdd(points[b].neg()); + } + + var index = [ + -3, /* -1 -1 */ + -1, /* -1 0 */ + -5, /* -1 1 */ + -7, /* 0 -1 */ + 0, /* 0 0 */ + 7, /* 0 1 */ + 5, /* 1 -1 */ + 1, /* 1 0 */ + 3 /* 1 1 */ + ]; + + var jsf = getJSF(coeffs[a], coeffs[b]); + max = Math.max(jsf[0].length, max); + naf[a] = new Array(max); + naf[b] = new Array(max); + for (var j = 0; j < max; j++) { + var ja = jsf[0][j] | 0; + var jb = jsf[1][j] | 0; + + naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; + naf[b][j] = 0; + wnd[a] = comb; + } + } + + var acc = this.jpoint(null, null, null); + var tmp = this._wnafT4; + for (var i = max; i >= 0; i--) { + var k = 0; + + while (i >= 0) { + var zero = true; + for (var j = 0; j < len; j++) { + tmp[j] = naf[j][i] | 0; + if (tmp[j] !== 0) + zero = false; + } + if (!zero) + break; + k++; + i--; + } + if (i >= 0) + k++; + acc = acc.dblp(k); + if (i < 0) + break; + + for (var j = 0; j < len; j++) { + var z = tmp[j]; + var p; + if (z === 0) + continue; + else if (z > 0) + p = wnd[j][(z - 1) >> 1]; + else if (z < 0) + p = wnd[j][(-z - 1) >> 1].neg(); + + if (p.type === 'affine') + acc = acc.mixedAdd(p); + else + acc = acc.add(p); + } + } + // Zeroify references + for (var i = 0; i < len; i++) + wnd[i] = null; + return acc.toP(); +}; + +function BasePoint(curve, type) { + this.curve = curve; + this.type = type; + this.precomputed = null; +} +BaseCurve.BasePoint = BasePoint; + +BasePoint.prototype.validate = function validate() { + return this.curve.validate(this); +}; + +BasePoint.prototype.precompute = function precompute(power) { + if (this.precomputed) + return this; + + var precomputed = { + doubles: null, + naf: null, + beta: null + }; + precomputed.naf = this._getNAFPoints(8); + precomputed.doubles = this._getDoubles(4, power); + precomputed.beta = this._getBeta(); + this.precomputed = precomputed; + + return this; +}; + +BasePoint.prototype._hasDoubles = function _hasDoubles(k) { + if (!this.precomputed) + return false; + + var doubles = this.precomputed.doubles; + if (!doubles) + return false; + + return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step); +}; + +BasePoint.prototype._getDoubles = function _getDoubles(step, power) { + if (this.precomputed && this.precomputed.doubles) + return this.precomputed.doubles; + + var doubles = [ this ]; + var acc = this; + for (var i = 0; i < power; i += step) { + for (var j = 0; j < step; j++) + acc = acc.dbl(); + doubles.push(acc); + } + return { + step: step, + points: doubles + }; +}; + +BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { + if (this.precomputed && this.precomputed.naf) + return this.precomputed.naf; + + var res = [ this ]; + var max = (1 << wnd) - 1; + var dbl = max === 1 ? null : this.dbl(); + for (var i = 1; i < max; i++) + res[i] = res[i - 1].add(dbl); + return { + wnd: wnd, + points: res + }; +}; + +BasePoint.prototype._getBeta = function _getBeta() { + return null; +}; + +BasePoint.prototype.dblp = function dblp(k) { + var r = this; + for (var i = 0; i < k; i++) + r = r.dbl(); + return r; +}; + +},{"../../elliptic":62,"bn.js":60}],64:[function(require,module,exports){ +'use strict'; + +var curve = require('../curve'); +var elliptic = require('../../elliptic'); +var bn = require('bn.js'); +var inherits = require('inherits'); +var Base = curve.base; + +var assert = elliptic.utils.assert; + +function EdwardsCurve(conf) { + // NOTE: Important as we are creating point in Base.call() + this.twisted = (conf.a | 0) !== 1; + this.mOneA = this.twisted && (conf.a | 0) === -1; + this.extended = this.mOneA; + + Base.call(this, 'edwards', conf); + + this.a = new bn(conf.a, 16).mod(this.red.m).toRed(this.red); + this.c = new bn(conf.c, 16).toRed(this.red); + this.c2 = this.c.redSqr(); + this.d = new bn(conf.d, 16).toRed(this.red); + this.dd = this.d.redAdd(this.d); + + assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); + this.oneC = (conf.c | 0) === 1; +} +inherits(EdwardsCurve, Base); +module.exports = EdwardsCurve; + +EdwardsCurve.prototype._mulA = function _mulA(num) { + if (this.mOneA) + return num.redNeg(); + else + return this.a.redMul(num); +}; + +EdwardsCurve.prototype._mulC = function _mulC(num) { + if (this.oneC) + return num; + else + return this.c.redMul(num); +}; + +// Just for compatibility with Short curve +EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { + return this.point(x, y, z, t); +}; + +EdwardsCurve.prototype.pointFromX = function pointFromX(odd, x) { + x = new bn(x, 16); + if (!x.red) + x = x.toRed(this.red); + + var x2 = x.redSqr(); + var rhs = this.c2.redSub(this.a.redMul(x2)); + var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); + + var y = rhs.redMul(lhs.redInvm()).redSqrt(); + var isOdd = y.fromRed().isOdd(); + if (odd && !isOdd || !odd && isOdd) + y = y.redNeg(); + + return this.point(x, y, curve.one); +}; + +EdwardsCurve.prototype.validate = function validate(point) { + if (point.isInfinity()) + return true; + + // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) + point.normalize(); + + var x2 = point.x.redSqr(); + var y2 = point.y.redSqr(); + var lhs = x2.redMul(this.a).redAdd(y2); + var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); + + return lhs.cmp(rhs) === 0; +}; + +function Point(curve, x, y, z, t) { + Base.BasePoint.call(this, curve, 'projective'); + if (x === null && y === null && z === null) { + this.x = this.curve.zero; + this.y = this.curve.one; + this.z = this.curve.one; + this.t = this.curve.zero; + this.zOne = true; + } else { + this.x = new bn(x, 16); + this.y = new bn(y, 16); + this.z = z ? new bn(z, 16) : this.curve.one; + this.t = t && new bn(t, 16); + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); + if (this.t && !this.t.red) + this.t = this.t.toRed(this.curve.red); + this.zOne = this.z === this.curve.one; + + // Use extended coordinates + if (this.curve.extended && !this.t) { + this.t = this.x.redMul(this.y); + if (!this.zOne) + this.t = this.t.redMul(this.z.redInvm()); + } + } +} +inherits(Point, Base.BasePoint); + +EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { + return Point.fromJSON(this, obj); +}; + +EdwardsCurve.prototype.point = function point(x, y, z, t) { + return new Point(this, x, y, z, t); +}; + +Point.fromJSON = function fromJSON(curve, obj) { + return new Point(curve, obj[0], obj[1], obj[2]); +}; + +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; + +Point.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.x.cmpn(0) === 0 && + this.y.cmp(this.z) === 0; +}; + +Point.prototype._extDbl = function _extDbl() { + // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html + // #doubling-dbl-2008-hwcd + // 4M + 4S + + // A = X1^2 + var a = this.x.redSqr(); + // B = Y1^2 + var b = this.y.redSqr(); + // C = 2 * Z1^2 + var c = this.z.redSqr(); + c = c.redIAdd(c); + // D = a * A + var d = this.curve._mulA(a); + // E = (X1 + Y1)^2 - A - B + var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); + // G = D + B + var g = d.redAdd(b); + // F = G - C + var f = g.redSub(c); + // H = D - B + var h = d.redSub(b); + // X3 = E * F + var nx = e.redMul(f); + // Y3 = G * H + var ny = g.redMul(h); + // T3 = E * H + var nt = e.redMul(h); + // Z3 = F * G + var nz = f.redMul(g); + return this.curve.point(nx, ny, nz, nt); +}; + +Point.prototype._projDbl = function _projDbl() { + // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html + // #doubling-dbl-2008-bbjlp + // #doubling-dbl-2007-bl + // and others + // Generally 3M + 4S or 2M + 4S + + // B = (X1 + Y1)^2 + var b = this.x.redAdd(this.y).redSqr(); + // C = X1^2 + var c = this.x.redSqr(); + // D = Y1^2 + var d = this.y.redSqr(); + + var nx; + var ny; + var nz; + if (this.curve.twisted) { + // E = a * C + var e = this.curve._mulA(c); + // F = E + D + var f = e.redAdd(d); + if (this.zOne) { + // X3 = (B - C - D) * (F - 2) + nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); + // Y3 = F * (E - D) + ny = f.redMul(e.redSub(d)); + // Z3 = F^2 - 2 * F + nz = f.redSqr().redSub(f).redSub(f); + } else { + // H = Z1^2 + var h = this.z.redSqr(); + // J = F - 2 * H + var j = f.redSub(h).redISub(h); + // X3 = (B-C-D)*J + nx = b.redSub(c).redISub(d).redMul(j); + // Y3 = F * (E - D) + ny = f.redMul(e.redSub(d)); + // Z3 = F * J + nz = f.redMul(j); + } + } else { + // E = C + D + var e = c.redAdd(d); + // H = (c * Z1)^2 + var h = this.curve._mulC(this.c.redMul(this.z)).redSqr(); + // J = E - 2 * H + var j = e.redSub(h).redSub(h); + // X3 = c * (B - E) * J + nx = this.curve._mulC(b.redISub(e)).redMul(j); + // Y3 = c * E * (C - D) + ny = this.curve._mulC(e).redMul(c.redISub(d)); + // Z3 = E * J + nz = e.redMul(j); + } + return this.curve.point(nx, ny, nz); +}; + +Point.prototype.dbl = function dbl() { + if (this.isInfinity()) + return this; + + // Double in extended coordinates + if (this.curve.extended) + return this._extDbl(); + else + return this._projDbl(); +}; + +Point.prototype._extAdd = function _extAdd(p) { + // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html + // #addition-add-2008-hwcd-3 + // 8M + + // A = (Y1 - X1) * (Y2 - X2) + var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); + // B = (Y1 + X1) * (Y2 + X2) + var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); + // C = T1 * k * T2 + var c = this.t.redMul(this.curve.dd).redMul(p.t); + // D = Z1 * 2 * Z2 + var d = this.z.redMul(p.z.redAdd(p.z)); + // E = B - A + var e = b.redSub(a); + // F = D - C + var f = d.redSub(c); + // G = D + C + var g = d.redAdd(c); + // H = B + A + var h = b.redAdd(a); + // X3 = E * F + var nx = e.redMul(f); + // Y3 = G * H + var ny = g.redMul(h); + // T3 = E * H + var nt = e.redMul(h); + // Z3 = F * G + var nz = f.redMul(g); + return this.curve.point(nx, ny, nz, nt); +}; + +Point.prototype._projAdd = function _projAdd(p) { + // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html + // #addition-add-2008-bbjlp + // #addition-add-2007-bl + // 10M + 1S + + // A = Z1 * Z2 + var a = this.z.redMul(p.z); + // B = A^2 + var b = a.redSqr(); + // C = X1 * X2 + var c = this.x.redMul(p.x); + // D = Y1 * Y2 + var d = this.y.redMul(p.y); + // E = d * C * D + var e = this.curve.d.redMul(c).redMul(d); + // F = B - E + var f = b.redSub(e); + // G = B + E + var g = b.redAdd(e); + // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) + var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); + var nx = a.redMul(f).redMul(tmp); + var ny; + var nz; + if (this.curve.twisted) { + // Y3 = A * G * (D - a * C) + ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); + // Z3 = F * G + nz = f.redMul(g); + } else { + // Y3 = A * G * (D - C) + ny = a.redMul(g).redMul(d.redSub(c)); + // Z3 = c * F * G + nz = this.curve._mulC(f).redMul(g); + } + return this.curve.point(nx, ny, nz); +}; + +Point.prototype.add = function add(p) { + if (this.isInfinity()) + return p; + if (p.isInfinity()) + return this; + + if (this.curve.extended) + return this._extAdd(p); + else + return this._projAdd(p); +}; + +Point.prototype.mul = function mul(k) { + if (this._hasDoubles(k)) + return this.curve._fixedNafMul(this, k); + else + return this.curve._wnafMul(this, k); +}; + +Point.prototype.mulAdd = function mulAdd(k1, p, k2) { + return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2); +}; + +Point.prototype.normalize = function normalize() { + if (this.zOne) + return this; + + // Normalize coordinates + var zi = this.z.redInvm(); + this.x = this.x.redMul(zi); + this.y = this.y.redMul(zi); + if (this.t) + this.t = this.t.redMul(zi); + this.z = this.curve.one; + this.zOne = true; + return this; +}; + +Point.prototype.neg = function neg() { + return this.curve.point(this.x.redNeg(), + this.y, + this.z, + this.t && this.t.redNeg()); +}; + +Point.prototype.getX = function getX() { + this.normalize(); + return this.x.fromRed(); +}; + +Point.prototype.getY = function getY() { + this.normalize(); + return this.y.fromRed(); +}; + +// Compatibility with BaseCurve +Point.prototype.toP = Point.prototype.normalize; +Point.prototype.mixedAdd = Point.prototype.add; + +},{"../../elliptic":62,"../curve":65,"bn.js":60,"inherits":180}],65:[function(require,module,exports){ +'use strict'; + +var curve = exports; + +curve.base = require('./base'); +curve.short = require('./short'); +curve.mont = require('./mont'); +curve.edwards = require('./edwards'); + +},{"./base":63,"./edwards":64,"./mont":66,"./short":67}],66:[function(require,module,exports){ +'use strict'; + +var curve = require('../curve'); +var bn = require('bn.js'); +var inherits = require('inherits'); +var Base = curve.base; + +function MontCurve(conf) { + Base.call(this, 'mont', conf); + + this.a = new bn(conf.a, 16).toRed(this.red); + this.b = new bn(conf.b, 16).toRed(this.red); + this.i4 = new bn(4).toRed(this.red).redInvm(); + this.two = new bn(2).toRed(this.red); + this.a24 = this.i4.redMul(this.a.redAdd(this.two)); +} +inherits(MontCurve, Base); +module.exports = MontCurve; + +MontCurve.prototype.validate = function validate(point) { + var x = point.normalize().x; + var x2 = x.redSqr(); + var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x); + var y = rhs.redSqrt(); + + return y.redSqr().cmp(rhs) === 0; +}; + +function Point(curve, x, z) { + Base.BasePoint.call(this, curve, 'projective'); + if (x === null && z === null) { + this.x = this.curve.one; + this.z = this.curve.zero; + } else { + this.x = new bn(x, 16); + this.z = new bn(z, 16); + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); + } +} +inherits(Point, Base.BasePoint); + +MontCurve.prototype.point = function point(x, z) { + return new Point(this, x, z); +}; + +MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) { + return Point.fromJSON(this, obj); +}; + +Point.prototype.precompute = function precompute() { + // No-op +}; + +Point.fromJSON = function fromJSON(curve, obj) { + return new Point(curve, obj[0], obj[1] || curve.one); +}; + +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; + +Point.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.z.cmpn(0) === 0; +}; + +Point.prototype.dbl = function dbl() { + // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3 + // 2M + 2S + 4A + + // A = X1 + Z1 + var a = this.x.redAdd(this.z); + // AA = A^2 + var aa = a.redSqr(); + // B = X1 - Z1 + var b = this.x.redSub(this.z); + // BB = B^2 + var bb = b.redSqr(); + // C = AA - BB + var c = aa.redSub(bb); + // X3 = AA * BB + var nx = aa.redMul(bb); + // Z3 = C * (BB + A24 * C) + var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c))); + return this.curve.point(nx, nz); +}; + +Point.prototype.add = function add() { + throw new Error('Not supported on Montgomery curve'); +}; + +Point.prototype.diffAdd = function diffAdd(p, diff) { + // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3 + // 4M + 2S + 6A + + // A = X2 + Z2 + var a = this.x.redAdd(this.z); + // B = X2 - Z2 + var b = this.x.redSub(this.z); + // C = X3 + Z3 + var c = p.x.redAdd(p.z); + // D = X3 - Z3 + var d = p.x.redSub(p.z); + // DA = D * A + var da = d.redMul(a); + // CB = C * B + var cb = c.redMul(b); + // X5 = Z1 * (DA + CB)^2 + var nx = diff.z.redMul(da.redAdd(cb).redSqr()); + // Z5 = X1 * (DA - CB)^2 + var nz = diff.x.redMul(da.redISub(cb).redSqr()); + return this.curve.point(nx, nz); +}; + +Point.prototype.mul = function mul(k) { + var t = k.clone(); + var a = this; // (N / 2) * Q + Q + var b = this.curve.point(null, null); // (N / 2) * Q + var c = this; // Q + + for (var bits = []; t.cmpn(0) !== 0; t.ishrn(1)) + bits.push(t.andln(1)); + + for (var i = bits.length - 1; i >= 0; i--) { + if (bits[i] === 0) { + // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q + a = a.diffAdd(b, c); + // N * Q = 2 * ((N / 2) * Q + Q)) + b = b.dbl(); + } else { + // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q) + b = a.diffAdd(b, c); + // N * Q + Q = 2 * ((N / 2) * Q + Q) + a = a.dbl(); + } + } + return b; +}; + +Point.prototype.mulAdd = function mulAdd() { + throw new Error('Not supported on Montgomery curve'); +}; + +Point.prototype.normalize = function normalize() { + this.x = this.x.redMul(this.z.redInvm()); + this.z = this.curve.one; + return this; +}; + +Point.prototype.getX = function getX() { + // Normalize coordinates + this.normalize(); + + return this.x.fromRed(); +}; + +},{"../curve":65,"bn.js":60,"inherits":180}],67:[function(require,module,exports){ +'use strict'; + +var curve = require('../curve'); +var elliptic = require('../../elliptic'); +var bn = require('bn.js'); +var inherits = require('inherits'); +var Base = curve.base; + +var assert = elliptic.utils.assert; + +function ShortCurve(conf) { + Base.call(this, 'short', conf); + + this.a = new bn(conf.a, 16).toRed(this.red); + this.b = new bn(conf.b, 16).toRed(this.red); + this.tinv = this.two.redInvm(); + + this.zeroA = this.a.fromRed().cmpn(0) === 0; + this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0; + + // If the curve is endomorphic, precalculate beta and lambda + this.endo = this._getEndomorphism(conf); + this._endoWnafT1 = new Array(4); + this._endoWnafT2 = new Array(4); +} +inherits(ShortCurve, Base); +module.exports = ShortCurve; + +ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) { + // No efficient endomorphism + if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1) + return; + + // Compute beta and lambda, that lambda * P = (beta * Px; Py) + var beta; + var lambda; + if (conf.beta) { + beta = new bn(conf.beta, 16).toRed(this.red); + } else { + var betas = this._getEndoRoots(this.p); + // Choose the smallest beta + beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1]; + beta = beta.toRed(this.red); + } + if (conf.lambda) { + lambda = new bn(conf.lambda, 16); + } else { + // Choose the lambda that is matching selected beta + var lambdas = this._getEndoRoots(this.n); + if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) { + lambda = lambdas[0]; + } else { + lambda = lambdas[1]; + assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0); + } + } + + // Get basis vectors, used for balanced length-two representation + var basis; + if (conf.basis) { + basis = conf.basis.map(function(vec) { + return { + a: new bn(vec.a, 16), + b: new bn(vec.b, 16) + }; + }); + } else { + basis = this._getEndoBasis(lambda); + } + + return { + beta: beta, + lambda: lambda, + basis: basis + }; +}; + +ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) { + // Find roots of for x^2 + x + 1 in F + // Root = (-1 +- Sqrt(-3)) / 2 + // + var red = num === this.p ? this.red : bn.mont(num); + var tinv = new bn(2).toRed(red).redInvm(); + var ntinv = tinv.redNeg(); + + var s = new bn(3).toRed(red).redNeg().redSqrt().redMul(tinv); + + var l1 = ntinv.redAdd(s).fromRed(); + var l2 = ntinv.redSub(s).fromRed(); + return [ l1, l2 ]; +}; + +ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) { + // aprxSqrt >= sqrt(this.n) + var aprxSqrt = this.n.shrn(Math.floor(this.n.bitLength() / 2)); + + // 3.74 + // Run EGCD, until r(L + 1) < aprxSqrt + var u = lambda; + var v = this.n.clone(); + var x1 = new bn(1); + var y1 = new bn(0); + var x2 = new bn(0); + var y2 = new bn(1); + + // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n) + var a0; + var b0; + // First vector + var a1; + var b1; + // Second vector + var a2; + var b2; + + var prevR; + var i = 0; + var r; + var x; + while (u.cmpn(0) !== 0) { + var q = v.div(u); + r = v.sub(q.mul(u)); + x = x2.sub(q.mul(x1)); + var y = y2.sub(q.mul(y1)); + + if (!a1 && r.cmp(aprxSqrt) < 0) { + a0 = prevR.neg(); + b0 = x1; + a1 = r.neg(); + b1 = x; + } else if (a1 && ++i === 2) { + break; + } + prevR = r; + + v = u; + u = r; + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; + } + a2 = r.neg(); + b2 = x; + + var len1 = a1.sqr().add(b1.sqr()); + var len2 = a2.sqr().add(b2.sqr()); + if (len2.cmp(len1) >= 0) { + a2 = a0; + b2 = b0; + } + + // Normalize signs + if (a1.sign) { + a1 = a1.neg(); + b1 = b1.neg(); + } + if (a2.sign) { + a2 = a2.neg(); + b2 = b2.neg(); + } + + return [ + { a: a1, b: b1 }, + { a: a2, b: b2 } + ]; +}; + +ShortCurve.prototype._endoSplit = function _endoSplit(k) { + var basis = this.endo.basis; + var v1 = basis[0]; + var v2 = basis[1]; + + var c1 = v2.b.mul(k).divRound(this.n); + var c2 = v1.b.neg().mul(k).divRound(this.n); + + var p1 = c1.mul(v1.a); + var p2 = c2.mul(v2.a); + var q1 = c1.mul(v1.b); + var q2 = c2.mul(v2.b); + + // Calculate answer + var k1 = k.sub(p1).sub(p2); + var k2 = q1.add(q2).neg(); + return { k1: k1, k2: k2 }; +}; + +ShortCurve.prototype.pointFromX = function pointFromX(odd, x) { + x = new bn(x, 16); + if (!x.red) + x = x.toRed(this.red); + + var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b); + var y = y2.redSqrt(); + + // XXX Is there any way to tell if the number is odd without converting it + // to non-red form? + var isOdd = y.fromRed().isOdd(); + if (odd && !isOdd || !odd && isOdd) + y = y.redNeg(); + + return this.point(x, y); +}; + +ShortCurve.prototype.validate = function validate(point) { + if (point.inf) + return true; + + var x = point.x; + var y = point.y; + + var ax = this.a.redMul(x); + var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b); + return y.redSqr().redISub(rhs).cmpn(0) === 0; +}; + +ShortCurve.prototype._endoWnafMulAdd = + function _endoWnafMulAdd(points, coeffs) { + var npoints = this._endoWnafT1; + var ncoeffs = this._endoWnafT2; + for (var i = 0; i < points.length; i++) { + var split = this._endoSplit(coeffs[i]); + var p = points[i]; + var beta = p._getBeta(); + + if (split.k1.sign) { + split.k1.sign = !split.k1.sign; + p = p.neg(true); + } + if (split.k2.sign) { + split.k2.sign = !split.k2.sign; + beta = beta.neg(true); + } + + npoints[i * 2] = p; + npoints[i * 2 + 1] = beta; + ncoeffs[i * 2] = split.k1; + ncoeffs[i * 2 + 1] = split.k2; + } + var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2); + + // Clean-up references to points and coefficients + for (var j = 0; j < i * 2; j++) { + npoints[j] = null; + ncoeffs[j] = null; + } + return res; +}; + +function Point(curve, x, y, isRed) { + Base.BasePoint.call(this, curve, 'affine'); + if (x === null && y === null) { + this.x = null; + this.y = null; + this.inf = true; + } else { + this.x = new bn(x, 16); + this.y = new bn(y, 16); + // Force redgomery representation when loading from JSON + if (isRed) { + this.x.forceRed(this.curve.red); + this.y.forceRed(this.curve.red); + } + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + this.inf = false; + } +} +inherits(Point, Base.BasePoint); + +ShortCurve.prototype.point = function point(x, y, isRed) { + return new Point(this, x, y, isRed); +}; + +ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) { + return Point.fromJSON(this, obj, red); +}; + +Point.prototype._getBeta = function _getBeta() { + if (!this.curve.endo) + return; + + var pre = this.precomputed; + if (pre && pre.beta) + return pre.beta; + + var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y); + if (pre) { + var curve = this.curve; + var endoMul = function(p) { + return curve.point(p.x.redMul(curve.endo.beta), p.y); + }; + pre.beta = beta; + beta.precomputed = { + beta: null, + naf: pre.naf && { + wnd: pre.naf.wnd, + points: pre.naf.points.map(endoMul) + }, + doubles: pre.doubles && { + step: pre.doubles.step, + points: pre.doubles.points.map(endoMul) + } + }; + } + return beta; +}; + +Point.prototype.toJSON = function toJSON() { + if (!this.precomputed) + return [ this.x, this.y ]; + + return [ this.x, this.y, this.precomputed && { + doubles: this.precomputed.doubles && { + step: this.precomputed.doubles.step, + points: this.precomputed.doubles.points.slice(1) + }, + naf: this.precomputed.naf && { + wnd: this.precomputed.naf.wnd, + points: this.precomputed.naf.points.slice(1) + } + } ]; +}; + +Point.fromJSON = function fromJSON(curve, obj, red) { + if (typeof obj === 'string') + obj = JSON.parse(obj); + var res = curve.point(obj[0], obj[1], red); + if (!obj[2]) + return res; + + function obj2point(obj) { + return curve.point(obj[0], obj[1], red); + } + + var pre = obj[2]; + res.precomputed = { + beta: null, + doubles: pre.doubles && { + step: pre.doubles.step, + points: [ res ].concat(pre.doubles.points.map(obj2point)) + }, + naf: pre.naf && { + wnd: pre.naf.wnd, + points: [ res ].concat(pre.naf.points.map(obj2point)) + } + }; + return res; +}; + +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; + +Point.prototype.isInfinity = function isInfinity() { + return this.inf; +}; + +Point.prototype.add = function add(p) { + // O + P = P + if (this.inf) + return p; + + // P + O = P + if (p.inf) + return this; + + // P + P = 2P + if (this.eq(p)) + return this.dbl(); + + // P + (-P) = O + if (this.neg().eq(p)) + return this.curve.point(null, null); + + // P + Q = O + if (this.x.cmp(p.x) === 0) + return this.curve.point(null, null); + + var c = this.y.redSub(p.y); + if (c.cmpn(0) !== 0) + c = c.redMul(this.x.redSub(p.x).redInvm()); + var nx = c.redSqr().redISub(this.x).redISub(p.x); + var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); + return this.curve.point(nx, ny); +}; + +Point.prototype.dbl = function dbl() { + if (this.inf) + return this; + + // 2P = O + var ys1 = this.y.redAdd(this.y); + if (ys1.cmpn(0) === 0) + return this.curve.point(null, null); + + var a = this.curve.a; + + var x2 = this.x.redSqr(); + var dyinv = ys1.redInvm(); + var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv); + + var nx = c.redSqr().redISub(this.x.redAdd(this.x)); + var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); + return this.curve.point(nx, ny); +}; + +Point.prototype.getX = function getX() { + return this.x.fromRed(); +}; + +Point.prototype.getY = function getY() { + return this.y.fromRed(); +}; + +Point.prototype.mul = function mul(k) { + k = new bn(k, 16); + + if (this._hasDoubles(k)) + return this.curve._fixedNafMul(this, k); + else if (this.curve.endo) + return this.curve._endoWnafMulAdd([ this ], [ k ]); + else + return this.curve._wnafMul(this, k); +}; + +Point.prototype.mulAdd = function mulAdd(k1, p2, k2) { + var points = [ this, p2 ]; + var coeffs = [ k1, k2 ]; + if (this.curve.endo) + return this.curve._endoWnafMulAdd(points, coeffs); + else + return this.curve._wnafMulAdd(1, points, coeffs, 2); +}; + +Point.prototype.eq = function eq(p) { + return this === p || + this.inf === p.inf && + (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0); +}; + +Point.prototype.neg = function neg(_precompute) { + if (this.inf) + return this; + + var res = this.curve.point(this.x, this.y.redNeg()); + if (_precompute && this.precomputed) { + var pre = this.precomputed; + var negate = function(p) { + return p.neg(); + }; + res.precomputed = { + naf: pre.naf && { + wnd: pre.naf.wnd, + points: pre.naf.points.map(negate) + }, + doubles: pre.doubles && { + step: pre.doubles.step, + points: pre.doubles.points.map(negate) + } + }; + } + return res; +}; + +Point.prototype.toJ = function toJ() { + if (this.inf) + return this.curve.jpoint(null, null, null); + + var res = this.curve.jpoint(this.x, this.y, this.curve.one); + return res; +}; + +function JPoint(curve, x, y, z) { + Base.BasePoint.call(this, curve, 'jacobian'); + if (x === null && y === null && z === null) { + this.x = this.curve.one; + this.y = this.curve.one; + this.z = new bn(0); + } else { + this.x = new bn(x, 16); + this.y = new bn(y, 16); + this.z = new bn(z, 16); + } + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); + + this.zOne = this.z === this.curve.one; +} +inherits(JPoint, Base.BasePoint); + +ShortCurve.prototype.jpoint = function jpoint(x, y, z) { + return new JPoint(this, x, y, z); +}; + +JPoint.prototype.toP = function toP() { + if (this.isInfinity()) + return this.curve.point(null, null); + + var zinv = this.z.redInvm(); + var zinv2 = zinv.redSqr(); + var ax = this.x.redMul(zinv2); + var ay = this.y.redMul(zinv2).redMul(zinv); + + return this.curve.point(ax, ay); +}; + +JPoint.prototype.neg = function neg() { + return this.curve.jpoint(this.x, this.y.redNeg(), this.z); +}; + +JPoint.prototype.add = function add(p) { + // O + P = P + if (this.isInfinity()) + return p; + + // P + O = P + if (p.isInfinity()) + return this; + + // 12M + 4S + 7A + var pz2 = p.z.redSqr(); + var z2 = this.z.redSqr(); + var u1 = this.x.redMul(pz2); + var u2 = p.x.redMul(z2); + var s1 = this.y.redMul(pz2.redMul(p.z)); + var s2 = p.y.redMul(z2.redMul(this.z)); + + var h = u1.redSub(u2); + var r = s1.redSub(s2); + if (h.cmpn(0) === 0) { + if (r.cmpn(0) !== 0) + return this.curve.jpoint(null, null, null); + else + return this.dbl(); + } + + var h2 = h.redSqr(); + var h3 = h2.redMul(h); + var v = u1.redMul(h2); + + var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); + var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); + var nz = this.z.redMul(p.z).redMul(h); + + return this.curve.jpoint(nx, ny, nz); +}; + +JPoint.prototype.mixedAdd = function mixedAdd(p) { + // O + P = P + if (this.isInfinity()) + return p.toJ(); + + // P + O = P + if (p.isInfinity()) + return this; + + // 8M + 3S + 7A + var z2 = this.z.redSqr(); + var u1 = this.x; + var u2 = p.x.redMul(z2); + var s1 = this.y; + var s2 = p.y.redMul(z2).redMul(this.z); + + var h = u1.redSub(u2); + var r = s1.redSub(s2); + if (h.cmpn(0) === 0) { + if (r.cmpn(0) !== 0) + return this.curve.jpoint(null, null, null); + else + return this.dbl(); + } + + var h2 = h.redSqr(); + var h3 = h2.redMul(h); + var v = u1.redMul(h2); + + var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); + var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); + var nz = this.z.redMul(h); + + return this.curve.jpoint(nx, ny, nz); +}; + +JPoint.prototype.dblp = function dblp(pow) { + if (pow === 0) + return this; + if (this.isInfinity()) + return this; + if (!pow) + return this.dbl(); + + if (this.curve.zeroA || this.curve.threeA) { + var r = this; + for (var i = 0; i < pow; i++) + r = r.dbl(); + return r; + } + + // 1M + 2S + 1A + N * (4S + 5M + 8A) + // N = 1 => 6M + 6S + 9A + var a = this.curve.a; + var tinv = this.curve.tinv; + + var jx = this.x; + var jy = this.y; + var jz = this.z; + var jz4 = jz.redSqr().redSqr(); + + // Reuse results + var jyd = jy.redAdd(jy); + for (var i = 0; i < pow; i++) { + var jx2 = jx.redSqr(); + var jyd2 = jyd.redSqr(); + var jyd4 = jyd2.redSqr(); + var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); + + var t1 = jx.redMul(jyd2); + var nx = c.redSqr().redISub(t1.redAdd(t1)); + var t2 = t1.redISub(nx); + var dny = c.redMul(t2); + dny = dny.redIAdd(dny).redISub(jyd4); + var nz = jyd.redMul(jz); + if (i + 1 < pow) + jz4 = jz4.redMul(jyd4); + + jx = nx; + jz = nz; + jyd = dny; + } + + return this.curve.jpoint(jx, jyd.redMul(tinv), jz); +}; + +JPoint.prototype.dbl = function dbl() { + if (this.isInfinity()) + return this; + + if (this.curve.zeroA) + return this._zeroDbl(); + else if (this.curve.threeA) + return this._threeDbl(); + else + return this._dbl(); +}; + +JPoint.prototype._zeroDbl = function _zeroDbl() { + var nx; + var ny; + var nz; + // Z = 1 + if (this.zOne) { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html + // #doubling-mdbl-2007-bl + // 1M + 5S + 14A + + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // S = 2 * ((X1 + YY)^2 - XX - YYYY) + var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + s = s.redIAdd(s); + // M = 3 * XX + a; a = 0 + var m = xx.redAdd(xx).redIAdd(xx); + // T = M ^ 2 - 2*S + var t = m.redSqr().redISub(s).redISub(s); + + // 8 * YYYY + var yyyy8 = yyyy.redIAdd(yyyy); + yyyy8 = yyyy8.redIAdd(yyyy8); + yyyy8 = yyyy8.redIAdd(yyyy8); + + // X3 = T + nx = t; + // Y3 = M * (S - T) - 8 * YYYY + ny = m.redMul(s.redISub(t)).redISub(yyyy8); + // Z3 = 2*Y1 + nz = this.y.redAdd(this.y); + } else { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html + // #doubling-dbl-2009-l + // 2M + 5S + 13A + + // A = X1^2 + var a = this.x.redSqr(); + // B = Y1^2 + var b = this.y.redSqr(); + // C = B^2 + var c = b.redSqr(); + // D = 2 * ((X1 + B)^2 - A - C) + var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c); + d = d.redIAdd(d); + // E = 3 * A + var e = a.redAdd(a).redIAdd(a); + // F = E^2 + var f = e.redSqr(); + + // 8 * C + var c8 = c.redIAdd(c); + c8 = c8.redIAdd(c8); + c8 = c8.redIAdd(c8); + + // X3 = F - 2 * D + nx = f.redISub(d).redISub(d); + // Y3 = E * (D - X3) - 8 * C + ny = e.redMul(d.redISub(nx)).redISub(c8); + // Z3 = 2 * Y1 * Z1 + nz = this.y.redMul(this.z); + nz = nz.redIAdd(nz); + } + + return this.curve.jpoint(nx, ny, nz); +}; + +JPoint.prototype._threeDbl = function _threeDbl() { + var nx; + var ny; + var nz; + // Z = 1 + if (this.zOne) { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html + // #doubling-mdbl-2007-bl + // 1M + 5S + 15A + + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // S = 2 * ((X1 + YY)^2 - XX - YYYY) + var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + s = s.redIAdd(s); + // M = 3 * XX + a + var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a); + // T = M^2 - 2 * S + var t = m.redSqr().redISub(s).redISub(s); + // X3 = T + nx = t; + // Y3 = M * (S - T) - 8 * YYYY + var yyyy8 = yyyy.redIAdd(yyyy); + yyyy8 = yyyy8.redIAdd(yyyy8); + yyyy8 = yyyy8.redIAdd(yyyy8); + ny = m.redMul(s.redISub(t)).redISub(yyyy8); + // Z3 = 2 * Y1 + nz = this.y.redAdd(this.y); + } else { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + // 3M + 5S + + // delta = Z1^2 + var delta = this.z.redSqr(); + // gamma = Y1^2 + var gamma = this.y.redSqr(); + // beta = X1 * gamma + var beta = this.x.redMul(gamma); + // alpha = 3 * (X1 - delta) * (X1 + delta) + var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta)); + alpha = alpha.redAdd(alpha).redIAdd(alpha); + // X3 = alpha^2 - 8 * beta + var beta4 = beta.redIAdd(beta); + beta4 = beta4.redIAdd(beta4); + var beta8 = beta4.redAdd(beta4); + nx = alpha.redSqr().redISub(beta8); + // Z3 = (Y1 + Z1)^2 - gamma - delta + nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta); + // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2 + var ggamma8 = gamma.redSqr(); + ggamma8 = ggamma8.redIAdd(ggamma8); + ggamma8 = ggamma8.redIAdd(ggamma8); + ggamma8 = ggamma8.redIAdd(ggamma8); + ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8); + } + + return this.curve.jpoint(nx, ny, nz); +}; + +JPoint.prototype._dbl = function _dbl() { + var a = this.curve.a; + + // 4M + 6S + 10A + var jx = this.x; + var jy = this.y; + var jz = this.z; + var jz4 = jz.redSqr().redSqr(); + + var jx2 = jx.redSqr(); + var jy2 = jy.redSqr(); + + var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); + + var jxd4 = jx.redAdd(jx); + jxd4 = jxd4.redIAdd(jxd4); + var t1 = jxd4.redMul(jy2); + var nx = c.redSqr().redISub(t1.redAdd(t1)); + var t2 = t1.redISub(nx); + + var jyd8 = jy2.redSqr(); + jyd8 = jyd8.redIAdd(jyd8); + jyd8 = jyd8.redIAdd(jyd8); + jyd8 = jyd8.redIAdd(jyd8); + var ny = c.redMul(t2).redISub(jyd8); + var nz = jy.redAdd(jy).redMul(jz); + + return this.curve.jpoint(nx, ny, nz); +}; + +JPoint.prototype.trpl = function trpl() { + if (!this.curve.zeroA) + return this.dbl().add(this); + + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl + // 5M + 10S + ... + + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // ZZ = Z1^2 + var zz = this.z.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // M = 3 * XX + a * ZZ2; a = 0 + var m = xx.redAdd(xx).redIAdd(xx); + // MM = M^2 + var mm = m.redSqr(); + // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM + var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + e = e.redIAdd(e); + e = e.redAdd(e).redIAdd(e); + e = e.redISub(mm); + // EE = E^2 + var ee = e.redSqr(); + // T = 16*YYYY + var t = yyyy.redIAdd(yyyy); + t = t.redIAdd(t); + t = t.redIAdd(t); + t = t.redIAdd(t); + // U = (M + E)^2 - MM - EE - T + var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t); + // X3 = 4 * (X1 * EE - 4 * YY * U) + var yyu4 = yy.redMul(u); + yyu4 = yyu4.redIAdd(yyu4); + yyu4 = yyu4.redIAdd(yyu4); + var nx = this.x.redMul(ee).redISub(yyu4); + nx = nx.redIAdd(nx); + nx = nx.redIAdd(nx); + // Y3 = 8 * Y1 * (U * (T - U) - E * EE) + var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee))); + ny = ny.redIAdd(ny); + ny = ny.redIAdd(ny); + ny = ny.redIAdd(ny); + // Z3 = (Z1 + E)^2 - ZZ - EE + var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee); + + return this.curve.jpoint(nx, ny, nz); +}; + +JPoint.prototype.mul = function mul(k, kbase) { + k = new bn(k, kbase); + + return this.curve._wnafMul(this, k); +}; + +JPoint.prototype.eq = function eq(p) { + if (p.type === 'affine') + return this.eq(p.toJ()); + + if (this === p) + return true; + + // x1 * z2^2 == x2 * z1^2 + var z2 = this.z.redSqr(); + var pz2 = p.z.redSqr(); + if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) + return false; + + // y1 * z2^3 == y2 * z1^3 + var z3 = z2.redMul(this.z); + var pz3 = pz2.redMul(p.z); + return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0; +}; + +JPoint.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; + +JPoint.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.z.cmpn(0) === 0; +}; + +},{"../../elliptic":62,"../curve":65,"bn.js":60,"inherits":180}],68:[function(require,module,exports){ +'use strict'; + +var curves = exports; + +var hash = require('hash.js'); +var elliptic = require('../elliptic'); + +var assert = elliptic.utils.assert; + +function PresetCurve(options) { + if (options.type === 'short') + this.curve = new elliptic.curve.short(options); + else if (options.type === 'edwards') + this.curve = new elliptic.curve.edwards(options); + else + this.curve = new elliptic.curve.mont(options); + this.g = this.curve.g; + this.n = this.curve.n; + this.hash = options.hash; + + assert(this.g.validate(), 'Invalid curve'); + assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O'); +} +curves.PresetCurve = PresetCurve; + +function defineCurve(name, options) { + Object.defineProperty(curves, name, { + configurable: true, + enumerable: true, + get: function() { + var curve = new PresetCurve(options); + Object.defineProperty(curves, name, { + configurable: true, + enumerable: true, + value: curve + }); + return curve; + } + }); +} + +defineCurve('p192', { + type: 'short', + prime: 'p192', + p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff', + a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc', + b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1', + n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831', + hash: hash.sha256, + gRed: false, + g: [ + '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012', + '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811' + ] +}); + +defineCurve('p224', { + type: 'short', + prime: 'p224', + p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001', + a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe', + b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4', + n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d', + hash: hash.sha256, + gRed: false, + g: [ + 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21', + 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34' + ] +}); + +defineCurve('p256', { + type: 'short', + prime: null, + p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff', + a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc', + b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b', + n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551', + hash: hash.sha256, + gRed: false, + g: [ + '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296', + '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5' + ] +}); + +defineCurve('curve25519', { + type: 'mont', + prime: 'p25519', + p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', + a: '76d06', + b: '0', + n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', + hash: hash.sha256, + gRed: false, + g: [ + '9' + ] +}); + +defineCurve('ed25519', { + type: 'edwards', + prime: 'p25519', + p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', + a: '-1', + c: '1', + // -121665 * (121666^(-1)) (mod P) + d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3', + n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', + hash: hash.sha256, + gRed: false, + g: [ + '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a', + + // 4/5 + '6666666666666666666666666666666666666666666666666666666666666658' + ] +}); + +var pre; +try { + pre = require('./precomputed/secp256k1'); +} catch (e) { + pre = undefined; +} + +defineCurve('secp256k1', { + type: 'short', + prime: 'k256', + p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', + a: '0', + b: '7', + n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141', + h: '1', + hash: hash.sha256, + + // Precomputed endomorphism + beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', + lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', + basis: [ + { + a: '3086d221a7d46bcde86c90e49284eb15', + b: '-e4437ed6010e88286f547fa90abfe4c3' + }, + { + a: '114ca50f7a8e2f3f657c1108d9d44cfd8', + b: '3086d221a7d46bcde86c90e49284eb15' + } + ], + + gRed: false, + g: [ + '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', + '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', + pre + ] +}); + +},{"../elliptic":62,"./precomputed/secp256k1":73,"hash.js":76}],69:[function(require,module,exports){ +'use strict'; + +var bn = require('bn.js'); +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; + +var KeyPair = require('./key'); +var Signature = require('./signature'); + +function EC(options) { + if (!(this instanceof EC)) + return new EC(options); + + // Shortcut `elliptic.ec(curve-name)` + if (typeof options === 'string') { + assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options); + + options = elliptic.curves[options]; + } + + // Shortcut for `elliptic.ec(elliptic.curves.curveName)` + if (options instanceof elliptic.curves.PresetCurve) + options = { curve: options }; + + this.curve = options.curve.curve; + this.n = this.curve.n; + this.nh = this.n.shrn(1); + this.g = this.curve.g; + + // Point on curve + this.g = options.curve.g; + this.g.precompute(options.curve.n.bitLength() + 1); + + // Hash for function for DRBG + this.hash = options.hash || options.curve.hash; +} +module.exports = EC; + +EC.prototype.keyPair = function keyPair(options) { + return new KeyPair(this, options); +}; + +EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) { + return KeyPair.fromPrivate(this, priv, enc); +}; + +EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) { + return KeyPair.fromPublic(this, pub, enc); +}; + +EC.prototype.genKeyPair = function genKeyPair(options) { + if (!options) + options = {}; + + // Instantiate Hmac_DRBG + var drbg = new elliptic.hmacDRBG({ + hash: this.hash, + pers: options.pers, + entropy: options.entropy || elliptic.rand(this.hash.hmacStrength), + nonce: this.n.toArray() + }); + + var bytes = this.n.byteLength(); + var ns2 = this.n.sub(new bn(2)); + do { + var priv = new bn(drbg.generate(bytes)); + if (priv.cmp(ns2) > 0) + continue; + + priv.iaddn(1); + return this.keyFromPrivate(priv); + } while (true); +}; + +EC.prototype._truncateToN = function truncateToN(msg, truncOnly) { + var delta = msg.byteLength() * 8 - this.n.bitLength(); + if (delta > 0) + msg = msg.shrn(delta); + if (!truncOnly && msg.cmp(this.n) >= 0) + return msg.sub(this.n); + else + return msg; +}; + +EC.prototype.sign = function sign(msg, key, enc, options) { + if (typeof enc === 'object') { + options = enc; + enc = null; + } + if (!options) + options = {}; + + key = this.keyFromPrivate(key, enc); + msg = this._truncateToN(new bn(msg, 16)); + + // Zero-extend key to provide enough entropy + var bytes = this.n.byteLength(); + var bkey = key.getPrivate().toArray(); + for (var i = bkey.length; i < 21; i++) + bkey.unshift(0); + + // Zero-extend nonce to have the same byte size as N + var nonce = msg.toArray(); + for (var i = nonce.length; i < bytes; i++) + nonce.unshift(0); + + // Instantiate Hmac_DRBG + var drbg = new elliptic.hmacDRBG({ + hash: this.hash, + entropy: bkey, + nonce: nonce + }); + + // Number of bytes to generate + var ns1 = this.n.sub(new bn(1)); + do { + var k = new bn(drbg.generate(this.n.byteLength())); + k = this._truncateToN(k, true); + if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) + continue; + + var kp = this.g.mul(k); + if (kp.isInfinity()) + continue; + + var kpX = kp.getX(); + var r = kpX.mod(this.n); + if (r.cmpn(0) === 0) + continue; + + var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg)).mod(this.n); + if (s.cmpn(0) === 0) + continue; + + // Use complement of `s`, if it is > `n / 2` + if (options.canonical && s.cmp(this.nh) > 0) + s = this.n.sub(s); + + var recoveryParam = (kp.getY().isOdd() ? 1 : 0) | + (kpX.cmp(r) !== 0 ? 2 : 0); + + return new Signature({ r: r, s: s, recoveryParam: recoveryParam }); + } while (true); +}; + +EC.prototype.verify = function verify(msg, signature, key, enc) { + msg = this._truncateToN(new bn(msg, 16)); + key = this.keyFromPublic(key, enc); + signature = new Signature(signature, 'hex'); + + // Perform primitive values validation + var r = signature.r; + var s = signature.s; + if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0) + return false; + if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0) + return false; + + // Validate signature + var sinv = s.invm(this.n); + var u1 = sinv.mul(msg).mod(this.n); + var u2 = sinv.mul(r).mod(this.n); + + var p = this.g.mulAdd(u1, key.getPublic(), u2); + if (p.isInfinity()) + return false; + + return p.getX().mod(this.n).cmp(r) === 0; +}; + +EC.prototype.recoverPubKey = function(msg, signature, j, enc) { + assert((3 & j) === j, 'The recovery param is more than two bits'); + signature = new Signature(signature, enc); + + var n = this.n; + var e = new bn(msg); + var r = signature.r; + var s = signature.s; + + // A set LSB signifies that the y-coordinate is odd + var isYOdd = j & 1; + var isSecondKey = j >> 1; + if (r.cmp(this.curve.p.mod(this.curve.n)) >= 0 && isSecondKey) + throw new Error('Unable to find sencond key candinate'); + + // 1.1. Let x = r + jn. + r = this.curve.pointFromX(isYOdd, r); + var eNeg = e.neg().mod(n); + + // 1.6.1 Compute Q = r^-1 (sR - eG) + // Q = r^-1 (sR + -eG) + var rInv = signature.r.invm(n); + return r.mul(s).add(this.g.mul(eNeg)).mul(rInv); +}; + +EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) { + signature = new Signature(signature, enc); + if (signature.recoveryParam !== null) + return signature.recoveryParam; + + for (var i = 0; i < 4; i++) { + var Qprime = this.recoverPubKey(e, signature, i); + + if (Qprime.eq(Q)) + return i; + } + throw new Error('Unable to find valid recovery factor'); +}; + +},{"../../elliptic":62,"./key":70,"./signature":71,"bn.js":60}],70:[function(require,module,exports){ +'use strict'; + +var bn = require('bn.js'); + +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; + +function KeyPair(ec, options) { + this.ec = ec; + this.priv = null; + this.pub = null; + + // KeyPair(ec, { priv: ..., pub: ... }) + if (options.priv) + this._importPrivate(options.priv, options.privEnc); + if (options.pub) + this._importPublic(options.pub, options.pubEnc); +} +module.exports = KeyPair; + +KeyPair.fromPublic = function fromPublic(ec, pub, enc) { + if (pub instanceof KeyPair) + return pub; + + return new KeyPair(ec, { + pub: pub, + pubEnc: enc + }); +}; + +KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) { + if (priv instanceof KeyPair) + return priv; + + return new KeyPair(ec, { + priv: priv, + privEnc: enc + }); +}; + +KeyPair.prototype.validate = function validate() { + var pub = this.getPublic(); + + if (pub.isInfinity()) + return { result: false, reason: 'Invalid public key' }; + if (!pub.validate()) + return { result: false, reason: 'Public key is not a point' }; + if (!pub.mul(this.ec.curve.n).isInfinity()) + return { result: false, reason: 'Public key * N != O' }; + + return { result: true, reason: null }; +}; + +KeyPair.prototype.getPublic = function getPublic(compact, enc) { + if (!this.pub) + this.pub = this.ec.g.mul(this.priv); + + // compact is optional argument + if (typeof compact === 'string') { + enc = compact; + compact = null; + } + + if (!enc) + return this.pub; + + var len = this.ec.curve.p.byteLength(); + var x = this.pub.getX().toArray(); + + for (var i = x.length; i < len; i++) + x.unshift(0); + + var res; + if (this.ec.curve.type !== 'mont') { + if (compact) { + res = [ this.pub.getY().isEven() ? 0x02 : 0x03 ].concat(x); + } else { + var y = this.pub.getY().toArray(); + for (var i = y.length; i < len; i++) + y.unshift(0); + var res = [ 0x04 ].concat(x, y); + } + } else { + res = x; + } + + return utils.encode(res, enc); +}; + +KeyPair.prototype.getPrivate = function getPrivate(enc) { + if (enc === 'hex') + return this.priv.toString(16, 2); + else + return this.priv; +}; + +KeyPair.prototype._importPrivate = function _importPrivate(key, enc) { + this.priv = new bn(key, enc || 16); + + // Ensure that the priv won't be bigger than n, otherwise we may fail + // in fixed multiplication method + this.priv = this.priv.mod(this.ec.curve.n); +}; + +KeyPair.prototype._importPublic = function _importPublic(key, enc) { + if (key.x || key.y) { + this.pub = this.ec.curve.point(key.x, key.y); + return; + } + + key = utils.toArray(key, enc); + if (this.ec.curve.type !== 'mont') + return this._importPublicShort(key); + else + return this._importPublicMont(key); +}; + +KeyPair.prototype._importPublicShort = function _importPublicShort(key) { + var len = this.ec.curve.p.byteLength(); + if (key[0] === 0x04 && key.length - 1 === 2 * len) { + this.pub = this.ec.curve.point( + key.slice(1, 1 + len), + key.slice(1 + len, 1 + 2 * len)); + } else if ((key[0] === 0x02 || key[0] === 0x03) && key.length - 1 === len) { + this.pub = this.ec.curve.pointFromX(key[0] === 0x03, key.slice(1, 1 + len)); + } +}; + +KeyPair.prototype._importPublicMont = function _importPublicMont(key) { + this.pub = this.ec.curve.point(key, 1); +}; + +// ECDH +KeyPair.prototype.derive = function derive(pub) { + return pub.mul(this.priv).getX(); +}; + +// ECDSA +KeyPair.prototype.sign = function sign(msg) { + return this.ec.sign(msg, this); +}; + +KeyPair.prototype.verify = function verify(msg, signature) { + return this.ec.verify(msg, signature, this); +}; + +KeyPair.prototype.inspect = function inspect() { + return ''; +}; + +},{"../../elliptic":62,"bn.js":60}],71:[function(require,module,exports){ +'use strict'; + +var bn = require('bn.js'); + +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; + +function Signature(options, enc) { + if (options instanceof Signature) + return options; + + if (this._importDER(options, enc)) + return; + + assert(options.r && options.s, 'Signature without r or s'); + this.r = new bn(options.r, 16); + this.s = new bn(options.s, 16); + if (options.recoveryParam !== null) + this.recoveryParam = options.recoveryParam; + else + this.recoveryParam = null; +} +module.exports = Signature; + +Signature.prototype._importDER = function _importDER(data, enc) { + data = utils.toArray(data, enc); + if (data.length < 6 || data[0] !== 0x30 || data[2] !== 0x02) + return false; + var total = data[1]; + if (1 + total > data.length) + return false; + var rlen = data[3]; + // Short length notation + if (rlen >= 0x80) + return false; + if (4 + rlen + 2 >= data.length) + return false; + if (data[4 + rlen] !== 0x02) + return false; + var slen = data[5 + rlen]; + // Short length notation + if (slen >= 0x80) + return false; + if (4 + rlen + 2 + slen > data.length) + return false; + + this.r = new bn(data.slice(4, 4 + rlen)); + this.s = new bn(data.slice(4 + rlen + 2, 4 + rlen + 2 + slen)); + this.recoveryParam = null; + + return true; +}; + +Signature.prototype.toDER = function toDER(enc) { + var r = this.r.toArray(); + var s = this.s.toArray(); + + // Pad values + if (r[0] & 0x80) + r = [ 0 ].concat(r); + // Pad values + if (s[0] & 0x80) + s = [ 0 ].concat(s); + + var total = r.length + s.length + 4; + var res = [ 0x30, total, 0x02, r.length ]; + res = res.concat(r, [ 0x02, s.length ], s); + return utils.encode(res, enc); +}; + +},{"../../elliptic":62,"bn.js":60}],72:[function(require,module,exports){ +'use strict'; + +var hash = require('hash.js'); +var elliptic = require('../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; + +function HmacDRBG(options) { + if (!(this instanceof HmacDRBG)) + return new HmacDRBG(options); + this.hash = options.hash; + this.predResist = !!options.predResist; + + this.outLen = this.hash.outSize; + this.minEntropy = options.minEntropy || this.hash.hmacStrength; + + this.reseed = null; + this.reseedInterval = null; + this.K = null; + this.V = null; + + var entropy = utils.toArray(options.entropy, options.entropyEnc); + var nonce = utils.toArray(options.nonce, options.nonceEnc); + var pers = utils.toArray(options.pers, options.persEnc); + assert(entropy.length >= (this.minEntropy / 8), + 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); + this._init(entropy, nonce, pers); +} +module.exports = HmacDRBG; + +HmacDRBG.prototype._init = function init(entropy, nonce, pers) { + var seed = entropy.concat(nonce).concat(pers); + + this.K = new Array(this.outLen / 8); + this.V = new Array(this.outLen / 8); + for (var i = 0; i < this.V.length; i++) { + this.K[i] = 0x00; + this.V[i] = 0x01; + } + + this._update(seed); + this.reseed = 1; + this.reseedInterval = 0x1000000000000; // 2^48 +}; + +HmacDRBG.prototype._hmac = function hmac() { + return new hash.hmac(this.hash, this.K); +}; + +HmacDRBG.prototype._update = function update(seed) { + var kmac = this._hmac() + .update(this.V) + .update([ 0x00 ]); + if (seed) + kmac = kmac.update(seed); + this.K = kmac.digest(); + this.V = this._hmac().update(this.V).digest(); + if (!seed) + return; + + this.K = this._hmac() + .update(this.V) + .update([ 0x01 ]) + .update(seed) + .digest(); + this.V = this._hmac().update(this.V).digest(); +}; + +HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) { + // Optional entropy enc + if (typeof entropyEnc !== 'string') { + addEnc = add; + add = entropyEnc; + entropyEnc = null; + } + + entropy = utils.toBuffer(entropy, entropyEnc); + add = utils.toBuffer(add, addEnc); + + assert(entropy.length >= (this.minEntropy / 8), + 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); + + this._update(entropy.concat(add || [])); + this.reseed = 1; +}; + +HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) { + if (this.reseed > this.reseedInterval) + throw new Error('Reseed is required'); + + // Optional encoding + if (typeof enc !== 'string') { + addEnc = add; + add = enc; + enc = null; + } + + // Optional additional data + if (add) { + add = utils.toArray(add, addEnc); + this._update(add); + } + + var temp = []; + while (temp.length < len) { + this.V = this._hmac().update(this.V).digest(); + temp = temp.concat(this.V); + } + + var res = temp.slice(0, len); + this._update(add); + this.reseed++; + return utils.encode(res, enc); +}; + +},{"../elliptic":62,"hash.js":76}],73:[function(require,module,exports){ +module.exports = { + doubles: { + step: 4, + points: [ + [ + 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a', + 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821' + ], + [ + '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508', + '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf' + ], + [ + '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739', + 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695' + ], + [ + '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640', + '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9' + ], + [ + '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c', + '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36' + ], + [ + '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda', + '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f' + ], + [ + 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa', + '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999' + ], + [ + '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0', + 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09' + ], + [ + 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d', + '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d' + ], + [ + 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d', + 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088' + ], + [ + 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1', + '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d' + ], + [ + '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0', + '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8' + ], + [ + '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047', + '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a' + ], + [ + '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862', + '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453' + ], + [ + '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7', + '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160' + ], + [ + '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd', + '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0' + ], + [ + '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83', + '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6' + ], + [ + '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a', + '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589' + ], + [ + '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8', + 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17' + ], + [ + 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d', + '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda' + ], + [ + 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725', + '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd' + ], + [ + '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754', + '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2' + ], + [ + '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c', + '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6' + ], + [ + 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6', + '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f' + ], + [ + '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39', + 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01' + ], + [ + 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891', + '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3' + ], + [ + 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b', + 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f' + ], + [ + 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03', + '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7' + ], + [ + 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d', + 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78' + ], + [ + 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070', + '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1' + ], + [ + '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4', + 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150' + ], + [ + '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da', + '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82' + ], + [ + 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11', + '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc' + ], + [ + '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e', + 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b' + ], + [ + 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41', + '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51' + ], + [ + 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef', + '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45' + ], + [ + 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8', + 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120' + ], + [ + '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d', + '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84' + ], + [ + '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96', + '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d' + ], + [ + '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd', + 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d' + ], + [ + '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5', + '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8' + ], + [ + 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266', + '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8' + ], + [ + '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71', + '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac' + ], + [ + '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac', + 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f' + ], + [ + '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751', + '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962' + ], + [ + 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e', + '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907' + ], + [ + '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241', + 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec' + ], + [ + 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3', + 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d' + ], + [ + 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f', + '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414' + ], + [ + '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19', + 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd' + ], + [ + '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be', + 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0' + ], + [ + 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9', + '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811' + ], + [ + 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2', + '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1' + ], + [ + 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13', + '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c' + ], + [ + '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c', + 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73' + ], + [ + '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba', + '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd' + ], + [ + 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151', + 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405' + ], + [ + '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073', + 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589' + ], + [ + '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458', + '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e' + ], + [ + '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b', + '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27' + ], + [ + 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366', + 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1' + ], + [ + '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa', + '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482' + ], + [ + '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0', + '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945' + ], + [ + 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787', + '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573' + ], + [ + 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e', + 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82' + ] + ] + }, + naf: { + wnd: 7, + points: [ + [ + 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', + '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672' + ], + [ + '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4', + 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6' + ], + [ + '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc', + '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da' + ], + [ + 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe', + 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37' + ], + [ + '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb', + 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b' + ], + [ + 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8', + 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81' + ], + [ + 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e', + '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58' + ], + [ + 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34', + '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77' + ], + [ + '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c', + '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a' + ], + [ + '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5', + '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c' + ], + [ + '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f', + '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67' + ], + [ + '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714', + '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402' + ], + [ + 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729', + 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55' + ], + [ + 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db', + '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482' + ], + [ + '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4', + 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82' + ], + [ + '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5', + 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396' + ], + [ + '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479', + '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49' + ], + [ + '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d', + '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf' + ], + [ + '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f', + '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a' + ], + [ + '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb', + 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7' + ], + [ + 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9', + 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933' + ], + [ + '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963', + '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a' + ], + [ + '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74', + '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6' + ], + [ + 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530', + 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37' + ], + [ + '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b', + '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e' + ], + [ + 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247', + 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6' + ], + [ + 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1', + 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476' + ], + [ + '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120', + '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40' + ], + [ + '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435', + '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61' + ], + [ + '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18', + '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683' + ], + [ + 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8', + '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5' + ], + [ + '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb', + '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b' + ], + [ + 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f', + '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417' + ], + [ + '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143', + 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868' + ], + [ + '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba', + 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a' + ], + [ + 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45', + 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6' + ], + [ + '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a', + '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996' + ], + [ + '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e', + 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e' + ], + [ + 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8', + 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d' + ], + [ + '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c', + '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2' + ], + [ + '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519', + 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e' + ], + [ + '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab', + '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437' + ], + [ + '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca', + 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311' + ], + [ + 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf', + '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4' + ], + [ + '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610', + '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575' + ], + [ + '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4', + 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d' + ], + [ + '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c', + 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d' + ], + [ + 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940', + 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629' + ], + [ + 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980', + 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06' + ], + [ + '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3', + '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374' + ], + [ + '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf', + '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee' + ], + [ + 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63', + '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1' + ], + [ + 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448', + 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b' + ], + [ + '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf', + '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661' + ], + [ + '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5', + '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6' + ], + [ + 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6', + '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e' + ], + [ + '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5', + '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d' + ], + [ + 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99', + 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc' + ], + [ + '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51', + 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4' + ], + [ + '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5', + '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c' + ], + [ + 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5', + '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b' + ], + [ + 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997', + '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913' + ], + [ + '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881', + '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154' + ], + [ + '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5', + '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865' + ], + [ + '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66', + 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc' + ], + [ + '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726', + 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224' + ], + [ + '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede', + '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e' + ], + [ + '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94', + '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6' + ], + [ + '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31', + '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511' + ], + [ + '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51', + 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b' + ], + [ + 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252', + 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2' + ], + [ + '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5', + 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c' + ], + [ + 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b', + '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3' + ], + [ + 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4', + '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d' + ], + [ + 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f', + '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700' + ], + [ + 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889', + '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4' + ], + [ + '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246', + 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196' + ], + [ + '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984', + '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4' + ], + [ + '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a', + 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257' + ], + [ + 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030', + 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13' + ], + [ + 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197', + '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096' + ], + [ + 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593', + 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38' + ], + [ + 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef', + '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f' + ], + [ + '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38', + '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448' + ], + [ + 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a', + '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a' + ], + [ + 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111', + '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4' + ], + [ + '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502', + '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437' + ], + [ + '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea', + 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7' + ], + [ + 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26', + '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d' + ], + [ + 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986', + '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a' + ], + [ + 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e', + '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54' + ], + [ + '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4', + '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77' + ], + [ + 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda', + 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517' + ], + [ + '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859', + 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10' + ], + [ + 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f', + 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125' + ], + [ + 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c', + '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e' + ], + [ + '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942', + 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1' + ], + [ + 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a', + '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2' + ], + [ + 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80', + '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423' + ], + [ + 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d', + '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8' + ], + [ + '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1', + 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758' + ], + [ + '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63', + 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375' + ], + [ + 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352', + '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d' + ], + [ + '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193', + 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec' + ], + [ + '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00', + '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0' + ], + [ + '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58', + 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c' + ], + [ + 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7', + 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4' + ], + [ + '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8', + 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f' + ], + [ + '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e', + '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649' + ], + [ + '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d', + 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826' + ], + [ + '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b', + '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5' + ], + [ + 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f', + 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87' + ], + [ + '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6', + '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b' + ], + [ + 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297', + '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc' + ], + [ + '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a', + '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c' + ], + [ + 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c', + 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f' + ], + [ + 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52', + '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a' + ], + [ + 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb', + 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46' + ], + [ + '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065', + 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f' + ], + [ + '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917', + '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03' + ], + [ + '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9', + 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08' + ], + [ + '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3', + '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8' + ], + [ + '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57', + '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373' + ], + [ + '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66', + 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3' + ], + [ + '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8', + '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8' + ], + [ + '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721', + '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1' + ], + [ + '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180', + '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9' + ] + ] + } +}; + +},{}],74:[function(require,module,exports){ +'use strict'; + +var utils = exports; + +utils.assert = function assert(val, msg) { + if (!val) + throw new Error(msg || 'Assertion failed'); +}; + +function toArray(msg, enc) { + if (Array.isArray(msg)) + return msg.slice(); + if (!msg) + return []; + var res = []; + if (typeof msg !== 'string') { + for (var i = 0; i < msg.length; i++) + res[i] = msg[i] | 0; + return res; + } + if (!enc) { + for (var i = 0; i < msg.length; i++) { + var c = msg.charCodeAt(i); + var hi = c >> 8; + var lo = c & 0xff; + if (hi) + res.push(hi, lo); + else + res.push(lo); + } + } else if (enc === 'hex') { + msg = msg.replace(/[^a-z0-9]+/ig, ''); + if (msg.length % 2 !== 0) + msg = '0' + msg; + for (var i = 0; i < msg.length; i += 2) + res.push(parseInt(msg[i] + msg[i + 1], 16)); + } + return res; +} +utils.toArray = toArray; + +function zero2(word) { + if (word.length === 1) + return '0' + word; + else + return word; +} +utils.zero2 = zero2; + +function toHex(msg) { + var res = ''; + for (var i = 0; i < msg.length; i++) + res += zero2(msg[i].toString(16)); + return res; +} +utils.toHex = toHex; + +utils.encode = function encode(arr, enc) { + if (enc === 'hex') + return toHex(arr); + else + return arr; +}; + +// Represent num in a w-NAF form +function getNAF(num, w) { + var naf = []; + var ws = 1 << (w + 1); + var k = num.clone(); + while (k.cmpn(1) >= 0) { + var z; + if (k.isOdd()) { + var mod = k.andln(ws - 1); + if (mod > (ws >> 1) - 1) + z = (ws >> 1) - mod; + else + z = mod; + k.isubn(z); + } else { + z = 0; + } + naf.push(z); + + // Optimization, shift by word if possible + var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1; + for (var i = 1; i < shift; i++) + naf.push(0); + k.ishrn(shift); + } + + return naf; +} +utils.getNAF = getNAF; + +// Represent k1, k2 in a Joint Sparse Form +function getJSF(k1, k2) { + var jsf = [ + [], + [] + ]; + + k1 = k1.clone(); + k2 = k2.clone(); + var d1 = 0; + var d2 = 0; + while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) { + + // First phase + var m14 = (k1.andln(3) + d1) & 3; + var m24 = (k2.andln(3) + d2) & 3; + if (m14 === 3) + m14 = -1; + if (m24 === 3) + m24 = -1; + var u1; + if ((m14 & 1) === 0) { + u1 = 0; + } else { + var m8 = (k1.andln(7) + d1) & 7; + if ((m8 === 3 || m8 === 5) && m24 === 2) + u1 = -m14; + else + u1 = m14; + } + jsf[0].push(u1); + + var u2; + if ((m24 & 1) === 0) { + u2 = 0; + } else { + var m8 = (k2.andln(7) + d2) & 7; + if ((m8 === 3 || m8 === 5) && m14 === 2) + u2 = -m24; + else + u2 = m24; + } + jsf[1].push(u2); + + // Second phase + if (2 * d1 === u1 + 1) + d1 = 1 - d1; + if (2 * d2 === u2 + 1) + d2 = 1 - d2; + k1.ishrn(1); + k2.ishrn(1); + } + + return jsf; +} +utils.getJSF = getJSF; + +},{}],75:[function(require,module,exports){ +var r; + +module.exports = function rand(len) { + if (!r) + r = new Rand(null); + + return r.generate(len); +}; + +function Rand(rand) { + this.rand = rand; +} +module.exports.Rand = Rand; + +Rand.prototype.generate = function generate(len) { + return this._rand(len); +}; + +if (typeof window === 'object') { + if (window.crypto && window.crypto.getRandomValues) { + // Modern browsers + Rand.prototype._rand = function _rand(n) { + var arr = new Uint8Array(n); + window.crypto.getRandomValues(arr); + return arr; + }; + } else if (window.msCrypto && window.msCrypto.getRandomValues) { + // IE + Rand.prototype._rand = function _rand(n) { + var arr = new Uint8Array(n); + window.msCrypto.getRandomValues(arr); + return arr; + }; + } else { + // Old junk + Rand.prototype._rand = function() { + throw new Error('Not implemented yet'); + }; + } +} else { + // Node.js or Web worker + try { + var crypto = require('cry' + 'pto'); + + Rand.prototype._rand = function _rand(n) { + return crypto.randomBytes(n); + }; + } catch (e) { + // Emulate crypto API using randy + Rand.prototype._rand = function _rand(n) { + var res = new Uint8Array(n); + for (var i = 0; i < res.length; i++) + res[i] = this.rand.getByte(); + return res; + }; + } +} + +},{}],76:[function(require,module,exports){ +var hash = exports; + +hash.utils = require('./hash/utils'); +hash.common = require('./hash/common'); +hash.sha = require('./hash/sha'); +hash.ripemd = require('./hash/ripemd'); +hash.hmac = require('./hash/hmac'); + +// Proxy hash functions to the main object +hash.sha1 = hash.sha.sha1; +hash.sha256 = hash.sha.sha256; +hash.sha224 = hash.sha.sha224; +hash.sha384 = hash.sha.sha384; +hash.sha512 = hash.sha.sha512; +hash.ripemd160 = hash.ripemd.ripemd160; + +},{"./hash/common":77,"./hash/hmac":78,"./hash/ripemd":79,"./hash/sha":80,"./hash/utils":81}],77:[function(require,module,exports){ +var hash = require('../hash'); +var utils = hash.utils; +var assert = utils.assert; + +function BlockHash() { + this.pending = null; + this.pendingTotal = 0; + this.blockSize = this.constructor.blockSize; + this.outSize = this.constructor.outSize; + this.hmacStrength = this.constructor.hmacStrength; + this.padLength = this.constructor.padLength / 8; + this.endian = 'big'; + + this._delta8 = this.blockSize / 8; + this._delta32 = this.blockSize / 32; +} +exports.BlockHash = BlockHash; + +BlockHash.prototype.update = function update(msg, enc) { + // Convert message to array, pad it, and join into 32bit blocks + msg = utils.toArray(msg, enc); + if (!this.pending) + this.pending = msg; + else + this.pending = this.pending.concat(msg); + this.pendingTotal += msg.length; + + // Enough data, try updating + if (this.pending.length >= this._delta8) { + msg = this.pending; + + // Process pending data in blocks + var r = msg.length % this._delta8; + this.pending = msg.slice(msg.length - r, msg.length); + if (this.pending.length === 0) + this.pending = null; + + msg = utils.join32(msg, 0, msg.length - r, this.endian); + for (var i = 0; i < msg.length; i += this._delta32) + this._update(msg, i, i + this._delta32); + } + + return this; +}; + +BlockHash.prototype.digest = function digest(enc) { + this.update(this._pad()); + assert(this.pending === null); + + return this._digest(enc); +}; + +BlockHash.prototype._pad = function pad() { + var len = this.pendingTotal; + var bytes = this._delta8; + var k = bytes - ((len + this.padLength) % bytes); + var res = new Array(k + this.padLength); + res[0] = 0x80; + for (var i = 1; i < k; i++) + res[i] = 0; + + // Append length + len <<= 3; + if (this.endian === 'big') { + for (var t = 8; t < this.padLength; t++) + res[i++] = 0; + + res[i++] = 0; + res[i++] = 0; + res[i++] = 0; + res[i++] = 0; + res[i++] = (len >>> 24) & 0xff; + res[i++] = (len >>> 16) & 0xff; + res[i++] = (len >>> 8) & 0xff; + res[i++] = len & 0xff; + } else { + res[i++] = len & 0xff; + res[i++] = (len >>> 8) & 0xff; + res[i++] = (len >>> 16) & 0xff; + res[i++] = (len >>> 24) & 0xff; + res[i++] = 0; + res[i++] = 0; + res[i++] = 0; + res[i++] = 0; + + for (var t = 8; t < this.padLength; t++) + res[i++] = 0; + } + + return res; +}; + +},{"../hash":76}],78:[function(require,module,exports){ +var hmac = exports; + +var hash = require('../hash'); +var utils = hash.utils; +var assert = utils.assert; + +function Hmac(hash, key, enc) { + if (!(this instanceof Hmac)) + return new Hmac(hash, key, enc); + this.Hash = hash; + this.blockSize = hash.blockSize / 8; + this.outSize = hash.outSize / 8; + this.inner = null; + this.outer = null; + + this._init(utils.toArray(key, enc)); +} +module.exports = Hmac; + +Hmac.prototype._init = function init(key) { + // Shorten key, if needed + if (key.length > this.blockSize) + key = new this.Hash().update(key).digest(); + assert(key.length <= this.blockSize); + + // Add padding to key + for (var i = key.length; i < this.blockSize; i++) + key.push(0); + + for (var i = 0; i < key.length; i++) + key[i] ^= 0x36; + this.inner = new this.Hash().update(key); + + // 0x36 ^ 0x5c = 0x6a + for (var i = 0; i < key.length; i++) + key[i] ^= 0x6a; + this.outer = new this.Hash().update(key); +}; + +Hmac.prototype.update = function update(msg, enc) { + this.inner.update(msg, enc); + return this; +}; + +Hmac.prototype.digest = function digest(enc) { + this.outer.update(this.inner.digest()); + return this.outer.digest(enc); +}; + +},{"../hash":76}],79:[function(require,module,exports){ +var hash = require('../hash'); +var utils = hash.utils; + +var rotl32 = utils.rotl32; +var sum32 = utils.sum32; +var sum32_3 = utils.sum32_3; +var sum32_4 = utils.sum32_4; +var BlockHash = hash.common.BlockHash; + +function RIPEMD160() { + if (!(this instanceof RIPEMD160)) + return new RIPEMD160(); + + BlockHash.call(this); + + this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; + this.endian = 'little'; +} +utils.inherits(RIPEMD160, BlockHash); +exports.ripemd160 = RIPEMD160; + +RIPEMD160.blockSize = 512; +RIPEMD160.outSize = 160; +RIPEMD160.hmacStrength = 192; +RIPEMD160.padLength = 64; + +RIPEMD160.prototype._update = function update(msg, start) { + var A = this.h[0]; + var B = this.h[1]; + var C = this.h[2]; + var D = this.h[3]; + var E = this.h[4]; + var Ah = A; + var Bh = B; + var Ch = C; + var Dh = D; + var Eh = E; + for (var j = 0; j < 80; j++) { + var T = sum32( + rotl32( + sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)), + s[j]), + E); + A = E; + E = D; + D = rotl32(C, 10); + C = B; + B = T; + T = sum32( + rotl32( + sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)), + sh[j]), + Eh); + Ah = Eh; + Eh = Dh; + Dh = rotl32(Ch, 10); + Ch = Bh; + Bh = T; + } + T = sum32_3(this.h[1], C, Dh); + this.h[1] = sum32_3(this.h[2], D, Eh); + this.h[2] = sum32_3(this.h[3], E, Ah); + this.h[3] = sum32_3(this.h[4], A, Bh); + this.h[4] = sum32_3(this.h[0], B, Ch); + this.h[0] = T; +}; + +RIPEMD160.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h, 'little'); + else + return utils.split32(this.h, 'little'); +}; + +function f(j, x, y, z) { + if (j <= 15) + return x ^ y ^ z; + else if (j <= 31) + return (x & y) | ((~x) & z); + else if (j <= 47) + return (x | (~y)) ^ z; + else if (j <= 63) + return (x & z) | (y & (~z)); + else + return x ^ (y | (~z)); +} + +function K(j) { + if (j <= 15) + return 0x00000000; + else if (j <= 31) + return 0x5a827999; + else if (j <= 47) + return 0x6ed9eba1; + else if (j <= 63) + return 0x8f1bbcdc; + else + return 0xa953fd4e; +} + +function Kh(j) { + if (j <= 15) + return 0x50a28be6; + else if (j <= 31) + return 0x5c4dd124; + else if (j <= 47) + return 0x6d703ef3; + else if (j <= 63) + return 0x7a6d76e9; + else + return 0x00000000; +} + +var r = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 +]; + +var rh = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 +]; + +var s = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 +]; + +var sh = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 +]; + +},{"../hash":76}],80:[function(require,module,exports){ +var hash = require('../hash'); +var utils = hash.utils; +var assert = utils.assert; + +var rotr32 = utils.rotr32; +var rotl32 = utils.rotl32; +var sum32 = utils.sum32; +var sum32_4 = utils.sum32_4; +var sum32_5 = utils.sum32_5; +var rotr64_hi = utils.rotr64_hi; +var rotr64_lo = utils.rotr64_lo; +var shr64_hi = utils.shr64_hi; +var shr64_lo = utils.shr64_lo; +var sum64 = utils.sum64; +var sum64_hi = utils.sum64_hi; +var sum64_lo = utils.sum64_lo; +var sum64_4_hi = utils.sum64_4_hi; +var sum64_4_lo = utils.sum64_4_lo; +var sum64_5_hi = utils.sum64_5_hi; +var sum64_5_lo = utils.sum64_5_lo; +var BlockHash = hash.common.BlockHash; + +var sha256_K = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +]; + +var sha512_K = [ + 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, + 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, + 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, + 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, + 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, + 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, + 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, + 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, + 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, + 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, + 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, + 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, + 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, + 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, + 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, + 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, + 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, + 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, + 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, + 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, + 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, + 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, + 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, + 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, + 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, + 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, + 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, + 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, + 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, + 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, + 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, + 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, + 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, + 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, + 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, + 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, + 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, + 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, + 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, + 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 +]; + +var sha1_K = [ + 0x5A827999, 0x6ED9EBA1, + 0x8F1BBCDC, 0xCA62C1D6 +]; + +function SHA256() { + if (!(this instanceof SHA256)) + return new SHA256(); + + BlockHash.call(this); + this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; + this.k = sha256_K; + this.W = new Array(64); +} +utils.inherits(SHA256, BlockHash); +exports.sha256 = SHA256; + +SHA256.blockSize = 512; +SHA256.outSize = 256; +SHA256.hmacStrength = 192; +SHA256.padLength = 64; + +SHA256.prototype._update = function _update(msg, start) { + var W = this.W; + + for (var i = 0; i < 16; i++) + W[i] = msg[start + i]; + for (; i < W.length; i++) + W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]); + + var a = this.h[0]; + var b = this.h[1]; + var c = this.h[2]; + var d = this.h[3]; + var e = this.h[4]; + var f = this.h[5]; + var g = this.h[6]; + var h = this.h[7]; + + assert(this.k.length === W.length); + for (var i = 0; i < W.length; i++) { + var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]); + var T2 = sum32(s0_256(a), maj32(a, b, c)); + h = g; + g = f; + f = e; + e = sum32(d, T1); + d = c; + c = b; + b = a; + a = sum32(T1, T2); + } + + this.h[0] = sum32(this.h[0], a); + this.h[1] = sum32(this.h[1], b); + this.h[2] = sum32(this.h[2], c); + this.h[3] = sum32(this.h[3], d); + this.h[4] = sum32(this.h[4], e); + this.h[5] = sum32(this.h[5], f); + this.h[6] = sum32(this.h[6], g); + this.h[7] = sum32(this.h[7], h); +}; + +SHA256.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h, 'big'); + else + return utils.split32(this.h, 'big'); +}; + +function SHA224() { + if (!(this instanceof SHA224)) + return new SHA224(); + + SHA256.call(this); + this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]; +} +utils.inherits(SHA224, SHA256); +exports.sha224 = SHA224; + +SHA224.blockSize = 512; +SHA224.outSize = 224; +SHA224.hmacStrength = 192; +SHA224.padLength = 64; + +SHA224.prototype._digest = function digest(enc) { + // Just truncate output + if (enc === 'hex') + return utils.toHex32(this.h.slice(0, 7), 'big'); + else + return utils.split32(this.h.slice(0, 7), 'big'); +}; + +function SHA512() { + if (!(this instanceof SHA512)) + return new SHA512(); + + BlockHash.call(this); + this.h = [ 0x6a09e667, 0xf3bcc908, + 0xbb67ae85, 0x84caa73b, + 0x3c6ef372, 0xfe94f82b, + 0xa54ff53a, 0x5f1d36f1, + 0x510e527f, 0xade682d1, + 0x9b05688c, 0x2b3e6c1f, + 0x1f83d9ab, 0xfb41bd6b, + 0x5be0cd19, 0x137e2179 ]; + this.k = sha512_K; + this.W = new Array(160); +} +utils.inherits(SHA512, BlockHash); +exports.sha512 = SHA512; + +SHA512.blockSize = 1024; +SHA512.outSize = 512; +SHA512.hmacStrength = 192; +SHA512.padLength = 128; + +SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) { + var W = this.W; + + // 32 x 32bit words + for (var i = 0; i < 32; i++) + W[i] = msg[start + i]; + for (; i < W.length; i += 2) { + var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2 + var c0_lo = g1_512_lo(W[i - 4], W[i - 3]); + var c1_hi = W[i - 14]; // i - 7 + var c1_lo = W[i - 13]; + var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15 + var c2_lo = g0_512_lo(W[i - 30], W[i - 29]); + var c3_hi = W[i - 32]; // i - 16 + var c3_lo = W[i - 31]; + + W[i] = sum64_4_hi(c0_hi, c0_lo, + c1_hi, c1_lo, + c2_hi, c2_lo, + c3_hi, c3_lo); + W[i + 1] = sum64_4_lo(c0_hi, c0_lo, + c1_hi, c1_lo, + c2_hi, c2_lo, + c3_hi, c3_lo); + } +}; + +SHA512.prototype._update = function _update(msg, start) { + this._prepareBlock(msg, start); + + var W = this.W; + + var ah = this.h[0]; + var al = this.h[1]; + var bh = this.h[2]; + var bl = this.h[3]; + var ch = this.h[4]; + var cl = this.h[5]; + var dh = this.h[6]; + var dl = this.h[7]; + var eh = this.h[8]; + var el = this.h[9]; + var fh = this.h[10]; + var fl = this.h[11]; + var gh = this.h[12]; + var gl = this.h[13]; + var hh = this.h[14]; + var hl = this.h[15]; + + assert(this.k.length === W.length); + for (var i = 0; i < W.length; i += 2) { + var c0_hi = hh; + var c0_lo = hl; + var c1_hi = s1_512_hi(eh, el); + var c1_lo = s1_512_lo(eh, el); + var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl); + var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl); + var c3_hi = this.k[i]; + var c3_lo = this.k[i + 1]; + var c4_hi = W[i]; + var c4_lo = W[i + 1]; + + var T1_hi = sum64_5_hi(c0_hi, c0_lo, + c1_hi, c1_lo, + c2_hi, c2_lo, + c3_hi, c3_lo, + c4_hi, c4_lo); + var T1_lo = sum64_5_lo(c0_hi, c0_lo, + c1_hi, c1_lo, + c2_hi, c2_lo, + c3_hi, c3_lo, + c4_hi, c4_lo); + + var c0_hi = s0_512_hi(ah, al); + var c0_lo = s0_512_lo(ah, al); + var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl); + var c1_lo = maj64_lo(ah, al, bh, bl, ch, cl); + + var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo); + var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo); + + hh = gh; + hl = gl; + + gh = fh; + gl = fl; + + fh = eh; + fl = el; + + eh = sum64_hi(dh, dl, T1_hi, T1_lo); + el = sum64_lo(dl, dl, T1_hi, T1_lo); + + dh = ch; + dl = cl; + + ch = bh; + cl = bl; + + bh = ah; + bl = al; + + ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo); + al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo); + } + + sum64(this.h, 0, ah, al); + sum64(this.h, 2, bh, bl); + sum64(this.h, 4, ch, cl); + sum64(this.h, 6, dh, dl); + sum64(this.h, 8, eh, el); + sum64(this.h, 10, fh, fl); + sum64(this.h, 12, gh, gl); + sum64(this.h, 14, hh, hl); +}; + +SHA512.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h, 'big'); + else + return utils.split32(this.h, 'big'); +}; + +function SHA384() { + if (!(this instanceof SHA384)) + return new SHA384(); + + SHA512.call(this); + this.h = [ 0xcbbb9d5d, 0xc1059ed8, + 0x629a292a, 0x367cd507, + 0x9159015a, 0x3070dd17, + 0x152fecd8, 0xf70e5939, + 0x67332667, 0xffc00b31, + 0x8eb44a87, 0x68581511, + 0xdb0c2e0d, 0x64f98fa7, + 0x47b5481d, 0xbefa4fa4 ]; +} +utils.inherits(SHA384, SHA512); +exports.sha384 = SHA384; + +SHA384.blockSize = 1024; +SHA384.outSize = 384; +SHA384.hmacStrength = 192; +SHA384.padLength = 128; + +SHA384.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h.slice(0, 12), 'big'); + else + return utils.split32(this.h.slice(0, 12), 'big'); +}; + +function SHA1() { + if (!(this instanceof SHA1)) + return new SHA1(); + + BlockHash.call(this); + this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, + 0x10325476, 0xc3d2e1f0 ]; + this.W = new Array(80); +} + +utils.inherits(SHA1, BlockHash); +exports.sha1 = SHA1; + +SHA1.blockSize = 512; +SHA1.outSize = 160; +SHA1.hmacStrength = 80; +SHA1.padLength = 64; + +SHA1.prototype._update = function _update(msg, start) { + var W = this.W; + + for (var i = 0; i < 16; i++) + W[i] = msg[start + i]; + + for(; i < W.length; i++) + W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); + + var a = this.h[0]; + var b = this.h[1]; + var c = this.h[2]; + var d = this.h[3]; + var e = this.h[4]; + + for (var i = 0; i < W.length; i++) { + var s = ~~(i / 20); + var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]); + e = d; + d = c; + c = rotl32(b, 30); + b = a; + a = t; + } + + this.h[0] = sum32(this.h[0], a); + this.h[1] = sum32(this.h[1], b); + this.h[2] = sum32(this.h[2], c); + this.h[3] = sum32(this.h[3], d); + this.h[4] = sum32(this.h[4], e); +}; + +SHA1.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h, 'big'); + else + return utils.split32(this.h, 'big'); +}; + +function ch32(x, y, z) { + return (x & y) ^ ((~x) & z); +} + +function maj32(x, y, z) { + return (x & y) ^ (x & z) ^ (y & z); +} + +function p32(x, y, z) { + return x ^ y ^ z; +} + +function s0_256(x) { + return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); +} + +function s1_256(x) { + return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); +} + +function g0_256(x) { + return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3); +} + +function g1_256(x) { + return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10); +} + +function ft_1(s, x, y, z) { + if (s === 0) + return ch32(x, y, z); + if (s === 1 || s === 3) + return p32(x, y, z); + if (s === 2) + return maj32(x, y, z); +} + +function ch64_hi(xh, xl, yh, yl, zh, zl) { + var r = (xh & yh) ^ ((~xh) & zh); + if (r < 0) + r += 0x100000000; + return r; +} + +function ch64_lo(xh, xl, yh, yl, zh, zl) { + var r = (xl & yl) ^ ((~xl) & zl); + if (r < 0) + r += 0x100000000; + return r; +} + +function maj64_hi(xh, xl, yh, yl, zh, zl) { + var r = (xh & yh) ^ (xh & zh) ^ (yh & zh); + if (r < 0) + r += 0x100000000; + return r; +} + +function maj64_lo(xh, xl, yh, yl, zh, zl) { + var r = (xl & yl) ^ (xl & zl) ^ (yl & zl); + if (r < 0) + r += 0x100000000; + return r; +} + +function s0_512_hi(xh, xl) { + var c0_hi = rotr64_hi(xh, xl, 28); + var c1_hi = rotr64_hi(xl, xh, 2); // 34 + var c2_hi = rotr64_hi(xl, xh, 7); // 39 + + var r = c0_hi ^ c1_hi ^ c2_hi; + if (r < 0) + r += 0x100000000; + return r; +} + +function s0_512_lo(xh, xl) { + var c0_lo = rotr64_lo(xh, xl, 28); + var c1_lo = rotr64_lo(xl, xh, 2); // 34 + var c2_lo = rotr64_lo(xl, xh, 7); // 39 + + var r = c0_lo ^ c1_lo ^ c2_lo; + if (r < 0) + r += 0x100000000; + return r; +} + +function s1_512_hi(xh, xl) { + var c0_hi = rotr64_hi(xh, xl, 14); + var c1_hi = rotr64_hi(xh, xl, 18); + var c2_hi = rotr64_hi(xl, xh, 9); // 41 + + var r = c0_hi ^ c1_hi ^ c2_hi; + if (r < 0) + r += 0x100000000; + return r; +} + +function s1_512_lo(xh, xl) { + var c0_lo = rotr64_lo(xh, xl, 14); + var c1_lo = rotr64_lo(xh, xl, 18); + var c2_lo = rotr64_lo(xl, xh, 9); // 41 + + var r = c0_lo ^ c1_lo ^ c2_lo; + if (r < 0) + r += 0x100000000; + return r; +} + +function g0_512_hi(xh, xl) { + var c0_hi = rotr64_hi(xh, xl, 1); + var c1_hi = rotr64_hi(xh, xl, 8); + var c2_hi = shr64_hi(xh, xl, 7); + + var r = c0_hi ^ c1_hi ^ c2_hi; + if (r < 0) + r += 0x100000000; + return r; +} + +function g0_512_lo(xh, xl) { + var c0_lo = rotr64_lo(xh, xl, 1); + var c1_lo = rotr64_lo(xh, xl, 8); + var c2_lo = shr64_lo(xh, xl, 7); + + var r = c0_lo ^ c1_lo ^ c2_lo; + if (r < 0) + r += 0x100000000; + return r; +} + +function g1_512_hi(xh, xl) { + var c0_hi = rotr64_hi(xh, xl, 19); + var c1_hi = rotr64_hi(xl, xh, 29); // 61 + var c2_hi = shr64_hi(xh, xl, 6); + + var r = c0_hi ^ c1_hi ^ c2_hi; + if (r < 0) + r += 0x100000000; + return r; +} + +function g1_512_lo(xh, xl) { + var c0_lo = rotr64_lo(xh, xl, 19); + var c1_lo = rotr64_lo(xl, xh, 29); // 61 + var c2_lo = shr64_lo(xh, xl, 6); + + var r = c0_lo ^ c1_lo ^ c2_lo; + if (r < 0) + r += 0x100000000; + return r; +} + +},{"../hash":76}],81:[function(require,module,exports){ +var utils = exports; +var inherits = require('inherits'); + +function toArray(msg, enc) { + if (Array.isArray(msg)) + return msg.slice(); + if (!msg) + return []; + var res = []; + if (typeof msg === 'string') { + if (!enc) { + for (var i = 0; i < msg.length; i++) { + var c = msg.charCodeAt(i); + var hi = c >> 8; + var lo = c & 0xff; + if (hi) + res.push(hi, lo); + else + res.push(lo); + } + } else if (enc === 'hex') { + msg = msg.replace(/[^a-z0-9]+/ig, ''); + if (msg.length % 2 !== 0) + msg = '0' + msg; + for (var i = 0; i < msg.length; i += 2) + res.push(parseInt(msg[i] + msg[i + 1], 16)); + } + } else { + for (var i = 0; i < msg.length; i++) + res[i] = msg[i] | 0; + } + return res; +} +utils.toArray = toArray; + +function toHex(msg) { + var res = ''; + for (var i = 0; i < msg.length; i++) + res += zero2(msg[i].toString(16)); + return res; +} +utils.toHex = toHex; + +function htonl(w) { + var res = (w >>> 24) | + ((w >>> 8) & 0xff00) | + ((w << 8) & 0xff0000) | + ((w & 0xff) << 24); + return res >>> 0; +} +utils.htonl = htonl; + +function toHex32(msg, endian) { + var res = ''; + for (var i = 0; i < msg.length; i++) { + var w = msg[i]; + if (endian === 'little') + w = htonl(w); + res += zero8(w.toString(16)); + } + return res; +} +utils.toHex32 = toHex32; + +function zero2(word) { + if (word.length === 1) + return '0' + word; + else + return word; +} +utils.zero2 = zero2; + +function zero8(word) { + if (word.length === 7) + return '0' + word; + else if (word.length === 6) + return '00' + word; + else if (word.length === 5) + return '000' + word; + else if (word.length === 4) + return '0000' + word; + else if (word.length === 3) + return '00000' + word; + else if (word.length === 2) + return '000000' + word; + else if (word.length === 1) + return '0000000' + word; + else + return word; +} +utils.zero8 = zero8; + +function join32(msg, start, end, endian) { + var len = end - start; + assert(len % 4 === 0); + var res = new Array(len / 4); + for (var i = 0, k = start; i < res.length; i++, k += 4) { + var w; + if (endian === 'big') + w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3]; + else + w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k]; + res[i] = w >>> 0; + } + return res; +} +utils.join32 = join32; + +function split32(msg, endian) { + var res = new Array(msg.length * 4); + for (var i = 0, k = 0; i < msg.length; i++, k += 4) { + var m = msg[i]; + if (endian === 'big') { + res[k] = m >>> 24; + res[k + 1] = (m >>> 16) & 0xff; + res[k + 2] = (m >>> 8) & 0xff; + res[k + 3] = m & 0xff; + } else { + res[k + 3] = m >>> 24; + res[k + 2] = (m >>> 16) & 0xff; + res[k + 1] = (m >>> 8) & 0xff; + res[k] = m & 0xff; + } + } + return res; +} +utils.split32 = split32; + +function rotr32(w, b) { + return (w >>> b) | (w << (32 - b)); +} +utils.rotr32 = rotr32; + +function rotl32(w, b) { + return (w << b) | (w >>> (32 - b)); +} +utils.rotl32 = rotl32; + +function sum32(a, b) { + return (a + b) >>> 0; +} +utils.sum32 = sum32; + +function sum32_3(a, b, c) { + return (a + b + c) >>> 0; +} +utils.sum32_3 = sum32_3; + +function sum32_4(a, b, c, d) { + return (a + b + c + d) >>> 0; +} +utils.sum32_4 = sum32_4; + +function sum32_5(a, b, c, d, e) { + return (a + b + c + d + e) >>> 0; +} +utils.sum32_5 = sum32_5; + +function assert(cond, msg) { + if (!cond) + throw new Error(msg || 'Assertion failed'); +} +utils.assert = assert; + +utils.inherits = inherits; + +function sum64(buf, pos, ah, al) { + var bh = buf[pos]; + var bl = buf[pos + 1]; + + var lo = (al + bl) >>> 0; + var hi = (lo < al ? 1 : 0) + ah + bh; + buf[pos] = hi >>> 0; + buf[pos + 1] = lo; +} +exports.sum64 = sum64; + +function sum64_hi(ah, al, bh, bl) { + var lo = (al + bl) >>> 0; + var hi = (lo < al ? 1 : 0) + ah + bh; + return hi >>> 0; +}; +exports.sum64_hi = sum64_hi; + +function sum64_lo(ah, al, bh, bl) { + var lo = al + bl; + return lo >>> 0; +}; +exports.sum64_lo = sum64_lo; + +function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) { + var carry = 0; + var lo = al; + lo = (lo + bl) >>> 0; + carry += lo < al ? 1 : 0; + lo = (lo + cl) >>> 0; + carry += lo < cl ? 1 : 0; + lo = (lo + dl) >>> 0; + carry += lo < dl ? 1 : 0; + + var hi = ah + bh + ch + dh + carry; + return hi >>> 0; +}; +exports.sum64_4_hi = sum64_4_hi; + +function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) { + var lo = al + bl + cl + dl; + return lo >>> 0; +}; +exports.sum64_4_lo = sum64_4_lo; + +function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { + var carry = 0; + var lo = al; + lo = (lo + bl) >>> 0; + carry += lo < al ? 1 : 0; + lo = (lo + cl) >>> 0; + carry += lo < cl ? 1 : 0; + lo = (lo + dl) >>> 0; + carry += lo < dl ? 1 : 0; + lo = (lo + el) >>> 0; + carry += lo < el ? 1 : 0; + + var hi = ah + bh + ch + dh + eh + carry; + return hi >>> 0; +}; +exports.sum64_5_hi = sum64_5_hi; + +function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { + var lo = al + bl + cl + dl + el; + + return lo >>> 0; +}; +exports.sum64_5_lo = sum64_5_lo; + +function rotr64_hi(ah, al, num) { + var r = (al << (32 - num)) | (ah >>> num); + return r >>> 0; +}; +exports.rotr64_hi = rotr64_hi; + +function rotr64_lo(ah, al, num) { + var r = (ah << (32 - num)) | (al >>> num); + return r >>> 0; +}; +exports.rotr64_lo = rotr64_lo; + +function shr64_hi(ah, al, num) { + return ah >>> num; +}; +exports.shr64_hi = shr64_hi; + +function shr64_lo(ah, al, num) { + var r = (ah << (32 - num)) | (al >>> num); + return r >>> 0; +}; +exports.shr64_lo = shr64_lo; + +},{"inherits":180}],82:[function(require,module,exports){ +module.exports={ + "name": "elliptic", + "version": "3.1.0", + "description": "EC cryptography", + "main": "lib/elliptic.js", + "scripts": { + "test": "make lint && mocha --reporter=spec test/*-test.js" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/indutny/elliptic.git" + }, + "keywords": [ + "EC", + "Elliptic", + "curve", + "Cryptography" + ], + "author": { + "name": "Fedor Indutny", + "email": "fedor@indutny.com" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/indutny/elliptic/issues" + }, + "homepage": "https://github.com/indutny/elliptic", + "devDependencies": { + "browserify": "^3.44.2", + "jscs": "^1.11.3", + "jshint": "^2.6.0", + "mocha": "^2.1.0", + "uglify-js": "^2.4.13" + }, + "dependencies": { + "bn.js": "^2.0.3", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" + }, + "gitHead": "d86cd2a8178f7e7cecbd6dd92eea084e2ab44c13", + "_id": "elliptic@3.1.0", + "_shasum": "c21682ef762769b56a74201609105da11d5f60cc", + "_from": "elliptic@>=3.0.0 <4.0.0", + "_npmVersion": "2.11.0", + "_nodeVersion": "2.2.1", + "_npmUser": { + "name": "indutny", + "email": "fedor@indutny.com" + }, + "maintainers": [ + { + "name": "indutny", + "email": "fedor@indutny.com" + } + ], + "dist": { + "shasum": "c21682ef762769b56a74201609105da11d5f60cc", + "tarball": "http://registry.npmjs.org/elliptic/-/elliptic-3.1.0.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-3.1.0.tgz", + "readme": "ERROR: No README data found!" +} + +},{}],83:[function(require,module,exports){ +(function (Buffer){ +var createHash = require('create-hash'); +module.exports = function evp(password, salt, keyLen) { + keyLen = keyLen/8; + var ki = 0; + var ii = 0; + var key = new Buffer(keyLen); + var addmd = 0; + var md, md_buf; + var i; + while (true) { + md = createHash('md5'); + if(addmd++ > 0) { + md.update(md_buf); + } + md.update(password); + md.update(salt); + md_buf = md.digest(); + i = 0; + if(keyLen > 0) { + while(true) { + if(keyLen === 0) { + break; + } + if(i === md_buf.length) { + break; + } + key[ki++] = md_buf[i++]; + keyLen--; + } + } + if(keyLen === 0) { + break; + } + } + for(i=0;i> 6]; + var primitive = (tag & 0x20) === 0; + + // Multi-octet tag - load + if ((tag & 0x1f) === 0x1f) { + var oct = tag; + tag = 0; + while ((oct & 0x80) === 0x80) { + oct = buf.readUInt8(fail); + if (buf.isError(oct)) + return oct; + + tag <<= 7; + tag |= oct & 0x7f; + } + } else { + tag &= 0x1f; + } + var tagStr = der.tag[tag]; + + return { + cls: cls, + primitive: primitive, + tag: tag, + tagStr: tagStr + }; +} + +function derDecodeLen(buf, primitive, fail) { + var len = buf.readUInt8(fail); + if (buf.isError(len)) + return len; + + // Indefinite form + if (!primitive && len === 0x80) + return null; + + // Definite form + if ((len & 0x80) === 0) { + // Short form + return len; + } + + // Long form + var num = len & 0x7f; + if (num >= 4) + return buf.error('length octect is too long'); + + len = 0; + for (var i = 0; i < num; i++) { + len <<= 8; + var j = buf.readUInt8(fail); + if (buf.isError(j)) + return j; + len |= j; + } + + return len; +} + +},{"../../asn1":88,"inherits":180}],97:[function(require,module,exports){ +var decoders = exports; + +decoders.der = require('./der'); +decoders.pem = require('./pem'); + +},{"./der":96,"./pem":98}],98:[function(require,module,exports){ +var inherits = require('inherits'); +var Buffer = require('buffer').Buffer; + +var asn1 = require('../../asn1'); +var DERDecoder = require('./der'); + +function PEMDecoder(entity) { + DERDecoder.call(this, entity); + this.enc = 'pem'; +}; +inherits(PEMDecoder, DERDecoder); +module.exports = PEMDecoder; + +PEMDecoder.prototype.decode = function decode(data, options) { + var lines = data.toString().split(/[\r\n]+/g); + + var label = options.label.toUpperCase(); + + var re = /^-----(BEGIN|END) ([^-]+)-----$/; + var start = -1; + var end = -1; + for (var i = 0; i < lines.length; i++) { + var match = lines[i].match(re); + if (match === null) + continue; + + if (match[2] !== label) + continue; + + if (start === -1) { + if (match[1] !== 'BEGIN') + break; + start = i; + } else { + if (match[1] !== 'END') + break; + end = i; + break; + } + } + if (start === -1 || end === -1) + throw new Error('PEM section not found for: ' + label); + + var base64 = lines.slice(start + 1, end).join(''); + // Remove excessive symbols + base64.replace(/[^a-z0-9\+\/=]+/gi, ''); + + var input = new Buffer(base64, 'base64'); + return DERDecoder.prototype.decode.call(this, input, options); +}; + +},{"../../asn1":88,"./der":96,"buffer":34,"inherits":180}],99:[function(require,module,exports){ +var inherits = require('inherits'); +var Buffer = require('buffer').Buffer; + +var asn1 = require('../../asn1'); +var base = asn1.base; +var bignum = asn1.bignum; + +// Import DER constants +var der = asn1.constants.der; + +function DEREncoder(entity) { + this.enc = 'der'; + this.name = entity.name; + this.entity = entity; + + // Construct base tree + this.tree = new DERNode(); + this.tree._init(entity.body); +}; +module.exports = DEREncoder; + +DEREncoder.prototype.encode = function encode(data, reporter) { + return this.tree._encode(data, reporter).join(); +}; + +// Tree methods + +function DERNode(parent) { + base.Node.call(this, 'der', parent); +} +inherits(DERNode, base.Node); + +DERNode.prototype._encodeComposite = function encodeComposite(tag, + primitive, + cls, + content) { + var encodedTag = encodeTag(tag, primitive, cls, this.reporter); + + // Short form + if (content.length < 0x80) { + var header = new Buffer(2); + header[0] = encodedTag; + header[1] = content.length; + return this._createEncoderBuffer([ header, content ]); + } + + // Long form + // Count octets required to store length + var lenOctets = 1; + for (var i = content.length; i >= 0x100; i >>= 8) + lenOctets++; + + var header = new Buffer(1 + 1 + lenOctets); + header[0] = encodedTag; + header[1] = 0x80 | lenOctets; + + for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8) + header[i] = j & 0xff; + + return this._createEncoderBuffer([ header, content ]); +}; + +DERNode.prototype._encodeStr = function encodeStr(str, tag) { + if (tag === 'octstr') + return this._createEncoderBuffer(str); + else if (tag === 'bitstr') + return this._createEncoderBuffer([ str.unused | 0, str.data ]); + else if (tag === 'ia5str') + return this._createEncoderBuffer(str); + return this.reporter.error('Encoding of string type: ' + tag + + ' unsupported'); +}; + +DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) { + if (typeof id === 'string') { + if (!values) + return this.reporter.error('string objid given, but no values map found'); + if (!values.hasOwnProperty(id)) + return this.reporter.error('objid not found in values map'); + id = values[id].split(/\s+/g); + for (var i = 0; i < id.length; i++) + id[i] |= 0; + } else if (Array.isArray(id)) { + id = id.slice(); + } + + if (!Array.isArray(id)) { + return this.reporter.error('objid() should be either array or string, ' + + 'got: ' + JSON.stringify(id)); + } + + if (!relative) { + if (id[1] >= 40) + return this.reporter.error('Second objid identifier OOB'); + id.splice(0, 2, id[0] * 40 + id[1]); + } + + // Count number of octets + var size = 0; + for (var i = 0; i < id.length; i++) { + var ident = id[i]; + for (size++; ident >= 0x80; ident >>= 7) + size++; + } + + var objid = new Buffer(size); + var offset = objid.length - 1; + for (var i = id.length - 1; i >= 0; i--) { + var ident = id[i]; + objid[offset--] = ident & 0x7f; + while ((ident >>= 7) > 0) + objid[offset--] = 0x80 | (ident & 0x7f); + } + + return this._createEncoderBuffer(objid); +}; + +function two(num) { + if (num < 10) + return '0' + num; + else + return num; +} + +DERNode.prototype._encodeTime = function encodeTime(time, tag) { + var str; + var date = new Date(time); + + if (tag === 'gentime') { + str = [ + two(date.getFullYear()), + two(date.getUTCMonth() + 1), + two(date.getUTCDate()), + two(date.getUTCHours()), + two(date.getUTCMinutes()), + two(date.getUTCSeconds()), + 'Z' + ].join(''); + } else if (tag === 'utctime') { + str = [ + two(date.getFullYear() % 100), + two(date.getUTCMonth() + 1), + two(date.getUTCDate()), + two(date.getUTCHours()), + two(date.getUTCMinutes()), + two(date.getUTCSeconds()), + 'Z' + ].join(''); + } else { + this.reporter.error('Encoding ' + tag + ' time is not supported yet'); + } + + return this._encodeStr(str, 'octstr'); +}; + +DERNode.prototype._encodeNull = function encodeNull() { + return this._createEncoderBuffer(''); +}; + +DERNode.prototype._encodeInt = function encodeInt(num, values) { + if (typeof num === 'string') { + if (!values) + return this.reporter.error('String int or enum given, but no values map'); + if (!values.hasOwnProperty(num)) { + return this.reporter.error('Values map doesn\'t contain: ' + + JSON.stringify(num)); + } + num = values[num]; + } + + // Bignum, assume big endian + if (typeof num !== 'number' && !Buffer.isBuffer(num)) { + var numArray = num.toArray(); + if (num.sign === false && numArray[0] & 0x80) { + numArray.unshift(0); + } + num = new Buffer(numArray); + } + + if (Buffer.isBuffer(num)) { + var size = num.length; + if (num.length === 0) + size++; + + var out = new Buffer(size); + num.copy(out); + if (num.length === 0) + out[0] = 0 + return this._createEncoderBuffer(out); + } + + if (num < 0x80) + return this._createEncoderBuffer(num); + + if (num < 0x100) + return this._createEncoderBuffer([0, num]); + + var size = 1; + for (var i = num; i >= 0x100; i >>= 8) + size++; + + var out = new Array(size); + for (var i = out.length - 1; i >= 0; i--) { + out[i] = num & 0xff; + num >>= 8; + } + if(out[0] & 0x80) { + out.unshift(0); + } + + return this._createEncoderBuffer(new Buffer(out)); +}; + +DERNode.prototype._encodeBool = function encodeBool(value) { + return this._createEncoderBuffer(value ? 0xff : 0); +}; + +DERNode.prototype._use = function use(entity, obj) { + if (typeof entity === 'function') + entity = entity(obj); + return entity._getEncoder('der').tree; +}; + +DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) { + var state = this._baseState; + var i; + if (state['default'] === null) + return false; + + var data = dataBuffer.join(); + if (state.defaultBuffer === undefined) + state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join(); + + if (data.length !== state.defaultBuffer.length) + return false; + + for (i=0; i < data.length; i++) + if (data[i] !== state.defaultBuffer[i]) + return false; + + return true; +}; + +// Utility methods + +function encodeTag(tag, primitive, cls, reporter) { + var res; + + if (tag === 'seqof') + tag = 'seq'; + else if (tag === 'setof') + tag = 'set'; + + if (der.tagByName.hasOwnProperty(tag)) + res = der.tagByName[tag]; + else if (typeof tag === 'number' && (tag | 0) === tag) + res = tag; + else + return reporter.error('Unknown tag: ' + tag); + + if (res >= 0x1f) + return reporter.error('Multi-octet tag encoding unsupported'); + + if (!primitive) + res |= 0x20; + + res |= (der.tagClassByName[cls || 'universal'] << 6); + + return res; +} + +},{"../../asn1":88,"buffer":34,"inherits":180}],100:[function(require,module,exports){ +var encoders = exports; + +encoders.der = require('./der'); +encoders.pem = require('./pem'); + +},{"./der":99,"./pem":101}],101:[function(require,module,exports){ +var inherits = require('inherits'); +var Buffer = require('buffer').Buffer; + +var asn1 = require('../../asn1'); +var DEREncoder = require('./der'); + +function PEMEncoder(entity) { + DEREncoder.call(this, entity); + this.enc = 'pem'; +}; +inherits(PEMEncoder, DEREncoder); +module.exports = PEMEncoder; + +PEMEncoder.prototype.encode = function encode(data, options) { + var buf = DEREncoder.prototype.encode.call(this, data); + + var p = buf.toString('base64'); + var out = [ '-----BEGIN ' + options.label + '-----' ]; + for (var i = 0; i < p.length; i += 64) + out.push(p.slice(i, i + 64)); + out.push('-----END ' + options.label + '-----'); + return out.join('\n'); +}; + +},{"../../asn1":88,"./der":99,"buffer":34,"inherits":180}],102:[function(require,module,exports){ +module.exports = assert; + +function assert(val, msg) { + if (!val) + throw new Error(msg || 'Assertion failed'); +} + +assert.equal = function assertEqual(l, r, msg) { + if (l != r) + throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r)); +}; + +},{}],103:[function(require,module,exports){ +(function (Buffer){ +// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js +var parseKeys = require('parse-asn1') +var BN = require('bn.js') +var elliptic = require('elliptic') +var crt = require('browserify-rsa') +var createHmac = require('create-hmac') +var curves = require('./curves') + +module.exports = sign +function sign (hash, key, hashType, signType) { + var priv = parseKeys(key) + if (priv.curve) { + if (signType !== 'ecdsa') { + throw new Error('wrong private key type') + } + return ecSign(hash, priv) + } else if (priv.type === 'dsa') { + return dsaSign(hash, priv, hashType) + if (signType !== 'dsa') { + throw new Error('wrong private key type') + } + } else { + if (signType !== 'rsa') { + throw new Error('wrong private key type') + } + } + var len = priv.modulus.byteLength() + var pad = [ 0, 1 ] + while (hash.length + pad.length + 1 < len) { + pad.push(0xff) + } + pad.push(0x00) + var i = -1 + while (++i < hash.length) { + pad.push(hash[i]) + } + + var out = crt(pad, priv) + return out +} +function ecSign (hash, priv) { + var curveId = curves[priv.curve.join('.')] + if (!curveId) + throw new Error('unknown curve ' + priv.curve.join('.')) + + var curve = new elliptic.ec(curveId) + + var key = curve.genKeyPair() + key._importPrivate(priv.privateKey) + var out = key.sign(hash) + return new Buffer(out.toDER()) +} +function dsaSign (hash, priv, algo) { + var x = priv.params.priv_key + var p = priv.params.p + var q = priv.params.q + var montq = BN.mont(q) + var g = priv.params.g + var r = new BN(0) + var k + var H = bits2int(hash, q).mod(q) + var s = false + var kv = getKey(x, q, hash, algo) + while (s === false) { + k = makeKey(q, kv, algo) + r = makeR(g, k, p, q) + s = k.invm(q).imul(H.add(x.mul(r))).mod(q) + if (!s.cmpn(0)) { + s = false + r = new BN(0) + } + } + return toDER(r, s) +} +function toDER (r, s) { + r = r.toArray() + s = s.toArray() + + // Pad values + if (r[0] & 0x80) + r = [ 0 ].concat(r) + // Pad values + if (s[0] & 0x80) + s = [0].concat(s) + + var total = r.length + s.length + 4 + var res = [ 0x30, total, 0x02, r.length ] + res = res.concat(r, [ 0x02, s.length ], s) + return new Buffer(res) +} +module.exports.getKey = getKey +function getKey (x, q, hash, algo) { + x = new Buffer(x.toArray()) + if (x.length < q.byteLength()) { + var zeros = new Buffer(q.byteLength() - x.length) + zeros.fill(0) + x = Buffer.concat([zeros, x]) + } + var hlen = hash.length + var hbits = bits2octets(hash, q) + var v = new Buffer(hlen) + v.fill(1) + var k = new Buffer(hlen) + k.fill(0) + k = createHmac(algo, k) + .update(v) + .update(new Buffer([0])) + .update(x) + .update(hbits) + .digest() + v = createHmac(algo, k) + .update(v) + .digest() + k = createHmac(algo, k) + .update(v) + .update(new Buffer([1])) + .update(x) + .update(hbits) + .digest() + v = createHmac(algo, k) + .update(v) + .digest() + return { + k: k, + v: v + } +} +function bits2int (obits, q) { + var bits = new BN(obits) + var shift = (obits.length << 3) - q.bitLength() + if (shift > 0) { + bits.ishrn(shift) + } + return bits +} +function bits2octets (bits, q) { + bits = bits2int(bits, q) + bits = bits.mod(q) + var out = new Buffer(bits.toArray()) + if (out.length < q.byteLength()) { + var zeros = new Buffer(q.byteLength() - out.length) + zeros.fill(0) + out = Buffer.concat([zeros, out]) + } + return out +} +module.exports.makeKey = makeKey +function makeKey (q, kv, algo) { + var t + var k + while (true) { + t = new Buffer('') + while (t.length * 8 < q.bitLength()) { + kv.v = createHmac(algo, kv.k) + .update(kv.v) + .digest() + t = Buffer.concat([t, kv.v]) + } + k = bits2int(t, q) + kv.k = createHmac(algo, kv.k) + .update(kv.v) + .update(new Buffer([0])) + .digest() + kv.v = createHmac(algo, kv.k) + .update(kv.v) + .digest() + if (k.cmp(q) === -1) { + return k + } + } +} +function makeR (g, k, p, q) { + return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q) +} + +}).call(this,require("buffer").Buffer) +},{"./curves":59,"bn.js":60,"browserify-rsa":61,"buffer":34,"create-hmac":141,"elliptic":62,"parse-asn1":87}],104:[function(require,module,exports){ +(function (Buffer){ +'use strict' +// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js +var parseKeys = require('parse-asn1') +var elliptic = require('elliptic') +var curves = require('./curves') +var BN = require('bn.js') +module.exports = verify + +function verify (sig, hash, key, signType) { + var pub = parseKeys(key) + if (pub.type === 'ec') { + if (signType !== 'ecdsa') { + throw new Error('wrong public key type') + } + return ecVerify(sig, hash, pub) + } else if (pub.type === 'dsa') { + if (signType !== 'dsa') { + throw new Error('wrong public key type') + } + return dsaVerify(sig, hash, pub) + } else { + if (signType !== 'rsa') { + throw new Error('wrong public key type') + } + } + var len = pub.modulus.byteLength() + var pad = [ 1 ] + var padNum = 0 + while (hash.length + pad.length + 2 < len) { + pad.push(0xff) + padNum++ + } + pad.push(0x00) + var i = -1 + while (++i < hash.length) { + pad.push(hash[i]) + } + pad = new Buffer(pad) + var red = BN.mont(pub.modulus) + sig = new BN(sig).toRed(red) + + sig = sig.redPow(new BN(pub.publicExponent)) + + sig = new Buffer(sig.fromRed().toArray()) + var out = 0 + if (padNum < 8) { + out = 1 + } + len = Math.min(sig.length, pad.length) + if (sig.length !== pad.length) { + out = 1 + } + + i = -1 + while (++i < len) { + out |= (sig[i] ^ pad[i]) + } + return out === 0 +} +function ecVerify (sig, hash, pub) { + var curveId = curves[pub.data.algorithm.curve.join('.')] + if (!curveId) + throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.')) + + var curve = new elliptic.ec(curveId) + + var pubkey = pub.data.subjectPrivateKey.data + return curve.verify(hash, sig, pubkey) +} +function dsaVerify (sig, hash, pub) { + var p = pub.data.p + var q = pub.data.q + var g = pub.data.g + var y = pub.data.pub_key + var unpacked = parseKeys.signature.decode(sig, 'der') + var s = unpacked.s + var r = unpacked.r + checkValue(s, q) + checkValue(r, q) + var montq = BN.mont(q) + var montp = BN.mont(p) + var w = s.invm(q) + var v = g.toRed(montp) + .redPow(new BN(hash).mul(w).mod(q)) + .fromRed() + .mul( + y.toRed(montp) + .redPow(r.mul(w).mod(q)) + .fromRed() + ).mod(p).mod(q) + return !v.cmp(r) +} +function checkValue (b, q) { + if (b.cmpn(0) <= 0) { + throw new Error('invalid sig') + } + if (b.cmp(q) >= q) { + throw new Error('invalid sig') + } +} + +}).call(this,require("buffer").Buffer) +},{"./curves":59,"bn.js":60,"buffer":34,"elliptic":62,"parse-asn1":87}],105:[function(require,module,exports){ +(function (Buffer){ +var elliptic = require('elliptic'); +var BN = require('bn.js'); + +module.exports = function createECDH(curve) { + return new ECDH(curve); +}; + +var aliases = { + secp256k1: { + name: 'secp256k1', + byteLength: 32 + }, + secp224r1: { + name: 'p224', + byteLength: 28 + }, + prime256v1: { + name: 'p256', + byteLength: 32 + }, + prime192v1: { + name: 'p192', + byteLength: 24 + }, + ed25519: { + name: 'ed25519', + byteLength: 32 + } +}; + +aliases.p224 = aliases.secp224r1; +aliases.p256 = aliases.secp256r1 = aliases.prime256v1; +aliases.p192 = aliases.secp192r1 = aliases.prime192v1; + +function ECDH(curve) { + this.curveType = aliases[curve]; + if (!this.curveType ) { + this.curveType = { + name: curve + }; + } + this.curve = new elliptic.ec(this.curveType.name); + this.keys = void 0; +} + +ECDH.prototype.generateKeys = function (enc, format) { + this.keys = this.curve.genKeyPair(); + return this.getPublicKey(enc, format); +}; + +ECDH.prototype.computeSecret = function (other, inenc, enc) { + inenc = inenc || 'utf8'; + if (!Buffer.isBuffer(other)) { + other = new Buffer(other, inenc); + } + var otherPub = this.curve.keyFromPublic(other).getPublic(); + var out = otherPub.mul(this.keys.getPrivate()).getX(); + return formatReturnValue(out, enc, this.curveType.byteLength); +}; + +ECDH.prototype.getPublicKey = function (enc, format) { + var key = this.keys.getPublic(format === 'compressed', true); + if (format === 'hybrid') { + if (key[key.length - 1] % 2) { + key[0] = 7; + } else { + key [0] = 6; + } + } + return formatReturnValue(key, enc); +}; + +ECDH.prototype.getPrivateKey = function (enc) { + return formatReturnValue(this.keys.getPrivate(), enc); +}; + +ECDH.prototype.setPublicKey = function (pub, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(pub)) { + pub = new Buffer(pub, enc); + } + this.keys._importPublic(pub); + return this; +}; + +ECDH.prototype.setPrivateKey = function (priv, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(priv)) { + priv = new Buffer(priv, enc); + } + var _priv = new BN(priv); + _priv = _priv.toString(16); + this.keys._importPrivate(_priv); + return this; +}; + +function formatReturnValue(bn, enc, len) { + if (!Array.isArray(bn)) { + bn = bn.toArray(); + } + var buf = new Buffer(bn); + if (len && buf.length < len) { + var zeros = new Buffer(len - buf.length); + zeros.fill(0); + buf = Buffer.concat([zeros, buf]); + } + if (!enc) { + return buf; + } else { + return buf.toString(enc); + } +} + +}).call(this,require("buffer").Buffer) +},{"bn.js":107,"buffer":34,"elliptic":108}],106:[function(require,module,exports){ +var createECDH = require('crypto').createECDH; + +module.exports = createECDH || require('./browser'); +},{"./browser":105,"crypto":38}],107:[function(require,module,exports){ +arguments[4][60][0].apply(exports,arguments) +},{"dup":60}],108:[function(require,module,exports){ +arguments[4][62][0].apply(exports,arguments) +},{"../package.json":128,"./elliptic/curve":111,"./elliptic/curves":114,"./elliptic/ec":115,"./elliptic/hmac-drbg":118,"./elliptic/utils":120,"brorand":121,"dup":62}],109:[function(require,module,exports){ +arguments[4][63][0].apply(exports,arguments) +},{"../../elliptic":108,"bn.js":107,"dup":63}],110:[function(require,module,exports){ +arguments[4][64][0].apply(exports,arguments) +},{"../../elliptic":108,"../curve":111,"bn.js":107,"dup":64,"inherits":180}],111:[function(require,module,exports){ +arguments[4][65][0].apply(exports,arguments) +},{"./base":109,"./edwards":110,"./mont":112,"./short":113,"dup":65}],112:[function(require,module,exports){ +arguments[4][66][0].apply(exports,arguments) +},{"../curve":111,"bn.js":107,"dup":66,"inherits":180}],113:[function(require,module,exports){ +arguments[4][67][0].apply(exports,arguments) +},{"../../elliptic":108,"../curve":111,"bn.js":107,"dup":67,"inherits":180}],114:[function(require,module,exports){ +arguments[4][68][0].apply(exports,arguments) +},{"../elliptic":108,"./precomputed/secp256k1":119,"dup":68,"hash.js":122}],115:[function(require,module,exports){ +arguments[4][69][0].apply(exports,arguments) +},{"../../elliptic":108,"./key":116,"./signature":117,"bn.js":107,"dup":69}],116:[function(require,module,exports){ +arguments[4][70][0].apply(exports,arguments) +},{"../../elliptic":108,"bn.js":107,"dup":70}],117:[function(require,module,exports){ +arguments[4][71][0].apply(exports,arguments) +},{"../../elliptic":108,"bn.js":107,"dup":71}],118:[function(require,module,exports){ +arguments[4][72][0].apply(exports,arguments) +},{"../elliptic":108,"dup":72,"hash.js":122}],119:[function(require,module,exports){ +arguments[4][73][0].apply(exports,arguments) +},{"dup":73}],120:[function(require,module,exports){ +arguments[4][74][0].apply(exports,arguments) +},{"dup":74}],121:[function(require,module,exports){ +arguments[4][75][0].apply(exports,arguments) +},{"dup":75}],122:[function(require,module,exports){ +arguments[4][76][0].apply(exports,arguments) +},{"./hash/common":123,"./hash/hmac":124,"./hash/ripemd":125,"./hash/sha":126,"./hash/utils":127,"dup":76}],123:[function(require,module,exports){ +arguments[4][77][0].apply(exports,arguments) +},{"../hash":122,"dup":77}],124:[function(require,module,exports){ +arguments[4][78][0].apply(exports,arguments) +},{"../hash":122,"dup":78}],125:[function(require,module,exports){ +arguments[4][79][0].apply(exports,arguments) +},{"../hash":122,"dup":79}],126:[function(require,module,exports){ +arguments[4][80][0].apply(exports,arguments) +},{"../hash":122,"dup":80}],127:[function(require,module,exports){ +arguments[4][81][0].apply(exports,arguments) +},{"dup":81,"inherits":180}],128:[function(require,module,exports){ +module.exports={ + "name": "elliptic", + "version": "3.1.0", + "description": "EC cryptography", + "main": "lib/elliptic.js", + "scripts": { + "test": "make lint && mocha --reporter=spec test/*-test.js" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/indutny/elliptic.git" + }, + "keywords": [ + "EC", + "Elliptic", + "curve", + "Cryptography" + ], + "author": { + "name": "Fedor Indutny", + "email": "fedor@indutny.com" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/indutny/elliptic/issues" + }, + "homepage": "https://github.com/indutny/elliptic", + "devDependencies": { + "browserify": "^3.44.2", + "jscs": "^1.11.3", + "jshint": "^2.6.0", + "mocha": "^2.1.0", + "uglify-js": "^2.4.13" + }, + "dependencies": { + "bn.js": "^2.0.3", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" + }, + "gitHead": "d86cd2a8178f7e7cecbd6dd92eea084e2ab44c13", + "_id": "elliptic@3.1.0", + "_shasum": "c21682ef762769b56a74201609105da11d5f60cc", + "_from": "elliptic@>=3.0.0 <4.0.0", + "_npmVersion": "2.11.0", + "_nodeVersion": "2.2.1", + "_npmUser": { + "name": "indutny", + "email": "fedor@indutny.com" + }, + "maintainers": [ + { + "name": "indutny", + "email": "fedor@indutny.com" + } + ], + "dist": { + "shasum": "c21682ef762769b56a74201609105da11d5f60cc", + "tarball": "http://registry.npmjs.org/elliptic/-/elliptic-3.1.0.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-3.1.0.tgz" +} + +},{}],129:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +var inherits = require('inherits') +var md5 = require('./md5') +var rmd160 = require('ripemd160') +var sha = require('sha.js') + +var Transform = require('stream').Transform + +function HashNoConstructor(hash) { + Transform.call(this) + + this._hash = hash + this.buffers = [] +} + +inherits(HashNoConstructor, Transform) + +HashNoConstructor.prototype._transform = function (data, _, next) { + this.buffers.push(data) + + next() +} + +HashNoConstructor.prototype._flush = function (next) { + this.push(this.digest()) + next() +} + +HashNoConstructor.prototype.update = function (data, enc) { + if (typeof data === 'string') { + data = new Buffer(data, enc) + } + + this.buffers.push(data) + return this +} + +HashNoConstructor.prototype.digest = function (enc) { + var buf = Buffer.concat(this.buffers) + var r = this._hash(buf) + this.buffers = null + + return enc ? r.toString(enc) : r +} + +function Hash(hash) { + Transform.call(this) + + this._hash = hash +} + +inherits(Hash, Transform) + +Hash.prototype._transform = function (data, enc, next) { + if (enc) data = new Buffer(data, enc) + + this._hash.update(data) + + next() +} + +Hash.prototype._flush = function (next) { + this.push(this._hash.digest()) + this._hash = null + + next() +} + +Hash.prototype.update = function (data, enc) { + if (typeof data === 'string') { + data = new Buffer(data, enc) + } + + this._hash.update(data) + return this +} + +Hash.prototype.digest = function (enc) { + var outData = this._hash.digest() + + return enc ? outData.toString(enc) : outData +} + +module.exports = function createHash (alg) { + if ('md5' === alg) return new HashNoConstructor(md5) + if ('rmd160' === alg) return new HashNoConstructor(rmd160) + + return new Hash(sha(alg)) +} + +}).call(this,require("buffer").Buffer) +},{"./md5":131,"buffer":34,"inherits":180,"ripemd160":132,"sha.js":134,"stream":199}],130:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +var intSize = 4; +var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0); +var chrsz = 8; + +function toArray(buf, bigEndian) { + if ((buf.length % intSize) !== 0) { + var len = buf.length + (intSize - (buf.length % intSize)); + buf = Buffer.concat([buf, zeroBuffer], len); + } + + var arr = []; + var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE; + for (var i = 0; i < buf.length; i += intSize) { + arr.push(fn.call(buf, i)); + } + return arr; +} + +function toBuffer(arr, size, bigEndian) { + var buf = new Buffer(size); + var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE; + for (var i = 0; i < arr.length; i++) { + fn.call(buf, arr[i], i * 4, true); + } + return buf; +} + +function hash(buf, fn, hashSize, bigEndian) { + if (!Buffer.isBuffer(buf)) buf = new Buffer(buf); + var arr = fn(toArray(buf, bigEndian), buf.length * chrsz); + return toBuffer(arr, hashSize, bigEndian); +} +exports.hash = hash; +}).call(this,require("buffer").Buffer) +},{"buffer":34}],131:[function(require,module,exports){ +'use strict'; +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +var helpers = require('./helpers'); + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ +function core_md5(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); + +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +module.exports = function md5(buf) { + return helpers.hash(buf, core_md5, 16); +}; +},{"./helpers":130}],132:[function(require,module,exports){ +(function (Buffer){ +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +/** @preserve +(c) 2012 by Cédric Mesnil. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// constants table +var zl = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 +] + +var zr = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 +] + +var sl = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 +] + +var sr = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 +] + +var hl = [0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E] +var hr = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000] + +function bytesToWords (bytes) { + var words = [] + for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { + words[b >>> 5] |= bytes[i] << (24 - b % 32) + } + return words +} + +function wordsToBytes (words) { + var bytes = [] + for (var b = 0; b < words.length * 32; b += 8) { + bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF) + } + return bytes +} + +function processBlock (H, M, offset) { + // swap endian + for (var i = 0; i < 16; i++) { + var offset_i = offset + i + var M_offset_i = M[offset_i] + + // Swap + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ) + } + + // Working variables + var al, bl, cl, dl, el + var ar, br, cr, dr, er + + ar = al = H[0] + br = bl = H[1] + cr = cl = H[2] + dr = dl = H[3] + er = el = H[4] + + // computation + var t + for (i = 0; i < 80; i += 1) { + t = (al + M[offset + zl[i]]) | 0 + if (i < 16) { + t += f1(bl, cl, dl) + hl[0] + } else if (i < 32) { + t += f2(bl, cl, dl) + hl[1] + } else if (i < 48) { + t += f3(bl, cl, dl) + hl[2] + } else if (i < 64) { + t += f4(bl, cl, dl) + hl[3] + } else {// if (i<80) { + t += f5(bl, cl, dl) + hl[4] + } + t = t | 0 + t = rotl(t, sl[i]) + t = (t + el) | 0 + al = el + el = dl + dl = rotl(cl, 10) + cl = bl + bl = t + + t = (ar + M[offset + zr[i]]) | 0 + if (i < 16) { + t += f5(br, cr, dr) + hr[0] + } else if (i < 32) { + t += f4(br, cr, dr) + hr[1] + } else if (i < 48) { + t += f3(br, cr, dr) + hr[2] + } else if (i < 64) { + t += f2(br, cr, dr) + hr[3] + } else {// if (i<80) { + t += f1(br, cr, dr) + hr[4] + } + + t = t | 0 + t = rotl(t, sr[i]) + t = (t + er) | 0 + ar = er + er = dr + dr = rotl(cr, 10) + cr = br + br = t + } + + // intermediate hash value + t = (H[1] + cl + dr) | 0 + H[1] = (H[2] + dl + er) | 0 + H[2] = (H[3] + el + ar) | 0 + H[3] = (H[4] + al + br) | 0 + H[4] = (H[0] + bl + cr) | 0 + H[0] = t +} + +function f1 (x, y, z) { + return ((x) ^ (y) ^ (z)) +} + +function f2 (x, y, z) { + return (((x) & (y)) | ((~x) & (z))) +} + +function f3 (x, y, z) { + return (((x) | (~(y))) ^ (z)) +} + +function f4 (x, y, z) { + return (((x) & (z)) | ((y) & (~(z)))) +} + +function f5 (x, y, z) { + return ((x) ^ ((y) | (~(z)))) +} + +function rotl (x, n) { + return (x << n) | (x >>> (32 - n)) +} + +function ripemd160 (message) { + var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0] + + if (typeof message === 'string') { + message = new Buffer(message, 'utf8') + } + + var m = bytesToWords(message) + + var nBitsLeft = message.length * 8 + var nBitsTotal = message.length * 8 + + // Add padding + m[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32) + m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | + (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00) + ) + + for (var i = 0; i < m.length; i += 16) { + processBlock(H, m, i) + } + + // swap endian + for (i = 0; i < 5; i++) { + // shortcut + var H_i = H[i] + + // Swap + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00) + } + + var digestbytes = wordsToBytes(H) + return new Buffer(digestbytes) +} + +module.exports = ripemd160 + +}).call(this,require("buffer").Buffer) +},{"buffer":34}],133:[function(require,module,exports){ +(function (Buffer){ +// prototype class for hash functions +function Hash (blockSize, finalSize) { + this._block = new Buffer(blockSize) + this._finalSize = finalSize + this._blockSize = blockSize + this._len = 0 + this._s = 0 +} + +Hash.prototype.update = function (data, enc) { + if (typeof data === 'string') { + enc = enc || 'utf8' + data = new Buffer(data, enc) + } + + var l = this._len += data.length + var s = this._s || 0 + var f = 0 + var buffer = this._block + + while (s < l) { + var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize)) + var ch = (t - f) + + for (var i = 0; i < ch; i++) { + buffer[(s % this._blockSize) + i] = data[i + f] + } + + s += ch + f += ch + + if ((s % this._blockSize) === 0) { + this._update(buffer) + } + } + this._s = s + + return this +} + +Hash.prototype.digest = function (enc) { + // Suppose the length of the message M, in bits, is l + var l = this._len * 8 + + // Append the bit 1 to the end of the message + this._block[this._len % this._blockSize] = 0x80 + + // and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize + this._block.fill(0, this._len % this._blockSize + 1) + + if (l % (this._blockSize * 8) >= this._finalSize * 8) { + this._update(this._block) + this._block.fill(0) + } + + // to this append the block which is equal to the number l written in binary + // TODO: handle case where l is > Math.pow(2, 29) + this._block.writeInt32BE(l, this._blockSize - 4) + + var hash = this._update(this._block) || this._hash() + + return enc ? hash.toString(enc) : hash +} + +Hash.prototype._update = function () { + throw new Error('_update must be implemented by subclass') +} + +module.exports = Hash + +}).call(this,require("buffer").Buffer) +},{"buffer":34}],134:[function(require,module,exports){ +var exports = module.exports = function SHA (algorithm) { + algorithm = algorithm.toLowerCase() + + var Algorithm = exports[algorithm] + if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)') + + return new Algorithm() +} + +exports.sha = require('./sha') +exports.sha1 = require('./sha1') +exports.sha224 = require('./sha224') +exports.sha256 = require('./sha256') +exports.sha384 = require('./sha384') +exports.sha512 = require('./sha512') + +},{"./sha":135,"./sha1":136,"./sha224":137,"./sha256":138,"./sha384":139,"./sha512":140}],135:[function(require,module,exports){ +(function (Buffer){ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined + * in FIPS PUB 180-1 + * This source code is derived from sha1.js of the same repository. + * The difference between SHA-0 and SHA-1 is just a bitwise rotate left + * operation was added. + */ + +var inherits = require('inherits') +var Hash = require('./hash') + +var W = new Array(80) + +function Sha () { + this.init() + this._w = W + + Hash.call(this, 64, 56) +} + +inherits(Sha, Hash) + +Sha.prototype.init = function () { + this._a = 0x67452301 | 0 + this._b = 0xefcdab89 | 0 + this._c = 0x98badcfe | 0 + this._d = 0x10325476 | 0 + this._e = 0xc3d2e1f0 | 0 + + return this +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol (num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)) +} + +Sha.prototype._update = function (M) { + var W = this._w + + var a = this._a + var b = this._b + var c = this._c + var d = this._d + var e = this._e + + var j = 0, k + + /* + * SHA-1 has a bitwise rotate left operation. But, SHA is not + * function calcW() { return rol(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1) } + */ + function calcW () { return W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16] } + function loop (w, f) { + W[j] = w + + var t = rol(a, 5) + f + e + w + k + + e = d + d = c + c = rol(b, 30) + b = a + a = t + j++ + } + + k = 1518500249 + while (j < 16) loop(M.readInt32BE(j * 4), (b & c) | ((~b) & d)) + while (j < 20) loop(calcW(), (b & c) | ((~b) & d)) + k = 1859775393 + while (j < 40) loop(calcW(), b ^ c ^ d) + k = -1894007588 + while (j < 60) loop(calcW(), (b & c) | (b & d) | (c & d)) + k = -899497514 + while (j < 80) loop(calcW(), b ^ c ^ d) + + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 +} + +Sha.prototype._hash = function () { + var H = new Buffer(20) + + H.writeInt32BE(this._a | 0, 0) + H.writeInt32BE(this._b | 0, 4) + H.writeInt32BE(this._c | 0, 8) + H.writeInt32BE(this._d | 0, 12) + H.writeInt32BE(this._e | 0, 16) + + return H +} + +module.exports = Sha + + +}).call(this,require("buffer").Buffer) +},{"./hash":133,"buffer":34,"inherits":180}],136:[function(require,module,exports){ +(function (Buffer){ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + +var inherits = require('inherits') +var Hash = require('./hash') + +var W = new Array(80) + +function Sha1 () { + this.init() + this._w = W + + Hash.call(this, 64, 56) +} + +inherits(Sha1, Hash) + +Sha1.prototype.init = function () { + this._a = 0x67452301 | 0 + this._b = 0xefcdab89 | 0 + this._c = 0x98badcfe | 0 + this._d = 0x10325476 | 0 + this._e = 0xc3d2e1f0 | 0 + + return this +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol (num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)) +} + +Sha1.prototype._update = function (M) { + var W = this._w + + var a = this._a + var b = this._b + var c = this._c + var d = this._d + var e = this._e + + var j = 0, k + + function calcW () { return rol(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1) } + function loop (w, f) { + W[j] = w + + var t = rol(a, 5) + f + e + w + k + + e = d + d = c + c = rol(b, 30) + b = a + a = t + j++ + } + + k = 1518500249 + while (j < 16) loop(M.readInt32BE(j * 4), (b & c) | ((~b) & d)) + while (j < 20) loop(calcW(), (b & c) | ((~b) & d)) + k = 1859775393 + while (j < 40) loop(calcW(), b ^ c ^ d) + k = -1894007588 + while (j < 60) loop(calcW(), (b & c) | (b & d) | (c & d)) + k = -899497514 + while (j < 80) loop(calcW(), b ^ c ^ d) + + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 +} + +Sha1.prototype._hash = function () { + var H = new Buffer(20) + + H.writeInt32BE(this._a | 0, 0) + H.writeInt32BE(this._b | 0, 4) + H.writeInt32BE(this._c | 0, 8) + H.writeInt32BE(this._d | 0, 12) + H.writeInt32BE(this._e | 0, 16) + + return H +} + +module.exports = Sha1 + +}).call(this,require("buffer").Buffer) +},{"./hash":133,"buffer":34,"inherits":180}],137:[function(require,module,exports){ +(function (Buffer){ +/** + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ + +var inherits = require('inherits') +var Sha256 = require('./sha256') +var Hash = require('./hash') + +var W = new Array(64) + +function Sha224 () { + this.init() + + this._w = W // new Array(64) + + Hash.call(this, 64, 56) +} + +inherits(Sha224, Sha256) + +Sha224.prototype.init = function () { + this._a = 0xc1059ed8 | 0 + this._b = 0x367cd507 | 0 + this._c = 0x3070dd17 | 0 + this._d = 0xf70e5939 | 0 + this._e = 0xffc00b31 | 0 + this._f = 0x68581511 | 0 + this._g = 0x64f98fa7 | 0 + this._h = 0xbefa4fa4 | 0 + + return this +} + +Sha224.prototype._hash = function () { + var H = new Buffer(28) + + H.writeInt32BE(this._a, 0) + H.writeInt32BE(this._b, 4) + H.writeInt32BE(this._c, 8) + H.writeInt32BE(this._d, 12) + H.writeInt32BE(this._e, 16) + H.writeInt32BE(this._f, 20) + H.writeInt32BE(this._g, 24) + + return H +} + +module.exports = Sha224 + +}).call(this,require("buffer").Buffer) +},{"./hash":133,"./sha256":138,"buffer":34,"inherits":180}],138:[function(require,module,exports){ +(function (Buffer){ +/** + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ + +var inherits = require('inherits') +var Hash = require('./hash') + +var K = [ + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 +] + +var W = new Array(64) + +function Sha256 () { + this.init() + + this._w = W // new Array(64) + + Hash.call(this, 64, 56) +} + +inherits(Sha256, Hash) + +Sha256.prototype.init = function () { + this._a = 0x6a09e667 | 0 + this._b = 0xbb67ae85 | 0 + this._c = 0x3c6ef372 | 0 + this._d = 0xa54ff53a | 0 + this._e = 0x510e527f | 0 + this._f = 0x9b05688c | 0 + this._g = 0x1f83d9ab | 0 + this._h = 0x5be0cd19 | 0 + + return this +} + +function S (X, n) { + return (X >>> n) | (X << (32 - n)) +} + +function R (X, n) { + return (X >>> n) +} + +function Ch (x, y, z) { + return ((x & y) ^ ((~x) & z)) +} + +function Maj (x, y, z) { + return ((x & y) ^ (x & z) ^ (y & z)) +} + +function Sigma0256 (x) { + return (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +} + +function Sigma1256 (x) { + return (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +} + +function Gamma0256 (x) { + return (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +} + +function Gamma1256 (x) { + return (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +} + +Sha256.prototype._update = function (M) { + var W = this._w + + var a = this._a | 0 + var b = this._b | 0 + var c = this._c | 0 + var d = this._d | 0 + var e = this._e | 0 + var f = this._f | 0 + var g = this._g | 0 + var h = this._h | 0 + + var j = 0 + + function calcW () { return Gamma1256(W[j - 2]) + W[j - 7] + Gamma0256(W[j - 15]) + W[j - 16] } + function loop (w) { + W[j] = w + + var T1 = h + Sigma1256(e) + Ch(e, f, g) + K[j] + w + var T2 = Sigma0256(a) + Maj(a, b, c) + + h = g + g = f + f = e + e = d + T1 + d = c + c = b + b = a + a = T1 + T2 + + j++ + } + + while (j < 16) loop(M.readInt32BE(j * 4)) + while (j < 64) loop(calcW()) + + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 + this._f = (f + this._f) | 0 + this._g = (g + this._g) | 0 + this._h = (h + this._h) | 0 +} + +Sha256.prototype._hash = function () { + var H = new Buffer(32) + + H.writeInt32BE(this._a, 0) + H.writeInt32BE(this._b, 4) + H.writeInt32BE(this._c, 8) + H.writeInt32BE(this._d, 12) + H.writeInt32BE(this._e, 16) + H.writeInt32BE(this._f, 20) + H.writeInt32BE(this._g, 24) + H.writeInt32BE(this._h, 28) + + return H +} + +module.exports = Sha256 + +}).call(this,require("buffer").Buffer) +},{"./hash":133,"buffer":34,"inherits":180}],139:[function(require,module,exports){ +(function (Buffer){ +var inherits = require('inherits') +var SHA512 = require('./sha512') +var Hash = require('./hash') + +var W = new Array(160) + +function Sha384 () { + this.init() + this._w = W + + Hash.call(this, 128, 112) +} + +inherits(Sha384, SHA512) + +Sha384.prototype.init = function () { + this._a = 0xcbbb9d5d | 0 + this._b = 0x629a292a | 0 + this._c = 0x9159015a | 0 + this._d = 0x152fecd8 | 0 + this._e = 0x67332667 | 0 + this._f = 0x8eb44a87 | 0 + this._g = 0xdb0c2e0d | 0 + this._h = 0x47b5481d | 0 + + this._al = 0xc1059ed8 | 0 + this._bl = 0x367cd507 | 0 + this._cl = 0x3070dd17 | 0 + this._dl = 0xf70e5939 | 0 + this._el = 0xffc00b31 | 0 + this._fl = 0x68581511 | 0 + this._gl = 0x64f98fa7 | 0 + this._hl = 0xbefa4fa4 | 0 + + return this +} + +Sha384.prototype._hash = function () { + var H = new Buffer(48) + + function writeInt64BE (h, l, offset) { + H.writeInt32BE(h, offset) + H.writeInt32BE(l, offset + 4) + } + + writeInt64BE(this._a, this._al, 0) + writeInt64BE(this._b, this._bl, 8) + writeInt64BE(this._c, this._cl, 16) + writeInt64BE(this._d, this._dl, 24) + writeInt64BE(this._e, this._el, 32) + writeInt64BE(this._f, this._fl, 40) + + return H +} + +module.exports = Sha384 + +}).call(this,require("buffer").Buffer) +},{"./hash":133,"./sha512":140,"buffer":34,"inherits":180}],140:[function(require,module,exports){ +(function (Buffer){ +var inherits = require('inherits') +var Hash = require('./hash') + +var K = [ + 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, + 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, + 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, + 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, + 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, + 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, + 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, + 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, + 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, + 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, + 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, + 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, + 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, + 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, + 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, + 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, + 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, + 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, + 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, + 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, + 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, + 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, + 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, + 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, + 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, + 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, + 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, + 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, + 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, + 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, + 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, + 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, + 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, + 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, + 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, + 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, + 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, + 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, + 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, + 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 +] + +var W = new Array(160) + +function Sha512 () { + this.init() + this._w = W + + Hash.call(this, 128, 112) +} + +inherits(Sha512, Hash) + +Sha512.prototype.init = function () { + this._a = 0x6a09e667 | 0 + this._b = 0xbb67ae85 | 0 + this._c = 0x3c6ef372 | 0 + this._d = 0xa54ff53a | 0 + this._e = 0x510e527f | 0 + this._f = 0x9b05688c | 0 + this._g = 0x1f83d9ab | 0 + this._h = 0x5be0cd19 | 0 + + this._al = 0xf3bcc908 | 0 + this._bl = 0x84caa73b | 0 + this._cl = 0xfe94f82b | 0 + this._dl = 0x5f1d36f1 | 0 + this._el = 0xade682d1 | 0 + this._fl = 0x2b3e6c1f | 0 + this._gl = 0xfb41bd6b | 0 + this._hl = 0x137e2179 | 0 + + return this +} + +function S (X, Xl, n) { + return (X >>> n) | (Xl << (32 - n)) +} + +function Ch (x, y, z) { + return ((x & y) ^ ((~x) & z)) +} + +function Maj (x, y, z) { + return ((x & y) ^ (x & z) ^ (y & z)) +} + +Sha512.prototype._update = function (M) { + var W = this._w + + var a = this._a | 0 + var b = this._b | 0 + var c = this._c | 0 + var d = this._d | 0 + var e = this._e | 0 + var f = this._f | 0 + var g = this._g | 0 + var h = this._h | 0 + + var al = this._al | 0 + var bl = this._bl | 0 + var cl = this._cl | 0 + var dl = this._dl | 0 + var el = this._el | 0 + var fl = this._fl | 0 + var gl = this._gl | 0 + var hl = this._hl | 0 + + var i = 0, j = 0 + var Wi, Wil + function calcW () { + var x = W[j - 15 * 2] + var xl = W[j - 15 * 2 + 1] + var gamma0 = S(x, xl, 1) ^ S(x, xl, 8) ^ (x >>> 7) + var gamma0l = S(xl, x, 1) ^ S(xl, x, 8) ^ S(xl, x, 7) + + x = W[j - 2 * 2] + xl = W[j - 2 * 2 + 1] + var gamma1 = S(x, xl, 19) ^ S(xl, x, 29) ^ (x >>> 6) + var gamma1l = S(xl, x, 19) ^ S(x, xl, 29) ^ S(xl, x, 6) + + // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] + var Wi7 = W[j - 7 * 2] + var Wi7l = W[j - 7 * 2 + 1] + + var Wi16 = W[j - 16 * 2] + var Wi16l = W[j - 16 * 2 + 1] + + Wil = gamma0l + Wi7l + Wi = gamma0 + Wi7 + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0) + Wil = Wil + gamma1l + Wi = Wi + gamma1 + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0) + Wil = Wil + Wi16l + Wi = Wi + Wi16 + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0) + } + + function loop () { + W[j] = Wi + W[j + 1] = Wil + + var maj = Maj(a, b, c) + var majl = Maj(al, bl, cl) + + var sigma0h = S(a, al, 28) ^ S(al, a, 2) ^ S(al, a, 7) + var sigma0l = S(al, a, 28) ^ S(a, al, 2) ^ S(a, al, 7) + var sigma1h = S(e, el, 14) ^ S(e, el, 18) ^ S(el, e, 9) + var sigma1l = S(el, e, 14) ^ S(el, e, 18) ^ S(e, el, 9) + + // t1 = h + sigma1 + ch + K[i] + W[i] + var Ki = K[j] + var Kil = K[j + 1] + + var ch = Ch(e, f, g) + var chl = Ch(el, fl, gl) + + var t1l = hl + sigma1l + var t1 = h + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0) + t1l = t1l + chl + t1 = t1 + ch + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0) + t1l = t1l + Kil + t1 = t1 + Ki + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0) + t1l = t1l + Wil + t1 = t1 + Wi + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0) + + // t2 = sigma0 + maj + var t2l = sigma0l + majl + var t2 = sigma0h + maj + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0) + + h = g + hl = gl + g = f + gl = fl + f = e + fl = el + el = (dl + t1l) | 0 + e = (d + t1 + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0 + d = c + dl = cl + c = b + cl = bl + b = a + bl = al + al = (t1l + t2l) | 0 + a = (t1 + t2 + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0 + + i++ + j += 2 + } + + while (i < 16) { + Wi = M.readInt32BE(j * 4) + Wil = M.readInt32BE(j * 4 + 4) + + loop() + } + + while (i < 80) { + calcW() + loop() + } + + this._al = (this._al + al) | 0 + this._bl = (this._bl + bl) | 0 + this._cl = (this._cl + cl) | 0 + this._dl = (this._dl + dl) | 0 + this._el = (this._el + el) | 0 + this._fl = (this._fl + fl) | 0 + this._gl = (this._gl + gl) | 0 + this._hl = (this._hl + hl) | 0 + + this._a = (this._a + a + ((this._al >>> 0) < (al >>> 0) ? 1 : 0)) | 0 + this._b = (this._b + b + ((this._bl >>> 0) < (bl >>> 0) ? 1 : 0)) | 0 + this._c = (this._c + c + ((this._cl >>> 0) < (cl >>> 0) ? 1 : 0)) | 0 + this._d = (this._d + d + ((this._dl >>> 0) < (dl >>> 0) ? 1 : 0)) | 0 + this._e = (this._e + e + ((this._el >>> 0) < (el >>> 0) ? 1 : 0)) | 0 + this._f = (this._f + f + ((this._fl >>> 0) < (fl >>> 0) ? 1 : 0)) | 0 + this._g = (this._g + g + ((this._gl >>> 0) < (gl >>> 0) ? 1 : 0)) | 0 + this._h = (this._h + h + ((this._hl >>> 0) < (hl >>> 0) ? 1 : 0)) | 0 +} + +Sha512.prototype._hash = function () { + var H = new Buffer(64) + + function writeInt64BE (h, l, offset) { + H.writeInt32BE(h, offset) + H.writeInt32BE(l, offset + 4) + } + + writeInt64BE(this._a, this._al, 0) + writeInt64BE(this._b, this._bl, 8) + writeInt64BE(this._c, this._cl, 16) + writeInt64BE(this._d, this._dl, 24) + writeInt64BE(this._e, this._el, 32) + writeInt64BE(this._f, this._fl, 40) + writeInt64BE(this._g, this._gl, 48) + writeInt64BE(this._h, this._hl, 56) + + return H +} + +module.exports = Sha512 + +}).call(this,require("buffer").Buffer) +},{"./hash":133,"buffer":34,"inherits":180}],141:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +var createHash = require('create-hash/browser'); +var inherits = require('inherits') + +var Transform = require('stream').Transform + +var ZEROS = new Buffer(128) +ZEROS.fill(0) + +function Hmac(alg, key) { + Transform.call(this) + + if (typeof key === 'string') { + key = new Buffer(key) + } + + var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64 + + this._alg = alg + this._key = key + + if (key.length > blocksize) { + key = createHash(alg).update(key).digest() + + } else if (key.length < blocksize) { + key = Buffer.concat([key, ZEROS], blocksize) + } + + var ipad = this._ipad = new Buffer(blocksize) + var opad = this._opad = new Buffer(blocksize) + + for (var i = 0; i < blocksize; i++) { + ipad[i] = key[i] ^ 0x36 + opad[i] = key[i] ^ 0x5C + } + + this._hash = createHash(alg).update(ipad) +} + +inherits(Hmac, Transform) + +Hmac.prototype.update = function (data, enc) { + this._hash.update(data, enc) + + return this +} + +Hmac.prototype._transform = function (data, _, next) { + this._hash.update(data) + + next() +} + +Hmac.prototype._flush = function (next) { + this.push(this.digest()) + + next() +} + +Hmac.prototype.digest = function (enc) { + var h = this._hash.digest() + + return createHash(this._alg).update(this._opad).update(h).digest(enc) +} + +module.exports = function createHmac(alg, key) { + return new Hmac(alg, key) +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34,"create-hash/browser":129,"inherits":180,"stream":199}],142:[function(require,module,exports){ +(function (Buffer){ +var generatePrime = require('./lib/generatePrime'); +var primes = require('./lib/primes'); + +var DH = require('./lib/dh'); + +function getDiffieHellman(mod) { + var prime = new Buffer(primes[mod].prime, 'hex'); + var gen = new Buffer(primes[mod].gen, 'hex'); + + return new DH(prime, gen); +} + +function createDiffieHellman(prime, enc, generator, genc) { + if (Buffer.isBuffer(enc) || (typeof enc === 'string' && ['hex', 'binary', 'base64'].indexOf(enc) === -1)) { + genc = generator; + generator = enc; + enc = undefined; + } + + enc = enc || 'binary'; + genc = genc || 'binary'; + generator = generator || new Buffer([2]); + + if (!Buffer.isBuffer(generator)) { + generator = new Buffer(generator, genc); + } + + if (typeof prime === 'number') { + return new DH(generatePrime(prime, generator), generator, true); + } + + if (!Buffer.isBuffer(prime)) { + prime = new Buffer(prime, enc); + } + + return new DH(prime, generator, true); +} + +exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman; +exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman; + +}).call(this,require("buffer").Buffer) +},{"./lib/dh":143,"./lib/generatePrime":144,"./lib/primes":145,"buffer":34}],143:[function(require,module,exports){ +(function (Buffer){ +var BN = require('bn.js'); +var MillerRabin = require('miller-rabin'); +var millerRabin = new MillerRabin(); +var TWENTYFOUR = new BN(24); +var ELEVEN = new BN(11); +var TEN = new BN(10); +var THREE = new BN(3); +var SEVEN = new BN(7); +var primes = require('./generatePrime'); +var randomBytes = require('randombytes'); +module.exports = DH; + +function setPublicKey(pub, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(pub)) { + pub = new Buffer(pub, enc); + } + this._pub = new BN(pub); + return this; +} + +function setPrivateKey(priv, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(priv)) { + priv = new Buffer(priv, enc); + } + this._priv = new BN(priv); + return this; +} + +var primeCache = {}; +function checkPrime(prime, generator) { + var gen = generator.toString('hex'); + var hex = [gen, prime.toString(16)].join('_'); + if (hex in primeCache) { + return primeCache[hex]; + } + var error = 0; + + if (prime.isEven() || + !primes.simpleSieve || + !primes.fermatTest(prime) || + !millerRabin.test(prime)) { + //not a prime so +1 + error += 1; + + if (gen === '02' || gen === '05') { + // we'd be able to check the generator + // it would fail so +8 + error += 8; + } else { + //we wouldn't be able to test the generator + // so +4 + error += 4; + } + primeCache[hex] = error; + return error; + } + if (!millerRabin.test(prime.shrn(1))) { + //not a safe prime + error += 2; + } + var rem; + switch (gen) { + case '02': + if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) { + // unsuidable generator + error += 8; + } + break; + case '05': + rem = prime.mod(TEN); + if (rem.cmp(THREE) && rem.cmp(SEVEN)) { + // prime mod 10 needs to equal 3 or 7 + error += 8; + } + break; + default: + error += 4; + } + primeCache[hex] = error; + return error; +} + +function defineError (self, error) { + try { + Object.defineProperty(self, 'verifyError', { + enumerable: true, + value: error, + writable: false + }); + } catch(e) { + self.verifyError = error; + } +} +function DH(prime, generator, malleable) { + this.setGenerator(generator); + this.__prime = new BN(prime); + this._prime = BN.mont(this.__prime); + this._primeLen = prime.length; + this._pub = void 0; + this._priv = void 0; + + if (malleable) { + this.setPublicKey = setPublicKey; + this.setPrivateKey = setPrivateKey; + defineError(this, checkPrime(this.__prime, generator)); + } else { + defineError(this, 8); + } +} + +DH.prototype.generateKeys = function () { + if (!this._priv) { + this._priv = new BN(randomBytes(this._primeLen)); + } + this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed(); + return this.getPublicKey(); +}; + +DH.prototype.computeSecret = function (other) { + other = new BN(other); + other = other.toRed(this._prime); + var secret = other.redPow(this._priv).fromRed(); + var out = new Buffer(secret.toArray()); + var prime = this.getPrime(); + if (out.length < prime.length) { + var front = new Buffer(prime.length - out.length); + front.fill(0); + out = Buffer.concat([front, out]); + } + return out; +}; + +DH.prototype.getPublicKey = function getPublicKey(enc) { + return formatReturnValue(this._pub, enc); +}; + +DH.prototype.getPrivateKey = function getPrivateKey(enc) { + return formatReturnValue(this._priv, enc); +}; + +DH.prototype.getPrime = function (enc) { + return formatReturnValue(this.__prime, enc); +}; + +DH.prototype.getGenerator = function (enc) { + return formatReturnValue(this._gen, enc); +}; + +DH.prototype.setGenerator = function (gen, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(gen)) { + gen = new Buffer(gen, enc); + } + this._gen = new BN(gen); + return this; +}; + +function formatReturnValue(bn, enc) { + var buf = new Buffer(bn.toArray()); + if (!enc) { + return buf; + } else { + return buf.toString(enc); + } +} +}).call(this,require("buffer").Buffer) +},{"./generatePrime":144,"bn.js":146,"buffer":34,"miller-rabin":147,"randombytes":178}],144:[function(require,module,exports){ +var randomBytes = require('randombytes'); +module.exports = findPrime; +findPrime.simpleSieve = simpleSieve; +findPrime.fermatTest = fermatTest; +var BN = require('bn.js'); +var TWENTYFOUR = new BN(24); +var MillerRabin = require('miller-rabin'); +var millerRabin = new MillerRabin(); +var ONE = new BN(1); +var TWO = new BN(2); +var FIVE = new BN(5); +var SIXTEEN = new BN(16); +var EIGHT = new BN(8); +var TEN = new BN(10); +var THREE = new BN(3); +var SEVEN = new BN(7); +var ELEVEN = new BN(11); +var FOUR = new BN(4); +var TWELVE = new BN(12); +var primes = null; + +function _getPrimes() { + if (primes !== null) + return primes; + + var limit = 0x100000; + var res = []; + res[0] = 2; + for (var i = 1, k = 3; k < limit; k += 2) { + var sqrt = Math.ceil(Math.sqrt(k)); + for (var j = 0; j < i && res[j] <= sqrt; j++) + if (k % res[j] === 0) + break; + + if (i !== j && res[j] <= sqrt) + continue; + + res[i++] = k; + } + primes = res; + return res; +} + +function simpleSieve(p) { + var primes = _getPrimes(); + + for (var i = 0; i < primes.length; i++) + if (p.modn(primes[i]) === 0) { + if (p.cmpn(primes[i]) === 0) { + return true; + } else { + return false; + } + } + + return true; +} + +function fermatTest(p) { + var red = BN.mont(p); + return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0; +} + +function findPrime(bits, gen) { + if (bits < 16) { + // this is what openssl does + if (gen === 2 || gen === 5) { + return new BN([0x8c, 0x7b]); + } else { + return new BN([0x8c, 0x27]); + } + } + gen = new BN(gen); + var runs, comp; + function generateRandom(bits) { + runs = -1; + var out = new BN(randomBytes(Math.ceil(bits / 8))); + while (out.bitLength() > bits) { + out.ishrn(1); + } + if (out.isEven()) { + out.iadd(ONE); + } + if (!out.testn(1)) { + out.iadd(TWO); + } + if (!gen.cmp(TWO)) { + while (out.mod(TWENTYFOUR).cmp(ELEVEN)) { + out.iadd(FOUR); + } + comp = { + major: [TWENTYFOUR], + minor: [TWELVE] + }; + } else if (!gen.cmp(FIVE)) { + rem = out.mod(TEN); + while (rem.cmp(THREE)) { + out.iadd(FOUR); + rem = out.mod(TEN); + } + comp = { + major: [FOUR, SIXTEEN], + minor: [TWO, EIGHT] + }; + } else { + comp = { + major: [FOUR], + minor: [TWO] + }; + } + return out; + } + var num = generateRandom(bits); + + var n2 = num.shrn(1); + + while (true) { + while (num.bitLength() > bits) { + num = generateRandom(bits); + n2 = num.shrn(1); + } + runs++; + if (simpleSieve(n2) && simpleSieve(num) && + fermatTest(n2) && fermatTest(num) && + millerRabin.test(n2) && millerRabin.test(num)) { + return num; + } + num.iadd(comp.major[runs%comp.major.length]); + n2.iadd(comp.minor[runs%comp.minor.length]); + } + +} +},{"bn.js":146,"miller-rabin":147,"randombytes":178}],145:[function(require,module,exports){ +module.exports={ + "modp1": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff" + }, + "modp2": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff" + }, + "modp5": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff" + }, + "modp14": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff" + }, + "modp15": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff" + }, + "modp16": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff" + }, + "modp17": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff" + }, + "modp18": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff" + } +} +},{}],146:[function(require,module,exports){ +arguments[4][60][0].apply(exports,arguments) +},{"dup":60}],147:[function(require,module,exports){ +var bn = require('bn.js'); +var brorand = require('brorand'); + +function MillerRabin(rand) { + this.rand = rand || new brorand.Rand(); +} +module.exports = MillerRabin; + +MillerRabin.create = function create(rand) { + return new MillerRabin(rand); +}; + +MillerRabin.prototype._rand = function _rand(n) { + var len = n.bitLength(); + var buf = this.rand.generate(Math.ceil(len / 8)); + + // Set low bits + buf[0] |= 3; + + // Mask high bits + var mask = len & 0x7; + if (mask !== 0) + buf[buf.length - 1] >>= 7 - mask; + + return new bn(buf); +} + +MillerRabin.prototype.test = function test(n, k, cb) { + var len = n.bitLength(); + var red = bn.mont(n); + var rone = new bn(1).toRed(red); + + if (!k) + k = Math.max(1, (len / 48) | 0); + + // Find d and s, (n - 1) = (2 ^ s) * d; + var n1 = n.subn(1); + var n2 = n1.subn(1); + for (var s = 0; !n1.testn(s); s++) {} + var d = n.shrn(s); + + var rn1 = n1.toRed(red); + + var prime = true; + for (; k > 0; k--) { + var a = this._rand(n2); + if (cb) + cb(a); + + var x = a.toRed(red).redPow(d); + if (x.cmp(rone) === 0 || x.cmp(rn1) === 0) + continue; + + for (var i = 1; i < s; i++) { + x = x.redSqr(); + + if (x.cmp(rone) === 0) + return false; + if (x.cmp(rn1) === 0) + break; + } + + if (i === s) + return false; + } + + return prime; +}; + +MillerRabin.prototype.getDivisor = function getDivisor(n, k) { + var len = n.bitLength(); + var red = bn.mont(n); + var rone = new bn(1).toRed(red); + + if (!k) + k = Math.max(1, (len / 48) | 0); + + // Find d and s, (n - 1) = (2 ^ s) * d; + var n1 = n.subn(1); + var n2 = n1.subn(1); + for (var s = 0; !n1.testn(s); s++) {} + var d = n.shrn(s); + + var rn1 = n1.toRed(red); + + for (; k > 0; k--) { + var a = this._rand(n2); + + var g = n.gcd(a); + if (g.cmpn(1) !== 0) + return g; + + var x = a.toRed(red).redPow(d); + if (x.cmp(rone) === 0 || x.cmp(rn1) === 0) + continue; + + for (var i = 1; i < s; i++) { + x = x.redSqr(); + + if (x.cmp(rone) === 0) + return x.fromRed().subn(1).gcd(n); + if (x.cmp(rn1) === 0) + break; + } + + if (i === s) { + x = x.redSqr(); + return x.fromRed().subn(1).gcd(n); + } + } + + return false; +}; + +},{"bn.js":146,"brorand":148}],148:[function(require,module,exports){ +arguments[4][75][0].apply(exports,arguments) +},{"dup":75}],149:[function(require,module,exports){ +(function (Buffer){ +var createHmac = require('create-hmac') +var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs + +exports.pbkdf2 = pbkdf2 +function pbkdf2 (password, salt, iterations, keylen, digest, callback) { + if (typeof digest === 'function') { + callback = digest + digest = undefined + } + + if (typeof callback !== 'function') { + throw new Error('No callback provided to pbkdf2') + } + + var result = pbkdf2Sync(password, salt, iterations, keylen, digest) + setTimeout(function () { + callback(undefined, result) + }) +} + +exports.pbkdf2Sync = pbkdf2Sync +function pbkdf2Sync (password, salt, iterations, keylen, digest) { + if (typeof iterations !== 'number') { + throw new TypeError('Iterations not a number') + } + + if (iterations < 0) { + throw new TypeError('Bad iterations') + } + + if (typeof keylen !== 'number') { + throw new TypeError('Key length not a number') + } + + if (keylen < 0 || keylen > MAX_ALLOC) { + throw new TypeError('Bad key length') + } + + digest = digest || 'sha1' + + if (!Buffer.isBuffer(password)) password = new Buffer(password, 'binary') + if (!Buffer.isBuffer(salt)) salt = new Buffer(salt, 'binary') + + var hLen + var l = 1 + var DK = new Buffer(keylen) + var block1 = new Buffer(salt.length + 4) + salt.copy(block1, 0, 0, salt.length) + + var r + var T + + for (var i = 1; i <= l; i++) { + block1.writeUInt32BE(i, salt.length) + var U = createHmac(digest, password).update(block1).digest() + + if (!hLen) { + hLen = U.length + T = new Buffer(hLen) + l = Math.ceil(keylen / hLen) + r = keylen - (l - 1) * hLen + } + + U.copy(T, 0, 0, hLen) + + for (var j = 1; j < iterations; j++) { + U = createHmac(digest, password).update(U).digest() + + for (var k = 0; k < hLen; k++) { + T[k] ^= U[k] + } + } + + var destPos = (i - 1) * hLen + var len = (i === l ? r : hLen) + T.copy(DK, destPos, 0, len) + } + + return DK +} + +}).call(this,require("buffer").Buffer) +},{"buffer":34,"create-hmac":141}],150:[function(require,module,exports){ +exports.publicEncrypt = require('./publicEncrypt'); +exports.privateDecrypt = require('./privateDecrypt'); + +exports.privateEncrypt = function privateEncrypt(key, buf) { + return exports.publicEncrypt(key, buf, true); +}; + +exports.publicDecrypt = function publicDecrypt(key, buf) { + return exports.privateDecrypt(key, buf, true); +}; +},{"./privateDecrypt":174,"./publicEncrypt":175}],151:[function(require,module,exports){ +(function (Buffer){ +var createHash = require('create-hash'); +module.exports = function (seed, len) { + var t = new Buffer(''); + var i = 0, c; + while (t.length < len) { + c = i2ops(i++); + t = Buffer.concat([t, createHash('sha1').update(seed).update(c).digest()]); + } + return t.slice(0, len); +}; + +function i2ops(c) { + var out = new Buffer(4); + out.writeUInt32BE(c,0); + return out; +} +}).call(this,require("buffer").Buffer) +},{"buffer":34,"create-hash":129}],152:[function(require,module,exports){ +arguments[4][60][0].apply(exports,arguments) +},{"dup":60}],153:[function(require,module,exports){ +arguments[4][61][0].apply(exports,arguments) +},{"bn.js":152,"buffer":34,"dup":61,"randombytes":178}],154:[function(require,module,exports){ +arguments[4][83][0].apply(exports,arguments) +},{"buffer":34,"create-hash":129,"dup":83}],155:[function(require,module,exports){ +arguments[4][84][0].apply(exports,arguments) +},{"dup":84}],156:[function(require,module,exports){ +arguments[4][85][0].apply(exports,arguments) +},{"asn1.js":159,"dup":85}],157:[function(require,module,exports){ +arguments[4][86][0].apply(exports,arguments) +},{"./EVP_BytesToKey":154,"browserify-aes":42,"buffer":34,"dup":86}],158:[function(require,module,exports){ +arguments[4][87][0].apply(exports,arguments) +},{"./aesid.json":155,"./asn1":156,"./fixProc":157,"browserify-aes":42,"buffer":34,"dup":87,"pbkdf2":149}],159:[function(require,module,exports){ +arguments[4][88][0].apply(exports,arguments) +},{"./asn1/api":160,"./asn1/base":162,"./asn1/constants":166,"./asn1/decoders":168,"./asn1/encoders":171,"bn.js":152,"dup":88}],160:[function(require,module,exports){ +arguments[4][89][0].apply(exports,arguments) +},{"../asn1":159,"dup":89,"inherits":180,"vm":202}],161:[function(require,module,exports){ +arguments[4][90][0].apply(exports,arguments) +},{"../base":162,"buffer":34,"dup":90,"inherits":180}],162:[function(require,module,exports){ +arguments[4][91][0].apply(exports,arguments) +},{"./buffer":161,"./node":163,"./reporter":164,"dup":91}],163:[function(require,module,exports){ +arguments[4][92][0].apply(exports,arguments) +},{"../base":162,"dup":92,"minimalistic-assert":173}],164:[function(require,module,exports){ +arguments[4][93][0].apply(exports,arguments) +},{"dup":93,"inherits":180}],165:[function(require,module,exports){ +arguments[4][94][0].apply(exports,arguments) +},{"../constants":166,"dup":94}],166:[function(require,module,exports){ +arguments[4][95][0].apply(exports,arguments) +},{"./der":165,"dup":95}],167:[function(require,module,exports){ +arguments[4][96][0].apply(exports,arguments) +},{"../../asn1":159,"dup":96,"inherits":180}],168:[function(require,module,exports){ +arguments[4][97][0].apply(exports,arguments) +},{"./der":167,"./pem":169,"dup":97}],169:[function(require,module,exports){ +arguments[4][98][0].apply(exports,arguments) +},{"../../asn1":159,"./der":167,"buffer":34,"dup":98,"inherits":180}],170:[function(require,module,exports){ +arguments[4][99][0].apply(exports,arguments) +},{"../../asn1":159,"buffer":34,"dup":99,"inherits":180}],171:[function(require,module,exports){ +arguments[4][100][0].apply(exports,arguments) +},{"./der":170,"./pem":172,"dup":100}],172:[function(require,module,exports){ +arguments[4][101][0].apply(exports,arguments) +},{"../../asn1":159,"./der":170,"buffer":34,"dup":101,"inherits":180}],173:[function(require,module,exports){ +arguments[4][102][0].apply(exports,arguments) +},{"dup":102}],174:[function(require,module,exports){ +(function (Buffer){ +var parseKeys = require('parse-asn1'); +var mgf = require('./mgf'); +var xor = require('./xor'); +var bn = require('bn.js'); +var crt = require('browserify-rsa'); +var createHash = require('create-hash'); +var withPublic = require('./withPublic'); +module.exports = function privateDecrypt(private_key, enc, reverse) { + var padding; + if (private_key.padding) { + padding = private_key.padding; + } else if (reverse) { + padding = 1; + } else { + padding = 4; + } + + var key = parseKeys(private_key); + var k = key.modulus.byteLength(); + if (enc.length > k || new bn(enc).cmp(key.modulus) >= 0) { + throw new Error('decryption error'); + } + var msg; + if (reverse) { + msg = withPublic(new bn(enc), key); + } else { + msg = crt(enc, key); + } + var zBuffer = new Buffer(k - msg.length); + zBuffer.fill(0); + msg = Buffer.concat([zBuffer, msg], k); + if (padding === 4) { + return oaep(key, msg); + } else if (padding === 1) { + return pkcs1(key, msg, reverse); + } else if (padding === 3) { + return msg; + } else { + throw new Error('unknown padding'); + } +}; + +function oaep(key, msg){ + var n = key.modulus; + var k = key.modulus.byteLength(); + var mLen = msg.length; + var iHash = createHash('sha1').update(new Buffer('')).digest(); + var hLen = iHash.length; + var hLen2 = 2 * hLen; + if (msg[0] !== 0) { + throw new Error('decryption error'); + } + var maskedSeed = msg.slice(1, hLen + 1); + var maskedDb = msg.slice(hLen + 1); + var seed = xor(maskedSeed, mgf(maskedDb, hLen)); + var db = xor(maskedDb, mgf(seed, k - hLen - 1)); + if (compare(iHash, db.slice(0, hLen))) { + throw new Error('decryption error'); + } + var i = hLen; + while (db[i] === 0) { + i++; + } + if (db[i++] !== 1) { + throw new Error('decryption error'); + } + return db.slice(i); +} + +function pkcs1(key, msg, reverse){ + var p1 = msg.slice(0, 2); + var i = 2; + var status = 0; + while (msg[i++] !== 0) { + if (i >= msg.length) { + status++; + break; + } + } + var ps = msg.slice(2, i - 1); + var p2 = msg.slice(i - 1, i); + + if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)){ + status++; + } + if (ps.length < 8) { + status++; + } + if (status) { + throw new Error('decryption error'); + } + return msg.slice(i); +} +function compare(a, b){ + a = new Buffer(a); + b = new Buffer(b); + var dif = 0; + var len = a.length; + if (a.length !== b.length) { + dif++; + len = Math.min(a.length, b.length); + } + var i = -1; + while (++i < len) { + dif += (a[i] ^ b[i]); + } + return dif; +} +}).call(this,require("buffer").Buffer) +},{"./mgf":151,"./withPublic":176,"./xor":177,"bn.js":152,"browserify-rsa":153,"buffer":34,"create-hash":129,"parse-asn1":158}],175:[function(require,module,exports){ +(function (Buffer){ +var parseKeys = require('parse-asn1'); +var randomBytes = require('randombytes'); +var createHash = require('create-hash'); +var mgf = require('./mgf'); +var xor = require('./xor'); +var bn = require('bn.js'); +var withPublic = require('./withPublic'); +var crt = require('browserify-rsa'); + +var constants = { + RSA_PKCS1_OAEP_PADDING: 4, + RSA_PKCS1_PADDIN: 1, + RSA_NO_PADDING: 3 +}; + +module.exports = function publicEncrypt(public_key, msg, reverse) { + var padding; + if (public_key.padding) { + padding = public_key.padding; + } else if (reverse) { + padding = 1; + } else { + padding = 4; + } + var key = parseKeys(public_key); + var paddedMsg; + if (padding === 4) { + paddedMsg = oaep(key, msg); + } else if (padding === 1) { + paddedMsg = pkcs1(key, msg, reverse); + } else if (padding === 3) { + paddedMsg = new bn(msg); + if (paddedMsg.cmp(key.modulus) >= 0) { + throw new Error('data too long for modulus'); + } + } else { + throw new Error('unknown padding'); + } + if (reverse) { + return crt(paddedMsg, key); + } else { + return withPublic(paddedMsg, key); + } +}; + +function oaep(key, msg){ + var k = key.modulus.byteLength(); + var mLen = msg.length; + var iHash = createHash('sha1').update(new Buffer('')).digest(); + var hLen = iHash.length; + var hLen2 = 2 * hLen; + if (mLen > k - hLen2 - 2) { + throw new Error('message too long'); + } + var ps = new Buffer(k - mLen - hLen2 - 2); + ps.fill(0); + var dblen = k - hLen - 1; + var seed = randomBytes(hLen); + var maskedDb = xor(Buffer.concat([iHash, ps, new Buffer([1]), msg], dblen), mgf(seed, dblen)); + var maskedSeed = xor(seed, mgf(maskedDb, hLen)); + return new bn(Buffer.concat([new Buffer([0]), maskedSeed, maskedDb], k)); +} +function pkcs1(key, msg, reverse){ + var mLen = msg.length; + var k = key.modulus.byteLength(); + if (mLen > k - 11) { + throw new Error('message too long'); + } + var ps; + if (reverse) { + ps = new Buffer(k - mLen - 3); + ps.fill(0xff); + } else { + ps = nonZero(k - mLen - 3); + } + return new bn(Buffer.concat([new Buffer([0, reverse?1:2]), ps, new Buffer([0]), msg], k)); +} +function nonZero(len, crypto) { + var out = new Buffer(len); + var i = 0; + var cache = randomBytes(len*2); + var cur = 0; + var num; + while (i < len) { + if (cur === cache.length) { + cache = randomBytes(len*2); + cur = 0; + } + num = cache[cur++]; + if (num) { + out[i++] = num; + } + } + return out; +} +}).call(this,require("buffer").Buffer) +},{"./mgf":151,"./withPublic":176,"./xor":177,"bn.js":152,"browserify-rsa":153,"buffer":34,"create-hash":129,"parse-asn1":158,"randombytes":178}],176:[function(require,module,exports){ +(function (Buffer){ +var bn = require('bn.js'); +function withPublic(paddedMsg, key) { + return new Buffer(paddedMsg + .toRed(bn.mont(key.modulus)) + .redPow(new bn(key.publicExponent)) + .fromRed() + .toArray()); +} + +module.exports = withPublic; +}).call(this,require("buffer").Buffer) +},{"bn.js":152,"buffer":34}],177:[function(require,module,exports){ +module.exports = function xor(a, b) { + var len = a.length; + var i = -1; + while (++i < len) { + a[i] ^= b[i]; + } + return a +}; +},{}],178:[function(require,module,exports){ +(function (process,global,Buffer){ +'use strict'; + +var crypto = global.crypto || global.msCrypto +if(crypto && crypto.getRandomValues) { + module.exports = randomBytes; +} else { + module.exports = oldBrowser; +} +function randomBytes(size, cb) { + var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array + /* This will not work in older browsers. + * See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues + */ + + crypto.getRandomValues(bytes); + if (typeof cb === 'function') { + return process.nextTick(function () { + cb(null, bytes); + }); + } + return bytes; +} +function oldBrowser() { + throw new Error( + 'secure random number generation not supported by this browser\n'+ + 'use chrome, FireFox or Internet Explorer 11' + ) +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) +},{"_process":183,"buffer":34}],179:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],180:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],181:[function(require,module,exports){ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; + +},{}],182:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + 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 the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 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 < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":183}],183:[function(require,module,exports){ +// shim for using process in browser + +var process = module.exports = {}; +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = setTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + currentQueue[queueIndex].run(); + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + clearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + setTimeout(drainQueue, 0); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],184:[function(require,module,exports){ +(function (global){ +/*! https://mths.be/punycode v1.3.2 by @mathias */ +;(function(root) { + + /** Detect free variables */ + var freeExports = typeof exports == 'object' && exports && + !exports.nodeType && exports; + var freeModule = typeof module == 'object' && module && + !module.nodeType && module; + var freeGlobal = typeof global == 'object' && global; + if ( + freeGlobal.global === freeGlobal || + freeGlobal.window === freeGlobal || + freeGlobal.self === freeGlobal + ) { + root = freeGlobal; + } + + /** + * The `punycode` object. + * @name punycode + * @type Object + */ + var punycode, + + /** Highest positive signed 32-bit float value */ + maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 + + /** Bootstring parameters */ + base = 36, + tMin = 1, + tMax = 26, + skew = 38, + damp = 700, + initialBias = 72, + initialN = 128, // 0x80 + delimiter = '-', // '\x2D' + + /** Regular expressions */ + regexPunycode = /^xn--/, + regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars + regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators + + /** Error messages */ + errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' + }, + + /** Convenience shortcuts */ + baseMinusTMin = base - tMin, + floor = Math.floor, + stringFromCharCode = String.fromCharCode, + + /** Temporary variable */ + key; + + /*--------------------------------------------------------------------------*/ + + /** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ + function error(type) { + throw RangeError(errors[type]); + } + + /** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ + function map(array, fn) { + var length = array.length; + var result = []; + while (length--) { + result[length] = fn(array[length]); + } + return result; + } + + /** + * A simple `Array#map`-like wrapper to work with domain name strings or email + * addresses. + * @private + * @param {String} domain The domain name or email address. + * @param {Function} callback The function that gets called for every + * character. + * @returns {Array} A new string of characters returned by the callback + * function. + */ + function mapDomain(string, fn) { + var parts = string.split('@'); + var result = ''; + if (parts.length > 1) { + // In email addresses, only the domain name should be punycoded. Leave + // the local part (i.e. everything up to `@`) intact. + result = parts[0] + '@'; + string = parts[1]; + } + // Avoid `split(regex)` for IE8 compatibility. See #17. + string = string.replace(regexSeparators, '\x2E'); + var labels = string.split('.'); + var encoded = map(labels, fn).join('.'); + return result + encoded; + } + + /** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ + function ucs2decode(string) { + var output = [], + counter = 0, + length = string.length, + value, + extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + + /** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ + function ucs2encode(array) { + return map(array, function(value) { + var output = ''; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + return output; + }).join(''); + } + + /** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ + function basicToDigit(codePoint) { + if (codePoint - 48 < 10) { + return codePoint - 22; + } + if (codePoint - 65 < 26) { + return codePoint - 65; + } + if (codePoint - 97 < 26) { + return codePoint - 97; + } + return base; + } + + /** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ + function digitToBasic(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); + } + + /** + * Bias adaptation function as per section 3.4 of RFC 3492. + * http://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ + function adapt(delta, numPoints, firstTime) { + var k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); + } + + /** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ + function decode(input) { + // Don't use UCS-2 + var output = [], + inputLength = input.length, + out, + i = 0, + n = initialN, + bias = initialBias, + basic, + j, + index, + oldi, + w, + k, + digit, + t, + /** Cached calculation results */ + baseMinusT; + + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. + + basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } + + for (j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error('not-basic'); + } + output.push(input.charCodeAt(j)); + } + + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. + + for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + for (oldi = i, w = 1, k = base; /* no condition */; k += base) { + + if (index >= inputLength) { + error('invalid-input'); + } + + digit = basicToDigit(input.charCodeAt(index++)); + + if (digit >= base || digit > floor((maxInt - i) / w)) { + error('overflow'); + } + + i += digit * w; + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + + if (digit < t) { + break; + } + + baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error('overflow'); + } + + w *= baseMinusT; + + } + + out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); + + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error('overflow'); + } + + n += floor(i / out); + i %= out; + + // Insert `n` at position `i` of the output + output.splice(i++, 0, n); + + } + + return ucs2encode(output); + } + + /** + * Converts a string of Unicode symbols (e.g. a domain name label) to a + * Punycode string of ASCII-only symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ + function encode(input) { + var n, + delta, + handledCPCount, + basicLength, + bias, + j, + m, + q, + k, + t, + currentValue, + output = [], + /** `inputLength` will hold the number of code points in `input`. */ + inputLength, + /** Cached calculation results */ + handledCPCountPlusOne, + baseMinusT, + qMinusT; + + // Convert the input in UCS-2 to Unicode + input = ucs2decode(input); + + // Cache the length + inputLength = input.length; + + // Initialize the state + n = initialN; + delta = 0; + bias = initialBias; + + // Handle the basic code points + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue < 0x80) { + output.push(stringFromCharCode(currentValue)); + } + } + + handledCPCount = basicLength = output.length; + + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. + + // Finish the basic string - if it is not empty - with a delimiter + if (basicLength) { + output.push(delimiter); + } + + // Main encoding loop: + while (handledCPCount < inputLength) { + + // All non-basic code points < n have been handled already. Find the next + // larger one: + for (m = maxInt, j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } + + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow + handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error('overflow'); + } + + delta += (m - n) * handledCPCountPlusOne; + n = m; + + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + + if (currentValue < n && ++delta > maxInt) { + error('overflow'); + } + + if (currentValue == n) { + // Represent delta as a generalized variable-length integer + for (q = delta, k = base; /* no condition */; k += base) { + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (q < t) { + break; + } + qMinusT = q - t; + baseMinusT = base - t; + output.push( + stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ); + q = floor(qMinusT / baseMinusT); + } + + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); + delta = 0; + ++handledCPCount; + } + } + + ++delta; + ++n; + + } + return output.join(''); + } + + /** + * Converts a Punycode string representing a domain name or an email address + * to Unicode. Only the Punycoded parts of the input will be converted, i.e. + * it doesn't matter if you call it on a string that has already been + * converted to Unicode. + * @memberOf punycode + * @param {String} input The Punycoded domain name or email address to + * convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ + function toUnicode(input) { + return mapDomain(input, function(string) { + return regexPunycode.test(string) + ? decode(string.slice(4).toLowerCase()) + : string; + }); + } + + /** + * Converts a Unicode string representing a domain name or an email address to + * Punycode. Only the non-ASCII parts of the domain name will be converted, + * i.e. it doesn't matter if you call it with a domain that's already in + * ASCII. + * @memberOf punycode + * @param {String} input The domain name or email address to convert, as a + * Unicode string. + * @returns {String} The Punycode representation of the given domain name or + * email address. + */ + function toASCII(input) { + return mapDomain(input, function(string) { + return regexNonASCII.test(string) + ? 'xn--' + encode(string) + : string; + }); + } + + /*--------------------------------------------------------------------------*/ + + /** Define the public API */ + punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '1.3.2', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode + }; + + /** Expose `punycode` */ + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define('punycode', function() { + return punycode; + }); + } else if (freeExports && freeModule) { + if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+ + freeModule.exports = punycode; + } else { // in Narwhal or RingoJS v0.7.0- + for (key in punycode) { + punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); + } + } + } else { // in Rhino or a web browser + root.punycode = punycode; + } + +}(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],185:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +'use strict'; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +module.exports = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; + + if (typeof qs !== 'string' || qs.length === 0) { + return obj; + } + + var regexp = /\+/g; + qs = qs.split(sep); + + var maxKeys = 1000; + if (options && typeof options.maxKeys === 'number') { + maxKeys = options.maxKeys; + } + + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; + } + + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; + + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); + } else { + kstr = x; + vstr = ''; + } + + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); + + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (isArray(obj[k])) { + obj[k].push(v); + } else { + obj[k] = [obj[k], v]; + } + } + + return obj; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +},{}],186:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +'use strict'; + +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; + + case 'boolean': + return v ? 'true' : 'false'; + + case 'number': + return isFinite(v) ? v : ''; + + default: + return ''; + } +}; + +module.exports = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } + + if (typeof obj === 'object') { + return map(objectKeys(obj), function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (isArray(obj[k])) { + return map(obj[k], function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).join(sep); + + } + + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +function map (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + res.push(f(xs[i], i)); + } + return res; +} + +var objectKeys = Object.keys || function (obj) { + var res = []; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; +}; + +},{}],187:[function(require,module,exports){ +'use strict'; + +exports.decode = exports.parse = require('./decode'); +exports.encode = exports.stringify = require('./encode'); + +},{"./decode":185,"./encode":186}],188:[function(require,module,exports){ +module.exports = require("./lib/_stream_duplex.js") + +},{"./lib/_stream_duplex.js":189}],189:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +module.exports = Duplex; + +/**/ +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +} +/**/ + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +forEach(objectKeys(Writable.prototype), function(method) { + if (!Duplex.prototype[method]) + Duplex.prototype[method] = Writable.prototype[method]; +}); + +function Duplex(options) { + if (!(this instanceof Duplex)) + return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) + this.readable = false; + + if (options && options.writable === false) + this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) + this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) + return; + + // no more data can be written. + // But allow more writes to happen in this tick. + process.nextTick(this.end.bind(this)); +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +}).call(this,require('_process')) +},{"./_stream_readable":191,"./_stream_writable":193,"_process":183,"core-util-is":194,"inherits":180}],190:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +module.exports = PassThrough; + +var Transform = require('./_stream_transform'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) + return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function(chunk, encoding, cb) { + cb(null, chunk); +}; + +},{"./_stream_transform":192,"core-util-is":194,"inherits":180}],191:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +module.exports = Readable; + +/**/ +var isArray = require('isarray'); +/**/ + + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; + +/**/ +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +var Stream = require('stream'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var StringDecoder; + + +/**/ +var debug = require('util'); +if (debug && debug.debuglog) { + debug = debug.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + + +util.inherits(Readable, Stream); + +function ReadableState(options, stream) { + var Duplex = require('./_stream_duplex'); + + options = options || {}; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.readableObjectMode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + var Duplex = require('./_stream_duplex'); + + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function(chunk, encoding) { + var state = this._readableState; + + if (util.isString(chunk) && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (util.isNullOrUndefined(chunk)) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); + + if (!addToFront) + state.reading = false; + + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) + state.buffer.unshift(chunk); + else + state.buffer.push(chunk); + + if (state.needReadable) + emitReadable(stream); + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + + + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (isNaN(n) || util.isNull(n)) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; + } + + if (n <= 0) + return 0; + + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } + + return n; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + debug('read', n); + var state = this._readableState; + var nOrig = n; + + if (!util.isNumber(n) || n > 0) + state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && + state.needReadable && + (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) + endReadable(this); + else + emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) + endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } + + if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) + state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + } + + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); + + var ret; + if (n > 0) + ret = fromList(n, state); + else + ret = null; + + if (util.isNull(ret)) { + state.needReadable = true; + n = 0; + } + + state.length -= n; + + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended && state.length === 0) + endReadable(this); + + if (!util.isNull(ret)) + this.emit('data', ret); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) + process.nextTick(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function(n) { + this.emit('error', new Error('not implemented')); +}; + +Readable.prototype.pipe = function(dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + process.nextTick(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && + (!dest._writableState || dest._writableState.needDrain)) + ondrain(); + } + + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + if (false === ret) { + debug('false write response, pause', + src._readableState.awaitDrain); + src._readableState.awaitDrain++; + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) + dest.on('error', onerror); + else if (isArray(dest._events.error)) + dest._events.error.unshift(onerror); + else + dest._events.error = [onerror, dest._events.error]; + + + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) + state.awaitDrain--; + if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + + +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) + return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) + return this; + + if (!dest) + dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; + } + + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) + return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function(ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + // If listening to data, and it has not explicitly been paused, + // then call resume to start the flow of data on the next tick. + if (ev === 'data' && false !== this._readableState.flowing) { + this.resume(); + } + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + var self = this; + process.nextTick(function() { + debug('readable nexttick read 0'); + self.read(0); + }); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function() { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + if (!state.reading) { + debug('resume read 0'); + this.read(0); + } + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + process.nextTick(function() { + resume_(stream, state); + }); + } +} + +function resume_(stream, state) { + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) + stream.read(0); +} + +Readable.prototype.pause = function() { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + if (state.flowing) { + do { + var chunk = stream.read(); + } while (null !== chunk && state.flowing); + } +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function(stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function() { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function(chunk) { + debug('wrapped data'); + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !chunk.length) + return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (util.isFunction(stream[i]) && util.isUndefined(this[i])) { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + forEach(events, function(ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + + + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; + + // nothing in the list, definitely empty. + if (list.length === 0) + return null; + + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + process.nextTick(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf (xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} + +}).call(this,require('_process')) +},{"./_stream_duplex":189,"_process":183,"buffer":34,"core-util-is":194,"events":179,"inherits":180,"isarray":181,"stream":199,"string_decoder/":200,"util":33}],192:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (!util.isNullOrUndefined(data)) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + this.once('prefinish', function() { + if (util.isFunction(this._flush)) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} + +Transform.prototype.push = function(chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function(chunk, encoding, cb) { + throw new Error('not implemented'); +}; + +Transform.prototype._write = function(chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || + rs.needReadable || + rs.length < rs.highWaterMark) + this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function(n) { + var ts = this._transformState; + + if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + + +function done(stream, er) { + if (er) + return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); + + if (ts.transforming) + throw new Error('calling transform done when still transforming'); + + return stream.push(null); +} + +},{"./_stream_duplex":189,"core-util-is":194,"inherits":180}],193:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Writable.WritableState = WritableState; + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Stream = require('stream'); + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + var Duplex = require('./_stream_duplex'); + + options = options || {}; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.writableObjectMode; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function(er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.buffer = []; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; +} + +function Writable(options) { + var Duplex = require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; + + +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); + valid = false; + } + return valid; +} + +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (util.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (!util.isFunction(cb)) + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function() { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function() { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && + !state.corked && + !state.finished && + !state.bufferProcessing && + state.buffer.length) + clearBuffer(this, state); + } +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + util.isString(chunk)) { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + if (util.isBuffer(chunk)) + encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) + state.needDrain = true; + + if (state.writing || state.corked) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, false, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) + stream._writev(chunk, state.onwrite); + else + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + process.nextTick(function() { + state.pendingcb--; + cb(er); + }); + else { + state.pendingcb--; + cb(er); + } + + stream._writableState.errorEmitted = true; + stream.emit('error', er); +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) + onwriteError(stream, state, sync, er, cb); + else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(stream, state); + + if (!finished && + !state.corked && + !state.bufferProcessing && + state.buffer.length) { + clearBuffer(stream, state); + } + + if (sync) { + process.nextTick(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + + if (stream._writev && state.buffer.length > 1) { + // Fast case, write everything using _writev() + var cbs = []; + for (var c = 0; c < state.buffer.length; c++) + cbs.push(state.buffer[c].callback); + + // count the one we are adding, as well. + // TODO(isaacs) clean this up + state.pendingcb++; + doWrite(stream, state, true, state.length, state.buffer, '', function(err) { + for (var i = 0; i < cbs.length; i++) { + state.pendingcb--; + cbs[i](err); + } + }); + + // Clear buffer + state.buffer = []; + } else { + // Slow case, write chunks one-by-one + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } + + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; + } + + state.bufferProcessing = false; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); + +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function(chunk, encoding, cb) { + var state = this._writableState; + + if (util.isFunction(chunk)) { + cb = chunk; + chunk = null; + encoding = null; + } else if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (!util.isNullOrUndefined(chunk)) + this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else + prefinish(stream, state); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + process.nextTick(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} + +}).call(this,require('_process')) +},{"./_stream_duplex":189,"_process":183,"buffer":34,"core-util-is":194,"inherits":180,"stream":199}],194:[function(require,module,exports){ +(function (Buffer){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +function isBuffer(arg) { + return Buffer.isBuffer(arg); +} +exports.isBuffer = isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} +}).call(this,require("buffer").Buffer) +},{"buffer":34}],195:[function(require,module,exports){ +module.exports = require("./lib/_stream_passthrough.js") + +},{"./lib/_stream_passthrough.js":190}],196:[function(require,module,exports){ +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = require('stream'); +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); + +},{"./lib/_stream_duplex.js":189,"./lib/_stream_passthrough.js":190,"./lib/_stream_readable.js":191,"./lib/_stream_transform.js":192,"./lib/_stream_writable.js":193,"stream":199}],197:[function(require,module,exports){ +module.exports = require("./lib/_stream_transform.js") + +},{"./lib/_stream_transform.js":192}],198:[function(require,module,exports){ +module.exports = require("./lib/_stream_writable.js") + +},{"./lib/_stream_writable.js":193}],199:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +module.exports = Stream; + +var EE = require('events').EventEmitter; +var inherits = require('inherits'); + +inherits(Stream, EE); +Stream.Readable = require('readable-stream/readable.js'); +Stream.Writable = require('readable-stream/writable.js'); +Stream.Duplex = require('readable-stream/duplex.js'); +Stream.Transform = require('readable-stream/transform.js'); +Stream.PassThrough = require('readable-stream/passthrough.js'); + +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; + + + +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. + +function Stream() { + EE.call(this); +} + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } + + source.on('error', onerror); + dest.on('error', onerror); + + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); + + source.removeListener('end', onend); + source.removeListener('close', onclose); + + source.removeListener('error', onerror); + dest.removeListener('error', onerror); + + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); + + dest.removeListener('close', cleanup); + } + + source.on('end', cleanup); + source.on('close', cleanup); + + dest.on('close', cleanup); + + dest.emit('pipe', source); + + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; + +},{"events":179,"inherits":180,"readable-stream/duplex.js":188,"readable-stream/passthrough.js":195,"readable-stream/readable.js":196,"readable-stream/transform.js":197,"readable-stream/writable.js":198}],200:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +var Buffer = require('buffer').Buffer; + +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; + + +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } + + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} + +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} + +},{"buffer":34}],201:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +var punycode = require('punycode'); + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; + +exports.Url = Url; + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; +} + +// Reference: RFC 3986, RFC 1808, RFC 2396 + +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, + + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], + + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), + + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), + hostEndingChars = ['/', '?', '#'], + hostnameMaxLen = 255, + hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + querystring = require('querystring'); + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && isObject(url) && url instanceof Url) return url; + + var u = new Url; + u.parse(url, parseQueryString, slashesDenoteHost); + return u; +} + +Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { + if (!isString(url)) { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } + + var rest = url; + + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = rest.trim(); + + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.substr(proto.length); + } + + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } + + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c + + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. + + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (var i = 0; i < hostEndingChars.length; i++) { + var hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } + + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = decodeURIComponent(auth); + } + + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (var i = 0; i < nonHostChars.length; i++) { + var hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) + hostEnd = rest.length; + + this.host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); + + // pull out port. + this.parseHost(); + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; + + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; + + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } + } + } + + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; + } else { + // hostnames are always lower case. + this.hostname = this.hostname.toLowerCase(); + } + + if (!ipv6Hostname) { + // IDNA Support: Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + var domainArray = this.hostname.split('.'); + var newOut = []; + for (var i = 0; i < domainArray.length; ++i) { + var s = domainArray[i]; + newOut.push(s.match(/[^A-Za-z0-9_-]/) ? + 'xn--' + punycode.encode(s) : s); + } + this.hostname = newOut.join('.'); + } + + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; + this.href += this.host; + + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } + + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { + + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); + } + } + + + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + this.query = rest.substr(qm + 1); + if (parseQueryString) { + this.query = querystring.parse(this.query); + } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + if (rest) this.pathname = rest; + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = '/'; + } + + //to support http.request + if (this.pathname || this.search) { + var p = this.pathname || ''; + var s = this.search || ''; + this.path = p + s; + } + + // finally, reconstruct the href based on what has been validated. + this.href = this.format(); + return this; +}; + +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (isString(obj)) obj = urlParse(obj); + if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} + +Url.prototype.format = function() { + var auth = this.auth || ''; + if (auth) { + auth = encodeURIComponent(auth); + auth = auth.replace(/%3A/i, ':'); + auth += '@'; + } + + var protocol = this.protocol || '', + pathname = this.pathname || '', + hash = this.hash || '', + host = false, + query = ''; + + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? + this.hostname : + '[' + this.hostname + ']'); + if (this.port) { + host += ':' + this.port; + } + } + + if (this.query && + isObject(this.query) && + Object.keys(this.query).length) { + query = querystring.stringify(this.query); + } + + var search = this.search || (query && ('?' + query)) || ''; + + if (protocol && protocol.substr(-1) !== ':') protocol += ':'; + + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (this.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; + + pathname = pathname.replace(/[?#]/g, function(match) { + return encodeURIComponent(match); + }); + search = search.replace('#', '%23'); + + return protocol + host + pathname + search + hash; +}; + +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} + +Url.prototype.resolve = function(relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; + +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} + +Url.prototype.resolveObject = function(relative) { + if (isString(relative)) { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } + + var result = new Url(); + Object.keys(this).forEach(function(k) { + result[k] = this[k]; + }, this); + + // hash is always overridden, no matter what. + // even href="" will remove it. + result.hash = relative.hash; + + // if the relative url is empty, then there's nothing left to do here. + if (relative.href === '') { + result.href = result.format(); + return result; + } + + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + Object.keys(relative).forEach(function(k) { + if (k !== 'protocol') + result[k] = relative[k]; + }); + + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[result.protocol] && + result.hostname && !result.pathname) { + result.path = result.pathname = '/'; + } + + result.href = result.format(); + return result; + } + + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + Object.keys(relative).forEach(function(k) { + result[k] = relative[k]; + }); + result.href = result.format(); + return result; + } + + result.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; + // to support http.request + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } + + var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (result.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = result.pathname && result.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = result.protocol && !slashedProtocol[result.protocol]; + + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + result.hostname = ''; + result.port = null; + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host; + else srcPath.unshift(result.host); + } + result.host = ''; + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + relative.host = null; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + result.host = (relative.host || relative.host === '') ? + relative.host : result.host; + result.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (!isNullOrUndefined(relative.search)) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + result.search = relative.search; + result.query = relative.query; + //to support http.request + if (!isNull(result.pathname) || !isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.href = result.format(); + return result; + } + + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; + //to support http.request + if (result.search) { + result.path = '/' + result.search; + } else { + result.path = null; + } + result.href = result.format(); + return result; + } + + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (result.host || relative.host) && (last === '.' || last === '..') || + last === ''); + + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + + if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { + srcPath.push(''); + } + + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); + + // put the host back + if (psychotic) { + result.hostname = result.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + + mustEndAbs = mustEndAbs || (result.host && srcPath.length); + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } + + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); + } + + //to support request.http + if (!isNull(result.pathname) || !isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; +}; + +Url.prototype.parseHost = function() { + var host = this.host; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); + } + host = host.substr(0, host.length - port.length); + } + if (host) this.hostname = host; +}; + +function isString(arg) { + return typeof arg === "string"; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isNull(arg) { + return arg === null; +} +function isNullOrUndefined(arg) { + return arg == null; +} + +},{"punycode":184,"querystring":187}],202:[function(require,module,exports){ +var indexOf = require('indexof'); + +var Object_keys = function (obj) { + if (Object.keys) return Object.keys(obj) + else { + var res = []; + for (var key in obj) res.push(key) + return res; + } +}; + +var forEach = function (xs, fn) { + if (xs.forEach) return xs.forEach(fn) + else for (var i = 0; i < xs.length; i++) { + fn(xs[i], i, xs); + } +}; + +var defineProp = (function() { + try { + Object.defineProperty({}, '_', {}); + return function(obj, name, value) { + Object.defineProperty(obj, name, { + writable: true, + enumerable: false, + configurable: true, + value: value + }) + }; + } catch(e) { + return function(obj, name, value) { + obj[name] = value; + }; + } +}()); + +var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function', +'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError', +'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError', +'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', +'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape']; + +function Context() {} +Context.prototype = {}; + +var Script = exports.Script = function NodeScript (code) { + if (!(this instanceof Script)) return new Script(code); + this.code = code; +}; + +Script.prototype.runInContext = function (context) { + if (!(context instanceof Context)) { + throw new TypeError("needs a 'context' argument."); + } + + var iframe = document.createElement('iframe'); + if (!iframe.style) iframe.style = {}; + iframe.style.display = 'none'; + + document.body.appendChild(iframe); + + var win = iframe.contentWindow; + var wEval = win.eval, wExecScript = win.execScript; + + if (!wEval && wExecScript) { + // win.eval() magically appears when this is called in IE: + wExecScript.call(win, 'null'); + wEval = win.eval; + } + + forEach(Object_keys(context), function (key) { + win[key] = context[key]; + }); + forEach(globals, function (key) { + if (context[key]) { + win[key] = context[key]; + } + }); + + var winKeys = Object_keys(win); + + var res = wEval.call(win, this.code); + + forEach(Object_keys(win), function (key) { + // Avoid copying circular objects like `top` and `window` by only + // updating existing context properties or new properties in the `win` + // that was only introduced after the eval. + if (key in context || indexOf(winKeys, key) === -1) { + context[key] = win[key]; + } + }); + + forEach(globals, function (key) { + if (!(key in context)) { + defineProp(context, key, win[key]); + } + }); + + document.body.removeChild(iframe); + + return res; +}; + +Script.prototype.runInThisContext = function () { + return eval(this.code); // maybe... +}; + +Script.prototype.runInNewContext = function (context) { + var ctx = Script.createContext(context); + var res = this.runInContext(ctx); + + forEach(Object_keys(ctx), function (key) { + context[key] = ctx[key]; + }); + + return res; +}; + +forEach(Object_keys(Script.prototype), function (name) { + exports[name] = Script[name] = function (code) { + var s = Script(code); + return s[name].apply(s, [].slice.call(arguments, 1)); + }; +}); + +exports.createScript = function (code) { + return exports.Script(code); +}; + +exports.createContext = Script.createContext = function (context) { + var copy = new Context(); + if(typeof context === 'object') { + forEach(Object_keys(context), function (key) { + copy[key] = context[key]; + }); + } + return copy; +}; + +},{"indexof":203}],203:[function(require,module,exports){ + +var indexOf = [].indexOf; + +module.exports = function(arr, obj){ + if (indexOf) return arr.indexOf(obj); + for (var i = 0; i < arr.length; ++i) { + if (arr[i] === obj) return i; + } + return -1; +}; +},{}],204:[function(require,module,exports){ +(function (global,__dirname){ +var E={},ca,process;if("undefined"!==typeof global&&global.window)module.exports=E,global.window.Olm=E,ca=function(F){window.crypto.getRandomValues(F)};else if("undefined"!==typeof window)window.Olm=E,ca=function(F){window.crypto.getRandomValues(F)};else if(module.exports){module.exports=E;var $a=require("crypto");ca=function(F){var v=$a.randomBytes(F.length);F.set(v)};process=global.process}else throw Error("Cannot find global to attach library to"); +(function(){function F(a){eval.call(null,a)}function v(a,b){a||L("Assertion failed: "+b)}function xa(g){var b=a["_"+g];if(!b)try{b=eval("_"+g)}catch(c){}v(b,"Cannot call unknown function "+g+" (perhaps LLVM optimizations or closure removed it?)");return b}function ya(a,b,c){c=c||"i8";"*"===c.charAt(c.length-1)&&(c="i32");switch(c){case "i1":w[a>>0]=b;break;case "i8":w[a>>0]=b;break;case "i16":da[a>>1]=b;break;case "i32":q[a>>2]=b;break;case "i64":tempI64=[b>>>0,(tempDouble=b,1<=+ab(tempDouble)?0< +tempDouble?(bb(+cb(tempDouble/4294967296),4294967295)|0)>>>0:~~+db((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)];q[a>>2]=tempI64[0];q[a+4>>2]=tempI64[1];break;case "float":ea[a>>2]=b;break;case "double":fa[a>>3]=b;break;default:L("invalid type for setValue: "+c)}}function za(a,b){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return w[a>>0];case "i8":return w[a>>0];case "i16":return da[a>>1];case "i32":return q[a>>2];case "i64":return q[a>>2];case "float":return ea[a>> +2];case "double":return fa[a>>3];default:L("invalid type for setValue: "+b)}return null}function G(a,b,c,e){var d,r;"number"===typeof a?(d=!0,r=a):(d=!1,r=a.length);var l="string"===typeof b?b:null;c=4==c?e:["function"===typeof S?S:f.p,f.j,f.p,f.e][void 0===c?2:c](Math.max(r,l?1:b.length));if(d){e=c;v(0==(c&3));for(a=c+(r&-4);e>2]=0;for(a=c+r;e>0]=0;return c}if("i8"===l)return a.subarray||a.slice?x.set(a,c):x.set(new Uint8Array(a),c),c;e=0;for(var h,Aa;e>0];c|=e;if(0==e&&!b)break;d++;if(b&&d==b)break}b||(b=d);e="";if(128>c){for(;0c?h+=String.fromCharCode(c):(c-=65536,h+=String.fromCharCode(55296|c>>10,56320|c&1023)))):h+=String.fromCharCode(c)}}function pa(a,b,c,e){if(!(0=l&&(l=65536+((l&1023)<<10)|a.charCodeAt(++h)& +1023);if(127>=l){if(c>=e)break;b[c++]=l}else{if(2047>=l){if(c+1>=e)break;b[c++]=192|l>>6}else{if(65535>=l){if(c+2>=e)break;b[c++]=224|l>>12}else{if(2097151>=l){if(c+3>=e)break;b[c++]=240|l>>18}else{if(67108863>=l){if(c+4>=e)break;b[c++]=248|l>>24}else{if(c+5>=e)break;b[c++]=252|l>>30;b[c++]=128|l>>24&63}b[c++]=128|l>>18&63}b[c++]=128|l>>12&63}b[c++]=128|l>>6&63}b[c++]=128|l&63}}b[c]=0;return c-d}function Ca(a){for(var b=0,c=0;c=e&&(e=65536+((e& +1023)<<10)|a.charCodeAt(++c)&1023);127>=e?++b:b=2047>=e?b+2:65535>=e?b+3:2097151>=e?b+4:67108863>=e?b+5:b+6}return b}function eb(g){return g.replace(/__Z[\w\d_]+/g,function(b){var c;a:{if(a.___cxa_demangle)try{var g=S(b.length);qa(b.substr(1),g);var d=S(4),h=a.___cxa_demangle(g,0,0,d);if(0===za(d,"i32")&&h){c=n(h);break a}}catch(l){c=b;break a}finally{g&&ra(g),d&&ra(d),h&&ra(h)}f.g("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");c=b}return b===c?b:b+" ["+c+"]"})}function Da(){var a= +eb,b;a:{b=Error();if(!b.stack){try{throw Error(0);}catch(c){b=c}if(!b.stack){b="(no stack trace available)";break a}}b=b.stack.toString()}return a(b)}function fb(a){0>0]=a[c],c+=1}function Ia(a,b){for(var c=0;c>0]=a[c]}function Ja(a,b,c){for(var e=0;e>0]=a.charCodeAt(e);c||(w[b>>0]=0)}function Ka(g){a.___errno_location&&(q[a.___errno_location()>>2]=g);return g}function ha(a){var b=ha;b.b||(A=fb(A),b.b=!0,v(f.e),b.v=f.e,f.e=function(){L("cannot dynamically allocate, sbrk now has control")});var c=A;return 0==a||b.v(a)?c:4294967295}function sa(){var a= +sa;a.b||(a.b=[]);a.b.push(f.f());return a.b.length-1}function O(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}function ta(g){function b(){if(!a.calledRun&&(a.calledRun=!0,!ia)){T||(T=!0,N(ja));N(La);if(a.onRuntimeInitialized)a.onRuntimeInitialized();a._main&&Ma&&a.callMain(g);if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)Ga(a.postRun.shift());N(Ha)}}g=g||a.arguments;null===Na&&(Na=Date.now());if(!(0 0) var gc = undefined");else if(Z||Q)a.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);return b.responseText},a.readAsync=function(a,b,c){var e= +new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=function(){200==e.status||0==e.status&&e.response?b(e.response):c()};e.onerror=c;e.send(null)},"undefined"!=typeof arguments&&(a.arguments=arguments),"undefined"!==typeof console?(a.print||(a.print=function(a){console.log(a)}),a.printErr||(a.printErr=function(a){console.warn(a)})):a.print||(a.print=function(){}),Q&&(a.load=importScripts),"undefined"===typeof a.setWindowTitle&&(a.setWindowTitle=function(a){document.title=a}); +else throw"Unknown runtime environment. Where are we?";!a.load&&a.read&&(a.load=function(g){F(a.read(g))});a.print||(a.print=function(){});a.printErr||(a.printErr=a.print);a.arguments||(a.arguments=[]);a.thisProgram||(a.thisProgram="./this.program");a.print=a.print;a.o=a.printErr;a.preRun=[];a.postRun=[];for(K in Y)Y.hasOwnProperty(K)&&(a[K]=Y[K]);var Y=void 0,f={C:function(a){tempRet0=a},A:function(){return tempRet0},f:function(){return C},d:function(a){C=a},r:function(a){switch(a){case "i1":case "i8":return 1; +case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?f.k:"i"===a[0]?(a=parseInt(a.substr(1)),v(0===a%8),a/8):0}},w:function(a){return Math.max(f.r(a),f.k)},D:16,R:function(a,b){"double"===b||"i64"===b?a&7&&(v(4===(a&7)),a+=4):v(0===(a&3));return a},L:function(a,b,c){return c||"i64"!=a&&"double"!=a?a?Math.min(b||(a?f.w(a):0),f.k):Math.min(b,8):8},m:function(g,b,c){return c&&c.length?(c.splice||(c=Array.prototype.slice.call(c)), +c.splice(0,0,b),a["dynCall_"+g].apply(null,c)):a["dynCall_"+g].call(null,b)},i:[],s:function(a){for(var b=0;b=R)L("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+R+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which adjusts the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 "), +a=!0;return a?(A=b,0):b},q:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},Q:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296*+(b|0)},h:8,k:4,F:0};a.Runtime=f;f.addFunction=f.s;f.removeFunction=f.B;var ia=!1,Sa,Ta;(function(){function a(b){b=b.toString().match(d).slice(1);return{arguments:b[0],body:b[1],returnValue:b[2]}}function b(){if(!h){h={};for(var b in c)c.hasOwnProperty(b)&&(h[b]=a(c[b]))}}var c={stackSave:function(){f.f()},stackRestore:function(){f.d()},arrayToC:function(a){var b= +f.j(a.length);Ia(a,b);return b},stringToC:function(a){var b=0;null!==a&&void 0!==a&&0!==a&&(b=f.j((a.length<<2)+1),qa(a,b));return b}},e={string:c.stringToC,array:c.arrayToC};Ta=function(a,b,c,g,d){a=xa(a);var h=[],J=0;if(g)for(var r=0;r>0];if(!c)return b;b+=String.fromCharCode(c)}};a.stringToAscii=function(a, +b){return Ja(a,b,!1)};a.UTF8ArrayToString=Ba;a.UTF8ToString=function(a){return Ba(x,a)};a.stringToUTF8Array=pa;a.stringToUTF8=function(a,b,c){return pa(a,x,b,c)};a.lengthBytesUTF8=Ca;a.stackTrace=Da;for(var u,w,x,da,Va,q,Wa,ea,fa,Xa=0,D=0,Ua=!1,Ya=0,C=0,va=0,A=0,Za=a.TOTAL_STACK||5242880,R=a.TOTAL_MEMORY||16777216,I=65536;II?2*I:I+16777216;I!==R&&(R=I);a.buffer?u=a.buffer:u=new ArrayBuffer(R);a.HEAP8=w=new Int8Array(u);a.HEAP16=da=new Int16Array(u);a.HEAP32=q=new Int32Array(u); +a.HEAPU8=x=new Uint8Array(u);a.HEAPU16=Va=new Uint16Array(u);a.HEAPU32=Wa=new Uint32Array(u);a.HEAPF32=ea=new Float32Array(u);a.HEAPF64=fa=new Float64Array(u);q[0]=255;if(255!==x[0]||0!==x[3])throw"Typed arrays 2 must be run on a little-endian system";a.HEAP=void 0;a.buffer=u;a.HEAP8=w;a.HEAP16=da;a.HEAP32=q;a.HEAPU8=x;a.HEAPU16=Va;a.HEAPU32=Wa;a.HEAPF32=ea;a.HEAPF64=fa;var Fa=[],ja=[],La=[],Pa=[],Ha=[],T=!1;a.addOnPreRun=Ea;a.addOnInit=function(a){ja.unshift(a)};a.addOnPreMain=function(a){La.unshift(a)}; +a.addOnExit=function(a){Pa.unshift(a)};a.addOnPostRun=Ga;a.intArrayFromString=ga;a.intArrayToString=function(a){for(var b=[],c=0;c>>16)*e+c*(b>>>16)<<16)|0});Math.P=Math.imul;Math.clz32||(Math.clz32=function(a){a=a>>>0;for(var b=0;32> +b;b++)if(a&1<<31-b)return b;return 32});Math.I=Math.clz32;var ab=Math.abs,db=Math.ceil,cb=Math.floor,bb=Math.min,M=0,wa=null,aa=null;a.addRunDependency=function(){M++;a.monitorRunDependencies&&a.monitorRunDependencies(M)};a.removeRunDependency=function(){M--;a.monitorRunDependencies&&a.monitorRunDependencies(M);if(0==M&&(null!==wa&&(clearInterval(wa),wa=null),aa)){var d=aa;aa=null;d()}};a.preloadedImages={};a.preloadedAudios={};Xa=8;D=Xa+36080;ja.push();G([34,174,40,215,152,47,138,66,205,101,239, +35,145,68,55,113,47,59,77,236,207,251,192,181,188,219,137,129,165,219,181,233,56,181,72,243,91,194,86,57,25,208,5,182,241,17,241,89,155,79,25,175,164,130,63,146,24,129,109,218,213,94,28,171,66,2,3,163,152,170,7,216,190,111,112,69,1,91,131,18,140,178,228,78,190,133,49,36,226,180,255,213,195,125,12,85,111,137,123,242,116,93,190,114,177,150,22,59,254,177,222,128,53,18,199,37,167,6,220,155,148,38,105,207,116,241,155,193,210,74,241,158,193,105,155,228,227,37,79,56,134,71,190,239,181,213,140,139,198,157, +193,15,101,156,172,119,204,161,12,36,117,2,43,89,111,44,233,45,131,228,166,110,170,132,116,74,212,251,65,189,220,169,176,92,181,83,17,131,218,136,249,118,171,223,102,238,82,81,62,152,16,50,180,45,109,198,49,168,63,33,251,152,200,39,3,176,228,14,239,190,199,127,89,191,194,143,168,61,243,11,224,198,37,167,10,147,71,145,167,213,111,130,3,224,81,99,202,6,112,110,14,10,103,41,41,20,252,47,210,70,133,10,183,39,38,201,38,92,56,33,27,46,237,42,196,90,252,109,44,77,223,179,149,157,19,13,56,83,222,99,175,139, +84,115,10,101,168,178,119,60,187,10,106,118,230,174,237,71,46,201,194,129,59,53,130,20,133,44,114,146,100,3,241,76,161,232,191,162,1,48,66,188,75,102,26,168,145,151,248,208,112,139,75,194,48,190,84,6,163,81,108,199,24,82,239,214,25,232,146,209,16,169,101,85,36,6,153,214,42,32,113,87,133,53,14,244,184,209,187,50,112,160,106,16,200,208,210,184,22,193,164,25,83,171,65,81,8,108,55,30,153,235,142,223,76,119,72,39,168,72,155,225,181,188,176,52,99,90,201,197,179,12,28,57,203,138,65,227,74,170,216,78,115, +227,99,119,79,202,156,91,163,184,178,214,243,111,46,104,252,178,239,93,238,130,143,116,96,47,23,67,111,99,165,120,114,171,240,161,20,120,200,132,236,57,100,26,8,2,199,140,40,30,99,35,250,255,190,144,233,189,130,222,235,108,80,164,21,121,198,178,247,163,249,190,43,83,114,227,242,120,113,198,156,97,38,234,206,62,39,202,7,194,192,33,199,184,134,209,30,235,224,205,214,125,218,234,120,209,110,238,127,79,125,245,186,111,23,114,170,103,240,6,166,152,200,162,197,125,99,10,174,13,249,190,4,152,63,17,27,71, +28,19,53,11,113,27,132,125,4,35,245,119,219,40,147,36,199,64,123,171,202,50,188,190,201,21,10,190,158,60,76,13,16,156,196,103,29,67,182,66,62,203,190,212,197,76,42,126,101,252,156,41,127,89,236,250,214,58,171,111,203,95,23,88,71,74,140,25,68,108,68,129,0,0,8,0,0,0,77,129,0,0,11,0,0,0,168,2,0,0,89,129,0,0,8,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,1,0,0,0,89,241,178,254,10,229,166,255,123,221,42,254,30,20,212,0,82,128,3,0,48,209,243,0,119,121,64,255,50,227,156,255,0,110,197,1,103,27,144, +0,133,59,140,1,189,241,36,255,248,37,195,1,96,220,55,0,183,76,62,255,195,66,61,0,50,76,164,1,225,164,76,255,76,61,163,255,117,62,31,0,81,145,64,255,118,65,14,0,162,115,214,255,6,138,46,0,124,230,244,255,10,138,143,0,52,26,194,0,184,244,76,0,129,143,41,1,190,244,19,255,123,170,122,255,98,129,68,0,121,213,147,0,86,101,30,255,161,103,155,0,140,89,67,255,239,229,190,1,67,11,181,0,198,240,137,254,238,69,188,255,67,151,238,0,19,42,108,255,229,85,113,1,50,68,135,255,17,106,9,0,50,103,1,255,80,1,168,1,35, +152,30,255,16,168,185,1,56,89,232,255,101,210,252,0,41,250,71,0,204,170,79,255,14,46,239,255,80,77,239,0,189,214,75,255,17,141,249,0,38,80,76,255,190,85,117,0,86,228,170,0,156,216,208,1,195,207,164,255,150,66,76,255,175,225,16,255,141,80,98,1,76,219,242,0,198,162,114,0,46,218,152,0,155,43,241,254,155,160,104,255,51,187,165,0,2,17,175,0,66,84,160,1,247,58,30,0,35,65,53,254,69,236,191,0,45,134,245,1,163,123,221,0,32,110,20,255,52,23,165,0,186,214,71,0,233,176,96,0,242,239,54,1,57,89,138,0,83,0,84,255, +136,160,100,0,92,142,120,254,104,124,190,0,181,177,62,255,250,41,85,0,152,130,42,1,96,252,246,0,151,151,63,254,239,133,62,0,32,56,156,0,45,167,189,255,142,133,179,1,131,86,211,0,187,179,150,254,250,170,14,255,210,163,78,0,37,52,151,0,99,77,26,0,238,156,213,255,213,192,209,1,73,46,84,0,20,65,41,1,54,206,79,0,201,131,146,254,170,111,24,255,177,33,50,254,171,38,203,255,78,247,116,0,209,221,153,0,133,128,178,1,58,44,25,0,201,39,59,1,189,19,252,0,49,229,210,1,117,187,117,0,181,179,184,1,0,114,219,0,48, +94,147,0,245,41,56,0,125,13,204,254,244,173,119,0,44,221,32,254,84,234,20,0,249,160,198,1,236,126,234,255,47,99,168,254,170,226,153,255,102,179,216,0,226,141,122,255,122,66,153,254,182,245,134,0,227,228,25,1,214,57,235,255,216,173,56,255,181,231,210,0,119,128,157,255,129,95,136,255,110,126,51,0,2,169,183,255,7,130,98,254,69,176,94,255,116,4,227,1,217,242,145,255,202,173,31,1,105,1,39,255,46,175,69,0,228,47,58,255,215,224,69,254,207,56,69,255,16,254,139,255,23,207,212,255,202,20,126,255,95,213,96, +255,9,176,33,0,200,5,207,255,241,42,128,254,35,33,192,255,248,229,196,1,129,17,120,0,251,103,151,255,7,52,112,255,140,56,66,255,40,226,245,255,217,70,37,254,172,214,9,255,72,67,134,1,146,192,214,255,44,38,112,0,68,184,75,255,206,90,251,0,149,235,141,0,181,170,58,0,116,244,239,0,92,157,2,0,102,173,98,0,233,137,96,1,127,49,203,0,5,155,148,0,23,148,9,255,211,122,12,0,34,134,26,255,219,204,136,0,134,8,41,255,224,83,43,254,85,25,247,0,109,127,0,254,169,136,48,0,238,119,219,255,231,173,213,0,206,18,254, +254,8,186,7,255,126,9,7,1,111,42,72,0,111,52,236,254,96,63,141,0,147,191,127,254,205,78,192,255,14,106,237,1,187,219,76,0,175,243,187,254,105,89,173,0,85,25,89,1,162,243,148,0,2,118,209,254,33,158,9,0,139,163,46,255,93,70,40,0,108,42,142,254,111,252,142,255,155,223,144,0,51,229,167,255,73,252,155,255,94,116,12,255,152,160,218,255,156,238,37,255,179,234,207,255,197,0,179,255,154,164,141,0,225,196,104,0,10,35,25,254,209,212,242,255,97,253,222,254,184,101,229,0,222,18,127,1,164,136,135,255,30,207,140, +254,146,97,243,0,129,192,26,254,201,84,33,255,111,10,78,255,147,81,178,255,4,4,24,0,161,238,215,255,6,141,33,0,53,215,14,255,41,181,208,255,231,139,157,0,179,203,221,255,255,185,113,0,189,226,172,255,113,66,214,255,202,62,45,255,102,64,8,255,78,174,16,254,133,117,68,255,182,120,89,255,133,114,211,0,189,110,21,255,15,10,106,0,41,192,1,0,152,232,121,255,188,60,160,255,153,113,206,255,0,183,226,254,180,13,72,255,176,160,14,254,211,201,134,255,158,24,143,0,127,105,53,0,96,12,189,0,167,215,251,255,159, +76,128,254,106,101,225,255,30,252,4,0,146,12,174,0,133,59,140,1,189,241,36,255,248,37,195,1,96,220,55,0,183,76,62,255,195,66,61,0,50,76,164,1,225,164,76,255,76,61,163,255,117,62,31,0,81,145,64,255,118,65,14,0,162,115,214,255,6,138,46,0,124,230,244,255,10,138,143,0,52,26,194,0,184,244,76,0,129,143,41,1,190,244,19,255,123,170,122,255,98,129,68,0,121,213,147,0,86,101,30,255,161,103,155,0,140,89,67,255,239,229,190,1,67,11,181,0,198,240,137,254,238,69,188,255,234,113,60,255,37,255,57,255,69,178,182,254, +128,208,179,0,118,26,125,254,3,7,214,255,241,50,77,255,85,203,197,255,211,135,250,255,25,48,100,255,187,213,180,254,17,88,105,0,83,209,158,1,5,115,98,0,4,174,60,254,171,55,110,255,217,181,17,255,20,188,170,0,146,156,102,254,87,214,174,255,114,122,155,1,233,44,170,0,127,8,239,1,214,236,234,0,175,5,219,0,49,106,61,255,6,66,208,255,2,106,110,255,81,234,19,255,215,107,192,255,67,151,238,0,19,42,108,255,229,85,113,1,50,68,135,255,17,106,9,0,50,103,1,255,80,1,168,1,35,152,30,255,16,168,185,1,56,89,232, +255,101,210,252,0,41,250,71,0,204,170,79,255,14,46,239,255,80,77,239,0,189,214,75,255,17,141,249,0,38,80,76,255,190,85,117,0,86,228,170,0,156,216,208,1,195,207,164,255,150,66,76,255,175,225,16,255,141,80,98,1,76,219,242,0,198,162,114,0,46,218,152,0,155,43,241,254,155,160,104,255,178,9,252,254,100,110,212,0,14,5,167,0,233,239,163,255,28,151,157,1,101,146,10,255,254,158,70,254,71,249,228,0,88,30,50,0,68,58,160,255,191,24,104,1,129,66,129,255,192,50,85,255,8,179,138,255,38,250,201,0,115,80,160,0,131, +230,113,0,125,88,147,0,90,68,199,0,253,76,158,0,28,255,118,0,113,250,254,0,66,75,46,0,230,218,43,0,229,120,186,1,148,68,43,0,136,124,238,1,187,107,197,255,84,53,246,255,51,116,254,255,51,187,165,0,2,17,175,0,66,84,160,1,247,58,30,0,35,65,53,254,69,236,191,0,45,134,245,1,163,123,221,0,32,110,20,255,52,23,165,0,186,214,71,0,233,176,96,0,242,239,54,1,57,89,138,0,83,0,84,255,136,160,100,0,92,142,120,254,104,124,190,0,181,177,62,255,250,41,85,0,152,130,42,1,96,252,246,0,151,151,63,254,239,133,62,0,32, +56,156,0,45,167,189,255,142,133,179,1,131,86,211,0,187,179,150,254,250,170,14,255,68,113,21,255,222,186,59,255,66,7,241,1,69,6,72,0,86,156,108,254,55,167,89,0,109,52,219,254,13,176,23,255,196,44,106,255,239,149,71,255,164,140,125,255,159,173,1,0,51,41,231,0,145,62,33,0,138,111,93,1,185,83,69,0,144,115,46,0,97,151,16,255,24,228,26,0,49,217,226,0,113,75,234,254,193,153,12,255,182,48,96,255,14,13,26,0,128,195,249,254,69,193,59,0,132,37,81,254,125,106,60,0,214,240,169,1,164,227,66,0,210,163,78,0,37,52, +151,0,99,77,26,0,238,156,213,255,213,192,209,1,73,46,84,0,20,65,41,1,54,206,79,0,201,131,146,254,170,111,24,255,177,33,50,254,171,38,203,255,78,247,116,0,209,221,153,0,133,128,178,1,58,44,25,0,201,39,59,1,189,19,252,0,49,229,210,1,117,187,117,0,181,179,184,1,0,114,219,0,48,94,147,0,245,41,56,0,125,13,204,254,244,173,119,0,44,221,32,254,84,234,20,0,249,160,198,1,236,126,234,255,143,62,221,0,129,89,214,255,55,139,5,254,68,20,191,255,14,204,178,1,35,195,217,0,47,51,206,1,38,246,165,0,206,27,6,254,158, +87,36,0,217,52,146,255,125,123,215,255,85,60,31,255,171,13,7,0,218,245,88,254,252,35,60,0,55,214,160,255,133,101,56,0,224,32,19,254,147,64,234,0,26,145,162,1,114,118,125,0,248,252,250,0,101,94,196,255,198,141,226,254,51,42,182,0,135,12,9,254,109,172,210,255,197,236,194,1,241,65,154,0,48,156,47,255,153,67,55,255,218,165,34,254,74,180,179,0,218,66,71,1,88,122,99,0,212,181,219,255,92,42,231,255,239,0,154,0,245,77,183,255,94,81,170,1,18,213,216,0,171,93,71,0,52,94,248,0,18,151,161,254,197,209,66,255, +174,244,15,254,162,48,183,0,49,61,240,254,182,93,195,0,199,228,6,1,200,5,17,255,137,45,237,255,108,148,4,0,90,79,237,255,39,63,77,255,53,82,207,1,142,22,118,255,101,232,18,1,92,26,67,0,5,200,88,255,33,168,138,255,149,225,72,0,2,209,27,255,44,245,168,1,220,237,17,255,30,211,105,254,141,238,221,0,128,80,245,254,111,254,14,0,222,95,190,1,223,9,241,0,146,76,212,255,108,205,104,255,63,117,153,0,144,69,48,0,35,228,111,0,192,33,193,255,112,214,190,254,115,152,151,0,23,102,88,0,51,74,248,0,226,199,143,254, +204,162,101,255,208,97,189,1,245,104,18,0,230,246,30,255,23,148,69,0,110,88,52,254,226,181,89,255,208,47,90,254,114,161,80,255,33,116,248,0,179,152,87,255,69,144,177,1,88,238,26,255,58,32,113,1,1,77,69,0,59,121,52,255,152,238,83,0,52,8,193,0,231,39,233,255,199,34,138,0,222,68,173,0,91,57,242,254,220,210,127,255,192,7,246,254,151,35,187,0,195,236,165,0,111,93,206,0,212,247,133,1,154,133,209,255,155,231,10,0,64,78,38,0,122,249,100,1,30,19,97,255,62,91,249,1,248,133,77,0,197,63,168,254,116,10,82,0,184, +236,113,254,212,203,194,255,61,100,252,254,36,5,202,255,119,91,153,255,129,79,29,0,103,103,171,254,237,215,111,255,216,53,69,0,239,240,23,0,194,149,221,255,38,225,222,0,232,255,180,254,118,82,133,255,57,209,177,1,139,232,133,0,158,176,46,254,194,115,46,0,88,247,229,1,28,103,191,0,221,222,175,254,149,235,44,0,151,228,25,254,218,105,103,0,142,85,210,0,149,129,190,255,213,65,94,254,117,134,224,255,82,198,117,0,157,221,220,0,163,101,36,0,197,114,37,0,104,172,166,254,11,182,0,0,81,72,188,255,97,188,16, +255,69,6,10,0,199,147,145,255,8,9,115,1,65,214,175,255,217,173,209,0,80,127,166,0,247,229,4,254,167,183,124,255,90,28,204,254,175,59,240,255,11,41,248,1,108,40,51,255,144,177,195,254,150,250,126,0,138,91,65,1,120,60,222,255,245,193,239,0,29,214,189,255,128,2,25,0,80,154,162,0,77,220,107,1,234,205,74,255,54,166,103,255,116,72,9,0,228,94,47,255,30,200,25,255,35,214,89,255,61,176,140,255,83,226,163,255,75,130,172,0,128,38,17,0,95,137,152,255,215,124,159,1,79,93,0,0,148,82,157,254,195,130,251,255,40, +202,76,255,251,126,224,0,157,99,62,254,207,7,225,255,96,68,195,0,140,186,157,255,131,19,231,255,42,128,254,0,52,219,61,254,102,203,72,0,141,7,11,255,186,164,213,0,31,122,119,0,133,242,145,0,208,252,232,255,91,213,182,255,143,4,250,254,249,215,74,0,165,30,111,1,171,9,223,0,229,123,34,1,92,130,26,255,77,155,45,1,195,139,28,255,59,224,78,0,136,17,247,0,108,121,32,0,79,250,189,255,96,227,252,254,38,241,62,0,62,174,125,255,155,111,93,255,10,230,206,1,97,197,40,255,0,49,57,254,65,250,13,0,18,251,150,255, +220,109,210,255,5,174,166,254,44,129,189,0,235,35,147,255,37,247,141,255,72,141,4,255,103,107,255,0,247,90,4,0,53,44,42,0,2,30,240,0,4,59,63,0,88,78,36,0,113,167,180,0,190,71,193,255,199,158,164,255,58,8,172,0,77,33,12,0,65,63,3,0,153,77,33,255,172,254,102,1,228,221,4,255,87,30,254,1,146,41,86,255,138,204,239,254,108,141,17,255,187,242,135,0,210,208,127,0,68,45,14,254,73,96,62,0,81,60,24,255,170,6,36,255,3,249,26,0,35,213,109,0,22,129,54,255,21,35,225,255,234,61,56,255,58,217,6,0,143,124,88,0,236, +126,66,0,209,38,183,255,34,238,6,255,174,145,102,0,95,22,211,0,196,15,153,254,46,84,232,255,117,34,146,1,231,250,74,255,27,134,100,1,92,187,195,255,170,198,112,0,120,28,42,0,209,70,67,0,29,81,31,0,29,168,100,1,169,173,160,0,107,35,117,0,62,96,59,255,81,12,69,1,135,239,190,255,220,252,18,0,163,220,58,255,137,137,188,255,83,102,109,0,96,6,76,0,234,222,210,255,185,174,205,1,60,158,213,255,13,241,214,0,172,129,140,0,93,104,242,0,192,156,251,0,43,117,30,0,225,81,158,0,127,232,218,0,226,28,203,0,233,27, +151,255,117,43,5,255,242,14,47,255,33,20,6,0,137,251,44,254,27,31,245,255,183,214,125,254,40,121,149,0,186,158,213,255,89,8,227,0,69,88,0,254,203,135,225,0,201,174,203,0,147,71,184,0,18,121,41,254,94,5,78,0,224,214,240,254,36,5,180,0,251,135,231,1,163,138,212,0,210,249,116,254,88,129,187,0,19,8,49,254,62,14,144,255,159,76,211,0,214,51,82,0,109,117,228,254,103,223,203,255,75,252,15,1,154,71,220,255,23,13,91,1,141,168,96,255,181,182,133,0,250,51,55,0,234,234,212,254,175,63,158,0,39,240,52,1,158,189, +36,255,213,40,85,1,32,180,247,255,19,102,26,1,84,24,97,255,69,21,222,0,148,139,122,255,220,213,235,1,232,203,255,0,121,57,147,0,227,7,154,0,53,22,147,1,72,1,225,0,82,134,48,254,83,60,157,255,145,72,169,0,34,103,239,0,198,233,47,0,116,19,4,255,184,106,9,255,183,129,83,0,36,176,230,1,34,103,72,0,219,162,134,0,245,42,158,0,32,149,96,254,165,44,144,0,202,239,72,254,215,150,5,0,42,66,36,1,132,215,175,0,86,174,86,255,26,197,156,255,49,232,135,254,103,182,82,0,253,128,176,1,153,178,122,0,245,250,10,0,236, +24,178,0,137,106,132,0,40,29,41,0,50,30,152,255,124,105,38,0,230,191,75,0,143,43,170,0,44,131,20,255,44,13,23,255,237,255,155,1,159,109,100,255,112,181,24,255,104,220,108,0,55,211,131,0,99,12,213,255,152,151,145,255,238,5,159,0,97,155,8,0,33,108,81,0,1,3,103,0,62,109,34,255,250,155,180,0,32,71,195,255,38,70,145,1,159,95,245,0,69,229,101,1,136,28,240,0,79,224,25,0,78,110,121,255,248,168,124,0,187,128,247,0,2,147,235,254,79,11,132,0,70,58,12,1,181,8,163,255,79,137,133,255,37,170,11,255,141,243,85,255, +176,231,215,255,204,150,164,255,239,215,39,255,46,87,156,254,8,163,88,255,172,34,232,0,66,44,102,255,27,54,41,254,236,99,87,255,41,123,169,1,52,114,43,0,117,134,40,0,155,134,26,0,231,207,91,254,35,132,38,255,19,102,125,254,36,227,133,255,118,3,113,255,29,13,124,0,152,96,74,1,88,146,206,255,167,191,220,254,162,18,88,255,182,100,23,0,31,117,52,0,81,46,106,1,12,2,7,0,69,80,201,1,209,246,172,0,12,48,141,1,224,211,88,0,116,226,159,0,122,98,130,0,65,236,234,1,225,226,9,255,207,226,123,1,89,214,59,0,112, +135,88,1,90,244,203,255,49,11,38,1,129,108,186,0,89,112,15,1,101,46,204,255,127,204,45,254,79,255,221,255,51,73,18,255,127,42,101,255,241,21,202,0,160,227,7,0,105,50,236,0,79,52,197,255,104,202,208,1,180,15,16,0,101,197,78,255,98,77,203,0,41,185,241,1,35,193,124,0,35,155,23,255,207,53,192,0,11,125,163,1,249,158,185,255,4,131,48,0,21,93,111,255,61,121,231,1,69,200,36,255,185,48,185,255,111,238,21,255,39,50,25,255,99,215,163,255,87,212,30,255,164,147,5,255,128,6,35,1,108,223,110,255,194,76,178,0,74, +101,180,0,243,47,48,0,174,25,43,255,82,173,253,1,54,114,192,255,40,55,91,0,215,108,176,255,11,56,7,0,224,233,76,0,209,98,202,254,242,25,125,0,44,193,93,254,203,8,177,0,135,176,19,0,112,71,213,255,206,59,176,1,4,67,26,0,14,143,213,254,42,55,208,255,60,67,120,0,193,21,163,0,99,164,115,0,10,20,118,0,156,212,222,254,160,7,217,255,114,245,76,1,117,59,123,0,176,194,86,254,213,15,176,0,78,206,207,254,213,129,59,0,233,251,22,1,96,55,152,255,236,255,15,255,197,89,84,255,93,149,133,0,174,160,113,0,234,99,169, +255,152,116,88,0,144,164,83,255,95,29,198,255,34,47,15,255,99,120,134,255,5,236,193,0,249,247,126,255,147,187,30,0,50,230,117,255,108,217,219,255,163,81,166,255,72,25,169,254,155,121,79,255,28,155,89,254,7,126,17,0,147,65,33,1,47,234,253,0,26,51,18,0,105,83,199,255,163,196,230,0,113,248,164,0,226,254,218,0,189,209,203,255,164,247,222,254,255,35,165,0,4,188,243,1,127,179,71,0,37,237,254,255,100,186,240,0,5,57,71,254,103,72,73,255,244,18,81,254,229,210,132,255,238,6,180,255,11,229,174,255,227,221,192, +1,17,49,28,0,163,215,196,254,9,118,4,255,51,240,71,0,113,129,109,255,76,240,231,0,188,177,127,0,125,71,44,1,26,175,243,0,94,169,25,254,27,230,29,0,15,139,119,1,168,170,186,255,172,197,76,255,252,75,188,0,137,124,196,0,72,22,96,255,45,151,249,1,220,145,100,0,64,192,159,255,120,239,226,0,129,178,146,0,0,192,125,0,235,138,234,0,183,157,146,0,83,199,192,255,184,172,72,255,73,225,128,0,77,6,250,255,186,65,67,0,104,246,207,0,188,32,138,255,218,24,242,0,67,138,81,254,237,129,121,255,20,207,150,1,41,199, +16,255,6,20,128,0,159,118,5,0,181,16,143,255,220,38,15,0,23,64,147,254,73,26,13,0,87,228,57,1,204,124,128,0,43,24,223,0,219,99,199,0,22,75,20,255,19,27,126,0,157,62,215,0,110,29,230,0,179,167,255,1,54,252,190,0,221,204,182,254,179,158,65,255,81,157,3,0,194,218,159,0,170,223,0,0,224,11,32,255,38,197,98,0,168,164,37,0,23,88,7,1,164,186,110,0,96,36,134,0,234,242,229,0,250,121,19,0,242,254,112,255,3,47,94,1,9,239,6,255,81,134,153,254,214,253,168,255,67,124,224,0,245,95,74,0,28,30,44,254,1,109,220,255, +178,89,89,0,252,36,76,0,24,198,46,255,76,77,111,0,134,234,136,255,39,94,29,0,185,72,234,255,70,68,135,255,231,102,7,254,77,231,140,0,167,47,58,1,148,97,118,255,16,27,225,1,166,206,143,255,110,178,214,255,180,131,162,0,143,141,225,1,13,218,78,255,114,153,33,1,98,104,204,0,175,114,117,1,167,206,75,0,202,196,83,1,58,64,67,0,138,47,111,1,196,247,128,255,137,224,224,254,158,112,207,0,154,100,255,1,134,37,107,0,198,128,79,255,127,209,155,255,163,254,185,254,60,14,243,0,31,219,112,254,29,217,65,0,200,13, +116,254,123,60,196,255,224,59,184,254,242,89,196,0,123,16,75,254,149,16,206,0,69,254,48,1,231,116,223,255,209,160,65,1,200,80,98,0,37,194,184,254,148,63,34,0,139,240,65,255,217,144,132,255,56,38,45,254,199,120,210,0,108,177,166,255,160,222,4,0,220,126,119,254,165,107,160,255,82,220,248,1,241,175,136,0,144,141,23,255,169,138,84,0,160,137,78,255,226,118,80,255,52,27,132,255,63,96,139,255,152,250,39,0,188,155,15,0,232,51,150,254,40,15,232,255,240,229,9,255,137,175,27,255,75,73,97,1,218,212,11,0,135, +5,162,1,107,185,213,0,2,249,107,255,40,242,70,0,219,200,25,0,25,157,13,0,67,82,80,255,196,249,23,255,145,20,149,0,50,72,146,0,94,76,148,1,24,251,65,0,31,192,23,0,184,212,201,255,123,233,162,1,247,173,72,0,162,87,219,254,126,134,89,0,159,11,12,254,166,105,29,0,73,27,228,1,113,120,183,255,66,163,109,1,212,143,11,255,159,231,168,1,255,128,90,0,57,14,58,254,89,52,10,255,253,8,163,1,0,145,210,255,10,129,85,1,46,181,27,0,103,136,160,254,126,188,209,255,34,35,111,0,215,219,24,255,212,11,214,254,101,5,118, +0,232,197,133,255,223,167,109,255,237,80,86,255,70,139,94,0,158,193,191,1,155,15,51,255,15,190,115,0,78,135,207,255,249,10,27,1,181,125,233,0,95,172,13,254,170,213,161,255,39,236,138,255,95,93,87,255,190,128,95,0,125,15,206,0,166,150,159,0,227,15,158,255,206,158,120,255,42,141,128,0,101,178,120,1,156,109,131,0,218,14,44,254,247,168,206,255,212,112,28,0,112,17,228,255,90,16,37,1,197,222,108,0,254,207,83,255,9,90,243,255,243,244,172,0,26,88,115,255,205,116,122,0,191,230,193,0,180,100,11,1,217,37,96, +255,154,78,156,0,235,234,31,255,206,178,178,255,149,192,251,0,182,250,135,0,246,22,105,0,124,193,109,255,2,210,149,255,169,17,170,0,0,96,110,255,117,9,8,1,50,123,40,255,193,189,99,0,34,227,160,0,48,80,70,254,211,51,236,0,45,122,245,254,44,174,8,0,173,37,233,255,158,65,171,0,122,69,215,255,90,80,2,255,131,106,96,254,227,114,135,0,205,49,119,254,176,62,64,255,82,51,17,255,241,20,243,255,130,13,8,254,128,217,243,255,162,27,1,254,90,118,241,0,246,198,246,255,55,16,118,255,200,159,157,0,163,17,1,0,140, +107,121,0,85,161,118,255,38,0,149,0,156,47,238,0,9,166,166,1,75,98,181,255,50,74,25,0,66,15,47,0,139,225,159,0,76,3,142,255,14,238,184,0,11,207,53,255,183,192,186,1,171,32,174,255,191,76,221,1,247,170,219,0,25,172,50,254,217,9,233,0,203,126,68,255,183,92,48,0,127,167,183,1,65,49,254,0,16,63,127,1,254,21,170,255,59,224,127,254,22,48,63,255,27,78,130,254,40,195,29,0,250,132,112,254,35,203,144,0,104,169,168,0,207,253,30,255,104,40,38,254,94,228,88,0,206,16,128,255,212,55,122,255,223,22,234,0,223,197, +127,0,253,181,181,1,145,102,118,0,236,153,36,255,212,217,72,255,20,38,24,254,138,62,62,0,152,140,4,0,230,220,99,255,1,21,212,255,148,201,231,0,244,123,9,254,0,171,210,0,51,58,37,255,1,255,14,255,244,183,145,254,0,242,166,0,22,74,132,0,121,216,41,0,95,195,114,254,133,24,151,255,156,226,231,255,247,5,77,255,246,148,115,254,225,92,81,255,222,80,246,254,170,123,89,255,74,199,141,0,29,20,8,255,138,136,70,255,93,75,92,0,221,147,49,254,52,126,226,0,229,124,23,0,46,9,181,0,205,64,52,1,131,254,28,0,151,158, +212,0,131,64,78,0,206,25,171,0,0,230,139,0,191,253,110,254,103,247,167,0,64,40,40,1,42,165,241,255,59,75,228,254,124,243,189,255,196,92,178,255,130,140,86,255,141,89,56,1,147,198,5,255,203,248,158,254,144,162,141,0,11,172,226,0,130,42,21,255,1,167,143,255,144,36,36,255,48,88,164,254,168,170,220,0,98,71,214,0,91,208,79,0,159,76,201,1,166,42,214,255,69,255,0,255,6,128,125,255,190,1,140,0,146,83,218,255,215,238,72,1,122,127,53,0,189,116,165,255,84,8,66,255,214,3,208,255,213,110,133,0,195,168,44,1,158, +231,69,0,162,64,200,254,91,58,104,0,182,58,187,254,249,228,136,0,203,134,76,254,99,221,233,0,75,254,214,254,80,69,154,0,64,152,248,254,236,136,202,255,157,105,153,254,149,175,20,0,22,35,19,255,124,121,233,0,186,250,198,254,132,229,139,0,137,80,174,255,165,125,68,0,144,202,148,254,235,239,248,0,135,184,118,0,101,94,17,255,122,72,70,254,69,130,146,0,127,222,248,1,69,127,118,255,30,82,215,254,188,74,19,255,229,167,194,254,117,25,66,255,65,234,56,254,213,22,156,0,151,59,93,254,45,28,27,255,186,126,164, +255,32,6,239,0,127,114,99,1,219,52,2,255,99,96,166,254,62,190,126,255,108,222,168,1,75,226,174,0,230,226,199,0,60,117,218,255,252,248,20,1,214,188,204,0,31,194,134,254,123,69,192,255,169,173,36,254,55,98,91,0,223,42,102,254,137,1,102,0,157,90,25,0,239,122,64,255,252,6,233,0,7,54,20,255,82,116,174,0,135,37,54,255,15,186,125,0,227,112,175,255,100,180,225,255,42,237,244,255,244,173,226,254,248,18,33,0,171,99,150,255,74,235,50,255,117,82,32,254,106,168,237,0,207,109,208,1,228,9,186,0,135,60,169,254,179, +92,143,0,244,170,104,255,235,45,124,255,70,99,186,0,117,137,183,0,224,31,215,0,40,9,100,0,26,16,95,1,68,217,87,0,8,151,20,255,26,100,58,255,176,165,203,1,52,118,70,0,7,32,254,254,244,254,245,255,167,144,194,255,125,113,23,255,176,121,181,0,136,84,209,0,138,6,30,255,89,48,28,0,33,155,14,255,25,240,154,0,141,205,109,1,70,115,62,255,20,40,107,254,138,154,199,255,94,223,226,255,157,171,38,0,163,177,25,254,45,118,3,255,14,222,23,1,209,190,81,255,118,123,232,1,13,213,101,255,123,55,123,254,27,246,165,0, +50,99,76,255,140,214,32,255,97,65,67,255,24,12,28,0,174,86,78,1,64,247,96,0,160,135,67,0,66,55,243,255,147,204,96,255,26,6,33,255,98,51,83,1,153,213,208,255,2,184,54,255,25,218,11,0,49,67,246,254,18,149,72,255,13,25,72,0,42,79,214,0,42,4,38,1,27,139,144,255,149,187,23,0,18,164,132,0,245,84,184,254,120,198,104,255,126,218,96,0,56,117,234,255,13,29,214,254,68,47,10,255,167,154,132,254,152,38,198,0,66,178,89,255,200,46,171,255,13,99,83,255,210,187,253,255,170,45,42,1,138,209,124,0,214,162,141,0,12,230, +156,0,102,36,112,254,3,147,67,0,52,215,123,255,233,171,54,255,98,137,62,0,247,218,39,255,231,218,236,0,247,191,127,0,195,146,84,0,165,176,92,255,19,212,94,255,17,74,227,0,88,40,153,1,198,147,1,255,206,67,245,254,240,3,218,255,61,141,213,255,97,183,106,0,195,232,235,254,95,86,154,0,209,48,205,254,118,209,241,255,240,120,223,1,213,29,159,0,163,127,147,255,13,218,93,0,85,24,68,254,70,20,80,255,189,5,140,1,82,97,254,255,99,99,191,255,132,84,133,255,107,218,116,255,112,122,46,0,105,17,32,0,194,160,63, +255,68,222,39,1,216,253,92,0,177,105,205,255,149,201,195,0,42,225,11,255,40,162,115,0,9,7,81,0,165,218,219,0,180,22,0,254,29,146,252,255,146,207,225,1,180,135,96,0,31,163,112,0,177,11,219,255,133,12,193,254,43,78,50,0,65,113,121,1,59,217,6,255,110,94,24,1,112,172,111,0,7,15,96,0,36,85,123,0,71,150,21,255,208,73,188,0,192,11,167,1,213,245,34,0,9,230,92,0,162,142,39,255,215,90,27,0,98,97,89,0,94,79,211,0,90,157,240,0,95,220,126,1,102,176,226,0,36,30,224,254,35,31,127,0,231,232,115,1,85,83,130,0,210, +73,245,255,47,143,114,255,68,65,197,0,59,72,62,255,183,133,173,254,93,121,118,255,59,177,81,255,234,69,173,255,205,128,177,0,220,244,51,0,26,244,209,1,73,222,77,255,163,8,96,254,150,149,211,0,158,254,203,1,54,127,139,0,161,224,59,0,4,109,22,255,222,42,45,255,208,146,102,255,236,142,187,0,50,205,245,255,10,74,89,254,48,79,142,0,222,76,130,255,30,166,63,0,236,12,13,255,49,184,244,0,187,113,102,0,218,101,253,0,153,57,182,254,32,150,42,0,25,198,146,1,237,241,56,0,140,68,5,0,91,164,172,255,78,145,186, +254,67,52,205,0,219,207,129,1,109,115,17,0,54,143,58,1,21,248,120,255,179,255,30,0,193,236,66,255,1,255,7,255,253,192,48,255,19,69,217,1,3,214,0,255,64,101,146,1,223,125,35,255,235,73,179,255,249,167,226,0,225,175,10,1,97,162,58,0,106,112,171,1,84,172,5,255,133,140,178,255,134,245,142,0,97,90,125,255,186,203,185,255,223,77,23,255,192,92,106,0,15,198,115,255,217,152,248,0,171,178,120,255,228,134,53,0,176,54,193,1,250,251,53,0,213,10,100,1,34,199,106,0,151,31,244,254,172,224,87,255,14,237,23,255,253, +85,26,255,127,39,116,255,172,104,100,0,251,14,70,255,212,208,138,255,253,211,250,0,176,49,165,0,15,76,123,255,37,218,160,255,92,135,16,1,10,126,114,255,70,5,224,255,247,249,141,0,68,20,60,1,241,210,189,255,195,217,187,1,151,3,113,0,151,92,174,0,231,62,178,255,219,183,225,0,23,23,33,255,205,181,80,0,57,184,248,255,67,180,1,255,90,123,93,255,39,0,162,255,96,248,52,255,84,66,140,0,34,127,228,255,194,138,7,1,166,110,188,0,21,17,155,1,154,190,198,255,214,80,59,255,18,7,143,0,72,29,226,1,199,217,249,0, +232,161,71,1,149,190,201,0,217,175,95,254,113,147,67,255,138,143,199,255,127,204,1,0,29,182,83,1,206,230,155,255,186,204,60,0,10,125,85,255,232,96,25,255,255,89,247,255,213,254,175,1,232,193,81,0,28,43,156,254,12,69,8,0,147,24,248,0,18,198,49,0,134,60,35,0,118,246,18,255,49,88,254,254,228,21,186,255,182,65,112,1,219,22,1,255,22,126,52,255,189,53,49,255,112,25,143,0,38,127,55,255,226,101,163,254,208,133,61,255,137,69,174,1,190,118,145,255,60,98,219,255,217,13,245,255,250,136,10,0,84,254,226,0,201, +31,125,1,240,51,251,255,31,131,130,255,2,138,50,255,215,215,177,1,223,12,238,255,252,149,56,255,124,91,68,255,72,126,170,254,119,255,100,0,130,135,232,255,14,79,178,0,250,131,197,0,138,198,208,0,121,216,139,254,119,18,36,255,29,193,122,0,16,42,45,255,213,240,235,1,230,190,169,255,198,35,228,254,110,173,72,0,214,221,241,255,56,148,135,0,192,117,78,254,141,93,207,255,143,65,149,0,21,18,98,255,95,44,244,1,106,191,77,0,254,85,8,254,214,110,176,255,73,173,19,254,160,196,199,255,237,90,144,0,193,172,113, +255,200,155,136,254,228,90,221,0,137,49,74,1,164,221,215,255,209,189,5,255,105,236,55,255,42,31,129,1,193,255,236,0,46,217,60,0,138,88,187,255,226,82,236,255,81,69,151,255,142,190,16,1,13,134,8,0,127,122,48,255,81,64,156,0,171,243,139,0,237,35,246,0,122,143,193,254,212,122,146,0,95,41,255,1,87,132,77,0,4,212,31,0,17,31,78,0,39,45,173,254,24,142,217,255,95,9,6,255,227,83,6,0,98,59,130,254,62,30,33,0,8,115,211,1,162,97,128,255,7,184,23,254,116,28,168,255,248,138,151,255,98,244,240,0,186,118,130,0,114, +248,235,255,105,173,200,1,160,124,71,255,94,36,164,1,175,65,146,255,238,241,170,254,202,198,197,0,228,71,138,254,45,246,109,255,194,52,158,0,133,187,176,0,83,252,154,254,89,189,221,255,170,73,252,0,148,58,125,0,36,68,51,254,42,69,177,255,168,76,86,255,38,100,204,255,38,53,35,0,175,19,97,0,225,238,253,255,81,81,135,0,210,27,255,254,235,73,107,0,8,207,115,0,82,127,136,0,84,99,21,254,207,19,136,0,100,164,101,0,80,208,77,255,132,207,237,255,15,3,15,255,33,166,110,0,156,95,85,255,37,185,111,1,150,106, +35,255,166,151,76,0,114,87,135,255,159,194,64,0,12,122,31,255,232,7,101,254,173,119,98,0,154,71,220,254,191,57,53,255,168,232,160,255,224,32,99,255,218,156,165,0,151,153,163,0,217,13,148,1,197,113,89,0,149,28,161,254,207,23,30,0,105,132,227,255,54,230,94,255,133,173,204,255,92,183,157,255,88,144,252,254,102,33,90,0,159,97,3,0,181,218,155,255,240,114,119,0,106,214,53,255,165,190,115,1,152,91,225,255,88,106,44,255,208,61,113,0,151,52,124,0,191,27,156,255,110,54,236,1,14,30,166,255,39,127,207,1,229, +199,28,0,188,228,188,254,100,157,235,0,246,218,183,1,107,22,193,255,206,160,95,0,76,239,147,0,207,161,117,0,51,166,2,255,52,117,10,254,73,56,227,255,152,193,225,0,132,94,136,255,101,191,209,0,32,107,229,255,198,43,180,1,100,210,118,0,114,67,153,255,23,88,26,255,89,154,92,1,220,120,140,255,144,114,207,255,252,115,250,255,34,206,72,0,138,133,127,255,8,178,124,1,87,75,97,0,15,229,92,254,240,67,131,255,118,123,227,254,146,120,104,255,145,213,255,1,129,187,70,255,219,119,54,0,1,19,173,0,45,150,148,1,248, +83,72,0,203,233,169,1,142,107,56,0,247,249,38,1,45,242,80,255,30,233,103,0,96,82,70,0,23,201,111,0,81,39,30,255,161,183,78,255,194,234,33,255,68,227,140,254,216,206,116,0,70,27,235,255,104,144,79,0,164,230,93,254,214,135,156,0,154,187,242,254,188,20,131,255,36,109,174,0,159,112,241,0,5,110,149,1,36,165,218,0,166,29,19,1,178,46,73,0,93,43,32,254,248,189,237,0,102,155,141,0,201,93,195,255,241,139,253,255,15,111,98,255,108,65,163,254,155,79,190,255,73,174,193,254,246,40,48,255,107,88,11,254,202,97,85, +255,253,204,18,255,113,242,66,0,110,160,194,254,208,18,186,0,81,21,60,0,188,104,167,255,124,166,97,254,210,133,142,0,56,242,137,254,41,111,130,0,111,151,58,1,111,213,141,255,183,172,241,255,38,6,196,255,185,7,123,255,46,11,246,0,245,105,119,1,15,2,161,255,8,206,45,255,18,202,74,255,83,124,115,1,212,141,157,0,83,8,209,254,139,15,232,255,172,54,173,254,50,247,132,0,214,189,213,0,144,184,105,0,223,254,248,0,255,147,240,255,23,188,72,0,7,51,54,0,188,25,180,254,220,180,0,255,83,160,20,0,163,189,243,255, +58,209,194,255,87,73,60,0,106,24,49,0,245,249,220,0,22,173,167,0,118,11,195,255,19,126,237,0,110,159,37,255,59,82,47,0,180,187,86,0,188,148,208,1,100,37,133,255,7,112,193,0,129,188,156,255,84,106,129,255,133,225,202,0,14,236,111,255,40,20,101,0,172,172,49,254,51,54,74,255,251,185,184,255,93,155,224,255,180,249,224,1,230,178,146,0,72,57,54,254,178,62,184,0,119,205,72,0,185,239,253,255,61,15,218,0,196,67,56,255,234,32,171,1,46,219,228,0,208,108,234,255,20,63,232,255,165,53,199,1,133,228,5,255,52,205, +107,0,74,238,140,255,150,156,219,254,239,172,178,255,251,189,223,254,32,142,211,255,218,15,138,1,241,196,80,0,28,36,98,254,22,234,199,0,61,237,220,255,246,57,37,0,142,17,142,255,157,62,26,0,43,238,95,254,3,217,6,255,213,25,240,1,39,220,174,255,154,205,48,254,19,13,192,255,244,34,54,254,140,16,155,0,240,181,5,254,155,193,60,0,166,128,4,255,36,145,56,255,150,240,219,0,120,51,145,0,82,153,42,1,140,236,146,0,107,92,248,1,189,10,3,0,63,136,242,0,211,39,24,0,19,202,161,1,173,27,186,255,210,204,239,254, +41,209,162,255,182,254,159,255,172,116,52,0,195,103,222,254,205,69,59,0,53,22,41,1,218,48,194,0,80,210,242,0,210,188,207,0,187,161,161,254,216,17,1,0,136,225,113,0,250,184,63,0,223,30,98,254,77,168,162,0,59,53,175,0,19,201,10,255,139,224,194,0,147,193,154,255,212,189,12,254,1,200,174,255,50,133,113,1,94,179,90,0,173,182,135,0,94,177,113,0,43,89,215,255,136,252,106,255,123,134,83,254,5,245,66,255,82,49,39,1,220,2,224,0,97,129,177,0,77,59,89,0,61,29,155,1,203,171,220,255,92,78,139,0,145,33,181,255, +169,24,141,1,55,150,179,0,139,60,80,255,218,39,97,0,2,147,107,255,60,248,72,0,173,230,47,1,6,83,182,255,16,105,162,254,137,212,81,255,180,184,134,1,39,222,164,255,221,105,251,1,239,112,125,0,63,7,97,0,63,104,227,255,148,58,12,0,90,60,224,255,84,212,252,0,79,215,168,0,248,221,199,1,115,121,1,0,36,172,120,0,32,162,187,255,57,107,49,255,147,42,21,0,106,198,43,1,57,74,87,0,126,203,81,255,129,135,195,0,140,31,177,0,221,139,194,0,3,222,215,0,131,68,231,0,177,86,178,254,124,151,180,0,184,124,38,1,70,163, +17,0,249,251,181,1,42,55,227,0,226,161,44,0,23,236,110,0,51,149,142,1,93,5,236,0,218,183,106,254,67,24,77,0,40,245,209,255,222,121,153,0,165,57,30,0,83,125,60,0,70,38,82,1,229,6,188,0,109,222,157,255,55,118,63,255,205,151,186,0,227,33,149,255,254,176,246,1,227,177,227,0,34,106,163,254,176,43,79,0,106,95,78,1,185,241,122,255,185,14,61,0,36,1,202,0,13,178,162,255,247,11,132,0,161,230,92,1,65,1,185,255,212,50,165,1,141,146,64,255,158,242,218,0,21,164,125,0,213,139,122,1,67,71,87,0,203,158,178,1,151, +92,43,0,152,111,5,255,39,3,239,255,217,255,250,255,176,63,71,255,74,245,77,1,250,174,18,255,34,49,227,255,246,46,251,255,154,35,48,1,125,157,61,255,106,36,78,255,97,236,153,0,136,187,120,255,113,134,171,255,19,213,217,254,216,94,209,255,252,5,61,0,94,3,202,0,3,26,183,255,64,191,43,255,30,23,21,0,129,141,77,255,102,120,7,1,194,76,140,0,188,175,52,255,17,81,148,0,232,86,55,1,225,48,172,0,134,42,42,255,238,50,47,0,169,18,254,0,20,147,87,255,14,195,239,255,69,247,23,0,238,229,128,255,177,49,112,0,168, +98,251,255,121,71,248,0,243,8,145,254,246,227,153,255,219,169,177,254,251,139,165,255,12,163,185,255,164,40,171,255,153,159,27,254,243,109,91,255,222,24,112,1,18,214,231,0,107,157,181,254,195,147,0,255,194,99,104,255,89,140,190,255,177,66,126,254,106,185,66,0,49,218,31,0,252,174,158,0,188,79,230,1,238,41,224,0,212,234,8,1,136,11,181,0,166,117,83,255,68,195,94,0,46,132,201,0,240,152,88,0,164,57,69,254,160,224,42,255,59,215,67,255,119,195,141,255,36,180,121,254,207,47,8,255,174,210,223,0,101,197,68, +255,255,82,141,1,250,137,233,0,97,86,133,1,16,80,69,0,132,131,159,0,116,93,100,0,45,141,139,0,152,172,157,255,90,43,91,0,71,153,46,0,39,16,112,255,217,136,97,255,220,198,25,254,177,53,49,0,222,88,134,255,128,15,60,0,207,192,169,255,192,116,209,255,106,78,211,1,200,213,183,255,7,12,122,254,222,203,60,255,33,110,199,254,251,106,117,0,228,225,4,1,120,58,7,255,221,193,84,254,112,133,27,0,189,200,201,255,139,135,150,0,234,55,176,255,61,50,65,0,152,108,169,255,220,85,1,255,112,135,227,0,162,26,186,0,207, +96,185,254,244,136,107,0,93,153,50,1,198,97,151,0,110,11,86,255,143,117,174,255,115,212,200,0,5,202,183,0,237,164,10,254,185,239,62,0,236,120,18,254,98,123,99,255,168,201,194,254,46,234,214,0,191,133,49,255,99,169,119,0,190,187,35,1,115,21,45,255,249,131,72,0,112,6,123,255,214,49,181,254,166,233,34,0,92,197,102,254,253,228,205,255,3,59,201,1,42,98,46,0,219,37,35,255,169,195,38,0,94,124,193,1,156,43,223,0,95,72,133,254,120,206,191,0,122,197,239,255,177,187,79,255,254,46,2,1,250,167,190,0,84,129,19, +0,203,113,166,255,249,31,189,254,72,157,202,255,208,71,73,255,207,24,72,0,10,16,18,1,210,81,76,255,88,208,192,255,126,243,107,255,238,141,120,255,199,121,234,255,137,12,59,255,36,220,123,255,148,179,60,254,240,12,29,0,66,0,97,1,36,30,38,255,115,1,93,255,96,103,231,255,197,158,59,1,192,164,240],"i8",4,f.h);G([202,202,57,255,24,174,48,0,89,77,155,1,42,76,215,0,244,151,233,0,23,48,81,0,239,127,52,254,227,130,37,255,248,116,93,1,124,132,118,0,173,254,192,1,6,235,83,255,110,175,231,1,251,28,182,0,129, +249,93,254,84,184,128,0,76,181,62,0,175,128,186,0,100,53,136,254,109,29,226,0,221,233,58,1,20,99,74,0,0,22,160,0,134,13,21,0,9,52,55,255,17,89,140,0,175,34,59,0,84,165,119,255,224,226,234,255,7,72,166,255,123,115,255,1,18,214,246,0,250,7,71,1,217,220,185,0,212,35,76,255,38,125,175,0,189,97,210,0,114,238,44,255,41,188,169,254,45,186,154,0,81,92,22,0,132,160,193,0,121,208,98,255,13,81,44,255,203,156,82,0,71,58,21,255,208,114,191,254,50,38,147,0,154,216,195,0,101,25,18,0,60,250,215,255,233,132,235,255, +103,175,142,1,16,14,92,0,141,31,110,254,238,241,45,255,153,217,239,1,97,168,47,255,249,85,16,1,28,175,62,255,57,254,54,0,222,231,126,0,166,45,117,254,18,189,96,255,228,76,50,0,200,244,94,0,198,152,120,1,68,34,69,255,12,65,160,254,101,19,90,0,167,197,120,255,68,54,185,255,41,218,188,0,113,168,48,0,88,105,189,1,26,82,32,255,185,93,164,1,228,240,237,255,66,182,53,0,171,197,92,255,107,9,233,1,199,120,144,255,78,49,10,255,109,170,105,255,90,4,31,255,28,244,113,255,74,58,11,0,62,220,246,255,121,154,200, +254,144,210,178,255,126,57,129,1,43,250,14,255,101,111,28,1,47,86,241,255,61,70,150,255,53,73,5,255,30,26,158,0,209,26,86,0,138,237,74,0,164,95,188,0,142,60,29,254,162,116,248,255,187,175,160,0,151,18,16,0,209,111,65,254,203,134,39,255,88,108,49,255,131,26,71,255,221,27,215,254,104,105,93,255,31,236,31,254,135,0,211,255,143,127,110,1,212,73,229,0,233,67,167,254,195,1,208,255,132,17,221,255,51,217,90,0,67,235,50,255,223,210,143,0,179,53,130,1,233,106,198,0,217,173,220,255,112,229,24,255,175,154,93, +254,71,203,246,255,48,66,133,255,3,136,230,255,23,221,113,254,235,111,213,0,170,120,95,254,251,221,2,0,45,130,158,254,105,94,217,255,242,52,180,254,213,68,45,255,104,38,28,0,244,158,76,0,161,200,96,255,207,53,13,255,187,67,148,0,170,54,248,0,119,162,178,255,83,20,11,0,42,42,192,1,146,159,163,255,183,232,111,0,77,229,21,255,71,53,143,0,27,76,34,0,246,136,47,255,219,39,182,255,92,224,201,1,19,142,14,255,69,182,241,255,163,118,245,0,9,109,106,1,170,181,247,255,78,47,238,255,84,210,176,255,213,107,139, +0,39,38,11,0,72,21,150,0,72,130,69,0,205,77,155,254,142,133,21,0,71,111,172,254,226,42,59,255,179,0,215,1,33,128,241,0,234,252,13,1,184,79,8,0,110,30,73,255,246,141,189,0,170,207,218,1,74,154,69,255,138,246,49,255,155,32,100,0,125,74,105,255,90,85,61,255,35,229,177,255,62,125,193,255,153,86,188,1,73,120,212,0,209,123,246,254,135,209,38,255,151,58,44,1,92,69,214,255,14,12,88,255,252,153,166,255,253,207,112,255,60,78,83,255,227,124,110,0,180,96,252,255,53,117,33,254,164,220,82,255,41,1,27,255,38,164, +166,255,164,99,169,254,61,144,70,255,192,166,18,0,107,250,66,0,197,65,50,0,1,179,18,255,255,104,1,255,43,153,35,255,80,111,168,0,110,175,168,0,41,105,45,255,219,14,205,255,164,233,140,254,43,1,118,0,233,67,195,0,178,82,159,255,138,87,122,255,212,238,90,255,144,35,124,254,25,140,164,0,251,215,44,254,133,70,107,255,101,227,80,254,92,169,55,0,215,42,49,0,114,180,85,255,33,232,27,1,172,213,25,0,62,176,123,254,32,133,24,255,225,191,62,0,93,70,153,0,181,42,104,1,22,191,224,255,200,200,140,255,249,234,37, +0,149,57,141,0,195,56,208,255,254,130,70,255,32,173,240,255,29,220,199,0,110,100,115,255,132,229,249,0,228,233,223,255,37,216,209,254,178,177,209,255,183,45,165,254,224,97,114,0,137,97,168,255,225,222,172,0,165,13,49,1,210,235,204,255,252,4,28,254,70,160,151,0,232,190,52,254,83,248,93,255,62,215,77,1,175,175,179,255,160,50,66,0,121,48,208,0,63,169,209,255,0,210,200,0,224,187,44,1,73,162,82,0,9,176,143,255,19,76,193,255,29,59,167,1,24,43,154,0,28,190,190,0,141,188,129,0,232,235,203,255,234,0,109,255, +54,65,159,0,60,88,232,255,121,253,150,254,252,233,131,255,198,110,41,1,83,77,71,255,200,22,59,254,106,253,242,255,21,12,207,255,237,66,189,0,90,198,202,1,225,172,127,0,53,22,202,0,56,230,132,0,1,86,183,0,109,190,42,0,243,68,174,1,109,228,154,0,200,177,122,1,35,160,183,255,177,48,85,255,90,218,169,255,248,152,78,0,202,254,110,0,6,52,43,0,142,98,65,255,63,145,22,0,70,106,93,0,232,138,107,1,110,179,61,255,211,129,218,1,242,209,92,0,35,90,217,1,182,143,106,255,116,101,217,255,114,250,221,255,173,204, +6,0,60,150,163,0,73,172,44,255,239,110,80,255,237,76,153,254,161,140,249,0,149,232,229,0,133,31,40,255,174,164,119,0,113,51,214,0,129,228,2,254,64,34,243,0,107,227,244,255,174,106,200,255,84,153,70,1,50,35,16,0,250,74,216,254,236,189,66,255,153,249,13,0,230,178,4,255,221,41,238,0,118,227,121,255,94,87,140,254,254,119,92,0,73,239,246,254,117,87,128,0,19,211,145,255,177,46,252,0,229,91,246,1,69,128,247,255,202,77,54,1,8,11,9,255,153,96,166,0,217,214,173,255,134,192,2,1,0,207,0,0,189,174,107,1,140,134, +100,0,158,193,243,1,182,102,171,0,235,154,51,0,142,5,123,255,60,168,89,1,217,14,92,255,19,214,5,1,211,167,254,0,44,6,202,254,120,18,236,255,15,113,184,255,184,223,139,0,40,177,119,254,182,123,90,255,176,165,176,0,247,77,194,0,27,234,120,0,231,0,214,255,59,39,30,0,125,99,145,255,150,68,68,1,141,222,248,0,153,123,210,255,110,127,152,255,229,33,214,1,135,221,197,0,137,97,2,0,12,143,204,255,81,41,188,0,115,79,130,255,94,3,132,0,152,175,187,255,124,141,10,255,126,192,179,255,11,103,198,0,149,6,45,0,219, +85,187,1,230,18,178,255,72,182,152,0,3,198,184,255,128,112,224,1,97,161,230,0,254,99,38,255,58,159,197,0,151,66,219,0,59,69,143,255,185,112,249,0,119,136,47,255,123,130,132,0,168,71,95,255,113,176,40,1,232,185,173,0,207,93,117,1,68,157,108,255,102,5,147,254,49,97,33,0,89,65,111,254,247,30,163,255,124,217,221,1,102,250,216,0,198,174,75,254,57,55,18,0,227,5,236,1,229,213,173,0,201,109,218,1,49,233,239,0,30,55,158,1,25,178,106,0,155,111,188,1,94,126,140,0,215,31,238,1,77,240,16,0,213,242,25,1,38,71, +168,0,205,186,93,254,49,211,140,255,219,0,180,255,134,118,165,0,160,147,134,255,110,186,35,255,198,243,42,0,243,146,119,0,134,235,163,1,4,241,135,255,193,46,193,254,103,180,79,255,225,4,184,254,242,118,130,0,146,135,176,1,234,111,30,0,69,66,213,254,41,96,123,0,121,94,42,255,178,191,195,255,46,130,42,0,117,84,8,255,233,49,214,254,238,122,109,0,6,71,89,1,236,211,123,0,244,13,48,254,119,148,14,0,114,28,86,255,75,237,25,255,145,229,16,254,129,100,53,255,134,150,120,254,168,157,50,0,23,72,104,255,224, +49,14,0,255,123,22,255,151,185,151,255,170,80,184,1,134,182,20,0,41,100,101,1,153,33,16,0,76,154,111,1,86,206,234,255,192,160,164,254,165,123,93,255,1,216,164,254,67,17,175,255,169,11,59,255,158,41,61,255,73,188,14,255,195,6,137,255,22,147,29,255,20,103,3,255,246,130,227,255,122,40,128,0,226,47,24,254,35,36,32,0,152,186,183,255,69,202,20,0,195,133,195,0,222,51,247,0,169,171,94,1,183,0,160,255,64,205,18,1,156,83,15,255,197,58,249,254,251,89,110,255,50,10,88,254,51,43,216,0,98,242,198,1,245,151,113, +0,171,236,194,1,197,31,199,255,229,81,38,1,41,59,20,0,253,104,230,0,152,93,14,255,246,242,146,254,214,169,240,255,240,102,108,254,160,167,236,0,154,218,188,0,150,233,202,255,27,19,250,1,2,71,133,255,175,12,63,1,145,183,198,0,104,120,115,255,130,251,247,0,17,212,167,255,62,123,132,255,247,100,189,0,155,223,152,0,143,197,33,0,155,59,44,255,150,93,240,1,127,3,87,255,95,71,207,1,167,85,1,255,188,152,116,255,10,23,23,0,137,195,93,1,54,98,97,0,240,0,168,255,148,188,127,0,134,107,151,0,76,253,171,0,90,132, +192,0,146,22,54,0,224,66,54,254,230,186,229,255,39,182,196,0,148,251,130,255,65,131,108,254,128,1,160,0,169,49,167,254,199,254,148,255,251,6,131,0,187,254,129,255,85,82,62,0,178,23,58,255,254,132,5,0,164,213,39,0,134,252,146,254,37,53,81,255,155,134,82,0,205,167,238,255,94,45,180,255,132,40,161,0,254,111,112,1,54,75,217,0,179,230,221,1,235,94,191,255,23,243,48,1,202,145,203,255,39,118,42,255,117,141,253,0,254,0,222,0,43,251,50,0,54,169,234,1,80,68,208,0,148,203,243,254,145,7,135,0,6,254,0,0,252,185, +127,0,98,8,129,255,38,35,72,255,211,36,220,1,40,26,89,0,168,64,197,254,3,222,239,255,2,83,215,254,180,159,105,0,58,115,194,0,186,116,106,255,229,247,219,255,129,118,193,0,202,174,183,1,166,161,72,0,201,107,147,254,237,136,74,0,233,230,106,1,105,111,168,0,64,224,30,1,1,229,3,0,102,151,175,255,194,238,228,255,254,250,212,0,187,237,121,0,67,251,96,1,197,30,11,0,183,95,204,0,205,89,138,0,64,221,37,1,255,223,30,255,178,48,211,255,241,200,90,255,167,209,96,255,57,130,221,0,46,114,200,255,61,184,66,0,55, +182,24,254,110,182,33,0,171,190,232,255,114,94,31,0,18,221,8,0,47,231,254,0,255,112,83,0,118,15,215,255,173,25,40,254,192,193,31,255,238,21,146,255,171,193,118,255,101,234,53,254,131,212,112,0,89,192,107,1,8,208,27,0,181,217,15,255,231,149,232,0,140,236,126,0,144,9,199,255,12,79,181,254,147,182,202,255,19,109,182,255,49,212,225,0,74,163,203,0,175,233,148,0,26,112,51,0,193,193,9,255,15,135,249,0,150,227,130,0,204,0,219,1,24,242,205,0,238,208,117,255,22,244,112,0,26,229,34,0,37,80,188,255,38,45,206, +254,240,90,225,255,29,3,47,255,42,224,76,0,186,243,167,0,32,132,15,255,5,51,125,0,139,135,24,0,6,241,219,0,172,229,133,255,246,214,50,0,231,11,207,255,191,126,83,1,180,163,170,255,245,56,24,1,178,164,211,255,3,16,202,1,98,57,118,255,141,131,89,254,33,51,24,0,243,149,91,255,253,52,14,0,35,169,67,254,49,30,88,255,179,27,36,255,165,140,183,0,58,189,151,0,88,31,0,0,75,169,66,0,66,101,199,255,24,216,199,1,121,196,26,255,14,79,203,254,240,226,81,255,94,28,10,255,83,193,240,255,204,193,131,255,94,15,86, +0,218,40,157,0,51,193,209,0,0,242,177,0,102,185,247,0,158,109,116,0,38,135,91,0,223,175,149,0,220,66,1,255,86,60,232,0,25,96,37,255,225,122,162,1,215,187,168,255,158,157,46,0,56,171,162,0,232,240,101,1,122,22,9,0,51,9,21,255,53,25,238,255,217,30,232,254,125,169,148,0,13,232,102,0,148,9,37,0,165,97,141,1,228,131,41,0,222,15,243,255,254,18,17,0,6,60,237,1,106,3,113,0,59,132,189,0,92,112,30,0,105,208,213,0,48,84,179,255,187,121,231,254,27,216,109,255,162,221,107,254,73,239,195,255,250,31,57,255,149, +135,89,255,185,23,115,1,3,163,157,255,18,112,250,0,25,57,187,255,161,96,164,0,47,16,243,0,12,141,251,254,67,234,184,255,41,18,161,0,175,6,96,255,160,172,52,254,24,176,183,255,198,193,85,1,124,121,137,255,151,50,114,255,220,203,60,255,207,239,5,1,0,38,107,255,55,238,94,254,70,152,94,0,213,220,77,1,120,17,69,255,85,164,190,255,203,234,81,0,38,49,37,254,61,144,124,0,137,78,49,254,168,247,48,0,95,164,252,0,105,169,135,0,253,228,134,0,64,166,75,0,81,73,20,255,207,210,10,0,234,106,150,255,94,34,90,255, +254,159,57,254,220,133,99,0,139,147,180,254,24,23,185,0,41,57,30,255,189,97,76,0,65,187,223,255,224,172,37,255,34,62,95,1,231,144,240,0,77,106,126,254,64,152,91,0,29,98,155,0,226,251,53,255,234,211,5,255,144,203,222,255,164,176,221,254,5,231,24,0,179,122,205,0,36,1,134,255,125,70,151,254,97,228,252,0,172,129,23,254,48,90,209,255,150,224,82,1,84,134,30,0,241,196,46,0,103,113,234,255,46,101,121,254,40,124,250,255,135,45,242,254,9,249,168,255,140,108,131,255,143,163,171,0,50,173,199,255,88,222,142,255, +200,95,158,0,142,192,163,255,7,117,135,0,111,124,22,0,236,12,65,254,68,38,65,255,227,174,254,0,244,245,38,0,240,50,208,255,161,63,250,0,60,209,239,0,122,35,19,0,14,33,230,254,2,159,113,0,106,20,127,255,228,205,96,0,137,210,174,254,180,212,144,255,89,98,154,1,34,88,139,0,167,162,112,1,65,110,197,0,241,37,169,0,66,56,131,255,10,201,83,254,133,253,187,255,177,112,45,254,196,251,0,0,196,250,151,255,238,232,214,255,150,209,205,0,28,240,118,0,71,76,83,1,236,99,91,0,42,250,131,1,96,18,64,255,118,222,35, +0,113,214,203,255,122,119,184,255,66,19,36,0,204,64,249,0,146,89,139,0,134,62,135,1,104,233,101,0,188,84,26,0,49,249,129,0,208,214,75,255,207,130,77,255,115,175,235,0,171,2,137,255,175,145,186,1,55,245,135,255,154,86,181,1,100,58,246,255,109,199,60,255,82,204,134,255,215,49,230,1,140,229,192,255,222,193,251,255,81,136,15,255,179,149,162,255,23,39,29,255,7,95,75,254,191,81,222,0,241,81,90,255,107,49,201,255,244,211,157,0,222,140,149,255,65,219,56,254,189,246,90,255,178,59,157,1,48,219,52,0,98,34,215, +0,28,17,187,255,175,169,24,0,92,79,161,255,236,200,194,1,147,143,234,0,229,225,7,1,197,168,14,0,235,51,53,1,253,120,174,0,197,6,168,255,202,117,171,0,163,21,206,0,114,85,90,255,15,41,10,255,194,19,99,0,65,55,216,254,162,146,116,0,50,206,212,255,64,146,29,255,158,158,131,1,100,165,130,255,172,23,129,255,125,53,9,255,15,193,18,1,26,49,11,255,181,174,201,1,135,201,14,255,100,19,149,0,219,98,79,0,42,99,143,254,96,0,48,255,197,249,83,254,104,149,79,255,235,110,136,254,82,128,44,255,65,41,36,254,88,211, +10,0,187,121,187,0,98,134,199,0,171,188,179,254,210,11,238,255,66,123,130,254,52,234,61,0,48,113,23,254,6,86,120,255,119,178,245,0,87,129,201,0,242,141,209,0,202,114,85,0,148,22,161,0,103,195,48,0,25,49,171,255,138,67,130,0,182,73,122,254,148,24,130,0,211,229,154,0,32,155,158,0,84,105,61,0,177,194,9,255,166,89,86,1,54,83,187,0,249,40,117,255,109,3,215,255,53,146,44,1,63,47,179,0,194,216,3,254,14,84,136,0,136,177,13,255,72,243,186,255,117,17,125,255,211,58,211,255,93,79,223,0,90,88,245,255,139,209, +111,255,70,222,47,0,10,246,79,255,198,217,178,0,227,225,11,1,78,126,179,255,62,43,126,0,103,148,35,0,129,8,165,254,245,240,148,0,61,51,142,0,81,208,134,0,15,137,115,255,211,119,236,255,159,245,248,255,2,134,136,255,230,139,58,1,160,164,254,0,114,85,141,255,49,166,182,255,144,70,84,1,85,182,7,0,46,53,93,0,9,166,161,255,55,162,178,255,45,184,188,0,146,28,44,254,169,90,49,0,120,178,241,1,14,123,127,255,7,241,199,1,189,66,50,255,198,143,101,254,189,243,135,255,141,24,24,254,75,97,87,0,118,251,154,1,237, +54,156,0,171,146,207,255,131,196,246,255,136,64,113,1,151,232,57,0,240,218,115,0,49,61,27,255,64,129,73,1,252,169,27,255,40,132,10,1,90,201,193,255,252,121,240,1,186,206,41,0,43,198,97,0,145,100,183,0,204,216,80,254,172,150,65,0,249,229,196,254,104,123,73,255,77,104,96,254,130,180,8,0,104,123,57,0,220,202,229,255,102,249,211,0,86,14,232,255,182,78,209,0,239,225,164,0,106,13,32,255,120,73,17,255,134,67,233,0,83,254,181,0,183,236,112,1,48,64,131,255,241,216,243,255,65,193,226,0,206,241,100,254,100, +134,166,255,237,202,197,0,55,13,81,0,32,124,102,255,40,228,177,0,118,181,31,1,231,160,134,255,119,187,202,0,0,142,60,255,128,38,189,255,166,201,150,0,207,120,26,1,54,184,172,0,12,242,204,254,133,66,230,0,34,38,31,1,184,112,80,0,32,51,165,254,191,243,55,0,58,73,146,254,155,167,205,255,100,104,152,255,197,254,207,255,173,19,247,0,238,10,202,0,239,151,242,0,94,59,39,255,240,29,102,255,10,92,154,255,229,84,219,255,161,129,80,0,208,90,204,1,240,219,174,255,158,102,145,1,53,178,76,255,52,108,168,1,83,222, +107,0,211,36,109,0,118,58,56,0,8,29,22,0,237,160,199,0,170,209,157,0,137,71,47,0,143,86,32,0,198,242,2,0,212,48,136,1,92,172,186,0,230,151,105,1,96,191,229,0,138,80,191,254,240,216,130,255,98,43,6,254,168,196,49,0,253,18,91,1,144,73,121,0,61,146,39,1,63,104,24,255,184,165,112,254,126,235,98,0,80,213,98,255,123,60,87,255,82,140,245,1,223,120,173,255,15,198,134,1,206,60,239,0,231,234,92,255,33,238,19,255,165,113,142,1,176,119,38,0,160,43,166,254,239,91,105,0,107,61,194,1,25,4,68,0,15,139,51,0,164,132, +106,255,34,116,46,254,168,95,197,0,137,212,23,0,72,156,58,0,137,112,69,254,150,105,154,255,236,201,157,0,23,212,154,255,136,82,227,254,226,59,221,255,95,149,192,0,81,118,52,255,33,43,215,1,14,147,75,255,89,156,121,254,14,18,79,0,147,208,139,1,151,218,62,255,156,88,8,1,210,184,98,255,20,175,123,255,102,83,229,0,220,65,116,1,150,250,4,255,92,142,220,255,34,247,66,255,204,225,179,254,151,81,151,0,71,40,236,255,138,63,62,0,6,79,240,255,183,185,181,0,118,50,27,0,63,227,192,0,123,99,58,1,50,224,155,255, +17,225,223,254,220,224,77,255,14,44,123,1,141,128,175,0,248,212,200,0,150,59,183,255,147,97,29,0,150,204,181,0,253,37,71,0,145,85,119,0,154,200,186,0,2,128,249,255,83,24,124,0,14,87,143,0,168,51,245,1,124,151,231,255,208,240,197,1,124,190,185,0,48,58,246,0,20,233,232,0,125,18,98,255,13,254,31,255,245,177,130,255,108,142,35,0,171,125,242,254,140,12,34,255,165,161,162,0,206,205,101,0,247,25,34,1,100,145,57,0,39,70,57,0,118,204,203,255,242,0,162,0,165,244,30,0,198,116,226,0,128,111,153,255,140,54,182, +1,60,122,15,255,155,58,57,1,54,50,198,0,171,211,29,255,107,138,167,255,173,107,199,255,109,161,193,0,89,72,242,255,206,115,89,255,250,254,142,254,177,202,94,255,81,89,50,0,7,105,66,255,25,254,255,254,203,64,23,255,79,222,108,255,39,249,75,0,241,124,50,0,239,152,133,0,221,241,105,0,147,151,98,0,213,161,121,254,242,49,137,0,233,37,249,254,42,183,27,0,184,119,230,255,217,32,163,255,208,251,228,1,137,62,131,255,79,64,9,254,94,48,113,0,17,138,50,254,193,255,22,0,247,18,197,1,67,55,104,0,16,205,95,255, +48,37,66,0,55,156,63,1,64,82,74,255,200,53,71,254,239,67,125,0,26,224,222,0,223,137,93,255,30,224,202,255,9,220,132,0,198,38,235,1,102,141,86,0,60,43,81,1,136,28,26,0,233,36,8,254,207,242,148,0,164,162,63,0,51,46,224,255,114,48,79,255,9,175,226,0,222,3,193,255,47,160,232,255,255,93,105,254,14,42,230,0,26,138,82,1,208,43,244,0,27,39,38,255,98,208,127,255,64,149,182,255,5,250,209,0,187,60,28,254,49,25,218,255,169,116,205,255,119,18,120,0,156,116,147,255,132,53,109,255,13,10,202,0,110,83,167,0,157,219, +137,255,6,3,130,255,50,167,30,255,60,159,47,255,129,128,157,254,94,3,189,0,3,166,68,0,83,223,215,0,150,90,194,1,15,168,65,0,227,83,51,255,205,171,66,255,54,187,60,1,152,102,45,255,119,154,225,0,240,247,136,0,100,197,178,255,139,71,223,255,204,82,16,1,41,206,42,255,156,192,221,255,216,123,244,255,218,218,185,255,187,186,239,255,252,172,160,255,195,52,22,0,144,174,181,254,187,100,115,255,211,78,176,255,27,7,193,0,147,213,104,255,90,201,10,255,80,123,66,1,22,33,186,0,1,7,99,254,30,206,10,0,229,234,5, +0,53,30,210,0,138,8,220,254,71,55,167,0,72,225,86,1,118,190,188,0,254,193,101,1,171,249,172,255,94,158,183,254,93,2,108,255,176,93,76,255,73,99,79,255,74,64,129,254,246,46,65,0,99,241,127,254,246,151,102,255,44,53,208,254,59,102,234,0,154,175,164,255,88,242,32,0,111,38,1,0,255,182,190,255,115,176,15,254,169,60,129,0,122,237,241,0,90,76,63,0,62,74,120,255,122,195,110,0,119,4,178,0,222,242,210,0,130,33,46,254,156,40,41,0,167,146,112,1,49,163,111,255,121,176,235,0,76,207,14,255,3,25,198,1,41,235,213, +0,85,36,214,1,49,92,109,255,200,24,30,254,168,236,195,0,145,39,124,1,236,195,149,0,90,36,184,255,67,85,170,255,38,35,26,254,131,124,68,255,239,155,35,255,54,201,164,0,196,22,117,255,49,15,205,0,24,224,29,1,126,113,144,0,117,21,182,0,203,159,141,0,223,135,77,0,176,230,176,255,190,229,215,255,99,37,181,255,51,21,138,255,25,189,89,255,49,48,165,254,152,45,247,0,170,108,222,0,80,202,5,0,27,69,103,254,204,22,129,255,180,252,62,254,210,1,91,255,146,110,254,255,219,162,28,0,223,252,213,1,59,8,33,0,206,16, +244,0,129,211,48,0,107,160,208,0,112,59,209,0,109,77,216,254,34,21,185,255,246,99,56,255,179,139,19,255,185,29,50,255,84,89,19,0,74,250,98,255,225,42,200,255,192,217,205,255,210,16,167,0,99,132,95,1,43,230,57,0,254,11,203,255,99,188,63,255,119,193,251,254,80,105,54,0,232,181,189,1,183,69,112,255,208,171,165,255,47,109,180,255,123,83,165,0,146,162,52,255,154,11,4,255,151,227,90,255,146,137,97,254,61,233,41,255,94,42,55,255,108,164,236,0,152,68,254,0,10,140,131,255,10,106,79,254,243,158,137,0,67,178, +66,254,177,123,198,255,15,62,34,0,197,88,42,255,149,95,177,255,152,0,198,255,149,254,113,255,225,90,163,255,125,217,247,0,18,17,224,0,128,66,120,254,192,25,9,255,50,221,205,0,49,212,70,0,233,255,164,0,2,209,9,0,221,52,219,254,172,224,244,255,94,56,206,1,242,179,2,255,31,91,164,1,230,46,138,255,189,230,220,0,57,47,61,255,111,11,157,0,177,91,152,0,28,230,98,0,97,87,126,0,198,89,145,255,167,79,107,0,249,77,160,1,29,233,230,255,150,21,86,254,60,11,193,0,151,37,36,254,185,150,243,255,228,212,83,1,172, +151,180,0,201,169,155,0,244,60,234,0,142,235,4,1,67,218,60,0,192,113,75,1,116,243,207,255,65,172,155,0,81,30,156,255,80,72,33,254,18,231,109,255,142,107,21,254,125,26,132,255,176,16,59,255,150,201,58,0,206,169,201,0,208,121,226,0,40,172,14,255,150,61,94,255,56,57,156,255,141,60,145,255,45,108,149,255,238,145,155,255,209,85,31,254,192,12,210,0,99,98,93,254,152,16,151,0,225,185,220,0,141,235,44,255,160,172,21,254,71,26,31,255,13,64,93,254,28,56,198,0,177,62,248,1,182,8,241,0,166,101,148,255,78,81,133, +255,129,222,215,1,188,169,129,255,232,7,97,0,49,112,60,255,217,229,251,0,119,108,138,0,39,19,123,254,131,49,235,0,132,84,145,0,130,230,148,255,25,74,187,0,5,245,54,255,185,219,241,1,18,194,228,255,241,202,102,0,105,113,202,0,155,235,79,0,21,9,178,255,156,1,239,0,200,148,61,0,115,247,210,255,49,221,135,0,58,189,8,1,35,46,9,0,81,65,5,255,52,158,185,255,125,116,46,255,74,140,13,255,210,92,172,254,147,23,71,0,217,224,253,254,115,108,180,255,145,58,48,254,219,177,24,255,156,255,60,1,154,147,242,0,253, +134,87,0,53,75,229,0,48,195,222,255,31,175,50,255,156,210,120,255,208,35,222,255,18,248,179,1,2,10,101,255,157,194,248,255,158,204,101,255,104,254,197,255,79,62,4,0,178,172,101,1,96,146,251,255,65,10,156,0,2,137,165,255,116,4,231,0,242,215,1,0,19,35,29,255,43,161,79,0,59,149,246,1,251,66,176,0,200,33,3,255,80,110,142,255,195,161,17,1,228,56,66,255,123,47,145,254,132,4,164,0,67,174,172,0,25,253,114,0,87,97,87,1,250,220,84,0,96,91,200,255,37,125,59,0,19,65,118,0,161,52,241,255,237,172,6,255,176,191, +255,255,1,65,130,254,223,190,230,0,101,253,231,255,146,35,109,0,250,29,77,1,49,0,19,0,123,90,155,1,22,86,32,255,218,213,65,0,111,93,127,0,60,93,169,255,8,127,182,0,17,186,14,254,253,137,246,255,213,25,48,254,76,238,0,255,248,92,70,255,99,224,139,0,184,9,255,1,7,164,208,0,205,131,198,1,87,214,199,0,130,214,95,0,221,149,222,0,23,38,171,254,197,110,213,0,43,115,140,254,215,177,118,0,96,52,66,1,117,158,237,0,14,64,182,255,46,63,174,255,158,95,190,255,225,205,177,255,43,5,142,255,172,99,212,255,244,187, +147,0,29,51,153,255,228,116,24,254,30,101,207,0,19,246,150,255,134,231,5,0,125,134,226,1,77,65,98,0,236,130,33,255,5,110,62,0,69,108,127,255,7,113,22,0,145,20,83,254,194,161,231,255,131,181,60,0,217,209,177,255,229,148,212,254,3,131,184,0,117,177,187,1,28,14,31,255,176,102,80,0,50,84,151,255,125,31,54,255,21,157,133,255,19,179,139,1,224,232,26,0,34,117,170,255,167,252,171,255,73,141,206,254,129,250,35,0,72,79,236,1,220,229,20,255,41,202,173,255,99,76,238,255,198,22,224,255,108,198,195,255,36,141, +96,1,236,158,59,255,106,100,87,0,110,226,2,0,227,234,222,0,154,93,119,255,74,112,164,255,67,91,2,255,21,145,33,255,102,214,137,255,175,230,103,254,163,246,166,0,93,247,116,254,167,224,28,255,220,2,57,1,171,206,84,0,123,228,17,255,27,120,119,0,119,11,147,1,180,47,225,255,104,200,185,254,165,2,114,0,77,78,212,0,45,154,177,255,24,196,121,254,82,157,182,0,90,16,190,1,12,147,197,0,95,239,152,255,11,235,71,0,86,146,119,255,172,134,214,0,60,131,196,0,161,225,129,0,31,130,120,254,95,200,51,0,105,231,210, +255,58,9,148,255,43,168,221,255,124,237,142,0,198,211,50,254,46,245,103,0,164,248,84,0,152,70,208,255,180,117,177,0,70,79,185,0,243,74,32,0,149,156,207,0,197,196,161,1,245,53,239,0,15,93,246,254,139,240,49,255,196,88,36,255,162,38,123,0,128,200,157,1,174,76,103,255,173,169,34,254,216,1,171,255,114,51,17,0,136,228,194,0,110,150,56,254,106,246,159,0,19,184,79,255,150,77,240,255,155,80,162,0,0,53,169,255,29,151,86,0,68,94,16,0,92,7,110,254,98,117,149,255,249,77,230,255,253,10,140,0,214,124,92,254,35, +118,235,0,89,48,57,1,22,53,166,0,184,144,61,255,179,255,194,0,214,248,61,254,59,110,246,0,121,21,81,254,166,3,228,0,106,64,26,255,69,232,134,255,242,220,53,254,46,220,85,0,113,149,247,255,97,179,103,255,190,127,11,0,135,209,182,0,95,52,129,1,170,144,206,255,122,200,204,255,168,100,146,0,60,144,149,254,70,60,40,0,122,52,177,255,246,211,101,255,174,237,8,0,7,51,120,0,19,31,173,0,126,239,156,255,143,189,203,0,196,128,88,255,233,133,226,255,30,125,173,255,201,108,50,0,123,100,59,255,254,163,3,1,221,148, +181,255,214,136,57,254,222,180,137,255,207,88,54,255,28,33,251,255,67,214,52,1,210,208,100,0,81,170,94,0,145,40,53,0,224,111,231,254,35,28,244,255,226,199,195,254,238,17,230,0,217,217,164,254,169,157,221,0,218,46,162,1,199,207,163,255,108,115,162,1,14,96,187,255,118,60,76,0,184,159,152,0,209,231,71,254,42,164,186,255,186,153,51,254,221,171,182,255,162,142,173,0,235,47,193,0,7,139,16,1,95,164,64,255,16,221,166,0,219,197,16,0,132,29,44,255,100,69,117,255,60,235,88,254,40,81,173,0,71,190,61,255,187, +88,157,0,231,11,23,0,237,117,164,0,225,168,223,255,154,114,116,255,163,152,242,1,24,32,170,0,125,98,113,254,168,19,76,0,17,157,220,254,155,52,5,0,19,111,161,255,71,90,252,255,173,110,240,0,10,198,121,255,253,255,240,255,66,123,210,0,221,194,215,254,121,163,17,255,225,7,99,0,190,49,182,0,115,9,133,1,232,26,138,255,213,68,132,0,44,119,122,255,179,98,51,0,149,90,106,0,71,50,230,255,10,153,118,255,177,70,25,0,165,87,205,0,55,138,234,0,238,30,97,0,113,155,207,0,98,153,127,0,34,107,219,254,117,114,172, +255,76,180,255,254,242,57,179,255,221,34,172,254,56,162,49,255,83,3,255,255,113,221,189,255,188,25,228,254,16,88,89,255,71,28,198,254,22,17,149,255,243,121,254,255,107,202,99,255,9,206,14,1,220,47,153,0,107,137,39,1,97,49,194,255,149,51,197,254,186,58,11,255,107,43,232,1,200,6,14,255,181,133,65,254,221,228,171,255,123,62,231,1,227,234,179,255,34,189,212,254,244,187,249,0,190,13,80,1,130,89,1,0,223,133,173,0,9,222,198,255,66,127,74,0,167,216,93,255,155,168,198,1,66,145,0,0,68,102,46,1,172,90,154,0, +216,128,75,255,160,40,51,0,158,17,27,1,124,240,49,0,236,202,176,255,151,124,192,255,38,193,190,0,95,182,61,0,163,147,124,255,255,165,51,255,28,40,17,254,215,96,78,0,86,145,218,254,31,36,202,255,86,9,5,0,111,41,200,255,237,108,97,0,57,62,44,0,117,184,15,1,45,241,116,0,152,1,220,255,157,165,188,0,250,15,131,1,60,44,125,255,65,220,251,255,75,50,184,0,53,90,128,255,231,80,194,255,136,129,127,1,21,18,187,255,45,58,161,255,71,147,34,0,174,249,11,254,35,141,29,0,239,68,177,255,115,110,58,0,238,190,177,1, +87,245,166,255,190,49,247,255,146,83,184,255,173,14,39,255,146,215,104,0,142,223,120,0,149,200,155,255,212,207,145,1,16,181,217,0,173,32,87,255,255,35,181,0,119,223,161,1,200,223,94,255,70,6,186,255,192,67,85,255,50,169,152,0,144,26,123,255,56,243,179,254,20,68,136,0,39,140,188,254,253,208,5,255,200,115,135,1,43,172,229,255,156,104,187,0,151,251,167,0,52,135,23,0,151,153,72,0,147,197,107,254,148,158,5,255,238,143,206,0,126,153,137,255,88,152,197,254,7,68,167,0,252,159,165,255,239,78,54,255,24,63, +55,255,38,222,94,0,237,183,12,255,206,204,210,0,19,39,246,254,30,74,231,0,135,108,29,1,179,115,0,0,117,118,116,1,132,6,252,255,145,129,161,1,105,67,141,0,82,37,226,255,238,226,228,255,204,214,129,254,162,123,100,255,185,121,234,0,45,108,231,0,66,8,56,255,132,136,128,0,172,224,66,254,175,157,188,0,230,223,226,254,242,219,69,0,184,14,119,1,82,162,56,0,114,123,20,0,162,103,85,255,49,239,99,254,156,135,215,0,111,255,167,254,39,196,214,0,144,38,79,1,249,168,125,0,155,97,156,255,23,52,219,255,150,22,144, +0,44,149,165,255,40,127,183,0,196,77,233,255,118,129,210,255,170,135,230,255,214,119,198,0,233,240,35,0,253,52,7,255,117,102,48,255,21,204,154,255,179,136,177,255,23,2,3,1,149,130,89,255,252,17,159,1,70,60,26,0,144,107,17,0,180,190,60,255,56,182,59,255,110,71,54,255,198,18,129,255,149,224,87,255,223,21,152,255,138,22,182,255,250,156,205,0,236,45,208,255,79,148,242,1,101,70,209,0,103,78,174,0,101,144,172,255,152,136,237,1,191,194,136,0,113,80,125,1,152,4,141,0,155,150,53,255,196,116,245,0,239,114, +73,254,19,82,17,255,124,125,234,255,40,52,191,0,42,210,158,255,155,132,165,0,178,5,42,1,64,92,40,255,36,85,77,255,178,228,118,0,137,66,96,254,115,226,66,0,110,240,69,254,151,111,80,0,167,174,236,255,227,108,107,255,188,242,65,255,183,81,255,0,57,206,181,255,47,34,181,255,213,240,158,1,71,75,95,0,156,40,24,255,102,210,81,0,171,199,228,255,154,34,41,0,227,175,75,0,21,239,195,0,138,229,95,1,76,192,49,0,117,123,87,1,227,225,130,0,125,62,63,255,2,198,171,0,254,36,13,254,145,186,206,0,148,255,244,255,35, +0,166,0,30,150,219,1,92,228,212,0,92,198,60,254,62,133,200,255,201,41,59,0,125,238,109,255,180,163,238,1,140,122,82,0,9,22,88,255,197,157,47,255,153,94,57,0,88,30,182,0,84,161,85,0,178,146,124,0,166,166,7,255,21,208,223,0,156,182,242,0,155,121,185,0,83,156,174,254,154,16,118,255,186,83,232,1,223,58,121,255,29,23,88,0,35,125,127,255,170,5,149,254,164,12,130,255,155,196,29,0,161,96,136,0,7,35,29,1,162,37,251,0,3,46,242,255,0,217,188,0,57,174,226,1,206,233,2,0,57,187,136,254,123,189,9,255,201,117,127, +255,186,36,204,0,231,25,216,0,80,78,105,0,19,134,129,255,148,203,68,0,141,81,125,254,248,165,200,255,214,144,135,0,151,55,166,255,38,235,91,0,21,46,154,0,223,254,150,255,35,153,180,255,125,176,29,1,43,98,30,255,216,122,230,255,233,160,12,0,57,185,12,254,240,113,7,255,5,9,16,254,26,91,108,0,109,198,203,0,8,147,40,0,129,134,228,255,124,186,40,255,114,98,132,254,166,132,23,0,99,69,44,0,9,242,238,255,184,53,59,0,132,129,102,255,52,32,243,254,147,223,200,255,123,83,179,254,135,144,201,255,141,37,56,1, +151,60,227,255,90,73,156,1,203,172,187,0,80,151,47,255,94,137,231,255,36,191,59,255,225,209,181,255,74,215,213,254,6,118,179,255,153,54,193,1,50,0,231,0,104,157,72,1,140,227,154,255,182,226,16,254,96,225,92,255,115,20,170,254,6,250,78,0,248,75,173,255,53,89,6,255,0,180,118,0,72,173,1,0,64,8,206,1,174,133,223,0,185,62,133,255,214,11,98,0,197,31,208,0,171,167,244,255,22,231,181,1,150,218,185,0,247,169,97,1,165,139,247,255,47,120,149,1,103,248,51,0,60,69,28,254,25,179,196,0,124,7,218,254,58,107,81,0, +184,233,156,255,252,74,36,0,118,188,67,0,141,95,53,255,222,94,165,254,46,61,53,0,206,59,115,255,47,236,250,255,74,5,32,1,129,154,238,255,106,32,226,0,121,187,61,255,3,166,241,254,67,170,172,255,29,216,178,255,23,201,252,0,253,110,243,0,200,125,57,0,109,192,96,255,52,115,238,0,38,121,243,255,201,56,33,0,194,118,130,0,75,96,25,255,170,30,230,254,39,63,253,0,36,45,250,255,251,1,239,0,160,212,92,1,45,209,237,0,243,33,87,254,237,84,201,255,212,18,157,254,212,99,127,255,217,98,16,254,139,172,239,0,168, +201,130,255,143,193,169,255,238,151,193,1,215,104,41,0,239,61,165,254,2,3,242,0,22,203,177,254,177,204,22,0,149,129,213,254,31,11,41,255,0,159,121,254,160,25,114,255,162,80,200,0,157,151,11,0,154,134,78,1,216,54,252,0,48,103,133,0,105,220,197,0,253,168,77,254,53,179,23,0,24,121,240,1,255,46,96,255,107,60,135,254,98,205,249,255,63,249,119,255,120,59,211,255,114,180,55,254,91,85,237,0,149,212,77,1,56,73,49,0,86,198,150,0,93,209,160,0,69,205,182,255,244,90,43,0,20,36,176,0,122,116,221,0,51,167,39,1, +231,1,63,255,13,197,134,0,3,209,34,255,135,59,202,0,167,100,78,0,47,223,76,0,185,60,62,0,178,166,123,1,132,12,161,255,61,174,43,0,195,69,144,0,127,47,191,1,34,44,78,0,57,234,52,1,255,22,40,255,246,94,146,0,83,228,128,0,60,78,224,255,0,96,210,255,153,175,236,0,159,21,73,0,180,115,196,254,131,225,106,0,255,167,134,0,159,8,112,255,120,68,194,255,176,196,198,255,118,48,168,255,93,169,1,0,112,200,102,1,74,24,254,0,19,141,4,254,142,62,63,0,131,179,187,255,77,156,155,255,119,86,164,0,170,208,146,255,208, +133,154,255,148,155,58,255,162,120,232,254,252,213,155,0,241,13,42,0,94,50,131,0,179,170,112,0,140,83,151,255,55,119,84,1,140,35,239,255,153,45,67,1,236,175,39,0,54,151,103,255,158,42,65,255,196,239,135,254,86,53,203,0,149,97,47,254,216,35,17,255,70,3,70,1,103,36,90,255,40,26,173,0,184,48,13,0,163,219,217,255,81,6,1,255,221,170,108,254,233,208,93,0,100,201,249,254,86,36,35,255,209,154,30,1,227,201,251,255,2,189,167,254,100,57,3,0,13,128,41,0,197,100,75,0,150,204,235,255,145,174,59,0,120,248,149,255, +85,55,225,0,114,210,53,254,199,204,119,0,14,247,74,1,63,251,129,0,67,104,151,1,135,130,80,0,79,89,55,255,117,230,157,255,25,96,143,0,213,145,5,0,69,241,120,1,149,243,95,255,114,42,20,0,131,72,2,0,154,53,20,255,73,62,109,0,196,102,152,0,41,12,204,255,122,38,11,1,250,10,145,0,207,125,148,0,246,244,222,255,41,32,85,1,112,213,126,0,162,249,86,1,71,198,127,255,81,9,21,1,98,39,4,255,204,71,45,1,75,111,137,0,234,59,231,0,32,48,95,255,204,31,114,1,29,196,181,255,51,241,167,254,93,109,142,0,104,144,45,0,235, +12,181,255,52,112,164,0,76,254,202,255,174,14,162,0,61,235,147,255,43,64,185,254,233,125,217,0,243,88,167,254,74,49,8,0,156,204,66,0,124,214,123,0,38,221,118,1,146,112,236,0,114,98,177,0,151,89,199,0,87,197,112,0,185,149,161,0,44,96,165,0,248,179,20,255,188,219,216,254,40,62,13,0,243,142,141,0,229,227,206,255,172,202,35,255,117,176,225,255,82,110,38,1,42,245,14,255,20,83,97,0,49,171,10,0,242,119,120,0,25,232,61,0,212,240,147,255,4,115,56,255,145,17,239,254,202,17,251,255,249,18,245,255,99,117,239, +0,184,4,179,255,246,237,51,255,37,239,137,255,166,112,166,255,81,188,33,255,185,250,142,255,54,187,173,0,208,112,201,0,246,43,228,1,104,184,88,255,212,52,196,255,51,117,108,255,254,117,155,0,46,91,15,255,87,14,144,255,87,227,204,0,83,26,83,1,159,76,227,0,159,27,213,1,24,151,108,0,117,144,179,254,137,209,82,0,38,159,10,0,115,133,201,0,223,182,156,1,110,196,93,255,57,60,233,0,5,167,105,255,154,197,164,0,96,34,186,255,147,133,37,1,220,99,190,0,1,167,84,255,20,145,171,0,194,197,251,254,95,78,133,255, +252,248,243,255,225,93,131,255,187,134,196,255,216,153,170,0,20,118,158,254,140,1,118,0,86,158,15,1,45,211,41,255,147,1,100,254,113,116,76,255,211,127,108,1,103,15,48,0,193,16,102,1,69,51,95,255,107,128,157,0,137,171,233,0,90,124,144,1,106,161,182,0,175,76,236,1,200,141,172,255,163,58,104,0,233,180,52,255,240,253,14,255,162,113,254,255,38,239,138,254,52,46,166,0,241,101,33,254,131,186,156,0,111,208,62,255,124,94,160,255,31,172,254,0,112,174,56,255,188,99,27,255,67,138,251,0,125,58,128,1,156,152,174, +255,178,12,247,255,252,84,158,0,82,197,14,254,172,200,83,255,37,39,46,1,106,207,167,0,24,189,34,0,131,178,144,0,206,213,4,0,161,226,210,0,72,51,105,255,97,45,187,255,78,184,223,255,176,29,251,0,79,160,86,255,116,37,178,0,82,77,213,1,82,84,141,255,226,101,212,1,175,88,199,255,245,94,247,1,172,118,109,255,166,185,190,0,131,181,120,0,87,254,93,255,134,240,73,255,32,245,143,255,139,162,103,255,179,98,18,254,217,204,112,0,147,223,120,255,53,10,243,0,166,140,150,0,125,80,200,255,14,109,219,255,91,218,1, +255,252,252,47,254,109,156,116,255,115,49,127,1,204,87,211,255,148,202,217,255,26,85,249,255,14,245,134,1,76,89,169,255,242,45,230,0,59,98,172,255,114,73,132,254,78,155,49,255,158,126,84,0,49,175,43,255,16,182,84,255,157,103,35,0,104,193,109,255,67,221,154,0,201,172,1,254,8,162,88,0,165,1,29,255,125,155,229,255,30,154,220,1,103,239,92,0,220,1,109,255,202,198,1,0,94,2,142,1,36,54,44,0,235,226,158,255,170,251,214,255,185,77,9,0,97,74,242,0,219,163,149,255,240,35,118,255,223,114,88,254,192,199,3,0,106, +37,24,255,201,161,118,255,97,89,99,1,224,58,103,255,101,199,147,254,222,60,99,0,234,25,59,1,52,135,27,0,102,3,91,254,168,216,235,0,229,232,136,0,104,60,129,0,46,168,238,0,39,191,67,0,75,163,47,0,143,97,98,255,56,216,168,1,168,233,252,255,35,111,22,255,92,84,43,0,26,200,87,1,91,253,152,0,202,56,70,0,142,8,77,0,80,10,175,1,252,199,76,0,22,110,82,255,129,1,194,0,11,128,61,1,87,14,145,255,253,222,190,1,15,72,174,0,85,163,86,254,58,99,44,255,45,24,188,254,26,205,15,0,19,229,210,254,248,67,195,0,99,71, +184,0,154,199,37,255,151,243,121,255,38,51,75,255,201,85,130,254,44,65,250,0,57,147,243,254,146,43,59,255,89,28,53,0,33,84,24,255,179,51,18,254,189,70,83,0,11,156,179,1,98,134,119,0,158,111,111,0,119,154,73,255,200,63,140,254,45,13,13,255,154,192,2,254,81,72,42,0,46,160,185,254,44,112,6,0,146,215,149,1,26,176,104,0,68,28,87,1,236,50,153,255,179,128,250,254,206,193,191,255,166,92,137,254,53,40,239,0,210,1,204,254,168,173,35,0,141,243,45,1,36,50,109,255,15,242,194,255,227,159,122,255,176,175,202,254, +70,57,72,0,40,223,56,0,208,162,58,255,183,98,93,0,15,111,12,0,30,8,76,255,132,127,246,255,45,242,103,0,69,181,15,255,10,209,30,0,3,179,121,0,241,232,218,1,123,199,88,255,2,210,202,1,188,130,81,255,94,101,208,1,103,36,45,0,76,193,24,1,95,26,241,255],"i8",4,f.h+10240);G([165,162,187,0,36,114,140,0,202,66,5,255,37,56,147,0,152,11,243,1,127,85,232,255,250,135,212,1,185,177,113,0,90,220,75,255,69,248,146,0,50,111,50,0,92,22,80,0,244,36,115,254,163,100,82,255,25,193,6,1,127,61,36,0,253,67,30,254,65,236, +170,255,161,17,215,254,63,175,140,0,55,127,4,0,79,112,233,0,109,160,40,0,143,83,7,255,65,26,238,255,217,169,140,255,78,94,189,255,0,147,190,255,147,71,186,254,106,77,127,255,233,157,233,1,135,87,237,255,208,13,236,1,155,109,36,255,180,100,218,0,180,163,18,0,190,110,9,1,17,63,123,255,179,136,180,255,165,123,123,255,144,188,81,254,71,240,108,255,25,112,11,255,227,218,51,255,167,50,234,255,114,79,108,255,31,19,115,255,183,240,99,0,227,87,143,255,72,217,248,255,102,169,95,1,129,149,149,0,238,133,12,1, +227,204,35,0,208,115,26,1,102,8,234,0,112,88,143,1,144,249,14,0,240,158,172,254,100,112,119,0,194,141,153,254,40,56,83,255,121,176,46,0,42,53,76,255,158,191,154,0,91,209,92,0,173,13,16,1,5,72,226,255,204,254,149,0,80,184,207,0,100,9,122,254,118,101,171,255,252,203,0,254,160,207,54,0,56,72,249,1,56,140,13,255,10,64,107,254,91,101,52,255,225,181,248,1,139,255,132,0,230,145,17,0,233,56,23,0,119,1,241,255,213,169,151,255,99,99,9,254,185,15,191,255,173,103,109,1,174,13,251,255,178,88,7,254,27,59,68,255, +10,33,2,255,248,97,59,0,26,30,146,1,176,147,10,0,95,121,207,1,188,88,24,0,185,94,254,254,115,55,201,0,24,50,70,0,120,53,6,0,142,66,146,0,228,226,249,255,104,192,222,1,173,68,219,0,162,184,36,255,143,102,137,255,157,11,23,0,125,45,98,0,235,93,225,254,56,112,160,255,70,116,243,1,153,249,55,255,129,39,17,1,241,80,244,0,87,69,21,1,94,228,73,255,78,66,65,255,194,227,231,0,61,146,87,255,173,155,23,255,112,116,219,254,216,38,11,255,131,186,133,0,94,212,187,0,100,47,91,0,204,254,175,255,222,18,215,254,173, +68,108,255,227,228,79,255,38,221,213,0,163,227,150,254,31,190,18,0,160,179,11,1,10,90,94,255,220,174,88,0,163,211,229,255,199,136,52,0,130,95,221,255,140,188,231,254,139,113,128,255,117,171,236,254,49,220,20,255,59,20,171,255,228,109,188,0,20,225,32,254,195,16,174,0,227,254,136,1,135,39,105,0,150,77,206,255,210,238,226,0,55,212,132,254,239,57,124,0,170,194,93,255,249,16,247,255,24,151,62,255,10,151,10,0,79,139,178,255,120,242,202,0,26,219,213,0,62,125,35,255,144,2,108,255,230,33,83,255,81,45,216, +1,224,62,17,0,214,217,125,0,98,153,153,255,179,176,106,254,131,93,138,255,109,62,36,255,178,121,32,255,120,252,70,0,220,248,37,0,204,88,103,1,128,220,251,255,236,227,7,1,106,49,198,255,60,56,107,0,99,114,238,0,220,204,94,1,73,187,1,0,89,154,34,0,78,217,165,255,14,195,249,255,9,230,253,255,205,135,245,0,26,252,7,255,84,205,27,1,134,2,112,0,37,158,32,0,231,91,237,255,191,170,204,255,152,7,222,0,109,192,49,0,193,166,146,255,232,19,181,255,105,142,52,255,103,16,27,1,253,200,165,0,195,217,4,255,52,189, +144,255,123,155,160,254,87,130,54,255,78,120,61,255,14,56,41,0,25,41,125,255,87,168,245,0,214,165,70,0,212,169,6,255,219,211,194,254,72,93,164,255,197,33,103,255,43,142,141,0,131,225,172,0,244,105,28,0,68,68,225,0,136,84,13,255,130,57,40,254,139,77,56,0,84,150,53,0,54,95,157,0,144,13,177,254,95,115,186,0,117,23,118,255,244,166,241,255,11,186,135,0,178,106,203,255,97,218,93,0,43,253,45,0,164,152,4,0,139,118,239,0,96,1,24,254,235,153,211,255,168,110,20,255,50,239,176,0,114,41,232,0,193,250,53,0,254, +160,111,254,136,122,41,255,97,108,67,0,215,152,23,255,140,209,212,0,42,189,163,0,202,42,50,255,106,106,189,255,190,68,217,255,233,58,117,0,229,220,243,1,197,3,4,0,37,120,54,254,4,156,134,255,36,61,171,254,165,136,100,255,212,232,14,0,90,174,10,0,216,198,65,255,12,3,64,0,116,113,115,255,248,103,8,0,231,125,18,255,160,28,197,0,30,184,35,1,223,73,249,255,123,20,46,254,135,56,37,255,173,13,229,1,119,161,34,255,245,61,73,0,205,125,112,0,137,104,134,0,217,246,30,255,237,142,143,0,65,159,102,255,108,164, +190,0,219,117,173,255,34,37,120,254,200,69,80,0,31,124,218,254,74,27,160,255,186,154,199,255,71,199,252,0,104,81,159,1,17,200,39,0,211,61,192,1,26,238,91,0,148,217,12,0,59,91,213,255,11,81,183,255,129,230,122,255,114,203,145,1,119,180,66,255,72,138,180,0,224,149,106,0,119,82,104,255,208,140,43,0,98,9,182,255,205,101,134,255,18,101,38,0,95,197,166,255,203,241,147,0,62,208,145,255,133,246,251,0,2,169,14,0,13,247,184,0,142,7,254,0,36,200,23,255,88,205,223,0,91,129,52,255,21,186,30,0,143,228,210,1,247, +234,248,255,230,69,31,254,176,186,135,255,238,205,52,1,139,79,43,0,17,176,217,254,32,243,67,0,242,111,233,0,44,35,9,255,227,114,81,1,4,71,12,255,38,105,191,0,7,117,50,255,81,79,16,0,63,68,65,255,157,36,110,255,77,241,3,255,226,45,251,1,142,25,206,0,120,123,209,1,28,254,238,255,5,128,126,255,91,222,215,255,162,15,191,0,86,240,73,0,135,185,81,254,44,241,163,0,212,219,210,255,112,162,155,0,207,101,118,0,168,72,56,255,196,5,52,0,72,172,242,255,126,22,157,255,146,96,59,255,162,121,152,254,140,16,95,0, +195,254,200,254,82,150,162,0,119,43,145,254,204,172,78,255,166,224,159,0,104,19,237,255,245,126,208,255,226,59,213,0,117,217,197,0,152,72,237,0,220,31,23,254,14,90,231,255,188,212,64,1,60,101,246,255,85,24,86,0,1,177,109,0,146,83,32,1,75,182,192,0,119,241,224,0,185,237,27,255,184,101,82,1,235,37,77,255,253,134,19,0,232,246,122,0,60,106,179,0,195,11,12,0,109,66,235,1,125,113,59,0,61,40,164,0,175,104,240,0,2,47,187,255,50,12,141,0,194,139,181,255,135,250,104,0,97,92,222,255,217,149,201,255,203,241, +118,255,79,151,67,0,122,142,218,255,149,245,239,0,138,42,200,254,80,37,97,255,124,112,167,255,36,138,87,255,130,29,147,255,241,87,78,255,204,97,19,1,177,209,22,255,247,227,127,254,99,119,83,255,212,25,198,1,16,179,179,0,145,77,172,254,89,153,14,255,218,189,167,0,107,233,59,255,35,33,243,254,44,112,112,255,161,127,79,1,204,175,10,0,40,21,138,254,104,116,228,0,199,95,137,255,133,190,168,255,146,165,234,1,183,99,39,0,183,220,54,254,255,222,133,0,162,219,121,254,63,239,6,0,225,102,54,255,251,18,246,0, +4,34,129,1,135,36,131,0,206,50,59,1,15,97,183,0,171,216,135,255,101,152,43,255,150,251,91,0,38,145,95,0,34,204,38,254,178,140,83,255,25,129,243,255,76,144,37,0,106,36,26,254,118,144,172,255,68,186,229,255,107,161,213,255,46,163,68,255,149,170,253,0,187,17,15,0,218,160,165,255,171,35,246,1,96,13,19,0,165,203,117,0,214,107,192,255,244,123,177,1,100,3,104,0,178,242,97,255,251,76,130,255,211,77,42,1,250,79,70,255,63,244,80,1,105,101,246,0,61,136,58,1,238,91,213,0,14,59,98,255,167,84,77,0,17,132,46,254, +57,175,197,255,185,62,184,0,76,64,207,0,172,175,208,254,175,74,37,0,138,27,211,254,148,125,194,0,10,89,81,0,168,203,101,255,43,213,209,1,235,245,54,0,30,35,226,255,9,126,70,0,226,125,94,254,156,117,20,255,57,248,112,1,230,48,64,255,164,92,166,1,224,214,230,255,36,120,143,0,55,8,43,255,251,1,245,1,106,98,165,0,74,107,106,254,53,4,54,255,90,178,150,1,3,120,123,255,244,5,89,1,114,250,61,255,254,153,82,1,77,15,17,0,57,238,90,1,95,223,230,0,236,52,47,254,103,148,164,255,121,207,36,1,18,16,185,255,75,20, +74,0,187,11,101,0,46,48,129,255,22,239,210,255,77,236,129,255,111,77,204,255,61,72,97,255,199,217,251,255,42,215,204,0,133,145,201,255,57,230,146,1,235,100,198,0,146,73,35,254,108,198,20,255,182,79,210,255,82,103,136,0,246,108,176,0,34,17,60,255,19,74,114,254,168,170,78,255,157,239,20,255,149,41,168,0,58,121,28,0,79,179,134,255,231,121,135,255,174,209,98,255,243,122,190,0,171,166,205,0,212,116,48,0,29,108,66,255,162,222,182,1,14,119,21,0,213,39,249,255,254,223,228,255,183,165,198,0,133,190,48,0,124, +208,109,255,119,175,85,255,9,209,121,1,48,171,189,255,195,71,134,1,136,219,51,255,182,91,141,254,49,159,72,0,35,118,245,255,112,186,227,255,59,137,31,0,137,44,163,0,114,103,60,254,8,213,150,0,162,10,113,255,194,104,72,0,220,131,116,255,178,79,92,0,203,250,213,254,93,193,189,255,130,255,34,254,212,188,151,0,136,17,20,255,20,101,83,255,212,206,166,0,229,238,73,255,151,74,3,255,168,87,215,0,155,188,133,255,166,129,73,0,240,79,133,255,178,211,81,255,203,72,163,254,193,168,165,0,14,164,199,254,30,255, +204,0,65,72,91,1,166,74,102,255,200,42,0,255,194,113,227,255,66,23,208,0,229,216,100,255,24,239,26,0,10,233,62,255,123,10,178,1,26,36,174,255,119,219,199,1,45,163,190,0,16,168,42,0,166,57,198,255,28,26,26,0,126,165,231,0,251,108,100,255,61,229,121,255,58,118,138,0,76,207,17,0,13,34,112,254,89,16,168,0,37,208,105,255,35,201,215,255,40,106,101,254,6,239,114,0,40,103,226,254,246,127,110,255,63,167,58,0,132,240,142,0,5,158,88,255,129,73,158,255,94,89,146,0,230,54,146,0,8,45,173,0,79,169,1,0,115,186,247, +0,84,64,131,0,67,224,253,255,207,189,64,0,154,28,81,1,45,184,54,255,87,212,224,255,0,96,73,255,129,33,235,1,52,66,80,255,251,174,155,255,4,179,37,0,234,164,93,254,93,175,253,0,198,69,87,255,224,106,46,0,99,29,210,0,62,188,114,255,44,234,8,0,169,175,247,255,23,109,137,255,229,182,39,0,192,165,94,254,245,101,217,0,191,88,96,0,196,94,99,255,106,238,11,254,53,126,243,0,94,1,101,255,46,147,2,0,201,124,124,255,141,12,218,0,13,166,157,1,48,251,237,255,155,250,124,255,106,148,146,255,182,13,202,0,28,61,167, +0,217,152,8,254,220,130,45,255,200,230,255,1,55,65,87,255,93,191,97,254,114,251,14,0,32,105,92,1,26,207,141,0,24,207,13,254,21,50,48,255,186,148,116,255,211,43,225,0,37,34,162,254,164,210,42,255,68,23,96,255,182,214,8,255,245,117,137,255,66,195,50,0,75,12,83,254,80,140,164,0,9,165,36,1,228,110,227,0,241,17,90,1,25,52,212,0,6,223,12,255,139,243,57,0,12,113,75,1,246,183,191,255,213,191,69,255,230,15,142,0,1,195,196,255,138,171,47,255,64,63,106,1,16,169,214,255,207,174,56,1,88,73,133,255,182,133,140, +0,177,14,25,255,147,184,53,255,10,227,161,255,120,216,244,255,73,77,233,0,157,238,139,1,59,65,233,0,70,251,216,1,41,184,153,255,32,203,112,0,146,147,253,0,87,101,109,1,44,82,133,255,244,150,53,255,94,152,232,255,59,93,39,255,88,147,220,255,78,81,13,1,32,47,252,255,160,19,114,255,93,107,39,255,118,16,211,1,185,119,209,255,227,219,127,254,88,105,236,255,162,110,23,255,36,166,110,255,91,236,221,255,66,234,116,0,111,19,244,254,10,233,26,0,32,183,6,254,2,191,242,0,218,156,53,254,41,60,70,255,168,236,111, +0,121,185,126,255,238,142,207,255,55,126,52,0,220,129,208,254,80,204,164,255,67,23,144,254,218,40,108,255,127,202,164,0,203,33,3,255,2,158,0,0,37,96,188,255,192,49,74,0,109,4,0,0,111,167,10,254,91,218,135,255,203,66,173,255,150,194,226,0,201,253,6,255,174,102,121,0,205,191,110,0,53,194,4,0,81,40,45,254,35,102,143,255,12,108,198,255,16,27,232,255,252,71,186,1,176,110,114,0,142,3,117,1,113,77,142,0,19,156,197,1,92,47,252,0,53,232,22,1,54,18,235,0,46,35,189,255,236,212,129,0,2,96,208,254,200,238,199, +255,59,175,164,255,146,43,231,0,194,217,52,255,3,223,12,0,138,54,178,254,85,235,207,0,232,207,34,0,49,52,50,255,166,113,89,255,10,45,216,255,62,173,28,0,111,165,246,0,118,115,91,255,128,84,60,0,167,144,203,0,87,13,243,0,22,30,228,1,177,113,146,255,129,170,230,254,252,153,129,255,145,225,43,0,70,231,5,255,122,105,126,254,86,246,148,255,110,37,154,254,209,3,91,0,68,145,62,0,228,16,165,255,55,221,249,254,178,210,91,0,83,146,226,254,69,146,186,0,93,210,104,254,16,25,173,0,231,186,38,0,189,122,140,255, +251,13,112,255,105,110,93,0,251,72,170,0,192,23,223,255,24,3,202,1,225,93,228,0,153,147,199,254,109,170,22,0,248,101,246,255,178,124,12,255,178,254,102,254,55,4,65,0,125,214,180,0,183,96,147,0,45,117,23,254,132,191,249,0,143,176,203,254,136,183,54,255,146,234,177,0,146,101,86,255,44,123,143,1,33,209,152,0,192,90,41,254,83,15,125,255,213,172,82,0,215,169,144,0,16,13,34,0,32,209,100,255,84,18,249,1,197,17,236,255,217,186,230,0,49,160,176,255,111,118,97,255,237,104,235,0,79,59,92,254,69,249,11,255,35, +172,74,1,19,118,68,0,222,124,165,255,180,66,35,255,86,174,246,0,43,74,111,255,126,144,86,255,228,234,91,0,242,213,24,254,69,44,235,255,220,180,35,0,8,248,7,255,102,47,92,255,240,205,102,255,113,230,171,1,31,185,201,255,194,246,70,255,122,17,187,0,134,70,199,255,149,3,150,255,117,63,103,0,65,104,123,255,212,54,19,1,6,141,88,0,83,134,243,255,136,53,103,0,169,27,180,0,177,49,24,0,111,54,167,0,195,61,215,255,31,1,108,1,60,42,70,0,185,3,162,255,194,149,40,255,246,127,38,254,190,119,38,255,61,119,8,1,96, +161,219,255,42,203,221,1,177,242,164,255,245,159,10,0,116,196,0,0,5,93,205,254,128,127,179,0,125,237,246,255,149,162,217,255,87,37,20,254,140,238,192,0,9,9,193,0,97,1,226,0,29,38,10,0,0,136,63,255,229,72,210,254,38,134,92,255,78,218,208,1,104,36,84,255,12,5,193,255,242,175,61,255,191,169,46,1,179,147,147,255,113,190,139,254,125,172,31,0,3,75,252,254,215,36,15,0,193,27,24,1,255,69,149,255,110,129,118,0,203,93,249,0,138,137,64,254,38,70,6,0,153,116,222,0,161,74,123,0,193,99,79,255,118,59,94,255,61, +12,43,1,146,177,157,0,46,147,191,0,16,255,38,0,11,51,31,1,60,58,98,255,111,194,77,1,154,91,244,0,140,40,144,1,173,10,251,0,203,209,50,254,108,130,78,0,228,180,90,0,174,7,250,0,31,174,60,0,41,171,30,0,116,99,82,255,118,193,139,255,187,173,198,254,218,111,56,0,185,123,216,0,249,158,52,0,52,180,93,255,201,9,91,255,56,45,166,254,132,155,203,255,58,232,110,0,52,211,89,255,253,0,162,1,9,87,183,0,145,136,44,1,94,122,245,0,85,188,171,1,147,92,198,0,0,8,104,0,30,95,174,0,221,230,52,1,247,247,235,255,137,174, +53,255,35,21,204,255,71,227,214,1,232,82,194,0,11,48,227,255,170,73,184,255,198,251,252,254,44,112,34,0,131,101,131,255,72,168,187,0,132,135,125,255,138,104,97,255,238,184,168,255,243,104,84,255,135,216,226,255,139,144,237,0,188,137,150,1,80,56,140,255,86,169,167,255,194,78,25,255,220,17,180,255,17,13,193,0,117,137,212,255,141,224,151,0,49,244,175,0,193,99,175,255,19,99,154,1,255,65,62,255,156,210,55,255,242,244,3,255,250,14,149,0,158,88,217,255,157,207,134,254,251,232,28,0,46,156,251,255,171,56, +184,255,239,51,234,0,142,138,131,255,25,254,243,1,10,201,194,0,63,97,75,0,210,239,162,0,192,200,31,1,117,214,243,0,24,71,222,254,54,40,232,255,76,183,111,254,144,14,87,255,214,79,136,255,216,196,212,0,132,27,140,254,131,5,253,0,124,108,19,255,28,215,75,0,76,222,55,254,233,182,63,0,68,171,191,254,52,111,222,255,10,105,77,255,80,170,235,0,143,24,88,255,45,231,121,0,148,129,224,1,61,246,84,0,253,46,219,255,239,76,33,0,49,148,18,254,230,37,69,0,67,134,22,254,142,155,94,0,31,157,211,254,213,42,30,255, +4,228,247,254,252,176,13,255,39,0,31,254,241,244,255,255,170,45,10,254,253,222,249,0,222,114,132,0,255,47,6,255,180,163,179,1,84,94,151,255,89,209,82,254,229,52,169,255,213,236,0,1,214,56,228,255,135,119,151,255,112,201,193,0,83,160,53,254,6,151,66,0,18,162,17,0,233,97,91,0,131,5,78,1,181,120,53,255,117,95,63,255,237,117,185,0,191,126,136,255,144,119,233,0,183,57,97,1,47,201,187,255,167,165,119,1,45,100,126,0,21,98,6,254,145,150,95,255,120,54,152,0,209,98,104,0,143,111,30,254,184,148,249,0,235,216, +46,0,248,202,148,255,57,95,22,0,242,225,163,0,233,247,232,255,71,171,19,255,103,244,49,255,84,103,93,255,68,121,244,1,82,224,13,0,41,79,43,255,249,206,167,255,215,52,21,254,192,32,22,255,247,111,60,0,101,74,38,255,22,91,84,254,29,28,13,255,198,231,215,254,244,154,200,0,223,137,237,0,211,132,14,0,95,64,206,255,17,62,247,255,233,131,121,1,93,23,77,0,205,204,52,254,81,189,136,0,180,219,138,1,143,18,94,0,204,43,140,254,188,175,219,0,111,98,143,255,151,63,162,255,211,50,71,254,19,146,53,0,146,45,83,254, +178,82,238,255,16,133,84,255,226,198,93,255,201,97,20,255,120,118,35,255,114,50,231,255,162,229,156,255,211,26,12,0,114,39,115,255,206,212,134,0,197,217,160,255,116,129,94,254,199,215,219,255,75,223,249,1,253,116,181,255,232,215,104,255,228,130,246,255,185,117,86,0,14,5,8,0,239,29,61,1,237,87,133,255,125,146,137,254,204,168,223,0,46,168,245,0,154,105,22,0,220,212,161,255,107,69,24,255,137,218,181,255,241,84,198,255,130,122,211,255,141,8,153,255,190,177,118,0,96,89,178,0,255,16,48,254,122,96,105,255, +117,54,232,255,34,126,105,255,204,67,166,0,232,52,138,255,211,147,12,0,25,54,7,0,44,15,215,254,51,236,45,0,190,68,129,1,106,147,225,0,28,93,45,254,236,141,15,255,17,61,161,0,220,115,192,0,236,145,24,254,111,168,169,0,224,58,63,255,127,164,188,0,82,234,75,1,224,158,134,0,209,68,110,1,217,166,217,0,70,225,166,1,187,193,143,255,16,7,88,255,10,205,140,0,117,192,156,1,17,56,38,0,27,124,108,1,171,215,55,255,95,253,212,0,155,135,168,255,246,178,153,254,154,68,74,0,232,61,96,254,105,132,59,0,33,76,199,1, +189,176,130,255,9,104,25,254,75,198,102,255,233,1,112,0,108,220,20,255,114,230,70,0,140,194,133,255,57,158,164,254,146,6,80,255,169,196,97,1,85,183,130,0,70,158,222,1,59,237,234,255,96,25,26,255,232,175,97,255,11,121,248,254,88,35,194,0,219,180,252,254,74,8,227,0,195,227,73,1,184,110,161,255,49,233,164,1,128,53,47,0,82,14,121,255,193,190,58,0,48,174,117,255,132,23,32,0,40,10,134,1,22,51,25,255,240,11,176,255,110,57,146,0,117,143,239,1,157,101,118,255,54,84,76,0,205,184,18,255,47,4,72,255,78,112,85, +255,193,50,66,1,93,16,52,255,8,105,134,0,12,109,72,255,58,156,251,0,144,35,204,0,44,160,117,254,50,107,194,0,1,68,165,255,111,110,162,0,158,83,40,254,76,214,234,0,58,216,205,255,171,96,147,255,40,227,114,1,176,227,241,0,70,249,183,1,136,84,139,255,60,122,247,254,143,9,117,255,177,174,137,254,73,247,143,0,236,185,126,255,62,25,247,255,45,64,56,255,161,244,6,0,34,57,56,1,105,202,83,0,128,147,208,0,6,103,10,255,74,138,65,255,97,80,100,255,214,174,33,255,50,134,74,255,110,151,130,254,111,84,172,0,84, +199,75,254,248,59,112,255,8,216,178,1,9,183,95,0,238,27,8,254,170,205,220,0,195,229,135,0,98,76,237,255,226,91,26,1,82,219,39,255,225,190,199,1,217,200,121,255,81,179,8,255,140,65,206,0,178,207,87,254,250,252,46,255,104,89,110,1,253,189,158,255,144,214,158,255,160,245,54,255,53,183,92,1,21,200,194,255,146,33,113,1,209,1,255,0,235,106,43,255,167,52,232,0,157,229,221,0,51,30,25,0,250,221,27,1,65,147,87,255,79,123,196,0,65,196,223,255,76,44,17,1,85,241,68,0,202,183,249,255,65,212,212,255,9,33,154,1, +71,59,80,0,175,194,59,255,141,72,9,0,100,160,244,0,230,208,56,0,59,25,75,254,80,194,194,0,18,3,200,254,160,159,115,0,132,143,247,1,111,93,57,255,58,237,11,1,134,222,135,255,122,163,108,1,123,43,190,255,251,189,206,254,80,182,72,255,208,246,224,1,17,60,9,0,161,207,38,0,141,109,91,0,216,15,211,255,136,78,110,0,98,163,104,255,21,80,121,255,173,178,183,1,127,143,4,0,104,60,82,254,214,16,13,255,96,238,33,1,158,148,230,255,127,129,62,255,51,255,210,255,62,141,236,254,157,55,224,255,114,39,244,0,192,188, +250,255,228,76,53,0,98,84,81,255,173,203,61,254,147,50,55,255,204,235,191,0,52,197,244,0,88,43,211,254,27,191,119,0,188,231,154,0,66,81,161,0,92,193,160,1,250,227,120,0,123,55,226,0,184,17,72,0,133,168,10,254,22,135,156,255,41,25,103,255,48,202,58,0,186,149,81,255,188,134,239,0,235,181,189,254,217,139,188,255,74,48,82,0,46,218,229,0,189,253,251,0,50,229,12,255,211,141,191,1,128,244,25,255,169,231,122,254,86,47,189,255,132,183,23,255,37,178,150,255,51,137,253,0,200,78,31,0,22,105,50,0,130,60,0,0,132, +163,91,254,23,231,187,0,192,79,239,0,157,102,164,255,192,82,20,1,24,181,103,255,240,9,234,0,1,123,164,255,133,233,0,255,202,242,242,0,60,186,245,0,241,16,199,255,224,116,158,254,191,125,91,255,224,86,207,0,121,37,231,255,227,9,198,255,15,153,239,255,121,232,217,254,75,112,82,0,95,12,57,254,51,214,105,255,148,220,97,1,199,98,36,0,156,209,12,254,10,212,52,0,217,180,55,254,212,170,232,255,216,20,84,255,157,250,135,0,157,99,127,254,1,206,41,0,149,36,70,1,54,196,201,255,87,116,0,254,235,171,150,0,27,163, +234,0,202,135,180,0,208,95,0,254,123,156,93,0,183,62,75,0,137,235,182,0,204,225,255,255,214,139,210,255,2,115,8,255,29,12,111,0,52,156,1,0,253,21,251,255,37,165,31,254,12,130,211,0,106,18,53,254,42,99,154,0,14,217,61,254,216,11,92,255,200,197,112,254,147,38,199,0,36,252,120,254,107,169,77,0,1,123,159,255,207,75,102,0,163,175,196,0,44,1,240,0,120,186,176,254,13,98,76,255,237,124,241,255,232,146,188,255,200,96,224,0,204,31,41,0,208,200,13,0,21,225,96,255,175,156,196,0,247,208,126,0,62,184,244,254,2, +171,81,0,85,115,158,0,54,64,45,255,19,138,114,0,135,71,205,0,227,47,147,1,218,231,66,0,253,209,28,0,244,15,173,255,6,15,118,254,16,150,208,255,185,22,50,255,86,112,207,255,75,113,215,1,63,146,43,255,4,225,19,254,227,23,62,255,14,255,214,254,45,8,205,255,87,197,151,254,210,82,215,255,245,248,247,255,128,248,70,0,225,247,87,0,90,120,70,0,213,245,92,0,13,133,226,0,47,181,5,1,92,163,105,255,6,30,133,254,232,178,61,255,230,149,24,255,18,49,158,0,228,100,61,254,116,243,251,255,77,75,92,1,81,219,147,255, +76,163,254,254,141,213,246,0,232,37,152,254,97,44,100,0,201,37,50,1,212,244,57,0,174,171,183,255,249,74,112,0,166,156,30,0,222,221,97,255,243,93,73,254,251,101,100,255,216,217,93,255,254,138,187,255,142,190,52,255,59,203,177,255,200,94,52,0,115,114,158,255,165,152,104,1,126,99,226,255,118,157,244,1,107,200,16,0,193,90,229,0,121,6,88,0,156,32,93,254,125,241,211,255,14,237,157,255,165,154,21,255,184,224,22,255,250,24,152,255,113,77,31,0,247,171,23,255,237,177,204,255,52,137,145,255,194,182,114,0,224, +234,149,0,10,111,103,1,201,129,4,0,238,142,78,0,52,6,40,255,110,213,165,254,60,207,253,0,62,215,69,0,96,97,0,255,49,45,202,0,120,121,22,255,235,139,48,1,198,45,34,255,182,50,27,1,131,210,91,255,46,54,128,0,175,123,105,255,198,141,78,254,67,244,239,255,245,54,103,254,78,38,242,255,2,92,249,254,251,174,87,255,139,63,144,0,24,108,27,255,34,102,18,1,34,22,152,0,66,229,118,254,50,143,99,0,144,169,149,1,118,30,152,0,178,8,121,1,8,159,18,0,90,101,230,255,129,29,119,0,68,36,11,1,232,183,55,0,23,255,96,255, +161,41,193,255,63,139,222,0,15,179,243,0,255,100,15,255,82,53,135,0,137,57,149,1,99,240,170,255,22,230,228,254,49,180,82,255,61,82,43,0,110,245,217,0,199,125,61,0,46,253,52,0,141,197,219,0,211,159,193,0,55,121,105,254,183,20,129,0,169,119,170,255,203,178,139,255,135,40,182,255,172,13,202,255,65,178,148,0,8,207,43,0,122,53,127,1,74,161,48,0,227,214,128,254,86,11,243,255,100,86,7,1,245,68,134,255,61,43,21,1,152,84,94,255,190,60,250,254,239,118,232,255,214,136,37,1,113,76,107,255,93,104,100,1,144,206, +23,255,110,150,154,1,228,103,185,0,218,49,50,254,135,77,139,255,185,1,78,0,0,161,148,255,97,29,233,255,207,148,149,255,160,168,0,0,91,128,171,255,6,28,19,254,11,111,247,0,39,187,150,255,138,232,149,0,117,62,68,255,63,216,188,255,235,234,32,254,29,57,160,255,25,12,241,1,169,60,191,0,32,131,141,255,237,159,123,255,94,197,94,254,116,254,3,255,92,179,97,254,121,97,92,255,170,112,14,0,21,149,248,0,248,227,3,0,80,96,109,0,75,192,74,1,12,90,226,255,161,106,68,1,208,114,127,255,114,42,255,254,74,26,74,255, +247,179,150,254,121,140,60,0,147,70,200,255,214,40,161,255,161,188,201,255,141,65,135,255,242,115,252,0,62,47,202,0,180,149,255,254,130,55,237,0,165,17,186,255,10,169,194,0,156,109,218,255,112,140,123,255,104,128,223,254,177,142,108,255,121,37,219,255,128,77,18,255,111,108,23,1,91,192,75,0,174,245,22,255,4,236,62,255,43,64,153,1,227,173,254,0,237,122,132,1,127,89,186,255,142,82,128,254,252,84,174,0,90,179,177,1,243,214,87,255,103,60,162,255,208,130,14,255,11,130,139,0,206,129,219,255,94,217,157,255, +239,230,230,255,116,115,159,254,164,107,95,0,51,218,2,1,216,125,198,255,140,202,128,254,11,95,68,255,55,9,93,254,174,153,6,255,204,172,96,0,69,160,110,0,213,38,49,254,27,80,213,0,118,125,114,0,70,70,67,255,15,142,73,255,131,122,185,255,243,20,50,254,130,237,40,0,210,159,140,1,197,151,65,255,84,153,66,0,195,126,90,0,16,238,236,1,118,187,102,255,3,24,133,255,187,69,230,0,56,197,92,1,213,69,94,255,80,138,229,1,206,7,230,0,222,111,230,1,91,233,119,255,9,89,7,1,2,98,1,0,148,74,133,255,51,246,180,255,228, +177,112,1,58,189,108,255,194,203,237,254,21,209,195,0,147,10,35,1,86,157,226,0,31,163,139,254,56,7,75,255,62,90,116,0,181,60,169,0,138,162,212,254,81,167,31,0,205,90,112,255,33,112,227,0,83,151,117,1,177,224,73,255,174,144,217,255,230,204,79,255,22,77,232,255,114,78,234,0,224,57,126,254,9,49,141,0,242,147,165,1,104,182,140,255,167,132,12,1,123,68,127,0,225,87,39,1,251,108,8,0,198,193,143,1,121,135,207,255,172,22,70,0,50,68,116,255,101,175,40,255,248,105,233,0,166,203,7,0,110,197,218,0,215,254,26, +254,168,226,253,0,31,143,96,0,11,103,41,0,183,129,203,254,100,247,74,255,213,126,132,0,210,147,44,0,199,234,27,1,148,47,181,0,155,91,158,1,54,105,175,255,2,78,145,254,102,154,95,0,128,207,127,254,52,124,236,255,130,84,71,0,221,243,211,0,152,170,207,0,222,106,199,0,183,84,94,254,92,200,56,255,138,182,115,1,142,96,146,0,133,136,228,0,97,18,150,0,55,251,66,0,140,102,4,0,202,103,151,0,30,19,248,255,51,184,207,0,202,198,89,0,55,197,225,254,169,95,249,255,66,65,68,255,188,234,126,0,166,223,100,1,112,239, +244,0,144,23,194,0,58,39,182,0,244,44,24,254,175,68,179,255,152,118,154,1,176,162,130,0,217,114,204,254,173,126,78,255,33,222,30,255,36,2,91,255,2,143,243,0,9,235,215,0,3,171,151,1,24,215,245,255,168,47,164,254,241,146,207,0,69,129,180,0,68,243,113,0,144,53,72,254,251,45,14,0,23,110,168,0,68,68,79,255,110,70,95,254,174,91,144,255,33,206,95,255,137,41,7,255,19,187,153,254,35,255,112,255,9,145,185,254,50,157,37,0,11,112,49,1,102,8,190,255,234,243,169,1,60,85,23,0,74,39,189,0,116,49,239,0,173,213,210, +0,46,161,108,255,159,150,37,0,196,120,185,255,34,98,6,255,153,195,62,255,97,230,71,255,102,61,76,0,26,212,236,255,164,97,16,0,198,59,146,0,163,23,196,0,56,24,61,0,181,98,193,0,251,147,229,255,98,189,24,255,46,54,206,255,234,82,246,0,183,103,38,1,109,62,204,0,10,240,224,0,146,22,117,255,142,154,120,0,69,212,35,0,208,99,118,1,121,255,3,255,72,6,194,0,117,17,197,255,125,15,23,0,154,79,153,0,214,94,197,255,185,55,147,255,62,254,78,254,127,82,153,0,110,102,63,255,108,82,161,255,105,187,212,1,80,138,39, +0,60,255,93,255,72,12,186,0,210,251,31,1,190,167,144,255,228,44,19,254,128,67,232,0,214,249,107,254,136,145,86,255,132,46,176,0,189,187,227,255,208,22,140,0,217,211,116,0,50,81,186,254,139,250,31,0,30,64,198,1,135,155,100,0,160,206,23,254,187,162,211,255,16,188,63,0,254,208,49,0,85,84,191,0,241,192,242,255,153,126,145,1,234,162,162,255,230,97,216,1,64,135,126,0,190,148,223,1,52,0,43,255,28,39,189,1,64,136,238,0,175,196,185,0,98,226,213,255,127,159,244,1,226,175,60,0,160,233,142,1,180,243,207,255, +69,152,89,1,31,101,21,0,144,25,164,254,139,191,209,0,91,25,121,0,32,147,5,0,39,186,123,255,63,115,230,255,93,167,198,255,143,213,220,255,179,156,19,255,25,66,122,0,214,160,217,255,2,45,62,255,106,79,146,254,51,137,99,255,87,100,231,255,175,145,232,255,101,184,1,255,174,9,125,0,82,37,161,1,36,114,141,255,48,222,142,255,245,186,154,0,5,174,221,254,63,114,155,255,135,55,160,1,80,31,135,0,126,250,179,1,236,218,45,0,20,28,145,1,16,147,73,0,249,189,132,1,17,189,192,255,223,142,198,255,72,20,15,255,250, +53,237,254,15,11,18,0,27,211,113,254,213,107,56,255,174,147,146,255,96,126,48,0,23,193,109,1,37,162,94,0,199,157,249,254,24,128,187,255,205,49,178,254,93,164,42,255,43,119,235,1,88,183,237,255,218,210,1,255,107,254,42,0,230,10,99,255,162,0,226,0,219,237,91,0,129,178,203,0,208,50,95,254,206,208,95,255,247,191,89,254,110,234,79,255,165,61,243,0,20,122,112,255,246,246,185,254,103,4,123,0,233,99,230,1,219,91,252,255,199,222,22,255,179,245,233,255,211,241,234,0,111,250,192,255,85,84,136,0,101,58,50,255, +131,173,156,254,119,45,51,255,118,233,16,254,242,90,214,0,94,159,219,1,3,3,234,255,98,76,92,254,80,54,230,0,5,228,231,254,53,24,223,255,113,56,118,1,20,132,1,255,171,210,236,0,56,241,158,255,186,115,19,255,8,229,174,0,48,44,0,1,114,114,166,255,6,73,226,255,205,89,244,0,137,227,75,1,248,173,56,0,74,120,246,254,119,3,11,255,81,120,198,255,136,122,98,255,146,241,221,1,109,194,78,255,223,241,70,1,214,200,169,255,97,190,47,255,47,103,174,255,99,92,72,254,118,233,180,255,193,35,233,254,26,229,32,255,222, +252,198,0,204,43,71,255,199,84,172,0,134,102,190,0,111,238,97,254,230,40,230,0,227,205,64,254,200,12,225,0,166,25,222,0,113,69,51,255,143,159,24,0,167,184,74,0,29,224,116,254,158,208,233,0,193,116,126,255,212,11,133,255,22,58,140,1,204,36,51,255,232,30,43,0,235,70,181,255,64,56,146,254,169,18,84,255,226,1,13,255,200,50,176,255,52,213,245,254,168,209,97,0,191,71,55,0,34,78,156,0,232,144,58,1,185,74,189,0,186,142,149,254,64,69,127,255,161,203,147,255,176,151,191,0,136,231,203,254,163,182,137,0,161, +126,251,254,233,32,66,0,68,207,66,0,30,28,37,0,93,114,96,1,254,92,247,255,44,171,69,0,202,119,11,255,188,118,50,1,255,83,136,255,71,82,26,0,70,227,2,0,32,235,121,1,181,41,154,0,71,134,229,254,202,255,36,0,41,152,5,0,154,63,73,255,34,182,124,0,121,221,150,255,26,204,213,1,41,172,87,0,90,157,146,255,109,130,20,0,71,107,200,255,243,102,189,0,1,195,145,254,46,88,117,0,8,206,227,0,191,110,253,255,109,128,20,254,134,85,51,255,137,177,112,1,216,34,22,255,131,16,208,255,121,149,170,0,114,19,23,1,166,80,31, +255,113,240,122,0,232,179,250,0,68,110,180,254,210,170,119,0,223,108,164,255,207,79,233,255,27,229,226,254,209,98,81,255,79,68,7,0,131,185,100,0,170,29,162,255,17,162,107,255,57,21,11,1,100,200,181,255,127,65,166,1,165,134,204,0,104,167,168,0,1,164,79,0,146,135,59,1,70,50,128,255,102,119,13,254,227,6,135,0,162,142,179,255,160,100,222,0,27,224,219,1,158,93,195,255,234,141,137,0,16,24,125,255,238,206,47,255,97,17,98,255,116,110,12,255,96,115,77,0,91,227,232,255,248,254,79,255,92,229,6,254,88,198,139, +0,206,75,129,0,250,77,206,255,141,244,123,1,138,69,220,0,32,151,6,1,131,167,22,255,237,68,167,254,199,189,150,0,163,171,138,255,51,188,6,255,95,29,137,254,148,226,179,0,181,107,208,255,134,31,82,255,151,101,45,255,129,202,225,0,224,72,147,0,48,138,151,255,195,64,206,254,237,218,158,0,106,29,137,254,253,189,233,255,103,15,17,255,194,97,255,0,178,45,169,254,198,225,155,0,39,48,117,255,135,106,115,0,97,38,181,0,150,47,65,255,83,130,229,254,246,38,129,0,92,239,154,254,91,99,127,0,161,111,33,255,238,217, +242,255,131,185,195,255,213,191,158,255,41,150,218,0,132,169,131,0,89,84,252,1,171,70,128,255,163,248,203,254,1,50,180,255,124,76,85,1,251,111,80,0,99,66,239,255,154,237,182,255,221,126,133,254,74,204,99,255,65,147,119,255,99,56,167,255,79,248,149,255,116,155,228,255,237,43,14,254,69,137,11,255,22,250,241,1,91,122,143,255,205,249,243,0,212,26,60,255,48,182,176,1,48,23,191,255,203,121,152,254,45,74,213,255,62,90,18,254,245,163,230,255,185,106,116,255,83,35,159,0,12,33,2,255,80,34,62,0,16,87,174,255, +173,101,85,0,202,36,81,254,160,69,204,255,64,225,187,0,58,206,94,0,86,144,47,0,229,86,245,0,63,145,190,1,37,5,39,0,109,251,26,0,137,147,234,0,162,121,145,255,144,116,206,255,197,232,185,255,183,190,140,255,73,12,254,255,139,20,242,255,170,90,239,255,97,66,187,255,245,181,135,254,222,136,52,0,245,5,51,254,203,47,78,0,152,101,216,0,73,23,125,0,254,96,33,1,235,210,73,255,43,209,88,1,7,129,109,0,122,104,228,254,170,242,203,0,242,204,135,255,202,28,233,255,65,6,127,0,159,144,71,0,100,140,95,0,78,150,13, +0,251,107,118,1,182,58,125,255,1,38,108,255,141,189,209,255,8,155,125,1,113,163,91,255,121,79,190,255,134,239,108,255,76,47,248,0,163,228,239,0,17,111,10,0,88,149,75,255,215,235,239,0,167,159,24,255,47,151,108,255,107,209,188,0,233,231,99,254,28,202,148,255,174,35,138,255,110,24,68,255,2,69,181,0,107,102,82,0,102,237,7,0,92,36,237,255,221,162,83,1,55,202,6,255,135,234,135,255,24,250,222,0,65,94,168,254,245,248,210,255,167,108,201,254,255,161,111,0,205,8,254,0,136,13,116,0,100,176,132,255,43,215,126, +255,177,133,130,255,158,79,148,0,67,224,37,1,12,206,21,255,62,34,110,1,237,104,175,255,80,132,111,255,142,174,72,0,84,229,180,254,105,179,140,0,64,248,15,255,233,138,16,0,245,67,123,254,218,121,212,255,63,95,218,1,213,133,137,255,143,182,82,255,48,28,11,0,244,114,141,1,209,175,76,255,157,181,150,255,186,229,3,255,164,157,111,1,231,189,139,0,119,202,190,255,218,106,64,255,68,235,63,254,96,26,172,255,187,47,11,1,215,18,251,255,81,84,89,0,68,58,128,0,94,113,5,1,92,129,208,255,97,15,83,254,9,28,188,0, +239,9,164,0,60,205,152,0,192,163,98,255,184,18,60,0,217,182,139,0,109,59,120,255,4,192,251,0,169,210,240,255,37,172,92,254,148,211,245,255,179,65,52,0,253,13,115,0,185,174,206,1,114,188,149,255,237,90,173,0,43,199,192,255,88,108,113,0,52,35,76,0,66,25,148,255,221,4,7,255,151,241,114,255,190,209,232,0,98,50,199,0,151,150,213,255,18,74,36,1,53,40,7,0,19,135,65,255,26,172,69,0,174,237,85,0,99,95,41,0,3,56,16,0,39,160,177,255,200,106,218,254,185,68,84,255,91,186,61,254,67,143,141,255,13,244,166,255,99, +114,198,0,199,110,163,255,193,18,186,0,124,239,246,1,110,68,22,0,2,235,46,1,212,60,107,0,105,42,105,1,14,230,152,0,7,5,131,0,141,104,154,255,213,3,6,0,131,228,162,255,179,100,28,1,231,123,85,255,206,14,223,1,253,96,230,0,38,152,149,1,98,137,122,0,214,205,3,255,226,152,179,255,6,133,137,0,158,69,140,255,113,162,154,255,180,243,172,255,27,189,115,255,143,46,220,255,213,134,225,255,126,29,69,0,188,43,137,1,242,70,9,0,90,204,255,255,231,170,147,0,23,56,19,254,56,125,157,255,48,179,218,255,79,182,253, +255,38,212,191,1,41,235,124,0,96,151,28,0,135,148,190,0,205,249,39,254,52,96,136,255,212,44,136,255,67,209,131,255,252,130,23,255,219,128,20,255,198,129,118,0,108,101,11,0,178,5,146,1,62,7,100,255,181,236,94,254,28,26,164,0,76,22,112,255,120,102,79,0,202,192,229,1,200,176,215,0,41,64,244,255,206,184,78,0,167,45,63,1,160,35,0,255,59,12,142,255,204,9,144,255,219,94,229,1,122,27,112,0,189,105,109,255,64,208,74,255,251,127,55,1,2,226,198,0,44,76,209,0,151,152,77,255,210,23,46,1,201,171,69,255,44,211, +231,0,190,37,224,255,245,196,62,255,169,181,222,255,34,211,17,0,119,241,197,255,229,35,152,1,21,69,40,255,178,226,161,0,148,179,193,0,219,194,254,1,40,206,51,255,231,92,250,1,67,153,170,0,21,148,241,0,170,69,82,255,121,18,231,255,92,114,3,0,184,62,230,0,225,201,87,255,146,96,162,255,181,242,220,0,173,187,221,1,226,62,170,255,56,126,217,1,117,13,227,255,179,44,239,0,157,141,155,255,144,221,83,0,235,209,208,0,42,17,165,1,251,81,133,0,124,245,201,254,97,211,24,255,83,214,166,0,154,36,9,255,248,47,127, +0,90,219,140,255,161,217,38,254,212,147,63,255,66,84,148,1,207,3,1,0,230,134,89,1,127,78,122,255,224,155,1,255,82,136,74,0,178,156,208,255,186,25,49,255,222,3,210,1,229,150,190,255,85,162,52,255,41,84,141,255,73,123,84,254,93,17,150,0,119,19,28,1,32,22,215,255,28,23,204,255,142,241,52,255,228,52,125,0,29,76,207,0,215,167,250,254,175,164,230,0,55,207,105,1,109,187,245,255,161,44,220,1,41,101,128,255,167,16,94,0,93,214,107,255,118,72,0,254,80,61,234,255,121,175,125,0,139,169,251,0,97,39,147,254,250, +196,49,255,165,179,110,254,223,70,187,255,22,142,125,1,154,179,138,255,118,176,42,1,10,174,153,0,156,92,102,0,168,13,161,255,143,16,32,0,250,197,180,255,203,163,44,1,87,32,36,0,161,153,20,255,123,252,15,0,25,227,80,0,60,88,142,0,17,22,201,1,154,205,77,255,39,63,47,0,8,122,141,0,128,23,182,254,204,39,19,255,4,112,29,255,23,36,140,255,210,234,116,254,53,50,63,255,121,171,104,255,160,219,94,0,87,82,14,254,231,42,5,0,165,139,127,254,86,78,38,0,130,60,66,254,203,30,45,255,46,196,122,1,249,53,162,255,136, +143,103,254,215,210,114,0,231,7,160,254,169,152,42,255,111,45,246,0,142,131,135,255,131,71,204,255,36,226,11,0,0,28,242,255,225,138,213,255,247,46,216,254,245,3,183,0,108,252,74,1,206,26,48,255,205,54,246,255,211,198,36,255,121,35,50,0,52,216,202,255,38,139,129,254,242,73,148,0,67,231,141,255,42,47,204,0,78,116,25,1,4,225,191,255,6,147,228,0,58,88,177,0,122,165,229,255,252,83,201,255,224,167,96,1,177,184,158,255,242,105,179,1,248,198,240,0,133,66,203,1,254,36,47,0,45,24,115,255,119,62,254,0,196,225, +186,254,123,141,172,0,26,85,41,255,226,111,183,0,213,231,151,0,4,59,7,255,238,138,148,0,66,147,33,255,31,246,141,255,209,141,116,255,104,112,31,0,88,161,172,0,83,215,230,254,47,111,151,0,45,38,52,1,132,45,204,0,138,128,109,254,233,117,134,255,243,190,173,254,241,236,240,0,82,127,236,254,40,223,161,255,110,182,225,255,123,174,239,0,135,242,145,1,51,209,154,0,150,3,115,254,217,164,252,255,55,156,69,1,84,94,255,255,232,73,45,1,20,19,212,255,96,197,59,254,96,251,33,0,38,199,73,1,64,172,247,255,117,116, +56,255,228,17,18,0,62,138,103,1,246,229,164,255,244,118,201,254,86,32,159,255,109,34,137,1,85,211,186,0,10,193,193,254,122,194,177,0,122,238,102,255,162,218,171,0,108,217,161,1,158,170,34,0,176,47,155,1,181,228,11,255,8,156,0,0,16,75,93,0,206,98,255,1,58,154,35,0,12,243,184,254,67,117,66,255,230,229,123,0,201,42,110,0,134,228,178,254,186,108,118,255],"i8",4,f.h+20480);G([58,19,154,255,82,169,62,255,114,143,115,1,239,196,50,255,173,48,193,255,147,2,84,255,150,134,147,254,95,232,73,0,109,227,52,254, +191,137,10,0,40,204,30,254,76,52,97,255,164,235,126,0,254,124,188,0,74,182,21,1,121,29,35,255,241,30,7,254,85,218,214,255,7,84,150,254,81,27,117,255,160,159,152,254,66,24,221,255,227,10,60,1,141,135,102,0,208,189,150,1,117,179,92,0,132,22,136,255,120,199,28,0,21,129,79,254,182,9,65,0,218,163,169,0,246,147,198,255,107,38,144,1,78,175,205,255,214,5,250,254,47,88,29,255,164,47,204,255,43,55,6,255,131,134,207,254,116,100,214,0,96,140,75,1,106,220,144,0,195,32,28,1,172,81,5,255,199,179,52,255,37,84,203, +0,170,112,174,0,11,4,91,0,69,244,27,1,117,131,92,0,33,152,175,255,140,153,107,255,251,135,43,254,87,138,4,255,198,234,147,254,121,152,84,255,205,101,155,1,157,9,25,0,72,106,17,254,108,153,0,255,189,229,186,0,193,8,176,255,174,149,209,0,238,130,29,0,233,214,126,1,61,226,102,0,57,163,4,1,198,111,51,255,45,79,78,1,115,210,10,255,218,9,25,255,158,139,198,255,211,82,187,254,80,133,83,0,157,129,230,1,243,133,134,255,40,136,16,0,77,107,79,255,183,85,92,1,177,204,202,0,163,71,147,255,152,69,190,0,172,51, +188,1,250,210,172,255,211,242,113,1,89,89,26,255,64,66,111,254,116,152,42,0,161,39,27,255,54,80,254,0,106,209,115,1,103,124,97,0,221,230,98,255,31,231,6,0,178,192,120,254,15,217,203,255,124,158,79,0,112,145,247,0,92,250,48,1,163,181,193,255,37,47,142,254,144,189,165,255,46,146,240,0,6,75,128,0,41,157,200,254,87,121,213,0,1,113,236,0,5,45,250,0,144,12,82,0,31,108,231,0,225,239,119,255,167,7,189,255,187,228,132,255,110,189,34,0,94,44,204,1,162,52,197,0,78,188,241,254,57,20,141,0,244,146,47,1,206,100, +51,0,125,107,148,254,27,195,77,0,152,253,90,1,7,143,144,255,51,37,31,0,34,119,38,255,7,197,118,0,153,188,211,0,151,20,116,254,245,65,52,255,180,253,110,1,47,177,209,0,161,99,17,255,118,222,202,0,125,179,252,1,123,54,126,255,145,57,191,0,55,186,121,0,10,243,138,0,205,211,229,255,125,156,241,254,148,156,185,255,227,19,188,255,124,41,32,255,31,34,206,254,17,57,83,0,204,22,37,255,42,96,98,0,119,102,184,1,3,190,28,0,110,82,218,255,200,204,192,255,201,145,118,0,117,204,146,0,132,32,98,1,192,194,121,0,106, +161,248,1,237,88,124,0,23,212,26,0,205,171,90,255,248,48,216,1,141,37,230,255,124,203,0,254,158,168,30,255,214,248,21,0,112,187,7,255,75,133,239,255,74,227,243,255,250,147,70,0,214,120,162,0,167,9,179,255,22,158,18,0,218,77,209,1,97,109,81,255,244,33,179,255,57,52,57,255,65,172,210,255,249,71,209,255,142,169,238,0,158,189,153,255,174,254,103,254,98,33,14,0,141,76,230,255,113,139,52,255,15,58,212,0,168,215,201,255,248,204,215,1,223,68,160,255,57,154,183,254,47,231,121,0,106,166,137,0,81,136,138,0, +165,43,51,0,231,139,61,0,57,95,59,254,118,98,25,255,151,63,236,1,94,190,250,255,169,185,114,1,5,250,58,255,75,105,97,1,215,223,134,0,113,99,163,1,128,62,112,0,99,106,147,0,163,195,10,0,33,205,182,0,214,14,174,255,129,38,231,255,53,182,223,0,98,42,159,255,247,13,40,0,188,210,177,1,6,21,0,255,255,61,148,254,137,45,129,255,89,26,116,254,126,38,114,0,251,50,242,254,121,134,128,255,204,249,167,254,165,235,215,0,202,177,243,0,133,141,62,0,240,130,190,1,110,175,255,0,0,20,146,1,37,210,121,255,7,39,130,0, +142,250,84,255,141,200,207,0,9,95,104,255,11,244,174,0,134,232,126,0,167,1,123,254,16,193,149,255,232,233,239,1,213,70,112,255,252,116,160,254,242,222,220,255,205,85,227,0,7,185,58,0,118,247,63,1,116,77,177,255,62,245,200,254,63,18,37,255,107,53,232,254,50,221,211,0,162,219,7,254,2,94,43,0,182,62,182,254,160,78,200,255,135,140,170,0,235,184,228,0,175,53,138,254,80,58,77,255,152,201,2,1,63,196,34,0,5,30,184,0,171,176,154,0,121,59,206,0,38,99,39,0,172,80,77,254,0,134,151,0,186,33,241,254,94,253,223, +255,44,114,252,0,108,126,57,255,201,40,13,255,39,229,27,255,39,239,23,1,151,121,51,255,153,150,248,0,10,234,174,255,118,246,4,254,200,245,38,0,69,161,242,1,16,178,150,0,113,56,130,0,171,31,105,0,26,88,108,255,49,42,106,0,251,169,66,0,69,93,149,0,20,57,254,0,164,25,111,0,90,188,90,255,204,4,197,0,40,213,50,1,212,96,132,255,88,138,180,254,228,146,124,255,184,246,247,0,65,117,86,255,253,102,210,254,254,121,36,0,137,115,3,255,60,24,216,0,134,18,29,0,59,226,97,0,176,142,71,0,7,209,161,0,189,84,51,254, +155,250,72,0,213,84,235,255,45,222,224,0,238,148,143,255,170,42,53,255,78,167,117,0,186,0,40,255,125,177,103,255,69,225,66,0,227,7,88,1,75,172,6,0,169,45,227,1,16,36,70,255,50,2,9,255,139,193,22,0,143,183,231,254,218,69,50,0,236,56,161,1,213,131,42,0,138,145,44,254,136,229,40,255,49,63,35,255,61,145,245,255,101,192,2,254,232,167,113,0,152,104,38,1,121,185,218,0,121,139,211,254,119,240,35,0,65,189,217,254,187,179,162,255,160,187,230,0,62,248,14,255,60,78,97,0,255,247,163,255,225,59,91,255,107,71,58, +255,241,47,33,1,50,117,236,0,219,177,63,254,244,90,179,0,35,194,215,255,189,67,50,255,23,135,129,0,104,189,37,255,185,57,194,0,35,62,231,255,220,248,108,0,12,231,178,0,143,80,91,1,131,93,101,255,144,39,2,1,255,250,178,0,5,17,236,254,139,32,46,0,204,188,38,254,245,115,52,255,191,113,73,254,191,108,69,255,22,69,245,1,23,203,178,0,170,99,170,0,65,248,111,0,37,108,153,255,64,37,69,0,0,88,62,254,89,148,144,255,191,68,224,1,241,39,53,0,41,203,237,255,145,126,194,255,221,42,253,255,25,99,151,0,97,253,223, +1,74,115,49,255,6,175,72,255,59,176,203,0,124,183,249,1,228,228,99,0,129,12,207,254,168,192,195,255,204,176,16,254,152,234,171,0,77,37,85,255,33,120,135,255,142,194,227,1,31,214,58,0,213,187,125,255,232,46,60,255,190,116,42,254,151,178,19,255,51,62,237,254,204,236,193,0,194,232,60,0,172,34,157,255,189,16,184,254,103,3,95,255,141,233,36,254,41,25,11,255,21,195,166,0,118,245,45,0,67,213,149,255,159,12,18,255,187,164,227,1,160,25,5,0,12,78,195,1,43,197,225,0,48,142,41,254,196,155,60,255,223,199,18,1, +145,136,156,0,252,117,169,254,145,226,238,0,239,23,107,0,109,181,188,255,230,112,49,254,73,170,237,255,231,183,227,255,80,220,20,0,194,107,127,1,127,205,101,0,46,52,197,1,210,171,36,255,88,3,90,255,56,151,141,0,96,187,255,255,42,78,200,0,254,70,70,1,244,125,168,0,204,68,138,1,124,215,70,0,102,66,200,254,17,52,228,0,117,220,143,254,203,248,123,0,56,18,174,255,186,151,164,255,51,232,208,1,160,228,43,255,249,29,25,1,68,190,63,0,252,126,0,0,168,2,0,0,157,129,0,0,11,0,0,0,173,129,0,0,181,129,0,0,199,129, +0,0,223,129,0,0,243,129,0,0,6,130,0,0,22,130,0,0,41,130,0,0,56,130,0,0,72,130,0,0,95,130,0,0,112,130,0,0,128,130,0,0,168,2,0,0,164,130,0,0,6,0,0,0,152,47,138,66,145,68,55,113,207,251,192,181,165,219,181,233,91,194,86,57,241,17,241,89,164,130,63,146,213,94,28,171,152,170,7,216,1,91,131,18,190,133,49,36,195,125,12,85,116,93,190,114,254,177,222,128,167,6,220,155,116,241,155,193,193,105,155,228,134,71,190,239,198,157,193,15,204,161,12,36,111,44,233,45,170,132,116,74,220,169,176,92,218,136,249,118,82, +81,62,152,109,198,49,168,200,39,3,176,199,127,89,191,243,11,224,198,71,145,167,213,81,99,202,6,103,41,41,20,133,10,183,39,56,33,27,46,252,109,44,77,19,13,56,83,84,115,10,101,187,10,106,118,46,201,194,129,133,44,114,146,161,232,191,162,75,102,26,168,112,139,75,194,163,81,108,199,25,232,146,209,36,6,153,214,133,53,14,244,112,160,106,16,22,193,164,25,8,108,55,30,76,119,72,39,181,188,176,52,179,12,28,57,74,170,216,78,79,202,156,91,243,111,46,104,238,130,143,116,111,99,165,120,20,120,200,132,8,2,199,140, +250,255,190,144,235,108,80,164,247,163,249,190,242,120,113,198,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,8,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,128,0,0,0,27,0,0,0,54,0,0,0,108,0,0,0,216,0,0,0,171,0,0,0,77,0,0,0,154,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255,255,255,255,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255,255,255,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,255,255,255,255,255,79,76,77,95,82,79,79,84,0,79,76,77,95,82,65,84,67,72,69,84,0,79,76,77,95,75,69,89,83,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,34,99,117,114,118,101,50,53,53,49,57,34,58,0,34,101,100,50,53,53,49,57,34,58,0,77,69,71,79,76,77,95,75,69,89,83,0,0,1,2,3,83,85,67,67,69,83,83,0,78,79,84,95,69,78,79,85,71,72,95,82,65,78,68,79,77,0,79,85,84,80,85,84,95,66,85,70,70,69,82,95,84,79,79,95,83,77,65,76,76,0,66,65,68,95,77,69,83,83,65,71,69,95,86,69,82,83,73,79,78,0,66,65,68,95,77,69,83,83,65,71,69,95,70,79,82,77,65,84,0,66,65,68,95,77,69,83,83,65,71,69,95,77,65,67,0,66,65,68,95,77,69,83,83,65,71,69,95,75,69,89,95,73,68,0,73,78,86,65, +76,73,68,95,66,65,83,69,54,52,0,66,65,68,95,65,67,67,79,85,78,84,95,75,69,89,0,85,78,75,78,79,87,78,95,80,73,67,75,76,69,95,86,69,82,83,73,79,78,0,67,79,82,82,85,80,84,69,68,95,80,73,67,75,76,69,0,66,65,68,95,83,69,83,83,73,79,78,95,75,69,89,0,85,78,75,78,79,87,78,95,77,69,83,83,65,71,69,95,73,78,68,69,88,0,85,78,75,78,79,87,78,95,69,82,82,79,82,0,80,105,99,107,108,101,0,99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253, +147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200, +55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22,0,0,0,0,0,0,2,3,9,11,13,14,4,6,18,22,26,28,6,5,27,29,23,18,8,12,36,44,52,56,10,15,45,39,57,54,12,10,54,58,46,36,14,9,63,49,35,42,16,24,72,88,104,112,18,27,65,83,101,126,20,30,90,78,114,108,22,29,83,69,127,98,24,20,108,116, +92,72,26,23,101,127,81,70,28,18,126,98,70,84,30,17,119,105,75,90,32,48,144,176,208,224,34,51,153,187,221,238,36,54,130,166,202,252,38,53,139,173,199,242,40,60,180,156,228,216,42,63,189,151,233,214,44,58,166,138,254,196,46,57,175,129,243,202,48,40,216,232,184,144,50,43,209,227,181,158,52,46,202,254,162,140,54,45,195,245,175,130,56,36,252,196,140,168,58,39,245,207,129,166,60,34,238,210,150,180,62,33,231,217,155,186,64,96,59,123,187,219,66,99,50,112,182,213,68,102,41,109,161,199,70,101,32,102,172,201, +72,108,31,87,143,227,74,111,22,92,130,237,76,106,13,65,149,255,78,105,4,74,152,241,80,120,115,35,211,171,82,123,122,40,222,165,84,126,97,53,201,183,86,125,104,62,196,185,88,116,87,15,231,147,90,119,94,4,234,157,92,114,69,25,253,143,94,113,76,18,240,129,96,80,171,203,107,59,98,83,162,192,102,53,100,86,185,221,113,39,102,85,176,214,124,41,104,92,143,231,95,3,106,95,134,236,82,13,108,90,157,241,69,31,110,89,148,250,72,17,112,72,227,147,3,75,114,75,234,152,14,69,116,78,241,133,25,87,118,77,248,142,20, +89,120,68,199,191,55,115,122,71,206,180,58,125,124,66,213,169,45,111,126,65,220,162,32,97,128,192,118,246,109,173,130,195,127,253,96,163,132,198,100,224,119,177,134,197,109,235,122,191,136,204,82,218,89,149,138,207,91,209,84,155,140,202,64,204,67,137,142,201,73,199,78,135,144,216,62,174,5,221,146,219,55,165,8,211,148,222,44,184,31,193,150,221,37,179,18,207,152,212,26,130,49,229,154,215,19,137,60,235,156,210,8,148,43,249,158,209,1,159,38,247,160,240,230,70,189,77,162,243,239,77,176,67,164,246,244, +80,167,81,166,245,253,91,170,95,168,252,194,106,137,117,170,255,203,97,132,123,172,250,208,124,147,105,174,249,217,119,158,103,176,232,174,30,213,61,178,235,167,21,216,51,180,238,188,8,207,33,182,237,181,3,194,47,184,228,138,50,225,5,186,231,131,57,236,11,188,226,152,36,251,25,190,225,145,47,246,23,192,160,77,141,214,118,194,163,68,134,219,120,196,166,95,155,204,106,198,165,86,144,193,100,200,172,105,161,226,78,202,175,96,170,239,64,204,170,123,183,248,82,206,169,114,188,245,92,208,184,5,213,190, +6,210,187,12,222,179,8,212,190,23,195,164,26,214,189,30,200,169,20,216,180,33,249,138,62,218,183,40,242,135,48,220,178,51,239,144,34,222,177,58,228,157,44,224,144,221,61,6,150,226,147,212,54,11,152,228,150,207,43,28,138,230,149,198,32,17,132,232,156,249,17,50,174,234,159,240,26,63,160,236,154,235,7,40,178,238,153,226,12,37,188,240,136,149,101,110,230,242,139,156,110,99,232,244,142,135,115,116,250,246,141,142,120,121,244,248,132,177,73,90,222,250,135,184,66,87,208,252,130,163,95,64,194,254,129,170, +84,77,204,27,155,236,247,218,65,25,152,229,252,215,79,31,157,254,225,192,93,29,158,247,234,205,83,19,151,200,219,238,121,17,148,193,208,227,119,23,145,218,205,244,101,21,146,211,198,249,107,11,131,164,175,178,49,9,128,173,164,191,63,15,133,182,185,168,45,13,134,191,178,165,35,3,143,128,131,134,9,1,140,137,136,139,7,7,137,146,149,156,21,5,138,155,158,145,27,59,171,124,71,10,161,57,168,117,76,7,175,63,173,110,81,16,189,61,174,103,90,29,179,51,167,88,107,62,153,49,164,81,96,51,151,55,161,74,125,36,133, +53,162,67,118,41,139,43,179,52,31,98,209,41,176,61,20,111,223,47,181,38,9,120,205,45,182,47,2,117,195,35,191,16,51,86,233,33,188,25,56,91,231,39,185,2,37,76,245,37,186,11,46,65,251,91,251,215,140,97,154,89,248,222,135,108,148,95,253,197,154,123,134,93,254,204,145,118,136,83,247,243,160,85,162,81,244,250,171,88,172,87,241,225,182,79,190,85,242,232,189,66,176,75,227,159,212,9,234,73,224,150,223,4,228,79,229,141,194,19,246,77,230,132,201,30,248,67,239,187,248,61,210,65,236,178,243,48,220,71,233,169, +238,39,206,69,234,160,229,42,192,123,203,71,60,177,122,121,200,78,55,188,116,127,205,85,42,171,102,125,206,92,33,166,104,115,199,99,16,133,66,113,196,106,27,136,76,119,193,113,6,159,94,117,194,120,13,146,80,107,211,15,100,217,10,105,208,6,111,212,4,111,213,29,114,195,22,109,214,20,121,206,24,99,223,43,72,237,50,97,220,34,67,224,60,103,217,57,94,247,46,101,218,48,85,250,32,155,91,154,1,183,236,153,88,147,10,186,226,159,93,136,23,173,240,157,94,129,28,160,254,147,87,190,45,131,212,145,84,183,38,142, +218,151,81,172,59,153,200,149,82,165,48,148,198,139,67,210,89,223,156,137,64,219,82,210,146,143,69,192,79,197,128,141,70,201,68,200,142,131,79,246,117,235,164,129,76,255,126,230,170,135,73,228,99,241,184,133,74,237,104,252,182,187,107,10,177,103,12,185,104,3,186,106,2,191,109,24,167,125,16,189,110,17,172,112,30,179,103,46,157,83,52,177,100,39,150,94,58,183,97,60,139,73,40,181,98,53,128,68,38,171,115,66,233,15,124,169,112,75,226,2,114,175,117,80,255,21,96,173,118,89,244,24,110,163,127,102,197,59,68, +161,124,111,206,54,74,167,121,116,211,33,88,165,122,125,216,44,86,219,59,161,122,12,55,217,56,168,113,1,57,223,61,179,108,22,43,221,62,186,103,27,37,211,55,133,86,56,15,209,52,140,93,53,1,215,49,151,64,34,19,213,50,158,75,47,29,203,35,233,34,100,71,201,32,224,41,105,73,207,37,251,52,126,91,205,38,242,63,115,85,195,47,205,14,80,127,193,44,196,5,93,113,199,41,223,24,74,99,197,42,214,19,71,109,251,11,49,202,220,215,249,8,56,193,209,217,255,13,35,220,198,203,253,14,42,215,203,197,243,7,21,230,232,239, +241,4,28,237,229,225,247,1,7,240,242,243,245,2,14,251,255,253,235,19,121,146,180,167,233,16,112,153,185,169,239,21,107,132,174,187,237,22,98,143,163,181,227,31,93,190,128,159,225,28,84,181,141,145,231,25,79,168,154,131,229,26,70,163,151,141,82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,124,227,57,130,155,47,255,135,52,142,67,68,196,222,233,203,84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,46,161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,248,246,100,134,104,152,22,212, +164,92,204,93,101,182,146,108,112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,216,171,0,140,188,211,10,247,228,88,5,184,179,69,6,208,44,30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,79,103,220,234,151,242,207,206,240,180,230,115,150,172,116,34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,113,29,41,197,137,111,183,98,14,170,24,190,27,252,86,62,75,198,210,121,32,154,219,192,254,120,205,90,244,31,221,168,51,136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181, +74,13,45,229,122,159,147,201,156,239,160,224,59,77,174,42,245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,214,38,225,105,20,99,85,33,12,125],"i8",4,f.h+30720);var hb=D,D=D+16;a._i64Subtract=ib;a._i64Add=jb;a._bitshift64Ashr=kb;a._memset=lb;a._bitshift64Lshr=mb;a._bitshift64Shl=nb;a._memcpy=ob;var Ya=C=f.q(D),Ua=!0,va=Ya+Za,A=f.q(va),pb=G([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0, +2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",3);a.t={Math:Math,Int8Array:Int8Array,Int16Array:Int16Array,Int32Array:Int32Array,Uint8Array:Uint8Array,Uint16Array:Uint16Array,Uint32Array:Uint32Array, +Float32Array:Float32Array,Float64Array:Float64Array,NaN:NaN,Infinity:Infinity};a.u={abort:L,assert:v,invoke_ii:function(g,b){try{return a.dynCall_ii(g,b)}catch(c){if("number"!==typeof c&&"longjmp"!==c)throw c;d.setThrew(1,0)}},invoke_iiiiiiiiii:function(g,b,c,e,h,f,l,k,m,n){try{return a.dynCall_iiiiiiiiii(g,b,c,e,h,f,l,k,m,n)}catch(p){if("number"!==typeof p&&"longjmp"!==p)throw p;d.setThrew(1,0)}},invoke_iii:function(g,b,c){try{return a.dynCall_iii(g,b,c)}catch(e){if("number"!==typeof e&&"longjmp"!== +e)throw e;d.setThrew(1,0)}},_pthread_self:function(){return 0},_abort:function(){a.abort()},___setErrNo:Ka,_llvm_stacksave:sa,_sbrk:ha,_time:function(a){var b=Date.now()/1E3|0;a&&(q[a>>2]=b);return b},_gettimeofday:function(a){var b=Date.now();q[a>>2]=b/1E3|0;q[a+4>>2]=b%1E3*1E3|0;return 0},_emscripten_memcpy_big:function(a,b,c){x.set(x.subarray(b,b+c),a);return a},_llvm_stackrestore:function(a){var b=sa,c=b.b[a];b.b.splice(a,1);f.d(c)},_sysconf:function(a){switch(a){case 30:return 4096;case 85:return I/ +4096;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 79:return 0;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1; +case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1E3;case 89:return 700;case 71:return 256; +case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:return"object"===typeof navigator?navigator.hardwareConcurrency||1:1}Ka(22);return-1},STACKTOP:C,STACK_MAX:va,tempDoublePtr:hb,ABORT:ia,cttz_i8:pb};// EMSCRIPTEN_START_ASM +var d=(function(global,env,buffer) { +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=env.cttz_i8|0;var n=0;var o=0;var p=0;var q=0;var r=global.NaN,s=global.Infinity;var t=0,u=0,v=0,w=0,x=0.0,y=0,z=0,A=0,B=0.0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=0;var M=global.Math.floor;var N=global.Math.abs;var O=global.Math.sqrt;var P=global.Math.pow;var Q=global.Math.cos;var R=global.Math.sin;var S=global.Math.tan;var T=global.Math.acos;var U=global.Math.asin;var V=global.Math.atan;var W=global.Math.atan2;var X=global.Math.exp;var Y=global.Math.log;var Z=global.Math.ceil;var _=global.Math.imul;var $=global.Math.min;var aa=global.Math.clz32;var ba=env.abort;var ca=env.assert;var da=env.invoke_ii;var ea=env.invoke_iiiiiiiiii;var fa=env.invoke_iii;var ga=env._pthread_self;var ha=env._abort;var ia=env.___setErrNo;var ja=env._llvm_stacksave;var ka=env._sbrk;var la=env._time;var ma=env._gettimeofday;var na=env._emscripten_memcpy_big;var oa=env._llvm_stackrestore;var pa=env._sysconf;var qa=0.0; +// EMSCRIPTEN_START_FUNCS +function ua(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function va(){return i|0}function wa(a){a=a|0;i=a}function xa(a,b){a=a|0;b=b|0;i=a;j=b}function ya(a,b){a=a|0;b=b|0;if(!n){n=a;o=b}}function za(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Aa(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ba(a){a=a|0;C=a}function Ca(){return C|0}function Da(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (((((c[b>>2]|0)+2|0)>>>0)/3|0)<<2)+((((c[b>>2]|0)+2|0)>>>0)%3|0)-2|0}function Ea(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;i=i+48|0;g=q+32|0;h=q+28|0;l=q+24|0;j=q+20|0;m=q+16|0;k=q+12|0;n=q+8|0;o=q+4|0;p=q;c[g>>2]=b;c[h>>2]=e;c[l>>2]=f;c[j>>2]=(c[g>>2]|0)+((((c[h>>2]|0)>>>0)/3|0)*3|0);c[m>>2]=c[g>>2];while(1){if((c[m>>2]|0)==(c[j>>2]|0))break;c[k>>2]=d[c[m>>2]>>0];c[k>>2]=c[k>>2]<<8;c[k>>2]=c[k>>2]|(d[(c[m>>2]|0)+1>>0]|0);c[k>>2]=c[k>>2]<<8;c[k>>2]=c[k>>2]|(d[(c[m>>2]|0)+2>>0]|0);c[m>>2]=(c[m>>2]|0)+3;a[(c[l>>2]|0)+3>>0]=a[32900+(c[k>>2]&63)>>0]|0;c[k>>2]=(c[k>>2]|0)>>>6;a[(c[l>>2]|0)+2>>0]=a[32900+(c[k>>2]&63)>>0]|0;c[k>>2]=(c[k>>2]|0)>>>6;a[(c[l>>2]|0)+1>>0]=a[32900+(c[k>>2]&63)>>0]|0;c[k>>2]=(c[k>>2]|0)>>>6;a[c[l>>2]>>0]=a[32900+(c[k>>2]|0)>>0]|0;c[l>>2]=(c[l>>2]|0)+4}c[n>>2]=(c[g>>2]|0)+(c[h>>2]|0)-(c[m>>2]|0);c[o>>2]=c[l>>2];if(!(c[n>>2]|0)){p=c[o>>2]|0;i=q;return p|0}c[p>>2]=d[c[m>>2]>>0];g=c[p>>2]|0;if((c[n>>2]|0)==2){c[p>>2]=g<<8;c[p>>2]=c[p>>2]|(d[(c[m>>2]|0)+1>>0]|0);c[p>>2]=c[p>>2]<<2;a[(c[l>>2]|0)+2>>0]=a[32900+(c[p>>2]&63)>>0]|0;c[p>>2]=(c[p>>2]|0)>>>6;c[o>>2]=(c[o>>2]|0)+3}else{c[p>>2]=g<<4;c[o>>2]=(c[o>>2]|0)+2}a[(c[l>>2]|0)+1>>0]=a[32900+(c[p>>2]&63)>>0]|0;c[p>>2]=(c[p>>2]|0)>>>6;a[c[l>>2]>>0]=a[32900+(c[p>>2]|0)>>0]|0;p=c[o>>2]|0;i=q;return p|0}function Fa(a){a=a|0;var b=0,d=0,e=0;e=i;i=i+16|0;b=e+4|0;d=e;c[d>>2]=a;if((((c[d>>2]|0)>>>0)%4|0|0)==1){c[b>>2]=-1;a=c[b>>2]|0;i=e;return a|0}else{c[b>>2]=(((((c[d>>2]|0)+2|0)>>>0)/4|0)*3|0)+((((c[d>>2]|0)+2|0)>>>0)%4|0)-2;a=c[b>>2]|0;i=e;return a|0}return 0}function Ga(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;i=i+32|0;j=p+28|0;k=p+24|0;l=p+20|0;g=p+16|0;m=p+12|0;h=p+8|0;n=p+4|0;o=p;c[j>>2]=b;c[k>>2]=e;c[l>>2]=f;c[g>>2]=(c[j>>2]|0)+((((c[k>>2]|0)>>>0)/4|0)<<2);c[m>>2]=c[j>>2];while(1){if((c[m>>2]|0)==(c[g>>2]|0))break;c[h>>2]=d[32964+((d[c[m>>2]>>0]|0)&127)>>0];c[h>>2]=c[h>>2]<<6;c[h>>2]=c[h>>2]|(d[32964+((d[(c[m>>2]|0)+1>>0]|0)&127)>>0]|0);c[h>>2]=c[h>>2]<<6;c[h>>2]=c[h>>2]|(d[32964+((d[(c[m>>2]|0)+2>>0]|0)&127)>>0]|0);c[h>>2]=c[h>>2]<<6;c[h>>2]=c[h>>2]|(d[32964+((d[(c[m>>2]|0)+3>>0]|0)&127)>>0]|0);c[m>>2]=(c[m>>2]|0)+4;a[(c[l>>2]|0)+2>>0]=c[h>>2];c[h>>2]=(c[h>>2]|0)>>>8;a[(c[l>>2]|0)+1>>0]=c[h>>2];c[h>>2]=(c[h>>2]|0)>>>8;a[c[l>>2]>>0]=c[h>>2];c[l>>2]=(c[l>>2]|0)+3}c[n>>2]=(c[j>>2]|0)+(c[k>>2]|0)-(c[m>>2]|0);if(!(c[n>>2]|0)){n=c[j>>2]|0;o=c[k>>2]|0;o=n+o|0;i=p;return o|0}c[o>>2]=d[32964+((d[c[m>>2]>>0]|0)&127)>>0];c[o>>2]=c[o>>2]<<6;c[o>>2]=c[o>>2]|(d[32964+((d[(c[m>>2]|0)+1>>0]|0)&127)>>0]|0);g=c[o>>2]|0;if((c[n>>2]|0)==3){c[o>>2]=g<<6;c[o>>2]=c[o>>2]|(d[32964+((d[(c[m>>2]|0)+2>>0]|0)&127)>>0]|0);c[o>>2]=(c[o>>2]|0)>>>2;a[(c[l>>2]|0)+1>>0]=c[o>>2];c[o>>2]=(c[o>>2]|0)>>>8}else c[o>>2]=g>>>4;a[c[l>>2]>>0]=c[o>>2];n=c[j>>2]|0;o=c[k>>2]|0;o=n+o|0;i=p;return o|0}function Ha(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Da(c[d>>2]|0)|0;i=b;return a|0}function Ia(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;g=i;i=i+16|0;j=g+12|0;h=g+8|0;e=g+4|0;f=g;c[j>>2]=a;c[h>>2]=b;c[e>>2]=d;c[f>>2]=Ea(c[j>>2]|0,c[h>>2]|0,c[e>>2]|0)|0;i=g;return (c[f>>2]|0)-(c[e>>2]|0)|0}function Ja(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Fa(c[d>>2]|0)|0;i=b;return a|0}function Ka(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;h=e+8|0;f=e+4|0;g=e;c[h>>2]=a;c[f>>2]=b;c[g>>2]=d;Ga(c[h>>2]|0,c[f>>2]|0,c[g>>2]|0)|0;d=Fa(c[f>>2]|0)|0;i=e;return d|0}function La(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=i;i=i+16|0;e=h+8|0;f=h+4|0;g=h;c[e>>2]=b;c[f>>2]=d;c[e>>2]=(c[e>>2]|0)+4;c[g>>2]=4;while(1){d=c[g>>2]|0;c[g>>2]=d+-1;if(!d)break;b=c[f>>2]&255;d=(c[e>>2]|0)+-1|0;c[e>>2]=d;a[d>>0]=b;c[f>>2]=(c[f>>2]|0)>>>8}i=h;return (c[e>>2]|0)+4|0}function Ma(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;l=i;i=i+32|0;f=l+16|0;g=l+12|0;h=l+8|0;j=l+4|0;k=l;c[g>>2]=a;c[h>>2]=b;c[j>>2]=e;c[c[j>>2]>>2]=0;if((c[h>>2]|0)>>>0<((c[g>>2]|0)+4|0)>>>0){c[f>>2]=c[h>>2];e=c[f>>2]|0;i=l;return e|0}c[k>>2]=4;while(1){e=c[k>>2]|0;c[k>>2]=e+-1;if(!e)break;a=c[j>>2]|0;c[a>>2]=c[a>>2]<<8;a=c[g>>2]|0;c[g>>2]=a+1;e=c[j>>2]|0;c[e>>2]=c[e>>2]|(d[a>>0]|0)}c[f>>2]=c[g>>2];e=c[f>>2]|0;i=l;return e|0}function Na(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;f=i;i=i+16|0;e=f;g=f+4|0;c[e>>2]=b;a[g>>0]=d&1;b=(a[g>>0]&1?1:0)&255;d=c[e>>2]|0;c[e>>2]=d+1;a[d>>0]=b;i=f;return c[e>>2]|0}function Oa(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+16|0;f=k+12|0;g=k+8|0;h=k+4|0;j=k;c[g>>2]=b;c[h>>2]=d;c[j>>2]=e;if((c[g>>2]|0)==(c[h>>2]|0)){c[f>>2]=c[h>>2];e=c[f>>2]|0;i=k;return e|0}else{e=c[g>>2]|0;c[g>>2]=e+1;a[c[j>>2]>>0]=(a[e>>0]|0)!=0&1;c[f>>2]=c[g>>2];e=c[f>>2]|0;i=k;return e|0}return 0}function Pa(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;g=i;i=i+16|0;f=g+8|0;h=g+4|0;e=g;c[f>>2]=a;c[h>>2]=b;c[e>>2]=d;Vh(c[f>>2]|0,c[h>>2]|0,c[e>>2]|0)|0;i=g;return (c[f>>2]|0)+(c[e>>2]|0)|0}function Qa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;l=i;i=i+32|0;f=l+16|0;g=l+12|0;h=l+8|0;j=l+4|0;k=l;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;if((c[h>>2]|0)>>>0<((c[g>>2]|0)+(c[k>>2]|0)|0)>>>0){c[f>>2]=c[h>>2];a=c[f>>2]|0;i=l;return a|0}else{Vh(c[j>>2]|0,c[g>>2]|0,c[k>>2]|0)|0;c[f>>2]=(c[g>>2]|0)+(c[k>>2]|0);a=c[f>>2]|0;i=l;return a|0}return 0}function Ra(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 32}function Sa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=Pa(c[d>>2]|0,c[f>>2]|0,32)|0;i=e;return c[d>>2]|0}function Ta(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;e=f+8|0;h=f+4|0;g=f;c[e>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=Qa(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0,32)|0;i=f;return c[e>>2]|0}function Ua(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 64}function Va(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=Pa(c[d>>2]|0,c[f>>2]|0,32)|0;c[d>>2]=Pa(c[d>>2]|0,(c[f>>2]|0)+32|0,32)|0;i=e;return c[d>>2]|0}function Wa(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;e=f+8|0;h=f+4|0;g=f;c[e>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=Qa(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0,32)|0;c[e>>2]=Qa(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+32|0,32)|0;i=f;return c[e>>2]|0}function Xa(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 64}function Ya(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=Pa(c[d>>2]|0,c[f>>2]|0,32)|0;c[d>>2]=Pa(c[d>>2]|0,(c[f>>2]|0)+32|0,32)|0;i=e;return c[d>>2]|0}function Za(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;e=f+8|0;h=f+4|0;g=f;c[e>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=Qa(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0,32)|0;c[e>>2]=Qa(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+32|0,32)|0;i=f;return c[e>>2]|0}function _a(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;b=La(c[f>>2]|0,c[e>>2]|0)|0;i=d;return b|0}function $a(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;h=e+8|0;g=e+4|0;f=e;c[h>>2]=a;c[g>>2]=b;c[f>>2]=d;d=Ma(c[h>>2]|0,c[g>>2]|0,c[f>>2]|0)|0;i=e;return d|0}function ab(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;h=e+8|0;g=e+4|0;f=e;c[h>>2]=a;c[g>>2]=b;c[f>>2]=d;a=Pa(c[h>>2]|0,c[g>>2]|0,c[f>>2]|0)|0;i=e;return a|0}function bb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;f=i;i=i+16|0;k=f+12|0;j=f+8|0;h=f+4|0;g=f;c[k>>2]=a;c[j>>2]=b;c[h>>2]=d;c[g>>2]=e;a=Qa(c[k>>2]|0,c[j>>2]|0,c[h>>2]|0,c[g>>2]|0)|0;i=f;return a|0}function cb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;g=i;i=i+32|0;k=g+16|0;l=g+12|0;j=g+8|0;h=g+4|0;f=g;c[k>>2]=a;c[l>>2]=b;c[j>>2]=d;c[h>>2]=e;c[f>>2]=1;b=1+(db(c[l>>2]|0)|0)|0;c[f>>2]=(c[f>>2]|0)+b;b=1+(eb(c[k>>2]|0)|0)|0;c[f>>2]=(c[f>>2]|0)+b;b=1+(db(c[j>>2]|0)|0)|0;c[f>>2]=(c[f>>2]|0)+b;c[f>>2]=(c[f>>2]|0)+(c[h>>2]|0);i=g;return c[f>>2]|0}function db(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;a=eb(c[b>>2]|0)|0;i=d;return a+(c[b>>2]|0)|0}function eb(a){a=a|0;var b=0,d=0,e=0;e=i;i=i+16|0;b=e+4|0;d=e;c[b>>2]=a;c[d>>2]=1;while(1){a=c[d>>2]|0;if((c[b>>2]|0)>>>0<128)break;c[d>>2]=a+1;c[b>>2]=(c[b>>2]|0)>>>7}i=e;return a|0}function fb(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=i;i=i+32|0;m=j+20|0;p=j+24|0;n=j+16|0;o=j+12|0;l=j+8|0;q=j+4|0;k=j;c[m>>2]=b;a[p>>0]=d;c[n>>2]=e;c[o>>2]=f;c[l>>2]=g;c[q>>2]=h;c[k>>2]=c[q>>2];d=a[p>>0]|0;b=c[k>>2]|0;c[k>>2]=b+1;a[b>>0]=d;c[k>>2]=gb(c[k>>2]|0,10,c[m>>2]|0,c[o>>2]|0)|0;c[k>>2]=ib(c[k>>2]|0,16,c[n>>2]|0)|0;c[k>>2]=gb(c[k>>2]|0,34,(c[m>>2]|0)+4|0,c[l>>2]|0)|0;i=j;return}function gb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;j=i;i=i+16|0;h=j+8|0;l=j+12|0;k=j+4|0;g=j;c[h>>2]=b;a[l>>0]=d;c[k>>2]=e;c[g>>2]=f;e=a[l>>0]|0;f=c[h>>2]|0;c[h>>2]=f+1;a[f>>0]=e;c[h>>2]=hb(c[h>>2]|0,c[g>>2]|0)|0;c[c[k>>2]>>2]=c[h>>2];i=j;return (c[h>>2]|0)+(c[g>>2]|0)|0}function hb(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+16|0;e=g+4|0;f=g;c[e>>2]=b;c[f>>2]=d;while(1){b=c[f>>2]|0;if((c[f>>2]|0)>>>0<128)break;d=c[e>>2]|0;c[e>>2]=d+1;a[d>>0]=127&b|128;c[f>>2]=(c[f>>2]|0)>>>7}f=c[e>>2]|0;c[e>>2]=f+1;a[f>>0]=b;i=g;return c[e>>2]|0}function ib(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0;f=i;i=i+16|0;h=f+4|0;j=f+8|0;g=f;c[h>>2]=b;a[j>>0]=d;c[g>>2]=e;d=a[j>>0]|0;e=c[h>>2]|0;c[h>>2]=e+1;a[e>>0]=d;e=hb(c[h>>2]|0,c[g>>2]|0)|0;i=f;return e|0}function jb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;n=i;i=i+32|0;g=n+24|0;o=n+20|0;h=n+16|0;j=n+12|0;l=n+8|0;k=n+4|0;m=n;c[g>>2]=b;c[o>>2]=d;c[h>>2]=e;c[j>>2]=f;c[l>>2]=c[o>>2];c[k>>2]=(c[o>>2]|0)+(c[h>>2]|0)+(0-(c[j>>2]|0));c[m>>2]=0;c[(c[g>>2]|0)+8>>2]=c[o>>2];c[(c[g>>2]|0)+12>>2]=c[h>>2];a[(c[g>>2]|0)+1>>0]=0;c[(c[g>>2]|0)+16>>2]=0;c[(c[g>>2]|0)+20>>2]=0;c[(c[g>>2]|0)+24>>2]=0;c[(c[g>>2]|0)+28>>2]=0;if((c[l>>2]|0)==(c[k>>2]|0)){i=n;return}if((c[h>>2]|0)>>>0<(c[j>>2]|0)>>>0){i=n;return}o=c[l>>2]|0;c[l>>2]=o+1;a[c[g>>2]>>0]=a[o>>0]|0;while(1){if((c[l>>2]|0)==(c[k>>2]|0))break;c[l>>2]=kb(c[l>>2]|0,c[k>>2]|0,10,(c[g>>2]|0)+16|0,(c[g>>2]|0)+20|0)|0;c[l>>2]=nb(c[l>>2]|0,c[k>>2]|0,16,(c[g>>2]|0)+4|0,(c[g>>2]|0)+1|0)|0;c[l>>2]=kb(c[l>>2]|0,c[k>>2]|0,34,(c[g>>2]|0)+24|0,(c[g>>2]|0)+28|0)|0;if((c[m>>2]|0)==(c[l>>2]|0))c[l>>2]=ob(c[l>>2]|0,c[k>>2]|0)|0;c[m>>2]=c[l>>2]}i=n;return}function kb(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=i;i=i+32|0;j=q+24|0;k=q+20|0;l=q+16|0;r=q+28|0;m=q+12|0;n=q+8|0;p=q+4|0;o=q;c[k>>2]=b;c[l>>2]=e;a[r>>0]=f;c[m>>2]=g;c[n>>2]=h;do if((c[k>>2]|0)!=(c[l>>2]|0)?(d[c[k>>2]>>0]|0|0)==(d[r>>0]|0|0):0){c[k>>2]=(c[k>>2]|0)+1;c[p>>2]=c[k>>2];c[k>>2]=lb(c[k>>2]|0,c[l>>2]|0)|0;c[o>>2]=mb(c[p>>2]|0,c[k>>2]|0)|0;if((c[o>>2]|0)>>>0<=((c[l>>2]|0)-(c[k>>2]|0)|0)>>>0){c[c[m>>2]>>2]=c[k>>2];c[c[n>>2]>>2]=c[o>>2];c[k>>2]=(c[k>>2]|0)+(c[o>>2]|0);break}c[j>>2]=c[l>>2];r=c[j>>2]|0;i=q;return r|0}while(0);c[j>>2]=c[k>>2];r=c[j>>2]|0;i=q;return r|0}function lb(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+16|0;h=k+8|0;j=k+4|0;f=k;g=k+12|0;c[j>>2]=b;c[f>>2]=e;while(1){e=c[j>>2]|0;if((c[j>>2]|0)==(c[f>>2]|0)){b=5;break}c[j>>2]=e+1;a[g>>0]=a[e>>0]|0;if(!((d[g>>0]|0)&128)){b=4;break}}if((b|0)==4){c[h>>2]=c[j>>2];j=c[h>>2]|0;i=k;return j|0}else if((b|0)==5){c[h>>2]=e;j=c[h>>2]|0;i=k;return j|0}return 0}function mb(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0;j=i;i=i+16|0;e=j+12|0;f=j+8|0;g=j+4|0;h=j;c[f>>2]=a;c[g>>2]=b;c[h>>2]=0;if((c[g>>2]|0)==(c[f>>2]|0)){c[e>>2]=0;a=c[e>>2]|0;i=j;return a|0}do{c[h>>2]=c[h>>2]<<7;a=(c[g>>2]|0)+-1|0;c[g>>2]=a;c[h>>2]=c[h>>2]|127&(d[a>>0]|0)}while((c[g>>2]|0)!=(c[f>>2]|0));c[e>>2]=c[h>>2];a=c[e>>2]|0;i=j;return a|0}function nb(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;i=i+32|0;j=p+16|0;k=p+12|0;l=p+20|0;m=p+8|0;n=p+4|0;o=p;c[j>>2]=b;c[k>>2]=e;a[l>>0]=f;c[m>>2]=g;c[n>>2]=h;if((c[j>>2]|0)==(c[k>>2]|0)){o=c[j>>2]|0;i=p;return o|0}if((d[c[j>>2]>>0]|0|0)!=(d[l>>0]|0|0)){o=c[j>>2]|0;i=p;return o|0}c[j>>2]=(c[j>>2]|0)+1;c[o>>2]=c[j>>2];c[j>>2]=lb(c[j>>2]|0,c[k>>2]|0)|0;o=mb(c[o>>2]|0,c[j>>2]|0)|0;c[c[m>>2]>>2]=o;a[c[n>>2]>>0]=1;o=c[j>>2]|0;i=p;return o|0}function ob(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;m=i;i=i+32|0;f=m+16|0;g=m+12|0;h=m+8|0;l=m+20|0;k=m+4|0;j=m;c[g>>2]=b;c[h>>2]=e;do if((c[g>>2]|0)!=(c[h>>2]|0)){a[l>>0]=a[c[g>>2]>>0]|0;if(!((d[l>>0]|0)&7)){c[g>>2]=lb(c[g>>2]|0,c[h>>2]|0)|0;c[g>>2]=lb(c[g>>2]|0,c[h>>2]|0)|0;break}if(((d[l>>0]|0)&7|0)!=2){c[f>>2]=c[h>>2];l=c[f>>2]|0;i=m;return l|0}c[g>>2]=lb(c[g>>2]|0,c[h>>2]|0)|0;c[k>>2]=c[g>>2];c[g>>2]=lb(c[g>>2]|0,c[h>>2]|0)|0;c[j>>2]=mb(c[k>>2]|0,c[g>>2]|0)|0;if((c[j>>2]|0)>>>0<=((c[h>>2]|0)-(c[g>>2]|0)|0)>>>0){c[g>>2]=(c[g>>2]|0)+(c[j>>2]|0);break}c[f>>2]=c[h>>2];l=c[f>>2]|0;i=m;return l|0}while(0);c[f>>2]=c[g>>2];l=c[f>>2]|0;i=m;return l|0}function pb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;g=i;i=i+32|0;l=g+16|0;k=g+12|0;j=g+8|0;h=g+4|0;f=g;c[l>>2]=a;c[k>>2]=b;c[j>>2]=d;c[h>>2]=e;c[f>>2]=1;a=1+(db(c[l>>2]|0)|0)|0;c[f>>2]=(c[f>>2]|0)+a;a=1+(db(c[k>>2]|0)|0)|0;c[f>>2]=(c[f>>2]|0)+a;a=1+(db(c[j>>2]|0)|0)|0;c[f>>2]=(c[f>>2]|0)+a;a=1+(db(c[h>>2]|0)|0)|0;c[f>>2]=(c[f>>2]|0)+a;i=g;return c[f>>2]|0}function qb(b,d,e,f,g,h,j){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;k=i;i=i+32|0;n=k+24|0;r=k+28|0;o=k+20|0;p=k+16|0;q=k+12|0;m=k+8|0;s=k+4|0;l=k;c[n>>2]=b;a[r>>0]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=g;c[m>>2]=h;c[s>>2]=j;c[l>>2]=c[s>>2];d=a[r>>0]|0;b=c[l>>2]|0;c[l>>2]=b+1;a[b>>0]=d;c[l>>2]=gb(c[l>>2]|0,10,(c[n>>2]|0)+8|0,c[q>>2]|0)|0;c[l>>2]=gb(c[l>>2]|0,18,(c[n>>2]|0)+4|0,c[p>>2]|0)|0;c[l>>2]=gb(c[l>>2]|0,26,c[n>>2]|0,c[o>>2]|0)|0;c[l>>2]=gb(c[l>>2]|0,34,(c[n>>2]|0)+12|0,c[m>>2]|0)|0;i=k;return}function rb(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;k=i;i=i+32|0;f=k+20|0;m=k+16|0;l=k+12|0;h=k+8|0;g=k+4|0;j=k;c[f>>2]=b;c[m>>2]=d;c[l>>2]=e;c[h>>2]=c[m>>2];c[g>>2]=(c[m>>2]|0)+(c[l>>2]|0);c[j>>2]=0;c[(c[f>>2]|0)+20>>2]=0;c[(c[f>>2]|0)+24>>2]=0;c[(c[f>>2]|0)+4>>2]=0;c[(c[f>>2]|0)+8>>2]=0;c[(c[f>>2]|0)+12>>2]=0;c[(c[f>>2]|0)+16>>2]=0;c[(c[f>>2]|0)+28>>2]=0;c[(c[f>>2]|0)+32>>2]=0;if((c[h>>2]|0)==(c[g>>2]|0)){i=k;return}m=c[h>>2]|0;c[h>>2]=m+1;a[c[f>>2]>>0]=a[m>>0]|0;while(1){if((c[h>>2]|0)==(c[g>>2]|0))break;c[h>>2]=kb(c[h>>2]|0,c[g>>2]|0,10,(c[f>>2]|0)+20|0,(c[f>>2]|0)+24|0)|0;c[h>>2]=kb(c[h>>2]|0,c[g>>2]|0,18,(c[f>>2]|0)+12|0,(c[f>>2]|0)+16|0)|0;c[h>>2]=kb(c[h>>2]|0,c[g>>2]|0,26,(c[f>>2]|0)+4|0,(c[f>>2]|0)+8|0)|0;c[h>>2]=kb(c[h>>2]|0,c[g>>2]|0,34,(c[f>>2]|0)+28|0,(c[f>>2]|0)+32|0)|0;if((c[j>>2]|0)==(c[h>>2]|0))c[h>>2]=ob(c[h>>2]|0,c[g>>2]|0)|0;c[j>>2]=c[h>>2]}i=k;return}function sb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;f=i;i=i+16|0;j=f+12|0;h=f+8|0;g=f+4|0;e=f;c[j>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=1;a=1+(eb(c[j>>2]|0)|0)|0;c[e>>2]=(c[e>>2]|0)+a;a=1+(db(c[h>>2]|0)|0)|0;c[e>>2]=(c[e>>2]|0)+a;c[e>>2]=(c[e>>2]|0)+(c[g>>2]|0);i=f;return c[e>>2]|0}function tb(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0;k=i;i=i+32|0;o=k+20|0;n=k+16|0;l=k+12|0;h=k+8|0;m=k+4|0;j=k;a[o>>0]=b;c[n>>2]=d;c[l>>2]=e;c[h>>2]=f;c[m>>2]=g;c[j>>2]=c[h>>2];f=a[o>>0]|0;b=c[j>>2]|0;c[j>>2]=b+1;a[b>>0]=f;c[j>>2]=ib(c[j>>2]|0,8,c[n>>2]|0)|0;c[j>>2]=gb(c[j>>2]|0,18,c[m>>2]|0,c[l>>2]|0)|0;i=k;return (c[j>>2]|0)-(c[h>>2]|0)|0}function ub(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=i;i=i+32|0;p=o+24|0;g=o+20|0;h=o+16|0;j=o+12|0;m=o+8|0;k=o+4|0;n=o;l=o+28|0;c[p>>2]=b;c[g>>2]=d;c[h>>2]=e;c[j>>2]=f;c[m>>2]=c[p>>2];c[k>>2]=(c[p>>2]|0)+(c[g>>2]|0)+(0-(c[h>>2]|0));c[n>>2]=0;a[l>>0]=0;c[(c[j>>2]|0)+4>>2]=0;c[(c[j>>2]|0)+12>>2]=0;c[(c[j>>2]|0)+16>>2]=0;if((c[m>>2]|0)==(c[k>>2]|0)){i=o;return}if((c[g>>2]|0)>>>0<(c[h>>2]|0)>>>0){i=o;return}p=c[m>>2]|0;c[m>>2]=p+1;a[c[j>>2]>>0]=a[p>>0]|0;while(1){if((c[m>>2]|0)==(c[k>>2]|0))break;c[m>>2]=nb(c[m>>2]|0,c[k>>2]|0,8,(c[j>>2]|0)+4|0,l)|0;c[m>>2]=kb(c[m>>2]|0,c[k>>2]|0,18,(c[j>>2]|0)+12|0,(c[j>>2]|0)+16|0)|0;if((c[n>>2]|0)==(c[m>>2]|0))c[m>>2]=ob(c[m>>2]|0,c[k>>2]|0)|0;c[n>>2]=c[m>>2]}c[(c[j>>2]|0)+8>>2]=a[l>>0]&1;i=o;return}function vb(b){b=b|0;var d=0,e=0;d=i;i=i+16|0;e=d;c[e>>2]=b;b=c[e>>2]|0;Ed(b,648,664);c[b+3216>>2]=0;a[b+3220>>0]=0;i=d;return}function wb(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 64}function xb(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;t=i;i=i+272|0;l=t+32|0;v=t+28|0;j=t+24|0;m=t+20|0;n=t+16|0;k=t+12|0;u=t+8|0;p=t+200|0;r=t+136|0;o=t+4|0;s=t+40|0;q=t;c[v>>2]=b;c[j>>2]=d;c[m>>2]=e;c[n>>2]=f;c[k>>2]=g;c[u>>2]=h;g=c[v>>2]|0;b=c[u>>2]|0;if(b>>>0<(wb(g)|0)>>>0){c[g+3216>>2]=1;c[l>>2]=-1;v=c[l>>2]|0;i=t;return v|0}else{Sb(c[k>>2]|0,p);Sb((c[k>>2]|0)+32|0,r);c[o>>2]=(c[j>>2]|0)+64;a[g+3220>>0]=0;e=g+3221|0;d=c[o>>2]|0;f=e+32|0;do{a[e>>0]=a[d>>0]|0;e=e+1|0;d=d+1|0}while((e|0)<(f|0));e=g+3253|0;d=p;f=e+32|0;do{a[e>>0]=a[d>>0]|0;e=e+1|0;d=d+1|0}while((e|0)<(f|0));e=g+3285|0;d=c[n>>2]|0;f=e+32|0;do{a[e>>0]=a[d>>0]|0;e=e+1|0;d=d+1|0}while((e|0)<(f|0));c[q>>2]=s;Tb(c[o>>2]|0,c[n>>2]|0,c[q>>2]|0);c[q>>2]=(c[q>>2]|0)+32;Tb(p,c[m>>2]|0,c[q>>2]|0);c[q>>2]=(c[q>>2]|0)+32;Tb(p,c[n>>2]|0,c[q>>2]|0);Nd(g,s,96,r);yb(p);yb(r);zb(s);c[l>>2]=0;v=c[l>>2]|0;i=t;return v|0}return 0}function yb(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,64);i=b;return}function zb(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,96);i=b;return}function Ab(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;u=i;i=i+256|0;h=u+104|0;x=u+100|0;j=u+96|0;k=u+92|0;w=u+88|0;v=u+84|0;r=u+48|0;s=u+240|0;n=u+16|0;q=u+208|0;o=u+12|0;l=u+8|0;m=u+4|0;t=u+112|0;p=u;c[x>>2]=b;c[j>>2]=d;c[k>>2]=e;c[w>>2]=f;c[v>>2]=g;d=c[x>>2]|0;rb(r,c[w>>2]|0,c[v>>2]|0);if(!(Bb(r,(c[k>>2]|0)!=0)|0)){c[d+3216>>2]=4;c[h>>2]=-1;x=c[h>>2]|0;i=u;return x|0}if((c[r+4>>2]|0)!=0&(c[k>>2]|0)!=0?(a[s>>0]=0==(Lh(c[k>>2]|0,c[r+4>>2]|0,32)|0)&1,!(a[s>>0]&1)):0){c[d+3216>>2]=6;c[h>>2]=-1;x=c[h>>2]|0;i=u;return x|0}Cb(d+3221|0,c[r+4>>2]|0)|0;Cb(d+3253|0,c[r+12>>2]|0)|0;Cb(d+3285|0,c[r+20>>2]|0)|0;w=c[r+28>>2]|0;x=c[r+32>>2]|0;jb(n,w,x,ra[c[c[c[d+4>>2]>>2]>>2]&1](c[d+4>>2]|0)|0);if(c[n+16>>2]|0?(c[n+20>>2]|0)==32:0){Cb(q,c[n+16>>2]|0)|0;c[o>>2]=Ze(c[j>>2]|0,d+3285|0)|0;if(c[o>>2]|0){c[l>>2]=(c[j>>2]|0)+64;c[m>>2]=(c[o>>2]|0)+5;c[p>>2]=t;Tb(c[m>>2]|0,d+3221|0,c[p>>2]|0);c[p>>2]=(c[p>>2]|0)+32;Tb(c[l>>2]|0,d+3253|0,c[p>>2]|0);c[p>>2]=(c[p>>2]|0)+32;Tb(c[m>>2]|0,d+3253|0,c[p>>2]|0);Id(d,t,96,q);zb(t);c[h>>2]=0;x=c[h>>2]|0;i=u;return x|0}else{c[d+3216>>2]=6;c[h>>2]=-1;x=c[h>>2]|0;i=u;return x|0}}c[d+3216>>2]=4;c[h>>2]=-1;x=c[h>>2]|0;i=u;return x|0}function Bb(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=i;i=i+16|0;f=h;e=h+5|0;g=h+4|0;c[f>>2]=b;a[e>>0]=d&1;a[g>>0]=1;if(a[g>>0]&1)if(a[e>>0]&1)e=1;else e=(c[(c[f>>2]|0)+4>>2]|0)!=0;else e=0;a[g>>0]=e&1;if(c[(c[f>>2]|0)+4>>2]|0){if(a[g>>0]&1)e=(c[(c[f>>2]|0)+8>>2]|0)==32;else e=0;a[g>>0]=e&1}if(a[g>>0]&1)e=(c[(c[f>>2]|0)+28>>2]|0)!=0;else e=0;a[g>>0]=e&1;if(a[g>>0]&1)e=(c[(c[f>>2]|0)+12>>2]|0)!=0;else e=0;a[g>>0]=e&1;if(a[g>>0]&1)e=(c[(c[f>>2]|0)+16>>2]|0)==32;else e=0;a[g>>0]=e&1;if(a[g>>0]&1)e=(c[(c[f>>2]|0)+20>>2]|0)!=0;else e=0;a[g>>0]=e&1;if(!(a[g>>0]&1)){f=0;f=f&1;a[g>>0]=f;g=a[g>>0]|0;g=g&1;i=h;return g|0}f=(c[(c[f>>2]|0)+24>>2]|0)==32;f=f&1;a[g>>0]=f;g=a[g>>0]|0;g=g&1;i=h;return g|0}function Cb(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+16|0;e=g+4|0;f=g;c[e>>2]=b;c[f>>2]=d;b=c[e>>2]|0;d=c[f>>2]|0;e=b+32|0;do{a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0}while((b|0)<(e|0));i=g;return (c[f>>2]|0)+32|0}function Db(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 32}function Eb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;j=i;i=i+128|0;e=j+16|0;l=j+12|0;f=j+8|0;k=j+4|0;h=j+24|0;g=j;c[l>>2]=a;c[f>>2]=b;c[k>>2]=d;b=c[l>>2]|0;a=c[k>>2]|0;if(a>>>0<(Db(b)|0)>>>0){c[b+3216>>2]=2;c[e>>2]=-1;l=c[e>>2]|0;i=j;return l|0}else{c[g>>2]=h;c[g>>2]=Fb(c[g>>2]|0,b+3221|0)|0;c[g>>2]=Fb(c[g>>2]|0,b+3253|0)|0;c[g>>2]=Fb(c[g>>2]|0,b+3285|0)|0;bc(h,96,c[f>>2]|0);c[e>>2]=Db(b)|0;l=c[e>>2]|0;i=j;return l|0}return 0}function Fb(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+16|0;f=g+4|0;e=g;c[f>>2]=b;c[e>>2]=d;b=c[f>>2]|0;d=c[e>>2]|0;e=b+32|0;do{a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0}while((b|0)<(e|0));i=g;return (c[f>>2]|0)+32|0}function Gb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;l=i;i=i+64|0;j=l+53|0;o=l+48|0;g=l+44|0;n=l+40|0;m=l+36|0;h=l;k=l+52|0;c[o>>2]=b;c[g>>2]=d;c[n>>2]=e;c[m>>2]=f;e=c[o>>2]|0;rb(h,c[n>>2]|0,c[m>>2]|0);if(!(Bb(h,(c[g>>2]|0)!=0)|0)){a[j>>0]=0;o=a[j>>0]|0;o=o&1;i=l;return o|0}a[k>>0]=1;if(c[h+4>>2]|0){if(a[k>>0]&1)f=0==(Lh(c[h+4>>2]|0,e+3221|0,32)|0);else f=0;a[k>>0]=f&1}if(c[g>>2]|0){if(a[k>>0]&1)f=0==(Lh(c[g>>2]|0,e+3221|0,32)|0);else f=0;a[k>>0]=f&1}if(a[k>>0]&1)f=0==(Lh(c[h+12>>2]|0,e+3253|0,32)|0);else f=0;a[k>>0]=f&1;if(a[k>>0]&1)f=0==(Lh(c[h+20>>2]|0,e+3285|0,32)|0);else f=0;a[k>>0]=f&1;a[j>>0]=a[k>>0]&1;o=a[j>>0]|0;o=o&1;i=l;return o|0}function Hb(b){b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[f>>2]=b;if(a[(c[f>>2]|0)+3220>>0]&1)c[d>>2]=1;else c[d>>2]=0;i=e;return c[d>>2]|0}function Ib(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;f=i;i=i+16|0;e=f+12|0;j=f+8|0;h=f+4|0;g=f;c[j>>2]=b;c[h>>2]=d;b=c[j>>2]|0;c[g>>2]=Be(b,c[h>>2]|0)|0;d=c[g>>2]|0;if(a[b+3220>>0]&1){c[e>>2]=d;j=c[e>>2]|0;i=f;return j|0}else{c[e>>2]=pb(32,32,32,d)|0;j=c[e>>2]|0;i=f;return j|0}return 0}function Jb(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=De(c[d>>2]|0)|0;i=b;return a|0}function Kb(b,d,e,f,g,h,j){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;u=i;i=i+64|0;k=u+60|0;w=u+56|0;l=u+52|0;m=u+48|0;n=u+44|0;o=u+40|0;p=u+36|0;v=u+32|0;q=u+28|0;r=u+24|0;t=u+8|0;s=u;c[w>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[p>>2]=h;c[v>>2]=j;h=c[w>>2]|0;b=c[v>>2]|0;if(b>>>0<(Ib(h,c[m>>2]|0)|0)>>>0){c[h+3216>>2]=2;c[k>>2]=-1;w=c[k>>2]|0;i=u;return w|0}c[r>>2]=Be(h,c[m>>2]|0)|0;if(a[h+3220>>0]&1)c[q>>2]=c[p>>2];else{qb(t,3,32,32,32,c[r>>2]|0,c[p>>2]|0);Fb(c[t+8>>2]|0,h+3285|0)|0;Fb(c[t>>2]|0,h+3221|0)|0;Fb(c[t+4>>2]|0,h+3253|0)|0;c[q>>2]=c[t+12>>2]}c[s>>2]=Ee(h,c[l>>2]|0,c[m>>2]|0,c[n>>2]|0,c[o>>2]|0,c[q>>2]|0,c[r>>2]|0)|0;if((c[s>>2]|0)==-1){c[h+3216>>2]=c[h+8>>2];c[h+8>>2]=0;c[k>>2]=c[s>>2];w=c[k>>2]|0;i=u;return w|0}else{c[k>>2]=c[s>>2];w=c[k>>2]|0;i=u;return w|0}return 0}function Lb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;m=i;i=i+80|0;f=m+64|0;p=m+60|0;n=m+56|0;o=m+52|0;g=m+48|0;h=m+44|0;j=m+40|0;k=m+4|0;l=m;c[p>>2]=a;c[n>>2]=b;c[o>>2]=d;c[g>>2]=e;d=c[p>>2]|0;e=c[o>>2]|0;do if((c[n>>2]|0)==1){c[h>>2]=e;c[j>>2]=c[g>>2]}else{rb(k,e,c[g>>2]|0);if(c[k+28>>2]|0){c[h>>2]=c[k+28>>2];c[j>>2]=c[k+32>>2];break}c[d+3216>>2]=4;c[f>>2]=-1;p=c[f>>2]|0;i=m;return p|0}while(0);c[l>>2]=Je(d,c[h>>2]|0,c[j>>2]|0)|0;if((c[l>>2]|0)==-1){c[d+3216>>2]=c[d+8>>2];c[d+8>>2]=0}c[f>>2]=c[l>>2];p=c[f>>2]|0;i=m;return p|0}function Mb(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;r=i;i=i+80|0;j=r+72|0;u=r+68|0;s=r+64|0;t=r+60|0;k=r+56|0;l=r+52|0;m=r+48|0;n=r+44|0;o=r+40|0;p=r+4|0;q=r;c[u>>2]=b;c[s>>2]=d;c[t>>2]=e;c[k>>2]=f;c[l>>2]=g;c[m>>2]=h;e=c[u>>2]|0;h=c[t>>2]|0;do if((c[s>>2]|0)==1){c[n>>2]=h;c[o>>2]=c[k>>2]}else{rb(p,h,c[k>>2]|0);if(c[p+28>>2]|0){c[n>>2]=c[p+28>>2];c[o>>2]=c[p+32>>2];break}c[e+3216>>2]=4;c[j>>2]=-1;u=c[j>>2]|0;i=r;return u|0}while(0);c[q>>2]=Ke(e,c[n>>2]|0,c[o>>2]|0,c[l>>2]|0,c[m>>2]|0)|0;if((c[q>>2]|0)==-1){c[e+3216>>2]=c[e+8>>2];c[e+8>>2]=0;c[j>>2]=c[q>>2];u=c[j>>2]|0;i=r;return u|0}else{a[e+3220>>0]=1;c[j>>2]=c[q>>2];u=c[j>>2]|0;i=r;return u|0}return 0}function Nb(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;a=Ob(676)|0;c[b>>2]=(c[b>>2]|0)+a;a=Pb((c[e>>2]|0)+3220|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ra((c[e>>2]|0)+3221|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ra((c[e>>2]|0)+3253|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ra((c[e>>2]|0)+3285|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Sd(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0}function Ob(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 4}function Pb(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 1}function Qb(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;f=i;i=i+16|0;e=f+4|0;g=f;c[e>>2]=b;c[g>>2]=d;c[e>>2]=La(c[e>>2]|0,1)|0;c[e>>2]=Na(c[e>>2]|0,a[(c[g>>2]|0)+3220>>0]&1)|0;c[e>>2]=Sa(c[e>>2]|0,(c[g>>2]|0)+3221|0)|0;c[e>>2]=Sa(c[e>>2]|0,(c[g>>2]|0)+3253|0)|0;c[e>>2]=Sa(c[e>>2]|0,(c[g>>2]|0)+3285|0)|0;c[e>>2]=he(c[e>>2]|0,c[g>>2]|0)|0;i=f;return c[e>>2]|0}function Rb(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+32|0;f=l+16|0;g=l+12|0;h=l+8|0;j=l+4|0;m=l;k=l+20|0;c[g>>2]=b;c[h>>2]=d;c[j>>2]=e;c[g>>2]=Ma(c[g>>2]|0,c[h>>2]|0,m)|0;d=c[m>>2]|0;a:do if((d|0)<1){switch(d|0){case -2147483647:break;default:{d=4;break a}}a[k>>0]=1;d=5}else{switch(d|0){case 1:break;default:{d=4;break a}}a[k>>0]=0;d=5}while(0);if((d|0)==4){c[(c[j>>2]|0)+3216>>2]=9;c[f>>2]=c[h>>2];m=c[f>>2]|0;i=l;return m|0}else if((d|0)==5){c[g>>2]=Oa(c[g>>2]|0,c[h>>2]|0,(c[j>>2]|0)+3220|0)|0;c[g>>2]=Ta(c[g>>2]|0,c[h>>2]|0,(c[j>>2]|0)+3221|0)|0;c[g>>2]=Ta(c[g>>2]|0,c[h>>2]|0,(c[j>>2]|0)+3253|0)|0;c[g>>2]=Ta(c[g>>2]|0,c[h>>2]|0,(c[j>>2]|0)+3285|0)|0;c[g>>2]=pe(c[g>>2]|0,c[h>>2]|0,c[j>>2]|0,a[k>>0]&1)|0;c[f>>2]=c[g>>2];m=c[f>>2]|0;i=l;return m|0}return 0}function Sb(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+16|0;e=g+4|0;f=g;c[e>>2]=b;c[f>>2]=d;d=(c[f>>2]|0)+32|0;b=c[e>>2]|0;e=d+32|0;do{a[d>>0]=a[b>>0]|0;d=d+1|0;b=b+1|0}while((d|0)<(e|0));Gh(c[f>>2]|0,(c[f>>2]|0)+32|0,33122)|0;i=g;return}function Tb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;g=e+8|0;f=e+4|0;h=e;c[g>>2]=a;c[f>>2]=b;c[h>>2]=d;Gh(c[h>>2]|0,(c[g>>2]|0)+32|0,c[f>>2]|0)|0;i=e;return}function Ub(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+16|0;e=g+4|0;f=g;c[e>>2]=b;c[f>>2]=d;d=(c[f>>2]|0)+32|0;b=c[e>>2]|0;e=d+32|0;do{a[d>>0]=a[b>>0]|0;d=d+1|0;b=b+1|0}while((d|0)<(e|0));Gg((c[f>>2]|0)+32|0,c[f>>2]|0);i=g;return}function Vb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;f=i;i=i+16|0;g=f+12|0;j=f+8|0;h=f+4|0;k=f;c[g>>2]=a;c[j>>2]=b;c[h>>2]=d;c[k>>2]=e;Fg(c[k>>2]|0,c[j>>2]|0,c[h>>2]|0,c[g>>2]|0,(c[g>>2]|0)+32|0);i=f;return}function Wb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;f=i;i=i+16|0;g=f+12|0;j=f+8|0;h=f+4|0;k=f;c[g>>2]=a;c[j>>2]=b;c[h>>2]=d;c[k>>2]=e;a=0!=(Dg(c[k>>2]|0,c[j>>2]|0,c[h>>2]|0,c[g>>2]|0)|0);i=f;return a|0}function Xb(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+16-(((c[b>>2]|0)>>>0)%16|0)|0}function Yb(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;p=i;i=i+288|0;r=p+264|0;q=p+260|0;j=p+256|0;k=p+252|0;l=p+248|0;o=p+8|0;n=p+272|0;m=p;c[r>>2]=b;c[q>>2]=e;c[j>>2]=f;c[k>>2]=g;c[l>>2]=h;Dh(c[r>>2]|0,o,256);f=n;g=c[q>>2]|0;e=f+16|0;do{a[f>>0]=a[g>>0]|0;f=f+1|0;g=g+1|0}while((f|0)<(e|0));while(1){if((c[k>>2]|0)>>>0<16)break;Zb(n,c[j>>2]|0);Bh(n,c[l>>2]|0,o,256);f=n;g=c[l>>2]|0;e=f+16|0;do{a[f>>0]=a[g>>0]|0;f=f+1|0;g=g+1|0}while((f|0)<(e|0));c[j>>2]=(c[j>>2]|0)+16;c[l>>2]=(c[l>>2]|0)+16;c[k>>2]=(c[k>>2]|0)-16}c[m>>2]=0;while(1){if((c[m>>2]|0)>>>0>=(c[k>>2]|0)>>>0)break;r=n+(c[m>>2]|0)|0;a[r>>0]=(d[r>>0]|0)^(d[(c[j>>2]|0)+(c[m>>2]|0)>>0]|0);c[m>>2]=(c[m>>2]|0)+1}while(1){if((c[m>>2]|0)>>>0>=16)break;r=n+(c[m>>2]|0)|0;a[r>>0]=(d[r>>0]|0)^16-(c[k>>2]|0);c[m>>2]=(c[m>>2]|0)+1}Bh(n,c[l>>2]|0,o,256);_b(o);$b(n);i=p;return}function Zb(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0;j=i;i=i+16|0;f=j+8|0;g=j+4|0;h=j;c[f>>2]=b;c[g>>2]=e;c[h>>2]=0;while(1){if((c[h>>2]|0)>>>0>=16)break;e=(c[f>>2]|0)+(c[h>>2]|0)|0;a[e>>0]=(d[e>>0]|0)^(d[(c[g>>2]|0)+(c[h>>2]|0)>>0]|0);c[h>>2]=(c[h>>2]|0)+1}i=j;return}function _b(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,240);i=b;return}function $b(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,16);i=b;return}function ac(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;r=i;i=i+304|0;t=r+264|0;s=r+260|0;j=r+256|0;k=r+252|0;l=r+248|0;p=r+8|0;m=r+288|0;n=r+272|0;o=r+4|0;q=r;c[t>>2]=b;c[s>>2]=e;c[j>>2]=f;c[k>>2]=g;c[l>>2]=h;Dh(c[t>>2]|0,p,256);f=m;g=c[s>>2]|0;e=f+16|0;do{a[f>>0]=a[g>>0]|0;f=f+1|0;g=g+1|0}while((f|0)<(e|0));c[o>>2]=0;while(1){if((c[o>>2]|0)>>>0>=(c[k>>2]|0)>>>0)break;f=n;g=(c[j>>2]|0)+(c[o>>2]|0)|0;e=f+16|0;do{a[f>>0]=a[g>>0]|0;f=f+1|0;g=g+1|0}while((f|0)<(e|0));Fh((c[j>>2]|0)+(c[o>>2]|0)|0,(c[l>>2]|0)+(c[o>>2]|0)|0,p,256);Zb((c[l>>2]|0)+(c[o>>2]|0)|0,m);f=m;g=n;e=f+16|0;do{a[f>>0]=a[g>>0]|0;f=f+1|0;g=g+1|0}while((f|0)<(e|0));c[o>>2]=(c[o>>2]|0)+16}_b(p);$b(m);$b(n);c[q>>2]=d[(c[l>>2]|0)+((c[k>>2]|0)-1)>>0];if((c[q>>2]|0)>>>0>(c[k>>2]|0)>>>0){t=-1;i=r;return t|0}t=(c[k>>2]|0)-(c[q>>2]|0)|0;i=r;return t|0}function bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+128|0;j=e+120|0;h=e+116|0;g=e+112|0;f=e;c[j>>2]=a;c[h>>2]=b;c[g>>2]=d;yh(f);zh(f,c[j>>2]|0,c[h>>2]|0);Ah(f,c[g>>2]|0);cc(f);i=e;return}function cc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,112);i=b;return}function dc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;g=i;i=i+208|0;o=g+128|0;n=g+124|0;m=g+120|0;l=g+116|0;k=g+112|0;j=g+136|0;h=g;c[o>>2]=a;c[n>>2]=b;c[m>>2]=d;c[l>>2]=e;c[k>>2]=f;ec(c[o>>2]|0,c[n>>2]|0,j);fc(h,j);zh(h,c[m>>2]|0,c[l>>2]|0);hc(h,j,c[k>>2]|0);gc(j);cc(h);i=g;return}function ec(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+128|0;f=k+120|0;g=k+116|0;h=k+112|0;j=k;c[f>>2]=b;c[g>>2]=d;c[h>>2]=e;e=c[h>>2]|0;b=e+64|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(b|0));if((c[g>>2]|0)>>>0>64){yh(j);zh(j,c[f>>2]|0,c[g>>2]|0);Ah(j,c[h>>2]|0);i=k;return}else{Vh(c[h>>2]|0,c[f>>2]|0,c[g>>2]|0)|0;i=k;return}}function fc(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;k=i;i=i+80|0;g=k+8|0;f=k+4|0;j=k+16|0;h=k;c[g>>2]=b;c[f>>2]=e;b=j;e=c[f>>2]|0;f=b+64|0;do{a[b>>0]=a[e>>0]|0;b=b+1|0;e=e+1|0}while((b|0)<(f|0));c[h>>2]=0;while(1){if((c[h>>2]|0)>>>0>=64)break;f=j+(c[h>>2]|0)|0;a[f>>0]=(d[f>>0]|0)^54;c[h>>2]=(c[h>>2]|0)+1}yh(c[g>>2]|0);zh(c[g>>2]|0,j,64);gc(j);i=k;return}function gc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,64);i=b;return}function hc(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0;m=i;i=i+224|0;g=m+124|0;n=m+120|0;h=m+116|0;l=m+128|0;k=m+112|0;j=m;c[g>>2]=b;c[n>>2]=e;c[h>>2]=f;b=l;e=c[n>>2]|0;f=b+64|0;do{a[b>>0]=a[e>>0]|0;b=b+1|0;e=e+1|0}while((b|0)<(f|0));c[k>>2]=0;while(1){if((c[k>>2]|0)>>>0>=64)break;n=l+(c[k>>2]|0)|0;a[n>>0]=(d[n>>0]|0)^92;c[k>>2]=(c[k>>2]|0)+1}Ah(c[g>>2]|0,l+64|0);yh(j);zh(j,l,96);Ah(j,c[h>>2]|0);cc(j);zb(l);i=m;return}function ic(b,d,e,f,g,h,j,k){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;x=i;i=i+256|0;l=x+144|0;m=x+140|0;n=x+136|0;o=x+132|0;p=x+128|0;q=x+124|0;r=x+120|0;y=x+116|0;t=x;u=x+184|0;w=x+152|0;s=x+112|0;v=x+148|0;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=g;c[q>>2]=h;c[r>>2]=j;c[y>>2]=k;c[s>>2]=c[y>>2];a[v>>0]=1;if(!(c[n>>2]|0)){c[n>>2]=36048;c[o>>2]=32}ec(c[n>>2]|0,c[o>>2]|0,u);fc(t,u);zh(t,c[l>>2]|0,c[m>>2]|0);hc(t,u,w);ec(w,32,u);fc(t,u);zh(t,c[p>>2]|0,c[q>>2]|0);zh(t,v,1);hc(t,u,w);while(1){l=c[r>>2]|0;if((c[s>>2]|0)>>>0<=32)break;m=w;n=l+32|0;do{a[l>>0]=a[m>>0]|0;l=l+1|0;m=m+1|0}while((l|0)<(n|0));c[r>>2]=(c[r>>2]|0)+32;c[s>>2]=(c[s>>2]|0)-32;a[v>>0]=(a[v>>0]|0)+1<<24>>24;fc(t,u);zh(t,w,32);zh(t,c[p>>2]|0,c[q>>2]|0);zh(t,v,1);hc(t,u,w)}Vh(l|0,w|0,c[s>>2]|0)|0;cc(t);gc(u);jc(w);i=x;return}function jc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,32);i=b;return}function kc(){return -1}function lc(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;e=b+4|0;d=b;c[e>>2]=a;c[d>>2]=c[(mc(c[e>>2]|0)|0)+7336>>2];a=Og(c[d>>2]|0)|0;i=b;return a|0}function mc(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[b>>2]|0}function nc(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;e=b+4|0;d=b;c[e>>2]=a;c[d>>2]=c[(oc(c[e>>2]|0)|0)+3216>>2];a=Og(c[d>>2]|0)|0;i=b;return a|0}function oc(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[b>>2]|0}function pc(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;e=b+4|0;d=b;c[e>>2]=a;c[d>>2]=c[(qc(c[e>>2]|0)|0)>>2];a=Og(c[d>>2]|0)|0;i=b;return a|0}function qc(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[b>>2]|0}function rc(){return 7340}function sc(){return 3320}function tc(){return 4}function uc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,7340);a=c[d>>2]|0;Xe(a);a=vc(a)|0;i=b;return a|0}function vc(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[b>>2]|0}function wc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,3320);a=c[d>>2]|0;vb(a);a=xc(a)|0;i=b;return a|0}function xc(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[b>>2]|0}function yc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,4);a=c[d>>2]|0;Ad(a);a=zc(a)|0;i=b;return a|0}function zc(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[b>>2]|0}function Ac(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,7340);Xe(c[d>>2]|0);i=b;return 7340}function Bc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,3320);vb(c[d>>2]|0);i=b;return 3320}function Cc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,4);Ad(c[d>>2]|0);i=b;return 4}function Dc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Pg(tf(mc(c[d>>2]|0)|0)|0)|0;i=b;return a|0}function Ec(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Pg(Nb(oc(c[d>>2]|0)|0)|0)|0;i=b;return a|0}function Fc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;n=i;i=i+32|0;g=n+28|0;p=n+24|0;h=n+20|0;j=n+16|0;k=n+12|0;o=n+8|0;l=n+4|0;m=n;c[p>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[o>>2]=f;c[l>>2]=mc(c[p>>2]|0)|0;c[m>>2]=tf(c[l>>2]|0)|0;f=c[o>>2]|0;if(f>>>0<(Pg(c[m>>2]|0)|0)>>>0){c[(c[l>>2]|0)+7336>>2]=2;c[g>>2]=-1;p=c[g>>2]|0;i=n;return p|0}else{f=Gc(c[k>>2]|0)|0;f=Qg(f,c[m>>2]|0)|0;Af(f,c[l>>2]|0)|0;f=Hc(c[h>>2]|0)|0;o=c[j>>2]|0;p=Gc(c[k>>2]|0)|0;c[g>>2]=Rg(f,o,p,c[m>>2]|0)|0;p=c[g>>2]|0;i=n;return p|0}return 0}function Gc(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[b>>2]|0}function Hc(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[b>>2]|0}function Ic(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;n=i;i=i+32|0;g=n+28|0;p=n+24|0;h=n+20|0;j=n+16|0;k=n+12|0;o=n+8|0;l=n+4|0;m=n;c[p>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[o>>2]=f;c[l>>2]=oc(c[p>>2]|0)|0;c[m>>2]=Nb(c[l>>2]|0)|0;a=c[o>>2]|0;if(a>>>0<(Pg(c[m>>2]|0)|0)>>>0){c[(c[l>>2]|0)+3216>>2]=2;c[g>>2]=-1;p=c[g>>2]|0;i=n;return p|0}else{a=Gc(c[k>>2]|0)|0;a=Qg(a,c[m>>2]|0)|0;Qb(a,c[l>>2]|0)|0;a=Hc(c[h>>2]|0)|0;o=c[j>>2]|0;p=Gc(c[k>>2]|0)|0;c[g>>2]=Rg(a,o,p,c[m>>2]|0)|0;p=c[g>>2]|0;i=n;return p|0}return 0}function Jc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;n=i;i=i+48|0;g=n+36|0;r=n+32|0;p=n+28|0;o=n+24|0;q=n+20|0;h=n+16|0;k=n+12|0;l=n+8|0;m=n+4|0;j=n;c[r>>2]=a;c[p>>2]=b;c[o>>2]=d;c[q>>2]=e;c[h>>2]=f;c[k>>2]=mc(c[r>>2]|0)|0;c[l>>2]=Gc(c[q>>2]|0)|0;f=Hc(c[p>>2]|0)|0;c[m>>2]=Sg(f,c[o>>2]|0,c[l>>2]|0,c[h>>2]|0,(c[k>>2]|0)+7336|0)|0;if((c[m>>2]|0)==-1){c[g>>2]=-1;r=c[g>>2]|0;i=n;return r|0}c[j>>2]=(c[l>>2]|0)+(c[m>>2]|0);r=c[j>>2]|0;if((r|0)==(Ef(c[l>>2]|0,(c[j>>2]|0)+1|0,c[k>>2]|0)|0)){c[g>>2]=c[h>>2];r=c[g>>2]|0;i=n;return r|0}if(!(c[(c[k>>2]|0)+7336>>2]|0))c[(c[k>>2]|0)+7336>>2]=10;c[g>>2]=-1;r=c[g>>2]|0;i=n;return r|0}function Kc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;n=i;i=i+48|0;g=n+36|0;r=n+32|0;p=n+28|0;o=n+24|0;q=n+20|0;h=n+16|0;k=n+12|0;l=n+8|0;m=n+4|0;j=n;c[r>>2]=a;c[p>>2]=b;c[o>>2]=d;c[q>>2]=e;c[h>>2]=f;c[k>>2]=oc(c[r>>2]|0)|0;c[l>>2]=Gc(c[q>>2]|0)|0;a=Hc(c[p>>2]|0)|0;c[m>>2]=Sg(a,c[o>>2]|0,c[l>>2]|0,c[h>>2]|0,(c[k>>2]|0)+3216|0)|0;if((c[m>>2]|0)==-1){c[g>>2]=-1;r=c[g>>2]|0;i=n;return r|0}c[j>>2]=(c[l>>2]|0)+(c[m>>2]|0);r=c[j>>2]|0;if((r|0)==(Rb(c[l>>2]|0,(c[j>>2]|0)+1|0,c[k>>2]|0)|0)){c[g>>2]=c[h>>2];r=c[g>>2]|0;i=n;return r|0}if(!(c[(c[k>>2]|0)+3216>>2]|0))c[(c[k>>2]|0)+3216>>2]=10;c[g>>2]=-1;r=c[g>>2]|0;i=n;return r|0}function Lc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=df(mc(c[d>>2]|0)|0)|0;i=b;return a|0}function Mc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;f=i;i=i+16|0;j=f+12|0;h=f+8|0;g=f+4|0;e=f;c[j>>2]=a;c[h>>2]=b;c[g>>2]=d;b=mc(c[j>>2]|0)|0;d=Gc(c[h>>2]|0)|0;c[e>>2]=ef(b,d,c[g>>2]|0)|0;Jf(c[h>>2]|0,c[g>>2]|0);i=f;return c[e>>2]|0}function Nc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=ff(mc(c[d>>2]|0)|0)|0;i=b;return a|0}function Oc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;h=e+8|0;g=e+4|0;f=e;c[h>>2]=a;c[g>>2]=b;c[f>>2]=d;d=mc(c[h>>2]|0)|0;b=Gc(c[g>>2]|0)|0;b=gf(d,b,c[f>>2]|0)|0;i=e;return b|0}function Pc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Qc(kf(mc(c[d>>2]|0)|0)|0)|0;i=b;return a|0}function Qc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Da(c[d>>2]|0)|0;i=b;return a|0}function Rc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;g=m+24|0;n=m+20|0;h=m+16|0;j=m+12|0;k=m+8|0;o=m+4|0;l=m;c[n>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[o>>2]=f;c[l>>2]=kf(mc(c[n>>2]|0)|0)|0;f=c[o>>2]|0;f=f>>>0<(Qc(c[l>>2]|0)|0)>>>0;a=mc(c[n>>2]|0)|0;if(f){c[a+7336>>2]=2;c[g>>2]=-1;o=c[g>>2]|0;i=m;return o|0}else{h=Hc(c[h>>2]|0)|0;n=c[j>>2]|0;o=Gc(c[k>>2]|0)|0;o=Sc(o,c[l>>2]|0)|0;lf(a,h,n,o,c[l>>2]|0)|0;o=Gc(c[k>>2]|0)|0;c[g>>2]=Tc(o,c[l>>2]|0)|0;o=c[g>>2]|0;i=m;return o|0}return 0}function Sc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e+4|0;d=e;c[f>>2]=a;c[d>>2]=b;b=c[f>>2]|0;b=b+(Da(c[d>>2]|0)|0)|0;i=e;return b+(0-(c[d>>2]|0))|0}function Tc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;d=e+4|0;h=e;c[f>>2]=a;c[g>>2]=b;c[d>>2]=Da(c[g>>2]|0)|0;c[h>>2]=(c[f>>2]|0)+(c[d>>2]|0)+(0-(c[g>>2]|0));Ea(c[h>>2]|0,c[g>>2]|0,c[f>>2]|0)|0;i=e;return c[d>>2]|0}function Uc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=mf(mc(c[d>>2]|0)|0)|0;i=b;return a|0}function Vc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;h=e+8|0;g=e+4|0;f=e;c[h>>2]=a;c[g>>2]=b;c[f>>2]=d;d=mc(c[h>>2]|0)|0;b=Gc(c[g>>2]|0)|0;b=nf(d,b,c[f>>2]|0)|0;i=e;return b|0}function Wc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=of(mc(c[d>>2]|0)|0)|0;i=b;return a|0}function Xc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=pf(mc(c[d>>2]|0)|0)|0;i=b;return a|0}function Yc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;b=mc(c[f>>2]|0)|0;b=qf(b,c[e>>2]|0)|0;i=d;return b|0}function Zc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;g=i;i=i+32|0;l=g+16|0;k=g+12|0;j=g+8|0;h=g+4|0;f=g;c[l>>2]=a;c[k>>2]=b;c[j>>2]=d;c[h>>2]=e;b=mc(c[l>>2]|0)|0;d=c[k>>2]|0;e=Gc(c[j>>2]|0)|0;c[f>>2]=rf(b,d,e,c[h>>2]|0)|0;Jf(c[j>>2]|0,c[h>>2]|0);i=g;return c[f>>2]|0}function _c(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=wb(oc(c[d>>2]|0)|0)|0;i=b;return a|0}function $c(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;w=i;i=i+128|0;k=w+52|0;l=w+48|0;m=w+44|0;A=w+40|0;y=w+36|0;z=w+32|0;x=w+28|0;n=w+24|0;o=w+20|0;p=w+16|0;t=w+12|0;q=w+8|0;u=w+4|0;r=w+88|0;s=w+56|0;v=w;c[l>>2]=a;c[m>>2]=b;c[A>>2]=d;c[y>>2]=e;c[z>>2]=f;c[x>>2]=g;c[n>>2]=h;c[o>>2]=j;c[p>>2]=Hc(c[A>>2]|0)|0;c[t>>2]=Hc(c[z>>2]|0)|0;c[q>>2]=c[y>>2];c[u>>2]=c[x>>2];if((Fa(c[q>>2]|0)|0)==32?(Fa(c[u>>2]|0)|0)==32:0){Ga(c[p>>2]|0,c[q>>2]|0,r)|0;Ga(c[t>>2]|0,c[u>>2]|0,s)|0;y=oc(c[l>>2]|0)|0;z=mc(c[m>>2]|0)|0;A=Gc(c[n>>2]|0)|0;c[v>>2]=xb(y,z,r,s,A,c[o>>2]|0)|0;Jf(c[n>>2]|0,c[o>>2]|0);c[k>>2]=c[v>>2];A=c[k>>2]|0;i=w;return A|0}c[(oc(c[l>>2]|0)|0)+3216>>2]=7;c[k>>2]=-1;A=c[k>>2]|0;i=w;return A|0}function ad(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+32|0;f=l+20|0;g=l+16|0;h=l+12|0;j=l+8|0;m=l+4|0;k=l;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[m>>2]=e;d=Gc(c[j>>2]|0)|0;a=c[m>>2]|0;c[k>>2]=bd(d,a,(oc(c[g>>2]|0)|0)+3216|0)|0;if((c[k>>2]|0)==-1){c[f>>2]=-1;m=c[f>>2]|0;i=l;return m|0}else{d=oc(c[g>>2]|0)|0;a=mc(c[h>>2]|0)|0;m=Gc(c[j>>2]|0)|0;c[f>>2]=Ab(d,a,0,m,c[k>>2]|0)|0;m=c[f>>2]|0;i=l;return m|0}return 0}function bd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;e=k+16|0;f=k+12|0;g=k+8|0;h=k+4|0;j=k;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[j>>2]=Fa(c[g>>2]|0)|0;if((c[j>>2]|0)==-1){c[c[h>>2]>>2]=7;c[e>>2]=-1;j=c[e>>2]|0;i=k;return j|0}else{Ga(c[f>>2]|0,c[g>>2]|0,c[f>>2]|0)|0;c[e>>2]=c[j>>2];j=c[e>>2]|0;i=k;return j|0}return 0}function cd(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;r=i;i=i+80|0;h=r+36|0;j=r+32|0;k=r+28|0;t=r+24|0;s=r+20|0;l=r+16|0;m=r+12|0;n=r+8|0;o=r+4|0;p=r+40|0;q=r;c[j>>2]=a;c[k>>2]=b;c[t>>2]=d;c[s>>2]=e;c[l>>2]=f;c[m>>2]=g;c[n>>2]=Hc(c[t>>2]|0)|0;c[o>>2]=c[s>>2];if((Fa(c[o>>2]|0)|0)!=32){c[(oc(c[j>>2]|0)|0)+3216>>2]=7;c[h>>2]=-1;t=c[h>>2]|0;i=r;return t|0}Ga(c[n>>2]|0,c[o>>2]|0,p)|0;s=Gc(c[l>>2]|0)|0;t=c[m>>2]|0;c[q>>2]=bd(s,t,(oc(c[j>>2]|0)|0)+3216|0)|0;if((c[q>>2]|0)==-1){c[h>>2]=-1;t=c[h>>2]|0;i=r;return t|0}else{e=oc(c[j>>2]|0)|0;s=mc(c[k>>2]|0)|0;t=Gc(c[l>>2]|0)|0;c[h>>2]=Ab(e,s,p,t,c[q>>2]|0)|0;t=c[h>>2]|0;i=r;return t|0}return 0}function dd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Qc(Db(oc(c[d>>2]|0)|0)|0)|0;i=b;return a|0}function ed(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;j=i;i=i+32|0;e=j+20|0;k=j+16|0;f=j+12|0;l=j+8|0;g=j+4|0;h=j;c[k>>2]=a;c[f>>2]=b;c[l>>2]=d;c[g>>2]=Db(oc(c[k>>2]|0)|0)|0;a=c[l>>2]|0;a=a>>>0<(Qc(c[g>>2]|0)|0)>>>0;b=oc(c[k>>2]|0)|0;if(a){c[b+3216>>2]=2;c[e>>2]=-1;l=c[e>>2]|0;i=j;return l|0}l=Gc(c[f>>2]|0)|0;l=Sc(l,c[g>>2]|0)|0;c[h>>2]=Eb(b,l,c[g>>2]|0)|0;if((c[h>>2]|0)==-1){c[e>>2]=c[h>>2];l=c[e>>2]|0;i=j;return l|0}else{l=Gc(c[f>>2]|0)|0;c[e>>2]=Tc(l,c[g>>2]|0)|0;l=c[e>>2]|0;i=j;return l|0}return 0}function fd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+32|0;f=l+16|0;g=l+12|0;h=l+8|0;m=l+4|0;k=l;j=l+20|0;c[g>>2]=b;c[h>>2]=d;c[m>>2]=e;d=Gc(c[h>>2]|0)|0;b=c[m>>2]|0;c[k>>2]=bd(d,b,(oc(c[g>>2]|0)|0)+3216|0)|0;if((c[k>>2]|0)==-1){c[f>>2]=-1;m=c[f>>2]|0;i=l;return m|0}else{b=oc(c[g>>2]|0)|0;m=Gc(c[h>>2]|0)|0;a[j>>0]=(Gb(b,0,m,c[k>>2]|0)|0)&1;c[f>>2]=a[j>>0]&1?1:0;m=c[f>>2]|0;i=l;return m|0}return 0}function gd(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;r=i;i=i+80|0;h=r+32|0;j=r+28|0;t=r+24|0;s=r+20|0;k=r+16|0;l=r+12|0;m=r+8|0;n=r+4|0;o=r+40|0;q=r;p=r+36|0;c[j>>2]=b;c[t>>2]=d;c[s>>2]=e;c[k>>2]=f;c[l>>2]=g;c[m>>2]=Hc(c[t>>2]|0)|0;c[n>>2]=c[s>>2];if((Fa(c[n>>2]|0)|0)!=32){c[(oc(c[j>>2]|0)|0)+3216>>2]=7;c[h>>2]=-1;t=c[h>>2]|0;i=r;return t|0}Ga(c[m>>2]|0,c[n>>2]|0,o)|0;s=Gc(c[k>>2]|0)|0;t=c[l>>2]|0;c[q>>2]=bd(s,t,(oc(c[j>>2]|0)|0)+3216|0)|0;if((c[q>>2]|0)==-1){c[h>>2]=-1;t=c[h>>2]|0;i=r;return t|0}else{s=oc(c[j>>2]|0)|0;t=Gc(c[k>>2]|0)|0;a[p>>0]=(Gb(s,o,t,c[q>>2]|0)|0)&1;c[h>>2]=a[p>>0]&1?1:0;t=c[h>>2]|0;i=r;return t|0}return 0}function hd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;f=i;i=i+16|0;d=f+8|0;g=f+4|0;e=f;c[d>>2]=a;c[g>>2]=b;b=mc(c[d>>2]|0)|0;c[e>>2]=bf(b,(oc(c[g>>2]|0)|0)+3285|0)|0;if((c[e>>2]|0)!=-1){g=c[e>>2]|0;i=f;return g|0}c[(mc(c[d>>2]|0)|0)+7336>>2]=6;g=c[e>>2]|0;i=f;return g|0}function id(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Hb(oc(c[d>>2]|0)|0)|0;i=b;return a|0}function jd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Jb(oc(c[d>>2]|0)|0)|0;i=b;return a|0}function kd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;a=oc(c[f>>2]|0)|0;a=Qc(Ib(a,c[e>>2]|0)|0)|0;i=d;return a|0}function ld(a,b,d,e,f,g,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;r=i;i=i+48|0;j=r+36|0;s=r+32|0;k=r+28|0;l=r+24|0;m=r+20|0;n=r+16|0;o=r+12|0;t=r+8|0;p=r+4|0;q=r;c[s>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[t>>2]=h;a=oc(c[s>>2]|0)|0;c[p>>2]=Ib(a,c[l>>2]|0)|0;a=c[t>>2]|0;a=a>>>0<(Qc(c[p>>2]|0)|0)>>>0;g=oc(c[s>>2]|0)|0;if(a){c[g+3216>>2]=2;c[j>>2]=-1;t=c[j>>2]|0;i=r;return t|0}a=Hc(c[k>>2]|0)|0;k=c[l>>2]|0;l=Gc(c[m>>2]|0)|0;s=c[n>>2]|0;t=Gc(c[o>>2]|0)|0;t=Sc(t,c[p>>2]|0)|0;c[q>>2]=Kb(g,a,k,l,s,t,c[p>>2]|0)|0;Jf(c[m>>2]|0,c[n>>2]|0);if((c[q>>2]|0)==-1){c[j>>2]=c[q>>2];t=c[j>>2]|0;i=r;return t|0}else{t=Gc(c[o>>2]|0)|0;c[j>>2]=Tc(t,c[p>>2]|0)|0;t=c[j>>2]|0;i=r;return t|0}return 0}function md(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;l=i;i=i+32|0;f=l+20|0;g=l+16|0;h=l+12|0;j=l+8|0;m=l+4|0;k=l;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[m>>2]=e;b=Gc(c[j>>2]|0)|0;a=c[m>>2]|0;c[k>>2]=bd(b,a,(oc(c[g>>2]|0)|0)+3216|0)|0;if((c[k>>2]|0)==-1){c[f>>2]=-1;m=c[f>>2]|0;i=l;return m|0}else{b=oc(c[g>>2]|0)|0;a=c[h>>2]|0;m=Gc(c[j>>2]|0)|0;c[f>>2]=Lb(b,a,m,c[k>>2]|0)|0;m=c[f>>2]|0;i=l;return m|0}return 0}function nd(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;p=i;i=i+32|0;h=p+28|0;j=p+24|0;k=p+20|0;l=p+16|0;q=p+12|0;m=p+8|0;n=p+4|0;o=p;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[q>>2]=e;c[m>>2]=f;c[n>>2]=g;f=Gc(c[l>>2]|0)|0;a=c[q>>2]|0;c[o>>2]=bd(f,a,(oc(c[j>>2]|0)|0)+3216|0)|0;if((c[o>>2]|0)==-1){c[h>>2]=-1;q=c[h>>2]|0;i=p;return q|0}else{e=oc(c[j>>2]|0)|0;b=c[k>>2]|0;f=Gc(c[l>>2]|0)|0;a=c[o>>2]|0;q=Gc(c[m>>2]|0)|0;c[h>>2]=Mb(e,b,f,a,q,c[n>>2]|0)|0;q=c[h>>2]|0;i=p;return q|0}return 0}function od(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Qc(Bd(qc(c[d>>2]|0)|0)|0)|0;i=b;return a|0}function pd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;n=i;i=i+32|0;g=n+28|0;o=n+24|0;h=n+20|0;j=n+16|0;k=n+12|0;p=n+8|0;l=n+4|0;m=n;c[o>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[p>>2]=f;c[l>>2]=Bd(qc(c[o>>2]|0)|0)|0;a=c[p>>2]|0;a=a>>>0<(Qc(c[l>>2]|0)|0)>>>0;b=qc(c[o>>2]|0)|0;if(a){c[b>>2]=2;c[g>>2]=-1;p=c[g>>2]|0;i=n;return p|0}h=Hc(c[h>>2]|0)|0;o=c[j>>2]|0;p=Gc(c[k>>2]|0)|0;p=Sc(p,c[l>>2]|0)|0;c[m>>2]=Cd(b,h,o,p,c[l>>2]|0)|0;if((c[m>>2]|0)==-1){c[g>>2]=c[m>>2];p=c[g>>2]|0;i=n;return p|0}else{p=Gc(c[k>>2]|0)|0;c[g>>2]=Tc(p,c[l>>2]|0)|0;p=c[g>>2]|0;i=n;return p|0}return 0}function qd(a,b,d,e,f,g,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;i=i+80|0;j=t+32|0;k=t+28|0;l=t+24|0;m=t+20|0;n=t+16|0;o=t+12|0;p=t+8|0;q=t+4|0;s=t+40|0;r=t;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=g;c[q>>2]=h;if((Fa(c[m>>2]|0)|0)!=32){c[(qc(c[k>>2]|0)|0)>>2]=7;c[j>>2]=-1;s=c[j>>2]|0;i=t;return s|0}h=Hc(c[l>>2]|0)|0;Ga(h,c[m>>2]|0,s)|0;h=Gc(c[p>>2]|0)|0;a=c[q>>2]|0;c[r>>2]=bd(h,a,qc(c[k>>2]|0)|0)|0;if((c[r>>2]|0)==-1){c[j>>2]=-1;s=c[j>>2]|0;i=t;return s|0}else{f=qc(c[k>>2]|0)|0;g=Hc(c[n>>2]|0)|0;h=c[o>>2]|0;a=Gc(c[p>>2]|0)|0;c[j>>2]=Dd(f,s,g,h,a,c[r>>2]|0)|0;s=c[j>>2]|0;i=t;return s|0}return 0}function rd(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 8}function sd(a,b){a=a|0;b=b|0;var d=0,e=0;d=i;i=i+16|0;e=d;c[d+4>>2]=a;c[e>>2]=b;b=Xb(c[e>>2]|0)|0;i=d;return b|0}function td(b,d,e,f,g,h,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;x=i;i=i+160|0;m=x+40|0;z=x+36|0;n=x+32|0;o=x+28|0;p=x+24|0;q=x+20|0;r=x+16|0;y=x+12|0;s=x+8|0;t=x+4|0;u=x;v=x+80|0;w=x+48|0;c[z>>2]=b;c[n>>2]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=g;c[r>>2]=h;c[y>>2]=j;c[s>>2]=k;c[t>>2]=l;c[u>>2]=c[z>>2];g=sd(c[z>>2]|0,c[q>>2]|0)|0;if(g>>>0<(c[y>>2]|0)>>>0){c[m>>2]=-1;z=c[m>>2]|0;i=x;return z|0}else{ud(c[(c[u>>2]|0)+4>>2]|0,c[(c[u>>2]|0)+8>>2]|0,c[n>>2]|0,c[o>>2]|0,v);Yb(v,v+64|0,c[p>>2]|0,c[q>>2]|0,c[r>>2]|0);dc(v+32|0,32,c[s>>2]|0,(c[t>>2]|0)-8|0,w);z=(c[s>>2]|0)+(c[t>>2]|0)+-8|0;a[z>>0]=a[w>>0]|0;a[z+1>>0]=a[w+1>>0]|0;a[z+2>>0]=a[w+2>>0]|0;a[z+3>>0]=a[w+3>>0]|0;a[z+4>>0]=a[w+4>>0]|0;a[z+5>>0]=a[w+5>>0]|0;a[z+6>>0]=a[w+6>>0]|0;a[z+7>>0]=a[w+7>>0]|0;xd(v);c[m>>2]=c[t>>2];z=c[m>>2]|0;i=x;return z|0}return 0}function ud(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;g=i;i=i+112|0;m=g+20|0;l=g+16|0;o=g+12|0;n=g+8|0;k=g+4|0;h=g+24|0;j=g;c[m>>2]=a;c[l>>2]=b;c[o>>2]=d;c[n>>2]=e;c[k>>2]=f;ic(c[o>>2]|0,c[n>>2]|0,0,0,c[m>>2]|0,c[l>>2]|0,h,80);c[j>>2]=h;c[j>>2]=Cb(c[k>>2]|0,c[j>>2]|0)|0;c[j>>2]=Cb((c[k>>2]|0)+32|0,c[j>>2]|0)|0;c[j>>2]=vd((c[k>>2]|0)+64|0,c[j>>2]|0)|0;wd(h);i=g;return}function vd(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+16|0;e=g+4|0;f=g;c[e>>2]=b;c[f>>2]=d;b=c[e>>2]|0;d=c[f>>2]|0;e=b+16|0;do{a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0}while((b|0)<(e|0));i=g;return (c[f>>2]|0)+16|0}function wd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,80);i=b;return}function xd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,80);i=b;return}function yd(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;i=i+16|0;d=e;c[e+4>>2]=a;c[d>>2]=b;i=e;return c[d>>2]|0}function zd(a,b,d,e,f,g,h,j,k){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;r=i;i=i+176|0;l=r+48|0;z=r+44|0;x=r+40|0;w=r+36|0;v=r+32|0;u=r+28|0;m=r+24|0;n=r+20|0;o=r+16|0;y=r+8|0;p=r+88|0;s=r+56|0;t=r+4|0;q=r;c[z>>2]=a;c[x>>2]=b;c[w>>2]=d;c[v>>2]=e;c[u>>2]=f;c[m>>2]=g;c[n>>2]=h;c[o>>2]=j;c[r+12>>2]=k;c[y>>2]=c[z>>2];ud(c[(c[y>>2]|0)+4>>2]|0,c[(c[y>>2]|0)+8>>2]|0,c[x>>2]|0,c[w>>2]|0,p);dc(p+32|0,32,c[v>>2]|0,(c[u>>2]|0)-8|0,s);c[t>>2]=(c[v>>2]|0)+(c[u>>2]|0)+-8;if(Kf(c[t>>2]|0,s,8)|0){c[q>>2]=ac(p,p+64|0,c[m>>2]|0,c[n>>2]|0,c[o>>2]|0)|0;xd(p);c[l>>2]=c[q>>2];z=c[l>>2]|0;i=r;return z|0}else{xd(p);c[l>>2]=-1;z=c[l>>2]|0;i=r;return z|0}return 0}function Ad(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;c[c[d>>2]>>2]=0;i=b;return}function Bd(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 32}function Cd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0;l=i;i=i+32|0;g=l+20|0;n=l+16|0;h=l+12|0;j=l+8|0;k=l+4|0;m=l;c[n>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[m>>2]=f;b=c[n>>2]|0;a=c[m>>2]|0;if(a>>>0<(Bd(b)|0)>>>0){c[b>>2]=2;c[g>>2]=-1;n=c[g>>2]|0;i=l;return n|0}else{bc(c[h>>2]|0,c[j>>2]|0,c[k>>2]|0);c[g>>2]=32;n=c[g>>2]|0;i=l;return n|0}return 0}function Dd(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;n=i;i=i+32|0;h=n+24|0;p=n+20|0;j=n+16|0;k=n+12|0;l=n+8|0;m=n+4|0;o=n;c[p>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[o>>2]=g;b=c[p>>2]|0;if((c[o>>2]|0)>>>0<64){c[b>>2]=5;c[h>>2]=-1;p=c[h>>2]|0;i=n;return p|0}if(Wb(c[j>>2]|0,c[k>>2]|0,c[l>>2]|0,c[m>>2]|0)|0){c[h>>2]=0;p=c[h>>2]|0;i=n;return p|0}else{c[b>>2]=5;c[h>>2]=-1;p=c[h>>2]|0;i=n;return p|0}return 0}function Ed(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;h=e+8|0;g=e+4|0;f=e;c[h>>2]=a;c[g>>2]=b;c[f>>2]=d;a=c[h>>2]|0;c[a>>2]=c[g>>2];c[a+4>>2]=c[f>>2];c[a+8>>2]=0;Fd(a+44|0);Gd(a+148|0);Hd(a+492|0);i=e;return}function Fd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;c[a>>2]=a+4;i=b;return}function Gd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;c[a>>2]=a+4;i=b;return}function Hd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;c[a>>2]=a+4;i=b;return}function Id(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0;h=i;i=i+96|0;n=h+16|0;m=h+12|0;l=h+8|0;j=h+4|0;g=h+24|0;k=h;c[n>>2]=b;c[m>>2]=d;c[l>>2]=e;c[j>>2]=f;d=c[n>>2]|0;ic(c[m>>2]|0,c[l>>2]|0,0,0,c[c[d>>2]>>2]|0,c[(c[d>>2]|0)+4>>2]|0,g,64);Jd(d+148|0)|0;c[(Md(d+148|0,0)|0)+32>>2]=0;c[k>>2]=g;c[k>>2]=Cb(d+12|0,c[k>>2]|0)|0;e=(Md(d+148|0,0)|0)+32+4|0;c[k>>2]=Cb(e,c[k>>2]|0)|0;d=Md(d+148|0,0)|0;e=c[j>>2]|0;f=d+32|0;do{a[d>>0]=a[e>>0]|0;d=d+1|0;e=e+1|0}while((d|0)<(f|0));gc(g);i=h;return}function Jd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;a=Ld(a,Kd(a)|0)|0;i=b;return a|0}function Kd(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+4|0}function Ld(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;i=i+16|0;d=g+8|0;e=g+4|0;f=g;c[d>>2]=a;c[e>>2]=b;b=c[d>>2]|0;if((c[b>>2]|0)==(b+4+340|0)){if((c[e>>2]|0)==(c[b>>2]|0))c[e>>2]=(c[e>>2]|0)+-68}else c[b>>2]=(c[b>>2]|0)+68;c[f>>2]=(c[b>>2]|0)+-68;while(1){if((c[f>>2]|0)==(c[e>>2]|0))break;b=c[f>>2]|0;a=(c[f>>2]|0)+-68|0;d=b+68|0;do{c[b>>2]=c[a>>2];b=b+4|0;a=a+4|0}while((b|0)<(d|0));c[f>>2]=(c[f>>2]|0)+-68}i=g;return c[e>>2]|0}function Md(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+16|0;e=f+4|0;d=f;c[e>>2]=a;c[d>>2]=b;i=f;return (c[e>>2]|0)+4+((c[d>>2]|0)*68|0)|0}function Nd(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0;h=i;i=i+96|0;n=h+16|0;m=h+12|0;l=h+8|0;j=h+4|0;g=h+24|0;k=h;c[n>>2]=b;c[m>>2]=d;c[l>>2]=e;c[j>>2]=f;f=c[n>>2]|0;ic(c[m>>2]|0,c[l>>2]|0,0,0,c[c[f>>2]>>2]|0,c[(c[f>>2]|0)+4>>2]|0,g,64);Od(f+44|0)|0;c[(Rd(f+44|0,0)|0)+64>>2]=0;c[k>>2]=g;c[k>>2]=Cb(f+12|0,c[k>>2]|0)|0;d=(Rd(f+44|0,0)|0)+64+4|0;c[k>>2]=Cb(d,c[k>>2]|0)|0;f=Rd(f+44|0,0)|0;d=c[j>>2]|0;e=f+64|0;do{a[f>>0]=a[d>>0]|0;f=f+1|0;d=d+1|0}while((f|0)<(e|0));gc(g);i=h;return}function Od(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;a=Qd(a,Pd(a)|0)|0;i=b;return a|0}function Pd(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+4|0}function Qd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;i=i+16|0;d=g+8|0;e=g+4|0;f=g;c[d>>2]=a;c[e>>2]=b;b=c[d>>2]|0;if((c[b>>2]|0)==(b+4+100|0)){if((c[e>>2]|0)==(c[b>>2]|0))c[e>>2]=(c[e>>2]|0)+-100}else c[b>>2]=(c[b>>2]|0)+100;c[f>>2]=(c[b>>2]|0)+-100;while(1){if((c[f>>2]|0)==(c[e>>2]|0))break;b=c[f>>2]|0;a=(c[f>>2]|0)+-100|0;d=b+100|0;do{c[b>>2]=c[a>>2];b=b+4|0;a=a+4|0}while((b|0)<(d|0));c[f>>2]=(c[f>>2]|0)+-100}i=g;return c[e>>2]|0}function Rd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+16|0;e=f+4|0;d=f;c[e>>2]=a;c[d>>2]=b;i=f;return (c[e>>2]|0)+4+((c[d>>2]|0)*100|0)|0}function Sd(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;c[b>>2]=(c[b>>2]|0)+32;a=Td((c[e>>2]|0)+44|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Zd((c[e>>2]|0)+148|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=ce((c[e>>2]|0)+492|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0}function Td(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;g=i;i=i+32|0;j=g+24|0;e=g+20|0;k=g+16|0;h=g+12|0;b=g+8|0;d=g+4|0;f=g;c[j>>2]=a;c[k>>2]=Ud(c[j>>2]|0)|0;c[e>>2]=Ob(k)|0;c[h>>2]=c[j>>2];c[b>>2]=Vd(c[h>>2]|0)|0;c[d>>2]=Wd(c[h>>2]|0)|0;while(1){if((c[b>>2]|0)==(c[d>>2]|0))break;c[f>>2]=c[b>>2];k=Xd(c[f>>2]|0)|0;c[e>>2]=(c[e>>2]|0)+k;c[b>>2]=(c[b>>2]|0)+100}i=g;return c[e>>2]|0}function Ud(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;i=b;return ((c[a>>2]|0)-(a+4)|0)/100|0|0}function Vd(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+4|0}function Wd(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[c[b>>2]>>2]|0}function Xd(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;a=Ua(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Yd((c[e>>2]|0)+64+4|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ob((c[e>>2]|0)+64|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0}function Yd(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 32}function Zd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;g=i;i=i+32|0;j=g+24|0;e=g+20|0;k=g+16|0;h=g+12|0;b=g+8|0;d=g+4|0;f=g;c[j>>2]=a;c[k>>2]=_d(c[j>>2]|0)|0;c[e>>2]=Ob(k)|0;c[h>>2]=c[j>>2];c[b>>2]=$d(c[h>>2]|0)|0;c[d>>2]=ae(c[h>>2]|0)|0;while(1){if((c[b>>2]|0)==(c[d>>2]|0))break;c[f>>2]=c[b>>2];k=be(c[f>>2]|0)|0;c[e>>2]=(c[e>>2]|0)+k;c[b>>2]=(c[b>>2]|0)+68}i=g;return c[e>>2]|0}function _d(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;i=b;return ((c[a>>2]|0)-(a+4)|0)/68|0|0}function $d(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+4|0}function ae(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[c[b>>2]>>2]|0}function be(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;a=Ra(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Yd((c[e>>2]|0)+32+4|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ob((c[e>>2]|0)+32|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0}function ce(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;g=i;i=i+32|0;j=g+24|0;e=g+20|0;k=g+16|0;h=g+12|0;b=g+8|0;d=g+4|0;f=g;c[j>>2]=a;c[k>>2]=de(c[j>>2]|0)|0;c[e>>2]=Ob(k)|0;c[h>>2]=c[j>>2];c[b>>2]=ee(c[h>>2]|0)|0;c[d>>2]=fe(c[h>>2]|0)|0;while(1){if((c[b>>2]|0)==(c[d>>2]|0))break;c[f>>2]=c[b>>2];k=ge(c[f>>2]|0)|0;c[e>>2]=(c[e>>2]|0)+k;c[b>>2]=(c[b>>2]|0)+68}i=g;return c[e>>2]|0}function de(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;i=b;return ((c[a>>2]|0)-(a+4)|0)/68|0|0}function ee(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+4|0}function fe(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[c[b>>2]>>2]|0}function ge(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;a=Ra(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Yd((c[e>>2]|0)+32+4|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ob((c[e>>2]|0)+32|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0}function he(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=ie(c[d>>2]|0,(c[f>>2]|0)+12|0)|0;c[d>>2]=je(c[d>>2]|0,(c[f>>2]|0)+44|0)|0;c[d>>2]=le(c[d>>2]|0,(c[f>>2]|0)+148|0)|0;c[d>>2]=ne(c[d>>2]|0,(c[f>>2]|0)+492|0)|0;i=e;return c[d>>2]|0}function ie(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;b=Pa(c[f>>2]|0,c[e>>2]|0,32)|0;i=d;return b|0}function je(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;i=i+32|0;d=h+20|0;k=h+16|0;j=h+12|0;e=h+8|0;f=h+4|0;g=h;c[d>>2]=a;c[k>>2]=b;a=c[d>>2]|0;c[d>>2]=La(a,Ud(c[k>>2]|0)|0)|0;c[j>>2]=c[k>>2];c[e>>2]=Vd(c[j>>2]|0)|0;c[f>>2]=Wd(c[j>>2]|0)|0;while(1){if((c[e>>2]|0)==(c[f>>2]|0))break;c[g>>2]=c[e>>2];c[d>>2]=ke(c[d>>2]|0,c[g>>2]|0)|0;c[e>>2]=(c[e>>2]|0)+100}i=h;return c[d>>2]|0}function ke(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=Va(c[d>>2]|0,c[f>>2]|0)|0;c[d>>2]=ie(c[d>>2]|0,(c[f>>2]|0)+64+4|0)|0;c[d>>2]=La(c[d>>2]|0,c[(c[f>>2]|0)+64>>2]|0)|0;i=e;return c[d>>2]|0}function le(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;i=i+32|0;d=h+20|0;k=h+16|0;j=h+12|0;e=h+8|0;f=h+4|0;g=h;c[d>>2]=a;c[k>>2]=b;a=c[d>>2]|0;c[d>>2]=La(a,_d(c[k>>2]|0)|0)|0;c[j>>2]=c[k>>2];c[e>>2]=$d(c[j>>2]|0)|0;c[f>>2]=ae(c[j>>2]|0)|0;while(1){if((c[e>>2]|0)==(c[f>>2]|0))break;c[g>>2]=c[e>>2];c[d>>2]=me(c[d>>2]|0,c[g>>2]|0)|0;c[e>>2]=(c[e>>2]|0)+68}i=h;return c[d>>2]|0}function me(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=Sa(c[d>>2]|0,c[f>>2]|0)|0;c[d>>2]=ie(c[d>>2]|0,(c[f>>2]|0)+32+4|0)|0;c[d>>2]=La(c[d>>2]|0,c[(c[f>>2]|0)+32>>2]|0)|0;i=e;return c[d>>2]|0}function ne(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;i=i+32|0;d=h+20|0;k=h+16|0;j=h+12|0;e=h+8|0;f=h+4|0;g=h;c[d>>2]=a;c[k>>2]=b;a=c[d>>2]|0;c[d>>2]=La(a,de(c[k>>2]|0)|0)|0;c[j>>2]=c[k>>2];c[e>>2]=ee(c[j>>2]|0)|0;c[f>>2]=fe(c[j>>2]|0)|0;while(1){if((c[e>>2]|0)==(c[f>>2]|0))break;c[g>>2]=c[e>>2];c[d>>2]=oe(c[d>>2]|0,c[g>>2]|0)|0;c[e>>2]=(c[e>>2]|0)+68}i=h;return c[d>>2]|0}function oe(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=Sa(c[d>>2]|0,c[f>>2]|0)|0;c[d>>2]=ie(c[d>>2]|0,(c[f>>2]|0)+32+4|0)|0;c[d>>2]=La(c[d>>2]|0,c[(c[f>>2]|0)+32>>2]|0)|0;i=e;return c[d>>2]|0}function pe(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;j=i;i=i+32|0;g=j+12|0;h=j+8|0;l=j+4|0;k=j+16|0;c[g>>2]=b;c[h>>2]=d;c[l>>2]=e;a[k>>0]=f&1;c[g>>2]=qe(c[g>>2]|0,c[h>>2]|0,(c[l>>2]|0)+12|0)|0;c[g>>2]=re(c[g>>2]|0,c[h>>2]|0,(c[l>>2]|0)+44|0)|0;c[g>>2]=ue(c[g>>2]|0,c[h>>2]|0,(c[l>>2]|0)+148|0)|0;c[g>>2]=xe(c[g>>2]|0,c[h>>2]|0,(c[l>>2]|0)+492|0)|0;if(!(a[k>>0]&1)){l=c[g>>2]|0;i=j;return l|0}c[g>>2]=Ma(c[g>>2]|0,c[h>>2]|0,j)|0;l=c[g>>2]|0;i=j;return l|0}function qe(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;h=e+8|0;g=e+4|0;f=e;c[h>>2]=a;c[g>>2]=b;c[f>>2]=d;d=Qa(c[h>>2]|0,c[g>>2]|0,c[f>>2]|0,32)|0;i=e;return d|0}function re(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;j=k+16|0;e=k+12|0;f=k+8|0;g=k+4|0;h=k;c[j>>2]=a;c[e>>2]=b;c[f>>2]=d;c[j>>2]=Ma(c[j>>2]|0,c[e>>2]|0,g)|0;while(1){a=c[g>>2]|0;c[g>>2]=a+-1;if(!a){e=5;break}if((c[j>>2]|0)==(c[e>>2]|0)){e=5;break}a=c[f>>2]|0;c[h>>2]=Qd(a,se(c[f>>2]|0)|0)|0;c[j>>2]=te(c[j>>2]|0,c[e>>2]|0,c[h>>2]|0)|0}if((e|0)==5){i=k;return c[j>>2]|0}return 0}function se(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[c[b>>2]>>2]|0}function te(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;e=f+8|0;h=f+4|0;g=f;c[e>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=Wa(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0)|0;c[e>>2]=qe(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+64+4|0)|0;c[e>>2]=Ma(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+64|0)|0;i=f;return c[e>>2]|0}function ue(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;j=k+16|0;e=k+12|0;f=k+8|0;g=k+4|0;h=k;c[j>>2]=a;c[e>>2]=b;c[f>>2]=d;c[j>>2]=Ma(c[j>>2]|0,c[e>>2]|0,g)|0;while(1){a=c[g>>2]|0;c[g>>2]=a+-1;if(!a){e=5;break}if((c[j>>2]|0)==(c[e>>2]|0)){e=5;break}a=c[f>>2]|0;c[h>>2]=Ld(a,ve(c[f>>2]|0)|0)|0;c[j>>2]=we(c[j>>2]|0,c[e>>2]|0,c[h>>2]|0)|0}if((e|0)==5){i=k;return c[j>>2]|0}return 0}function ve(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[c[b>>2]>>2]|0}function we(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;e=f+8|0;h=f+4|0;g=f;c[e>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=Ta(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0)|0;c[e>>2]=qe(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+32+4|0)|0;c[e>>2]=Ma(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+32|0)|0;i=f;return c[e>>2]|0}function xe(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;j=k+16|0;e=k+12|0;f=k+8|0;g=k+4|0;h=k;c[j>>2]=a;c[e>>2]=b;c[f>>2]=d;c[j>>2]=Ma(c[j>>2]|0,c[e>>2]|0,g)|0;while(1){a=c[g>>2]|0;c[g>>2]=a+-1;if(!a){e=5;break}if((c[j>>2]|0)==(c[e>>2]|0)){e=5;break}a=c[f>>2]|0;c[h>>2]=ze(a,ye(c[f>>2]|0)|0)|0;c[j>>2]=Ae(c[j>>2]|0,c[e>>2]|0,c[h>>2]|0)|0}if((e|0)==5){i=k;return c[j>>2]|0}return 0}function ye(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[c[b>>2]>>2]|0}function ze(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;i=i+16|0;d=g+8|0;e=g+4|0;f=g;c[d>>2]=a;c[e>>2]=b;b=c[d>>2]|0;if((c[b>>2]|0)==(b+4+2720|0)){if((c[e>>2]|0)==(c[b>>2]|0))c[e>>2]=(c[e>>2]|0)+-68}else c[b>>2]=(c[b>>2]|0)+68;c[f>>2]=(c[b>>2]|0)+-68;while(1){if((c[f>>2]|0)==(c[e>>2]|0))break;b=c[f>>2]|0;a=(c[f>>2]|0)+-68|0;d=b+68|0;do{c[b>>2]=c[a>>2];b=b+4|0;a=a+4|0}while((b|0)<(d|0));c[f>>2]=(c[f>>2]|0)+-68}i=g;return c[e>>2]|0}function Ae(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;e=f+8|0;h=f+4|0;g=f;c[e>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=Ta(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0)|0;c[e>>2]=qe(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+32+4|0)|0;c[e>>2]=Ma(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+32|0)|0;i=f;return c[e>>2]|0}function Be(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;g=i;i=i+16|0;h=g+12|0;d=g+8|0;e=g+4|0;f=g;c[h>>2]=a;c[d>>2]=b;b=c[h>>2]|0;c[e>>2]=0;if(!(Ce(b+44|0)|0))c[e>>2]=c[(Rd(b+44|0,0)|0)+64>>2];c[f>>2]=ta[c[(c[c[b+4>>2]>>2]|0)+4>>2]&3](c[b+4>>2]|0,c[d>>2]|0)|0;e=c[e>>2]|0;h=c[f>>2]|0;h=cb(e,32,h,ra[c[c[c[b+4>>2]>>2]>>2]&1](c[b+4>>2]|0)|0)|0;i=g;return h|0}function Ce(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;i=b;return (c[a>>2]|0)==(a+4|0)|0}function De(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Ce((c[d>>2]|0)+44|0)|0;i=b;return (a?32:0)|0}function Ee(a,b,d,e,f,g,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;v=i;i=i+96|0;j=v+88|0;x=v+84|0;k=v+80|0;l=v+76|0;m=v+72|0;w=v+68|0;n=v+64|0;o=v+60|0;s=v+56|0;r=v+20|0;p=v+16|0;q=v+12|0;t=v+8|0;u=v;c[x>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[w>>2]=f;c[n>>2]=g;c[o>>2]=h;h=c[x>>2]|0;c[s>>2]=Be(h,c[l>>2]|0)|0;a=c[w>>2]|0;if(a>>>0<(De(h)|0)>>>0){c[h+8>>2]=1;c[j>>2]=-1;x=c[j>>2]|0;i=v;return x|0}if((c[o>>2]|0)>>>0<(c[s>>2]|0)>>>0){c[h+8>>2]=2;c[j>>2]=-1;x=c[j>>2]|0;i=v;return x|0}if(Ce(h+44|0)|0){Od(h+44|0)|0;o=c[m>>2]|0;Sb(o,Rd(h+44|0,0)|0);o=Rd(h+44|0,0)|0;w=Md(h+148|0,0)|0;x=c[h>>2]|0;Fe(h+12|0,o,w,x,h+12|0,(Rd(h+44|0,0)|0)+64|0)}x=(Rd(h+44|0,0)|0)+64|0;Ge(x,c[h>>2]|0,r);x=(Rd(h+44|0,0)|0)+64|0;He(x,(Rd(h+44|0,0)|0)+64|0);c[p>>2]=ta[c[(c[c[h+4>>2]>>2]|0)+4>>2]&3](c[h+4>>2]|0,c[l>>2]|0)|0;c[q>>2]=c[r>>2];c[t>>2]=Rd(h+44|0,0)|0;fb(u,3,c[q>>2]|0,32,c[p>>2]|0,c[n>>2]|0);Fb(c[u>>2]|0,c[t>>2]|0)|0;sa[c[(c[c[h+4>>2]>>2]|0)+8>>2]&3](c[h+4>>2]|0,r+4|0,32,c[k>>2]|0,c[l>>2]|0,c[u+4>>2]|0,c[p>>2]|0,c[n>>2]|0,c[s>>2]|0)|0;Ie(r);c[j>>2]=c[s>>2];x=c[j>>2]|0;i=v;return x|0}function Fe(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;h=i;i=i+128|0;p=h+24|0;r=h+20|0;q=h+16|0;o=h+12|0;n=h+8|0;l=h+4|0;j=h+96|0;k=h+32|0;m=h;c[p>>2]=a;c[r>>2]=b;c[q>>2]=d;c[o>>2]=e;c[n>>2]=f;c[l>>2]=g;Tb(c[r>>2]|0,c[q>>2]|0,j);ic(j,32,c[p>>2]|0,32,c[(c[o>>2]|0)+8>>2]|0,c[(c[o>>2]|0)+12>>2]|0,k,64);c[m>>2]=k;c[m>>2]=Cb(c[n>>2]|0,c[m>>2]|0)|0;c[m>>2]=Cb((c[l>>2]|0)+4|0,c[m>>2]|0)|0;c[c[l>>2]>>2]=0;gc(k);jc(j);i=h;return}function Ge(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;e=i;i=i+16|0;g=e+8|0;f=e;c[g>>2]=a;c[e+4>>2]=b;c[f>>2]=d;dc((c[g>>2]|0)+4|0,32,33154,1,(c[f>>2]|0)+4|0);c[c[f>>2]>>2]=c[c[g>>2]>>2];i=e;return}function He(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;dc((c[f>>2]|0)+4|0,32,33155,1,(c[e>>2]|0)+4|0);c[c[e>>2]>>2]=(c[c[f>>2]>>2]|0)+1;i=d;return}function Ie(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,36);i=b;return}function Je(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;g=i;i=i+48|0;e=g+44|0;k=g+40|0;j=g+36|0;h=g+32|0;f=g;c[k>>2]=a;c[j>>2]=b;c[h>>2]=d;b=c[k>>2]|0;d=c[j>>2]|0;a=c[h>>2]|0;jb(f,d,a,ra[c[c[c[b+4>>2]>>2]>>2]&1](c[b+4>>2]|0)|0);if(c[f+24>>2]|0){c[e>>2]=ta[c[(c[c[b+4>>2]>>2]|0)+12>>2]&3](c[b+4>>2]|0,c[f+28>>2]|0)|0;k=c[e>>2]|0;i=g;return k|0}else{c[b+8>>2]=4;c[e>>2]=-1;k=c[e>>2]|0;i=g;return k|0}return 0}function Ke(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;A=i;i=i+112|0;j=A+100|0;D=A+96|0;C=A+92|0;B=A+88|0;k=A+84|0;l=A+80|0;v=A+48|0;u=A+44|0;s=A+40|0;q=A+36|0;m=A+32|0;o=A+28|0;w=A+24|0;x=A+20|0;r=A+16|0;n=A+12|0;p=A+8|0;y=A+4|0;t=A;c[D>>2]=b;c[C>>2]=e;c[B>>2]=f;c[k>>2]=g;c[l>>2]=h;e=c[D>>2]|0;g=c[C>>2]|0;b=c[B>>2]|0;jb(v,g,b,ra[c[c[c[e+4>>2]>>2]>>2]&1](c[e+4>>2]|0)|0);if((d[v>>0]|0|0)!=3){c[e+8>>2]=3;c[j>>2]=-1;D=c[j>>2]|0;i=A;return D|0}if((a[v+1>>0]&1?c[v+16>>2]|0:0)?c[v+24>>2]|0:0){c[u>>2]=ta[c[(c[c[e+4>>2]>>2]|0)+12>>2]&3](c[e+4>>2]|0,c[v+28>>2]|0)|0;if((c[l>>2]|0)>>>0<(c[u>>2]|0)>>>0){c[e+8>>2]=2;c[j>>2]=-1;D=c[j>>2]|0;i=A;return D|0}if((c[v+20>>2]|0)!=32){c[e+8>>2]=4;c[j>>2]=-1;D=c[j>>2]|0;i=A;return D|0}c[s>>2]=0;c[q>>2]=e+148;c[m>>2]=Kd(c[q>>2]|0)|0;c[o>>2]=ve(c[q>>2]|0)|0;while(1){if((c[m>>2]|0)==(c[o>>2]|0))break;c[w>>2]=c[m>>2];if(!(Lh(c[w>>2]|0,c[v+16>>2]|0,32)|0)){z=14;break}c[m>>2]=(c[m>>2]|0)+68}if((z|0)==14)c[s>>2]=c[w>>2];c[x>>2]=-1;a:do if(c[s>>2]|0){if((c[(c[s>>2]|0)+32>>2]|0)>>>0<=(c[v+4>>2]|0)>>>0){c[x>>2]=Ne(e,(c[s>>2]|0)+32|0,v,c[k>>2]|0,c[l>>2]|0)|0;break}c[r>>2]=e+492;c[n>>2]=Re(c[r>>2]|0)|0;c[p>>2]=ye(c[r>>2]|0)|0;while(1){if((c[n>>2]|0)==(c[p>>2]|0))break a;c[y>>2]=c[n>>2];if(((c[v+4>>2]|0)==(c[(c[y>>2]|0)+32>>2]|0)?0==(Lh(c[y>>2]|0,c[v+16>>2]|0,32)|0):0)?(c[x>>2]=Oe(c[e+4>>2]|0,(c[y>>2]|0)+32|0,v,c[k>>2]|0,c[l>>2]|0)|0,(c[x>>2]|0)!=-1):0)break;c[n>>2]=(c[n>>2]|0)+68}Se(c[y>>2]|0);Te(e+492|0,c[y>>2]|0);c[j>>2]=c[x>>2];D=c[j>>2]|0;i=A;return D|0}else c[x>>2]=Le(e,v,c[k>>2]|0,c[l>>2]|0)|0;while(0);if((c[x>>2]|0)==-1){c[e+8>>2]=5;c[j>>2]=-1;D=c[j>>2]|0;i=A;return D|0}if(!(c[s>>2]|0)){c[s>>2]=Jd(e+148|0)|0;Cb(c[s>>2]|0,c[v+16>>2]|0)|0;D=Rd(e+44|0,0)|0;Fe(e+12|0,D,c[s>>2]|0,c[e>>2]|0,e+12|0,(c[s>>2]|0)+32|0);Ue(Rd(e+44|0,0)|0);Ve(e+44|0,Pd(e+44|0)|0)}while(1){if((c[(c[s>>2]|0)+32>>2]|0)>>>0>=(c[v+4>>2]|0)>>>0)break;c[t>>2]=We(e+492|0)|0;Ge((c[s>>2]|0)+32|0,c[e>>2]|0,(c[t>>2]|0)+32|0);D=c[t>>2]|0;C=c[s>>2]|0;c[D>>2]=c[C>>2];c[D+4>>2]=c[C+4>>2];c[D+8>>2]=c[C+8>>2];c[D+12>>2]=c[C+12>>2];c[D+16>>2]=c[C+16>>2];c[D+20>>2]=c[C+20>>2];c[D+24>>2]=c[C+24>>2];c[D+28>>2]=c[C+28>>2];He((c[s>>2]|0)+32|0,(c[s>>2]|0)+32|0)}He((c[s>>2]|0)+32|0,(c[s>>2]|0)+32|0);c[j>>2]=c[x>>2];D=c[j>>2]|0;i=A;return D|0}c[e+8>>2]=4;c[j>>2]=-1;D=c[j>>2]|0;i=A;return D|0}function Le(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;i=i+128|0;f=o+88|0;g=o+84|0;h=o+80|0;j=o+76|0;k=o+72|0;m=o+96|0;l=o+4|0;n=o;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;if(Ce((c[g>>2]|0)+44|0)|0){c[f>>2]=-1;a=c[f>>2]|0;i=o;return a|0}if((c[(c[h>>2]|0)+4>>2]|0)>>>0>2e3){c[f>>2]=-1;a=c[f>>2]|0;i=o;return a|0}else{Cb(l,c[(c[h>>2]|0)+16>>2]|0)|0;b=(c[g>>2]|0)+12|0;a=Me((c[g>>2]|0)+44|0,0)|0;Fe(b,a,l,c[c[g>>2]>>2]|0,m,l+32|0);c[n>>2]=Ne(c[g>>2]|0,l+32|0,c[h>>2]|0,c[j>>2]|0,c[k>>2]|0)|0;jc(m);Qe(l);c[f>>2]=c[n>>2];a=c[f>>2]|0;i=o;return a|0}return 0}function Me(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=i;i=i+16|0;e=f+4|0;d=f;c[e>>2]=a;c[d>>2]=b;i=f;return (c[e>>2]|0)+4+((c[d>>2]|0)*100|0)|0}function Ne(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;i=i+112|0;h=q+96|0;j=q+92|0;g=q+88|0;k=q+84|0;l=q+80|0;m=q+76|0;o=q+40|0;n=q+4|0;p=q;c[j>>2]=a;c[g>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;if((c[(c[k>>2]|0)+4>>2]|0)>>>0<(c[c[g>>2]>>2]|0)>>>0){c[h>>2]=-1;p=c[h>>2]|0;i=q;return p|0}if(((c[(c[k>>2]|0)+4>>2]|0)-(c[c[g>>2]>>2]|0)|0)>>>0>2e3){c[h>>2]=-1;p=c[h>>2]|0;i=q;return p|0}e=o;b=c[g>>2]|0;f=e+36|0;do{c[e>>2]=c[b>>2];e=e+4|0;b=b+4|0}while((e|0)<(f|0));while(1){if((c[o>>2]|0)>>>0>=(c[(c[k>>2]|0)+4>>2]|0)>>>0)break;He(o,o)}Ge(o,c[c[j>>2]>>2]|0,n);c[p>>2]=Oe(c[(c[j>>2]|0)+4>>2]|0,n,c[k>>2]|0,c[l>>2]|0,c[m>>2]|0)|0;Pe(o);c[h>>2]=c[p>>2];p=c[h>>2]|0;i=q;return p|0}function Oe(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0;g=i;i=i+32|0;m=g+16|0;l=g+12|0;k=g+8|0;j=g+4|0;h=g;c[m>>2]=a;c[l>>2]=b;c[k>>2]=d;c[j>>2]=e;c[h>>2]=f;d=sa[c[(c[c[m>>2]>>2]|0)+16>>2]&3](c[m>>2]|0,(c[l>>2]|0)+4|0,32,c[(c[k>>2]|0)+8>>2]|0,c[(c[k>>2]|0)+12>>2]|0,c[(c[k>>2]|0)+24>>2]|0,c[(c[k>>2]|0)+28>>2]|0,c[j>>2]|0,c[h>>2]|0)|0;i=g;return d|0}function Pe(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,36);i=b;return}function Qe(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,68);i=b;return}function Re(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+4|0}function Se(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,68);i=b;return}function Te(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;i=i+16|0;e=g+4|0;f=g;c[e>>2]=a;c[f>>2]=b;b=c[e>>2]|0;c[b>>2]=(c[b>>2]|0)+-68;while(1){if((c[f>>2]|0)==(c[b>>2]|0))break;a=c[f>>2]|0;d=(c[f>>2]|0)+68|0;e=a+68|0;do{c[a>>2]=c[d>>2];a=a+4|0;d=d+4|0}while((a|0)<(e|0));c[f>>2]=(c[f>>2]|0)+68}i=g;return}function Ue(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jf(c[d>>2]|0,100);i=b;return}function Ve(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=i;i=i+16|0;e=g+4|0;f=g;c[e>>2]=a;c[f>>2]=b;b=c[e>>2]|0;c[b>>2]=(c[b>>2]|0)+-100;while(1){if((c[f>>2]|0)==(c[b>>2]|0))break;a=c[f>>2]|0;d=(c[f>>2]|0)+100|0;e=a+100|0;do{c[a>>2]=c[d>>2];a=a+4|0;d=d+4|0}while((a|0)<(e|0));c[f>>2]=(c[f>>2]|0)+100}i=g;return}function We(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;a=ze(a,Re(a)|0)|0;i=b;return a|0}function Xe(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;Ye(a+128|0);c[a+7332>>2]=0;c[a+7336>>2]=0;i=b;return}function Ye(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;c[a>>2]=a+4;i=b;return}function Ze(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;j=i;i=i+32|0;g=j+24|0;l=j+20|0;d=j+16|0;k=j+12|0;e=j+8|0;f=j+4|0;h=j;c[l>>2]=a;c[d>>2]=b;c[k>>2]=(c[l>>2]|0)+128;c[e>>2]=_e(c[k>>2]|0)|0;c[f>>2]=$e(c[k>>2]|0)|0;while(1){if((c[e>>2]|0)==(c[f>>2]|0)){d=6;break}c[h>>2]=c[e>>2];if(af((c[h>>2]|0)+5|0,c[d>>2]|0)|0){d=4;break}c[e>>2]=(c[e>>2]|0)+72}if((d|0)==4){c[g>>2]=c[h>>2];l=c[g>>2]|0;i=j;return l|0}else if((d|0)==6){c[g>>2]=0;l=c[g>>2]|0;i=j;return l|0}return 0}function _e(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+4|0}function $e(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[c[b>>2]>>2]|0}function af(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;b=Kf(c[f>>2]|0,c[e>>2]|0,32)|0;i=d;return b|0}function bf(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;j=i;i=i+32|0;f=j+16|0;d=j+12|0;e=j+8|0;g=j+4|0;h=j;c[d>>2]=a;c[e>>2]=b;d=c[d>>2]|0;c[g>>2]=_e(d+128|0)|0;while(1){a=c[g>>2]|0;if((a|0)==($e(d+128|0)|0)){b=6;break}b=af((c[g>>2]|0)+5|0,c[e>>2]|0)|0;a=c[g>>2]|0;if(b){b=4;break}c[g>>2]=a+72}if((b|0)==4){c[h>>2]=c[a>>2];cf(d+128|0,c[g>>2]|0);c[f>>2]=c[h>>2];h=c[f>>2]|0;i=j;return h|0}else if((b|0)==6){c[f>>2]=-1;h=c[f>>2]|0;i=j;return h|0}return 0}function cf(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;k=i;i=i+16|0;h=k+4|0;j=k;c[h>>2]=b;c[j>>2]=d;b=c[h>>2]|0;c[b>>2]=(c[b>>2]|0)+-72;while(1){if((c[j>>2]|0)==(c[b>>2]|0))break;e=c[j>>2]|0;d=(c[j>>2]|0)+72|0;f=e;g=d;h=f+68|0;do{c[f>>2]=c[g>>2];f=f+4|0;g=g+4|0}while((f|0)<(h|0));a[e+68>>0]=a[d+68>>0]|0;c[j>>2]=(c[j>>2]|0)+72}i=k;return}function df(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 64}function ef(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;g=i;i=i+16|0;e=g+12|0;j=g+8|0;f=g+4|0;h=g;c[j>>2]=a;c[f>>2]=b;c[h>>2]=d;b=c[j>>2]|0;a=c[h>>2]|0;if(a>>>0<(df(b)|0)>>>0){c[b+7336>>2]=1;c[e>>2]=-1;j=c[e>>2]|0;i=g;return j|0}else{Ub(c[f>>2]|0,b);c[f>>2]=(c[f>>2]|0)+32;Sb(c[f>>2]|0,b+64|0);c[e>>2]=0;j=c[e>>2]|0;i=g;return j|0}return 0}function ff(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[d+4>>2]=a;c[b>>2]=0;c[b>>2]=(c[b>>2]|0)+1;c[b>>2]=(c[b>>2]|0)+13;c[b>>2]=(c[b>>2]|0)+1;a=Da(32)|0;c[b>>2]=(c[b>>2]|0)+a;c[b>>2]=(c[b>>2]|0)+2;c[b>>2]=(c[b>>2]|0)+10;c[b>>2]=(c[b>>2]|0)+1;a=Da(32)|0;c[b>>2]=(c[b>>2]|0)+a;c[b>>2]=(c[b>>2]|0)+2;i=d;return c[b>>2]|0}function gf(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;j=i;i=i+32|0;f=j+20|0;m=j+16|0;g=j+12|0;l=j+8|0;h=j+4|0;k=j;c[m>>2]=b;c[g>>2]=d;c[l>>2]=e;d=c[m>>2]|0;c[h>>2]=c[g>>2];c[k>>2]=ff(d)|0;if((c[l>>2]|0)>>>0<(c[k>>2]|0)>>>0){c[d+7336>>2]=2;c[f>>2]=-1;m=c[f>>2]|0;i=j;return m|0}else{m=c[h>>2]|0;c[h>>2]=m+1;a[m>>0]=123;c[h>>2]=hf(c[h>>2]|0,33156)|0;m=c[h>>2]|0;c[h>>2]=m+1;a[m>>0]=34;c[h>>2]=Ea(d+64|0,32,c[h>>2]|0)|0;m=c[h>>2]|0;c[h>>2]=m+1;a[m>>0]=34;m=c[h>>2]|0;c[h>>2]=m+1;a[m>>0]=44;c[h>>2]=jf(c[h>>2]|0,33170)|0;m=c[h>>2]|0;c[h>>2]=m+1;a[m>>0]=34;c[h>>2]=Ea(d,32,c[h>>2]|0)|0;m=c[h>>2]|0;c[h>>2]=m+1;a[m>>0]=34;m=c[h>>2]|0;c[h>>2]=m+1;a[m>>0]=125;c[f>>2]=(c[h>>2]|0)-(c[g>>2]|0);m=c[f>>2]|0;i=j;return m|0}return 0}function hf(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+16|0;f=g+4|0;e=g;c[f>>2]=b;c[e>>2]=d;b=c[f>>2]|0;d=c[e>>2]|0;e=b+13|0;do{a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0}while((b|0)<(e|0));i=g;return (c[f>>2]|0)+13|0}function jf(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;g=i;i=i+16|0;f=g+4|0;e=g;c[f>>2]=b;c[e>>2]=d;b=c[f>>2]|0;d=c[e>>2]|0;e=b+10|0;do{a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0}while((b|0)<(e|0));i=g;return (c[f>>2]|0)+10|0}function kf(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 64}function lf(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0;l=i;i=i+32|0;g=l+20|0;n=l+16|0;h=l+12|0;j=l+8|0;k=l+4|0;m=l;c[n>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[m>>2]=f;b=c[n>>2]|0;a=c[m>>2]|0;if(a>>>0<(kf(b)|0)>>>0){c[b+7336>>2]=2;c[g>>2]=-1;n=c[g>>2]|0;i=l;return n|0}else{Vb(b,c[h>>2]|0,c[j>>2]|0,c[k>>2]|0);c[g>>2]=kf(b)|0;n=c[g>>2]|0;i=l;return n|0}return 0}function mf(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;j=i;i=i+32|0;l=j+20|0;h=j+16|0;f=j+24|0;k=j+12|0;d=j+8|0;e=j+4|0;g=j;c[l>>2]=b;b=c[l>>2]|0;c[h>>2]=0;a[f>>0]=1;c[k>>2]=b+128;c[d>>2]=_e(c[k>>2]|0)|0;c[e>>2]=$e(c[k>>2]|0)|0;while(1){if((c[d>>2]|0)==(c[e>>2]|0))break;c[g>>2]=c[d>>2];if(!(a[(c[g>>2]|0)+4>>0]&1)){a[f>>0]=0;c[h>>2]=(c[h>>2]|0)+2;l=Da(Ob(c[g>>2]|0)|0)|0;c[h>>2]=(c[h>>2]|0)+l;c[h>>2]=(c[h>>2]|0)+3;l=Da(32)|0;c[h>>2]=(c[h>>2]|0)+l;c[h>>2]=(c[h>>2]|0)+1}c[d>>2]=(c[d>>2]|0)+72}if(!(a[f>>0]&1)){l=c[h>>2]|0;l=l+3|0;c[h>>2]=l;l=c[h>>2]|0;l=l+13|0;c[h>>2]=l;l=c[h>>2]|0;i=j;return l|0}c[h>>2]=(c[h>>2]|0)+1;l=c[h>>2]|0;l=l+3|0;c[h>>2]=l;l=c[h>>2]|0;l=l+13|0;c[h>>2]=l;l=c[h>>2]|0;i=j;return l|0}function nf(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;q=i;i=i+48|0;g=q+36|0;s=q+32|0;h=q+28|0;r=q+24|0;o=q+20|0;p=q+40|0;m=q+16|0;k=q+12|0;l=q+8|0;n=q+4|0;j=q;c[s>>2]=b;c[h>>2]=e;c[r>>2]=f;e=c[s>>2]|0;c[o>>2]=c[h>>2];b=c[r>>2]|0;if(b>>>0<(mf(e)|0)>>>0){c[e+7336>>2]=2;c[g>>2]=-1;s=c[g>>2]|0;i=q;return s|0}s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=123;c[o>>2]=hf(c[o>>2]|0,33156)|0;a[p>>0]=123;c[m>>2]=e+128;c[k>>2]=_e(c[m>>2]|0)|0;c[l>>2]=$e(c[m>>2]|0)|0;while(1){if((c[k>>2]|0)==(c[l>>2]|0))break;c[n>>2]=c[k>>2];if(!(a[(c[n>>2]|0)+4>>0]&1)){r=a[p>>0]|0;s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=r;s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=34;s=Ob(c[n>>2]|0)|0;c[j>>2]=ja()|0;r=i;i=i+((1*s|0)+15&-16)|0;La(r,c[c[n>>2]>>2]|0)|0;c[o>>2]=Ea(r,s,c[o>>2]|0)|0;s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=34;s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=58;s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=34;c[o>>2]=Ea((c[n>>2]|0)+5|0,32,c[o>>2]|0)|0;s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=34;a[p>>0]=44;oa(c[j>>2]|0)}c[k>>2]=(c[k>>2]|0)+72}if((d[p>>0]|0|0)!=44){r=a[p>>0]|0;s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=r}s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=125;s=c[o>>2]|0;c[o>>2]=s+1;a[s>>0]=125;c[g>>2]=(c[o>>2]|0)-(c[h>>2]|0);s=c[g>>2]|0;i=q;return s|0}function of(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;i=i+32|0;k=h+20|0;f=h+16|0;j=h+12|0;d=h+8|0;e=h+4|0;g=h;c[k>>2]=b;b=c[k>>2]|0;c[f>>2]=0;c[j>>2]=b+128;c[d>>2]=_e(c[j>>2]|0)|0;c[e>>2]=$e(c[j>>2]|0)|0;while(1){if((c[d>>2]|0)==(c[e>>2]|0))break;c[g>>2]=c[d>>2];if(!(a[(c[g>>2]|0)+4>>0]&1)){a[(c[g>>2]|0)+4>>0]=1;c[f>>2]=(c[f>>2]|0)+1}c[d>>2]=(c[d>>2]|0)+72}i=h;return c[f>>2]|0}function pf(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 100}function qf(a,b){a=a|0;b=b|0;var d=0,e=0;e=i;i=i+16|0;d=e;c[e+4>>2]=a;c[d>>2]=b;i=e;return c[d>>2]<<5|0}function rf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;g=m+24|0;o=m+20|0;h=m+16|0;j=m+12|0;n=m+8|0;k=m+4|0;l=m;c[o>>2]=b;c[h>>2]=d;c[j>>2]=e;c[n>>2]=f;d=c[o>>2]|0;b=c[n>>2]|0;if(b>>>0<(qf(d,c[h>>2]|0)|0)>>>0){c[d+7336>>2]=1;c[g>>2]=-1;o=c[g>>2]|0;i=m;return o|0}c[k>>2]=0;while(1){if((c[k>>2]|0)>>>0>=(c[h>>2]|0)>>>0)break;c[l>>2]=sf(d+128|0,_e(d+128|0)|0)|0;n=d+7332|0;o=(c[n>>2]|0)+1|0;c[n>>2]=o;c[c[l>>2]>>2]=o;a[(c[l>>2]|0)+4>>0]=0;Sb(c[j>>2]|0,(c[l>>2]|0)+5|0);c[j>>2]=(c[j>>2]|0)+32;c[k>>2]=(c[k>>2]|0)+1}c[g>>2]=c[h>>2];o=c[g>>2]|0;i=m;return o|0}function sf(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;k=i;i=i+16|0;g=k+8|0;h=k+4|0;j=k;c[g>>2]=b;c[h>>2]=d;d=c[g>>2]|0;if((c[d>>2]|0)==(d+4+7200|0)){if((c[h>>2]|0)==(c[d>>2]|0))c[h>>2]=(c[h>>2]|0)+-72}else c[d>>2]=(c[d>>2]|0)+72;c[j>>2]=(c[d>>2]|0)+-72;while(1){if((c[j>>2]|0)==(c[h>>2]|0))break;d=c[j>>2]|0;b=(c[j>>2]|0)+-72|0;e=d;f=b;g=e+68|0;do{c[e>>2]=c[f>>2];e=e+4|0;f=f+4|0}while((e|0)<(g|0));a[d+68>>0]=a[b+68>>0]|0;c[j>>2]=(c[j>>2]|0)+-72}i=k;return c[h>>2]|0}function tf(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;a=Ob(700)|0;c[b>>2]=(c[b>>2]|0)+a;a=uf(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=vf((c[e>>2]|0)+128|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ob((c[e>>2]|0)+7332|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0}function uf(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;a=Xa(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ua((c[e>>2]|0)+64|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0}function vf(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;g=i;i=i+32|0;j=g+24|0;e=g+20|0;k=g+16|0;h=g+12|0;b=g+8|0;d=g+4|0;f=g;c[j>>2]=a;c[k>>2]=wf(c[j>>2]|0)|0;c[e>>2]=Ob(k)|0;c[h>>2]=c[j>>2];c[b>>2]=xf(c[h>>2]|0)|0;c[d>>2]=yf(c[h>>2]|0)|0;while(1){if((c[b>>2]|0)==(c[d>>2]|0))break;c[f>>2]=c[b>>2];k=zf(c[f>>2]|0)|0;c[e>>2]=(c[e>>2]|0)+k;c[b>>2]=(c[b>>2]|0)+72}i=g;return c[e>>2]|0}function wf(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;i=b;return ((c[a>>2]|0)-(a+4)|0)/72|0|0}function xf(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return (c[b>>2]|0)+4|0}function yf(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[c[b>>2]>>2]|0}function zf(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;a=Ob(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Pb((c[e>>2]|0)+4|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ua((c[e>>2]|0)+5|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0}function Af(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=La(c[d>>2]|0,1)|0;c[d>>2]=Bf(c[d>>2]|0,c[f>>2]|0)|0;c[d>>2]=Cf(c[d>>2]|0,(c[f>>2]|0)+128|0)|0;c[d>>2]=La(c[d>>2]|0,c[(c[f>>2]|0)+7332>>2]|0)|0;i=e;return c[d>>2]|0}function Bf(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;d=e+4|0;f=e;c[d>>2]=a;c[f>>2]=b;c[d>>2]=Ya(c[d>>2]|0,c[f>>2]|0)|0;c[d>>2]=Va(c[d>>2]|0,(c[f>>2]|0)+64|0)|0;i=e;return c[d>>2]|0}function Cf(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;h=i;i=i+32|0;d=h+20|0;k=h+16|0;j=h+12|0;e=h+8|0;f=h+4|0;g=h;c[d>>2]=a;c[k>>2]=b;a=c[d>>2]|0;c[d>>2]=La(a,wf(c[k>>2]|0)|0)|0;c[j>>2]=c[k>>2];c[e>>2]=xf(c[j>>2]|0)|0;c[f>>2]=yf(c[j>>2]|0)|0;while(1){if((c[e>>2]|0)==(c[f>>2]|0))break;c[g>>2]=c[e>>2];c[d>>2]=Df(c[d>>2]|0,c[g>>2]|0)|0;c[e>>2]=(c[e>>2]|0)+72}i=h;return c[d>>2]|0}function Df(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;f=i;i=i+16|0;e=f+4|0;g=f;c[e>>2]=b;c[g>>2]=d;c[e>>2]=La(c[e>>2]|0,c[c[g>>2]>>2]|0)|0;c[e>>2]=Na(c[e>>2]|0,a[(c[g>>2]|0)+4>>0]&1)|0;c[e>>2]=Va(c[e>>2]|0,(c[g>>2]|0)+5|0)|0;i=f;return c[e>>2]|0}function Ef(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;j=i;i=i+32|0;e=j+16|0;f=j+12|0;g=j+8|0;h=j+4|0;k=j;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[f>>2]=Ma(c[f>>2]|0,c[g>>2]|0,k)|0;if((c[k>>2]|0)!=1){c[(c[h>>2]|0)+7336>>2]=9;c[e>>2]=c[g>>2];k=c[e>>2]|0;i=j;return k|0}else{c[f>>2]=Ff(c[f>>2]|0,c[g>>2]|0,c[h>>2]|0)|0;c[f>>2]=Gf(c[f>>2]|0,c[g>>2]|0,(c[h>>2]|0)+128|0)|0;c[f>>2]=Ma(c[f>>2]|0,c[g>>2]|0,(c[h>>2]|0)+7332|0)|0;c[e>>2]=c[f>>2];k=c[e>>2]|0;i=j;return k|0}return 0}function Ff(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;e=f+8|0;h=f+4|0;g=f;c[e>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=Za(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0)|0;c[e>>2]=Wa(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+64|0)|0;i=f;return c[e>>2]|0}function Gf(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;k=i;i=i+32|0;j=k+16|0;e=k+12|0;f=k+8|0;g=k+4|0;h=k;c[j>>2]=a;c[e>>2]=b;c[f>>2]=d;c[j>>2]=Ma(c[j>>2]|0,c[e>>2]|0,g)|0;while(1){a=c[g>>2]|0;c[g>>2]=a+-1;if(!a){e=5;break}if((c[j>>2]|0)==(c[e>>2]|0)){e=5;break}a=c[f>>2]|0;c[h>>2]=sf(a,$e(c[f>>2]|0)|0)|0;c[j>>2]=Hf(c[j>>2]|0,c[e>>2]|0,c[h>>2]|0)|0}if((e|0)==5){i=k;return c[j>>2]|0}return 0}function Hf(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;e=f+8|0;h=f+4|0;g=f;c[e>>2]=a;c[h>>2]=b;c[g>>2]=d;c[e>>2]=Ma(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0)|0;c[e>>2]=Oa(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+4|0)|0;c[e>>2]=Wa(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+5|0)|0;i=f;return c[e>>2]|0}function If(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;Jf(c[f>>2]|0,c[e>>2]|0);i=d;return}function Jf(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;g=i;i=i+16|0;j=g+12|0;h=g+8|0;f=g+4|0;e=g;c[j>>2]=b;c[h>>2]=d;c[f>>2]=c[j>>2];c[e>>2]=(c[f>>2]|0)+(c[h>>2]|0);while(1){if((c[f>>2]|0)==(c[e>>2]|0))break;j=c[f>>2]|0;c[f>>2]=j+1;a[j>>0]=0}i=g;return}function Kf(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;l=i;i=i+16|0;g=l+8|0;h=l+4|0;j=l;k=l+12|0;c[g>>2]=b;c[h>>2]=e;c[j>>2]=f;a[k>>0]=0;while(1){f=c[j>>2]|0;c[j>>2]=f+-1;if(!f)break;e=c[g>>2]|0;c[g>>2]=e+1;e=d[e>>0]|0;f=c[h>>2]|0;c[h>>2]=f+1;a[k>>0]=d[k>>0]|0|e^(d[f>>0]|0)}i=l;return (d[k>>0]|0|0)==0|0}function Lf(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;c[c[d>>2]>>2]=0;c[(c[d>>2]|0)+4>>2]=0;c[(c[d>>2]|0)+8>>2]=0;c[(c[d>>2]|0)+12>>2]=0;c[(c[d>>2]|0)+16>>2]=0;c[(c[d>>2]|0)+20>>2]=0;c[(c[d>>2]|0)+24>>2]=0;c[(c[d>>2]|0)+28>>2]=0;c[(c[d>>2]|0)+32>>2]=0;c[(c[d>>2]|0)+36>>2]=0;i=b;return}function Mf(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;c[c[d>>2]>>2]=1;c[(c[d>>2]|0)+4>>2]=0;c[(c[d>>2]|0)+8>>2]=0;c[(c[d>>2]|0)+12>>2]=0;c[(c[d>>2]|0)+16>>2]=0;c[(c[d>>2]|0)+20>>2]=0;c[(c[d>>2]|0)+24>>2]=0;c[(c[d>>2]|0)+28>>2]=0;c[(c[d>>2]|0)+32>>2]=0;c[(c[d>>2]|0)+36>>2]=0;i=b;return}function Nf(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;e=i;i=i+144|0;f=e+128|0;M=e+124|0;L=e+120|0;K=e+116|0;I=e+112|0;G=e+108|0;E=e+104|0;C=e+100|0;A=e+96|0;y=e+92|0;w=e+88|0;u=e+84|0;s=e+80|0;J=e+76|0;H=e+72|0;F=e+68|0;D=e+64|0;B=e+60|0;z=e+56|0;x=e+52|0;v=e+48|0;t=e+44|0;r=e+40|0;q=e+36|0;p=e+32|0;o=e+28|0;n=e+24|0;m=e+20|0;l=e+16|0;k=e+12|0;j=e+8|0;h=e+4|0;g=e;c[f>>2]=a;c[M>>2]=b;c[L>>2]=d;c[K>>2]=c[c[M>>2]>>2];c[I>>2]=c[(c[M>>2]|0)+4>>2];c[G>>2]=c[(c[M>>2]|0)+8>>2];c[E>>2]=c[(c[M>>2]|0)+12>>2];c[C>>2]=c[(c[M>>2]|0)+16>>2];c[A>>2]=c[(c[M>>2]|0)+20>>2];c[y>>2]=c[(c[M>>2]|0)+24>>2];c[w>>2]=c[(c[M>>2]|0)+28>>2];c[u>>2]=c[(c[M>>2]|0)+32>>2];c[s>>2]=c[(c[M>>2]|0)+36>>2];c[J>>2]=c[c[L>>2]>>2];c[H>>2]=c[(c[L>>2]|0)+4>>2];c[F>>2]=c[(c[L>>2]|0)+8>>2];c[D>>2]=c[(c[L>>2]|0)+12>>2];c[B>>2]=c[(c[L>>2]|0)+16>>2];c[z>>2]=c[(c[L>>2]|0)+20>>2];c[x>>2]=c[(c[L>>2]|0)+24>>2];c[v>>2]=c[(c[L>>2]|0)+28>>2];c[t>>2]=c[(c[L>>2]|0)+32>>2];c[r>>2]=c[(c[L>>2]|0)+36>>2];c[q>>2]=(c[K>>2]|0)+(c[J>>2]|0);c[p>>2]=(c[I>>2]|0)+(c[H>>2]|0);c[o>>2]=(c[G>>2]|0)+(c[F>>2]|0);c[n>>2]=(c[E>>2]|0)+(c[D>>2]|0);c[m>>2]=(c[C>>2]|0)+(c[B>>2]|0);c[l>>2]=(c[A>>2]|0)+(c[z>>2]|0);c[k>>2]=(c[y>>2]|0)+(c[x>>2]|0);c[j>>2]=(c[w>>2]|0)+(c[v>>2]|0);c[h>>2]=(c[u>>2]|0)+(c[t>>2]|0);c[g>>2]=(c[s>>2]|0)+(c[r>>2]|0);c[c[f>>2]>>2]=c[q>>2];c[(c[f>>2]|0)+4>>2]=c[p>>2];c[(c[f>>2]|0)+8>>2]=c[o>>2];c[(c[f>>2]|0)+12>>2]=c[n>>2];c[(c[f>>2]|0)+16>>2]=c[m>>2];c[(c[f>>2]|0)+20>>2]=c[l>>2];c[(c[f>>2]|0)+24>>2]=c[k>>2];c[(c[f>>2]|0)+28>>2]=c[j>>2];c[(c[f>>2]|0)+32>>2]=c[h>>2];c[(c[f>>2]|0)+36>>2]=c[g>>2];i=e;return}function Of(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;e=i;i=i+144|0;f=e+128|0;M=e+124|0;B=e+120|0;A=e+116|0;y=e+112|0;w=e+108|0;u=e+104|0;s=e+100|0;q=e+96|0;o=e+92|0;m=e+88|0;k=e+84|0;h=e+80|0;L=e+76|0;K=e+72|0;J=e+68|0;I=e+64|0;H=e+60|0;G=e+56|0;F=e+52|0;E=e+48|0;D=e+44|0;C=e+40|0;z=e+36|0;x=e+32|0;v=e+28|0;t=e+24|0;r=e+20|0;p=e+16|0;n=e+12|0;l=e+8|0;j=e+4|0;g=e;c[f>>2]=a;c[M>>2]=b;c[B>>2]=d;c[A>>2]=c[c[f>>2]>>2];c[y>>2]=c[(c[f>>2]|0)+4>>2];c[w>>2]=c[(c[f>>2]|0)+8>>2];c[u>>2]=c[(c[f>>2]|0)+12>>2];c[s>>2]=c[(c[f>>2]|0)+16>>2];c[q>>2]=c[(c[f>>2]|0)+20>>2];c[o>>2]=c[(c[f>>2]|0)+24>>2];c[m>>2]=c[(c[f>>2]|0)+28>>2];c[k>>2]=c[(c[f>>2]|0)+32>>2];c[h>>2]=c[(c[f>>2]|0)+36>>2];c[L>>2]=c[c[M>>2]>>2];c[K>>2]=c[(c[M>>2]|0)+4>>2];c[J>>2]=c[(c[M>>2]|0)+8>>2];c[I>>2]=c[(c[M>>2]|0)+12>>2];c[H>>2]=c[(c[M>>2]|0)+16>>2];c[G>>2]=c[(c[M>>2]|0)+20>>2];c[F>>2]=c[(c[M>>2]|0)+24>>2];c[E>>2]=c[(c[M>>2]|0)+28>>2];c[D>>2]=c[(c[M>>2]|0)+32>>2];c[C>>2]=c[(c[M>>2]|0)+36>>2];c[z>>2]=c[A>>2]^c[L>>2];c[x>>2]=c[y>>2]^c[K>>2];c[v>>2]=c[w>>2]^c[J>>2];c[t>>2]=c[u>>2]^c[I>>2];c[r>>2]=c[s>>2]^c[H>>2];c[p>>2]=c[q>>2]^c[G>>2];c[n>>2]=c[o>>2]^c[F>>2];c[l>>2]=c[m>>2]^c[E>>2];c[j>>2]=c[k>>2]^c[D>>2];c[g>>2]=c[h>>2]^c[C>>2];c[B>>2]=0-(c[B>>2]|0);c[z>>2]=c[z>>2]&c[B>>2];c[x>>2]=c[x>>2]&c[B>>2];c[v>>2]=c[v>>2]&c[B>>2];c[t>>2]=c[t>>2]&c[B>>2];c[r>>2]=c[r>>2]&c[B>>2];c[p>>2]=c[p>>2]&c[B>>2];c[n>>2]=c[n>>2]&c[B>>2];c[l>>2]=c[l>>2]&c[B>>2];c[j>>2]=c[j>>2]&c[B>>2];c[g>>2]=c[g>>2]&c[B>>2];c[c[f>>2]>>2]=c[A>>2]^c[z>>2];c[(c[f>>2]|0)+4>>2]=c[y>>2]^c[x>>2];c[(c[f>>2]|0)+8>>2]=c[w>>2]^c[v>>2];c[(c[f>>2]|0)+12>>2]=c[u>>2]^c[t>>2];c[(c[f>>2]|0)+16>>2]=c[s>>2]^c[r>>2];c[(c[f>>2]|0)+20>>2]=c[q>>2]^c[p>>2];c[(c[f>>2]|0)+24>>2]=c[o>>2]^c[n>>2];c[(c[f>>2]|0)+28>>2]=c[m>>2]^c[l>>2];c[(c[f>>2]|0)+32>>2]=c[k>>2]^c[j>>2];c[(c[f>>2]|0)+36>>2]=c[h>>2]^c[g>>2];i=e;return}function Pf(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;d=i;i=i+48|0;e=d+44|0;q=d+40|0;p=d+36|0;o=d+32|0;n=d+28|0;m=d+24|0;l=d+20|0;k=d+16|0;j=d+12|0;h=d+8|0;g=d+4|0;f=d;c[e>>2]=a;c[q>>2]=b;c[p>>2]=c[c[q>>2]>>2];c[o>>2]=c[(c[q>>2]|0)+4>>2];c[n>>2]=c[(c[q>>2]|0)+8>>2];c[m>>2]=c[(c[q>>2]|0)+12>>2];c[l>>2]=c[(c[q>>2]|0)+16>>2];c[k>>2]=c[(c[q>>2]|0)+20>>2];c[j>>2]=c[(c[q>>2]|0)+24>>2];c[h>>2]=c[(c[q>>2]|0)+28>>2];c[g>>2]=c[(c[q>>2]|0)+32>>2];c[f>>2]=c[(c[q>>2]|0)+36>>2];c[c[e>>2]>>2]=c[p>>2];c[(c[e>>2]|0)+4>>2]=c[o>>2];c[(c[e>>2]|0)+8>>2]=c[n>>2];c[(c[e>>2]|0)+12>>2]=c[m>>2];c[(c[e>>2]|0)+16>>2]=c[l>>2];c[(c[e>>2]|0)+20>>2]=c[k>>2];c[(c[e>>2]|0)+24>>2]=c[j>>2];c[(c[e>>2]|0)+28>>2]=c[h>>2];c[(c[e>>2]|0)+32>>2]=c[g>>2];c[(c[e>>2]|0)+36>>2]=c[f>>2];i=d;return}function Qf(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;d=i;i=i+176|0;e=d+164|0;A=d+160|0;p=d+152|0;o=d+144|0;n=d+136|0;m=d+128|0;l=d+120|0;k=d+112|0;j=d+104|0;h=d+96|0;g=d+88|0;f=d+80|0;u=d+72|0;y=d+64|0;t=d+56|0;x=d+48|0;s=d+40|0;w=d+32|0;r=d+24|0;v=d+16|0;q=d+8|0;z=d;c[e>>2]=a;c[A>>2]=b;b=Rf(c[A>>2]|0)|0;a=p;c[a>>2]=b;c[a+4>>2]=C;a=Sf((c[A>>2]|0)+4|0)|0;a=Uh(a|0,C|0,6)|0;b=o;c[b>>2]=a;c[b+4>>2]=C;b=Sf((c[A>>2]|0)+7|0)|0;b=Uh(b|0,C|0,5)|0;a=n;c[a>>2]=b;c[a+4>>2]=C;a=Sf((c[A>>2]|0)+10|0)|0;a=Uh(a|0,C|0,3)|0;b=m;c[b>>2]=a;c[b+4>>2]=C;b=Sf((c[A>>2]|0)+13|0)|0;b=Uh(b|0,C|0,2)|0;a=l;c[a>>2]=b;c[a+4>>2]=C;a=Rf((c[A>>2]|0)+16|0)|0;b=k;c[b>>2]=a;c[b+4>>2]=C;b=Sf((c[A>>2]|0)+20|0)|0;b=Uh(b|0,C|0,7)|0;a=j;c[a>>2]=b;c[a+4>>2]=C;a=Sf((c[A>>2]|0)+23|0)|0;a=Uh(a|0,C|0,5)|0;b=h;c[b>>2]=a;c[b+4>>2]=C;b=Sf((c[A>>2]|0)+26|0)|0;b=Uh(b|0,C|0,4)|0;a=g;c[a>>2]=b;c[a+4>>2]=C;a=Sf((c[A>>2]|0)+29|0)|0;a=Uh(a&8388607|0,0,2)|0;b=f;c[b>>2]=a;c[b+4>>2]=C;b=f;b=Qh(c[b>>2]|0,c[b+4>>2]|0,16777216,0)|0;b=Rh(b|0,C|0,25)|0;a=z;c[a>>2]=b;c[a+4>>2]=C;a=z;a=_h(c[a>>2]|0,c[a+4>>2]|0,19,0)|0;b=p;a=Qh(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=p;c[b>>2]=a;c[b+4>>2]=C;b=z;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;a=f;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=f;c[a>>2]=b;c[a+4>>2]=C;a=o;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;b=y;c[b>>2]=a;c[b+4>>2]=C;b=y;a=n;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=n;c[a>>2]=b;c[a+4>>2]=C;a=y;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;b=o;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=o;c[b>>2]=a;c[b+4>>2]=C;b=m;b=Qh(c[b>>2]|0,c[b+4>>2]|0,16777216,0)|0;b=Rh(b|0,C|0,25)|0;a=x;c[a>>2]=b;c[a+4>>2]=C;a=x;b=l;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=l;c[b>>2]=a;c[b+4>>2]=C;b=x;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;a=m;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=m;c[a>>2]=b;c[a+4>>2]=C;a=k;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;b=w;c[b>>2]=a;c[b+4>>2]=C;b=w;a=j;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=j;c[a>>2]=b;c[a+4>>2]=C;a=w;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;b=k;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=k;c[b>>2]=a;c[b+4>>2]=C;b=h;b=Qh(c[b>>2]|0,c[b+4>>2]|0,16777216,0)|0;b=Rh(b|0,C|0,25)|0;a=v;c[a>>2]=b;c[a+4>>2]=C;a=v;b=g;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=g;c[b>>2]=a;c[b+4>>2]=C;b=v;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;a=h;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=h;c[a>>2]=b;c[a+4>>2]=C;a=p;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=u;c[b>>2]=a;c[b+4>>2]=C;b=u;a=o;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=o;c[a>>2]=b;c[a+4>>2]=C;a=u;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=p;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=p;c[b>>2]=a;c[b+4>>2]=C;b=n;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=t;c[a>>2]=b;c[a+4>>2]=C;a=t;b=m;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=m;c[b>>2]=a;c[b+4>>2]=C;b=t;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=n;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=n;c[a>>2]=b;c[a+4>>2]=C;a=l;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=s;c[b>>2]=a;c[b+4>>2]=C;b=s;a=k;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=k;c[a>>2]=b;c[a+4>>2]=C;a=s;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=l;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=l;c[b>>2]=a;c[b+4>>2]=C;b=j;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=r;c[a>>2]=b;c[a+4>>2]=C;a=r;b=h;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=h;c[b>>2]=a;c[b+4>>2]=C;b=r;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=j;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=j;c[a>>2]=b;c[a+4>>2]=C;a=g;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=q;c[b>>2]=a;c[b+4>>2]=C;b=q;a=f;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=f;c[a>>2]=b;c[a+4>>2]=C;a=q;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=g;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=g;c[b>>2]=a;c[b+4>>2]=C;c[c[e>>2]>>2]=c[p>>2];c[(c[e>>2]|0)+4>>2]=c[o>>2];c[(c[e>>2]|0)+8>>2]=c[n>>2];c[(c[e>>2]|0)+12>>2]=c[m>>2];c[(c[e>>2]|0)+16>>2]=c[l>>2];c[(c[e>>2]|0)+20>>2]=c[k>>2];c[(c[e>>2]|0)+24>>2]=c[j>>2];c[(c[e>>2]|0)+28>>2]=c[h>>2];c[(c[e>>2]|0)+32>>2]=c[g>>2];c[(c[e>>2]|0)+36>>2]=c[f>>2];i=d;return}function Rf(a){a=a|0;var b=0,e=0,f=0,g=0,h=0,j=0;b=i;i=i+16|0;g=b+8|0;e=b;c[g>>2]=a;f=e;c[f>>2]=d[c[g>>2]>>0];c[f+4>>2]=0;f=Uh(d[(c[g>>2]|0)+1>>0]|0|0,0,8)|0;h=e;j=c[h+4>>2]|C;a=e;c[a>>2]=c[h>>2]|f;c[a+4>>2]=j;a=Uh(d[(c[g>>2]|0)+2>>0]|0|0,0,16)|0;j=e;f=c[j+4>>2]|C;h=e;c[h>>2]=c[j>>2]|a;c[h+4>>2]=f;g=Uh(d[(c[g>>2]|0)+3>>0]|0|0,0,24)|0;h=e;f=c[h+4>>2]|C;a=e;c[a>>2]=c[h>>2]|g;c[a+4>>2]=f;a=e;C=c[a+4>>2]|0;i=b;return c[a>>2]|0}function Sf(a){a=a|0;var b=0,e=0,f=0,g=0,h=0,j=0;b=i;i=i+16|0;g=b+8|0;e=b;c[g>>2]=a;a=e;c[a>>2]=d[c[g>>2]>>0];c[a+4>>2]=0;a=Uh(d[(c[g>>2]|0)+1>>0]|0|0,0,8)|0;j=e;f=c[j+4>>2]|C;h=e;c[h>>2]=c[j>>2]|a;c[h+4>>2]=f;g=Uh(d[(c[g>>2]|0)+2>>0]|0|0,0,16)|0;h=e;f=c[h+4>>2]|C;a=e;c[a>>2]=c[h>>2]|g;c[a+4>>2]=f;a=e;C=c[a+4>>2]|0;i=b;return c[a>>2]|0}function Tf(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;l=i;i=i+176|0;d=l+172|0;e=l+168|0;g=l+128|0;h=l+88|0;j=l+48|0;k=l+8|0;f=l;c[d>>2]=a;c[e>>2]=b;Uf(g,c[e>>2]|0);c[f>>2]=1;while(1){if((c[f>>2]|0)>=1)break;Uf(g,g);c[f>>2]=(c[f>>2]|0)+1}Uf(h,g);c[f>>2]=1;while(1){if((c[f>>2]|0)>=2)break;Uf(h,h);c[f>>2]=(c[f>>2]|0)+1}Vf(h,c[e>>2]|0,h);Vf(g,g,h);Uf(j,g);c[f>>2]=1;while(1){if((c[f>>2]|0)>=1)break;Uf(j,j);c[f>>2]=(c[f>>2]|0)+1}Vf(h,h,j);Uf(j,h);c[f>>2]=1;while(1){if((c[f>>2]|0)>=5)break;Uf(j,j);c[f>>2]=(c[f>>2]|0)+1}Vf(h,j,h);Uf(j,h);c[f>>2]=1;while(1){if((c[f>>2]|0)>=10)break;Uf(j,j);c[f>>2]=(c[f>>2]|0)+1}Vf(j,j,h);Uf(k,j);c[f>>2]=1;while(1){if((c[f>>2]|0)>=20)break;Uf(k,k);c[f>>2]=(c[f>>2]|0)+1}Vf(j,k,j);Uf(j,j);c[f>>2]=1;while(1){if((c[f>>2]|0)>=10)break;Uf(j,j);c[f>>2]=(c[f>>2]|0)+1}Vf(h,j,h);Uf(j,h);c[f>>2]=1;while(1){if((c[f>>2]|0)>=50)break;Uf(j,j);c[f>>2]=(c[f>>2]|0)+1}Vf(j,j,h);Uf(k,j);c[f>>2]=1;while(1){if((c[f>>2]|0)>=100)break;Uf(k,k);c[f>>2]=(c[f>>2]|0)+1}Vf(j,k,j);Uf(j,j);c[f>>2]=1;while(1){if((c[f>>2]|0)>=50)break;Uf(j,j);c[f>>2]=(c[f>>2]|0)+1}Vf(h,j,h);Uf(h,h);c[f>>2]=1;while(1){if((c[f>>2]|0)>=5)break;Uf(h,h);c[f>>2]=(c[f>>2]|0)+1}Vf(c[d>>2]|0,h,g);i=l;return}function Uf(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0;d=i;i=i+704|0;e=d+696|0;Za=d+692|0;Ya=d+688|0;Wa=d+684|0;Ta=d+680|0;Sa=d+676|0;Pa=d+672|0;Oa=d+668|0;Ja=d+664|0;Ia=d+660|0;Ea=d+656|0;Da=d+652|0;Xa=d+648|0;Va=d+644|0;Ua=d+640|0;Ra=d+636|0;Qa=d+632|0;Ma=d+628|0;Ka=d+624|0;Ga=d+620|0;Na=d+616|0;La=d+612|0;Ha=d+608|0;Fa=d+604|0;Ca=d+600|0;Ba=d+592|0;va=d+584|0;qa=d+576|0;ka=d+568|0;fa=d+560|0;$=d+552|0;W=d+544|0;Q=d+536|0;L=d+528|0;F=d+520|0;pa=d+512|0;ja=d+504|0;ea=d+496|0;_=d+488|0;V=d+480|0;P=d+472|0;K=d+464|0;E=d+456|0;Aa=d+448|0;da=d+440|0;Z=d+432|0;U=d+424|0;O=d+416|0;J=d+408|0;D=d+400|0;za=d+392|0;ua=d+384|0;T=d+376|0;N=d+368|0;I=d+360|0;B=d+352|0;ya=d+344|0;ta=d+336|0;oa=d+328|0;H=d+320|0;A=d+312|0;xa=d+304|0;sa=d+296|0;na=d+288|0;ia=d+280|0;wa=d+272|0;ra=d+264|0;ma=d+256|0;ha=d+248|0;ca=d+240|0;la=d+232|0;ga=d+224|0;ba=d+216|0;Y=d+208|0;aa=d+200|0;X=d+192|0;S=d+184|0;R=d+176|0;M=d+168|0;G=d+160|0;p=d+152|0;o=d+144|0;n=d+136|0;m=d+128|0;l=d+120|0;k=d+112|0;j=d+104|0;h=d+96|0;g=d+88|0;f=d+80|0;q=d+72|0;z=d+64|0;x=d+56|0;v=d+48|0;t=d+40|0;y=d+32|0;w=d+24|0;u=d+16|0;s=d+8|0;r=d;c[e>>2]=a;c[Za>>2]=b;c[Ya>>2]=c[c[Za>>2]>>2];c[Wa>>2]=c[(c[Za>>2]|0)+4>>2];c[Ta>>2]=c[(c[Za>>2]|0)+8>>2];c[Sa>>2]=c[(c[Za>>2]|0)+12>>2];c[Pa>>2]=c[(c[Za>>2]|0)+16>>2];c[Oa>>2]=c[(c[Za>>2]|0)+20>>2];c[Ja>>2]=c[(c[Za>>2]|0)+24>>2];c[Ia>>2]=c[(c[Za>>2]|0)+28>>2];c[Ea>>2]=c[(c[Za>>2]|0)+32>>2];c[Da>>2]=c[(c[Za>>2]|0)+36>>2];c[Xa>>2]=c[Ya>>2]<<1;c[Va>>2]=c[Wa>>2]<<1;c[Ua>>2]=c[Ta>>2]<<1;c[Ra>>2]=c[Sa>>2]<<1;c[Qa>>2]=c[Pa>>2]<<1;c[Ma>>2]=c[Oa>>2]<<1;c[Ka>>2]=c[Ja>>2]<<1;c[Ga>>2]=c[Ia>>2]<<1;c[Na>>2]=(c[Oa>>2]|0)*38;c[La>>2]=(c[Ja>>2]|0)*19;c[Ha>>2]=(c[Ia>>2]|0)*38;c[Fa>>2]=(c[Ea>>2]|0)*19;c[Ca>>2]=(c[Da>>2]|0)*38;b=c[Ya>>2]|0;a=c[Ya>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Ba;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Wa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=va;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Ta>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=qa;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Sa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ka;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=fa;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Oa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=$;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Ja>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=W;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Ia>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Q;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Ea>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=L;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Da>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=F;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Wa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=pa;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ta>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ja;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ra>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ea;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=_;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ma>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=V;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ja>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=P;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ga>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=K;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ea>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=E;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Aa;c[b>>2]=a;c[b+4>>2]=C;b=c[Ta>>2]|0;a=c[Ta>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=da;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Sa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Z;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=U;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Oa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=O;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Ja>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=J;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Ia>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=D;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=za;c[b>>2]=a;c[b+4>>2]=C;b=c[Ta>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ua;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Sa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=T;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=N;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Ma>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=I;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Ja>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=B;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ya;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ta;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=oa;c[b>>2]=a;c[b+4>>2]=C;b=c[Pa>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=H;c[b>>2]=a;c[b+4>>2]=C;b=c[Qa>>2]|0;a=c[Oa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=A;c[b>>2]=a;c[b+4>>2]=C;b=c[Qa>>2]|0;a=c[La>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=xa;c[b>>2]=a;c[b+4>>2]=C;b=c[Pa>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=sa;c[b>>2]=a;c[b+4>>2]=C;b=c[Qa>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=na;c[b>>2]=a;c[b+4>>2]=C;b=c[Pa>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ia;c[b>>2]=a;c[b+4>>2]=C;b=c[Oa>>2]|0;a=c[Na>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=wa;c[b>>2]=a;c[b+4>>2]=C;b=c[Ma>>2]|0;a=c[La>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ra;c[b>>2]=a;c[b+4>>2]=C;b=c[Ma>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ma;c[b>>2]=a;c[b+4>>2]=C;b=c[Ma>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ha;c[b>>2]=a;c[b+4>>2]=C;b=c[Ma>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ca;c[b>>2]=a;c[b+4>>2]=C;b=c[Ja>>2]|0;a=c[La>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=la;c[b>>2]=a;c[b+4>>2]=C;b=c[Ja>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ga;c[b>>2]=a;c[b+4>>2]=C;b=c[Ka>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ba;c[b>>2]=a;c[b+4>>2]=C;b=c[Ja>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Y;c[b>>2]=a;c[b+4>>2]=C;b=c[Ia>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=aa;c[b>>2]=a;c[b+4>>2]=C;b=c[Ga>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=X;c[b>>2]=a;c[b+4>>2]=C;b=c[Ga>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=S;c[b>>2]=a;c[b+4>>2]=C;b=c[Ea>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=R;c[b>>2]=a;c[b+4>>2]=C;b=c[Ea>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=M;c[b>>2]=a;c[b+4>>2]=C;b=c[Da>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=G;c[b>>2]=a;c[b+4>>2]=C;b=Ba;a=Aa;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=za;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ya;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=xa;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=wa;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=p;c[b>>2]=a;c[b+4>>2]=C;b=va;a=ua;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=ta;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=sa;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=ra;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=o;c[a>>2]=b;c[a+4>>2]=C;a=qa;b=pa;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=oa;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=na;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ma;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=la;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=n;c[a>>2]=b;c[a+4>>2]=C;a=ka;b=ja;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ia;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=ha;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ga;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=m;c[b>>2]=a;c[b+4>>2]=C;b=fa;a=ea;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=da;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ca;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=ba;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=aa;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=l;c[b>>2]=a;c[b+4>>2]=C;b=$;a=_;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=Z;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=Y;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=X;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=k;c[a>>2]=b;c[a+4>>2]=C;a=W;b=V;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=U;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=T;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=S;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=R;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=j;c[a>>2]=b;c[a+4>>2]=C;a=Q;b=P;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=O;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=N;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=M;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=h;c[b>>2]=a;c[b+4>>2]=C;b=L;a=K;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=J;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=I;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=H;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=G;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=g;c[b>>2]=a;c[b+4>>2]=C;b=F;a=E;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=D;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=B;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=A;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=f;c[a>>2]=b;c[a+4>>2]=C;a=p;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=q;c[b>>2]=a;c[b+4>>2]=C;b=q;a=o;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=o;c[a>>2]=b;c[a+4>>2]=C;a=q;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=p;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=p;c[b>>2]=a;c[b+4>>2]=C;b=l;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=t;c[a>>2]=b;c[a+4>>2]=C;a=t;b=k;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=k;c[b>>2]=a;c[b+4>>2]=C;b=t;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=l;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=l;c[a>>2]=b;c[a+4>>2]=C;a=o;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;b=z;c[b>>2]=a;c[b+4>>2]=C;b=z;a=n;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=n;c[a>>2]=b;c[a+4>>2]=C;a=z;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;b=o;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=o;c[b>>2]=a;c[b+4>>2]=C;b=k;b=Qh(c[b>>2]|0,c[b+4>>2]|0,16777216,0)|0;b=Rh(b|0,C|0,25)|0;a=y;c[a>>2]=b;c[a+4>>2]=C;a=y;b=j;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=j;c[b>>2]=a;c[b+4>>2]=C;b=y;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;a=k;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=k;c[a>>2]=b;c[a+4>>2]=C;a=n;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=x;c[b>>2]=a;c[b+4>>2]=C;b=x;a=m;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=m;c[a>>2]=b;c[a+4>>2]=C;a=x;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=n;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=n;c[b>>2]=a;c[b+4>>2]=C;b=j;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=w;c[a>>2]=b;c[a+4>>2]=C;a=w;b=h;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=h;c[b>>2]=a;c[b+4>>2]=C;b=w;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=j;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=j;c[a>>2]=b;c[a+4>>2]=C;a=m;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;b=v;c[b>>2]=a;c[b+4>>2]=C;b=v;a=l;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=l;c[a>>2]=b;c[a+4>>2]=C;a=v;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;b=m;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=m;c[b>>2]=a;c[b+4>>2]=C;b=h;b=Qh(c[b>>2]|0,c[b+4>>2]|0,16777216,0)|0;b=Rh(b|0,C|0,25)|0;a=u;c[a>>2]=b;c[a+4>>2]=C;a=u;b=g;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=g;c[b>>2]=a;c[b+4>>2]=C;b=u;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;a=h;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=h;c[a>>2]=b;c[a+4>>2]=C;a=l;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=t;c[b>>2]=a;c[b+4>>2]=C;b=t;a=k;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=k;c[a>>2]=b;c[a+4>>2]=C;a=t;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=l;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=l;c[b>>2]=a;c[b+4>>2]=C;b=g;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=s;c[a>>2]=b;c[a+4>>2]=C;a=s;b=f;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=f;c[b>>2]=a;c[b+4>>2]=C;b=s;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=g;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=g;c[a>>2]=b;c[a+4>>2]=C;a=f;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;b=r;c[b>>2]=a;c[b+4>>2]=C;b=r;b=_h(c[b>>2]|0,c[b+4>>2]|0,19,0)|0;a=p;b=Qh(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=p;c[a>>2]=b;c[a+4>>2]=C;a=r;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;b=f;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=f;c[b>>2]=a;c[b+4>>2]=C;b=p;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=q;c[a>>2]=b;c[a+4>>2]=C;a=q;b=o;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=o;c[b>>2]=a;c[b+4>>2]=C;b=q;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=p;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=p;c[a>>2]=b;c[a+4>>2]=C;c[c[e>>2]>>2]=c[p>>2];c[(c[e>>2]|0)+4>>2]=c[o>>2];c[(c[e>>2]|0)+8>>2]=c[n>>2];c[(c[e>>2]|0)+12>>2]=c[m>>2];c[(c[e>>2]|0)+16>>2]=c[l>>2];c[(c[e>>2]|0)+20>>2]=c[k>>2];c[(c[e>>2]|0)+24>>2]=c[j>>2];c[(c[e>>2]|0)+28>>2]=c[h>>2];c[(c[e>>2]|0)+32>>2]=c[g>>2];c[(c[e>>2]|0)+36>>2]=c[f>>2];i=d;return} +function _g(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=i;i=i+32|0;g=o+28|0;h=o+24|0;j=o+20|0;k=o+16|0;l=o+12|0;p=o+8|0;n=o+4|0;m=o;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[p>>2]=f;c[n>>2]=Zg(c[h>>2]|0)|0;a=c[p>>2]|0;if(a>>>0<(Pg(c[n>>2]|0)|0)>>>0){c[(c[h>>2]|0)+264>>2]=2;c[g>>2]=-1;p=c[g>>2]|0;i=o;return p|0}else{c[m>>2]=Qg(c[l>>2]|0,c[n>>2]|0)|0;c[m>>2]=_a(c[m>>2]|0,1)|0;c[m>>2]=Jg(c[h>>2]|0,c[m>>2]|0)|0;c[m>>2]=Jg((c[h>>2]|0)+132|0,c[m>>2]|0)|0;c[g>>2]=Rg(c[j>>2]|0,c[k>>2]|0,c[l>>2]|0,c[n>>2]|0)|0;p=c[g>>2]|0;i=o;return p|0}return 0}function $g(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;p=i;i=i+48|0;j=p+36|0;k=p+32|0;r=p+28|0;q=p+24|0;g=p+20|0;l=p+16|0;o=p+12|0;m=p+8|0;n=p+4|0;h=p;c[k>>2]=a;c[r>>2]=b;c[q>>2]=d;c[g>>2]=e;c[l>>2]=f;c[h>>2]=Sg(c[r>>2]|0,c[q>>2]|0,c[g>>2]|0,c[l>>2]|0,(c[k>>2]|0)+264|0)|0;if((c[h>>2]|0)==-1){c[j>>2]=c[h>>2];r=c[j>>2]|0;i=p;return r|0}c[o>>2]=c[g>>2];c[m>>2]=(c[o>>2]|0)+(c[h>>2]|0);c[o>>2]=$a(c[o>>2]|0,c[m>>2]|0,n)|0;g=c[k>>2]|0;if((c[n>>2]|0)!=1){c[g+264>>2]=9;c[j>>2]=-1;r=c[j>>2]|0;i=p;return r|0}c[o>>2]=Kg(g,c[o>>2]|0,c[m>>2]|0)|0;c[o>>2]=Kg((c[k>>2]|0)+132|0,c[o>>2]|0,c[m>>2]|0)|0;if((c[m>>2]|0)!=(c[o>>2]|0)){c[(c[k>>2]|0)+264>>2]=10;c[j>>2]=-1;r=c[j>>2]|0;i=p;return r|0}else{c[j>>2]=c[l>>2];r=c[j>>2]|0;i=p;return r|0}return 0}function ah(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;h=i;i=i+32|0;e=h+16|0;j=h+12|0;f=h+8|0;k=h+4|0;g=h;c[j>>2]=a;c[f>>2]=b;c[k>>2]=d;c[g>>2]=Ka(c[f>>2]|0,c[k>>2]|0,c[f>>2]|0)|0;b=c[j>>2]|0;if((c[g>>2]|0)==-1){c[b+264>>2]=7;c[e>>2]=-1;k=c[e>>2]|0;i=h;return k|0}else{c[e>>2]=bh(b,c[f>>2]|0,c[g>>2]|0)|0;k=c[e>>2]|0;i=h;return k|0}return 0}function bh(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;j=i;i=i+48|0;f=j+32|0;g=j+28|0;l=j+24|0;k=j+20|0;h=j;c[g>>2]=a;c[l>>2]=b;c[k>>2]=e;e=c[l>>2]|0;a=c[k>>2]|0;ub(e,a,ra[c[c[c[8126]>>2]>>2]&1](c[8126]|0)|0,h);if((d[h>>0]|0|0)!=3){c[(c[g>>2]|0)+264>>2]=3;c[f>>2]=-1;l=c[f>>2]|0;i=j;return l|0}if(c[h+12>>2]|0){c[f>>2]=ta[c[(c[c[8126]>>2]|0)+12>>2]&3](c[8126]|0,c[h+16>>2]|0)|0;l=c[f>>2]|0;i=j;return l|0}else{c[(c[g>>2]|0)+264>>2]=4;c[f>>2]=-1;l=c[f>>2]|0;i=j;return l|0}return 0}function ch(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;m=i;i=i+32|0;g=m+24|0;n=m+20|0;h=m+16|0;o=m+12|0;j=m+8|0;k=m+4|0;l=m;c[n>>2]=a;c[h>>2]=b;c[o>>2]=d;c[j>>2]=e;c[k>>2]=f;c[l>>2]=Ka(c[h>>2]|0,c[o>>2]|0,c[h>>2]|0)|0;f=c[n>>2]|0;if((c[l>>2]|0)==-1){c[f+264>>2]=7;c[g>>2]=-1;o=c[g>>2]|0;i=m;return o|0}else{c[g>>2]=dh(f,c[h>>2]|0,c[l>>2]|0,c[j>>2]|0,c[k>>2]|0)|0;o=c[g>>2]|0;i=m;return o|0}return 0}function dh(a,b,e,f,g){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=i;i=i+192|0;j=t+184|0;k=t+180|0;l=t+176|0;m=t+172|0;n=t+168|0;o=t+164|0;p=t+144|0;h=t+140|0;r=t+136|0;q=t+132|0;s=t;c[k>>2]=a;c[l>>2]=b;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;f=c[l>>2]|0;a=c[m>>2]|0;ub(f,a,ra[c[c[c[8126]>>2]>>2]&1](c[8126]|0)|0,p);if((d[p>>0]|0|0)!=3){c[(c[k>>2]|0)+264>>2]=3;c[j>>2]=-1;s=c[j>>2]|0;i=t;return s|0}if(c[p+8>>2]|0?c[p+12>>2]|0:0){c[h>>2]=ta[c[(c[c[8126]>>2]|0)+12>>2]&3](c[8126]|0,c[p+16>>2]|0)|0;if((c[o>>2]|0)>>>0<(c[h>>2]|0)>>>0){c[(c[k>>2]|0)+264>>2]=2;c[j>>2]=-1;s=c[j>>2]|0;i=t;return s|0}do if(((c[p+4>>2]|0)-(c[(c[k>>2]|0)+132+128>>2]|0)|0)>>>0<2147483648)c[q>>2]=(c[k>>2]|0)+132;else{h=c[k>>2]|0;if(((c[p+4>>2]|0)-(c[(c[k>>2]|0)+128>>2]|0)|0)>>>0<2147483648){Vh(s|0,h|0,132)|0;c[q>>2]=s;break}c[h+264>>2]=12;c[j>>2]=-1;s=c[j>>2]|0;i=t;return s|0}while(0);Ng(c[q>>2]|0,c[p+4>>2]|0);c[r>>2]=sa[c[(c[c[8126]>>2]|0)+16>>2]&3](c[8126]|0,c[q>>2]|0,128,c[l>>2]|0,c[m>>2]|0,c[p+12>>2]|0,c[p+16>>2]|0,c[n>>2]|0,c[o>>2]|0)|0;If(s,132);if((c[r>>2]|0)==-1){c[(c[k>>2]|0)+264>>2]=5;c[j>>2]=c[r>>2];s=c[j>>2]|0;i=t;return s|0}else{c[j>>2]=c[r>>2];s=c[j>>2]|0;i=t;return s|0}}c[(c[k>>2]|0)+264>>2]=4;c[j>>2]=-1;s=c[j>>2]|0;i=t;return s|0}function eh(){return 148}function fh(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=c[e>>2];gh(c[b>>2]|0)|0;i=d;return c[b>>2]|0}function gh(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;If(c[d>>2]|0,148);i=b;return 148}function hh(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Og(c[(c[d>>2]|0)+144>>2]|0)|0;i=b;return a|0}function ih(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Pg(jh(c[d>>2]|0)|0)|0;i=b;return a|0}function jh(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;c[b>>2]=(c[b>>2]|0)+4;a=Ig(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;c[b>>2]=(c[b>>2]|0)+12;i=d;return c[b>>2]|0}function kh(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=i;i=i+32|0;g=o+28|0;h=o+24|0;j=o+20|0;k=o+16|0;l=o+12|0;p=o+8|0;n=o+4|0;m=o;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[p>>2]=f;c[n>>2]=jh(c[h>>2]|0)|0;a=c[p>>2]|0;if(a>>>0<(Pg(c[n>>2]|0)|0)>>>0){c[(c[h>>2]|0)+144>>2]=2;c[g>>2]=-1;p=c[g>>2]|0;i=o;return p|0}else{c[m>>2]=Qg(c[l>>2]|0,c[n>>2]|0)|0;c[m>>2]=_a(c[m>>2]|0,1)|0;c[m>>2]=Jg(c[h>>2]|0,c[m>>2]|0)|0;c[m>>2]=ab(c[m>>2]|0,(c[h>>2]|0)+132|0,12)|0;c[g>>2]=Rg(c[j>>2]|0,c[k>>2]|0,c[l>>2]|0,c[n>>2]|0)|0;p=c[g>>2]|0;i=o;return p|0}return 0}function lh(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;p=i;i=i+48|0;j=p+36|0;k=p+32|0;r=p+28|0;q=p+24|0;g=p+20|0;l=p+16|0;o=p+12|0;m=p+8|0;n=p+4|0;h=p;c[k>>2]=a;c[r>>2]=b;c[q>>2]=d;c[g>>2]=e;c[l>>2]=f;c[h>>2]=Sg(c[r>>2]|0,c[q>>2]|0,c[g>>2]|0,c[l>>2]|0,(c[k>>2]|0)+144|0)|0;if((c[h>>2]|0)==-1){c[j>>2]=c[h>>2];r=c[j>>2]|0;i=p;return r|0}c[o>>2]=c[g>>2];c[m>>2]=(c[o>>2]|0)+(c[h>>2]|0);c[o>>2]=$a(c[o>>2]|0,c[m>>2]|0,n)|0;g=c[k>>2]|0;if((c[n>>2]|0)!=1){c[g+144>>2]=9;c[j>>2]=-1;r=c[j>>2]|0;i=p;return r|0}c[o>>2]=Kg(g,c[o>>2]|0,c[m>>2]|0)|0;c[o>>2]=bb(c[o>>2]|0,c[m>>2]|0,(c[k>>2]|0)+132|0,12)|0;if((c[m>>2]|0)!=(c[o>>2]|0)){c[(c[k>>2]|0)+144>>2]=10;c[j>>2]=-1;r=c[j>>2]|0;i=p;return r|0}else{c[j>>2]=c[l>>2];r=c[j>>2]|0;i=p;return r|0}return 0}function mh(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;i=b;return 132}function nh(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;j=i;i=i+16|0;f=j+12|0;g=j+8|0;h=j+4|0;k=j;c[g>>2]=b;c[h>>2]=d;c[k>>2]=e;b=c[k>>2]|0;b=b>>>0<(mh(c[g>>2]|0)|0)>>>0;d=c[g>>2]|0;if(b){c[d+144>>2]=1;c[f>>2]=-1;k=c[f>>2]|0;i=j;return k|0}else{Hg(d,c[h>>2]|0,0);c[h>>2]=(c[h>>2]|0)+128;ma((c[g>>2]|0)+132|0,0)|0;k=(c[g>>2]|0)+132+8|0;h=c[h>>2]|0;a[k>>0]=a[h>>0]|0;a[k+1>>0]=a[h+1>>0]|0;a[k+2>>0]=a[h+2>>0]|0;a[k+3>>0]=a[h+3>>0]|0;c[f>>2]=0;k=c[f>>2]|0;i=j;return k|0}return 0}function oh(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;g=d+8|0;f=d+4|0;e=d;c[g>>2]=a;c[f>>2]=b;c[e>>2]=ph(c[g>>2]|0,c[f>>2]|0)|0;a=Ha(c[e>>2]|0)|0;i=d;return a|0}function ph(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;g=d+12|0;h=d+8|0;f=d+4|0;e=d;c[g>>2]=a;c[h>>2]=b;c[f>>2]=ta[c[(c[c[8126]>>2]|0)+4>>2]&3](c[8126]|0,c[h>>2]|0)|0;c[e>>2]=ra[c[c[c[8126]>>2]>>2]&1](c[8126]|0)|0;a=sb(c[(c[g>>2]|0)+128>>2]|0,c[f>>2]|0,c[e>>2]|0)|0;i=d;return a|0}function qh(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;p=i;i=i+48|0;g=p+32|0;h=p+28|0;j=p+24|0;k=p+20|0;l=p+16|0;q=p+12|0;n=p+8|0;o=p+4|0;m=p;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[q>>2]=f;c[n>>2]=ph(c[h>>2]|0,c[k>>2]|0)|0;a=c[q>>2]|0;if(a>>>0<(Ha(c[n>>2]|0)|0)>>>0){c[(c[h>>2]|0)+144>>2]=2;c[g>>2]=-1;q=c[g>>2]|0;i=p;return q|0}q=c[l>>2]|0;q=q+(Ha(c[n>>2]|0)|0)|0;c[m>>2]=q+(0-(c[n>>2]|0));c[o>>2]=rh(c[h>>2]|0,c[j>>2]|0,c[k>>2]|0,c[m>>2]|0)|0;if((c[o>>2]|0)==-1){c[g>>2]=c[o>>2];q=c[g>>2]|0;i=p;return q|0}else{c[g>>2]=Ia(c[m>>2]|0,c[n>>2]|0,c[l>>2]|0)|0;q=c[g>>2]|0;i=p;return q|0}return 0}function rh(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=i;i=i+48|0;f=j+36|0;g=j+32|0;p=j+28|0;o=j+24|0;l=j+20|0;m=j+16|0;q=j+12|0;k=j+8|0;h=j+4|0;n=j;c[g>>2]=a;c[p>>2]=b;c[o>>2]=d;c[l>>2]=e;c[m>>2]=ta[c[(c[c[8126]>>2]|0)+4>>2]&3](c[8126]|0,c[o>>2]|0)|0;c[q>>2]=ra[c[c[c[8126]>>2]>>2]&1](c[8126]|0)|0;c[k>>2]=tb(3,c[(c[g>>2]|0)+128>>2]|0,c[m>>2]|0,c[l>>2]|0,n)|0;c[k>>2]=(c[k>>2]|0)+(c[q>>2]|0);c[h>>2]=sa[c[(c[c[8126]>>2]|0)+8>>2]&3](c[8126]|0,c[g>>2]|0,128,c[p>>2]|0,c[o>>2]|0,c[n>>2]|0,c[m>>2]|0,c[l>>2]|0,c[k>>2]|0)|0;if((c[h>>2]|0)==-1){c[f>>2]=c[h>>2];q=c[f>>2]|0;i=j;return q|0}else{Lg(c[g>>2]|0);c[f>>2]=c[h>>2];q=c[f>>2]|0;i=j;return q|0}return 0}function sh(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;a=Ha(12)|0;i=b;return a|0}function th(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;g=i;i=i+16|0;e=g+12|0;h=g+8|0;f=g+4|0;j=g;c[h>>2]=a;c[f>>2]=b;c[j>>2]=d;a=c[j>>2]|0;a=a>>>0<(sh(c[h>>2]|0)|0)>>>0;b=c[h>>2]|0;if(a){c[b+144>>2]=2;c[e>>2]=-1;j=c[e>>2]|0;i=g;return j|0}else{c[e>>2]=Ia(b+132|0,12,c[f>>2]|0)|0;j=c[e>>2]|0;i=g;return j|0}return 0}function uh(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[b>>2]=a;i=d;return c[(c[b>>2]|0)+128>>2]|0}function vh(a){a=a|0;var b=0;b=i;i=i+16|0;c[b>>2]=a;a=Ha(128)|0;i=b;return a|0}function wh(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;g=i;i=i+16|0;e=g+12|0;h=g+8|0;f=g+4|0;j=g;c[h>>2]=a;c[f>>2]=b;c[j>>2]=d;a=c[j>>2]|0;a=a>>>0<(vh(c[h>>2]|0)|0)>>>0;b=c[h>>2]|0;if(a){c[b+144>>2]=2;c[e>>2]=-1;j=c[e>>2]|0;i=g;return j|0}else{c[e>>2]=Ia(b,128,c[f>>2]|0)|0;j=c[e>>2]|0;i=g;return j|0}return 0}function xh(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;D=i;i=i+256|0;m=D;e=0;f=0;while(1){c[m+(e<<2)>>2]=(d[b+(f|1)>>0]|0)<<16|(d[b+f>>0]|0)<<24|(d[b+(f|2)>>0]|0)<<8|(d[b+(f|3)>>0]|0);e=e+1|0;if((e|0)==16)break;else f=f+4|0}b=c[m>>2]|0;e=16;do{C=c[m+(e+-2<<2)>>2]|0;B=b;b=c[m+(e+-15<<2)>>2]|0;c[m+(e<<2)>>2]=B+(c[m+(e+-7<<2)>>2]|0)+((C>>>19|C<<13)^C>>>10^(C>>>17|C<<15))+((b>>>18|b<<14)^b>>>3^(b>>>7|b<<25));e=e+1|0}while((e|0)!=64);p=a+80|0;q=c[p>>2]|0;r=a+84|0;s=c[r>>2]|0;t=a+88|0;u=c[t>>2]|0;v=a+92|0;w=c[v>>2]|0;x=a+96|0;y=c[x>>2]|0;z=a+100|0;A=c[z>>2]|0;B=a+104|0;C=c[B>>2]|0;n=a+108|0;o=c[n>>2]|0;l=q;j=s;h=u;f=w;a=y;e=A;b=C;g=o;k=0;while(1){g=((a>>>6|a<<26)^(a>>>11|a<<21)^(a>>>25|a<<7))+g+(b&~a^e&a)+(c[32584+(k<<2)>>2]|0)+(c[m+(k<<2)>>2]|0)|0;f=g+f|0;g=((l>>>2|l<<30)^(l>>>13|l<<19)^(l>>>22|l<<10))+(l&(j^h)^j&h)+g|0;k=k+1|0;if((k|0)==64){k=l;break}else{F=a;E=l;l=g;a=f;g=b;b=e;e=F;f=h;h=j;j=E}}c[p>>2]=q+g;c[r>>2]=s+k;c[t>>2]=u+j;c[v>>2]=w+h;c[x>>2]=y+f;c[z>>2]=A+a;c[B>>2]=C+e;c[n>>2]=o+b;i=D;return}function yh(a){a=a|0;var b=0;c[a+64>>2]=0;b=a+72|0;c[b>>2]=0;c[b+4>>2]=0;c[a+80>>2]=1779033703;c[a+84>>2]=-1150833019;c[a+88>>2]=1013904242;c[a+92>>2]=-1521486534;c[a+96>>2]=1359893119;c[a+100>>2]=-1694144372;c[a+104>>2]=528734635;c[a+108>>2]=1541459225;return}function zh(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if(!e)return;g=b+64|0;h=b+72|0;f=c[g>>2]|0;i=0;do{a[b+f>>0]=a[d+i>>0]|0;f=(c[g>>2]|0)+1|0;c[g>>2]=f;if((f|0)==64){xh(b,b);j=h;j=Qh(c[j>>2]|0,c[j+4>>2]|0,512,0)|0;f=h;c[f>>2]=j;c[f+4>>2]=C;c[g>>2]=0;f=0}i=i+1|0}while((i|0)!=(e|0));return}function Ah(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=b+64|0;e=c[g>>2]|0;f=e+1|0;a[b+e>>0]=-128;if(e>>>0<56){if(f>>>0<56)Sh(b+f|0,0,55-e|0)|0}else{if(f>>>0<64)Sh(b+f|0,0,63-e|0)|0;xh(b,b);e=b;f=e+56|0;do{c[e>>2]=0;e=e+4|0}while((e|0)<(f|0))}i=b+72|0;h=i;h=Qh(c[g>>2]<<3|0,0,c[h>>2]|0,c[h+4>>2]|0)|0;g=C;c[i>>2]=h;c[i+4>>2]=g;a[b+63>>0]=h;i=Th(h|0,g|0,8)|0;a[b+62>>0]=i;i=Th(h|0,g|0,16)|0;a[b+61>>0]=i;i=Th(h|0,g|0,24)|0;a[b+60>>0]=i;a[b+59>>0]=g;i=Th(h|0,g|0,40)|0;a[b+58>>0]=i;i=Th(h|0,g|0,48)|0;a[b+57>>0]=i;g=Th(h|0,g|0,56)|0;a[b+56>>0]=g;xh(b,b);g=b+80|0;h=b+84|0;i=b+88|0;j=b+92|0;k=b+96|0;l=b+100|0;m=b+104|0;e=b+108|0;f=0;do{b=24-(f<<3)|0;a[d+f>>0]=(c[g>>2]|0)>>>b;a[d+(f+4)>>0]=(c[h>>2]|0)>>>b;a[d+(f+8)>>0]=(c[i>>2]|0)>>>b;a[d+(f+12)>>0]=(c[j>>2]|0)>>>b;a[d+(f+16)>>0]=(c[k>>2]|0)>>>b;a[d+(f+20)>>0]=(c[l>>2]|0)>>>b;a[d+(f+24)>>0]=(c[m>>2]|0)>>>b;a[d+(f+28)>>0]=(c[e>>2]|0)>>>b;f=f+1|0}while((f|0)!=4);return}function Bh(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;L=i;i=i+16|0;K=L;B=K+4|0;I=K+8|0;O=a[b+3>>0]|0;J=K+12|0;q=a[b+4>>0]|0;v=K+1|0;o=a[b+5>>0]|0;w=K+5|0;N=a[b+6>>0]|0;x=K+9|0;M=a[b+7>>0]|0;y=K+13|0;u=a[b+8>>0]|0;z=K+2|0;h=a[b+9>>0]|0;A=K+6|0;r=a[b+10>>0]|0;C=K+10|0;t=a[b+11>>0]|0;D=K+14|0;k=a[b+12>>0]|0;E=K+3|0;s=a[b+13>>0]|0;F=K+7|0;p=a[b+14>>0]|0;G=K+11|0;n=a[b+15>>0]|0;H=K+15|0;l=c[f>>2]|0;m=(d[b>>0]|0)^l>>>24;j=(d[b+1>>0]|0)^l>>>16;a[I>>0]=(d[b+2>>0]|0)^l>>>8;a[J>>0]=O&255^l;l=c[f+4>>2]|0;q=q&255^l>>>24;o=o&255^l>>>16;a[x>>0]=N&255^l>>>8;a[y>>0]=M&255^l;l=c[f+8>>2]|0;u=u&255^l>>>24;h=h&255^l>>>16;r=r&255^l>>>8;a[D>>0]=t&255^l;l=c[f+12>>2]|0;k=k&255^l>>>24;b=s&255^l>>>16;p=p&255^l>>>8;l=n&255^l;a[K>>0]=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;a[v>>0]=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;a[z>>0]=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;a[E>>0]=a[(k&15)+(33451+(k>>>4<<4))>>0]|0;j=a[(j&15)+(33451+((j>>>4&15)<<4))>>0]|0;h=a[(h&15)+(33451+((h>>>4&15)<<4))>>0]|0;b=a[(b&15)+(33451+((b>>>4&15)<<4))>>0]|0;k=d[I>>0]|0;k=a[(k&15)+(33451+(k>>>4<<4))>>0]|0;u=d[x>>0]|0;u=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;r=a[(r&15)+(33451+((r>>>4&15)<<4))>>0]|0;p=a[(p&15)+(33451+((p>>>4&15)<<4))>>0]|0;q=d[J>>0]|0;q=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;m=d[y>>0]|0;m=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;n=d[D>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;a[B>>0]=a[(o&15)+(33451+((o>>>4&15)<<4))>>0]|0;a[w>>0]=h;a[A>>0]=b;a[F>>0]=j;a[I>>0]=r;a[C>>0]=k;a[x>>0]=p;a[G>>0]=u;a[J>>0]=l;a[H>>0]=n;a[D>>0]=m;a[y>>0]=q;Ch(K);q=c[f+16>>2]|0;m=(d[K>>0]|0)^q>>>24;a[B>>0]=(d[B>>0]|0)^q>>>16;a[I>>0]=(d[I>>0]|0)^q>>>8;a[J>>0]=(d[J>>0]|0)^q;q=c[f+20>>2]|0;n=(d[v>>0]|0)^q>>>24;l=(d[w>>0]|0)^q>>>16;a[x>>0]=(d[x>>0]|0)^q>>>8;a[y>>0]=(d[y>>0]|0)^q;q=c[f+24>>2]|0;u=(d[z>>0]|0)^q>>>24;p=(d[A>>0]|0)^q>>>16;k=(d[C>>0]|0)^q>>>8;a[D>>0]=(d[D>>0]|0)^q;q=c[f+28>>2]|0;r=(d[E>>0]|0)^q>>>24;j=(d[F>>0]|0)^q>>>16;b=(d[G>>0]|0)^q>>>8;q=(d[H>>0]|0)^q;a[K>>0]=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;a[v>>0]=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;a[z>>0]=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;a[E>>0]=a[(r&15)+(33451+(r>>>4<<4))>>0]|0;r=d[B>>0]|0;r=a[(r&15)+(33451+(r>>>4<<4))>>0]|0;p=a[(p&15)+(33451+((p>>>4&15)<<4))>>0]|0;j=a[(j&15)+(33451+((j>>>4&15)<<4))>>0]|0;u=d[I>>0]|0;u=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;n=d[x>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;k=a[(k&15)+(33451+((k>>>4&15)<<4))>>0]|0;b=a[(b&15)+(33451+((b>>>4&15)<<4))>>0]|0;m=d[J>>0]|0;m=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;h=d[y>>0]|0;h=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;o=d[D>>0]|0;o=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;q=a[(q&15)+(33451+((q>>>4&15)<<4))>>0]|0;a[B>>0]=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;a[w>>0]=p;a[A>>0]=j;a[F>>0]=r;a[I>>0]=k;a[C>>0]=u;a[x>>0]=b;a[G>>0]=n;a[J>>0]=q;a[H>>0]=o;a[D>>0]=h;a[y>>0]=m;Ch(K);m=c[f+32>>2]|0;h=(d[K>>0]|0)^m>>>24;a[B>>0]=(d[B>>0]|0)^m>>>16;a[I>>0]=(d[I>>0]|0)^m>>>8;a[J>>0]=(d[J>>0]|0)^m;m=c[f+36>>2]|0;o=(d[v>>0]|0)^m>>>24;q=(d[w>>0]|0)^m>>>16;a[x>>0]=(d[x>>0]|0)^m>>>8;a[y>>0]=(d[y>>0]|0)^m;m=c[f+40>>2]|0;n=(d[z>>0]|0)^m>>>24;b=(d[A>>0]|0)^m>>>16;u=(d[C>>0]|0)^m>>>8;a[D>>0]=(d[D>>0]|0)^m;m=c[f+44>>2]|0;k=(d[E>>0]|0)^m>>>24;r=(d[F>>0]|0)^m>>>16;j=(d[G>>0]|0)^m>>>8;m=(d[H>>0]|0)^m;a[K>>0]=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;a[v>>0]=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;a[z>>0]=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;a[E>>0]=a[(k&15)+(33451+(k>>>4<<4))>>0]|0;k=d[B>>0]|0;k=a[(k&15)+(33451+(k>>>4<<4))>>0]|0;b=a[(b&15)+(33451+((b>>>4&15)<<4))>>0]|0;r=a[(r&15)+(33451+((r>>>4&15)<<4))>>0]|0;n=d[I>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;o=d[x>>0]|0;o=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;u=a[(u&15)+(33451+((u>>>4&15)<<4))>>0]|0;j=a[(j&15)+(33451+((j>>>4&15)<<4))>>0]|0;h=d[J>>0]|0;h=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;p=d[y>>0]|0;p=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;l=d[D>>0]|0;l=a[(l&15)+(33451+(l>>>4<<4))>>0]|0;m=a[(m&15)+(33451+((m>>>4&15)<<4))>>0]|0;a[B>>0]=a[(q&15)+(33451+((q>>>4&15)<<4))>>0]|0;a[w>>0]=b;a[A>>0]=r;a[F>>0]=k;a[I>>0]=u;a[C>>0]=n;a[x>>0]=j;a[G>>0]=o;a[J>>0]=m;a[H>>0]=l;a[D>>0]=p;a[y>>0]=h;Ch(K);h=c[f+48>>2]|0;p=(d[K>>0]|0)^h>>>24;a[B>>0]=(d[B>>0]|0)^h>>>16;a[I>>0]=(d[I>>0]|0)^h>>>8;a[J>>0]=(d[J>>0]|0)^h;h=c[f+52>>2]|0;l=(d[v>>0]|0)^h>>>24;m=(d[w>>0]|0)^h>>>16;a[x>>0]=(d[x>>0]|0)^h>>>8;a[y>>0]=(d[y>>0]|0)^h;h=c[f+56>>2]|0;o=(d[z>>0]|0)^h>>>24;j=(d[A>>0]|0)^h>>>16;n=(d[C>>0]|0)^h>>>8;a[D>>0]=(d[D>>0]|0)^h;h=c[f+60>>2]|0;u=(d[E>>0]|0)^h>>>24;k=(d[F>>0]|0)^h>>>16;r=(d[G>>0]|0)^h>>>8;h=(d[H>>0]|0)^h;a[K>>0]=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;a[v>>0]=a[(l&15)+(33451+(l>>>4<<4))>>0]|0;a[z>>0]=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;a[E>>0]=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;u=d[B>>0]|0;u=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;j=a[(j&15)+(33451+((j>>>4&15)<<4))>>0]|0;k=a[(k&15)+(33451+((k>>>4&15)<<4))>>0]|0;o=d[I>>0]|0;o=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;l=d[x>>0]|0;l=a[(l&15)+(33451+(l>>>4<<4))>>0]|0;n=a[(n&15)+(33451+((n>>>4&15)<<4))>>0]|0;r=a[(r&15)+(33451+((r>>>4&15)<<4))>>0]|0;p=d[J>>0]|0;p=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;b=d[y>>0]|0;b=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;q=d[D>>0]|0;q=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;h=a[(h&15)+(33451+((h>>>4&15)<<4))>>0]|0;a[B>>0]=a[(m&15)+(33451+((m>>>4&15)<<4))>>0]|0;a[w>>0]=j;a[A>>0]=k;a[F>>0]=u;a[I>>0]=n;a[C>>0]=o;a[x>>0]=r;a[G>>0]=l;a[J>>0]=h;a[H>>0]=q;a[D>>0]=b;a[y>>0]=p;Ch(K);p=c[f+64>>2]|0;b=(d[K>>0]|0)^p>>>24;a[B>>0]=(d[B>>0]|0)^p>>>16;a[I>>0]=(d[I>>0]|0)^p>>>8;a[J>>0]=(d[J>>0]|0)^p;p=c[f+68>>2]|0;q=(d[v>>0]|0)^p>>>24;h=(d[w>>0]|0)^p>>>16;a[x>>0]=(d[x>>0]|0)^p>>>8;a[y>>0]=(d[y>>0]|0)^p;p=c[f+72>>2]|0;l=(d[z>>0]|0)^p>>>24;r=(d[A>>0]|0)^p>>>16;o=(d[C>>0]|0)^p>>>8;a[D>>0]=(d[D>>0]|0)^p;p=c[f+76>>2]|0;n=(d[E>>0]|0)^p>>>24;u=(d[F>>0]|0)^p>>>16;k=(d[G>>0]|0)^p>>>8;p=(d[H>>0]|0)^p;a[K>>0]=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;a[v>>0]=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;a[z>>0]=a[(l&15)+(33451+(l>>>4<<4))>>0]|0;a[E>>0]=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;n=d[B>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;r=a[(r&15)+(33451+((r>>>4&15)<<4))>>0]|0;u=a[(u&15)+(33451+((u>>>4&15)<<4))>>0]|0;l=d[I>>0]|0;l=a[(l&15)+(33451+(l>>>4<<4))>>0]|0;q=d[x>>0]|0;q=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;o=a[(o&15)+(33451+((o>>>4&15)<<4))>>0]|0;k=a[(k&15)+(33451+((k>>>4&15)<<4))>>0]|0;b=d[J>>0]|0;b=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;j=d[y>>0]|0;j=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;m=d[D>>0]|0;m=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;p=a[(p&15)+(33451+((p>>>4&15)<<4))>>0]|0;a[B>>0]=a[(h&15)+(33451+((h>>>4&15)<<4))>>0]|0;a[w>>0]=r;a[A>>0]=u;a[F>>0]=n;a[I>>0]=o;a[C>>0]=l;a[x>>0]=k;a[G>>0]=q;a[J>>0]=p;a[H>>0]=m;a[D>>0]=j;a[y>>0]=b;Ch(K);b=c[f+80>>2]|0;j=(d[K>>0]|0)^b>>>24;a[B>>0]=(d[B>>0]|0)^b>>>16;a[I>>0]=(d[I>>0]|0)^b>>>8;a[J>>0]=(d[J>>0]|0)^b;b=c[f+84>>2]|0;m=(d[v>>0]|0)^b>>>24;p=(d[w>>0]|0)^b>>>16;a[x>>0]=(d[x>>0]|0)^b>>>8;a[y>>0]=(d[y>>0]|0)^b;b=c[f+88>>2]|0;q=(d[z>>0]|0)^b>>>24;k=(d[A>>0]|0)^b>>>16;l=(d[C>>0]|0)^b>>>8;a[D>>0]=(d[D>>0]|0)^b;b=c[f+92>>2]|0;o=(d[E>>0]|0)^b>>>24;n=(d[F>>0]|0)^b>>>16;u=(d[G>>0]|0)^b>>>8;b=(d[H>>0]|0)^b;a[K>>0]=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;a[v>>0]=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;a[z>>0]=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;a[E>>0]=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;o=d[B>>0]|0;o=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;k=a[(k&15)+(33451+((k>>>4&15)<<4))>>0]|0;n=a[(n&15)+(33451+((n>>>4&15)<<4))>>0]|0;q=d[I>>0]|0;q=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;m=d[x>>0]|0;m=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;u=a[(u&15)+(33451+((u>>>4&15)<<4))>>0]|0;j=d[J>>0]|0;j=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;r=d[y>>0]|0;r=a[(r&15)+(33451+(r>>>4<<4))>>0]|0;h=d[D>>0]|0;h=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;b=a[(b&15)+(33451+((b>>>4&15)<<4))>>0]|0;a[B>>0]=a[(p&15)+(33451+((p>>>4&15)<<4))>>0]|0;a[w>>0]=k;a[A>>0]=n;a[F>>0]=o;a[I>>0]=l;a[C>>0]=q;a[x>>0]=u;a[G>>0]=m;a[J>>0]=b;a[H>>0]=h;a[D>>0]=r;a[y>>0]=j;Ch(K);j=c[f+96>>2]|0;r=(d[K>>0]|0)^j>>>24;a[B>>0]=(d[B>>0]|0)^j>>>16;a[I>>0]=(d[I>>0]|0)^j>>>8;a[J>>0]=(d[J>>0]|0)^j;j=c[f+100>>2]|0;h=(d[v>>0]|0)^j>>>24;b=(d[w>>0]|0)^j>>>16;a[x>>0]=(d[x>>0]|0)^j>>>8;a[y>>0]=(d[y>>0]|0)^j;j=c[f+104>>2]|0;m=(d[z>>0]|0)^j>>>24;u=(d[A>>0]|0)^j>>>16;q=(d[C>>0]|0)^j>>>8;a[D>>0]=(d[D>>0]|0)^j;j=c[f+108>>2]|0;l=(d[E>>0]|0)^j>>>24;o=(d[F>>0]|0)^j>>>16;n=(d[G>>0]|0)^j>>>8;j=(d[H>>0]|0)^j;a[K>>0]=a[(r&15)+(33451+(r>>>4<<4))>>0]|0;a[v>>0]=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;a[z>>0]=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;a[E>>0]=a[(l&15)+(33451+(l>>>4<<4))>>0]|0;l=d[B>>0]|0;l=a[(l&15)+(33451+(l>>>4<<4))>>0]|0;u=a[(u&15)+(33451+((u>>>4&15)<<4))>>0]|0;o=a[(o&15)+(33451+((o>>>4&15)<<4))>>0]|0;m=d[I>>0]|0;m=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;h=d[x>>0]|0;h=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;q=a[(q&15)+(33451+((q>>>4&15)<<4))>>0]|0;n=a[(n&15)+(33451+((n>>>4&15)<<4))>>0]|0;r=d[J>>0]|0;r=a[(r&15)+(33451+(r>>>4<<4))>>0]|0;k=d[y>>0]|0;k=a[(k&15)+(33451+(k>>>4<<4))>>0]|0;p=d[D>>0]|0;p=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;j=a[(j&15)+(33451+((j>>>4&15)<<4))>>0]|0;a[B>>0]=a[(b&15)+(33451+((b>>>4&15)<<4))>>0]|0;a[w>>0]=u;a[A>>0]=o;a[F>>0]=l;a[I>>0]=q;a[C>>0]=m;a[x>>0]=n;a[G>>0]=h;a[J>>0]=j;a[H>>0]=p;a[D>>0]=k;a[y>>0]=r;Ch(K);r=c[f+112>>2]|0;k=(d[K>>0]|0)^r>>>24;a[B>>0]=(d[B>>0]|0)^r>>>16;a[I>>0]=(d[I>>0]|0)^r>>>8;a[J>>0]=(d[J>>0]|0)^r;r=c[f+116>>2]|0;p=(d[v>>0]|0)^r>>>24;j=(d[w>>0]|0)^r>>>16;a[x>>0]=(d[x>>0]|0)^r>>>8;a[y>>0]=(d[y>>0]|0)^r;r=c[f+120>>2]|0;h=(d[z>>0]|0)^r>>>24;n=(d[A>>0]|0)^r>>>16;m=(d[C>>0]|0)^r>>>8;a[D>>0]=(d[D>>0]|0)^r;r=c[f+124>>2]|0;q=(d[E>>0]|0)^r>>>24;l=(d[F>>0]|0)^r>>>16;o=(d[G>>0]|0)^r>>>8;r=(d[H>>0]|0)^r;a[K>>0]=a[(k&15)+(33451+(k>>>4<<4))>>0]|0;a[v>>0]=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;a[z>>0]=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;a[E>>0]=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;q=d[B>>0]|0;q=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;n=a[(n&15)+(33451+((n>>>4&15)<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;h=d[I>>0]|0;h=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;p=d[x>>0]|0;p=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;m=a[(m&15)+(33451+((m>>>4&15)<<4))>>0]|0;o=a[(o&15)+(33451+((o>>>4&15)<<4))>>0]|0;k=d[J>>0]|0;k=a[(k&15)+(33451+(k>>>4<<4))>>0]|0;u=d[y>>0]|0;u=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;b=d[D>>0]|0;b=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;r=a[(r&15)+(33451+((r>>>4&15)<<4))>>0]|0;a[B>>0]=a[(j&15)+(33451+((j>>>4&15)<<4))>>0]|0;a[w>>0]=n;a[A>>0]=l;a[F>>0]=q;a[I>>0]=m;a[C>>0]=h;a[x>>0]=o;a[G>>0]=p;a[J>>0]=r;a[H>>0]=b;a[D>>0]=u;a[y>>0]=k;Ch(K);k=c[f+128>>2]|0;u=(d[K>>0]|0)^k>>>24;a[B>>0]=(d[B>>0]|0)^k>>>16;a[I>>0]=(d[I>>0]|0)^k>>>8;a[J>>0]=(d[J>>0]|0)^k;k=c[f+132>>2]|0;b=(d[v>>0]|0)^k>>>24;r=(d[w>>0]|0)^k>>>16;a[x>>0]=(d[x>>0]|0)^k>>>8;a[y>>0]=(d[y>>0]|0)^k;k=c[f+136>>2]|0;p=(d[z>>0]|0)^k>>>24;o=(d[A>>0]|0)^k>>>16;h=(d[C>>0]|0)^k>>>8;a[D>>0]=(d[D>>0]|0)^k;k=c[f+140>>2]|0;m=(d[E>>0]|0)^k>>>24;q=(d[F>>0]|0)^k>>>16;l=(d[G>>0]|0)^k>>>8;k=(d[H>>0]|0)^k;a[K>>0]=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;a[v>>0]=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;a[z>>0]=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;a[E>>0]=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;m=d[B>>0]|0;m=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;o=a[(o&15)+(33451+((o>>>4&15)<<4))>>0]|0;q=a[(q&15)+(33451+((q>>>4&15)<<4))>>0]|0;p=d[I>>0]|0;p=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;b=d[x>>0]|0;b=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;h=a[(h&15)+(33451+((h>>>4&15)<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;u=d[J>>0]|0;u=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;n=d[y>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;j=d[D>>0]|0;j=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;k=a[(k&15)+(33451+((k>>>4&15)<<4))>>0]|0;a[B>>0]=a[(r&15)+(33451+((r>>>4&15)<<4))>>0]|0;a[w>>0]=o;a[A>>0]=q;a[F>>0]=m;a[I>>0]=h;a[C>>0]=p;a[x>>0]=l;a[G>>0]=b;a[J>>0]=k;a[H>>0]=j;a[D>>0]=n;a[y>>0]=u;Ch(K);u=c[f+144>>2]|0;n=(d[K>>0]|0)^u>>>24;a[B>>0]=(d[B>>0]|0)^u>>>16;a[I>>0]=(d[I>>0]|0)^u>>>8;a[J>>0]=(d[J>>0]|0)^u;u=c[f+148>>2]|0;j=(d[v>>0]|0)^u>>>24;k=(d[w>>0]|0)^u>>>16;a[x>>0]=(d[x>>0]|0)^u>>>8;a[y>>0]=(d[y>>0]|0)^u;u=c[f+152>>2]|0;b=(d[z>>0]|0)^u>>>24;l=(d[A>>0]|0)^u>>>16;p=(d[C>>0]|0)^u>>>8;a[D>>0]=(d[D>>0]|0)^u;u=c[f+156>>2]|0;h=(d[E>>0]|0)^u>>>24;m=(d[F>>0]|0)^u>>>16;q=(d[G>>0]|0)^u>>>8;u=(d[H>>0]|0)^u;a[K>>0]=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;a[v>>0]=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;b=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;a[z>>0]=b;h=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;a[E>>0]=h;j=d[B>>0]|0;j=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;k=a[(k&15)+(33451+((k>>>4&15)<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;m=a[(m&15)+(33451+((m>>>4&15)<<4))>>0]|0;n=d[I>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;o=d[x>>0]|0;o=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;p=a[(p&15)+(33451+((p>>>4&15)<<4))>>0]|0;q=a[(q&15)+(33451+((q>>>4&15)<<4))>>0]|0;r=d[J>>0]|0;r=a[(r&15)+(33451+(r>>>4<<4))>>0]|0;s=d[y>>0]|0;s=a[(s&15)+(33451+(s>>>4<<4))>>0]|0;t=d[D>>0]|0;t=a[(t&15)+(33451+(t>>>4<<4))>>0]|0;u=a[(u&15)+(33451+((u>>>4&15)<<4))>>0]|0;a[B>>0]=k;a[w>>0]=l;a[A>>0]=m;a[F>>0]=j;a[I>>0]=p;a[C>>0]=n;a[x>>0]=q;a[G>>0]=o;a[J>>0]=u;a[H>>0]=t;a[D>>0]=s;a[y>>0]=r;if((g|0)==128){N=c[f+160>>2]|0;O=((d[K>>0]|0)^N>>>24)&255;a[K>>0]=O;k=(k&255^N>>>16)&255;a[B>>0]=k;B=(p&255^N>>>8)&255;a[I>>0]=B;p=(u&255^N)&255;a[J>>0]=p;N=c[f+164>>2]|0;u=((d[v>>0]|0)^N>>>24)&255;a[v>>0]=u;v=(l&255^N>>>16)&255;a[w>>0]=v;w=(q&255^N>>>8)&255;a[x>>0]=w;x=(r&255^N)&255;a[y>>0]=x;N=c[f+168>>2]|0;y=(b&255^N>>>24)&255;a[z>>0]=y;I=(m&255^N>>>16)&255;a[A>>0]=I;J=(n&255^N>>>8)&255;a[C>>0]=J;z=(s&255^N)&255;a[D>>0]=z;N=c[f+172>>2]|0;g=(h&255^N>>>24)&255;a[E>>0]=g;K=(j&255^N>>>16)&255;a[F>>0]=K;M=(o&255^N>>>8)&255;a[G>>0]=M;N=(t&255^N)&255;a[H>>0]=N;A=k;C=p;D=u;E=v;F=w;G=x;H=y;f=z;a[e>>0]=O;O=e+1|0;a[O>>0]=A;O=e+2|0;a[O>>0]=B;O=e+3|0;a[O>>0]=C;O=e+4|0;a[O>>0]=D;O=e+5|0;a[O>>0]=E;O=e+6|0;a[O>>0]=F;O=e+7|0;a[O>>0]=G;O=e+8|0;a[O>>0]=H;O=e+9|0;a[O>>0]=I;O=e+10|0;a[O>>0]=J;O=e+11|0;a[O>>0]=f;O=e+12|0;a[O>>0]=g;O=e+13|0;a[O>>0]=K;O=e+14|0;a[O>>0]=M;O=e+15|0;a[O>>0]=N;i=L;return}Ch(K);k=c[f+160>>2]|0;u=(d[K>>0]|0)^k>>>24;a[B>>0]=(d[B>>0]|0)^k>>>16;a[I>>0]=(d[I>>0]|0)^k>>>8;a[J>>0]=(d[J>>0]|0)^k;k=c[f+164>>2]|0;b=(d[v>>0]|0)^k>>>24;r=(d[w>>0]|0)^k>>>16;a[x>>0]=(d[x>>0]|0)^k>>>8;a[y>>0]=(d[y>>0]|0)^k;k=c[f+168>>2]|0;p=(d[z>>0]|0)^k>>>24;o=(d[A>>0]|0)^k>>>16;h=(d[C>>0]|0)^k>>>8;a[D>>0]=(d[D>>0]|0)^k;k=c[f+172>>2]|0;m=(d[E>>0]|0)^k>>>24;q=(d[F>>0]|0)^k>>>16;l=(d[G>>0]|0)^k>>>8;k=(d[H>>0]|0)^k;a[K>>0]=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;a[v>>0]=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;a[z>>0]=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;a[E>>0]=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;m=d[B>>0]|0;m=a[(m&15)+(33451+(m>>>4<<4))>>0]|0;o=a[(o&15)+(33451+((o>>>4&15)<<4))>>0]|0;q=a[(q&15)+(33451+((q>>>4&15)<<4))>>0]|0;p=d[I>>0]|0;p=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;b=d[x>>0]|0;b=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;h=a[(h&15)+(33451+((h>>>4&15)<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;u=d[J>>0]|0;u=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;n=d[y>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;j=d[D>>0]|0;j=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;k=a[(k&15)+(33451+((k>>>4&15)<<4))>>0]|0;a[B>>0]=a[(r&15)+(33451+((r>>>4&15)<<4))>>0]|0;a[w>>0]=o;a[A>>0]=q;a[F>>0]=m;a[I>>0]=h;a[C>>0]=p;a[x>>0]=l;a[G>>0]=b;a[J>>0]=k;a[H>>0]=j;a[D>>0]=n;a[y>>0]=u;Ch(K);u=c[f+176>>2]|0;n=(d[K>>0]|0)^u>>>24;a[B>>0]=(d[B>>0]|0)^u>>>16;a[I>>0]=(d[I>>0]|0)^u>>>8;a[J>>0]=(d[J>>0]|0)^u;u=c[f+180>>2]|0;j=(d[v>>0]|0)^u>>>24;k=(d[w>>0]|0)^u>>>16;a[x>>0]=(d[x>>0]|0)^u>>>8;a[y>>0]=(d[y>>0]|0)^u;u=c[f+184>>2]|0;b=(d[z>>0]|0)^u>>>24;l=(d[A>>0]|0)^u>>>16;p=(d[C>>0]|0)^u>>>8;a[D>>0]=(d[D>>0]|0)^u;u=c[f+188>>2]|0;h=(d[E>>0]|0)^u>>>24;m=(d[F>>0]|0)^u>>>16;q=(d[G>>0]|0)^u>>>8;u=(d[H>>0]|0)^u;a[K>>0]=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;a[v>>0]=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;b=a[(b&15)+(33451+(b>>>4<<4))>>0]|0;a[z>>0]=b;h=a[(h&15)+(33451+(h>>>4<<4))>>0]|0;a[E>>0]=h;j=d[B>>0]|0;j=a[(j&15)+(33451+(j>>>4<<4))>>0]|0;k=a[(k&15)+(33451+((k>>>4&15)<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;m=a[(m&15)+(33451+((m>>>4&15)<<4))>>0]|0;n=d[I>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;o=d[x>>0]|0;o=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;p=a[(p&15)+(33451+((p>>>4&15)<<4))>>0]|0;q=a[(q&15)+(33451+((q>>>4&15)<<4))>>0]|0;r=d[J>>0]|0;r=a[(r&15)+(33451+(r>>>4<<4))>>0]|0;s=d[y>>0]|0;s=a[(s&15)+(33451+(s>>>4<<4))>>0]|0;t=d[D>>0]|0;t=a[(t&15)+(33451+(t>>>4<<4))>>0]|0;u=a[(u&15)+(33451+((u>>>4&15)<<4))>>0]|0;a[B>>0]=k;a[w>>0]=l;a[A>>0]=m;a[F>>0]=j;a[I>>0]=p;a[C>>0]=n;a[x>>0]=q;a[G>>0]=o;a[J>>0]=u;a[H>>0]=t;a[D>>0]=s;a[y>>0]=r;if((g|0)==192){N=c[f+192>>2]|0;O=((d[K>>0]|0)^N>>>24)&255;a[K>>0]=O;k=(k&255^N>>>16)&255;a[B>>0]=k;B=(p&255^N>>>8)&255;a[I>>0]=B;p=(u&255^N)&255;a[J>>0]=p;N=c[f+196>>2]|0;u=((d[v>>0]|0)^N>>>24)&255;a[v>>0]=u;v=(l&255^N>>>16)&255;a[w>>0]=v;w=(q&255^N>>>8)&255;a[x>>0]=w;x=(r&255^N)&255;a[y>>0]=x;N=c[f+200>>2]|0;y=(b&255^N>>>24)&255;a[z>>0]=y;I=(m&255^N>>>16)&255;a[A>>0]=I;J=(n&255^N>>>8)&255;a[C>>0]=J;z=(s&255^N)&255;a[D>>0]=z;N=c[f+204>>2]|0;g=(h&255^N>>>24)&255;a[E>>0]=g;K=(j&255^N>>>16)&255;a[F>>0]=K;M=(o&255^N>>>8)&255;a[G>>0]=M;N=(t&255^N)&255;a[H>>0]=N;A=k;C=p;D=u;E=v;F=w;G=x;H=y;f=z;a[e>>0]=O;O=e+1|0;a[O>>0]=A;O=e+2|0;a[O>>0]=B;O=e+3|0;a[O>>0]=C;O=e+4|0;a[O>>0]=D;O=e+5|0;a[O>>0]=E;O=e+6|0;a[O>>0]=F;O=e+7|0;a[O>>0]=G;O=e+8|0;a[O>>0]=H;O=e+9|0;a[O>>0]=I;O=e+10|0;a[O>>0]=J;O=e+11|0;a[O>>0]=f;O=e+12|0;a[O>>0]=g;O=e+13|0;a[O>>0]=K;O=e+14|0;a[O>>0]=M;O=e+15|0;a[O>>0]=N;i=L;return}else{Ch(K);s=c[f+192>>2]|0;N=(d[K>>0]|0)^s>>>24;a[B>>0]=(d[B>>0]|0)^s>>>16;a[I>>0]=(d[I>>0]|0)^s>>>8;a[J>>0]=(d[J>>0]|0)^s;s=c[f+196>>2]|0;p=(d[v>>0]|0)^s>>>24;r=(d[w>>0]|0)^s>>>16;a[x>>0]=(d[x>>0]|0)^s>>>8;a[y>>0]=(d[y>>0]|0)^s;s=c[f+200>>2]|0;u=(d[z>>0]|0)^s>>>24;g=(d[A>>0]|0)^s>>>16;q=(d[C>>0]|0)^s>>>8;a[D>>0]=(d[D>>0]|0)^s;s=c[f+204>>2]|0;o=(d[E>>0]|0)^s>>>24;m=(d[F>>0]|0)^s>>>16;l=(d[G>>0]|0)^s>>>8;s=(d[H>>0]|0)^s;a[K>>0]=a[(N&15)+(33451+(N>>>4<<4))>>0]|0;a[v>>0]=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;a[z>>0]=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;a[E>>0]=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;o=d[B>>0]|0;o=a[(o&15)+(33451+(o>>>4<<4))>>0]|0;g=a[(g&15)+(33451+((g>>>4&15)<<4))>>0]|0;m=a[(m&15)+(33451+((m>>>4&15)<<4))>>0]|0;u=d[I>>0]|0;u=a[(u&15)+(33451+(u>>>4<<4))>>0]|0;p=d[x>>0]|0;p=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;q=a[(q&15)+(33451+((q>>>4&15)<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;N=d[J>>0]|0;N=a[(N&15)+(33451+(N>>>4<<4))>>0]|0;n=d[y>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;M=d[D>>0]|0;M=a[(M&15)+(33451+(M>>>4<<4))>>0]|0;s=a[(s&15)+(33451+((s>>>4&15)<<4))>>0]|0;a[B>>0]=a[(r&15)+(33451+((r>>>4&15)<<4))>>0]|0;a[w>>0]=g;a[A>>0]=m;a[F>>0]=o;a[I>>0]=q;a[C>>0]=u;a[x>>0]=l;a[G>>0]=p;a[J>>0]=s;a[H>>0]=M;a[D>>0]=n;a[y>>0]=N;Ch(K);N=c[f+208>>2]|0;n=(d[K>>0]|0)^N>>>24;a[B>>0]=(d[B>>0]|0)^N>>>16;a[I>>0]=(d[I>>0]|0)^N>>>8;a[J>>0]=(d[J>>0]|0)^N;N=c[f+212>>2]|0;M=(d[v>>0]|0)^N>>>24;s=(d[w>>0]|0)^N>>>16;a[x>>0]=(d[x>>0]|0)^N>>>8;a[y>>0]=(d[y>>0]|0)^N;N=c[f+216>>2]|0;p=(d[z>>0]|0)^N>>>24;l=(d[A>>0]|0)^N>>>16;u=(d[C>>0]|0)^N>>>8;a[D>>0]=(d[D>>0]|0)^N;N=c[f+220>>2]|0;q=(d[E>>0]|0)^N>>>24;o=(d[F>>0]|0)^N>>>16;m=(d[G>>0]|0)^N>>>8;N=(d[H>>0]|0)^N;a[K>>0]=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;a[v>>0]=a[(M&15)+(33451+(M>>>4<<4))>>0]|0;a[z>>0]=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;a[E>>0]=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;q=d[B>>0]|0;q=a[(q&15)+(33451+(q>>>4<<4))>>0]|0;s=a[(s&15)+(33451+((s>>>4&15)<<4))>>0]|0;l=a[(l&15)+(33451+((l>>>4&15)<<4))>>0]|0;o=a[(o&15)+(33451+((o>>>4&15)<<4))>>0]|0;p=d[I>>0]|0;p=a[(p&15)+(33451+(p>>>4<<4))>>0]|0;M=d[x>>0]|0;M=a[(M&15)+(33451+(M>>>4<<4))>>0]|0;u=a[(u&15)+(33451+((u>>>4&15)<<4))>>0]|0;m=a[(m&15)+(33451+((m>>>4&15)<<4))>>0]|0;n=d[J>>0]|0;n=a[(n&15)+(33451+(n>>>4<<4))>>0]|0;g=d[y>>0]|0;g=a[(g&15)+(33451+(g>>>4<<4))>>0]|0;r=d[D>>0]|0;r=a[(r&15)+(33451+(r>>>4<<4))>>0]|0;N=a[(N&15)+(33451+((N>>>4&15)<<4))>>0]|0;t=c[f+224>>2]|0;O=((d[K>>0]|0)^t>>>24)&255;a[K>>0]=O;s=(s&255^t>>>16)&255;a[B>>0]=s;B=(u&255^t>>>8)&255;a[I>>0]=B;t=(N&255^t)&255;a[J>>0]=t;N=c[f+228>>2]|0;u=((d[v>>0]|0)^N>>>24)&255;a[v>>0]=u;v=(l&255^N>>>16)&255;a[w>>0]=v;w=(m&255^N>>>8)&255;a[x>>0]=w;x=(n&255^N)&255;a[y>>0]=x;N=c[f+232>>2]|0;y=((d[z>>0]|0)^N>>>24)&255;a[z>>0]=y;I=(o&255^N>>>16)&255;a[A>>0]=I;J=(p&255^N>>>8)&255;a[C>>0]=J;z=(g&255^N)&255;a[D>>0]=z;N=c[f+236>>2]|0;g=((d[E>>0]|0)^N>>>24)&255;a[E>>0]=g;K=(q&255^N>>>16)&255;a[F>>0]=K;M=(M&255^N>>>8)&255;a[G>>0]=M;N=(r&255^N)&255;a[H>>0]=N;A=s;C=t;D=u;E=v;F=w;G=x;H=y;f=z;a[e>>0]=O;O=e+1|0;a[O>>0]=A;O=e+2|0;a[O>>0]=B;O=e+3|0;a[O>>0]=C;O=e+4|0;a[O>>0]=D;O=e+5|0;a[O>>0]=E;O=e+6|0;a[O>>0]=F;O=e+7|0;a[O>>0]=G;O=e+8|0;a[O>>0]=H;O=e+9|0;a[O>>0]=I;O=e+10|0;a[O>>0]=J;O=e+11|0;a[O>>0]=f;O=e+12|0;a[O>>0]=g;O=e+13|0;a[O>>0]=K;O=e+14|0;a[O>>0]=M;O=e+15|0;a[O>>0]=N;i=L;return}}function Ch(b){b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;n=a[b>>0]|0;l=b+4|0;e=a[l>>0]|0;f=b+8|0;g=a[f>>0]|0;h=b+12|0;d=a[h>>0]|0;j=n&255;i=e&255;c=g&255;m=d&255;a[b>>0]=d^g^a[33707+(j*6|0)>>0]^a[33707+(i*6|0)+1>>0];a[l>>0]=a[33707+(i*6|0)>>0]^n^d^a[33707+(c*6|0)+1>>0];a[f>>0]=a[33707+(m*6|0)+1>>0]^(a[33707+(c*6|0)>>0]^(e^n));a[h>>0]=g^e^a[33707+(j*6|0)+1>>0]^a[33707+(m*6|0)>>0];h=b+1|0;m=a[h>>0]|0;j=b+5|0;e=a[j>>0]|0;g=b+9|0;f=a[g>>0]|0;n=b+13|0;c=a[n>>0]|0;l=m&255;d=e&255;i=f&255;k=c&255;a[h>>0]=c^f^a[33707+(l*6|0)>>0]^a[33707+(d*6|0)+1>>0];a[j>>0]=a[33707+(d*6|0)>>0]^m^c^a[33707+(i*6|0)+1>>0];a[g>>0]=a[33707+(k*6|0)+1>>0]^(a[33707+(i*6|0)>>0]^(e^m));a[n>>0]=f^e^a[33707+(l*6|0)+1>>0]^a[33707+(k*6|0)>>0];n=b+2|0;k=a[n>>0]|0;l=b+6|0;e=a[l>>0]|0;f=b+10|0;g=a[f>>0]|0;m=b+14|0;i=a[m>>0]|0;j=k&255;c=e&255;d=g&255;h=i&255;a[n>>0]=i^g^a[33707+(j*6|0)>>0]^a[33707+(c*6|0)+1>>0];a[l>>0]=a[33707+(c*6|0)>>0]^k^i^a[33707+(d*6|0)+1>>0];a[f>>0]=a[33707+(h*6|0)+1>>0]^(a[33707+(d*6|0)>>0]^(e^k));a[m>>0]=g^e^a[33707+(j*6|0)+1>>0]^a[33707+(h*6|0)>>0];m=b+3|0;h=a[m>>0]|0;j=b+7|0;e=a[j>>0]|0;g=b+11|0;f=a[g>>0]|0;b=b+15|0;k=a[b>>0]|0;d=h&255;l=e&255;i=f&255;c=k&255;a[m>>0]=k^f^a[33707+(d*6|0)>>0]^a[33707+(l*6|0)+1>>0];a[j>>0]=a[33707+(l*6|0)>>0]^h^k^a[33707+(i*6|0)+1>>0];a[g>>0]=a[33707+(c*6|0)+1>>0]^(a[33707+(i*6|0)>>0]^(e^h));a[b>>0]=f^e^a[33707+(d*6|0)+1>>0]^a[33707+(c*6|0)>>0];return}function Dh(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0;switch(e|0){case 128:{g=4;h=44;break}case 192:{g=6;h=52;break}case 256:{g=8;h=60;break}default:return}e=0;do{f=e<<2;c[b+(e<<2)>>2]=(d[a+(f|1)>>0]|0)<<16|(d[a+f>>0]|0)<<24|(d[a+(f|2)>>0]|0)<<8|(d[a+(f|3)>>0]|0);e=e+1|0}while((e|0)<(g|0));if(g>>>0>6)f=g;else{f=g;do{a=f+-1|0;e=c[b+(a<<2)>>2]|0;if(!((f|0)%(g|0)|0))e=((d[(e&15)+(33451+((e>>>4&15)<<4))>>0]|0)<<8|(d[(e>>>24&15)+(33451+(e>>>28<<4))>>0]|0)|(d[(e>>>8&15)+(33451+((e>>>12&15)<<4))>>0]|0)<<16|(d[(e>>>16&15)+(33451+((e>>>20&15)<<4))>>0]|0)<<24)^c[32840+(((a|0)/(g|0)|0)<<2)>>2];c[b+(f<<2)>>2]=c[b+(f-g<<2)>>2]^e;f=f+1|0}while((f|0)<(h|0));return}do{a=f+-1|0;e=c[b+(a<<2)>>2]|0;switch((f|0)%(g|0)|0|0){case 0:{e=((d[(e&15)+(33451+((e>>>4&15)<<4))>>0]|0)<<8|(d[(e>>>24&15)+(33451+(e>>>28<<4))>>0]|0)|(d[(e>>>8&15)+(33451+((e>>>12&15)<<4))>>0]|0)<<16|(d[(e>>>16&15)+(33451+((e>>>20&15)<<4))>>0]|0)<<24)^c[32840+(((a|0)/(g|0)|0)<<2)>>2];break}case 4:{e=(d[(e>>>8&15)+(33451+((e>>>12&15)<<4))>>0]|0)<<8|(d[(e&15)+(33451+((e>>>4&15)<<4))>>0]|0)|(d[(e>>>16&15)+(33451+((e>>>20&15)<<4))>>0]|0)<<16|(d[(e>>>24&15)+(33451+(e>>>28<<4))>>0]|0)<<24;break}default:{}}c[b+(f<<2)>>2]=c[b+(f-g<<2)>>2]^e;f=f+1|0}while((f|0)<(h|0));return}function Eh(b){b=b|0;var c=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;j=b+4|0;f=b+8|0;e=b+12|0;c=d[b>>0]|0;h=d[j>>0]|0;k=d[f>>0]|0;g=d[e>>0]|0;a[b>>0]=a[33707+(g*6|0)+2>>0]^(a[33707+(k*6|0)+4>>0]^(a[33707+(h*6|0)+3>>0]^a[33707+(c*6|0)+5>>0]));a[j>>0]=a[33707+(g*6|0)+4>>0]^(a[33707+(k*6|0)+3>>0]^(a[33707+(h*6|0)+5>>0]^a[33707+(c*6|0)+2>>0]));a[f>>0]=a[33707+(g*6|0)+3>>0]^(a[33707+(k*6|0)+5>>0]^(a[33707+(h*6|0)+2>>0]^a[33707+(c*6|0)+4>>0]));a[e>>0]=a[33707+(g*6|0)+5>>0]^(a[33707+(k*6|0)+2>>0]^(a[33707+(h*6|0)+4>>0]^a[33707+(c*6|0)+3>>0]));e=b+1|0;c=b+5|0;h=b+9|0;k=b+13|0;g=d[e>>0]|0;f=d[c>>0]|0;j=d[h>>0]|0;i=d[k>>0]|0;a[e>>0]=a[33707+(i*6|0)+2>>0]^(a[33707+(j*6|0)+4>>0]^(a[33707+(f*6|0)+3>>0]^a[33707+(g*6|0)+5>>0]));a[c>>0]=a[33707+(i*6|0)+4>>0]^(a[33707+(j*6|0)+3>>0]^(a[33707+(f*6|0)+5>>0]^a[33707+(g*6|0)+2>>0]));a[h>>0]=a[33707+(i*6|0)+3>>0]^(a[33707+(j*6|0)+5>>0]^(a[33707+(f*6|0)+2>>0]^a[33707+(g*6|0)+4>>0]));a[k>>0]=a[33707+(i*6|0)+5>>0]^(a[33707+(j*6|0)+2>>0]^(a[33707+(f*6|0)+4>>0]^a[33707+(g*6|0)+3>>0]));k=b+2|0;g=b+6|0;f=b+10|0;j=b+14|0;i=d[k>>0]|0;h=d[g>>0]|0;c=d[f>>0]|0;e=d[j>>0]|0;a[k>>0]=a[33707+(e*6|0)+2>>0]^(a[33707+(c*6|0)+4>>0]^(a[33707+(h*6|0)+3>>0]^a[33707+(i*6|0)+5>>0]));a[g>>0]=a[33707+(e*6|0)+4>>0]^(a[33707+(c*6|0)+3>>0]^(a[33707+(h*6|0)+5>>0]^a[33707+(i*6|0)+2>>0]));a[f>>0]=a[33707+(e*6|0)+3>>0]^(a[33707+(c*6|0)+5>>0]^(a[33707+(h*6|0)+2>>0]^a[33707+(i*6|0)+4>>0]));a[j>>0]=a[33707+(e*6|0)+5>>0]^(a[33707+(c*6|0)+2>>0]^(a[33707+(h*6|0)+4>>0]^a[33707+(i*6|0)+3>>0]));j=b+3|0;i=b+7|0;h=b+11|0;b=b+15|0;c=d[j>>0]|0;e=d[i>>0]|0;f=d[h>>0]|0;g=d[b>>0]|0;a[j>>0]=a[33707+(g*6|0)+2>>0]^(a[33707+(f*6|0)+4>>0]^(a[33707+(e*6|0)+3>>0]^a[33707+(c*6|0)+5>>0]));a[i>>0]=a[33707+(g*6|0)+4>>0]^(a[33707+(f*6|0)+3>>0]^(a[33707+(e*6|0)+5>>0]^a[33707+(c*6|0)+2>>0]));a[h>>0]=a[33707+(g*6|0)+3>>0]^(a[33707+(f*6|0)+5>>0]^(a[33707+(e*6|0)+2>>0]^a[33707+(c*6|0)+4>>0]));a[b>>0]=a[33707+(g*6|0)+5>>0]^(a[33707+(f*6|0)+2>>0]^(a[33707+(e*6|0)+4>>0]^a[33707+(c*6|0)+3>>0]));return}function Fh(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0;N=i;i=i+16|0;M=N;h=a[b>>0]|0;a[M>>0]=h;m=a[b+1>>0]|0;E=M+4|0;a[E>>0]=m;v=a[b+2>>0]|0;K=M+8|0;a[K>>0]=v;w=a[b+3>>0]|0;L=M+12|0;a[L>>0]=w;j=a[b+4>>0]|0;y=M+1|0;a[y>>0]=j;k=a[b+5>>0]|0;z=M+5|0;a[z>>0]=k;l=a[b+6>>0]|0;A=M+9|0;a[A>>0]=l;n=a[b+7>>0]|0;B=M+13|0;a[B>>0]=n;o=a[b+8>>0]|0;C=M+2|0;a[C>>0]=o;p=a[b+9>>0]|0;D=M+6|0;a[D>>0]=p;q=a[b+10>>0]|0;F=M+10|0;a[F>>0]=q;r=a[b+11>>0]|0;G=M+14|0;a[G>>0]=r;s=a[b+12>>0]|0;H=M+3|0;a[H>>0]=s;t=a[b+13>>0]|0;I=M+7|0;a[I>>0]=t;u=a[b+14>>0]|0;J=M+11|0;a[J>>0]=u;b=a[b+15>>0]|0;x=M+15|0;a[x>>0]=b;if((g|0)>128){if((g|0)>192){R=c[f+224>>2]|0;S=h&255^R>>>24;P=m&255^R>>>16;g=v&255^R>>>8;v=w&255^R;m=c[f+228>>2]|0;R=j&255^m>>>24;O=k&255^m>>>16;w=l&255^m>>>8;k=n&255^m;m=c[f+232>>2]|0;Q=o&255^m>>>24;n=p&255^m>>>16;j=q&255^m>>>8;m=r&255^m;r=c[f+236>>2]|0;p=s&255^r>>>24;o=t&255^r>>>16;h=u&255^r>>>8;r=b&255^r;l=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;a[y>>0]=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;a[C>>0]=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;a[H>>0]=a[(p&15)+(35243+(p>>>4<<4))>>0]|0;o=a[(o&15)+(35243+((o>>>4&15)<<4))>>0]|0;p=a[(P&15)+(35243+((P>>>4&15)<<4))>>0]|0;a[D>>0]=a[(O&15)+(35243+((O>>>4&15)<<4))>>0]|0;a[I>>0]=a[(n&15)+(35243+((n>>>4&15)<<4))>>0]|0;j=a[(j&15)+(35243+((j>>>4&15)<<4))>>0]|0;h=a[(h&15)+(35243+((h>>>4&15)<<4))>>0]|0;n=a[(g&15)+(35243+((g>>>4&15)<<4))>>0]|0;a[J>>0]=a[(w&15)+(35243+((w>>>4&15)<<4))>>0]|0;k=a[(k&15)+(35243+((k>>>4&15)<<4))>>0]|0;m=a[(m&15)+(35243+((m>>>4&15)<<4))>>0]|0;r=a[(r&15)+(35243+((r>>>4&15)<<4))>>0]|0;b=a[(v&15)+(35243+((v>>>4&15)<<4))>>0]|0;q=c[f+208>>2]|0;a[M>>0]=l&255^q>>>24;a[E>>0]=o&255^q>>>16;a[K>>0]=j&255^q>>>8;a[L>>0]=k&255^q;q=c[f+212>>2]|0;a[y>>0]=(d[y>>0]|0)^q>>>24;a[z>>0]=p&255^q>>>16;a[A>>0]=h&255^q>>>8;a[B>>0]=m&255^q;q=c[f+216>>2]|0;a[C>>0]=(d[C>>0]|0)^q>>>24;a[D>>0]=(d[D>>0]|0)^q>>>16;a[F>>0]=n&255^q>>>8;a[G>>0]=r&255^q;q=c[f+220>>2]|0;a[H>>0]=(d[H>>0]|0)^q>>>24;a[I>>0]=(d[I>>0]|0)^q>>>16;a[J>>0]=(d[J>>0]|0)^q>>>8;a[x>>0]=b&255^q;Eh(M);q=a[I>>0]|0;b=a[D>>0]|0;r=a[z>>0]|0;n=a[E>>0]|0;m=a[J>>0]|0;h=a[A>>0]|0;p=a[F>>0]|0;k=a[K>>0]|0;j=a[x>>0]|0;a[x>>0]=a[L>>0]|0;o=a[B>>0]|0;l=a[G>>0]|0;s=d[M>>0]|0;a[M>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;s=d[y>>0]|0;a[y>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;s=d[C>>0]|0;a[C>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;s=d[H>>0]|0;a[H>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;q=q&255;q=a[(q&15)+(35243+(q>>>4<<4))>>0]|0;n=n&255;n=a[(n&15)+(35243+(n>>>4<<4))>>0]|0;r=r&255;a[D>>0]=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;b=b&255;a[I>>0]=a[(b&15)+(35243+(b>>>4<<4))>>0]|0;p=p&255;p=a[(p&15)+(35243+(p>>>4<<4))>>0]|0;m=m&255;m=a[(m&15)+(35243+(m>>>4<<4))>>0]|0;k=k&255;k=a[(k&15)+(35243+(k>>>4<<4))>>0]|0;h=h&255;a[J>>0]=a[(h&15)+(35243+(h>>>4<<4))>>0]|0;o=o&255;o=a[(o&15)+(35243+(o>>>4<<4))>>0]|0;l=l&255;l=a[(l&15)+(35243+(l>>>4<<4))>>0]|0;j=j&255;j=a[(j&15)+(35243+(j>>>4<<4))>>0]|0;h=d[x>>0]|0;h=a[(h&15)+(35243+(h>>>4<<4))>>0]|0;b=c[f+192>>2]|0;a[M>>0]=(d[M>>0]|0)^b>>>24;a[E>>0]=q&255^b>>>16;a[K>>0]=p&255^b>>>8;a[L>>0]=o&255^b;b=c[f+196>>2]|0;a[y>>0]=(d[y>>0]|0)^b>>>24;a[z>>0]=n&255^b>>>16;a[A>>0]=m&255^b>>>8;a[B>>0]=l&255^b;b=c[f+200>>2]|0;a[C>>0]=(d[C>>0]|0)^b>>>24;a[D>>0]=(d[D>>0]|0)^b>>>16;a[F>>0]=k&255^b>>>8;a[G>>0]=j&255^b;b=c[f+204>>2]|0;a[H>>0]=(d[H>>0]|0)^b>>>24;a[I>>0]=(d[I>>0]|0)^b>>>16;a[J>>0]=(d[J>>0]|0)^b>>>8;a[x>>0]=h&255^b;Eh(M);b=a[M>>0]|0;h=a[y>>0]|0;j=a[C>>0]|0;k=a[H>>0]|0;l=a[I>>0]|0;m=a[E>>0]|0;n=a[z>>0]|0;o=a[D>>0]|0;p=a[F>>0]|0;q=a[J>>0]|0;r=a[K>>0]|0;s=a[A>>0]|0;t=a[B>>0]|0;u=a[G>>0]|0;v=a[x>>0]|0;w=a[L>>0]|0}else{R=c[f+192>>2]|0;g=(h&255^R>>>24)&255;a[M>>0]=g;m=(m&255^R>>>16)&255;a[E>>0]=m;P=(v&255^R>>>8)&255;a[K>>0]=P;w=(w&255^R)&255;a[L>>0]=w;R=c[f+196>>2]|0;h=(j&255^R>>>24)&255;a[y>>0]=h;O=(k&255^R>>>16)&255;a[z>>0]=O;Q=(l&255^R>>>8)&255;a[A>>0]=Q;R=(n&255^R)&255;a[B>>0]=R;S=c[f+200>>2]|0;j=(o&255^S>>>24)&255;a[C>>0]=j;o=(p&255^S>>>16)&255;a[D>>0]=o;p=(q&255^S>>>8)&255;a[F>>0]=p;S=(r&255^S)&255;a[G>>0]=S;v=c[f+204>>2]|0;k=(s&255^v>>>24)&255;a[H>>0]=k;l=(t&255^v>>>16)&255;a[I>>0]=l;q=(u&255^v>>>8)&255;a[J>>0]=q;v=(b&255^v)&255;a[x>>0]=v;b=g;n=O;r=P;s=Q;t=R;u=S}S=b&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;h=h&255;a[y>>0]=a[(h&15)+(35243+(h>>>4<<4))>>0]|0;j=j&255;a[C>>0]=a[(j&15)+(35243+(j>>>4<<4))>>0]|0;k=k&255;a[H>>0]=a[(k&15)+(35243+(k>>>4<<4))>>0]|0;l=l&255;l=a[(l&15)+(35243+(l>>>4<<4))>>0]|0;k=m&255;k=a[(k&15)+(35243+(k>>>4<<4))>>0]|0;j=n&255;a[D>>0]=a[(j&15)+(35243+(j>>>4<<4))>>0]|0;j=o&255;a[I>>0]=a[(j&15)+(35243+(j>>>4<<4))>>0]|0;j=p&255;j=a[(j&15)+(35243+(j>>>4<<4))>>0]|0;h=q&255;h=a[(h&15)+(35243+(h>>>4<<4))>>0]|0;n=r&255;n=a[(n&15)+(35243+(n>>>4<<4))>>0]|0;p=s&255;a[J>>0]=a[(p&15)+(35243+(p>>>4<<4))>>0]|0;p=t&255;p=a[(p&15)+(35243+(p>>>4<<4))>>0]|0;m=u&255;m=a[(m&15)+(35243+(m>>>4<<4))>>0]|0;r=v&255;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;b=w&255;b=a[(b&15)+(35243+(b>>>4<<4))>>0]|0;q=c[f+176>>2]|0;a[M>>0]=S&255^q>>>24;a[E>>0]=l&255^q>>>16;a[K>>0]=j&255^q>>>8;a[L>>0]=p&255^q;q=c[f+180>>2]|0;a[y>>0]=(d[y>>0]|0)^q>>>24;a[z>>0]=k&255^q>>>16;a[A>>0]=h&255^q>>>8;a[B>>0]=m&255^q;q=c[f+184>>2]|0;a[C>>0]=(d[C>>0]|0)^q>>>24;a[D>>0]=(d[D>>0]|0)^q>>>16;a[F>>0]=n&255^q>>>8;a[G>>0]=r&255^q;q=c[f+188>>2]|0;a[H>>0]=(d[H>>0]|0)^q>>>24;a[I>>0]=(d[I>>0]|0)^q>>>16;a[J>>0]=(d[J>>0]|0)^q>>>8;a[x>>0]=b&255^q;Eh(M);q=a[I>>0]|0;b=a[D>>0]|0;r=a[z>>0]|0;n=a[E>>0]|0;m=a[J>>0]|0;h=a[A>>0]|0;p=a[F>>0]|0;k=a[K>>0]|0;j=a[x>>0]|0;a[x>>0]=a[L>>0]|0;o=a[B>>0]|0;l=a[G>>0]|0;s=d[M>>0]|0;a[M>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;s=d[y>>0]|0;a[y>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;s=d[C>>0]|0;a[C>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;s=d[H>>0]|0;a[H>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;q=q&255;q=a[(q&15)+(35243+(q>>>4<<4))>>0]|0;n=n&255;n=a[(n&15)+(35243+(n>>>4<<4))>>0]|0;r=r&255;a[D>>0]=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;b=b&255;a[I>>0]=a[(b&15)+(35243+(b>>>4<<4))>>0]|0;p=p&255;p=a[(p&15)+(35243+(p>>>4<<4))>>0]|0;m=m&255;m=a[(m&15)+(35243+(m>>>4<<4))>>0]|0;k=k&255;k=a[(k&15)+(35243+(k>>>4<<4))>>0]|0;h=h&255;a[J>>0]=a[(h&15)+(35243+(h>>>4<<4))>>0]|0;o=o&255;o=a[(o&15)+(35243+(o>>>4<<4))>>0]|0;l=l&255;l=a[(l&15)+(35243+(l>>>4<<4))>>0]|0;j=j&255;j=a[(j&15)+(35243+(j>>>4<<4))>>0]|0;h=d[x>>0]|0;h=a[(h&15)+(35243+(h>>>4<<4))>>0]|0;b=c[f+160>>2]|0;a[M>>0]=(d[M>>0]|0)^b>>>24;a[E>>0]=q&255^b>>>16;a[K>>0]=p&255^b>>>8;a[L>>0]=o&255^b;b=c[f+164>>2]|0;a[y>>0]=(d[y>>0]|0)^b>>>24;a[z>>0]=n&255^b>>>16;a[A>>0]=m&255^b>>>8;a[B>>0]=l&255^b;b=c[f+168>>2]|0;a[C>>0]=(d[C>>0]|0)^b>>>24;a[D>>0]=(d[D>>0]|0)^b>>>16;a[F>>0]=k&255^b>>>8;a[G>>0]=j&255^b;b=c[f+172>>2]|0;a[H>>0]=(d[H>>0]|0)^b>>>24;a[I>>0]=(d[I>>0]|0)^b>>>16;a[J>>0]=(d[J>>0]|0)^b>>>8;a[x>>0]=h&255^b;Eh(M);b=a[M>>0]|0;h=a[y>>0]|0;j=a[C>>0]|0;k=a[H>>0]|0;l=a[I>>0]|0;m=a[E>>0]|0;n=a[z>>0]|0;o=a[D>>0]|0;p=a[F>>0]|0;q=a[J>>0]|0;r=a[K>>0]|0;s=a[A>>0]|0;t=a[B>>0]|0;u=a[G>>0]|0;v=a[x>>0]|0;w=a[L>>0]|0}else{R=c[f+160>>2]|0;g=(h&255^R>>>24)&255;a[M>>0]=g;m=(m&255^R>>>16)&255;a[E>>0]=m;P=(v&255^R>>>8)&255;a[K>>0]=P;w=(w&255^R)&255;a[L>>0]=w;R=c[f+164>>2]|0;h=(j&255^R>>>24)&255;a[y>>0]=h;O=(k&255^R>>>16)&255;a[z>>0]=O;Q=(l&255^R>>>8)&255;a[A>>0]=Q;R=(n&255^R)&255;a[B>>0]=R;S=c[f+168>>2]|0;j=(o&255^S>>>24)&255;a[C>>0]=j;o=(p&255^S>>>16)&255;a[D>>0]=o;p=(q&255^S>>>8)&255;a[F>>0]=p;S=(r&255^S)&255;a[G>>0]=S;v=c[f+172>>2]|0;k=(s&255^v>>>24)&255;a[H>>0]=k;l=(t&255^v>>>16)&255;a[I>>0]=l;q=(u&255^v>>>8)&255;a[J>>0]=q;v=(b&255^v)&255;a[x>>0]=v;b=g;n=O;r=P;s=Q;t=R;u=S}b=b&255;b=a[(b&15)+(35243+(b>>>4<<4))>>0]|0;O=h&255;a[y>>0]=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;O=j&255;a[C>>0]=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;O=k&255;a[H>>0]=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;l=l&255;l=a[(l&15)+(35243+(l>>>4<<4))>>0]|0;O=m&255;O=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;R=n&255;a[D>>0]=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;R=o&255;a[I>>0]=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;R=p&255;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;g=q&255;g=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;S=r&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;s=s&255;a[J>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;s=t&255;s=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;r=u&255;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;t=v&255;t=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;P=w&255;P=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;Q=c[f+144>>2]|0;a[M>>0]=b&255^Q>>>24;a[E>>0]=l&255^Q>>>16;a[K>>0]=R&255^Q>>>8;a[L>>0]=s&255^Q;Q=c[f+148>>2]|0;a[y>>0]=(d[y>>0]|0)^Q>>>24;a[z>>0]=O&255^Q>>>16;a[A>>0]=g&255^Q>>>8;a[B>>0]=r&255^Q;Q=c[f+152>>2]|0;a[C>>0]=(d[C>>0]|0)^Q>>>24;a[D>>0]=(d[D>>0]|0)^Q>>>16;a[F>>0]=S&255^Q>>>8;a[G>>0]=t&255^Q;Q=c[f+156>>2]|0;a[H>>0]=(d[H>>0]|0)^Q>>>24;a[I>>0]=(d[I>>0]|0)^Q>>>16;a[J>>0]=(d[J>>0]|0)^Q>>>8;a[x>>0]=P&255^Q;Eh(M);Q=a[I>>0]|0;P=a[D>>0]|0;t=a[z>>0]|0;v=a[E>>0]|0;S=a[J>>0]|0;r=a[A>>0]|0;s=a[F>>0]|0;g=a[K>>0]|0;O=a[x>>0]|0;a[x>>0]=a[L>>0]|0;R=a[B>>0]|0;w=a[G>>0]|0;u=d[M>>0]|0;a[M>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[y>>0]|0;a[y>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[C>>0]|0;a[C>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[H>>0]|0;a[H>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;Q=Q&255;Q=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;v=v&255;v=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;t=t&255;a[D>>0]=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;P=P&255;a[I>>0]=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;s=s&255;s=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;S=S&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;g=g&255;g=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;r=r&255;a[J>>0]=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;R=R&255;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;w=w&255;w=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;O=O&255;O=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;r=d[x>>0]|0;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;P=c[f+128>>2]|0;a[M>>0]=(d[M>>0]|0)^P>>>24;a[E>>0]=Q&255^P>>>16;a[K>>0]=s&255^P>>>8;a[L>>0]=R&255^P;P=c[f+132>>2]|0;a[y>>0]=(d[y>>0]|0)^P>>>24;a[z>>0]=v&255^P>>>16;a[A>>0]=S&255^P>>>8;a[B>>0]=w&255^P;P=c[f+136>>2]|0;a[C>>0]=(d[C>>0]|0)^P>>>24;a[D>>0]=(d[D>>0]|0)^P>>>16;a[F>>0]=g&255^P>>>8;a[G>>0]=O&255^P;P=c[f+140>>2]|0;a[H>>0]=(d[H>>0]|0)^P>>>24;a[I>>0]=(d[I>>0]|0)^P>>>16;a[J>>0]=(d[J>>0]|0)^P>>>8;a[x>>0]=r&255^P;Eh(M);P=a[I>>0]|0;r=a[D>>0]|0;O=a[z>>0]|0;g=a[E>>0]|0;w=a[J>>0]|0;S=a[A>>0]|0;v=a[F>>0]|0;R=a[K>>0]|0;s=a[x>>0]|0;a[x>>0]=a[L>>0]|0;Q=a[B>>0]|0;t=a[G>>0]|0;u=d[M>>0]|0;a[M>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[y>>0]|0;a[y>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[C>>0]|0;a[C>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[H>>0]|0;a[H>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;P=P&255;P=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;g=g&255;g=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;O=O&255;a[D>>0]=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;r=r&255;a[I>>0]=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;v=v&255;v=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;w=w&255;w=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;R=R&255;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;S=S&255;a[J>>0]=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;Q=Q&255;Q=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;t=t&255;t=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;s=s&255;s=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;S=d[x>>0]|0;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;r=c[f+112>>2]|0;a[M>>0]=(d[M>>0]|0)^r>>>24;a[E>>0]=P&255^r>>>16;a[K>>0]=v&255^r>>>8;a[L>>0]=Q&255^r;r=c[f+116>>2]|0;a[y>>0]=(d[y>>0]|0)^r>>>24;a[z>>0]=g&255^r>>>16;a[A>>0]=w&255^r>>>8;a[B>>0]=t&255^r;r=c[f+120>>2]|0;a[C>>0]=(d[C>>0]|0)^r>>>24;a[D>>0]=(d[D>>0]|0)^r>>>16;a[F>>0]=R&255^r>>>8;a[G>>0]=s&255^r;r=c[f+124>>2]|0;a[H>>0]=(d[H>>0]|0)^r>>>24;a[I>>0]=(d[I>>0]|0)^r>>>16;a[J>>0]=(d[J>>0]|0)^r>>>8;a[x>>0]=S&255^r;Eh(M);r=a[I>>0]|0;S=a[D>>0]|0;s=a[z>>0]|0;R=a[E>>0]|0;t=a[J>>0]|0;w=a[A>>0]|0;g=a[F>>0]|0;Q=a[K>>0]|0;v=a[x>>0]|0;a[x>>0]=a[L>>0]|0;P=a[B>>0]|0;O=a[G>>0]|0;u=d[M>>0]|0;a[M>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[y>>0]|0;a[y>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[C>>0]|0;a[C>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[H>>0]|0;a[H>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;r=r&255;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;R=R&255;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;s=s&255;a[D>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;S=S&255;a[I>>0]=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;g=g&255;g=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;t=t&255;t=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;Q=Q&255;Q=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;w=w&255;a[J>>0]=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;P=P&255;P=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;O=O&255;O=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;v=v&255;v=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;w=d[x>>0]|0;w=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;S=c[f+96>>2]|0;a[M>>0]=(d[M>>0]|0)^S>>>24;a[E>>0]=r&255^S>>>16;a[K>>0]=g&255^S>>>8;a[L>>0]=P&255^S;S=c[f+100>>2]|0;a[y>>0]=(d[y>>0]|0)^S>>>24;a[z>>0]=R&255^S>>>16;a[A>>0]=t&255^S>>>8;a[B>>0]=O&255^S;S=c[f+104>>2]|0;a[C>>0]=(d[C>>0]|0)^S>>>24;a[D>>0]=(d[D>>0]|0)^S>>>16;a[F>>0]=Q&255^S>>>8;a[G>>0]=v&255^S;S=c[f+108>>2]|0;a[H>>0]=(d[H>>0]|0)^S>>>24;a[I>>0]=(d[I>>0]|0)^S>>>16;a[J>>0]=(d[J>>0]|0)^S>>>8;a[x>>0]=w&255^S;Eh(M);S=a[I>>0]|0;w=a[D>>0]|0;v=a[z>>0]|0;Q=a[E>>0]|0;O=a[J>>0]|0;t=a[A>>0]|0;R=a[F>>0]|0;P=a[K>>0]|0;g=a[x>>0]|0;a[x>>0]=a[L>>0]|0;r=a[B>>0]|0;s=a[G>>0]|0;u=d[M>>0]|0;a[M>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[y>>0]|0;a[y>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[C>>0]|0;a[C>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[H>>0]|0;a[H>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;S=S&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;Q=Q&255;Q=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;v=v&255;a[D>>0]=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;w=w&255;a[I>>0]=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;R=R&255;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;O=O&255;O=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;P=P&255;P=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;t=t&255;a[J>>0]=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;r=r&255;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;s=s&255;s=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;g=g&255;g=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;t=d[x>>0]|0;t=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;w=c[f+80>>2]|0;a[M>>0]=(d[M>>0]|0)^w>>>24;a[E>>0]=S&255^w>>>16;a[K>>0]=R&255^w>>>8;a[L>>0]=r&255^w;w=c[f+84>>2]|0;a[y>>0]=(d[y>>0]|0)^w>>>24;a[z>>0]=Q&255^w>>>16;a[A>>0]=O&255^w>>>8;a[B>>0]=s&255^w;w=c[f+88>>2]|0;a[C>>0]=(d[C>>0]|0)^w>>>24;a[D>>0]=(d[D>>0]|0)^w>>>16;a[F>>0]=P&255^w>>>8;a[G>>0]=g&255^w;w=c[f+92>>2]|0;a[H>>0]=(d[H>>0]|0)^w>>>24;a[I>>0]=(d[I>>0]|0)^w>>>16;a[J>>0]=(d[J>>0]|0)^w>>>8;a[x>>0]=t&255^w;Eh(M);w=a[I>>0]|0;t=a[D>>0]|0;g=a[z>>0]|0;P=a[E>>0]|0;s=a[J>>0]|0;O=a[A>>0]|0;Q=a[F>>0]|0;r=a[K>>0]|0;R=a[x>>0]|0;a[x>>0]=a[L>>0]|0;S=a[B>>0]|0;v=a[G>>0]|0;u=d[M>>0]|0;a[M>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[y>>0]|0;a[y>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[C>>0]|0;a[C>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[H>>0]|0;a[H>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;w=w&255;w=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;P=P&255;P=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;g=g&255;a[D>>0]=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;t=t&255;a[I>>0]=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;Q=Q&255;Q=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;s=s&255;s=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;r=r&255;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;O=O&255;a[J>>0]=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;S=S&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;v=v&255;v=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;R=R&255;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;O=d[x>>0]|0;O=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;t=c[f+64>>2]|0;a[M>>0]=(d[M>>0]|0)^t>>>24;a[E>>0]=w&255^t>>>16;a[K>>0]=Q&255^t>>>8;a[L>>0]=S&255^t;t=c[f+68>>2]|0;a[y>>0]=(d[y>>0]|0)^t>>>24;a[z>>0]=P&255^t>>>16;a[A>>0]=s&255^t>>>8;a[B>>0]=v&255^t;t=c[f+72>>2]|0;a[C>>0]=(d[C>>0]|0)^t>>>24;a[D>>0]=(d[D>>0]|0)^t>>>16;a[F>>0]=r&255^t>>>8;a[G>>0]=R&255^t;t=c[f+76>>2]|0;a[H>>0]=(d[H>>0]|0)^t>>>24;a[I>>0]=(d[I>>0]|0)^t>>>16;a[J>>0]=(d[J>>0]|0)^t>>>8;a[x>>0]=O&255^t;Eh(M);t=a[I>>0]|0;O=a[D>>0]|0;R=a[z>>0]|0;r=a[E>>0]|0;v=a[J>>0]|0;s=a[A>>0]|0;P=a[F>>0]|0;S=a[K>>0]|0;Q=a[x>>0]|0;a[x>>0]=a[L>>0]|0;w=a[B>>0]|0;g=a[G>>0]|0;u=d[M>>0]|0;a[M>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[y>>0]|0;a[y>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[C>>0]|0;a[C>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[H>>0]|0;a[H>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;t=t&255;t=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;r=r&255;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;R=R&255;a[D>>0]=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;O=O&255;a[I>>0]=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;P=P&255;P=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;v=v&255;v=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;S=S&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;s=s&255;a[J>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;w=w&255;w=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;g=g&255;g=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;Q=Q&255;Q=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;s=d[x>>0]|0;s=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;O=c[f+48>>2]|0;a[M>>0]=(d[M>>0]|0)^O>>>24;a[E>>0]=t&255^O>>>16;a[K>>0]=P&255^O>>>8;a[L>>0]=w&255^O;O=c[f+52>>2]|0;a[y>>0]=(d[y>>0]|0)^O>>>24;a[z>>0]=r&255^O>>>16;a[A>>0]=v&255^O>>>8;a[B>>0]=g&255^O;O=c[f+56>>2]|0;a[C>>0]=(d[C>>0]|0)^O>>>24;a[D>>0]=(d[D>>0]|0)^O>>>16;a[F>>0]=S&255^O>>>8;a[G>>0]=Q&255^O;O=c[f+60>>2]|0;a[H>>0]=(d[H>>0]|0)^O>>>24;a[I>>0]=(d[I>>0]|0)^O>>>16;a[J>>0]=(d[J>>0]|0)^O>>>8;a[x>>0]=s&255^O;Eh(M);O=a[I>>0]|0;s=a[D>>0]|0;Q=a[z>>0]|0;S=a[E>>0]|0;g=a[J>>0]|0;v=a[A>>0]|0;r=a[F>>0]|0;w=a[K>>0]|0;P=a[x>>0]|0;a[x>>0]=a[L>>0]|0;t=a[B>>0]|0;R=a[G>>0]|0;u=d[M>>0]|0;a[M>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[y>>0]|0;a[y>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[C>>0]|0;a[C>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[H>>0]|0;a[H>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;O=O&255;O=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;S=S&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;Q=Q&255;a[D>>0]=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;s=s&255;a[I>>0]=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;r=r&255;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;g=g&255;g=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;w=w&255;w=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;v=v&255;a[J>>0]=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;t=t&255;t=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;R=R&255;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;P=P&255;P=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;v=d[x>>0]|0;v=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;s=c[f+32>>2]|0;a[M>>0]=(d[M>>0]|0)^s>>>24;a[E>>0]=O&255^s>>>16;a[K>>0]=r&255^s>>>8;a[L>>0]=t&255^s;s=c[f+36>>2]|0;a[y>>0]=(d[y>>0]|0)^s>>>24;a[z>>0]=S&255^s>>>16;a[A>>0]=g&255^s>>>8;a[B>>0]=R&255^s;s=c[f+40>>2]|0;a[C>>0]=(d[C>>0]|0)^s>>>24;a[D>>0]=(d[D>>0]|0)^s>>>16;a[F>>0]=w&255^s>>>8;a[G>>0]=P&255^s;s=c[f+44>>2]|0;a[H>>0]=(d[H>>0]|0)^s>>>24;a[I>>0]=(d[I>>0]|0)^s>>>16;a[J>>0]=(d[J>>0]|0)^s>>>8;a[x>>0]=v&255^s;Eh(M);s=a[I>>0]|0;v=a[D>>0]|0;P=a[z>>0]|0;w=a[E>>0]|0;R=a[J>>0]|0;g=a[A>>0]|0;S=a[F>>0]|0;t=a[K>>0]|0;r=a[x>>0]|0;a[x>>0]=a[L>>0]|0;O=a[B>>0]|0;Q=a[G>>0]|0;u=d[M>>0]|0;a[M>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[y>>0]|0;a[y>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[C>>0]|0;a[C>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;u=d[H>>0]|0;a[H>>0]=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;s=s&255;s=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;w=w&255;w=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;P=P&255;a[D>>0]=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;v=v&255;a[I>>0]=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;S=S&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;R=R&255;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;t=t&255;t=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;g=g&255;a[J>>0]=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;O=O&255;O=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;Q=Q&255;Q=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;r=r&255;r=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;g=d[x>>0]|0;g=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;v=c[f+16>>2]|0;a[M>>0]=(d[M>>0]|0)^v>>>24;a[E>>0]=s&255^v>>>16;a[K>>0]=S&255^v>>>8;a[L>>0]=O&255^v;v=c[f+20>>2]|0;a[y>>0]=(d[y>>0]|0)^v>>>24;a[z>>0]=w&255^v>>>16;a[A>>0]=R&255^v>>>8;a[B>>0]=Q&255^v;v=c[f+24>>2]|0;a[C>>0]=(d[C>>0]|0)^v>>>24;a[D>>0]=(d[D>>0]|0)^v>>>16;a[F>>0]=t&255^v>>>8;a[G>>0]=r&255^v;v=c[f+28>>2]|0;a[H>>0]=(d[H>>0]|0)^v>>>24;a[I>>0]=(d[I>>0]|0)^v>>>16;a[J>>0]=(d[J>>0]|0)^v>>>8;a[x>>0]=g&255^v;Eh(M);v=a[I>>0]|0;g=a[D>>0]|0;r=a[z>>0]|0;t=a[E>>0]|0;Q=a[J>>0]|0;R=a[A>>0]|0;w=a[F>>0]|0;O=a[K>>0]|0;S=a[x>>0]|0;a[x>>0]=a[L>>0]|0;s=a[B>>0]|0;P=a[G>>0]|0;u=d[M>>0]|0;u=a[(u&15)+(35243+(u>>>4<<4))>>0]|0;a[M>>0]=u;q=d[y>>0]|0;a[y>>0]=a[(q&15)+(35243+(q>>>4<<4))>>0]|0;q=d[C>>0]|0;a[C>>0]=a[(q&15)+(35243+(q>>>4<<4))>>0]|0;q=d[H>>0]|0;a[H>>0]=a[(q&15)+(35243+(q>>>4<<4))>>0]|0;v=v&255;v=a[(v&15)+(35243+(v>>>4<<4))>>0]|0;t=t&255;t=a[(t&15)+(35243+(t>>>4<<4))>>0]|0;r=r&255;a[D>>0]=a[(r&15)+(35243+(r>>>4<<4))>>0]|0;g=g&255;a[I>>0]=a[(g&15)+(35243+(g>>>4<<4))>>0]|0;w=w&255;w=a[(w&15)+(35243+(w>>>4<<4))>>0]|0;Q=Q&255;Q=a[(Q&15)+(35243+(Q>>>4<<4))>>0]|0;O=O&255;O=a[(O&15)+(35243+(O>>>4<<4))>>0]|0;R=R&255;a[J>>0]=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;s=s&255;s=a[(s&15)+(35243+(s>>>4<<4))>>0]|0;P=P&255;P=a[(P&15)+(35243+(P>>>4<<4))>>0]|0;S=S&255;S=a[(S&15)+(35243+(S>>>4<<4))>>0]|0;R=d[x>>0]|0;R=a[(R&15)+(35243+(R>>>4<<4))>>0]|0;g=c[f>>2]|0;u=(u&255^g>>>24)&255;a[M>>0]=u;v=(v&255^g>>>16)&255;a[E>>0]=v;w=(w&255^g>>>8)&255;a[K>>0]=w;g=(s&255^g)&255;a[L>>0]=g;M=c[f+4>>2]|0;x=((d[y>>0]|0)^M>>>24)&255;a[y>>0]=x;y=(t&255^M>>>16)&255;a[z>>0]=y;z=(Q&255^M>>>8)&255;a[A>>0]=z;A=(P&255^M)&255;a[B>>0]=A;M=c[f+8>>2]|0;E=((d[C>>0]|0)^M>>>24)&255;a[C>>0]=E;K=((d[D>>0]|0)^M>>>16)&255;a[D>>0]=K;L=(O&255^M>>>8)&255;a[F>>0]=L;M=(S&255^M)&255;a[G>>0]=M;S=c[f+12>>2]|0;O=((d[H>>0]|0)^S>>>24)&255;a[H>>0]=O;P=((d[I>>0]|0)^S>>>16)&255;a[I>>0]=P;Q=((d[J>>0]|0)^S>>>8)&255;a[e>>0]=u;a[e+1>>0]=v;a[e+2>>0]=w;a[e+3>>0]=g;a[e+4>>0]=x;a[e+5>>0]=y;a[e+6>>0]=z;a[e+7>>0]=A;a[e+8>>0]=E;a[e+9>>0]=K;a[e+10>>0]=L;a[e+11>>0]=M;a[e+12>>0]=O;a[e+13>>0]=P;a[e+14>>0]=Q;a[e+15>>0]=R&255^S;i=N;return}function Gh(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Ob=0,Pb=0,Qb=0;Hb=i;i=i+2640|0;Gb=Hb+2456|0;xb=Hb+2304|0;Cb=Hb+2152|0;wb=Hb+2e3|0;ub=Hb+1848|0;vb=Hb+1696|0;Db=Hb+1544|0;yb=Hb+1392|0;zb=Hb+1240|0;Ab=Hb+1088|0;g=Hb+936|0;h=Hb+784|0;j=Hb+632|0;k=Hb+480|0;n=Hb+328|0;sb=Hb+248|0;Bb=Hb+168|0;Fb=Hb+80|0;Eb=Hb;tb=Hb+2608|0;$=tb;o=e;Z=$+32|0;do{a[$>>0]=a[o>>0]|0;$=$+1|0;o=o+1|0}while(($|0)<(Z|0));a[tb>>0]=(d[tb>>0]|0)&248;$=tb+31|0;a[$>>0]=(d[$>>0]|0)&63|64;$=d[f>>0]|0;ob=Uh(d[f+1>>0]|0|0,0,8)|0;nb=C;qb=Uh(d[f+2>>0]|0|0,0,16)|0;nb=nb|C;pb=d[f+3>>0]|0;Z=Uh(pb|0,0,24)|0;rb=sb;c[rb>>2]=ob|$|qb|Z&50331648;c[rb+4>>2]=nb;rb=Uh(d[f+4>>0]|0|0,0,8)|0;nb=C;Z=Uh(d[f+5>>0]|0|0,0,16)|0;nb=nb|C;qb=d[f+6>>0]|0;$=Uh(qb|0,0,24)|0;nb=Th(rb|pb|Z|$|0,nb|C|0,2)|0;$=sb+8|0;c[$>>2]=nb&33554431;c[$+4>>2]=0;$=Uh(d[f+7>>0]|0|0,0,8)|0;nb=C;Z=Uh(d[f+8>>0]|0|0,0,16)|0;nb=nb|C;pb=d[f+9>>0]|0;rb=Uh(pb|0,0,24)|0;nb=Th($|qb|Z|rb|0,nb|C|0,3)|0;rb=sb+16|0;c[rb>>2]=nb&67108863;c[rb+4>>2]=0;rb=Uh(d[f+10>>0]|0|0,0,8)|0;nb=C;Z=Uh(d[f+11>>0]|0|0,0,16)|0;nb=nb|C;qb=d[f+12>>0]|0;$=Uh(qb|0,0,24)|0;nb=Th(rb|pb|Z|$|0,nb|C|0,5)|0;$=sb+24|0;c[$>>2]=nb&33554431;c[$+4>>2]=0;$=Uh(d[f+13>>0]|0|0,0,8)|0;nb=C;Z=Uh(d[f+14>>0]|0|0,0,16)|0;nb=nb|C;pb=Uh(d[f+15>>0]|0|0,0,24)|0;nb=Th($|qb|Z|pb|0,nb|C|0,6)|0;pb=sb+32|0;c[pb>>2]=nb&67108863;c[pb+4>>2]=0;pb=d[f+16>>0]|0;nb=Uh(d[f+17>>0]|0|0,0,8)|0;Z=C;qb=Uh(d[f+18>>0]|0|0,0,16)|0;Z=Z|C;$=d[f+19>>0]|0;rb=Uh($|0,0,24)|0;ob=sb+40|0;c[ob>>2]=nb|pb|qb|rb&16777216;c[ob+4>>2]=Z;ob=Uh(d[f+20>>0]|0|0,0,8)|0;Z=C;rb=Uh(d[f+21>>0]|0|0,0,16)|0;Z=Z|C;qb=d[f+22>>0]|0;pb=Uh(qb|0,0,24)|0;Z=Th(ob|$|rb|pb|0,Z|C|0,1)|0;pb=sb+48|0;c[pb>>2]=Z&67108863;c[pb+4>>2]=0;pb=Uh(d[f+23>>0]|0|0,0,8)|0;Z=C;rb=Uh(d[f+24>>0]|0|0,0,16)|0;Z=Z|C;$=d[f+25>>0]|0;ob=Uh($|0,0,24)|0;Z=Th(pb|qb|rb|ob|0,Z|C|0,3)|0;ob=sb+56|0;c[ob>>2]=Z&33554431;c[ob+4>>2]=0;ob=Uh(d[f+26>>0]|0|0,0,8)|0;Z=C;rb=Uh(d[f+27>>0]|0|0,0,16)|0;Z=Z|C;qb=d[f+28>>0]|0;pb=Uh(qb|0,0,24)|0;Z=Th(ob|$|rb|pb|0,Z|C|0,4)|0;pb=sb+64|0;c[pb>>2]=Z&67108863;c[pb+4>>2]=0;pb=Uh(d[f+29>>0]|0|0,0,8)|0;Z=C;rb=Uh(d[f+30>>0]|0|0,0,16)|0;Z=Z|C;$=Uh(d[f+31>>0]|0|0,0,24)|0;Z=Th(pb|qb|rb|$|0,Z|C|0,6)|0;$=sb+72|0;c[$>>2]=Z&33554431;c[$+4>>2]=0;Sh(zb|0,0,152)|0;$=zb;c[$>>2]=1;c[$+4>>2]=0;Sh(Ab|0,0,152)|0;$=Ab;c[$>>2]=1;c[$+4>>2]=0;Sh(g|0,0,152)|0;Sh(h|0,0,152)|0;Sh(j|0,0,152)|0;$=j;c[$>>2]=1;c[$+4>>2]=0;Sh(k|0,0,152)|0;Sh(n|0,0,152)|0;$=n;c[$>>2]=1;c[$+4>>2]=0;$=yb+80|0;Z=$+72|0;do{c[$>>2]=0;$=$+4|0}while(($|0)<(Z|0));$=yb;o=sb;Z=$+80|0;do{c[$>>2]=c[o>>2];$=$+4|0;o=o+4|0}while(($|0)<(Z|0));ia=wb+144|0;ja=wb+64|0;ka=wb+136|0;la=wb+56|0;ma=wb+128|0;na=wb+48|0;oa=wb+120|0;pa=wb+40|0;qa=wb+112|0;ra=wb+32|0;sa=wb+104|0;ta=wb+24|0;ua=wb+96|0;va=wb+16|0;wa=wb+88|0;xa=wb+8|0;ya=wb+80|0;za=ub+144|0;Aa=ub+64|0;Ba=ub+136|0;Ca=ub+56|0;Da=ub+128|0;Ea=ub+48|0;Fa=ub+120|0;Ga=ub+40|0;Ha=ub+112|0;Ia=ub+32|0;Ja=ub+104|0;Ka=ub+24|0;La=ub+96|0;Ma=ub+16|0;Na=ub+88|0;Oa=ub+8|0;Pa=ub+80|0;Qa=wb+72|0;Ra=ub+72|0;Sa=xb+8|0;Ta=Cb+8|0;Ua=xb+16|0;Va=Cb+16|0;Wa=xb+24|0;Xa=Cb+24|0;Ya=xb+32|0;Za=Cb+32|0;_a=xb+40|0;$a=Cb+40|0;ab=xb+48|0;bb=Cb+48|0;cb=xb+56|0;db=Cb+56|0;eb=xb+64|0;fb=Cb+64|0;gb=xb+72|0;hb=Cb+72|0;ib=Gb+80|0;jb=Gb+8|0;kb=Gb+16|0;lb=Gb+24|0;mb=Gb+32|0;nb=Gb+40|0;ob=Gb+48|0;pb=Gb+56|0;qb=Gb+64|0;rb=Gb+72|0;f=0;l=yb;m=zb;e=Ab;do{o=a[tb+(31-f)>>0]|0;ha=0;da=h;ea=j;fa=k;ga=n;while(1){aa=o&255;ba=Ph(0,0,aa>>>7|0,0)|0;ca=C;h=0;do{V=e+(h<<3)|0;T=V;U=c[T>>2]|0;T=c[T+4>>2]|0;$=l+(h<<3)|0;X=$;Z=c[X>>2]|0;X=c[X+4>>2]|0;Y=(Z^U)&ba;W=(X^T)&ca;U=Rh(0,Y^U|0,32)|0;c[V>>2]=U;c[V+4>>2]=C;Z=Rh(0,Y^Z|0,32)|0;c[$>>2]=Z;c[$+4>>2]=C;h=h+1|0}while((h|0)!=10);h=0;do{V=g+(h<<3)|0;T=V;U=c[T>>2]|0;T=c[T+4>>2]|0;$=m+(h<<3)|0;X=$;Z=c[X>>2]|0;X=c[X+4>>2]|0;Y=(Z^U)&ba;W=(X^T)&ca;U=Rh(0,Y^U|0,32)|0;c[V>>2]=U;c[V+4>>2]=C;Z=Rh(0,Y^Z|0,32)|0;c[$>>2]=Z;c[$+4>>2]=C;h=h+1|0}while((h|0)!=10);W=e;j=c[W>>2]|0;W=c[W+4>>2]|0;r=e+8|0;M=r;S=c[M>>2]|0;M=c[M+4>>2]|0;Lb=e+16|0;D=Lb;B=c[D>>2]|0;D=c[D+4>>2]|0;U=e+24|0;Ib=U;s=c[Ib>>2]|0;Ib=c[Ib+4>>2]|0;Y=e+32|0;Z=Y;Mb=c[Z>>2]|0;Z=c[Z+4>>2]|0;G=e+40|0;h=G;V=c[h>>2]|0;h=c[h+4>>2]|0;u=e+48|0;L=u;K=c[L>>2]|0;L=c[L+4>>2]|0;y=e+56|0;z=y;O=c[z>>2]|0;z=c[z+4>>2]|0;Nb=e+64|0;E=Nb;v=c[E>>2]|0;E=c[E+4>>2]|0;k=e+72|0;Jb=k;Kb=c[Jb>>2]|0;Jb=c[Jb+4>>2]|0;X=g;R=c[X>>2]|0;X=c[X+4>>2]|0;H=Qh(R|0,X|0,j|0,W|0)|0;I=e;c[I>>2]=H;c[I+4>>2]=C;I=g+8|0;H=I;N=c[H>>2]|0;H=c[H+4>>2]|0;x=Qh(N|0,H|0,S|0,M|0)|0;c[r>>2]=x;c[r+4>>2]=C;r=g+16|0;x=r;w=c[x>>2]|0;x=c[x+4>>2]|0;n=Qh(w|0,x|0,B|0,D|0)|0;c[Lb>>2]=n;c[Lb+4>>2]=C;Lb=g+24|0;n=Lb;o=c[n>>2]|0;n=c[n+4>>2]|0;Pb=Qh(o|0,n|0,s|0,Ib|0)|0;c[U>>2]=Pb;c[U+4>>2]=C;U=g+32|0;Pb=U;$=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;Q=Qh($|0,Pb|0,Mb|0,Z|0)|0;c[Y>>2]=Q;c[Y+4>>2]=C;Y=g+40|0;Q=Y;P=c[Q>>2]|0;Q=c[Q+4>>2]|0;F=Qh(P|0,Q|0,V|0,h|0)|0;c[G>>2]=F;c[G+4>>2]=C;G=g+48|0;F=G;T=c[F>>2]|0;F=c[F+4>>2]|0;J=Qh(T|0,F|0,K|0,L|0)|0;c[u>>2]=J;c[u+4>>2]=C;u=g+56|0;J=u;A=c[J>>2]|0;J=c[J+4>>2]|0;q=Qh(A|0,J|0,O|0,z|0)|0;c[y>>2]=q;c[y+4>>2]=C;y=g+64|0;q=y;p=c[q>>2]|0;q=c[q+4>>2]|0;Ob=Qh(p|0,q|0,v|0,E|0)|0;c[Nb>>2]=Ob;c[Nb+4>>2]=C;Nb=g+72|0;Ob=Nb;t=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;Qb=Qh(t|0,Ob|0,Kb|0,Jb|0)|0;c[k>>2]=Qb;c[k+4>>2]=C;X=Ph(j|0,W|0,R|0,X|0)|0;R=g;c[R>>2]=X;c[R+4>>2]=C;H=Ph(S|0,M|0,N|0,H|0)|0;c[I>>2]=H;c[I+4>>2]=C;x=Ph(B|0,D|0,w|0,x|0)|0;c[r>>2]=x;c[r+4>>2]=C;n=Ph(s|0,Ib|0,o|0,n|0)|0;c[Lb>>2]=n;c[Lb+4>>2]=C;Pb=Ph(Mb|0,Z|0,$|0,Pb|0)|0;c[U>>2]=Pb;c[U+4>>2]=C;Q=Ph(V|0,h|0,P|0,Q|0)|0;c[Y>>2]=Q;c[Y+4>>2]=C;F=Ph(K|0,L|0,T|0,F|0)|0;c[G>>2]=F;c[G+4>>2]=C;J=Ph(O|0,z|0,A|0,J|0)|0;c[u>>2]=J;c[u+4>>2]=C;q=Ph(v|0,E|0,p|0,q|0)|0;c[y>>2]=q;c[y+4>>2]=C;Ob=Ph(Kb|0,Jb|0,t|0,Ob|0)|0;c[Nb>>2]=Ob;c[Nb+4>>2]=C;Nb=l;Ob=c[Nb>>2]|0;Nb=c[Nb+4>>2]|0;t=l+8|0;Jb=t;Kb=c[Jb>>2]|0;Jb=c[Jb+4>>2]|0;y=l+16|0;q=y;p=c[q>>2]|0;q=c[q+4>>2]|0;E=l+24|0;v=E;u=c[v>>2]|0;v=c[v+4>>2]|0;J=l+32|0;A=J;z=c[A>>2]|0;A=c[A+4>>2]|0;O=l+40|0;G=O;F=c[G>>2]|0;G=c[G+4>>2]|0;T=l+48|0;L=T;K=c[L>>2]|0;L=c[L+4>>2]|0;Y=l+56|0;Q=Y;P=c[Q>>2]|0;Q=c[Q+4>>2]|0;h=l+64|0;V=h;U=c[V>>2]|0;V=c[V+4>>2]|0;Pb=l+72|0;$=Pb;Z=c[$>>2]|0;$=c[$+4>>2]|0;Mb=m;Lb=c[Mb>>2]|0;Mb=c[Mb+4>>2]|0;n=Qh(Lb|0,Mb|0,Ob|0,Nb|0)|0;o=l;c[o>>2]=n;c[o+4>>2]=C;o=m+8|0;n=o;Ib=c[n>>2]|0;n=c[n+4>>2]|0;s=Qh(Ib|0,n|0,Kb|0,Jb|0)|0;c[t>>2]=s;c[t+4>>2]=C;t=m+16|0;s=t;r=c[s>>2]|0;s=c[s+4>>2]|0;x=Qh(r|0,s|0,p|0,q|0)|0;c[y>>2]=x;c[y+4>>2]=C;y=m+24|0;x=y;w=c[x>>2]|0;x=c[x+4>>2]|0;D=Qh(w|0,x|0,u|0,v|0)|0;c[E>>2]=D;c[E+4>>2]=C;E=m+32|0;D=E;B=c[D>>2]|0;D=c[D+4>>2]|0;I=Qh(B|0,D|0,z|0,A|0)|0;c[J>>2]=I;c[J+4>>2]=C;J=m+40|0;I=J;H=c[I>>2]|0;I=c[I+4>>2]|0;N=Qh(H|0,I|0,F|0,G|0)|0;c[O>>2]=N;c[O+4>>2]=C;O=m+48|0;N=O;M=c[N>>2]|0;N=c[N+4>>2]|0;S=Qh(M|0,N|0,K|0,L|0)|0;c[T>>2]=S;c[T+4>>2]=C;T=m+56|0;S=T;R=c[S>>2]|0;S=c[S+4>>2]|0;X=Qh(R|0,S|0,P|0,Q|0)|0;c[Y>>2]=X;c[Y+4>>2]=C;Y=m+64|0;X=Y;W=c[X>>2]|0;X=c[X+4>>2]|0;j=Qh(W|0,X|0,U|0,V|0)|0;c[h>>2]=j;c[h+4>>2]=C;h=m+72|0;j=h;k=c[j>>2]|0;j=c[j+4>>2]|0;Qb=Qh(k|0,j|0,Z|0,$|0)|0;c[Pb>>2]=Qb;c[Pb+4>>2]=C;Mb=Ph(Ob|0,Nb|0,Lb|0,Mb|0)|0;Lb=m;c[Lb>>2]=Mb;c[Lb+4>>2]=C;n=Ph(Kb|0,Jb|0,Ib|0,n|0)|0;c[o>>2]=n;c[o+4>>2]=C;s=Ph(p|0,q|0,r|0,s|0)|0;c[t>>2]=s;c[t+4>>2]=C;x=Ph(u|0,v|0,w|0,x|0)|0;c[y>>2]=x;c[y+4>>2]=C;D=Ph(z|0,A|0,B|0,D|0)|0;c[E>>2]=D;c[E+4>>2]=C;I=Ph(F|0,G|0,H|0,I|0)|0;c[J>>2]=I;c[J+4>>2]=C;N=Ph(K|0,L|0,M|0,N|0)|0;c[O>>2]=N;c[O+4>>2]=C;S=Ph(P|0,Q|0,R|0,S|0)|0;c[T>>2]=S;c[T+4>>2]=C;X=Ph(U|0,V|0,W|0,X|0)|0;c[Y>>2]=X;c[Y+4>>2]=C;j=Ph(Z|0,$|0,k|0,j|0)|0;c[h>>2]=j;c[h+4>>2]=C;Hh(wb,l,g);Hh(ub,e,m);h=ia;j=c[h>>2]|0;h=c[h+4>>2]|0;k=ja;$=c[k>>2]|0;k=c[k+4>>2]|0;Z=_h(j|0,h|0,18,0)|0;Y=C;h=Qh($|0,k|0,j|0,h|0)|0;Y=Qh(h|0,C|0,Z|0,Y|0)|0;Z=ja;c[Z>>2]=Y;c[Z+4>>2]=C;Z=ka;Y=c[Z>>2]|0;Z=c[Z+4>>2]|0;h=la;j=c[h>>2]|0;h=c[h+4>>2]|0;k=_h(Y|0,Z|0,18,0)|0;$=C;Z=Qh(j|0,h|0,Y|0,Z|0)|0;$=Qh(Z|0,C|0,k|0,$|0)|0;k=la;c[k>>2]=$;c[k+4>>2]=C;k=ma;$=c[k>>2]|0;k=c[k+4>>2]|0;Z=na;Y=c[Z>>2]|0;Z=c[Z+4>>2]|0;h=_h($|0,k|0,18,0)|0;j=C;k=Qh(Y|0,Z|0,$|0,k|0)|0;j=Qh(k|0,C|0,h|0,j|0)|0;h=na;c[h>>2]=j;c[h+4>>2]=C;h=oa;j=c[h>>2]|0;h=c[h+4>>2]|0;k=pa;$=c[k>>2]|0;k=c[k+4>>2]|0;Z=_h(j|0,h|0,18,0)|0;Y=C;h=Qh($|0,k|0,j|0,h|0)|0;Y=Qh(h|0,C|0,Z|0,Y|0)|0;Z=pa;c[Z>>2]=Y;c[Z+4>>2]=C;Z=qa;Y=c[Z>>2]|0;Z=c[Z+4>>2]|0;h=ra;j=c[h>>2]|0;h=c[h+4>>2]|0;k=_h(Y|0,Z|0,18,0)|0;$=C;Z=Qh(j|0,h|0,Y|0,Z|0)|0;$=Qh(Z|0,C|0,k|0,$|0)|0;k=ra;c[k>>2]=$;c[k+4>>2]=C;k=sa;$=c[k>>2]|0;k=c[k+4>>2]|0;Z=ta;Y=c[Z>>2]|0;Z=c[Z+4>>2]|0;h=_h($|0,k|0,18,0)|0;j=C;k=Qh(Y|0,Z|0,$|0,k|0)|0;j=Qh(k|0,C|0,h|0,j|0)|0;h=ta;c[h>>2]=j;c[h+4>>2]=C;h=ua;j=c[h>>2]|0;h=c[h+4>>2]|0;k=va;$=c[k>>2]|0;k=c[k+4>>2]|0;Z=_h(j|0,h|0,18,0)|0;Y=C;h=Qh($|0,k|0,j|0,h|0)|0;Y=Qh(h|0,C|0,Z|0,Y|0)|0;Z=va;c[Z>>2]=Y;c[Z+4>>2]=C;Z=wa;Y=c[Z>>2]|0;Z=c[Z+4>>2]|0;h=xa;j=c[h>>2]|0;h=c[h+4>>2]|0;k=_h(Y|0,Z|0,18,0)|0;$=C;Z=Qh(j|0,h|0,Y|0,Z|0)|0;$=Qh(Z|0,C|0,k|0,$|0)|0;k=xa;c[k>>2]=$;c[k+4>>2]=C;k=ya;$=c[k>>2]|0;k=c[k+4>>2]|0;Z=wb;Y=c[Z>>2]|0;Z=c[Z+4>>2]|0;h=_h($|0,k|0,18,0)|0;j=C;k=Qh(Y|0,Z|0,$|0,k|0)|0;j=Qh(k|0,C|0,h|0,j|0)|0;h=C;k=wb;c[k>>2]=j;c[k+4>>2]=h;k=ya;c[k>>2]=0;c[k+4>>2]=0;k=0;do{Nb=Qh(h>>31>>>6|0,0,j|0,h|0)|0;Nb=Rh(Nb|0,C|0,26)|0;Mb=C;Lb=Uh(Nb|0,Mb|0,26)|0;Lb=Ph(j|0,h|0,Lb|0,C|0)|0;Qb=wb+(k<<3)|0;c[Qb>>2]=Lb;c[Qb+4>>2]=C;Qb=wb+((k|1)<<3)|0;Lb=Qb;Lb=Qh(Nb|0,Mb|0,c[Lb>>2]|0,c[Lb+4>>2]|0)|0;Mb=C;Nb=Qh(Mb>>31>>>7|0,0,Lb|0,Mb|0)|0;Nb=Rh(Nb|0,C|0,25)|0;Ob=C;Pb=Uh(Nb|0,Ob|0,25)|0;Pb=Ph(Lb|0,Mb|0,Pb|0,C|0)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;k=k+2|0;Qb=wb+(k<<3)|0;Pb=Qb;j=Qh(Nb|0,Ob|0,c[Pb>>2]|0,c[Pb+4>>2]|0)|0;h=C;c[Qb>>2]=j;c[Qb+4>>2]=h}while(k>>>0<10);o=ya;n=c[o>>2]|0;o=c[o+4>>2]|0;h=wb;p=c[h>>2]|0;h=c[h+4>>2]|0;j=_h(n|0,o|0,18,0)|0;k=C;o=Qh(p|0,h|0,n|0,o|0)|0;k=Qh(o|0,C|0,j|0,k|0)|0;j=C;o=ya;c[o>>2]=0;c[o+4>>2]=0;o=Qh(j>>31>>>6|0,0,k|0,j|0)|0;o=Rh(o|0,C|0,26)|0;n=C;h=Uh(o|0,n|0,26)|0;h=Ph(k|0,j|0,h|0,C|0)|0;j=C;k=wb;c[k>>2]=h;c[k+4>>2]=j;k=xa;k=Qh(o|0,n|0,c[k>>2]|0,c[k+4>>2]|0)|0;n=C;o=xa;c[o>>2]=k;c[o+4>>2]=n;o=za;p=c[o>>2]|0;o=c[o+4>>2]|0;q=Aa;Qb=c[q>>2]|0;q=c[q+4>>2]|0;Pb=_h(p|0,o|0,18,0)|0;Ob=C;o=Qh(Qb|0,q|0,p|0,o|0)|0;Ob=Qh(o|0,C|0,Pb|0,Ob|0)|0;Pb=Aa;c[Pb>>2]=Ob;c[Pb+4>>2]=C;Pb=Ba;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;o=Ca;p=c[o>>2]|0;o=c[o+4>>2]|0;q=_h(Ob|0,Pb|0,18,0)|0;Qb=C;Pb=Qh(p|0,o|0,Ob|0,Pb|0)|0;Qb=Qh(Pb|0,C|0,q|0,Qb|0)|0;q=Ca;c[q>>2]=Qb;c[q+4>>2]=C;q=Da;Qb=c[q>>2]|0;q=c[q+4>>2]|0;Pb=Ea;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;o=_h(Qb|0,q|0,18,0)|0;p=C;q=Qh(Ob|0,Pb|0,Qb|0,q|0)|0;p=Qh(q|0,C|0,o|0,p|0)|0;o=Ea;c[o>>2]=p;c[o+4>>2]=C;o=Fa;p=c[o>>2]|0;o=c[o+4>>2]|0;q=Ga;Qb=c[q>>2]|0;q=c[q+4>>2]|0;Pb=_h(p|0,o|0,18,0)|0;Ob=C;o=Qh(Qb|0,q|0,p|0,o|0)|0;Ob=Qh(o|0,C|0,Pb|0,Ob|0)|0;Pb=Ga;c[Pb>>2]=Ob;c[Pb+4>>2]=C;Pb=Ha;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;o=Ia;p=c[o>>2]|0;o=c[o+4>>2]|0;q=_h(Ob|0,Pb|0,18,0)|0;Qb=C;Pb=Qh(p|0,o|0,Ob|0,Pb|0)|0;Qb=Qh(Pb|0,C|0,q|0,Qb|0)|0;q=Ia;c[q>>2]=Qb;c[q+4>>2]=C;q=Ja;Qb=c[q>>2]|0;q=c[q+4>>2]|0;Pb=Ka;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;o=_h(Qb|0,q|0,18,0)|0;p=C;q=Qh(Ob|0,Pb|0,Qb|0,q|0)|0;p=Qh(q|0,C|0,o|0,p|0)|0;o=Ka;c[o>>2]=p;c[o+4>>2]=C;o=La;p=c[o>>2]|0;o=c[o+4>>2]|0;q=Ma;Qb=c[q>>2]|0;q=c[q+4>>2]|0;Pb=_h(p|0,o|0,18,0)|0;Ob=C;o=Qh(Qb|0,q|0,p|0,o|0)|0;Ob=Qh(o|0,C|0,Pb|0,Ob|0)|0;Pb=Ma;c[Pb>>2]=Ob;c[Pb+4>>2]=C;Pb=Na;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;o=Oa;p=c[o>>2]|0;o=c[o+4>>2]|0;q=_h(Ob|0,Pb|0,18,0)|0;Qb=C;Pb=Qh(p|0,o|0,Ob|0,Pb|0)|0;Qb=Qh(Pb|0,C|0,q|0,Qb|0)|0;q=Oa;c[q>>2]=Qb;c[q+4>>2]=C;q=Pa;Qb=c[q>>2]|0;q=c[q+4>>2]|0;Pb=ub;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;o=_h(Qb|0,q|0,18,0)|0;p=C;q=Qh(Ob|0,Pb|0,Qb|0,q|0)|0;p=Qh(q|0,C|0,o|0,p|0)|0;o=C;q=ub;c[q>>2]=p;c[q+4>>2]=o;q=Pa;c[q>>2]=0;c[q+4>>2]=0;q=0;do{Nb=Qh(o>>31>>>6|0,0,p|0,o|0)|0;Nb=Rh(Nb|0,C|0,26)|0;Mb=C;Lb=Uh(Nb|0,Mb|0,26)|0;Lb=Ph(p|0,o|0,Lb|0,C|0)|0;Qb=ub+(q<<3)|0;c[Qb>>2]=Lb;c[Qb+4>>2]=C;Qb=ub+((q|1)<<3)|0;Lb=Qb;Lb=Qh(Nb|0,Mb|0,c[Lb>>2]|0,c[Lb+4>>2]|0)|0;Mb=C;Nb=Qh(Mb>>31>>>7|0,0,Lb|0,Mb|0)|0;Nb=Rh(Nb|0,C|0,25)|0;Ob=C;Pb=Uh(Nb|0,Ob|0,25)|0;Pb=Ph(Lb|0,Mb|0,Pb|0,C|0)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;q=q+2|0;Qb=ub+(q<<3)|0;Pb=Qb;p=Qh(Nb|0,Ob|0,c[Pb>>2]|0,c[Pb+4>>2]|0)|0;o=C;c[Qb>>2]=p;c[Qb+4>>2]=o}while(q>>>0<10);F=Pa;D=c[F>>2]|0;F=c[F+4>>2]|0;z=ub;E=c[z>>2]|0;z=c[z+4>>2]|0;A=_h(D|0,F|0,18,0)|0;B=C;F=Qh(E|0,z|0,D|0,F|0)|0;B=Qh(F|0,C|0,A|0,B|0)|0;A=C;F=Pa;c[F>>2]=0;c[F+4>>2]=0;F=Qh(A>>31>>>6|0,0,B|0,A|0)|0;F=Rh(F|0,C|0,26)|0;D=C;z=Uh(F|0,D|0,26)|0;z=Ph(B|0,A|0,z|0,C|0)|0;A=C;B=Oa;B=Qh(F|0,D|0,c[B>>2]|0,c[B+4>>2]|0)|0;D=C;F=va;E=c[F>>2]|0;F=c[F+4>>2]|0;J=ta;I=c[J>>2]|0;J=c[J+4>>2]|0;N=ra;M=c[N>>2]|0;N=c[N+4>>2]|0;R=pa;Q=c[R>>2]|0;R=c[R+4>>2]|0;V=na;U=c[V>>2]|0;V=c[V+4>>2]|0;Z=la;Y=c[Z>>2]|0;Z=c[Z+4>>2]|0;Kb=ja;Jb=c[Kb>>2]|0;Kb=c[Kb+4>>2]|0;Ob=Qa;Nb=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;H=Qh(z|0,A|0,h|0,j|0)|0;G=wb;c[G>>2]=H;c[G+4>>2]=C;G=Qh(B|0,D|0,k|0,n|0)|0;H=xa;c[H>>2]=G;c[H+4>>2]=C;H=Ma;G=c[H>>2]|0;H=c[H+4>>2]|0;K=Qh(G|0,H|0,E|0,F|0)|0;L=va;c[L>>2]=K;c[L+4>>2]=C;L=Ka;K=c[L>>2]|0;L=c[L+4>>2]|0;O=Qh(K|0,L|0,I|0,J|0)|0;P=ta;c[P>>2]=O;c[P+4>>2]=C;P=Ia;O=c[P>>2]|0;P=c[P+4>>2]|0;S=Qh(O|0,P|0,M|0,N|0)|0;T=ra;c[T>>2]=S;c[T+4>>2]=C;T=Ga;S=c[T>>2]|0;T=c[T+4>>2]|0;W=Qh(S|0,T|0,Q|0,R|0)|0;X=pa;c[X>>2]=W;c[X+4>>2]=C;X=Ea;W=c[X>>2]|0;X=c[X+4>>2]|0;$=Qh(W|0,X|0,U|0,V|0)|0;Ib=na;c[Ib>>2]=$;c[Ib+4>>2]=C;Ib=Ca;$=c[Ib>>2]|0;Ib=c[Ib+4>>2]|0;Lb=Qh($|0,Ib|0,Y|0,Z|0)|0;Mb=la;c[Mb>>2]=Lb;c[Mb+4>>2]=C;Mb=Aa;Lb=c[Mb>>2]|0;Mb=c[Mb+4>>2]|0;Pb=Qh(Lb|0,Mb|0,Jb|0,Kb|0)|0;Qb=ja;c[Qb>>2]=Pb;c[Qb+4>>2]=C;Qb=Ra;Pb=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;x=Qh(Pb|0,Qb|0,Nb|0,Ob|0)|0;y=Qa;c[y>>2]=x;c[y+4>>2]=C;h=Ph(h|0,j|0,z|0,A|0)|0;j=ub;c[j>>2]=h;c[j+4>>2]=C;j=Ph(k|0,n|0,B|0,D|0)|0;h=Oa;c[h>>2]=j;c[h+4>>2]=C;h=Ph(E|0,F|0,G|0,H|0)|0;j=Ma;c[j>>2]=h;c[j+4>>2]=C;j=Ph(I|0,J|0,K|0,L|0)|0;h=Ka;c[h>>2]=j;c[h+4>>2]=C;h=Ph(M|0,N|0,O|0,P|0)|0;j=Ia;c[j>>2]=h;c[j+4>>2]=C;j=Ph(Q|0,R|0,S|0,T|0)|0;h=Ga;c[h>>2]=j;c[h+4>>2]=C;h=Ph(U|0,V|0,W|0,X|0)|0;j=Ea;c[j>>2]=h;c[j+4>>2]=C;j=Ph(Y|0,Z|0,$|0,Ib|0)|0;h=Ca;c[h>>2]=j;c[h+4>>2]=C;h=Ph(Jb|0,Kb|0,Lb|0,Mb|0)|0;j=Aa;c[j>>2]=h;c[j+4>>2]=C;j=Ph(Nb|0,Ob|0,Pb|0,Qb|0)|0;h=Ra;c[h>>2]=j;c[h+4>>2]=C;Ih(Db,wb);Ih(vb,ub);Hh(ub,vb,sb);h=za;j=c[h>>2]|0;h=c[h+4>>2]|0;k=Aa;Qb=c[k>>2]|0;k=c[k+4>>2]|0;Pb=_h(j|0,h|0,18,0)|0;Ob=C;h=Qh(Qb|0,k|0,j|0,h|0)|0;Ob=Qh(h|0,C|0,Pb|0,Ob|0)|0;Pb=Aa;c[Pb>>2]=Ob;c[Pb+4>>2]=C;Pb=Ba;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;h=Ca;j=c[h>>2]|0;h=c[h+4>>2]|0;k=_h(Ob|0,Pb|0,18,0)|0;Qb=C;Pb=Qh(j|0,h|0,Ob|0,Pb|0)|0;Qb=Qh(Pb|0,C|0,k|0,Qb|0)|0;k=Ca;c[k>>2]=Qb;c[k+4>>2]=C;k=Da;Qb=c[k>>2]|0;k=c[k+4>>2]|0;Pb=Ea;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;h=_h(Qb|0,k|0,18,0)|0;j=C;k=Qh(Ob|0,Pb|0,Qb|0,k|0)|0;j=Qh(k|0,C|0,h|0,j|0)|0;h=Ea;c[h>>2]=j;c[h+4>>2]=C;h=Fa;j=c[h>>2]|0;h=c[h+4>>2]|0;k=Ga;Qb=c[k>>2]|0;k=c[k+4>>2]|0;Pb=_h(j|0,h|0,18,0)|0;Ob=C;h=Qh(Qb|0,k|0,j|0,h|0)|0;Ob=Qh(h|0,C|0,Pb|0,Ob|0)|0;Pb=Ga;c[Pb>>2]=Ob;c[Pb+4>>2]=C;Pb=Ha;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;h=Ia;j=c[h>>2]|0;h=c[h+4>>2]|0;k=_h(Ob|0,Pb|0,18,0)|0;Qb=C;Pb=Qh(j|0,h|0,Ob|0,Pb|0)|0;Qb=Qh(Pb|0,C|0,k|0,Qb|0)|0;k=Ia;c[k>>2]=Qb;c[k+4>>2]=C;k=Ja;Qb=c[k>>2]|0;k=c[k+4>>2]|0;Pb=Ka;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;h=_h(Qb|0,k|0,18,0)|0;j=C;k=Qh(Ob|0,Pb|0,Qb|0,k|0)|0;j=Qh(k|0,C|0,h|0,j|0)|0;h=Ka;c[h>>2]=j;c[h+4>>2]=C;h=La;j=c[h>>2]|0;h=c[h+4>>2]|0;k=Ma;Qb=c[k>>2]|0;k=c[k+4>>2]|0;Pb=_h(j|0,h|0,18,0)|0;Ob=C;h=Qh(Qb|0,k|0,j|0,h|0)|0;Ob=Qh(h|0,C|0,Pb|0,Ob|0)|0;Pb=Ma;c[Pb>>2]=Ob;c[Pb+4>>2]=C;Pb=Na;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;h=Oa;j=c[h>>2]|0;h=c[h+4>>2]|0;k=_h(Ob|0,Pb|0,18,0)|0;Qb=C;Pb=Qh(j|0,h|0,Ob|0,Pb|0)|0;Qb=Qh(Pb|0,C|0,k|0,Qb|0)|0;k=Oa;c[k>>2]=Qb;c[k+4>>2]=C;k=Pa;Qb=c[k>>2]|0;k=c[k+4>>2]|0;Pb=ub;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;h=_h(Qb|0,k|0,18,0)|0;j=C;k=Qh(Ob|0,Pb|0,Qb|0,k|0)|0;j=Qh(k|0,C|0,h|0,j|0)|0;h=C;k=ub;c[k>>2]=j;c[k+4>>2]=h;k=Pa;c[k>>2]=0;c[k+4>>2]=0;k=0;do{Nb=Qh(h>>31>>>6|0,0,j|0,h|0)|0;Nb=Rh(Nb|0,C|0,26)|0;Mb=C;Lb=Uh(Nb|0,Mb|0,26)|0;Lb=Ph(j|0,h|0,Lb|0,C|0)|0;Qb=ub+(k<<3)|0;c[Qb>>2]=Lb;c[Qb+4>>2]=C;Qb=ub+((k|1)<<3)|0;Lb=Qb;Lb=Qh(Nb|0,Mb|0,c[Lb>>2]|0,c[Lb+4>>2]|0)|0;Mb=C;Nb=Qh(Mb>>31>>>7|0,0,Lb|0,Mb|0)|0;Nb=Rh(Nb|0,C|0,25)|0;Ob=C;Pb=Uh(Nb|0,Ob|0,25)|0;Pb=Ph(Lb|0,Mb|0,Pb|0,C|0)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;k=k+2|0;Qb=ub+(k<<3)|0;Pb=Qb;j=Qh(Nb|0,Ob|0,c[Pb>>2]|0,c[Pb+4>>2]|0)|0;h=C;c[Qb>>2]=j;c[Qb+4>>2]=h}while(k>>>0<10);Z=Pa;$=c[Z>>2]|0;Z=c[Z+4>>2]|0;Qb=ub;Ob=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;o=_h($|0,Z|0,18,0)|0;Pb=C;Z=Qh(Ob|0,Qb|0,$|0,Z|0)|0;Pb=Qh(Z|0,C|0,o|0,Pb|0)|0;o=C;Z=Pa;c[Z>>2]=0;c[Z+4>>2]=0;Z=Qh(o>>31>>>6|0,0,Pb|0,o|0)|0;Z=Rh(Z|0,C|0,26)|0;$=C;Qb=Uh(Z|0,$|0,26)|0;Qb=Ph(Pb|0,o|0,Qb|0,C|0)|0;o=ub;c[o>>2]=Qb;c[o+4>>2]=C;o=Oa;o=Qh(Z|0,$|0,c[o>>2]|0,c[o+4>>2]|0)|0;$=Oa;c[$>>2]=o;c[$+4>>2]=C;$=da;o=Db;Z=$+80|0;do{c[$>>2]=c[o>>2];$=$+4|0;o=o+4|0}while(($|0)<(Z|0));$=ea;o=ub;Z=$+80|0;do{c[$>>2]=c[o>>2];$=$+4|0;o=o+4|0}while(($|0)<(Z|0));Ih(xb,e);Ih(Cb,g);Hh(fa,xb,Cb);h=fa+144|0;k=c[h>>2]|0;h=c[h+4>>2]|0;j=fa+64|0;Qb=j;o=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;Ob=_h(k|0,h|0,18,0)|0;Pb=C;h=Qh(o|0,Qb|0,k|0,h|0)|0;Pb=Qh(h|0,C|0,Ob|0,Pb|0)|0;c[j>>2]=Pb;c[j+4>>2]=C;j=fa+136|0;Pb=c[j>>2]|0;j=c[j+4>>2]|0;Ob=fa+56|0;h=Ob;k=c[h>>2]|0;h=c[h+4>>2]|0;Qb=_h(Pb|0,j|0,18,0)|0;o=C;j=Qh(k|0,h|0,Pb|0,j|0)|0;o=Qh(j|0,C|0,Qb|0,o|0)|0;c[Ob>>2]=o;c[Ob+4>>2]=C;Ob=fa+128|0;o=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;Qb=fa+48|0;j=Qb;Pb=c[j>>2]|0;j=c[j+4>>2]|0;h=_h(o|0,Ob|0,18,0)|0;k=C;Ob=Qh(Pb|0,j|0,o|0,Ob|0)|0;k=Qh(Ob|0,C|0,h|0,k|0)|0;c[Qb>>2]=k;c[Qb+4>>2]=C;Qb=fa+120|0;k=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;h=fa+40|0;Ob=h;o=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;j=_h(k|0,Qb|0,18,0)|0;Pb=C;Qb=Qh(o|0,Ob|0,k|0,Qb|0)|0;Pb=Qh(Qb|0,C|0,j|0,Pb|0)|0;c[h>>2]=Pb;c[h+4>>2]=C;h=fa+112|0;Pb=c[h>>2]|0;h=c[h+4>>2]|0;j=fa+32|0;Qb=j;k=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;Ob=_h(Pb|0,h|0,18,0)|0;o=C;h=Qh(k|0,Qb|0,Pb|0,h|0)|0;o=Qh(h|0,C|0,Ob|0,o|0)|0;c[j>>2]=o;c[j+4>>2]=C;j=fa+104|0;o=c[j>>2]|0;j=c[j+4>>2]|0;Ob=fa+24|0;h=Ob;Pb=c[h>>2]|0;h=c[h+4>>2]|0;Qb=_h(o|0,j|0,18,0)|0;k=C;j=Qh(Pb|0,h|0,o|0,j|0)|0;k=Qh(j|0,C|0,Qb|0,k|0)|0;c[Ob>>2]=k;c[Ob+4>>2]=C;Ob=fa+96|0;k=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;Qb=fa+16|0;j=Qb;o=c[j>>2]|0;j=c[j+4>>2]|0;h=_h(k|0,Ob|0,18,0)|0;Pb=C;Ob=Qh(o|0,j|0,k|0,Ob|0)|0;Pb=Qh(Ob|0,C|0,h|0,Pb|0)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;Qb=fa+88|0;Pb=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;h=fa+8|0;Ob=h;k=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;j=_h(Pb|0,Qb|0,18,0)|0;o=C;Qb=Qh(k|0,Ob|0,Pb|0,Qb|0)|0;o=Qh(Qb|0,C|0,j|0,o|0)|0;j=h;c[j>>2]=o;c[j+4>>2]=C;j=fa+80|0;o=j;Qb=c[o>>2]|0;o=c[o+4>>2]|0;Pb=fa;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;k=_h(Qb|0,o|0,18,0)|0;n=C;o=Qh(Ob|0,Pb|0,Qb|0,o|0)|0;n=Qh(o|0,C|0,k|0,n|0)|0;k=C;o=fa;c[o>>2]=n;c[o+4>>2]=k;o=j;c[o>>2]=0;c[o+4>>2]=0;o=0;do{Nb=Qh(k>>31>>>6|0,0,n|0,k|0)|0;Nb=Rh(Nb|0,C|0,26)|0;Mb=C;Lb=Uh(Nb|0,Mb|0,26)|0;Lb=Ph(n|0,k|0,Lb|0,C|0)|0;Qb=fa+(o<<3)|0;c[Qb>>2]=Lb;c[Qb+4>>2]=C;Qb=fa+((o|1)<<3)|0;Lb=Qb;Lb=Qh(Nb|0,Mb|0,c[Lb>>2]|0,c[Lb+4>>2]|0)|0;Mb=C;Nb=Qh(Mb>>31>>>7|0,0,Lb|0,Mb|0)|0;Nb=Rh(Nb|0,C|0,25)|0;Ob=C;Pb=Uh(Nb|0,Ob|0,25)|0;Pb=Ph(Lb|0,Mb|0,Pb|0,C|0)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;o=o+2|0;Qb=fa+(o<<3)|0;Pb=Qb;n=Qh(Nb|0,Ob|0,c[Pb>>2]|0,c[Pb+4>>2]|0)|0;k=C;c[Qb>>2]=n;c[Qb+4>>2]=k}while(o>>>0<10);G=j;I=c[G>>2]|0;G=c[G+4>>2]|0;k=fa;n=c[k>>2]|0;k=c[k+4>>2]|0;F=_h(I|0,G|0,18,0)|0;H=C;G=Qh(n|0,k|0,I|0,G|0)|0;H=Qh(G|0,C|0,F|0,H|0)|0;F=C;c[j>>2]=0;c[j+4>>2]=0;j=Qh(F>>31>>>6|0,0,H|0,F|0)|0;j=Rh(j|0,C|0,26)|0;G=C;I=Uh(j|0,G|0,26)|0;I=Ph(H|0,F|0,I|0,C|0)|0;F=fa;c[F>>2]=I;c[F+4>>2]=C;F=h;F=Qh(j|0,G|0,c[F>>2]|0,c[F+4>>2]|0)|0;G=h;c[G>>2]=F;c[G+4>>2]=C;G=xb;F=c[G>>2]|0;G=c[G+4>>2]|0;h=Cb;h=Ph(F|0,G|0,c[h>>2]|0,c[h+4>>2]|0)|0;j=C;I=Cb;c[I>>2]=h;c[I+4>>2]=j;I=Sa;H=c[I>>2]|0;I=c[I+4>>2]|0;k=Ta;k=Ph(H|0,I|0,c[k>>2]|0,c[k+4>>2]|0)|0;n=C;K=Ta;c[K>>2]=k;c[K+4>>2]=n;K=Ua;J=c[K>>2]|0;K=c[K+4>>2]|0;o=Va;o=Ph(J|0,K|0,c[o>>2]|0,c[o+4>>2]|0)|0;p=C;M=Va;c[M>>2]=o;c[M+4>>2]=p;M=Wa;L=c[M>>2]|0;M=c[M+4>>2]|0;q=Xa;q=Ph(L|0,M|0,c[q>>2]|0,c[q+4>>2]|0)|0;r=C;O=Xa;c[O>>2]=q;c[O+4>>2]=r;O=Ya;N=c[O>>2]|0;O=c[O+4>>2]|0;s=Za;s=Ph(N|0,O|0,c[s>>2]|0,c[s+4>>2]|0)|0;t=C;Q=Za;c[Q>>2]=s;c[Q+4>>2]=t;Q=_a;P=c[Q>>2]|0;Q=c[Q+4>>2]|0;u=$a;u=Ph(P|0,Q|0,c[u>>2]|0,c[u+4>>2]|0)|0;v=C;S=$a;c[S>>2]=u;c[S+4>>2]=v;S=ab;R=c[S>>2]|0;S=c[S+4>>2]|0;w=bb;w=Ph(R|0,S|0,c[w>>2]|0,c[w+4>>2]|0)|0;x=C;U=bb;c[U>>2]=w;c[U+4>>2]=x;U=cb;T=c[U>>2]|0;U=c[U+4>>2]|0;y=db;y=Ph(T|0,U|0,c[y>>2]|0,c[y+4>>2]|0)|0;z=C;W=db;c[W>>2]=y;c[W+4>>2]=z;W=eb;V=c[W>>2]|0;W=c[W+4>>2]|0;A=fb;A=Ph(V|0,W|0,c[A>>2]|0,c[A+4>>2]|0)|0;B=C;Y=fb;c[Y>>2]=A;c[Y+4>>2]=B;Y=gb;X=c[Y>>2]|0;Y=c[Y+4>>2]|0;D=hb;D=Ph(X|0,Y|0,c[D>>2]|0,c[D+4>>2]|0)|0;E=C;$=hb;c[$>>2]=D;c[$+4>>2]=E;$=ib;Z=$+72|0;do{c[$>>2]=0;$=$+4|0}while(($|0)<(Z|0));j=_h(h|0,j|0,121665,0)|0;h=C;Qb=Gb;c[Qb>>2]=j;c[Qb+4>>2]=h;Qb=_h(k|0,n|0,121665,0)|0;k=jb;c[k>>2]=Qb;c[k+4>>2]=C;k=_h(o|0,p|0,121665,0)|0;Qb=kb;c[Qb>>2]=k;c[Qb+4>>2]=C;Qb=_h(q|0,r|0,121665,0)|0;k=lb;c[k>>2]=Qb;c[k+4>>2]=C;k=_h(s|0,t|0,121665,0)|0;Qb=mb;c[Qb>>2]=k;c[Qb+4>>2]=C;Qb=_h(u|0,v|0,121665,0)|0;k=nb;c[k>>2]=Qb;c[k+4>>2]=C;k=_h(w|0,x|0,121665,0)|0;Qb=ob;c[Qb>>2]=k;c[Qb+4>>2]=C;Qb=_h(y|0,z|0,121665,0)|0;k=pb;c[k>>2]=Qb;c[k+4>>2]=C;k=_h(A|0,B|0,121665,0)|0;Qb=qb;c[Qb>>2]=k;c[Qb+4>>2]=C;Qb=_h(D|0,E|0,121665,0)|0;k=rb;c[k>>2]=Qb;c[k+4>>2]=C;k=ib;c[k>>2]=0;c[k+4>>2]=0;k=0;do{Nb=Qh(h>>31>>>6|0,0,j|0,h|0)|0;Nb=Rh(Nb|0,C|0,26)|0;Mb=C;Lb=Uh(Nb|0,Mb|0,26)|0;Lb=Ph(j|0,h|0,Lb|0,C|0)|0;Qb=Gb+(k<<3)|0;c[Qb>>2]=Lb;c[Qb+4>>2]=C;Qb=Gb+((k|1)<<3)|0;Lb=Qb;Lb=Qh(Nb|0,Mb|0,c[Lb>>2]|0,c[Lb+4>>2]|0)|0;Mb=C;Nb=Qh(Mb>>31>>>7|0,0,Lb|0,Mb|0)|0;Nb=Rh(Nb|0,C|0,25)|0;Ob=C;Pb=Uh(Nb|0,Ob|0,25)|0;Pb=Ph(Lb|0,Mb|0,Pb|0,C|0)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;k=k+2|0;Qb=Gb+(k<<3)|0;Pb=Qb;j=Qh(Nb|0,Ob|0,c[Pb>>2]|0,c[Pb+4>>2]|0)|0;h=C;c[Qb>>2]=j;c[Qb+4>>2]=h}while(k>>>0<10);h=ib;k=c[h>>2]|0;h=c[h+4>>2]|0;o=Gb;Ob=c[o>>2]|0;o=c[o+4>>2]|0;Pb=_h(k|0,h|0,18,0)|0;n=C;h=Qh(Ob|0,o|0,k|0,h|0)|0;n=Qh(h|0,C|0,Pb|0,n|0)|0;Pb=C;h=ib;c[h>>2]=0;c[h+4>>2]=0;h=Qh(Pb>>31>>>6|0,0,n|0,Pb|0)|0;h=Rh(h|0,C|0,26)|0;k=C;o=Uh(h|0,k|0,26)|0;Ob=C;j=jb;Qb=c[j>>2]|0;j=c[j+4>>2]|0;Pb=Qh(n|0,Pb|0,F|0,G|0)|0;Ob=Ph(Pb|0,C|0,o|0,Ob|0)|0;o=Gb;c[o>>2]=Ob;c[o+4>>2]=C;j=Qh(Qb|0,j|0,H|0,I|0)|0;k=Qh(j|0,C|0,h|0,k|0)|0;h=jb;c[h>>2]=k;c[h+4>>2]=C;h=kb;h=Qh(c[h>>2]|0,c[h+4>>2]|0,J|0,K|0)|0;k=kb;c[k>>2]=h;c[k+4>>2]=C;k=lb;k=Qh(c[k>>2]|0,c[k+4>>2]|0,L|0,M|0)|0;h=lb;c[h>>2]=k;c[h+4>>2]=C;h=mb;h=Qh(c[h>>2]|0,c[h+4>>2]|0,N|0,O|0)|0;k=mb;c[k>>2]=h;c[k+4>>2]=C;k=nb;k=Qh(c[k>>2]|0,c[k+4>>2]|0,P|0,Q|0)|0;h=nb;c[h>>2]=k;c[h+4>>2]=C;h=ob;h=Qh(c[h>>2]|0,c[h+4>>2]|0,R|0,S|0)|0;k=ob;c[k>>2]=h;c[k+4>>2]=C;k=pb;k=Qh(c[k>>2]|0,c[k+4>>2]|0,T|0,U|0)|0;h=pb;c[h>>2]=k;c[h+4>>2]=C;h=qb;h=Qh(c[h>>2]|0,c[h+4>>2]|0,V|0,W|0)|0;k=qb;c[k>>2]=h;c[k+4>>2]=C;k=rb;k=Qh(c[k>>2]|0,c[k+4>>2]|0,X|0,Y|0)|0;h=rb;c[h>>2]=k;c[h+4>>2]=C;Hh(ga,Cb,Gb);h=ga+144|0;k=c[h>>2]|0;h=c[h+4>>2]|0;j=ga+64|0;Qb=j;o=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;Ob=_h(k|0,h|0,18,0)|0;Pb=C;h=Qh(o|0,Qb|0,k|0,h|0)|0;Pb=Qh(h|0,C|0,Ob|0,Pb|0)|0;c[j>>2]=Pb;c[j+4>>2]=C;j=ga+136|0;Pb=c[j>>2]|0;j=c[j+4>>2]|0;Ob=ga+56|0;h=Ob;k=c[h>>2]|0;h=c[h+4>>2]|0;Qb=_h(Pb|0,j|0,18,0)|0;o=C;j=Qh(k|0,h|0,Pb|0,j|0)|0;o=Qh(j|0,C|0,Qb|0,o|0)|0;c[Ob>>2]=o;c[Ob+4>>2]=C;Ob=ga+128|0;o=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;Qb=ga+48|0;j=Qb;Pb=c[j>>2]|0;j=c[j+4>>2]|0;h=_h(o|0,Ob|0,18,0)|0;k=C;Ob=Qh(Pb|0,j|0,o|0,Ob|0)|0;k=Qh(Ob|0,C|0,h|0,k|0)|0;c[Qb>>2]=k;c[Qb+4>>2]=C;Qb=ga+120|0;k=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;h=ga+40|0;Ob=h;o=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;j=_h(k|0,Qb|0,18,0)|0;Pb=C;Qb=Qh(o|0,Ob|0,k|0,Qb|0)|0;Pb=Qh(Qb|0,C|0,j|0,Pb|0)|0;c[h>>2]=Pb;c[h+4>>2]=C;h=ga+112|0;Pb=c[h>>2]|0;h=c[h+4>>2]|0;j=ga+32|0;Qb=j;k=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;Ob=_h(Pb|0,h|0,18,0)|0;o=C;h=Qh(k|0,Qb|0,Pb|0,h|0)|0;o=Qh(h|0,C|0,Ob|0,o|0)|0;c[j>>2]=o;c[j+4>>2]=C;j=ga+104|0;o=c[j>>2]|0;j=c[j+4>>2]|0;Ob=ga+24|0;h=Ob;Pb=c[h>>2]|0;h=c[h+4>>2]|0;Qb=_h(o|0,j|0,18,0)|0;k=C;j=Qh(Pb|0,h|0,o|0,j|0)|0;k=Qh(j|0,C|0,Qb|0,k|0)|0;c[Ob>>2]=k;c[Ob+4>>2]=C;Ob=ga+96|0;k=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;Qb=ga+16|0;j=Qb;o=c[j>>2]|0;j=c[j+4>>2]|0;h=_h(k|0,Ob|0,18,0)|0;Pb=C;Ob=Qh(o|0,j|0,k|0,Ob|0)|0;Pb=Qh(Ob|0,C|0,h|0,Pb|0)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;Qb=ga+88|0;Pb=c[Qb>>2]|0;Qb=c[Qb+4>>2]|0;h=ga+8|0;Ob=h;k=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;j=_h(Pb|0,Qb|0,18,0)|0;o=C;Qb=Qh(k|0,Ob|0,Pb|0,Qb|0)|0;o=Qh(Qb|0,C|0,j|0,o|0)|0;j=h;c[j>>2]=o;c[j+4>>2]=C;j=ga+80|0;o=j;Qb=c[o>>2]|0;o=c[o+4>>2]|0;Pb=ga;Ob=c[Pb>>2]|0;Pb=c[Pb+4>>2]|0;k=_h(Qb|0,o|0,18,0)|0;n=C;o=Qh(Ob|0,Pb|0,Qb|0,o|0)|0;n=Qh(o|0,C|0,k|0,n|0)|0;k=C;o=ga;c[o>>2]=n;c[o+4>>2]=k;o=j;c[o>>2]=0;c[o+4>>2]=0;o=0;do{Nb=Qh(k>>31>>>6|0,0,n|0,k|0)|0;Nb=Rh(Nb|0,C|0,26)|0;Mb=C;Lb=Uh(Nb|0,Mb|0,26)|0;Lb=Ph(n|0,k|0,Lb|0,C|0)|0;Qb=ga+(o<<3)|0;c[Qb>>2]=Lb;c[Qb+4>>2]=C;Qb=ga+((o|1)<<3)|0;Lb=Qb;Lb=Qh(Nb|0,Mb|0,c[Lb>>2]|0,c[Lb+4>>2]|0)|0;Mb=C;Nb=Qh(Mb>>31>>>7|0,0,Lb|0,Mb|0)|0;Nb=Rh(Nb|0,C|0,25)|0;Ob=C;Pb=Uh(Nb|0,Ob|0,25)|0;Pb=Ph(Lb|0,Mb|0,Pb|0,C|0)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;o=o+2|0;Qb=ga+(o<<3)|0;Pb=Qb;n=Qh(Nb|0,Ob|0,c[Pb>>2]|0,c[Pb+4>>2]|0)|0;k=C;c[Qb>>2]=n;c[Qb+4>>2]=k}while(o>>>0<10);Ob=j;Pb=c[Ob>>2]|0;Ob=c[Ob+4>>2]|0;Nb=ga;Lb=c[Nb>>2]|0;Nb=c[Nb+4>>2]|0;Qb=_h(Pb|0,Ob|0,18,0)|0;Mb=C;Ob=Qh(Lb|0,Nb|0,Pb|0,Ob|0)|0;Mb=Qh(Ob|0,C|0,Qb|0,Mb|0)|0;Qb=C;Ob=j;c[Ob>>2]=0;c[Ob+4>>2]=0;Ob=Qh(Qb>>31>>>6|0,0,Mb|0,Qb|0)|0;Ob=Rh(Ob|0,C|0,26)|0;Pb=C;Nb=Uh(Ob|0,Pb|0,26)|0;Nb=Ph(Mb|0,Qb|0,Nb|0,C|0)|0;Qb=ga;c[Qb>>2]=Nb;c[Qb+4>>2]=C;Qb=h;Qb=Qh(Ob|0,Pb|0,c[Qb>>2]|0,c[Qb+4>>2]|0)|0;c[h>>2]=Qb;c[h+4>>2]=C;h=0;do{Lb=fa+(h<<3)|0;Jb=Lb;Kb=c[Jb>>2]|0;Jb=c[Jb+4>>2]|0;Qb=da+(h<<3)|0;Nb=Qb;Pb=c[Nb>>2]|0;Nb=c[Nb+4>>2]|0;Ob=(Pb^Kb)&ba;Mb=(Nb^Jb)&ca;Kb=Rh(0,Ob^Kb|0,32)|0;c[Lb>>2]=Kb;c[Lb+4>>2]=C;Pb=Rh(0,Ob^Pb|0,32)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;h=h+1|0}while((h|0)!=10);h=0;do{Lb=ga+(h<<3)|0;Jb=Lb;Kb=c[Jb>>2]|0;Jb=c[Jb+4>>2]|0;Qb=ea+(h<<3)|0;Nb=Qb;Pb=c[Nb>>2]|0;Nb=c[Nb+4>>2]|0;Ob=(Pb^Kb)&ba;Mb=(Nb^Jb)&ca;Kb=Rh(0,Ob^Kb|0,32)|0;c[Lb>>2]=Kb;c[Lb+4>>2]=C;Pb=Rh(0,Ob^Pb|0,32)|0;c[Qb>>2]=Pb;c[Qb+4>>2]=C;h=h+1|0}while((h|0)!=10);ha=ha+1|0;if((ha|0)==8){h=l;l=da;j=m;m=ea;k=e;e=fa;n=g;g=ga;break}else{Nb=ga;Ob=fa;Pb=ea;Qb=da;o=aa<<1&255;ga=g;g=Nb;fa=e;e=Ob;ea=m;m=Pb;da=l;l=Qb}}f=f+1|0}while((f|0)!=32);$=Bb;o=e;Z=$+80|0;do{c[$>>2]=c[o>>2];$=$+4|0;o=o+4|0}while(($|0)<(Z|0));$=Fb;o=g;Z=$+80|0;do{c[$>>2]=c[o>>2];$=$+4|0;o=o+4|0}while(($|0)<(Z|0));Ih(Gb,Fb);Ih(Ab,Gb);Ih(zb,Ab);Jh(xb,zb,Fb);Jh(Cb,xb,Gb);Ih(zb,Cb);Jh(wb,zb,xb);Ih(zb,wb);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Jh(ub,zb,wb);Ih(zb,ub);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Jh(vb,Ab,ub);Ih(zb,vb);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Jh(zb,Ab,vb);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Jh(Db,zb,ub);Ih(zb,Db);Ih(Ab,zb);e=2;do{Ih(zb,Ab);Ih(Ab,zb);e=e+2|0}while((e|0)<50);Jh(yb,Ab,Db);Ih(Ab,yb);Ih(zb,Ab);e=2;do{Ih(Ab,zb);Ih(zb,Ab);e=e+2|0}while((e|0)<100);Jh(Ab,zb,yb);Ih(zb,Ab);Ih(Ab,zb);e=2;do{Ih(zb,Ab);Ih(Ab,zb);e=e+2|0}while((e|0)<50);Jh(zb,Ab,Db);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Ih(zb,Ab);Ih(Ab,zb);Jh(Eb,Ab,Cb);Jh(Fb,Bb,Eb);e=c[Fb>>2]|0;c[Gb>>2]=e;k=Gb+4|0;c[k>>2]=c[Fb+8>>2];l=Gb+8|0;c[l>>2]=c[Fb+16>>2];m=Gb+12|0;c[m>>2]=c[Fb+24>>2];n=Gb+16|0;c[n>>2]=c[Fb+32>>2];o=Gb+20|0;c[o>>2]=c[Fb+40>>2];p=Gb+24|0;c[p>>2]=c[Fb+48>>2];q=Gb+28|0;c[q>>2]=c[Fb+56>>2];r=Gb+32|0;c[r>>2]=c[Fb+64>>2];s=Gb+36|0;c[s>>2]=c[Fb+72>>2];g=0;do{f=Gb+(g<<2)|0;h=e>>31&e;if(!(g&1)){Pb=h>>26;c[f>>2]=(_(Pb,-67108864)|0)+e;g=g+1|0;Qb=Gb+(g<<2)|0;e=(c[Qb>>2]|0)+Pb|0;c[Qb>>2]=e}else{Pb=h>>25;c[f>>2]=(_(Pb,-33554432)|0)+e;g=g+1|0;Qb=Gb+(g<<2)|0;e=(c[Qb>>2]|0)+Pb|0;c[Qb>>2]=e}}while((g|0)!=9);g=c[s>>2]|0;e=(g>>31&g)>>25;c[s>>2]=(_(e,-33554432)|0)+g;e=(e*19|0)+(c[Gb>>2]|0)|0;c[Gb>>2]=e;g=0;do{f=Gb+(g<<2)|0;h=e>>31&e;if(!(g&1)){Pb=h>>26;c[f>>2]=(_(Pb,-67108864)|0)+e;g=g+1|0;Qb=Gb+(g<<2)|0;e=(c[Qb>>2]|0)+Pb|0;c[Qb>>2]=e}else{Pb=h>>25;c[f>>2]=(_(Pb,-33554432)|0)+e;g=g+1|0;Qb=Gb+(g<<2)|0;e=(c[Qb>>2]|0)+Pb|0;c[Qb>>2]=e}}while((g|0)!=9);g=c[s>>2]|0;e=(g>>31&g)>>25;c[s>>2]=(_(e,-33554432)|0)+g;e=(e*19|0)+(c[Gb>>2]|0)|0;g=(e>>31&e)>>26;e=(_(g,-67108864)|0)+e|0;c[Gb>>2]=e;c[k>>2]=g+(c[k>>2]|0);g=0;do{f=Gb+(g<<2)|0;if(!(g&1)){c[f>>2]=e&67108863;g=g+1|0;Qb=Gb+(g<<2)|0;e=(c[Qb>>2]|0)+(e>>26)|0;c[Qb>>2]=e}else{c[f>>2]=e&33554431;g=g+1|0;Qb=Gb+(g<<2)|0;e=(c[Qb>>2]|0)+(e>>25)|0;c[Qb>>2]=e}}while((g|0)!=9);e=c[s>>2]|0;c[s>>2]=e&33554431;e=(c[Gb>>2]|0)+((e>>25)*19|0)|0;c[Gb>>2]=e;g=0;do{f=Gb+(g<<2)|0;if(!(g&1)){c[f>>2]=e&67108863;g=g+1|0;Qb=Gb+(g<<2)|0;e=(c[Qb>>2]|0)+(e>>26)|0;c[Qb>>2]=e}else{c[f>>2]=e&33554431;g=g+1|0;Qb=Gb+(g<<2)|0;e=(c[Qb>>2]|0)+(e>>25)|0;c[Qb>>2]=e}}while((g|0)!=9);j=c[s>>2]|0;h=j&33554431;c[s>>2]=h;j=(c[Gb>>2]|0)+((j>>25)*19|0)|0;c[Gb>>2]=j;f=1;e=~(j+-67108845>>31);do{g=c[Gb+(f<<2)>>2]|0;if(!(f&1)){g=g<<16&(g^-67108864);g=g<<8&g;g=g<<4&g;g=g<<2&g;g=g<<1&g}else{g=g<<16&(g^-33554432);g=g<<8&g;g=g<<4&g;g=g<<2&g;g=g<<1&g}e=g>>31&e;f=f+1|0}while((f|0)!=10);Db=j-(e&67108845)|0;c[Gb>>2]=Db;Ab=e&67108863;Bb=e&33554431;Fb=(c[k>>2]|0)-Bb|0;Ib=(c[l>>2]|0)-Ab|0;Kb=(c[m>>2]|0)-Bb|0;Lb=(c[n>>2]|0)-Ab|0;Mb=(c[o>>2]|0)-Bb|0;c[o>>2]=Mb;Pb=(c[p>>2]|0)-Ab|0;Qb=(c[q>>2]|0)-Bb|0;Ab=(c[r>>2]|0)-Ab|0;Cb=Fb<<2;c[k>>2]=Cb;Eb=Ib<<3;c[l>>2]=Eb;Gb=Kb<<5;c[m>>2]=Gb;Jb=Lb<<6;c[n>>2]=Jb;Nb=Pb<<1;c[p>>2]=Nb;Ob=Qb<<3;c[q>>2]=Ob;c[r>>2]=Ab<<4;c[s>>2]=h-Bb<<6;a[b>>0]=Db;a[b+1>>0]=Db>>>8;a[b+2>>0]=Db>>>16;a[b+3>>0]=Cb|Db>>>24;a[b+4>>0]=Fb>>>6;a[b+5>>0]=Fb>>>14;a[b+6>>0]=Eb|Fb>>>22;a[b+7>>0]=Ib>>>5;a[b+8>>0]=Ib>>>13;a[b+9>>0]=Gb|Ib>>>21;a[b+10>>0]=Kb>>>3;a[b+11>>0]=Kb>>>11;a[b+12>>0]=Jb|Kb>>>19;a[b+13>>0]=Lb>>>2;a[b+14>>0]=Lb>>>10;a[b+15>>0]=Lb>>>18;a[b+16>>0]=Mb;a[b+17>>0]=Mb>>>8;a[b+18>>0]=Mb>>>16;a[b+19>>0]=Mb>>>24|Nb;a[b+20>>0]=Pb>>>7;a[b+21>>0]=Pb>>>15;a[b+22>>0]=Ob|Pb>>>23;a[b+23>>0]=Qb>>>5;a[b+24>>0]=Qb>>>13;Pb=c[r>>2]|0;a[b+25>>0]=Pb|Qb>>>21;a[b+26>>0]=Pb>>>8;a[b+27>>0]=Pb>>>16;Qb=c[s>>2]|0;a[b+28>>0]=Qb|Pb>>>24;a[b+29>>0]=Qb>>>8;a[b+30>>0]=Qb>>>16;a[b+31>>0]=Qb>>>24;i=Hb;return 0}function Hh(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;h=Rh(0,c[b>>2]|0,32)|0;n=C;w=Rh(0,c[d>>2]|0,32)|0;n=_h(w|0,C|0,h|0,n|0)|0;h=a;c[h>>2]=n;c[h+4>>2]=C;h=Rh(0,c[b>>2]|0,32)|0;n=C;w=d+8|0;s=Rh(0,c[w>>2]|0,32)|0;n=_h(s|0,C|0,h|0,n|0)|0;h=C;s=b+8|0;r=Rh(0,c[s>>2]|0,32)|0;p=C;v=Rh(0,c[d>>2]|0,32)|0;p=_h(v|0,C|0,r|0,p|0)|0;h=Qh(p|0,C|0,n|0,h|0)|0;n=a+8|0;c[n>>2]=h;c[n+4>>2]=C;n=Rh(0,c[s>>2]|0,31)|0;h=C;p=Rh(0,c[w>>2]|0,32)|0;h=_h(p|0,C|0,n|0,h|0)|0;n=C;p=Rh(0,c[b>>2]|0,32)|0;r=C;v=d+16|0;l=Rh(0,c[v>>2]|0,32)|0;r=_h(l|0,C|0,p|0,r|0)|0;n=Qh(r|0,C|0,h|0,n|0)|0;h=C;r=b+16|0;p=Rh(0,c[r>>2]|0,32)|0;l=C;u=Rh(0,c[d>>2]|0,32)|0;l=_h(u|0,C|0,p|0,l|0)|0;l=Qh(n|0,h|0,l|0,C|0)|0;h=a+16|0;c[h>>2]=l;c[h+4>>2]=C;h=Rh(0,c[s>>2]|0,32)|0;l=C;n=Rh(0,c[v>>2]|0,32)|0;l=_h(n|0,C|0,h|0,l|0)|0;h=C;n=Rh(0,c[r>>2]|0,32)|0;p=C;u=Rh(0,c[w>>2]|0,32)|0;p=_h(u|0,C|0,n|0,p|0)|0;h=Qh(p|0,C|0,l|0,h|0)|0;l=C;p=Rh(0,c[b>>2]|0,32)|0;n=C;u=d+24|0;g=Rh(0,c[u>>2]|0,32)|0;n=_h(g|0,C|0,p|0,n|0)|0;n=Qh(h|0,l|0,n|0,C|0)|0;l=C;h=b+24|0;p=Rh(0,c[h>>2]|0,32)|0;g=C;j=Rh(0,c[d>>2]|0,32)|0;g=_h(j|0,C|0,p|0,g|0)|0;g=Qh(n|0,l|0,g|0,C|0)|0;l=a+24|0;c[l>>2]=g;c[l+4>>2]=C;l=Rh(0,c[r>>2]|0,32)|0;g=C;n=Rh(0,c[v>>2]|0,32)|0;g=_h(n|0,C|0,l|0,g|0)|0;l=C;n=Rh(0,c[s>>2]|0,32)|0;p=C;j=Rh(0,c[u>>2]|0,32)|0;p=_h(j|0,C|0,n|0,p|0)|0;n=C;j=Rh(0,c[h>>2]|0,32)|0;q=C;o=Rh(0,c[w>>2]|0,32)|0;q=_h(o|0,C|0,j|0,q|0)|0;n=Qh(q|0,C|0,p|0,n|0)|0;n=Uh(n|0,C|0,1)|0;l=Qh(n|0,C|0,g|0,l|0)|0;g=C;n=Rh(0,c[b>>2]|0,32)|0;p=C;q=d+32|0;j=Rh(0,c[q>>2]|0,32)|0;p=_h(j|0,C|0,n|0,p|0)|0;p=Qh(l|0,g|0,p|0,C|0)|0;g=C;l=b+32|0;n=Rh(0,c[l>>2]|0,32)|0;j=C;o=Rh(0,c[d>>2]|0,32)|0;j=_h(o|0,C|0,n|0,j|0)|0;j=Qh(p|0,g|0,j|0,C|0)|0;g=a+32|0;c[g>>2]=j;c[g+4>>2]=C;g=Rh(0,c[r>>2]|0,32)|0;j=C;p=Rh(0,c[u>>2]|0,32)|0;j=_h(p|0,C|0,g|0,j|0)|0;g=C;p=Rh(0,c[h>>2]|0,32)|0;n=C;o=Rh(0,c[v>>2]|0,32)|0;n=_h(o|0,C|0,p|0,n|0)|0;g=Qh(n|0,C|0,j|0,g|0)|0;j=C;n=Rh(0,c[s>>2]|0,32)|0;p=C;o=Rh(0,c[q>>2]|0,32)|0;p=_h(o|0,C|0,n|0,p|0)|0;p=Qh(g|0,j|0,p|0,C|0)|0;j=C;g=Rh(0,c[l>>2]|0,32)|0;n=C;o=Rh(0,c[w>>2]|0,32)|0;n=_h(o|0,C|0,g|0,n|0)|0;n=Qh(p|0,j|0,n|0,C|0)|0;j=C;p=Rh(0,c[b>>2]|0,32)|0;g=C;o=d+40|0;t=Rh(0,c[o>>2]|0,32)|0;g=_h(t|0,C|0,p|0,g|0)|0;g=Qh(n|0,j|0,g|0,C|0)|0;j=C;n=b+40|0;p=Rh(0,c[n>>2]|0,32)|0;t=C;k=Rh(0,c[d>>2]|0,32)|0;t=_h(k|0,C|0,p|0,t|0)|0;t=Qh(g|0,j|0,t|0,C|0)|0;j=a+40|0;c[j>>2]=t;c[j+4>>2]=C;j=Rh(0,c[h>>2]|0,32)|0;t=C;g=Rh(0,c[u>>2]|0,32)|0;t=_h(g|0,C|0,j|0,t|0)|0;j=C;g=Rh(0,c[s>>2]|0,32)|0;p=C;k=Rh(0,c[o>>2]|0,32)|0;p=_h(k|0,C|0,g|0,p|0)|0;j=Qh(p|0,C|0,t|0,j|0)|0;t=C;p=Rh(0,c[n>>2]|0,32)|0;g=C;k=Rh(0,c[w>>2]|0,32)|0;g=_h(k|0,C|0,p|0,g|0)|0;g=Qh(j|0,t|0,g|0,C|0)|0;g=Uh(g|0,C|0,1)|0;t=C;j=Rh(0,c[r>>2]|0,32)|0;p=C;k=Rh(0,c[q>>2]|0,32)|0;p=_h(k|0,C|0,j|0,p|0)|0;p=Qh(g|0,t|0,p|0,C|0)|0;t=C;g=Rh(0,c[l>>2]|0,32)|0;j=C;k=Rh(0,c[v>>2]|0,32)|0;j=_h(k|0,C|0,g|0,j|0)|0;j=Qh(p|0,t|0,j|0,C|0)|0;t=C;p=Rh(0,c[b>>2]|0,32)|0;g=C;k=d+48|0;x=Rh(0,c[k>>2]|0,32)|0;g=_h(x|0,C|0,p|0,g|0)|0;g=Qh(j|0,t|0,g|0,C|0)|0;t=C;j=b+48|0;p=Rh(0,c[j>>2]|0,32)|0;x=C;m=Rh(0,c[d>>2]|0,32)|0;x=_h(m|0,C|0,p|0,x|0)|0;x=Qh(g|0,t|0,x|0,C|0)|0;t=a+48|0;c[t>>2]=x;c[t+4>>2]=C;t=Rh(0,c[h>>2]|0,32)|0;x=C;g=Rh(0,c[q>>2]|0,32)|0;x=_h(g|0,C|0,t|0,x|0)|0;t=C;g=Rh(0,c[l>>2]|0,32)|0;p=C;m=Rh(0,c[u>>2]|0,32)|0;p=_h(m|0,C|0,g|0,p|0)|0;t=Qh(p|0,C|0,x|0,t|0)|0;x=C;p=Rh(0,c[r>>2]|0,32)|0;g=C;m=Rh(0,c[o>>2]|0,32)|0;g=_h(m|0,C|0,p|0,g|0)|0;g=Qh(t|0,x|0,g|0,C|0)|0;x=C;t=Rh(0,c[n>>2]|0,32)|0;p=C;m=Rh(0,c[v>>2]|0,32)|0;p=_h(m|0,C|0,t|0,p|0)|0;p=Qh(g|0,x|0,p|0,C|0)|0;x=C;g=Rh(0,c[s>>2]|0,32)|0;t=C;m=Rh(0,c[k>>2]|0,32)|0;t=_h(m|0,C|0,g|0,t|0)|0;t=Qh(p|0,x|0,t|0,C|0)|0;x=C;p=Rh(0,c[j>>2]|0,32)|0;g=C;m=Rh(0,c[w>>2]|0,32)|0;g=_h(m|0,C|0,p|0,g|0)|0;g=Qh(t|0,x|0,g|0,C|0)|0;x=C;t=Rh(0,c[b>>2]|0,32)|0;p=C;m=d+56|0;y=Rh(0,c[m>>2]|0,32)|0;p=_h(y|0,C|0,t|0,p|0)|0;p=Qh(g|0,x|0,p|0,C|0)|0;x=C;g=b+56|0;t=Rh(0,c[g>>2]|0,32)|0;y=C;i=Rh(0,c[d>>2]|0,32)|0;y=_h(i|0,C|0,t|0,y|0)|0;y=Qh(p|0,x|0,y|0,C|0)|0;x=a+56|0;c[x>>2]=y;c[x+4>>2]=C;x=Rh(0,c[l>>2]|0,32)|0;y=C;p=Rh(0,c[q>>2]|0,32)|0;y=_h(p|0,C|0,x|0,y|0)|0;x=C;p=Rh(0,c[h>>2]|0,32)|0;t=C;i=Rh(0,c[o>>2]|0,32)|0;t=_h(i|0,C|0,p|0,t|0)|0;p=C;i=Rh(0,c[n>>2]|0,32)|0;f=C;e=Rh(0,c[u>>2]|0,32)|0;f=_h(e|0,C|0,i|0,f|0)|0;p=Qh(f|0,C|0,t|0,p|0)|0;t=C;f=Rh(0,c[s>>2]|0,32)|0;i=C;e=Rh(0,c[m>>2]|0,32)|0;i=_h(e|0,C|0,f|0,i|0)|0;i=Qh(p|0,t|0,i|0,C|0)|0;t=C;p=Rh(0,c[g>>2]|0,32)|0;f=C;e=Rh(0,c[w>>2]|0,32)|0;f=_h(e|0,C|0,p|0,f|0)|0;f=Qh(i|0,t|0,f|0,C|0)|0;f=Uh(f|0,C|0,1)|0;x=Qh(f|0,C|0,y|0,x|0)|0;y=C;f=Rh(0,c[r>>2]|0,32)|0;t=C;i=Rh(0,c[k>>2]|0,32)|0;t=_h(i|0,C|0,f|0,t|0)|0;t=Qh(x|0,y|0,t|0,C|0)|0;y=C;x=Rh(0,c[j>>2]|0,32)|0;f=C;i=Rh(0,c[v>>2]|0,32)|0;f=_h(i|0,C|0,x|0,f|0)|0;f=Qh(t|0,y|0,f|0,C|0)|0;y=C;t=Rh(0,c[b>>2]|0,32)|0;x=C;i=d+64|0;p=Rh(0,c[i>>2]|0,32)|0;x=_h(p|0,C|0,t|0,x|0)|0;x=Qh(f|0,y|0,x|0,C|0)|0;y=C;f=b+64|0;t=Rh(0,c[f>>2]|0,32)|0;p=C;e=Rh(0,c[d>>2]|0,32)|0;p=_h(e|0,C|0,t|0,p|0)|0;p=Qh(x|0,y|0,p|0,C|0)|0;y=a+64|0;c[y>>2]=p;c[y+4>>2]=C;y=Rh(0,c[l>>2]|0,32)|0;p=C;x=Rh(0,c[o>>2]|0,32)|0;p=_h(x|0,C|0,y|0,p|0)|0;y=C;x=Rh(0,c[n>>2]|0,32)|0;t=C;e=Rh(0,c[q>>2]|0,32)|0;t=_h(e|0,C|0,x|0,t|0)|0;y=Qh(t|0,C|0,p|0,y|0)|0;p=C;t=Rh(0,c[h>>2]|0,32)|0;x=C;e=Rh(0,c[k>>2]|0,32)|0;x=_h(e|0,C|0,t|0,x|0)|0;x=Qh(y|0,p|0,x|0,C|0)|0;p=C;y=Rh(0,c[j>>2]|0,32)|0;t=C;e=Rh(0,c[u>>2]|0,32)|0;t=_h(e|0,C|0,y|0,t|0)|0;t=Qh(x|0,p|0,t|0,C|0)|0;p=C;x=Rh(0,c[r>>2]|0,32)|0;y=C;e=Rh(0,c[m>>2]|0,32)|0;y=_h(e|0,C|0,x|0,y|0)|0;y=Qh(t|0,p|0,y|0,C|0)|0;p=C;t=Rh(0,c[g>>2]|0,32)|0;x=C;e=Rh(0,c[v>>2]|0,32)|0;x=_h(e|0,C|0,t|0,x|0)|0;x=Qh(y|0,p|0,x|0,C|0)|0;p=C;y=Rh(0,c[s>>2]|0,32)|0;t=C;e=Rh(0,c[i>>2]|0,32)|0;t=_h(e|0,C|0,y|0,t|0)|0;t=Qh(x|0,p|0,t|0,C|0)|0;p=C;x=Rh(0,c[f>>2]|0,32)|0;y=C;e=Rh(0,c[w>>2]|0,32)|0;y=_h(e|0,C|0,x|0,y|0)|0;y=Qh(t|0,p|0,y|0,C|0)|0;p=C;t=Rh(0,c[b>>2]|0,32)|0;x=C;e=d+72|0;z=Rh(0,c[e>>2]|0,32)|0;x=_h(z|0,C|0,t|0,x|0)|0;x=Qh(y|0,p|0,x|0,C|0)|0;p=C;b=b+72|0;y=Rh(0,c[b>>2]|0,32)|0;t=C;d=Rh(0,c[d>>2]|0,32)|0;t=_h(d|0,C|0,y|0,t|0)|0;t=Qh(x|0,p|0,t|0,C|0)|0;d=a+72|0;c[d>>2]=t;c[d+4>>2]=C;d=Rh(0,c[n>>2]|0,32)|0;t=C;p=Rh(0,c[o>>2]|0,32)|0;t=_h(p|0,C|0,d|0,t|0)|0;d=C;p=Rh(0,c[h>>2]|0,32)|0;x=C;y=Rh(0,c[m>>2]|0,32)|0;x=_h(y|0,C|0,p|0,x|0)|0;d=Qh(x|0,C|0,t|0,d|0)|0;t=C;x=Rh(0,c[g>>2]|0,32)|0;p=C;y=Rh(0,c[u>>2]|0,32)|0;p=_h(y|0,C|0,x|0,p|0)|0;p=Qh(d|0,t|0,p|0,C|0)|0;t=C;d=Rh(0,c[s>>2]|0,32)|0;s=C;x=Rh(0,c[e>>2]|0,32)|0;s=_h(x|0,C|0,d|0,s|0)|0;s=Qh(p|0,t|0,s|0,C|0)|0;t=C;p=Rh(0,c[b>>2]|0,32)|0;d=C;w=Rh(0,c[w>>2]|0,32)|0;d=_h(w|0,C|0,p|0,d|0)|0;d=Qh(s|0,t|0,d|0,C|0)|0;d=Uh(d|0,C|0,1)|0;t=C;s=Rh(0,c[l>>2]|0,32)|0;p=C;w=Rh(0,c[k>>2]|0,32)|0;p=_h(w|0,C|0,s|0,p|0)|0;p=Qh(d|0,t|0,p|0,C|0)|0;t=C;d=Rh(0,c[j>>2]|0,32)|0;s=C;w=Rh(0,c[q>>2]|0,32)|0;s=_h(w|0,C|0,d|0,s|0)|0;s=Qh(p|0,t|0,s|0,C|0)|0;t=C;p=Rh(0,c[r>>2]|0,32)|0;d=C;w=Rh(0,c[i>>2]|0,32)|0;d=_h(w|0,C|0,p|0,d|0)|0;d=Qh(s|0,t|0,d|0,C|0)|0;t=C;s=Rh(0,c[f>>2]|0,32)|0;p=C;w=Rh(0,c[v>>2]|0,32)|0;p=_h(w|0,C|0,s|0,p|0)|0;p=Qh(d|0,t|0,p|0,C|0)|0;t=a+80|0;c[t>>2]=p;c[t+4>>2]=C;t=Rh(0,c[n>>2]|0,32)|0;p=C;d=Rh(0,c[k>>2]|0,32)|0;p=_h(d|0,C|0,t|0,p|0)|0;t=C;d=Rh(0,c[j>>2]|0,32)|0;s=C;w=Rh(0,c[o>>2]|0,32)|0;s=_h(w|0,C|0,d|0,s|0)|0;t=Qh(s|0,C|0,p|0,t|0)|0;p=C;s=Rh(0,c[l>>2]|0,32)|0;d=C;w=Rh(0,c[m>>2]|0,32)|0;d=_h(w|0,C|0,s|0,d|0)|0;d=Qh(t|0,p|0,d|0,C|0)|0;p=C;t=Rh(0,c[g>>2]|0,32)|0;s=C;w=Rh(0,c[q>>2]|0,32)|0;s=_h(w|0,C|0,t|0,s|0)|0;s=Qh(d|0,p|0,s|0,C|0)|0;p=C;d=Rh(0,c[h>>2]|0,32)|0;t=C;w=Rh(0,c[i>>2]|0,32)|0;t=_h(w|0,C|0,d|0,t|0)|0;t=Qh(s|0,p|0,t|0,C|0)|0;p=C;s=Rh(0,c[f>>2]|0,32)|0;d=C;w=Rh(0,c[u>>2]|0,32)|0;d=_h(w|0,C|0,s|0,d|0)|0;d=Qh(t|0,p|0,d|0,C|0)|0;p=C;r=Rh(0,c[r>>2]|0,32)|0;t=C;s=Rh(0,c[e>>2]|0,32)|0;t=_h(s|0,C|0,r|0,t|0)|0;t=Qh(d|0,p|0,t|0,C|0)|0;p=C;d=Rh(0,c[b>>2]|0,32)|0;r=C;v=Rh(0,c[v>>2]|0,32)|0;r=_h(v|0,C|0,d|0,r|0)|0;r=Qh(t|0,p|0,r|0,C|0)|0;p=a+88|0;c[p>>2]=r;c[p+4>>2]=C;p=Rh(0,c[j>>2]|0,32)|0;r=C;t=Rh(0,c[k>>2]|0,32)|0;r=_h(t|0,C|0,p|0,r|0)|0;p=C;t=Rh(0,c[n>>2]|0,32)|0;d=C;v=Rh(0,c[m>>2]|0,32)|0;d=_h(v|0,C|0,t|0,d|0)|0;t=C;v=Rh(0,c[g>>2]|0,32)|0;s=C;w=Rh(0,c[o>>2]|0,32)|0;s=_h(w|0,C|0,v|0,s|0)|0;t=Qh(s|0,C|0,d|0,t|0)|0;d=C;h=Rh(0,c[h>>2]|0,32)|0;s=C;v=Rh(0,c[e>>2]|0,32)|0;s=_h(v|0,C|0,h|0,s|0)|0;s=Qh(t|0,d|0,s|0,C|0)|0;d=C;t=Rh(0,c[b>>2]|0,32)|0;h=C;u=Rh(0,c[u>>2]|0,32)|0;h=_h(u|0,C|0,t|0,h|0)|0;h=Qh(s|0,d|0,h|0,C|0)|0;h=Uh(h|0,C|0,1)|0;p=Qh(h|0,C|0,r|0,p|0)|0;r=C;h=Rh(0,c[l>>2]|0,32)|0;d=C;s=Rh(0,c[i>>2]|0,32)|0;d=_h(s|0,C|0,h|0,d|0)|0;d=Qh(p|0,r|0,d|0,C|0)|0;r=C;p=Rh(0,c[f>>2]|0,32)|0;h=C;s=Rh(0,c[q>>2]|0,32)|0;h=_h(s|0,C|0,p|0,h|0)|0;h=Qh(d|0,r|0,h|0,C|0)|0;r=a+96|0;c[r>>2]=h;c[r+4>>2]=C;r=Rh(0,c[j>>2]|0,32)|0;h=C;d=Rh(0,c[m>>2]|0,32)|0;h=_h(d|0,C|0,r|0,h|0)|0;r=C;d=Rh(0,c[g>>2]|0,32)|0;p=C;s=Rh(0,c[k>>2]|0,32)|0;p=_h(s|0,C|0,d|0,p|0)|0;r=Qh(p|0,C|0,h|0,r|0)|0;h=C;p=Rh(0,c[n>>2]|0,32)|0;d=C;s=Rh(0,c[i>>2]|0,32)|0;d=_h(s|0,C|0,p|0,d|0)|0;d=Qh(r|0,h|0,d|0,C|0)|0;h=C;r=Rh(0,c[f>>2]|0,32)|0;p=C;s=Rh(0,c[o>>2]|0,32)|0;p=_h(s|0,C|0,r|0,p|0)|0;p=Qh(d|0,h|0,p|0,C|0)|0;h=C;l=Rh(0,c[l>>2]|0,32)|0;d=C;r=Rh(0,c[e>>2]|0,32)|0;d=_h(r|0,C|0,l|0,d|0)|0;d=Qh(p|0,h|0,d|0,C|0)|0;h=C;p=Rh(0,c[b>>2]|0,32)|0;l=C;q=Rh(0,c[q>>2]|0,32)|0;l=_h(q|0,C|0,p|0,l|0)|0;l=Qh(d|0,h|0,l|0,C|0)|0;h=a+104|0;c[h>>2]=l;c[h+4>>2]=C;h=Rh(0,c[g>>2]|0,32)|0;l=C;d=Rh(0,c[m>>2]|0,32)|0;l=_h(d|0,C|0,h|0,l|0)|0;h=C;d=Rh(0,c[n>>2]|0,32)|0;n=C;p=Rh(0,c[e>>2]|0,32)|0;n=_h(p|0,C|0,d|0,n|0)|0;h=Qh(n|0,C|0,l|0,h|0)|0;l=C;n=Rh(0,c[b>>2]|0,32)|0;d=C;o=Rh(0,c[o>>2]|0,32)|0;d=_h(o|0,C|0,n|0,d|0)|0;d=Qh(h|0,l|0,d|0,C|0)|0;d=Uh(d|0,C|0,1)|0;l=C;h=Rh(0,c[j>>2]|0,32)|0;n=C;o=Rh(0,c[i>>2]|0,32)|0;n=_h(o|0,C|0,h|0,n|0)|0;n=Qh(d|0,l|0,n|0,C|0)|0;l=C;d=Rh(0,c[f>>2]|0,32)|0;h=C;o=Rh(0,c[k>>2]|0,32)|0;h=_h(o|0,C|0,d|0,h|0)|0;h=Qh(n|0,l|0,h|0,C|0)|0;l=a+112|0;c[l>>2]=h;c[l+4>>2]=C;l=Rh(0,c[g>>2]|0,32)|0;h=C;n=Rh(0,c[i>>2]|0,32)|0;h=_h(n|0,C|0,l|0,h|0)|0;l=C;n=Rh(0,c[f>>2]|0,32)|0;d=C;o=Rh(0,c[m>>2]|0,32)|0;d=_h(o|0,C|0,n|0,d|0)|0;l=Qh(d|0,C|0,h|0,l|0)|0;h=C;d=Rh(0,c[j>>2]|0,32)|0;j=C;n=Rh(0,c[e>>2]|0,32)|0;j=_h(n|0,C|0,d|0,j|0)|0;j=Qh(l|0,h|0,j|0,C|0)|0;h=C;l=Rh(0,c[b>>2]|0,32)|0;d=C;k=Rh(0,c[k>>2]|0,32)|0;d=_h(k|0,C|0,l|0,d|0)|0;d=Qh(j|0,h|0,d|0,C|0)|0;h=a+120|0;c[h>>2]=d;c[h+4>>2]=C;h=Rh(0,c[f>>2]|0,32)|0;d=C;j=Rh(0,c[i>>2]|0,32)|0;d=_h(j|0,C|0,h|0,d|0)|0;h=C;g=Rh(0,c[g>>2]|0,32)|0;j=C;l=Rh(0,c[e>>2]|0,32)|0;j=_h(l|0,C|0,g|0,j|0)|0;g=C;l=Rh(0,c[b>>2]|0,32)|0;k=C;m=Rh(0,c[m>>2]|0,32)|0;k=_h(m|0,C|0,l|0,k|0)|0;g=Qh(k|0,C|0,j|0,g|0)|0;g=Uh(g|0,C|0,1)|0;h=Qh(g|0,C|0,d|0,h|0)|0;d=a+128|0;c[d>>2]=h;c[d+4>>2]=C;f=Rh(0,c[f>>2]|0,32)|0;d=C;h=Rh(0,c[e>>2]|0,32)|0;d=_h(h|0,C|0,f|0,d|0)|0;f=C;h=Rh(0,c[b>>2]|0,32)|0;g=C;i=Rh(0,c[i>>2]|0,32)|0;g=_h(i|0,C|0,h|0,g|0)|0;f=Qh(g|0,C|0,d|0,f|0)|0;d=a+136|0;c[d>>2]=f;c[d+4>>2]=C;d=Rh(0,c[b>>2]|0,31)|0;b=C;e=Rh(0,c[e>>2]|0,32)|0;b=_h(e|0,C|0,d|0,b|0)|0;a=a+144|0;c[a>>2]=b;c[a+4>>2]=C;return} +function cg(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0;g=i;i=i+688|0;h=g+676|0;Pa=g+672|0;Oa=g+668|0;Na=g+664|0;Aa=g+656|0;ya=g+648|0;wa=g+640|0;ua=g+632|0;sa=g+624|0;qa=g+616|0;oa=g+608|0;ma=g+600|0;ka=g+592|0;ia=g+584|0;ga=g+576|0;ea=g+568|0;za=g+560|0;xa=g+552|0;va=g+544|0;ta=g+536|0;ra=g+528|0;pa=g+520|0;na=g+512|0;la=g+504|0;ja=g+496|0;ha=g+488|0;fa=g+480|0;da=g+472|0;Ma=g+464|0;La=g+456|0;Ka=g+448|0;Ja=g+440|0;Ia=g+432|0;Ha=g+424|0;Ga=g+416|0;Fa=g+408|0;Ea=g+400|0;Da=g+392|0;Ca=g+384|0;Ba=g+376|0;u=g+368|0;t=g+360|0;s=g+352|0;r=g+344|0;q=g+336|0;p=g+328|0;o=g+320|0;n=g+312|0;m=g+304|0;l=g+296|0;k=g+288|0;j=g+280|0;H=g+272|0;J=g+264|0;K=g+256|0;L=g+248|0;M=g+240|0;N=g+232|0;T=g+224|0;U=g+216|0;V=g+208|0;W=g+200|0;X=g+192|0;Y=g+184|0;G=g+176|0;F=g+168|0;E=g+160|0;D=g+152|0;B=g+144|0;A=g+136|0;z=g+128|0;y=g+120|0;x=g+112|0;w=g+104|0;v=g+96|0;I=g+88|0;S=g+80|0;P=g+72|0;R=g+64|0;O=g+56|0;Q=g+48|0;$=g+40|0;ca=g+32|0;_=g+24|0;ba=g+16|0;Z=g+8|0;aa=g;c[h>>2]=b;c[Pa>>2]=d;c[Oa>>2]=e;c[Na>>2]=f;e=Sf(c[Pa>>2]|0)|0;b=Aa;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Pa>>2]|0)+2|0)|0;b=Th(b|0,C|0,5)|0;e=ya;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Pa>>2]|0)+5|0)|0;e=Th(e|0,C|0,2)|0;b=wa;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Pa>>2]|0)+7|0)|0;b=Th(b|0,C|0,7)|0;e=ua;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Rf((c[Pa>>2]|0)+10|0)|0;e=Th(e|0,C|0,4)|0;b=sa;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Sf((c[Pa>>2]|0)+13|0)|0;b=Th(b|0,C|0,1)|0;e=qa;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Rf((c[Pa>>2]|0)+15|0)|0;e=Th(e|0,C|0,6)|0;b=oa;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Sf((c[Pa>>2]|0)+18|0)|0;b=Th(b|0,C|0,3)|0;e=ma;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Pa>>2]|0)+21|0)|0;b=ka;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Pa>>2]|0)+23|0)|0;b=Th(b|0,C|0,5)|0;e=ia;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Pa>>2]|0)+26|0)|0;e=Th(e|0,C|0,2)|0;b=ga;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Pa>>2]|0)+28|0)|0;b=Th(b|0,C|0,7)|0;e=ea;c[e>>2]=b;c[e+4>>2]=C;e=Sf(c[Oa>>2]|0)|0;b=za;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Oa>>2]|0)+2|0)|0;b=Th(b|0,C|0,5)|0;e=xa;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Oa>>2]|0)+5|0)|0;e=Th(e|0,C|0,2)|0;b=va;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Oa>>2]|0)+7|0)|0;b=Th(b|0,C|0,7)|0;e=ta;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Rf((c[Oa>>2]|0)+10|0)|0;e=Th(e|0,C|0,4)|0;b=ra;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Sf((c[Oa>>2]|0)+13|0)|0;b=Th(b|0,C|0,1)|0;e=pa;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Rf((c[Oa>>2]|0)+15|0)|0;e=Th(e|0,C|0,6)|0;b=na;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Sf((c[Oa>>2]|0)+18|0)|0;b=Th(b|0,C|0,3)|0;e=la;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Oa>>2]|0)+21|0)|0;b=ja;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Oa>>2]|0)+23|0)|0;b=Th(b|0,C|0,5)|0;e=ha;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Oa>>2]|0)+26|0)|0;e=Th(e|0,C|0,2)|0;b=fa;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Oa>>2]|0)+28|0)|0;b=Th(b|0,C|0,7)|0;e=da;c[e>>2]=b;c[e+4>>2]=C;e=Sf(c[Na>>2]|0)|0;b=Ma;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Na>>2]|0)+2|0)|0;b=Th(b|0,C|0,5)|0;e=La;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Na>>2]|0)+5|0)|0;e=Th(e|0,C|0,2)|0;b=Ka;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Na>>2]|0)+7|0)|0;b=Th(b|0,C|0,7)|0;e=Ja;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Rf((c[Na>>2]|0)+10|0)|0;e=Th(e|0,C|0,4)|0;b=Ia;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Sf((c[Na>>2]|0)+13|0)|0;b=Th(b|0,C|0,1)|0;e=Ha;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Rf((c[Na>>2]|0)+15|0)|0;e=Th(e|0,C|0,6)|0;b=Ga;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Sf((c[Na>>2]|0)+18|0)|0;b=Th(b|0,C|0,3)|0;e=Fa;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Na>>2]|0)+21|0)|0;b=Ea;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Na>>2]|0)+23|0)|0;b=Th(b|0,C|0,5)|0;e=Da;c[e>>2]=2097151&b;c[e+4>>2]=0;e=Sf((c[Na>>2]|0)+26|0)|0;e=Th(e|0,C|0,2)|0;b=Ca;c[b>>2]=2097151&e;c[b+4>>2]=0;b=Rf((c[Na>>2]|0)+28|0)|0;b=Th(b|0,C|0,7)|0;e=Ba;c[e>>2]=b;c[e+4>>2]=C;e=Ma;b=c[e>>2]|0;e=c[e+4>>2]|0;d=Aa;f=za;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=u;c[e>>2]=f;c[e+4>>2]=C;e=La;f=c[e>>2]|0;e=c[e+4>>2]|0;b=Aa;d=xa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ya;b=za;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=t;c[e>>2]=b;c[e+4>>2]=C;e=Ka;b=c[e>>2]|0;e=c[e+4>>2]|0;d=Aa;f=va;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ya;d=xa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=wa;b=za;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=s;c[e>>2]=b;c[e+4>>2]=C;e=Ja;b=c[e>>2]|0;e=c[e+4>>2]|0;d=Aa;f=ta;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ya;d=va;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=wa;b=xa;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ua;f=za;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=Ia;f=c[e>>2]|0;e=c[e+4>>2]|0;b=Aa;d=ra;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ya;b=ta;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=wa;f=va;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ua;d=xa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=sa;b=za;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=q;c[e>>2]=b;c[e+4>>2]=C;e=Ha;b=c[e>>2]|0;e=c[e+4>>2]|0;d=Aa;f=pa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ya;d=ra;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=wa;b=ta;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ua;f=va;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=sa;d=xa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=qa;b=za;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=p;c[e>>2]=b;c[e+4>>2]=C;e=Ga;b=c[e>>2]|0;e=c[e+4>>2]|0;d=Aa;f=na;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ya;d=pa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=wa;b=ra;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ua;f=ta;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=sa;d=va;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=qa;b=xa;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=oa;f=za;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=Fa;f=c[e>>2]|0;e=c[e+4>>2]|0;b=Aa;d=la;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ya;b=na;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=wa;f=pa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ua;d=ra;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=sa;b=ta;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=qa;f=va;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=oa;d=xa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ma;b=za;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=n;c[e>>2]=b;c[e+4>>2]=C;e=Ea;b=c[e>>2]|0;e=c[e+4>>2]|0;d=Aa;f=ja;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ya;d=la;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=wa;b=na;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ua;f=pa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=sa;d=ra;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=qa;b=ta;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=oa;f=va;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ma;d=xa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ka;b=za;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=m;c[e>>2]=b;c[e+4>>2]=C;e=Da;b=c[e>>2]|0;e=c[e+4>>2]|0;d=Aa;f=ha;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ya;d=ja;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=wa;b=la;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ua;f=na;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=sa;d=pa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=qa;b=ra;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=oa;f=ta;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ma;d=va;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ka;b=xa;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ia;f=za;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=Ca;f=c[e>>2]|0;e=c[e+4>>2]|0;b=Aa;d=fa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ya;b=ha;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=wa;f=ja;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ua;d=la;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=sa;b=na;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=qa;f=pa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=oa;d=ra;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ma;b=ta;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ka;f=va;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ia;d=xa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ga;b=za;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=k;c[e>>2]=b;c[e+4>>2]=C;e=Ba;b=c[e>>2]|0;e=c[e+4>>2]|0;d=Aa;f=da;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ya;d=fa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=wa;b=ha;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ua;f=ja;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=sa;d=la;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=qa;b=na;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=oa;f=pa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ma;d=ra;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ka;b=ta;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ia;f=va;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ga;d=xa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ea;b=za;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=j;c[e>>2]=b;c[e+4>>2]=C;e=ya;b=da;b=_h(c[e>>2]|0,c[e+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;e=C;d=wa;f=fa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ua;d=ha;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=sa;b=ja;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=qa;f=la;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=oa;d=na;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ma;b=pa;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ka;f=ra;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ia;d=ta;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ga;b=va;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ea;f=xa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=H;c[e>>2]=f;c[e+4>>2]=C;e=wa;f=da;f=_h(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=C;b=ua;d=fa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=sa;b=ha;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=qa;f=ja;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=oa;d=la;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ma;b=na;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ka;f=pa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ia;d=ra;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ga;b=ta;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ea;f=va;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=J;c[e>>2]=f;c[e+4>>2]=C;e=ua;f=da;f=_h(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=C;b=sa;d=fa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=qa;b=ha;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=oa;f=ja;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ma;d=la;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ka;b=na;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ia;f=pa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ga;d=ra;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ea;b=ta;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=K;c[e>>2]=b;c[e+4>>2]=C;e=sa;b=da;b=_h(c[e>>2]|0,c[e+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;e=C;d=qa;f=fa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=oa;d=ha;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ma;b=ja;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ka;f=la;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ia;d=na;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ga;b=pa;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ea;f=ra;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=L;c[e>>2]=f;c[e+4>>2]=C;e=qa;f=da;f=_h(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=C;b=oa;d=fa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ma;b=ha;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ka;f=ja;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ia;d=la;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ga;b=na;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ea;f=pa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=M;c[e>>2]=f;c[e+4>>2]=C;e=oa;f=da;f=_h(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=C;b=ma;d=fa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ka;b=ha;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ia;f=ja;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ga;d=la;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ea;b=na;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=N;c[e>>2]=b;c[e+4>>2]=C;e=ma;b=da;b=_h(c[e>>2]|0,c[e+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;e=C;d=ka;f=fa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=C;b=ia;d=ha;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ga;b=ja;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ea;f=la;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=T;c[e>>2]=f;c[e+4>>2]=C;e=ka;f=da;f=_h(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=C;b=ia;d=fa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ga;b=ha;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=C;d=ea;f=ja;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=U;c[e>>2]=f;c[e+4>>2]=C;e=ia;f=da;f=_h(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=C;b=ga;d=fa;d=_h(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Qh(f|0,e|0,d|0,C|0)|0;e=C;f=ea;b=ha;b=_h(c[f>>2]|0,c[f+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;b=Qh(d|0,e|0,b|0,C|0)|0;e=V;c[e>>2]=b;c[e+4>>2]=C;e=ga;b=da;b=_h(c[e>>2]|0,c[e+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;e=C;d=ea;f=fa;f=_h(c[d>>2]|0,c[d+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;f=Qh(b|0,e|0,f|0,C|0)|0;e=W;c[e>>2]=f;c[e+4>>2]=C;e=ea;f=da;f=_h(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=X;c[e>>2]=f;c[e+4>>2]=C;e=Y;c[e>>2]=0;c[e+4>>2]=0;e=u;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=G;c[f>>2]=e;c[f+4>>2]=C;f=G;e=t;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=G;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=u;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=u;c[f>>2]=e;c[f+4>>2]=C;f=s;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=E;c[e>>2]=f;c[e+4>>2]=C;e=E;f=r;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=r;c[f>>2]=e;c[f+4>>2]=C;f=E;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=s;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=s;c[e>>2]=f;c[e+4>>2]=C;e=q;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=B;c[f>>2]=e;c[f+4>>2]=C;f=B;e=p;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=B;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=q;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=o;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=z;c[e>>2]=f;c[e+4>>2]=C;e=z;f=n;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=n;c[f>>2]=e;c[f+4>>2]=C;f=z;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=o;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=m;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=x;c[f>>2]=e;c[f+4>>2]=C;f=x;e=l;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=x;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=m;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=k;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=v;c[e>>2]=f;c[e+4>>2]=C;e=v;f=j;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=j;c[f>>2]=e;c[f+4>>2]=C;f=v;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=k;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=H;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=S;c[f>>2]=e;c[f+4>>2]=C;f=S;e=J;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=J;c[e>>2]=f;c[e+4>>2]=C;e=S;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=H;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=K;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=R;c[e>>2]=f;c[e+4>>2]=C;e=R;f=L;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=L;c[f>>2]=e;c[f+4>>2]=C;f=R;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=K;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=K;c[e>>2]=f;c[e+4>>2]=C;e=M;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=Q;c[f>>2]=e;c[f+4>>2]=C;f=Q;e=N;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=N;c[e>>2]=f;c[e+4>>2]=C;e=Q;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=M;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=M;c[f>>2]=e;c[f+4>>2]=C;f=T;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=ca;c[e>>2]=f;c[e+4>>2]=C;e=ca;f=U;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=U;c[f>>2]=e;c[f+4>>2]=C;f=ca;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=T;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=T;c[e>>2]=f;c[e+4>>2]=C;e=V;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=ba;c[f>>2]=e;c[f+4>>2]=C;f=ba;e=W;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=W;c[e>>2]=f;c[e+4>>2]=C;e=ba;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=V;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=V;c[f>>2]=e;c[f+4>>2]=C;f=X;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=aa;c[e>>2]=f;c[e+4>>2]=C;e=aa;f=Y;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=Y;c[f>>2]=e;c[f+4>>2]=C;f=aa;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=X;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=X;c[e>>2]=f;c[e+4>>2]=C;e=t;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=F;c[f>>2]=e;c[f+4>>2]=C;f=F;e=s;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=s;c[e>>2]=f;c[e+4>>2]=C;e=F;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=t;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=t;c[f>>2]=e;c[f+4>>2]=C;f=r;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=D;c[e>>2]=f;c[e+4>>2]=C;e=D;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=D;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=r;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=p;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=A;c[f>>2]=e;c[f+4>>2]=C;f=A;e=o;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=A;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=p;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=p;c[f>>2]=e;c[f+4>>2]=C;f=n;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=y;c[e>>2]=f;c[e+4>>2]=C;e=y;f=m;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=y;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=n;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=l;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=w;c[f>>2]=e;c[f+4>>2]=C;f=w;e=k;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=w;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=l;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=l;c[f>>2]=e;c[f+4>>2]=C;f=j;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=I;c[e>>2]=f;c[e+4>>2]=C;e=I;f=H;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=I;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=j;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=J;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=P;c[f>>2]=e;c[f+4>>2]=C;f=P;e=K;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=K;c[e>>2]=f;c[e+4>>2]=C;e=P;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=J;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=J;c[f>>2]=e;c[f+4>>2]=C;f=L;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=O;c[e>>2]=f;c[e+4>>2]=C;e=O;f=M;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=M;c[f>>2]=e;c[f+4>>2]=C;f=O;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=L;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=L;c[e>>2]=f;c[e+4>>2]=C;e=N;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=$;c[f>>2]=e;c[f+4>>2]=C;f=$;e=T;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=T;c[e>>2]=f;c[e+4>>2]=C;e=$;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=N;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=N;c[f>>2]=e;c[f+4>>2]=C;f=U;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=_;c[e>>2]=f;c[e+4>>2]=C;e=_;f=V;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=V;c[f>>2]=e;c[f+4>>2]=C;f=_;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=U;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=U;c[e>>2]=f;c[e+4>>2]=C;e=W;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=Z;c[f>>2]=e;c[f+4>>2]=C;f=Z;e=X;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=X;c[e>>2]=f;c[e+4>>2]=C;e=Z;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=W;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=W;c[f>>2]=e;c[f+4>>2]=C;f=Y;f=_h(c[f>>2]|0,c[f+4>>2]|0,666643,0)|0;e=j;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=Y;e=_h(c[e>>2]|0,c[e+4>>2]|0,470296,0)|0;f=H;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=Y;f=_h(c[f>>2]|0,c[f+4>>2]|0,654183,0)|0;e=J;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=J;c[e>>2]=f;c[e+4>>2]=C;e=Y;e=_h(c[e>>2]|0,c[e+4>>2]|0,997805,0)|0;f=K;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=K;c[f>>2]=e;c[f+4>>2]=C;f=Y;f=_h(c[f>>2]|0,c[f+4>>2]|0,136657,0)|0;e=L;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=L;c[e>>2]=f;c[e+4>>2]=C;e=Y;e=_h(c[e>>2]|0,c[e+4>>2]|0,683901,0)|0;f=M;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=M;c[f>>2]=e;c[f+4>>2]=C;f=Y;c[f>>2]=0;c[f+4>>2]=0;f=X;f=_h(c[f>>2]|0,c[f+4>>2]|0,666643,0)|0;e=k;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=X;e=_h(c[e>>2]|0,c[e+4>>2]|0,470296,0)|0;f=j;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=j;c[f>>2]=e;c[f+4>>2]=C;f=X;f=_h(c[f>>2]|0,c[f+4>>2]|0,654183,0)|0;e=H;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=H;c[e>>2]=f;c[e+4>>2]=C;e=X;e=_h(c[e>>2]|0,c[e+4>>2]|0,997805,0)|0;f=J;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=J;c[f>>2]=e;c[f+4>>2]=C;f=X;f=_h(c[f>>2]|0,c[f+4>>2]|0,136657,0)|0;e=K;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=K;c[e>>2]=f;c[e+4>>2]=C;e=X;e=_h(c[e>>2]|0,c[e+4>>2]|0,683901,0)|0;f=L;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=L;c[f>>2]=e;c[f+4>>2]=C;f=X;c[f>>2]=0;c[f+4>>2]=0;f=W;f=_h(c[f>>2]|0,c[f+4>>2]|0,666643,0)|0;e=l;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=W;e=_h(c[e>>2]|0,c[e+4>>2]|0,470296,0)|0;f=k;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=k;c[f>>2]=e;c[f+4>>2]=C;f=W;f=_h(c[f>>2]|0,c[f+4>>2]|0,654183,0)|0;e=j;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=W;e=_h(c[e>>2]|0,c[e+4>>2]|0,997805,0)|0;f=H;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=W;f=_h(c[f>>2]|0,c[f+4>>2]|0,136657,0)|0;e=J;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=J;c[e>>2]=f;c[e+4>>2]=C;e=W;e=_h(c[e>>2]|0,c[e+4>>2]|0,683901,0)|0;f=K;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=K;c[f>>2]=e;c[f+4>>2]=C;f=W;c[f>>2]=0;c[f+4>>2]=0;f=V;f=_h(c[f>>2]|0,c[f+4>>2]|0,666643,0)|0;e=m;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=m;c[e>>2]=f;c[e+4>>2]=C;e=V;e=_h(c[e>>2]|0,c[e+4>>2]|0,470296,0)|0;f=l;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=l;c[f>>2]=e;c[f+4>>2]=C;f=V;f=_h(c[f>>2]|0,c[f+4>>2]|0,654183,0)|0;e=k;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=V;e=_h(c[e>>2]|0,c[e+4>>2]|0,997805,0)|0;f=j;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=j;c[f>>2]=e;c[f+4>>2]=C;f=V;f=_h(c[f>>2]|0,c[f+4>>2]|0,136657,0)|0;e=H;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=H;c[e>>2]=f;c[e+4>>2]=C;e=V;e=_h(c[e>>2]|0,c[e+4>>2]|0,683901,0)|0;f=J;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=J;c[f>>2]=e;c[f+4>>2]=C;f=V;c[f>>2]=0;c[f+4>>2]=0;f=U;f=_h(c[f>>2]|0,c[f+4>>2]|0,666643,0)|0;e=n;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=U;e=_h(c[e>>2]|0,c[e+4>>2]|0,470296,0)|0;f=m;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=U;f=_h(c[f>>2]|0,c[f+4>>2]|0,654183,0)|0;e=l;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=U;e=_h(c[e>>2]|0,c[e+4>>2]|0,997805,0)|0;f=k;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=k;c[f>>2]=e;c[f+4>>2]=C;f=U;f=_h(c[f>>2]|0,c[f+4>>2]|0,136657,0)|0;e=j;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=U;e=_h(c[e>>2]|0,c[e+4>>2]|0,683901,0)|0;f=H;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=U;c[f>>2]=0;c[f+4>>2]=0;f=T;f=_h(c[f>>2]|0,c[f+4>>2]|0,666643,0)|0;e=o;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=T;e=_h(c[e>>2]|0,c[e+4>>2]|0,470296,0)|0;f=n;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=n;c[f>>2]=e;c[f+4>>2]=C;f=T;f=_h(c[f>>2]|0,c[f+4>>2]|0,654183,0)|0;e=m;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=m;c[e>>2]=f;c[e+4>>2]=C;e=T;e=_h(c[e>>2]|0,c[e+4>>2]|0,997805,0)|0;f=l;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=l;c[f>>2]=e;c[f+4>>2]=C;f=T;f=_h(c[f>>2]|0,c[f+4>>2]|0,136657,0)|0;e=k;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=T;e=_h(c[e>>2]|0,c[e+4>>2]|0,683901,0)|0;f=j;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=j;c[f>>2]=e;c[f+4>>2]=C;f=T;c[f>>2]=0;c[f+4>>2]=0;f=o;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=z;c[e>>2]=f;c[e+4>>2]=C;e=z;f=n;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=n;c[f>>2]=e;c[f+4>>2]=C;f=z;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=o;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=m;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=x;c[f>>2]=e;c[f+4>>2]=C;f=x;e=l;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=x;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=m;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=k;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=v;c[e>>2]=f;c[e+4>>2]=C;e=v;f=j;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=j;c[f>>2]=e;c[f+4>>2]=C;f=v;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=k;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=H;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=S;c[f>>2]=e;c[f+4>>2]=C;f=S;e=J;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=J;c[e>>2]=f;c[e+4>>2]=C;e=S;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=H;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=K;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=R;c[e>>2]=f;c[e+4>>2]=C;e=R;f=L;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=L;c[f>>2]=e;c[f+4>>2]=C;f=R;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=K;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=K;c[e>>2]=f;c[e+4>>2]=C;e=M;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=Q;c[f>>2]=e;c[f+4>>2]=C;f=Q;e=N;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=N;c[e>>2]=f;c[e+4>>2]=C;e=Q;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=M;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=M;c[f>>2]=e;c[f+4>>2]=C;f=n;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=y;c[e>>2]=f;c[e+4>>2]=C;e=y;f=m;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=y;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=n;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=l;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=w;c[f>>2]=e;c[f+4>>2]=C;f=w;e=k;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=w;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=l;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=l;c[f>>2]=e;c[f+4>>2]=C;f=j;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=I;c[e>>2]=f;c[e+4>>2]=C;e=I;f=H;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=I;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=j;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=J;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=P;c[f>>2]=e;c[f+4>>2]=C;f=P;e=K;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=K;c[e>>2]=f;c[e+4>>2]=C;e=P;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=J;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=J;c[f>>2]=e;c[f+4>>2]=C;f=L;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=O;c[e>>2]=f;c[e+4>>2]=C;e=O;f=M;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=M;c[f>>2]=e;c[f+4>>2]=C;f=O;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=L;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=L;c[e>>2]=f;c[e+4>>2]=C;e=N;e=_h(c[e>>2]|0,c[e+4>>2]|0,666643,0)|0;f=p;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=p;c[f>>2]=e;c[f+4>>2]=C;f=N;f=_h(c[f>>2]|0,c[f+4>>2]|0,470296,0)|0;e=o;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=N;e=_h(c[e>>2]|0,c[e+4>>2]|0,654183,0)|0;f=n;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=n;c[f>>2]=e;c[f+4>>2]=C;f=N;f=_h(c[f>>2]|0,c[f+4>>2]|0,997805,0)|0;e=m;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=m;c[e>>2]=f;c[e+4>>2]=C;e=N;e=_h(c[e>>2]|0,c[e+4>>2]|0,136657,0)|0;f=l;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=l;c[f>>2]=e;c[f+4>>2]=C;f=N;f=_h(c[f>>2]|0,c[f+4>>2]|0,683901,0)|0;e=k;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=N;c[e>>2]=0;c[e+4>>2]=0;e=M;e=_h(c[e>>2]|0,c[e+4>>2]|0,666643,0)|0;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=M;f=_h(c[f>>2]|0,c[f+4>>2]|0,470296,0)|0;e=p;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=M;e=_h(c[e>>2]|0,c[e+4>>2]|0,654183,0)|0;f=o;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=o;c[f>>2]=e;c[f+4>>2]=C;f=M;f=_h(c[f>>2]|0,c[f+4>>2]|0,997805,0)|0;e=n;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=M;e=_h(c[e>>2]|0,c[e+4>>2]|0,136657,0)|0;f=m;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=M;f=_h(c[f>>2]|0,c[f+4>>2]|0,683901,0)|0;e=l;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=M;c[e>>2]=0;c[e+4>>2]=0;e=L;e=_h(c[e>>2]|0,c[e+4>>2]|0,666643,0)|0;f=r;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=r;c[f>>2]=e;c[f+4>>2]=C;f=L;f=_h(c[f>>2]|0,c[f+4>>2]|0,470296,0)|0;e=q;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=q;c[e>>2]=f;c[e+4>>2]=C;e=L;e=_h(c[e>>2]|0,c[e+4>>2]|0,654183,0)|0;f=p;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=p;c[f>>2]=e;c[f+4>>2]=C;f=L;f=_h(c[f>>2]|0,c[f+4>>2]|0,997805,0)|0;e=o;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=L;e=_h(c[e>>2]|0,c[e+4>>2]|0,136657,0)|0;f=n;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=n;c[f>>2]=e;c[f+4>>2]=C;f=L;f=_h(c[f>>2]|0,c[f+4>>2]|0,683901,0)|0;e=m;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=m;c[e>>2]=f;c[e+4>>2]=C;e=L;c[e>>2]=0;c[e+4>>2]=0;e=K;e=_h(c[e>>2]|0,c[e+4>>2]|0,666643,0)|0;f=s;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=s;c[f>>2]=e;c[f+4>>2]=C;f=K;f=_h(c[f>>2]|0,c[f+4>>2]|0,470296,0)|0;e=r;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=K;e=_h(c[e>>2]|0,c[e+4>>2]|0,654183,0)|0;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=K;f=_h(c[f>>2]|0,c[f+4>>2]|0,997805,0)|0;e=p;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=K;e=_h(c[e>>2]|0,c[e+4>>2]|0,136657,0)|0;f=o;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=o;c[f>>2]=e;c[f+4>>2]=C;f=K;f=_h(c[f>>2]|0,c[f+4>>2]|0,683901,0)|0;e=n;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=K;c[e>>2]=0;c[e+4>>2]=0;e=J;e=_h(c[e>>2]|0,c[e+4>>2]|0,666643,0)|0;f=t;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=t;c[f>>2]=e;c[f+4>>2]=C;f=J;f=_h(c[f>>2]|0,c[f+4>>2]|0,470296,0)|0;e=s;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=s;c[e>>2]=f;c[e+4>>2]=C;e=J;e=_h(c[e>>2]|0,c[e+4>>2]|0,654183,0)|0;f=r;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=r;c[f>>2]=e;c[f+4>>2]=C;f=J;f=_h(c[f>>2]|0,c[f+4>>2]|0,997805,0)|0;e=q;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=q;c[e>>2]=f;c[e+4>>2]=C;e=J;e=_h(c[e>>2]|0,c[e+4>>2]|0,136657,0)|0;f=p;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=p;c[f>>2]=e;c[f+4>>2]=C;f=J;f=_h(c[f>>2]|0,c[f+4>>2]|0,683901,0)|0;e=o;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=J;c[e>>2]=0;c[e+4>>2]=0;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,666643,0)|0;f=u;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=u;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,470296,0)|0;e=t;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,654183,0)|0;f=s;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=s;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,997805,0)|0;e=r;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,136657,0)|0;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,683901,0)|0;e=p;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=H;c[e>>2]=0;c[e+4>>2]=0;e=u;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=G;c[f>>2]=e;c[f+4>>2]=C;f=G;e=t;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=G;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=u;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=u;c[f>>2]=e;c[f+4>>2]=C;f=s;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=E;c[e>>2]=f;c[e+4>>2]=C;e=E;f=r;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=r;c[f>>2]=e;c[f+4>>2]=C;f=E;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=s;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=s;c[e>>2]=f;c[e+4>>2]=C;e=q;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=B;c[f>>2]=e;c[f+4>>2]=C;f=B;e=p;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=B;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=q;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=o;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=z;c[e>>2]=f;c[e+4>>2]=C;e=z;f=n;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=n;c[f>>2]=e;c[f+4>>2]=C;f=z;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=o;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=m;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=x;c[f>>2]=e;c[f+4>>2]=C;f=x;e=l;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=x;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=m;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=k;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=v;c[e>>2]=f;c[e+4>>2]=C;e=v;f=j;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=j;c[f>>2]=e;c[f+4>>2]=C;f=v;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=k;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=t;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=F;c[f>>2]=e;c[f+4>>2]=C;f=F;e=s;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=s;c[e>>2]=f;c[e+4>>2]=C;e=F;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=t;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=t;c[f>>2]=e;c[f+4>>2]=C;f=r;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=D;c[e>>2]=f;c[e+4>>2]=C;e=D;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=D;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=r;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=p;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=A;c[f>>2]=e;c[f+4>>2]=C;f=A;e=o;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=o;c[e>>2]=f;c[e+4>>2]=C;e=A;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=p;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=p;c[f>>2]=e;c[f+4>>2]=C;f=n;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=y;c[e>>2]=f;c[e+4>>2]=C;e=y;f=m;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=y;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=n;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=l;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1048576,0)|0;e=Rh(e|0,C|0,21)|0;f=w;c[f>>2]=e;c[f+4>>2]=C;f=w;e=k;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=k;c[e>>2]=f;c[e+4>>2]=C;e=w;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=l;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=l;c[f>>2]=e;c[f+4>>2]=C;f=j;f=Qh(c[f>>2]|0,c[f+4>>2]|0,1048576,0)|0;f=Rh(f|0,C|0,21)|0;e=I;c[e>>2]=f;c[e+4>>2]=C;e=I;f=H;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=I;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=j;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,666643,0)|0;f=u;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=u;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,470296,0)|0;e=t;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,654183,0)|0;f=s;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=s;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,997805,0)|0;e=r;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,136657,0)|0;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,683901,0)|0;e=p;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=H;c[e>>2]=0;c[e+4>>2]=0;e=u;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=G;c[f>>2]=e;c[f+4>>2]=C;f=G;e=t;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=G;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=u;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=u;c[f>>2]=e;c[f+4>>2]=C;f=t;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=F;c[e>>2]=f;c[e+4>>2]=C;e=F;f=s;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=s;c[f>>2]=e;c[f+4>>2]=C;f=F;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=t;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=s;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=E;c[f>>2]=e;c[f+4>>2]=C;f=E;e=r;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=E;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=s;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=s;c[f>>2]=e;c[f+4>>2]=C;f=r;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=D;c[e>>2]=f;c[e+4>>2]=C;e=D;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=D;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=r;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=q;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=B;c[f>>2]=e;c[f+4>>2]=C;f=B;e=p;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=B;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=q;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=p;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=A;c[e>>2]=f;c[e+4>>2]=C;e=A;f=o;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=o;c[f>>2]=e;c[f+4>>2]=C;f=A;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=p;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=o;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=z;c[f>>2]=e;c[f+4>>2]=C;f=z;e=n;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=z;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=o;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=o;c[f>>2]=e;c[f+4>>2]=C;f=n;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=y;c[e>>2]=f;c[e+4>>2]=C;e=y;f=m;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=y;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=n;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=m;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=x;c[f>>2]=e;c[f+4>>2]=C;f=x;e=l;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=x;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=m;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=l;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=w;c[e>>2]=f;c[e+4>>2]=C;e=w;f=k;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=k;c[f>>2]=e;c[f+4>>2]=C;f=w;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=l;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=k;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=v;c[f>>2]=e;c[f+4>>2]=C;f=v;e=j;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=v;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=k;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=k;c[f>>2]=e;c[f+4>>2]=C;f=j;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=I;c[e>>2]=f;c[e+4>>2]=C;e=I;f=H;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=H;c[f>>2]=e;c[f+4>>2]=C;f=I;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=j;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,666643,0)|0;f=u;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=u;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,470296,0)|0;e=t;f=Qh(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,654183,0)|0;f=s;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=s;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,997805,0)|0;e=r;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=H;e=_h(c[e>>2]|0,c[e+4>>2]|0,136657,0)|0;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=H;f=_h(c[f>>2]|0,c[f+4>>2]|0,683901,0)|0;e=p;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=H;c[e>>2]=0;c[e+4>>2]=0;e=u;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=G;c[f>>2]=e;c[f+4>>2]=C;f=G;e=t;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=G;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=u;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=u;c[f>>2]=e;c[f+4>>2]=C;f=t;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=F;c[e>>2]=f;c[e+4>>2]=C;e=F;f=s;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=s;c[f>>2]=e;c[f+4>>2]=C;f=F;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=t;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=t;c[e>>2]=f;c[e+4>>2]=C;e=s;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=E;c[f>>2]=e;c[f+4>>2]=C;f=E;e=r;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=E;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=s;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=s;c[f>>2]=e;c[f+4>>2]=C;f=r;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=D;c[e>>2]=f;c[e+4>>2]=C;e=D;f=q;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=D;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=r;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=r;c[e>>2]=f;c[e+4>>2]=C;e=q;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=B;c[f>>2]=e;c[f+4>>2]=C;f=B;e=p;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=B;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=q;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=q;c[f>>2]=e;c[f+4>>2]=C;f=p;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=A;c[e>>2]=f;c[e+4>>2]=C;e=A;f=o;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=o;c[f>>2]=e;c[f+4>>2]=C;f=A;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=p;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=p;c[e>>2]=f;c[e+4>>2]=C;e=o;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=z;c[f>>2]=e;c[f+4>>2]=C;f=z;e=n;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=z;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=o;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=o;c[f>>2]=e;c[f+4>>2]=C;f=n;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=y;c[e>>2]=f;c[e+4>>2]=C;e=y;f=m;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=y;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=n;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=n;c[e>>2]=f;c[e+4>>2]=C;e=m;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=x;c[f>>2]=e;c[f+4>>2]=C;f=x;e=l;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=x;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=m;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=m;c[f>>2]=e;c[f+4>>2]=C;f=l;f=Rh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=w;c[e>>2]=f;c[e+4>>2]=C;e=w;f=k;e=Qh(c[f>>2]|0,c[f+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;f=k;c[f>>2]=e;c[f+4>>2]=C;f=w;f=Uh(c[f>>2]|0,c[f+4>>2]|0,21)|0;e=l;f=Ph(c[e>>2]|0,c[e+4>>2]|0,f|0,C|0)|0;e=l;c[e>>2]=f;c[e+4>>2]=C;e=k;e=Rh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=v;c[f>>2]=e;c[f+4>>2]=C;f=v;e=j;f=Qh(c[e>>2]|0,c[e+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;e=j;c[e>>2]=f;c[e+4>>2]=C;e=v;e=Uh(c[e>>2]|0,c[e+4>>2]|0,21)|0;f=k;e=Ph(c[f>>2]|0,c[f+4>>2]|0,e|0,C|0)|0;f=k;c[f>>2]=e;c[f+4>>2]=C;f=u;f=Rh(c[f>>2]|0,c[f+4>>2]|0,0)|0;a[c[h>>2]>>0]=f;f=u;f=Rh(c[f>>2]|0,c[f+4>>2]|0,8)|0;a[(c[h>>2]|0)+1>>0]=f;f=u;f=Rh(c[f>>2]|0,c[f+4>>2]|0,16)|0;e=C;b=t;b=Uh(c[b>>2]|0,c[b+4>>2]|0,5)|0;a[(c[h>>2]|0)+2>>0]=f|b;b=t;b=Rh(c[b>>2]|0,c[b+4>>2]|0,3)|0;a[(c[h>>2]|0)+3>>0]=b;b=t;b=Rh(c[b>>2]|0,c[b+4>>2]|0,11)|0;a[(c[h>>2]|0)+4>>0]=b;b=t;b=Rh(c[b>>2]|0,c[b+4>>2]|0,19)|0;f=C;e=s;e=Uh(c[e>>2]|0,c[e+4>>2]|0,2)|0;a[(c[h>>2]|0)+5>>0]=b|e;e=s;e=Rh(c[e>>2]|0,c[e+4>>2]|0,6)|0;a[(c[h>>2]|0)+6>>0]=e;e=s;e=Rh(c[e>>2]|0,c[e+4>>2]|0,14)|0;b=C;f=r;f=Uh(c[f>>2]|0,c[f+4>>2]|0,7)|0;a[(c[h>>2]|0)+7>>0]=e|f;f=r;f=Rh(c[f>>2]|0,c[f+4>>2]|0,1)|0;a[(c[h>>2]|0)+8>>0]=f;f=r;f=Rh(c[f>>2]|0,c[f+4>>2]|0,9)|0;a[(c[h>>2]|0)+9>>0]=f;f=r;f=Rh(c[f>>2]|0,c[f+4>>2]|0,17)|0;e=C;b=q;b=Uh(c[b>>2]|0,c[b+4>>2]|0,4)|0;a[(c[h>>2]|0)+10>>0]=f|b;b=q;b=Rh(c[b>>2]|0,c[b+4>>2]|0,4)|0;a[(c[h>>2]|0)+11>>0]=b;b=q;b=Rh(c[b>>2]|0,c[b+4>>2]|0,12)|0;a[(c[h>>2]|0)+12>>0]=b;b=q;b=Rh(c[b>>2]|0,c[b+4>>2]|0,20)|0;f=C;e=p;e=Uh(c[e>>2]|0,c[e+4>>2]|0,1)|0;a[(c[h>>2]|0)+13>>0]=b|e;e=p;e=Rh(c[e>>2]|0,c[e+4>>2]|0,7)|0;a[(c[h>>2]|0)+14>>0]=e;e=p;e=Rh(c[e>>2]|0,c[e+4>>2]|0,15)|0;b=C;f=o;f=Uh(c[f>>2]|0,c[f+4>>2]|0,6)|0;a[(c[h>>2]|0)+15>>0]=e|f;f=o;f=Rh(c[f>>2]|0,c[f+4>>2]|0,2)|0;a[(c[h>>2]|0)+16>>0]=f;f=o;f=Rh(c[f>>2]|0,c[f+4>>2]|0,10)|0;a[(c[h>>2]|0)+17>>0]=f;f=o;f=Rh(c[f>>2]|0,c[f+4>>2]|0,18)|0;e=C;b=n;b=Uh(c[b>>2]|0,c[b+4>>2]|0,3)|0;a[(c[h>>2]|0)+18>>0]=f|b;b=n;b=Rh(c[b>>2]|0,c[b+4>>2]|0,5)|0;a[(c[h>>2]|0)+19>>0]=b;b=n;b=Rh(c[b>>2]|0,c[b+4>>2]|0,13)|0;a[(c[h>>2]|0)+20>>0]=b;b=m;b=Rh(c[b>>2]|0,c[b+4>>2]|0,0)|0;a[(c[h>>2]|0)+21>>0]=b;b=m;b=Rh(c[b>>2]|0,c[b+4>>2]|0,8)|0;a[(c[h>>2]|0)+22>>0]=b;b=m;b=Rh(c[b>>2]|0,c[b+4>>2]|0,16)|0;f=C;e=l;e=Uh(c[e>>2]|0,c[e+4>>2]|0,5)|0;a[(c[h>>2]|0)+23>>0]=b|e;e=l;e=Rh(c[e>>2]|0,c[e+4>>2]|0,3)|0;a[(c[h>>2]|0)+24>>0]=e;e=l;e=Rh(c[e>>2]|0,c[e+4>>2]|0,11)|0;a[(c[h>>2]|0)+25>>0]=e;e=l;e=Rh(c[e>>2]|0,c[e+4>>2]|0,19)|0;b=C;f=k;f=Uh(c[f>>2]|0,c[f+4>>2]|0,2)|0;a[(c[h>>2]|0)+26>>0]=e|f;f=k;f=Rh(c[f>>2]|0,c[f+4>>2]|0,6)|0;a[(c[h>>2]|0)+27>>0]=f;f=k;f=Rh(c[f>>2]|0,c[f+4>>2]|0,14)|0;e=C;b=j;b=Uh(c[b>>2]|0,c[b+4>>2]|0,7)|0;a[(c[h>>2]|0)+28>>0]=f|b;b=j;b=Rh(c[b>>2]|0,c[b+4>>2]|0,1)|0;a[(c[h>>2]|0)+29>>0]=b;b=j;b=Rh(c[b>>2]|0,c[b+4>>2]|0,9)|0;a[(c[h>>2]|0)+30>>0]=b;b=j;b=Rh(c[b>>2]|0,c[b+4>>2]|0,17)|0;a[(c[h>>2]|0)+31>>0]=b;i=g;return}function dg(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+64|0;f=e+48|0;j=e+44|0;h=e+40|0;g=e;c[f>>2]=a;c[j>>2]=b;c[h>>2]=d;Nf(c[f>>2]|0,(c[j>>2]|0)+40|0,c[j>>2]|0);ag((c[f>>2]|0)+40|0,(c[j>>2]|0)+40|0,c[j>>2]|0);Vf((c[f>>2]|0)+80|0,c[f>>2]|0,c[h>>2]|0);Vf((c[f>>2]|0)+40|0,(c[f>>2]|0)+40|0,(c[h>>2]|0)+40|0);Vf((c[f>>2]|0)+120|0,(c[h>>2]|0)+120|0,(c[j>>2]|0)+120|0);Vf(c[f>>2]|0,(c[j>>2]|0)+80|0,(c[h>>2]|0)+80|0);Nf(g,c[f>>2]|0,c[f>>2]|0);ag(c[f>>2]|0,(c[f>>2]|0)+80|0,(c[f>>2]|0)+40|0);Nf((c[f>>2]|0)+40|0,(c[f>>2]|0)+80|0,(c[f>>2]|0)+40|0);Nf((c[f>>2]|0)+80|0,g,(c[f>>2]|0)+120|0);ag((c[f>>2]|0)+120|0,g,(c[f>>2]|0)+120|0);i=e;return}function eg(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;o=i;i=i+2304|0;g=o+1780|0;s=o+1776|0;q=o+1772|0;r=o+1768|0;j=o+2040|0;k=o+1784|0;h=o+488|0;m=o+328|0;n=o+168|0;p=o+8|0;l=o;c[g>>2]=b;c[s>>2]=d;c[q>>2]=e;c[r>>2]=f;fg(j,c[s>>2]|0);fg(k,c[r>>2]|0);gg(h,c[q>>2]|0);hg(m,c[q>>2]|0);kg(p,m);dg(m,p,h);kg(n,m);gg(h+160|0,n);dg(m,p,h+160|0);kg(n,m);gg(h+320|0,n);dg(m,p,h+320|0);kg(n,m);gg(h+480|0,n);dg(m,p,h+480|0);kg(n,m);gg(h+640|0,n);dg(m,p,h+640|0);kg(n,m);gg(h+800|0,n);dg(m,p,h+800|0);kg(n,m);gg(h+960|0,n);dg(m,p,h+960|0);kg(n,m);gg(h+1120|0,n);lg(c[g>>2]|0);c[l>>2]=255;while(1){if((c[l>>2]|0)<0)break;if(a[j+(c[l>>2]|0)>>0]|0)break;if(a[k+(c[l>>2]|0)>>0]|0)break;c[l>>2]=(c[l>>2]|0)+-1}while(1){if((c[l>>2]|0)<0)break;jg(m,c[g>>2]|0);if((a[j+(c[l>>2]|0)>>0]|0)<=0){if((a[j+(c[l>>2]|0)>>0]|0)<0){kg(n,m);mg(m,n,h+(((0-(a[j+(c[l>>2]|0)>>0]|0)|0)/2|0)*160|0)|0)}}else{kg(n,m);dg(m,n,h+(((a[j+(c[l>>2]|0)>>0]|0)/2|0)*160|0)|0)}if((a[k+(c[l>>2]|0)>>0]|0)<=0){if((a[k+(c[l>>2]|0)>>0]|0)<0){kg(n,m);og(m,n,744+(((0-(a[k+(c[l>>2]|0)>>0]|0)|0)/2|0)*120|0)|0)}}else{kg(n,m);ng(m,n,744+(((a[k+(c[l>>2]|0)>>0]|0)/2|0)*120|0)|0)}pg(c[g>>2]|0,m);c[l>>2]=(c[l>>2]|0)+-1}i=o;return}function fg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;l=i;i=i+32|0;g=l+16|0;f=l+12|0;j=l+8|0;h=l+4|0;k=l;c[g>>2]=b;c[f>>2]=e;c[j>>2]=0;while(1){if((c[j>>2]|0)>=256)break;a[(c[g>>2]|0)+(c[j>>2]|0)>>0]=1&d[(c[f>>2]|0)+(c[j>>2]>>3)>>0]>>(c[j>>2]&7);c[j>>2]=(c[j>>2]|0)+1}c[j>>2]=0;while(1){if((c[j>>2]|0)>=256)break;a:do if(a[(c[g>>2]|0)+(c[j>>2]|0)>>0]|0){c[h>>2]=1;while(1){if((c[h>>2]|0)>6)break a;if(((c[j>>2]|0)+(c[h>>2]|0)|0)>=256)break a;b:do if(a[(c[g>>2]|0)+((c[j>>2]|0)+(c[h>>2]|0))>>0]|0){f=c[j>>2]|0;if(((a[(c[g>>2]|0)+(c[j>>2]|0)>>0]|0)+(a[(c[g>>2]|0)+((c[j>>2]|0)+(c[h>>2]|0))>>0]<>2])|0)<=15){b=(c[g>>2]|0)+(c[j>>2]|0)|0;a[b>>0]=(a[b>>0]|0)+(a[(c[g>>2]|0)+(f+(c[h>>2]|0))>>0]<>2]);a[(c[g>>2]|0)+((c[j>>2]|0)+(c[h>>2]|0))>>0]=0;break}if(((a[(c[g>>2]|0)+f>>0]|0)-(a[(c[g>>2]|0)+((c[j>>2]|0)+(c[h>>2]|0))>>0]<>2])|0)<-15)break a;b=(c[g>>2]|0)+(c[j>>2]|0)|0;a[b>>0]=(a[b>>0]|0)-(a[(c[g>>2]|0)+((c[j>>2]|0)+(c[h>>2]|0))>>0]<>2]);c[k>>2]=(c[j>>2]|0)+(c[h>>2]|0);while(1){if((c[k>>2]|0)>=256)break b;f=(c[g>>2]|0)+(c[k>>2]|0)|0;if(!(a[(c[g>>2]|0)+(c[k>>2]|0)>>0]|0))break;a[f>>0]=0;c[k>>2]=(c[k>>2]|0)+1}a[f>>0]=1}while(0);c[h>>2]=(c[h>>2]|0)+1}}while(0);c[j>>2]=(c[j>>2]|0)+1}i=l;return}function gg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;Nf(c[f>>2]|0,(c[e>>2]|0)+40|0,c[e>>2]|0);ag((c[f>>2]|0)+40|0,(c[e>>2]|0)+40|0,c[e>>2]|0);Pf((c[f>>2]|0)+80|0,(c[e>>2]|0)+80|0);Vf((c[f>>2]|0)+120|0,(c[e>>2]|0)+120|0,704);i=d;return}function hg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+128|0;f=d+124|0;g=d+120|0;e=d;c[f>>2]=a;c[g>>2]=b;ig(e,c[g>>2]|0);jg(c[f>>2]|0,e);i=d;return}function ig(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;Pf(c[f>>2]|0,c[e>>2]|0);Pf((c[f>>2]|0)+40|0,(c[e>>2]|0)+40|0);Pf((c[f>>2]|0)+80|0,(c[e>>2]|0)+80|0);i=d;return}function jg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+48|0;e=d+44|0;g=d+40|0;f=d;c[e>>2]=a;c[g>>2]=b;Uf(c[e>>2]|0,c[g>>2]|0);Uf((c[e>>2]|0)+80|0,(c[g>>2]|0)+40|0);$f((c[e>>2]|0)+120|0,(c[g>>2]|0)+80|0);Nf((c[e>>2]|0)+40|0,c[g>>2]|0,(c[g>>2]|0)+40|0);Uf(f,(c[e>>2]|0)+40|0);Nf((c[e>>2]|0)+40|0,(c[e>>2]|0)+80|0,c[e>>2]|0);ag((c[e>>2]|0)+80|0,(c[e>>2]|0)+80|0,c[e>>2]|0);ag(c[e>>2]|0,f,(c[e>>2]|0)+40|0);ag((c[e>>2]|0)+120|0,(c[e>>2]|0)+120|0,(c[e>>2]|0)+80|0);i=d;return}function kg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;Vf(c[f>>2]|0,c[e>>2]|0,(c[e>>2]|0)+120|0);Vf((c[f>>2]|0)+40|0,(c[e>>2]|0)+40|0,(c[e>>2]|0)+80|0);Vf((c[f>>2]|0)+80|0,(c[e>>2]|0)+80|0,(c[e>>2]|0)+120|0);Vf((c[f>>2]|0)+120|0,c[e>>2]|0,(c[e>>2]|0)+40|0);i=d;return}function lg(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Lf(c[d>>2]|0);Mf((c[d>>2]|0)+40|0);Mf((c[d>>2]|0)+80|0);i=b;return}function mg(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+64|0;f=e+48|0;j=e+44|0;h=e+40|0;g=e;c[f>>2]=a;c[j>>2]=b;c[h>>2]=d;Nf(c[f>>2]|0,(c[j>>2]|0)+40|0,c[j>>2]|0);ag((c[f>>2]|0)+40|0,(c[j>>2]|0)+40|0,c[j>>2]|0);Vf((c[f>>2]|0)+80|0,c[f>>2]|0,(c[h>>2]|0)+40|0);Vf((c[f>>2]|0)+40|0,(c[f>>2]|0)+40|0,c[h>>2]|0);Vf((c[f>>2]|0)+120|0,(c[h>>2]|0)+120|0,(c[j>>2]|0)+120|0);Vf(c[f>>2]|0,(c[j>>2]|0)+80|0,(c[h>>2]|0)+80|0);Nf(g,c[f>>2]|0,c[f>>2]|0);ag(c[f>>2]|0,(c[f>>2]|0)+80|0,(c[f>>2]|0)+40|0);Nf((c[f>>2]|0)+40|0,(c[f>>2]|0)+80|0,(c[f>>2]|0)+40|0);ag((c[f>>2]|0)+80|0,g,(c[f>>2]|0)+120|0);Nf((c[f>>2]|0)+120|0,g,(c[f>>2]|0)+120|0);i=e;return}function ng(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+64|0;f=e+48|0;h=e+44|0;j=e+40|0;g=e;c[f>>2]=a;c[h>>2]=b;c[j>>2]=d;Nf(c[f>>2]|0,(c[h>>2]|0)+40|0,c[h>>2]|0);ag((c[f>>2]|0)+40|0,(c[h>>2]|0)+40|0,c[h>>2]|0);Vf((c[f>>2]|0)+80|0,c[f>>2]|0,c[j>>2]|0);Vf((c[f>>2]|0)+40|0,(c[f>>2]|0)+40|0,(c[j>>2]|0)+40|0);Vf((c[f>>2]|0)+120|0,(c[j>>2]|0)+80|0,(c[h>>2]|0)+120|0);Nf(g,(c[h>>2]|0)+80|0,(c[h>>2]|0)+80|0);ag(c[f>>2]|0,(c[f>>2]|0)+80|0,(c[f>>2]|0)+40|0);Nf((c[f>>2]|0)+40|0,(c[f>>2]|0)+80|0,(c[f>>2]|0)+40|0);Nf((c[f>>2]|0)+80|0,g,(c[f>>2]|0)+120|0);ag((c[f>>2]|0)+120|0,g,(c[f>>2]|0)+120|0);i=e;return}function og(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+64|0;f=e+48|0;h=e+44|0;j=e+40|0;g=e;c[f>>2]=a;c[h>>2]=b;c[j>>2]=d;Nf(c[f>>2]|0,(c[h>>2]|0)+40|0,c[h>>2]|0);ag((c[f>>2]|0)+40|0,(c[h>>2]|0)+40|0,c[h>>2]|0);Vf((c[f>>2]|0)+80|0,c[f>>2]|0,(c[j>>2]|0)+40|0);Vf((c[f>>2]|0)+40|0,(c[f>>2]|0)+40|0,c[j>>2]|0);Vf((c[f>>2]|0)+120|0,(c[j>>2]|0)+80|0,(c[h>>2]|0)+120|0);Nf(g,(c[h>>2]|0)+80|0,(c[h>>2]|0)+80|0);ag(c[f>>2]|0,(c[f>>2]|0)+80|0,(c[f>>2]|0)+40|0);Nf((c[f>>2]|0)+40|0,(c[f>>2]|0)+80|0,(c[f>>2]|0)+40|0);ag((c[f>>2]|0)+80|0,g,(c[f>>2]|0)+120|0);Nf((c[f>>2]|0)+120|0,g,(c[f>>2]|0)+120|0);i=e;return}function pg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;f=d+4|0;e=d;c[f>>2]=a;c[e>>2]=b;Vf(c[f>>2]|0,c[e>>2]|0,(c[e>>2]|0)+120|0);Vf((c[f>>2]|0)+40|0,(c[e>>2]|0)+40|0,(c[e>>2]|0)+80|0);Vf((c[f>>2]|0)+80|0,(c[e>>2]|0)+80|0,(c[e>>2]|0)+120|0);i=d;return}function qg(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;l=i;i=i+224|0;e=l+208|0;f=l+204|0;g=l+200|0;j=l+160|0;m=l+120|0;n=l+80|0;k=l+40|0;h=l;c[f>>2]=a;c[g>>2]=b;Qf((c[f>>2]|0)+40|0,c[g>>2]|0);Mf((c[f>>2]|0)+80|0);Uf(j,(c[f>>2]|0)+40|0);Vf(m,j,1704);ag(j,j,(c[f>>2]|0)+80|0);Nf(m,m,(c[f>>2]|0)+80|0);Uf(n,m);Vf(n,n,m);Uf(c[f>>2]|0,n);Vf(c[f>>2]|0,c[f>>2]|0,m);Vf(c[f>>2]|0,c[f>>2]|0,j);_f(c[f>>2]|0,c[f>>2]|0);Vf(c[f>>2]|0,c[f>>2]|0,n);Vf(c[f>>2]|0,c[f>>2]|0,j);Uf(k,c[f>>2]|0);Vf(k,k,m);ag(h,k,j);do if(Yf(h)|0){Nf(h,k,j);if(!(Yf(h)|0)){Vf(c[f>>2]|0,c[f>>2]|0,1744);break}c[e>>2]=-1;n=c[e>>2]|0;i=l;return n|0}while(0);n=Wf(c[f>>2]|0)|0;if((n|0)==((d[(c[g>>2]|0)+31>>0]|0)>>7|0))Zf(c[f>>2]|0,c[f>>2]|0);Vf((c[f>>2]|0)+120|0,c[f>>2]|0,(c[f>>2]|0)+40|0);c[e>>2]=0;n=c[e>>2]|0;i=l;return n|0}function rg(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Lf(c[d>>2]|0);Mf((c[d>>2]|0)+40|0);Mf((c[d>>2]|0)+80|0);Lf((c[d>>2]|0)+120|0);i=b;return}function sg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;f=i;i=i+128|0;g=f+124|0;l=f+120|0;k=f+80|0;h=f+40|0;j=f;c[g>>2]=b;c[l>>2]=e;Tf(k,(c[l>>2]|0)+80|0);Vf(h,c[l>>2]|0,k);Vf(j,(c[l>>2]|0)+40|0,k);Xf(c[g>>2]|0,j);e=(Wf(h)|0)<<7;b=(c[g>>2]|0)+31|0;a[b>>0]=(d[b>>0]|0)^e;i=f;return}function tg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;o=i;i=i+496|0;g=o+412|0;f=o+408|0;j=o+424|0;h=o+416|0;l=o+248|0;m=o+128|0;n=o+8|0;k=o;c[g>>2]=b;c[f>>2]=e;c[k>>2]=0;while(1){if((c[k>>2]|0)>=32)break;a[j+((c[k>>2]<<1)+0)>>0]=d[(c[f>>2]|0)+(c[k>>2]|0)>>0]>>0&15;a[j+((c[k>>2]<<1)+1)>>0]=d[(c[f>>2]|0)+(c[k>>2]|0)>>0]>>4&15;c[k>>2]=(c[k>>2]|0)+1}a[h>>0]=0;c[k>>2]=0;while(1){f=a[h>>0]|0;if((c[k>>2]|0)>=63)break;b=j+(c[k>>2]|0)|0;a[b>>0]=(a[b>>0]|0)+f;a[h>>0]=(a[j+(c[k>>2]|0)>>0]|0)+8;a[h>>0]=a[h>>0]>>4;b=j+(c[k>>2]|0)|0;a[b>>0]=(a[b>>0]|0)-(a[h>>0]<<4);c[k>>2]=(c[k>>2]|0)+1}h=j+63|0;a[h>>0]=(a[h>>0]|0)+f;rg(c[g>>2]|0);c[k>>2]=1;while(1){if((c[k>>2]|0)>=64)break;ug(n,(c[k>>2]|0)/2|0,a[j+(c[k>>2]|0)>>0]|0);ng(l,c[g>>2]|0,n);kg(c[g>>2]|0,l);c[k>>2]=(c[k>>2]|0)+2}hg(l,c[g>>2]|0);pg(m,l);jg(l,m);pg(m,l);jg(l,m);pg(m,l);jg(l,m);kg(c[g>>2]|0,l);c[k>>2]=0;while(1){if((c[k>>2]|0)>=64)break;ug(n,(c[k>>2]|0)/2|0,a[j+(c[k>>2]|0)>>0]|0);ng(l,c[g>>2]|0,n);kg(c[g>>2]|0,l);c[k>>2]=(c[k>>2]|0)+2}i=o;return}function ug(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0;g=i;i=i+144|0;k=g+124|0;m=g+120|0;n=g+130|0;j=g;h=g+129|0;l=g+128|0;c[k>>2]=b;c[m>>2]=e;a[n>>0]=f;a[h>>0]=vg(a[n>>0]|0)|0;a[l>>0]=(a[n>>0]|0)-((0-(d[h>>0]|0)&a[n>>0])<<1);Mf(c[k>>2]|0);Mf((c[k>>2]|0)+40|0);Lf((c[k>>2]|0)+80|0);b=c[k>>2]|0;e=1784+((c[m>>2]|0)*960|0)|0;xg(b,e,wg(a[l>>0]|0,1)|0);e=c[k>>2]|0;b=1784+((c[m>>2]|0)*960|0)+120|0;xg(e,b,wg(a[l>>0]|0,2)|0);b=c[k>>2]|0;e=1784+((c[m>>2]|0)*960|0)+240|0;xg(b,e,wg(a[l>>0]|0,3)|0);e=c[k>>2]|0;b=1784+((c[m>>2]|0)*960|0)+360|0;xg(e,b,wg(a[l>>0]|0,4)|0);b=c[k>>2]|0;e=1784+((c[m>>2]|0)*960|0)+480|0;xg(b,e,wg(a[l>>0]|0,5)|0);e=c[k>>2]|0;b=1784+((c[m>>2]|0)*960|0)+600|0;xg(e,b,wg(a[l>>0]|0,6)|0);b=c[k>>2]|0;e=1784+((c[m>>2]|0)*960|0)+720|0;xg(b,e,wg(a[l>>0]|0,7)|0);e=c[k>>2]|0;b=1784+((c[m>>2]|0)*960|0)+840|0;xg(e,b,wg(a[l>>0]|0,8)|0);Pf(j,(c[k>>2]|0)+40|0);Pf(j+40|0,c[k>>2]|0);Zf(j+80|0,(c[k>>2]|0)+80|0);xg(c[k>>2]|0,j,a[h>>0]|0);i=g;return}function vg(b){b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e+8|0;d=e;a[f>>0]=b;b=a[f>>0]|0;f=d;c[f>>2]=b;c[f+4>>2]=((b|0)<0)<<31>>31;f=d;f=Th(c[f>>2]|0,c[f+4>>2]|0,63)|0;b=d;c[b>>2]=f;c[b+4>>2]=C;i=e;return c[d>>2]&255|0}function wg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;g=i;i=i+16|0;m=g+12|0;l=g+11|0;k=g+10|0;j=g+9|0;h=g+8|0;f=g;a[m>>0]=b;a[l>>0]=e;a[k>>0]=a[m>>0]|0;a[j>>0]=a[l>>0]|0;a[h>>0]=(d[k>>0]|0)^(d[j>>0]|0);e=f;c[e>>2]=d[h>>0];c[e+4>>2]=0;e=f;e=Ph(c[e>>2]|0,c[e+4>>2]|0,1,0)|0;b=f;c[b>>2]=e;c[b+4>>2]=C;b=f;b=Th(c[b>>2]|0,c[b+4>>2]|0,63)|0;e=f;c[e>>2]=b;c[e+4>>2]=C;i=g;return c[f>>2]&255|0}function xg(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0;g=i;i=i+16|0;k=g+4|0;j=g;h=g+8|0;c[k>>2]=b;c[j>>2]=e;a[h>>0]=f;Of(c[k>>2]|0,c[j>>2]|0,d[h>>0]|0);Of((c[k>>2]|0)+40|0,(c[j>>2]|0)+40|0,d[h>>0]|0);Of((c[k>>2]|0)+80|0,(c[j>>2]|0)+80|0,d[h>>0]|0);i=g;return}function yg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;f=i;i=i+128|0;g=f+124|0;l=f+120|0;k=f+80|0;h=f+40|0;j=f;c[g>>2]=b;c[l>>2]=e;Tf(k,(c[l>>2]|0)+80|0);Vf(h,c[l>>2]|0,k);Vf(j,(c[l>>2]|0)+40|0,k);Xf(c[g>>2]|0,j);e=(Wf(h)|0)<<7;b=(c[g>>2]|0)+31|0;a[b>>0]=(d[b>>0]|0)^e;i=f;return}function zg(a){a=a|0;var b=0,d=0,e=0;e=i;i=i+16|0;b=e+4|0;d=e;c[d>>2]=a;if(!(c[d>>2]|0)){c[b>>2]=1;a=c[b>>2]|0;i=e;return a|0}else{c[(c[d>>2]|0)+72>>2]=0;a=c[d>>2]|0;c[a>>2]=0;c[a+4>>2]=0;a=(c[d>>2]|0)+8|0;c[a>>2]=-205731576;c[a+4>>2]=1779033703;a=(c[d>>2]|0)+8+8|0;c[a>>2]=-2067093701;c[a+4>>2]=-1150833019;a=(c[d>>2]|0)+8+16|0;c[a>>2]=-23791573;c[a+4>>2]=1013904242;a=(c[d>>2]|0)+8+24|0;c[a>>2]=1595750129;c[a+4>>2]=-1521486534;a=(c[d>>2]|0)+8+32|0;c[a>>2]=-1377402159;c[a+4>>2]=1359893119;a=(c[d>>2]|0)+8+40|0;c[a>>2]=725511199;c[a+4>>2]=-1694144372;a=(c[d>>2]|0)+8+48|0;c[a>>2]=-79577749;c[a+4>>2]=528734635;a=(c[d>>2]|0)+8+56|0;c[a>>2]=327033209;c[a+4>>2]=1541459225;c[b>>2]=0;a=c[b>>2]|0;i=e;return a|0}return 0}function Ag(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;n=i;i=i+32|0;l=n+24|0;f=n+20|0;g=n+16|0;h=n+12|0;k=n+8|0;j=n+4|0;m=n;c[f>>2]=b;c[g>>2]=d;c[h>>2]=e;if(!(c[f>>2]|0)){c[l>>2]=1;m=c[l>>2]|0;i=n;return m|0}if(!(c[g>>2]|0)){c[l>>2]=1;m=c[l>>2]|0;i=n;return m|0}if((c[(c[f>>2]|0)+72>>2]|0)>>>0>128){c[l>>2]=1;m=c[l>>2]|0;i=n;return m|0}while(1){if((c[h>>2]|0)>>>0<=0){d=22;break}if((c[h>>2]|0)>>>0>=128?(c[(c[f>>2]|0)+72>>2]|0)==0:0){b=Bg(c[f>>2]|0,c[g>>2]|0)|0;c[m>>2]=b;if(b|0){d=10;break}b=c[f>>2]|0;e=b;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1024,0)|0;c[b>>2]=e;c[b+4>>2]=C;c[g>>2]=(c[g>>2]|0)+128;c[h>>2]=(c[h>>2]|0)-128;continue}if((c[h>>2]|0)>>>0<(128-(c[(c[f>>2]|0)+72>>2]|0)|0)>>>0)d=c[h>>2]|0;else d=128-(c[(c[f>>2]|0)+72>>2]|0)|0;c[k>>2]=d;c[j>>2]=0;while(1){if((c[j>>2]|0)>>>0>=(c[k>>2]|0)>>>0)break;a[(c[f>>2]|0)+76+((c[j>>2]|0)+(c[(c[f>>2]|0)+72>>2]|0))>>0]=a[(c[g>>2]|0)+(c[j>>2]|0)>>0]|0;c[j>>2]=(c[j>>2]|0)+1}b=(c[f>>2]|0)+72|0;c[b>>2]=(c[b>>2]|0)+(c[k>>2]|0);c[g>>2]=(c[g>>2]|0)+(c[k>>2]|0);c[h>>2]=(c[h>>2]|0)-(c[k>>2]|0);if((c[(c[f>>2]|0)+72>>2]|0)!=128)continue;b=Bg(c[f>>2]|0,(c[f>>2]|0)+76|0)|0;c[m>>2]=b;if(b|0){d=20;break}b=c[f>>2]|0;e=b;e=Qh(c[e>>2]|0,c[e+4>>2]|0,1024,0)|0;c[b>>2]=e;c[b+4>>2]=C;c[(c[f>>2]|0)+72>>2]=0}if((d|0)==10){c[l>>2]=c[m>>2];m=c[l>>2]|0;i=n;return m|0}else if((d|0)==20){c[l>>2]=c[m>>2];m=c[l>>2]|0;i=n;return m|0}else if((d|0)==22){c[l>>2]=0;m=c[l>>2]|0;i=n;return m|0}return 0}function Bg(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;m=i;i=i+736|0;e=m+728|0;f=m+724|0;g=m+656|0;h=m+16|0;k=m+8|0;l=m;j=m+720|0;c[e>>2]=a;c[f>>2]=b;c[j>>2]=0;while(1){if((c[j>>2]|0)>=8)break;n=(c[e>>2]|0)+8+(c[j>>2]<<3)|0;b=c[n+4>>2]|0;a=g+(c[j>>2]<<3)|0;c[a>>2]=c[n>>2];c[a+4>>2]=b;c[j>>2]=(c[j>>2]|0)+1}c[j>>2]=0;while(1){if((c[j>>2]|0)>=16)break;t=(d[(c[f>>2]|0)+(c[j>>2]<<3)>>0]|0)&255;t=Uh(t|0,((t|0)<0)<<31>>31|0,56)|0;q=C;s=(d[(c[f>>2]|0)+(c[j>>2]<<3)+1>>0]|0)&255;s=Uh(s|0,((s|0)<0)<<31>>31|0,48)|0;q=q|C;r=(d[(c[f>>2]|0)+(c[j>>2]<<3)+2>>0]|0)&255;r=Uh(r|0,((r|0)<0)<<31>>31|0,40)|0;b=(d[(c[f>>2]|0)+(c[j>>2]<<3)+3>>0]|0)&255;b=q|C|b;q=(d[(c[f>>2]|0)+(c[j>>2]<<3)+4>>0]|0)&255;q=Uh(q|0,((q|0)<0)<<31>>31|0,24)|0;b=b|C;p=(d[(c[f>>2]|0)+(c[j>>2]<<3)+5>>0]|0)&255;p=Uh(p|0,((p|0)<0)<<31>>31|0,16)|0;b=b|C;o=(d[(c[f>>2]|0)+(c[j>>2]<<3)+6>>0]|0)&255;o=Uh(o|0,((o|0)<0)<<31>>31|0,8)|0;a=(d[(c[f>>2]|0)+(c[j>>2]<<3)+7>>0]|0)&255;n=h+(c[j>>2]<<3)|0;c[n>>2]=t|s|r|q|p|o|a;c[n+4>>2]=b|C|((a|0)<0)<<31>>31;c[j>>2]=(c[j>>2]|0)+1}c[j>>2]=16;while(1){if((c[j>>2]|0)>=80)break;t=h+((c[j>>2]|0)-2<<3)|0;t=Th(c[t>>2]|0,c[t+4>>2]|0,19)|0;o=C;q=h+((c[j>>2]|0)-2<<3)|0;q=Uh(c[q>>2]|0,c[q+4>>2]|0,45)|0;o=o|C;p=h+((c[j>>2]|0)-2<<3)|0;p=Th(c[p>>2]|0,c[p+4>>2]|0,61)|0;n=C;s=h+((c[j>>2]|0)-2<<3)|0;s=Uh(c[s>>2]|0,c[s+4>>2]|0,3)|0;n=o^(n|C);o=h+((c[j>>2]|0)-2<<3)|0;o=Th(c[o>>2]|0,c[o+4>>2]|0,6)|0;a=h+((c[j>>2]|0)-7<<3)|0;a=Qh((t|q)^(p|s)^o|0,n^C|0,c[a>>2]|0,c[a+4>>2]|0)|0;n=C;o=h+((c[j>>2]|0)-15<<3)|0;o=Th(c[o>>2]|0,c[o+4>>2]|0,1)|0;s=C;p=h+((c[j>>2]|0)-15<<3)|0;p=Uh(c[p>>2]|0,c[p+4>>2]|0,63)|0;s=s|C;q=h+((c[j>>2]|0)-15<<3)|0;q=Th(c[q>>2]|0,c[q+4>>2]|0,8)|0;t=C;r=h+((c[j>>2]|0)-15<<3)|0;r=Uh(c[r>>2]|0,c[r+4>>2]|0,56)|0;t=s^(t|C);s=h+((c[j>>2]|0)-15<<3)|0;s=Th(c[s>>2]|0,c[s+4>>2]|0,7)|0;t=Qh(a|0,n|0,(o|p)^(q|r)^s|0,t^C|0)|0;s=h+((c[j>>2]|0)-16<<3)|0;s=Qh(t|0,C|0,c[s>>2]|0,c[s+4>>2]|0)|0;t=h+(c[j>>2]<<3)|0;c[t>>2]=s;c[t+4>>2]=C;c[j>>2]=(c[j>>2]|0)+1}c[j>>2]=0;while(1){if((c[j>>2]|0)>=80)break;t=g+56|0;s=c[t>>2]|0;t=c[t+4>>2]|0;n=g+32|0;n=Th(c[n>>2]|0,c[n+4>>2]|0,14)|0;q=C;p=g+32|0;p=Uh(c[p>>2]|0,c[p+4>>2]|0,50)|0;q=q|C;o=g+32|0;o=Th(c[o>>2]|0,c[o+4>>2]|0,18)|0;a=C;u=g+32|0;u=Uh(c[u>>2]|0,c[u+4>>2]|0,46)|0;a=q^(a|C);q=g+32|0;q=Th(c[q>>2]|0,c[q+4>>2]|0,41)|0;r=C;f=g+32|0;f=Uh(c[f>>2]|0,c[f+4>>2]|0,23)|0;r=Qh(s|0,t|0,(n|p)^(o|u)^(q|f)|0,a^(r|C)|0)|0;a=g+48|0;f=g+32|0;q=g+40|0;u=g+48|0;u=Qh(r|0,C|0,c[a>>2]^c[f>>2]&(c[q>>2]^c[u>>2])|0,c[a+4>>2]^c[f+4>>2]&(c[q+4>>2]^c[u+4>>2])|0)|0;q=8+((c[j>>2]|0)+0<<3)|0;q=Qh(u|0,C|0,c[q>>2]|0,c[q+4>>2]|0)|0;u=h+((c[j>>2]|0)+0<<3)|0;u=Qh(q|0,C|0,c[u>>2]|0,c[u+4>>2]|0)|0;q=k;c[q>>2]=u;c[q+4>>2]=C;q=g;q=Th(c[q>>2]|0,c[q+4>>2]|0,28)|0;u=C;f=g;f=Uh(c[f>>2]|0,c[f+4>>2]|0,36)|0;u=u|C;a=g;a=Th(c[a>>2]|0,c[a+4>>2]|0,34)|0;r=C;o=g;o=Uh(c[o>>2]|0,c[o+4>>2]|0,30)|0;r=u^(r|C);u=g;u=Th(c[u>>2]|0,c[u+4>>2]|0,39)|0;p=C;n=g;n=Uh(c[n>>2]|0,c[n+4>>2]|0,25)|0;t=g;s=g+8|0;b=g+16|0;v=g;w=g+8|0;w=Qh((q|f)^(a|o)^(u|n)|0,r^(p|C)|0,(c[t>>2]|c[s>>2])&c[b>>2]|c[v>>2]&c[w>>2]|0,(c[t+4>>2]|c[s+4>>2])&c[b+4>>2]|c[v+4>>2]&c[w+4>>2]|0)|0;v=l;c[v>>2]=w;c[v+4>>2]=C;v=k;w=g+24|0;b=w;v=Qh(c[b>>2]|0,c[b+4>>2]|0,c[v>>2]|0,c[v+4>>2]|0)|0;c[w>>2]=v;c[w+4>>2]=C;w=k;v=l;v=Qh(c[w>>2]|0,c[w+4>>2]|0,c[v>>2]|0,c[v+4>>2]|0)|0;w=g+56|0;c[w>>2]=v;c[w+4>>2]=C;w=g+48|0;v=c[w>>2]|0;w=c[w+4>>2]|0;b=g+24|0;b=Th(c[b>>2]|0,c[b+4>>2]|0,14)|0;s=C;t=g+24|0;t=Uh(c[t>>2]|0,c[t+4>>2]|0,50)|0;s=s|C;p=g+24|0;p=Th(c[p>>2]|0,c[p+4>>2]|0,18)|0;r=C;n=g+24|0;n=Uh(c[n>>2]|0,c[n+4>>2]|0,46)|0;r=s^(r|C);s=g+24|0;s=Th(c[s>>2]|0,c[s+4>>2]|0,41)|0;u=C;o=g+24|0;o=Uh(c[o>>2]|0,c[o+4>>2]|0,23)|0;u=Qh(v|0,w|0,(b|t)^(p|n)^(s|o)|0,r^(u|C)|0)|0;r=g+40|0;o=g+24|0;s=g+32|0;n=g+40|0;n=Qh(u|0,C|0,c[r>>2]^c[o>>2]&(c[s>>2]^c[n>>2])|0,c[r+4>>2]^c[o+4>>2]&(c[s+4>>2]^c[n+4>>2])|0)|0;s=8+((c[j>>2]|0)+1<<3)|0;s=Qh(n|0,C|0,c[s>>2]|0,c[s+4>>2]|0)|0;n=h+((c[j>>2]|0)+1<<3)|0;n=Qh(s|0,C|0,c[n>>2]|0,c[n+4>>2]|0)|0;s=k;c[s>>2]=n;c[s+4>>2]=C;s=g+56|0;s=Th(c[s>>2]|0,c[s+4>>2]|0,28)|0;n=C;o=g+56|0;o=Uh(c[o>>2]|0,c[o+4>>2]|0,36)|0;n=n|C;r=g+56|0;r=Th(c[r>>2]|0,c[r+4>>2]|0,34)|0;u=C;p=g+56|0;p=Uh(c[p>>2]|0,c[p+4>>2]|0,30)|0;u=n^(u|C);n=g+56|0;n=Th(c[n>>2]|0,c[n+4>>2]|0,39)|0;t=C;b=g+56|0;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;w=g+56|0;v=g;a=g+8|0;f=g+56|0;q=g;q=Qh((s|o)^(r|p)^(n|b)|0,u^(t|C)|0,(c[w>>2]|c[v>>2])&c[a>>2]|c[f>>2]&c[q>>2]|0,(c[w+4>>2]|c[v+4>>2])&c[a+4>>2]|c[f+4>>2]&c[q+4>>2]|0)|0;f=l;c[f>>2]=q;c[f+4>>2]=C;f=k;q=g+16|0;a=q;f=Qh(c[a>>2]|0,c[a+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;c[q>>2]=f;c[q+4>>2]=C;q=k;f=l;f=Qh(c[q>>2]|0,c[q+4>>2]|0,c[f>>2]|0,c[f+4>>2]|0)|0;q=g+48|0;c[q>>2]=f;c[q+4>>2]=C;q=g+40|0;f=c[q>>2]|0;q=c[q+4>>2]|0;a=g+16|0;a=Th(c[a>>2]|0,c[a+4>>2]|0,14)|0;v=C;w=g+16|0;w=Uh(c[w>>2]|0,c[w+4>>2]|0,50)|0;v=v|C;t=g+16|0;t=Th(c[t>>2]|0,c[t+4>>2]|0,18)|0;u=C;b=g+16|0;b=Uh(c[b>>2]|0,c[b+4>>2]|0,46)|0;u=v^(u|C);v=g+16|0;v=Th(c[v>>2]|0,c[v+4>>2]|0,41)|0;n=C;p=g+16|0;p=Uh(c[p>>2]|0,c[p+4>>2]|0,23)|0;n=Qh(f|0,q|0,(a|w)^(t|b)^(v|p)|0,u^(n|C)|0)|0;u=g+32|0;p=g+16|0;v=g+24|0;b=g+32|0;b=Qh(n|0,C|0,c[u>>2]^c[p>>2]&(c[v>>2]^c[b>>2])|0,c[u+4>>2]^c[p+4>>2]&(c[v+4>>2]^c[b+4>>2])|0)|0;v=8+((c[j>>2]|0)+2<<3)|0;v=Qh(b|0,C|0,c[v>>2]|0,c[v+4>>2]|0)|0;b=h+((c[j>>2]|0)+2<<3)|0;b=Qh(v|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;v=k;c[v>>2]=b;c[v+4>>2]=C;v=g+48|0;v=Th(c[v>>2]|0,c[v+4>>2]|0,28)|0;b=C;p=g+48|0;p=Uh(c[p>>2]|0,c[p+4>>2]|0,36)|0;b=b|C;u=g+48|0;u=Th(c[u>>2]|0,c[u+4>>2]|0,34)|0;n=C;t=g+48|0;t=Uh(c[t>>2]|0,c[t+4>>2]|0,30)|0;n=b^(n|C);b=g+48|0;b=Th(c[b>>2]|0,c[b+4>>2]|0,39)|0;w=C;a=g+48|0;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;q=g+48|0;f=g+56|0;r=g;o=g+48|0;s=g+56|0;s=Qh((v|p)^(u|t)^(b|a)|0,n^(w|C)|0,(c[q>>2]|c[f>>2])&c[r>>2]|c[o>>2]&c[s>>2]|0,(c[q+4>>2]|c[f+4>>2])&c[r+4>>2]|c[o+4>>2]&c[s+4>>2]|0)|0;o=l;c[o>>2]=s;c[o+4>>2]=C;o=k;s=g+8|0;r=s;o=Qh(c[r>>2]|0,c[r+4>>2]|0,c[o>>2]|0,c[o+4>>2]|0)|0;c[s>>2]=o;c[s+4>>2]=C;s=k;o=l;o=Qh(c[s>>2]|0,c[s+4>>2]|0,c[o>>2]|0,c[o+4>>2]|0)|0;s=g+40|0;c[s>>2]=o;c[s+4>>2]=C;s=g+32|0;o=c[s>>2]|0;s=c[s+4>>2]|0;r=g+8|0;r=Th(c[r>>2]|0,c[r+4>>2]|0,14)|0;f=C;q=g+8|0;q=Uh(c[q>>2]|0,c[q+4>>2]|0,50)|0;f=f|C;w=g+8|0;w=Th(c[w>>2]|0,c[w+4>>2]|0,18)|0;n=C;a=g+8|0;a=Uh(c[a>>2]|0,c[a+4>>2]|0,46)|0;n=f^(n|C);f=g+8|0;f=Th(c[f>>2]|0,c[f+4>>2]|0,41)|0;b=C;t=g+8|0;t=Uh(c[t>>2]|0,c[t+4>>2]|0,23)|0;b=Qh(o|0,s|0,(r|q)^(w|a)^(f|t)|0,n^(b|C)|0)|0;n=g+24|0;t=g+8|0;f=g+16|0;a=g+24|0;a=Qh(b|0,C|0,c[n>>2]^c[t>>2]&(c[f>>2]^c[a>>2])|0,c[n+4>>2]^c[t+4>>2]&(c[f+4>>2]^c[a+4>>2])|0)|0;f=8+((c[j>>2]|0)+3<<3)|0;f=Qh(a|0,C|0,c[f>>2]|0,c[f+4>>2]|0)|0;a=h+((c[j>>2]|0)+3<<3)|0;a=Qh(f|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;f=k;c[f>>2]=a;c[f+4>>2]=C;f=g+40|0;f=Th(c[f>>2]|0,c[f+4>>2]|0,28)|0;a=C;t=g+40|0;t=Uh(c[t>>2]|0,c[t+4>>2]|0,36)|0;a=a|C;n=g+40|0;n=Th(c[n>>2]|0,c[n+4>>2]|0,34)|0;b=C;w=g+40|0;w=Uh(c[w>>2]|0,c[w+4>>2]|0,30)|0;b=a^(b|C);a=g+40|0;a=Th(c[a>>2]|0,c[a+4>>2]|0,39)|0;q=C;r=g+40|0;r=Uh(c[r>>2]|0,c[r+4>>2]|0,25)|0;s=g+40|0;o=g+48|0;u=g+56|0;p=g+40|0;v=g+48|0;v=Qh((f|t)^(n|w)^(a|r)|0,b^(q|C)|0,(c[s>>2]|c[o>>2])&c[u>>2]|c[p>>2]&c[v>>2]|0,(c[s+4>>2]|c[o+4>>2])&c[u+4>>2]|c[p+4>>2]&c[v+4>>2]|0)|0;p=l;c[p>>2]=v;c[p+4>>2]=C;p=k;v=g;p=Qh(c[v>>2]|0,c[v+4>>2]|0,c[p>>2]|0,c[p+4>>2]|0)|0;v=g;c[v>>2]=p;c[v+4>>2]=C;v=k;p=l;p=Qh(c[v>>2]|0,c[v+4>>2]|0,c[p>>2]|0,c[p+4>>2]|0)|0;v=g+32|0;c[v>>2]=p;c[v+4>>2]=C;v=g+24|0;p=c[v>>2]|0;v=c[v+4>>2]|0;u=g;u=Th(c[u>>2]|0,c[u+4>>2]|0,14)|0;o=C;s=g;s=Uh(c[s>>2]|0,c[s+4>>2]|0,50)|0;o=o|C;q=g;q=Th(c[q>>2]|0,c[q+4>>2]|0,18)|0;b=C;r=g;r=Uh(c[r>>2]|0,c[r+4>>2]|0,46)|0;b=o^(b|C);o=g;o=Th(c[o>>2]|0,c[o+4>>2]|0,41)|0;a=C;w=g;w=Uh(c[w>>2]|0,c[w+4>>2]|0,23)|0;a=Qh(p|0,v|0,(u|s)^(q|r)^(o|w)|0,b^(a|C)|0)|0;b=g+16|0;w=g;o=g+8|0;r=g+16|0;r=Qh(a|0,C|0,c[b>>2]^c[w>>2]&(c[o>>2]^c[r>>2])|0,c[b+4>>2]^c[w+4>>2]&(c[o+4>>2]^c[r+4>>2])|0)|0;o=8+((c[j>>2]|0)+4<<3)|0;o=Qh(r|0,C|0,c[o>>2]|0,c[o+4>>2]|0)|0;r=h+((c[j>>2]|0)+4<<3)|0;r=Qh(o|0,C|0,c[r>>2]|0,c[r+4>>2]|0)|0;o=k;c[o>>2]=r;c[o+4>>2]=C;o=g+32|0;o=Th(c[o>>2]|0,c[o+4>>2]|0,28)|0;r=C;w=g+32|0;w=Uh(c[w>>2]|0,c[w+4>>2]|0,36)|0;r=r|C;b=g+32|0;b=Th(c[b>>2]|0,c[b+4>>2]|0,34)|0;a=C;q=g+32|0;q=Uh(c[q>>2]|0,c[q+4>>2]|0,30)|0;a=r^(a|C);r=g+32|0;r=Th(c[r>>2]|0,c[r+4>>2]|0,39)|0;s=C;u=g+32|0;u=Uh(c[u>>2]|0,c[u+4>>2]|0,25)|0;v=g+32|0;p=g+40|0;n=g+48|0;t=g+32|0;f=g+40|0;f=Qh((o|w)^(b|q)^(r|u)|0,a^(s|C)|0,(c[v>>2]|c[p>>2])&c[n>>2]|c[t>>2]&c[f>>2]|0,(c[v+4>>2]|c[p+4>>2])&c[n+4>>2]|c[t+4>>2]&c[f+4>>2]|0)|0;t=l;c[t>>2]=f;c[t+4>>2]=C;t=k;f=g+56|0;n=f;t=Qh(c[n>>2]|0,c[n+4>>2]|0,c[t>>2]|0,c[t+4>>2]|0)|0;c[f>>2]=t;c[f+4>>2]=C;f=k;t=l;t=Qh(c[f>>2]|0,c[f+4>>2]|0,c[t>>2]|0,c[t+4>>2]|0)|0;f=g+24|0;c[f>>2]=t;c[f+4>>2]=C;f=g+16|0;t=c[f>>2]|0;f=c[f+4>>2]|0;n=g+56|0;n=Th(c[n>>2]|0,c[n+4>>2]|0,14)|0;p=C;v=g+56|0;v=Uh(c[v>>2]|0,c[v+4>>2]|0,50)|0;p=p|C;s=g+56|0;s=Th(c[s>>2]|0,c[s+4>>2]|0,18)|0;a=C;u=g+56|0;u=Uh(c[u>>2]|0,c[u+4>>2]|0,46)|0;a=p^(a|C);p=g+56|0;p=Th(c[p>>2]|0,c[p+4>>2]|0,41)|0;r=C;q=g+56|0;q=Uh(c[q>>2]|0,c[q+4>>2]|0,23)|0;r=Qh(t|0,f|0,(n|v)^(s|u)^(p|q)|0,a^(r|C)|0)|0;a=g+8|0;q=g+56|0;p=g;u=g+8|0;u=Qh(r|0,C|0,c[a>>2]^c[q>>2]&(c[p>>2]^c[u>>2])|0,c[a+4>>2]^c[q+4>>2]&(c[p+4>>2]^c[u+4>>2])|0)|0;p=8+((c[j>>2]|0)+5<<3)|0;p=Qh(u|0,C|0,c[p>>2]|0,c[p+4>>2]|0)|0;u=h+((c[j>>2]|0)+5<<3)|0;u=Qh(p|0,C|0,c[u>>2]|0,c[u+4>>2]|0)|0;p=k;c[p>>2]=u;c[p+4>>2]=C;p=g+24|0;p=Th(c[p>>2]|0,c[p+4>>2]|0,28)|0;u=C;q=g+24|0;q=Uh(c[q>>2]|0,c[q+4>>2]|0,36)|0;u=u|C;a=g+24|0;a=Th(c[a>>2]|0,c[a+4>>2]|0,34)|0;r=C;s=g+24|0;s=Uh(c[s>>2]|0,c[s+4>>2]|0,30)|0;r=u^(r|C);u=g+24|0;u=Th(c[u>>2]|0,c[u+4>>2]|0,39)|0;v=C;n=g+24|0;n=Uh(c[n>>2]|0,c[n+4>>2]|0,25)|0;f=g+24|0;t=g+32|0;b=g+40|0;w=g+24|0;o=g+32|0;o=Qh((p|q)^(a|s)^(u|n)|0,r^(v|C)|0,(c[f>>2]|c[t>>2])&c[b>>2]|c[w>>2]&c[o>>2]|0,(c[f+4>>2]|c[t+4>>2])&c[b+4>>2]|c[w+4>>2]&c[o+4>>2]|0)|0;w=l;c[w>>2]=o;c[w+4>>2]=C;w=k;o=g+48|0;b=o;w=Qh(c[b>>2]|0,c[b+4>>2]|0,c[w>>2]|0,c[w+4>>2]|0)|0;c[o>>2]=w;c[o+4>>2]=C;o=k;w=l;w=Qh(c[o>>2]|0,c[o+4>>2]|0,c[w>>2]|0,c[w+4>>2]|0)|0;o=g+16|0;c[o>>2]=w;c[o+4>>2]=C;o=g+8|0;w=c[o>>2]|0;o=c[o+4>>2]|0;b=g+48|0;b=Th(c[b>>2]|0,c[b+4>>2]|0,14)|0;t=C;f=g+48|0;f=Uh(c[f>>2]|0,c[f+4>>2]|0,50)|0;t=t|C;v=g+48|0;v=Th(c[v>>2]|0,c[v+4>>2]|0,18)|0;r=C;n=g+48|0;n=Uh(c[n>>2]|0,c[n+4>>2]|0,46)|0;r=t^(r|C);t=g+48|0;t=Th(c[t>>2]|0,c[t+4>>2]|0,41)|0;u=C;s=g+48|0;s=Uh(c[s>>2]|0,c[s+4>>2]|0,23)|0;u=Qh(w|0,o|0,(b|f)^(v|n)^(t|s)|0,r^(u|C)|0)|0;r=g;s=g+48|0;t=g+56|0;n=g;n=Qh(u|0,C|0,c[r>>2]^c[s>>2]&(c[t>>2]^c[n>>2])|0,c[r+4>>2]^c[s+4>>2]&(c[t+4>>2]^c[n+4>>2])|0)|0;t=8+((c[j>>2]|0)+6<<3)|0;t=Qh(n|0,C|0,c[t>>2]|0,c[t+4>>2]|0)|0;n=h+((c[j>>2]|0)+6<<3)|0;n=Qh(t|0,C|0,c[n>>2]|0,c[n+4>>2]|0)|0;t=k;c[t>>2]=n;c[t+4>>2]=C;t=g+16|0;t=Th(c[t>>2]|0,c[t+4>>2]|0,28)|0;n=C;s=g+16|0;s=Uh(c[s>>2]|0,c[s+4>>2]|0,36)|0;n=n|C;r=g+16|0;r=Th(c[r>>2]|0,c[r+4>>2]|0,34)|0;u=C;v=g+16|0;v=Uh(c[v>>2]|0,c[v+4>>2]|0,30)|0;u=n^(u|C);n=g+16|0;n=Th(c[n>>2]|0,c[n+4>>2]|0,39)|0;f=C;b=g+16|0;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;o=g+16|0;w=g+24|0;a=g+32|0;q=g+16|0;p=g+24|0;p=Qh((t|s)^(r|v)^(n|b)|0,u^(f|C)|0,(c[o>>2]|c[w>>2])&c[a>>2]|c[q>>2]&c[p>>2]|0,(c[o+4>>2]|c[w+4>>2])&c[a+4>>2]|c[q+4>>2]&c[p+4>>2]|0)|0;q=l;c[q>>2]=p;c[q+4>>2]=C;q=k;p=g+40|0;a=p;q=Qh(c[a>>2]|0,c[a+4>>2]|0,c[q>>2]|0,c[q+4>>2]|0)|0;c[p>>2]=q;c[p+4>>2]=C;p=k;q=l;q=Qh(c[p>>2]|0,c[p+4>>2]|0,c[q>>2]|0,c[q+4>>2]|0)|0;p=g+8|0;c[p>>2]=q;c[p+4>>2]=C;p=g;q=c[p>>2]|0;p=c[p+4>>2]|0;a=g+40|0;a=Th(c[a>>2]|0,c[a+4>>2]|0,14)|0;w=C;o=g+40|0;o=Uh(c[o>>2]|0,c[o+4>>2]|0,50)|0;w=w|C;f=g+40|0;f=Th(c[f>>2]|0,c[f+4>>2]|0,18)|0;u=C;b=g+40|0;b=Uh(c[b>>2]|0,c[b+4>>2]|0,46)|0;u=w^(u|C);w=g+40|0;w=Th(c[w>>2]|0,c[w+4>>2]|0,41)|0;n=C;v=g+40|0;v=Uh(c[v>>2]|0,c[v+4>>2]|0,23)|0;n=Qh(q|0,p|0,(a|o)^(f|b)^(w|v)|0,u^(n|C)|0)|0;u=g+56|0;v=g+40|0;w=g+48|0;b=g+56|0;b=Qh(n|0,C|0,c[u>>2]^c[v>>2]&(c[w>>2]^c[b>>2])|0,c[u+4>>2]^c[v+4>>2]&(c[w+4>>2]^c[b+4>>2])|0)|0;w=8+((c[j>>2]|0)+7<<3)|0;w=Qh(b|0,C|0,c[w>>2]|0,c[w+4>>2]|0)|0;b=h+((c[j>>2]|0)+7<<3)|0;b=Qh(w|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;w=k;c[w>>2]=b;c[w+4>>2]=C;w=g+8|0;w=Th(c[w>>2]|0,c[w+4>>2]|0,28)|0;b=C;v=g+8|0;v=Uh(c[v>>2]|0,c[v+4>>2]|0,36)|0;b=b|C;u=g+8|0;u=Th(c[u>>2]|0,c[u+4>>2]|0,34)|0;n=C;f=g+8|0;f=Uh(c[f>>2]|0,c[f+4>>2]|0,30)|0;n=b^(n|C);b=g+8|0;b=Th(c[b>>2]|0,c[b+4>>2]|0,39)|0;o=C;a=g+8|0;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;p=g+8|0;q=g+16|0;r=g+24|0;s=g+8|0;t=g+16|0;t=Qh((w|v)^(u|f)^(b|a)|0,n^(o|C)|0,(c[p>>2]|c[q>>2])&c[r>>2]|c[s>>2]&c[t>>2]|0,(c[p+4>>2]|c[q+4>>2])&c[r+4>>2]|c[s+4>>2]&c[t+4>>2]|0)|0;s=l;c[s>>2]=t;c[s+4>>2]=C;s=k;t=g+32|0;r=t;s=Qh(c[r>>2]|0,c[r+4>>2]|0,c[s>>2]|0,c[s+4>>2]|0)|0;c[t>>2]=s;c[t+4>>2]=C;t=k;s=l;s=Qh(c[t>>2]|0,c[t+4>>2]|0,c[s>>2]|0,c[s+4>>2]|0)|0;t=g;c[t>>2]=s;c[t+4>>2]=C;c[j>>2]=(c[j>>2]|0)+8}c[j>>2]=0;while(1){if((c[j>>2]|0)>=8)break;w=(c[e>>2]|0)+8+(c[j>>2]<<3)|0;v=g+(c[j>>2]<<3)|0;v=Qh(c[w>>2]|0,c[w+4>>2]|0,c[v>>2]|0,c[v+4>>2]|0)|0;w=(c[e>>2]|0)+8+(c[j>>2]<<3)|0;c[w>>2]=v;c[w+4>>2]=C;c[j>>2]=(c[j>>2]|0)+1}i=m;return 0}function Cg(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;j=i;i=i+16|0;e=j+12|0;f=j+8|0;g=j+4|0;h=j;c[f>>2]=b;c[g>>2]=d;if(!(c[f>>2]|0)){c[e>>2]=1;h=c[e>>2]|0;i=j;return h|0}if(!(c[g>>2]|0)){c[e>>2]=1;h=c[e>>2]|0;i=j;return h|0}if((c[(c[f>>2]|0)+72>>2]|0)>>>0>=128){c[e>>2]=1;h=c[e>>2]|0;i=j;return h|0}d=_h(c[(c[f>>2]|0)+72>>2]|0,0,8,0)|0;b=c[f>>2]|0;k=b;d=Qh(c[k>>2]|0,c[k+4>>2]|0,d|0,C|0)|0;c[b>>2]=d;c[b+4>>2]=C;b=(c[f>>2]|0)+72|0;d=c[b>>2]|0;c[b>>2]=d+1;a[(c[f>>2]|0)+76+d>>0]=-128;if((c[(c[f>>2]|0)+72>>2]|0)>>>0>112){while(1){b=c[f>>2]|0;if((c[(c[f>>2]|0)+72>>2]|0)>>>0>=128)break;d=b+72|0;k=c[d>>2]|0;c[d>>2]=k+1;a[(c[f>>2]|0)+76+k>>0]=0}Bg(b,(c[f>>2]|0)+76|0)|0;c[(c[f>>2]|0)+72>>2]=0}while(1){b=c[f>>2]|0;if((c[(c[f>>2]|0)+72>>2]|0)>>>0>=120)break;d=b+72|0;k=c[d>>2]|0;c[d>>2]=k+1;a[(c[f>>2]|0)+76+k>>0]=0}k=b;k=Th(c[k>>2]|0,c[k+4>>2]|0,56)|0;a[(c[f>>2]|0)+76+120>>0]=k;k=c[f>>2]|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,48)|0;a[(c[f>>2]|0)+76+120+1>>0]=k;k=c[f>>2]|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,40)|0;a[(c[f>>2]|0)+76+120+2>>0]=k;a[(c[f>>2]|0)+76+120+3>>0]=c[(c[f>>2]|0)+4>>2];k=c[f>>2]|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,24)|0;a[(c[f>>2]|0)+76+120+4>>0]=k;k=c[f>>2]|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,16)|0;a[(c[f>>2]|0)+76+120+5>>0]=k;k=c[f>>2]|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,8)|0;a[(c[f>>2]|0)+76+120+6>>0]=k;a[(c[f>>2]|0)+76+120+7>>0]=c[c[f>>2]>>2];Bg(c[f>>2]|0,(c[f>>2]|0)+76|0)|0;c[h>>2]=0;while(1){if((c[h>>2]|0)>=8)break;k=(c[f>>2]|0)+8+(c[h>>2]<<3)|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,56)|0;a[(c[g>>2]|0)+(c[h>>2]<<3)>>0]=k;k=(c[f>>2]|0)+8+(c[h>>2]<<3)|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,48)|0;a[(c[g>>2]|0)+(c[h>>2]<<3)+1>>0]=k;k=(c[f>>2]|0)+8+(c[h>>2]<<3)|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,40)|0;a[(c[g>>2]|0)+(c[h>>2]<<3)+2>>0]=k;a[(c[g>>2]|0)+(c[h>>2]<<3)+3>>0]=c[(c[f>>2]|0)+8+(c[h>>2]<<3)+4>>2];k=(c[f>>2]|0)+8+(c[h>>2]<<3)|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,24)|0;a[(c[g>>2]|0)+(c[h>>2]<<3)+4>>0]=k;k=(c[f>>2]|0)+8+(c[h>>2]<<3)|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,16)|0;a[(c[g>>2]|0)+(c[h>>2]<<3)+5>>0]=k;k=(c[f>>2]|0)+8+(c[h>>2]<<3)|0;k=Th(c[k>>2]|0,c[k+4>>2]|0,8)|0;a[(c[g>>2]|0)+(c[h>>2]<<3)+6>>0]=k;a[(c[g>>2]|0)+(c[h>>2]<<3)+7>>0]=c[(c[f>>2]|0)+8+(c[h>>2]<<3)>>2];c[h>>2]=(c[h>>2]|0)+1}c[e>>2]=0;k=c[e>>2]|0;i=j;return k|0}function Dg(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;i=i+608|0;g=r+504|0;h=r+500|0;j=r+496|0;k=r+492|0;l=r+488|0;p=r+544|0;o=r+512|0;q=r;m=r+328|0;n=r+208|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=e;c[l>>2]=f;if((d[(c[h>>2]|0)+63>>0]|0)&224|0){c[g>>2]=0;a=c[g>>2]|0;i=r;return a|0}if(qg(m,c[l>>2]|0)|0){c[g>>2]=0;a=c[g>>2]|0;i=r;return a|0}zg(q)|0;Ag(q,c[h>>2]|0,32)|0;Ag(q,c[l>>2]|0,32)|0;Ag(q,c[j>>2]|0,c[k>>2]|0)|0;Cg(q,p)|0;bg(p);eg(n,p,m,(c[h>>2]|0)+32|0);yg(o,n);if(Eg(o,c[h>>2]|0)|0){c[g>>2]=1;a=c[g>>2]|0;i=r;return a|0}else{c[g>>2]=0;a=c[g>>2]|0;i=r;return a|0}return 0}function Eg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0;g=i;i=i+16|0;j=g+4|0;h=g;f=g+8|0;c[j>>2]=b;c[h>>2]=e;a[f>>0]=0;a[f>>0]=d[c[j>>2]>>0]^d[c[h>>2]>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+1>>0]^d[(c[h>>2]|0)+1>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+2>>0]^d[(c[h>>2]|0)+2>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+3>>0]^d[(c[h>>2]|0)+3>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+4>>0]^d[(c[h>>2]|0)+4>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+5>>0]^d[(c[h>>2]|0)+5>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+6>>0]^d[(c[h>>2]|0)+6>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+7>>0]^d[(c[h>>2]|0)+7>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+8>>0]^d[(c[h>>2]|0)+8>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+9>>0]^d[(c[h>>2]|0)+9>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+10>>0]^d[(c[h>>2]|0)+10>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+11>>0]^d[(c[h>>2]|0)+11>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+12>>0]^d[(c[h>>2]|0)+12>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+13>>0]^d[(c[h>>2]|0)+13>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+14>>0]^d[(c[h>>2]|0)+14>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+15>>0]^d[(c[h>>2]|0)+15>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+16>>0]^d[(c[h>>2]|0)+16>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+17>>0]^d[(c[h>>2]|0)+17>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+18>>0]^d[(c[h>>2]|0)+18>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+19>>0]^d[(c[h>>2]|0)+19>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+20>>0]^d[(c[h>>2]|0)+20>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+21>>0]^d[(c[h>>2]|0)+21>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+22>>0]^d[(c[h>>2]|0)+22>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+23>>0]^d[(c[h>>2]|0)+23>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+24>>0]^d[(c[h>>2]|0)+24>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+25>>0]^d[(c[h>>2]|0)+25>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+26>>0]^d[(c[h>>2]|0)+26>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+27>>0]^d[(c[h>>2]|0)+27>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+28>>0]^d[(c[h>>2]|0)+28>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+29>>0]^d[(c[h>>2]|0)+29>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+30>>0]^d[(c[h>>2]|0)+30>>0];a[f>>0]=d[f>>0]|d[(c[j>>2]|0)+31>>0]^d[(c[h>>2]|0)+31>>0];i=g;return ((a[f>>0]|0)!=0^1)&1|0}function Fg(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;g=i;i=i+528|0;l=g+384|0;o=g+380|0;n=g+376|0;p=g+372|0;j=g+368|0;m=g;k=g+456|0;h=g+392|0;q=g+208|0;c[l>>2]=a;c[o>>2]=b;c[n>>2]=d;c[p>>2]=e;c[j>>2]=f;zg(m)|0;Ag(m,(c[j>>2]|0)+32|0,32)|0;Ag(m,c[o>>2]|0,c[n>>2]|0)|0;Cg(m,h)|0;bg(h);tg(q,h);sg(c[l>>2]|0,q);zg(m)|0;Ag(m,c[l>>2]|0,32)|0;Ag(m,c[p>>2]|0,32)|0;Ag(m,c[o>>2]|0,c[n>>2]|0)|0;Cg(m,k)|0;bg(k);cg((c[l>>2]|0)+32|0,k,c[j>>2]|0,h);i=g;return}function Gg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0;f=i;i=i+176|0;j=f+164|0;h=f+160|0;g=f;c[j>>2]=b;c[h>>2]=e;e=c[j>>2]|0;a[e>>0]=(d[e>>0]|0)&248;e=(c[j>>2]|0)+31|0;a[e>>0]=(d[e>>0]|0)&63;e=(c[j>>2]|0)+31|0;a[e>>0]=d[e>>0]|0|64;tg(g,c[j>>2]|0);sg(c[h>>2]|0,g);i=f;return}function Hg(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0;f=i;i=i+16|0;h=f+8|0;g=f+4|0;j=f;c[h>>2]=b;c[g>>2]=d;c[j>>2]=e;c[(c[h>>2]|0)+128>>2]=c[j>>2];e=c[h>>2]|0;b=c[g>>2]|0;d=e+128|0;do{a[e>>0]=a[b>>0]|0;e=e+1|0;b=b+1|0}while((e|0)<(d|0));i=f;return}function Ig(a){a=a|0;var b=0,d=0;d=i;i=i+16|0;b=d;c[d+4>>2]=a;c[b>>2]=0;c[b>>2]=(c[b>>2]|0)+128;c[b>>2]=(c[b>>2]|0)+4;i=d;return c[b>>2]|0}function Jg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;e=i;i=i+16|0;f=e+4|0;d=e;c[f>>2]=a;c[d>>2]=b;c[d>>2]=ab(c[d>>2]|0,c[f>>2]|0,128)|0;c[d>>2]=_a(c[d>>2]|0,c[(c[f>>2]|0)+128>>2]|0)|0;i=e;return c[d>>2]|0}function Kg(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;f=i;i=i+16|0;g=f+8|0;e=f+4|0;h=f;c[g>>2]=a;c[e>>2]=b;c[h>>2]=d;c[e>>2]=bb(c[e>>2]|0,c[h>>2]|0,c[g>>2]|0,128)|0;c[e>>2]=$a(c[e>>2]|0,c[h>>2]|0,(c[g>>2]|0)+128|0)|0;i=f;return c[e>>2]|0}function Lg(a){a=a|0;var b=0,d=0,e=0,f=0,g=0;g=i;i=i+16|0;b=g+12|0;f=g+8|0;d=g+4|0;e=g;c[b>>2]=a;c[f>>2]=16777215;c[d>>2]=0;a=(c[b>>2]|0)+128|0;c[a>>2]=(c[a>>2]|0)+1;while(1){if((c[d>>2]|0)>=4)break;if(!(c[(c[b>>2]|0)+128>>2]&c[f>>2]))break;c[d>>2]=(c[d>>2]|0)+1;c[f>>2]=(c[f>>2]|0)>>>8}c[e>>2]=3;while(1){if((c[e>>2]|0)<(c[d>>2]|0))break;Mg(c[b>>2]|0,c[d>>2]|0,c[e>>2]|0);c[e>>2]=(c[e>>2]|0)+-1}i=g;return}function Mg(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;g=e+8|0;h=e+4|0;f=e;c[g>>2]=a;c[h>>2]=b;c[f>>2]=d;dc((c[g>>2]|0)+(c[h>>2]<<5)|0,32,33193+(c[f>>2]|0)|0,1,(c[g>>2]|0)+(c[f>>2]<<5)|0);i=e;return}function Ng(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;m=i;i=i+32|0;d=m+24|0;e=m+20|0;f=m+16|0;j=m+12|0;h=m+8|0;g=m+4|0;k=m;c[d>>2]=a;c[e>>2]=b;c[f>>2]=0;while(1){if((c[f>>2]|0)>=4)break;c[j>>2]=4-(c[f>>2]|0)-1<<3;c[h>>2]=-1<>2];c[k>>2]=((c[e>>2]|0)>>>(c[j>>2]|0))-((c[(c[d>>2]|0)+128>>2]|0)>>>(c[j>>2]|0))&255;if(!(c[k>>2]|0)){if((c[e>>2]|0)>>>0<(c[(c[d>>2]|0)+128>>2]|0)>>>0){c[k>>2]=256;l=6}}else l=6;if((l|0)==6){while(1){l=0;if((c[k>>2]|0)>>>0<=1)break;Mg(c[d>>2]|0,c[f>>2]|0,c[f>>2]|0);c[k>>2]=(c[k>>2]|0)+-1;l=6}c[g>>2]=3;while(1){if((c[g>>2]|0)<(c[f>>2]|0))break;Mg(c[d>>2]|0,c[f>>2]|0,c[g>>2]|0);c[g>>2]=(c[g>>2]|0)+-1}c[(c[d>>2]|0)+128>>2]=c[e>>2]&c[h>>2]}c[f>>2]=(c[f>>2]|0)+1}i=m;return}function Og(a){a=a|0;var b=0,d=0,e=0;e=i;i=i+16|0;b=e+4|0;d=e;c[d>>2]=a;if((c[d>>2]|0)>>>0<13)c[b>>2]=c[32520+(c[d>>2]<<2)>>2];else c[b>>2]=33430;i=e;return c[b>>2]|0}function Pg(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;i=i+16|0;f=b+8|0;e=b+4|0;d=b;c[f>>2]=a;c[e>>2]=32572;c[d>>2]=ta[c[(c[c[e>>2]>>2]|0)+4>>2]&3](c[e>>2]|0,c[f>>2]|0)|0;a=ra[c[c[c[e>>2]>>2]>>2]&1](c[e>>2]|0)|0;c[d>>2]=(c[d>>2]|0)+a;a=Ha(c[d>>2]|0)|0;i=b;return a|0}function Qg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;e=i;i=i+16|0;f=e+12|0;h=e+8|0;g=e+4|0;d=e;c[f>>2]=a;c[h>>2]=b;c[g>>2]=32572;c[d>>2]=ta[c[(c[c[g>>2]>>2]|0)+4>>2]&3](c[g>>2]|0,c[h>>2]|0)|0;b=ra[c[c[c[g>>2]>>2]>>2]&1](c[g>>2]|0)|0;c[d>>2]=(c[d>>2]|0)+b;b=c[f>>2]|0;b=b+(Ha(c[d>>2]|0)|0)|0;i=e;return b+(0-(c[d>>2]|0))|0}function Rg(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=i;i=i+48|0;n=g+32|0;m=g+28|0;h=g+24|0;f=g+20|0;o=g+16|0;l=g+12|0;j=g+8|0;p=g+4|0;k=g;c[n>>2]=a;c[m>>2]=b;c[h>>2]=d;c[f>>2]=e;c[o>>2]=32572;c[l>>2]=ta[c[(c[c[o>>2]>>2]|0)+4>>2]&3](c[o>>2]|0,c[f>>2]|0)|0;e=c[l>>2]|0;c[j>>2]=e+(ra[c[c[c[o>>2]>>2]>>2]&1](c[o>>2]|0)|0);c[p>>2]=Ha(c[j>>2]|0)|0;c[k>>2]=(c[h>>2]|0)+(c[p>>2]|0)+(0-(c[j>>2]|0));sa[c[(c[c[o>>2]>>2]|0)+8>>2]&3](c[o>>2]|0,c[n>>2]|0,c[m>>2]|0,c[k>>2]|0,c[f>>2]|0,c[k>>2]|0,c[l>>2]|0,c[k>>2]|0,c[j>>2]|0)|0;Ia(c[k>>2]|0,c[j>>2]|0,c[h>>2]|0)|0;i=g;return c[f>>2]|0}function Sg(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=i;i=i+48|0;g=r+36|0;h=r+32|0;j=r+28|0;k=r+24|0;l=r+20|0;m=r+16|0;o=r+12|0;n=r+8|0;p=r+4|0;q=r;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[o>>2]=Ja(c[l>>2]|0)|0;if((c[o>>2]|0)==-1){if(c[m>>2]|0)c[c[m>>2]>>2]=7;c[g>>2]=-1;q=c[g>>2]|0;i=r;return q|0}else{Ka(c[k>>2]|0,c[l>>2]|0,c[k>>2]|0)|0;c[n>>2]=32572;f=c[o>>2]|0;c[p>>2]=f-(ra[c[c[c[n>>2]>>2]>>2]&1](c[n>>2]|0)|0);c[q>>2]=sa[c[(c[c[n>>2]>>2]|0)+16>>2]&3](c[n>>2]|0,c[h>>2]|0,c[j>>2]|0,c[k>>2]|0,c[o>>2]|0,c[k>>2]|0,c[p>>2]|0,c[k>>2]|0,c[p>>2]|0)|0;if((c[q>>2]|0)==-1&(c[m>>2]|0)!=0)c[c[m>>2]>>2]=8;c[g>>2]=c[q>>2];q=c[g>>2]|0;i=r;return q|0}return 0}function Tg(){return 268}function Ug(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=c[e>>2];Vg(c[b>>2]|0)|0;i=d;return c[b>>2]|0}function Vg(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;If(c[d>>2]|0,268);i=b;return 268}function Wg(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Og(c[(c[d>>2]|0)+264>>2]|0)|0;i=b;return a|0}function Xg(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;n=i;i=i+160|0;f=n+20|0;g=n+16|0;h=n+12|0;j=n+8|0;k=n+4|0;l=n+24|0;m=n;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[m>>2]=Ja(c[k>>2]|0)|0;if((c[m>>2]|0)==-1){c[(c[g>>2]|0)+264>>2]=7;c[f>>2]=-1;e=c[f>>2]|0;i=n;return e|0}if((c[m>>2]|0)!=128){c[(c[g>>2]|0)+264>>2]=11;c[f>>2]=-1;e=c[f>>2]|0;i=n;return e|0}else{Ka(c[j>>2]|0,c[k>>2]|0,l)|0;Hg(c[g>>2]|0,l,c[h>>2]|0);Hg((c[g>>2]|0)+132|0,l,c[h>>2]|0);If(l,128);c[f>>2]=0;e=c[f>>2]|0;i=n;return e|0}return 0}function Yg(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Pg(Zg(c[d>>2]|0)|0)|0;i=b;return a|0}function Zg(a){a=a|0;var b=0,d=0,e=0;d=i;i=i+16|0;e=d+4|0;b=d;c[e>>2]=a;c[b>>2]=0;c[b>>2]=(c[b>>2]|0)+4;a=Ig(c[e>>2]|0)|0;c[b>>2]=(c[b>>2]|0)+a;a=Ig((c[e>>2]|0)+132|0)|0;c[b>>2]=(c[b>>2]|0)+a;i=d;return c[b>>2]|0} +function Vf(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Ob=0,Pb=0,Qb=0,Rb=0,Sb=0,Tb=0,Ub=0,Vb=0,Wb=0,Xb=0,Yb=0,Zb=0,_b=0,$b=0,ac=0,bc=0;e=i;i=i+1120|0;f=e+1104|0;bc=e+1100|0;ac=e+1096|0;$b=e+1092|0;Zb=e+1088|0;Vb=e+1084|0;Tb=e+1080|0;Qb=e+1076|0;Ob=e+1072|0;Lb=e+1068|0;Jb=e+1064|0;Gb=e+1060|0;xb=e+1056|0;Fb=e+1052|0;Hb=e+1048|0;Kb=e+1044|0;Mb=e+1040|0;Pb=e+1036|0;Rb=e+1032|0;Ub=e+1028|0;Wb=e+1024|0;Yb=e+1020|0;_b=e+1016|0;Eb=e+1012|0;Db=e+1008|0;Cb=e+1004|0;Bb=e+1e3|0;Ab=e+996|0;zb=e+992|0;yb=e+988|0;wb=e+984|0;ub=e+980|0;Xb=e+976|0;Sb=e+972|0;Nb=e+968|0;Ib=e+964|0;vb=e+960|0;tb=e+952|0;jb=e+944|0;$a=e+936|0;Ra=e+928|0;Ha=e+920|0;xa=e+912|0;na=e+904|0;da=e+896|0;V=e+888|0;L=e+880|0;ib=e+872|0;_a=e+864|0;Qa=e+856|0;Ga=e+848|0;wa=e+840|0;ma=e+832|0;ca=e+824|0;U=e+816|0;K=e+808|0;sb=e+800|0;Za=e+792|0;Pa=e+784|0;Fa=e+776|0;va=e+768|0;la=e+760|0;ba=e+752|0;T=e+744|0;J=e+736|0;rb=e+728|0;hb=e+720|0;Oa=e+712|0;Ea=e+704|0;ua=e+696|0;ka=e+688|0;aa=e+680|0;S=e+672|0;I=e+664|0;qb=e+656|0;gb=e+648|0;Ya=e+640|0;Da=e+632|0;ta=e+624|0;ja=e+616|0;$=e+608|0;R=e+600|0;H=e+592|0;pb=e+584|0;fb=e+576|0;Xa=e+568|0;Na=e+560|0;sa=e+552|0;ia=e+544|0;_=e+536|0;Q=e+528|0;G=e+520|0;ob=e+512|0;eb=e+504|0;Wa=e+496|0;Ma=e+488|0;Ca=e+480|0;ha=e+472|0;Z=e+464|0;P=e+456|0;F=e+448|0;nb=e+440|0;db=e+432|0;Va=e+424|0;La=e+416|0;Ba=e+408|0;ra=e+400|0;Y=e+392|0;O=e+384|0;E=e+376|0;mb=e+368|0;cb=e+360|0;Ua=e+352|0;Ka=e+344|0;Aa=e+336|0;qa=e+328|0;ga=e+320|0;N=e+312|0;D=e+304|0;lb=e+296|0;bb=e+288|0;Ta=e+280|0;Ja=e+272|0;za=e+264|0;pa=e+256|0;fa=e+248|0;X=e+240|0;B=e+232|0;kb=e+224|0;ab=e+216|0;Sa=e+208|0;Ia=e+200|0;ya=e+192|0;oa=e+184|0;ea=e+176|0;W=e+168|0;M=e+160|0;q=e+152|0;p=e+144|0;o=e+136|0;n=e+128|0;m=e+120|0;l=e+112|0;k=e+104|0;j=e+96|0;h=e+88|0;g=e+80|0;r=e+72|0;A=e+64|0;y=e+56|0;w=e+48|0;u=e+40|0;z=e+32|0;x=e+24|0;v=e+16|0;t=e+8|0;s=e;c[f>>2]=a;c[bc>>2]=b;c[ac>>2]=d;c[$b>>2]=c[c[bc>>2]>>2];c[Zb>>2]=c[(c[bc>>2]|0)+4>>2];c[Vb>>2]=c[(c[bc>>2]|0)+8>>2];c[Tb>>2]=c[(c[bc>>2]|0)+12>>2];c[Qb>>2]=c[(c[bc>>2]|0)+16>>2];c[Ob>>2]=c[(c[bc>>2]|0)+20>>2];c[Lb>>2]=c[(c[bc>>2]|0)+24>>2];c[Jb>>2]=c[(c[bc>>2]|0)+28>>2];c[Gb>>2]=c[(c[bc>>2]|0)+32>>2];c[xb>>2]=c[(c[bc>>2]|0)+36>>2];c[Fb>>2]=c[c[ac>>2]>>2];c[Hb>>2]=c[(c[ac>>2]|0)+4>>2];c[Kb>>2]=c[(c[ac>>2]|0)+8>>2];c[Mb>>2]=c[(c[ac>>2]|0)+12>>2];c[Pb>>2]=c[(c[ac>>2]|0)+16>>2];c[Rb>>2]=c[(c[ac>>2]|0)+20>>2];c[Ub>>2]=c[(c[ac>>2]|0)+24>>2];c[Wb>>2]=c[(c[ac>>2]|0)+28>>2];c[Yb>>2]=c[(c[ac>>2]|0)+32>>2];c[_b>>2]=c[(c[ac>>2]|0)+36>>2];c[Eb>>2]=(c[Hb>>2]|0)*19;c[Db>>2]=(c[Kb>>2]|0)*19;c[Cb>>2]=(c[Mb>>2]|0)*19;c[Bb>>2]=(c[Pb>>2]|0)*19;c[Ab>>2]=(c[Rb>>2]|0)*19;c[zb>>2]=(c[Ub>>2]|0)*19;c[yb>>2]=(c[Wb>>2]|0)*19;c[wb>>2]=(c[Yb>>2]|0)*19;c[ub>>2]=(c[_b>>2]|0)*19;c[Xb>>2]=c[Zb>>2]<<1;c[Sb>>2]=c[Tb>>2]<<1;c[Nb>>2]=c[Ob>>2]<<1;c[Ib>>2]=c[Jb>>2]<<1;c[vb>>2]=c[xb>>2]<<1;a=c[$b>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=tb;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=jb;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[Kb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=$a;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[Mb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ra;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[Pb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ha;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[Rb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=xa;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[Ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=na;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[Wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=da;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[Yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=V;c[a>>2]=d;c[a+4>>2]=C;a=c[$b>>2]|0;d=c[_b>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=L;c[a>>2]=d;c[a+4>>2]=C;a=c[Zb>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ib;c[a>>2]=d;c[a+4>>2]=C;a=c[Xb>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=_a;c[a>>2]=d;c[a+4>>2]=C;a=c[Zb>>2]|0;d=c[Kb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Qa;c[a>>2]=d;c[a+4>>2]=C;a=c[Xb>>2]|0;d=c[Mb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ga;c[a>>2]=d;c[a+4>>2]=C;a=c[Zb>>2]|0;d=c[Pb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=wa;c[a>>2]=d;c[a+4>>2]=C;a=c[Xb>>2]|0;d=c[Rb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ma;c[a>>2]=d;c[a+4>>2]=C;a=c[Zb>>2]|0;d=c[Ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ca;c[a>>2]=d;c[a+4>>2]=C;a=c[Xb>>2]|0;d=c[Wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=U;c[a>>2]=d;c[a+4>>2]=C;a=c[Zb>>2]|0;d=c[Yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=K;c[a>>2]=d;c[a+4>>2]=C;a=c[Xb>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=sb;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Za;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Pa;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[Kb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Fa;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[Mb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=va;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[Pb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=la;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[Rb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ba;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[Ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=T;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[Wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=J;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=rb;c[a>>2]=d;c[a+4>>2]=C;a=c[Vb>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=hb;c[a>>2]=d;c[a+4>>2]=C;a=c[Tb>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Oa;c[a>>2]=d;c[a+4>>2]=C;a=c[Sb>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ea;c[a>>2]=d;c[a+4>>2]=C;a=c[Tb>>2]|0;d=c[Kb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ua;c[a>>2]=d;c[a+4>>2]=C;a=c[Sb>>2]|0;d=c[Mb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ka;c[a>>2]=d;c[a+4>>2]=C;a=c[Tb>>2]|0;d=c[Pb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=aa;c[a>>2]=d;c[a+4>>2]=C;a=c[Sb>>2]|0;d=c[Rb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=S;c[a>>2]=d;c[a+4>>2]=C;a=c[Tb>>2]|0;d=c[Ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=I;c[a>>2]=d;c[a+4>>2]=C;a=c[Sb>>2]|0;d=c[yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=qb;c[a>>2]=d;c[a+4>>2]=C;a=c[Tb>>2]|0;d=c[wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=gb;c[a>>2]=d;c[a+4>>2]=C;a=c[Sb>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ya;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Da;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ta;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[Kb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ja;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[Mb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=$;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[Pb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=R;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[Rb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=H;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[zb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=pb;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=fb;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Xa;c[a>>2]=d;c[a+4>>2]=C;a=c[Qb>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Na;c[a>>2]=d;c[a+4>>2]=C;a=c[Ob>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=sa;c[a>>2]=d;c[a+4>>2]=C;a=c[Nb>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ia;c[a>>2]=d;c[a+4>>2]=C;a=c[Ob>>2]|0;d=c[Kb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=_;c[a>>2]=d;c[a+4>>2]=C;a=c[Nb>>2]|0;d=c[Mb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Q;c[a>>2]=d;c[a+4>>2]=C;a=c[Ob>>2]|0;d=c[Pb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=G;c[a>>2]=d;c[a+4>>2]=C;a=c[Nb>>2]|0;d=c[Ab>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ob;c[a>>2]=d;c[a+4>>2]=C;a=c[Ob>>2]|0;d=c[zb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=eb;c[a>>2]=d;c[a+4>>2]=C;a=c[Nb>>2]|0;d=c[yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Wa;c[a>>2]=d;c[a+4>>2]=C;a=c[Ob>>2]|0;d=c[wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ma;c[a>>2]=d;c[a+4>>2]=C;a=c[Nb>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ca;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ha;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Z;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[Kb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=P;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[Mb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=F;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[Bb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=nb;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[Ab>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=db;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[zb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Va;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=La;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ba;c[a>>2]=d;c[a+4>>2]=C;a=c[Lb>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ra;c[a>>2]=d;c[a+4>>2]=C;a=c[Jb>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Y;c[a>>2]=d;c[a+4>>2]=C;a=c[Ib>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=O;c[a>>2]=d;c[a+4>>2]=C;a=c[Jb>>2]|0;d=c[Kb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=E;c[a>>2]=d;c[a+4>>2]=C;a=c[Ib>>2]|0;d=c[Cb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=mb;c[a>>2]=d;c[a+4>>2]=C;a=c[Jb>>2]|0;d=c[Bb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=cb;c[a>>2]=d;c[a+4>>2]=C;a=c[Ib>>2]|0;d=c[Ab>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ua;c[a>>2]=d;c[a+4>>2]=C;a=c[Jb>>2]|0;d=c[zb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ka;c[a>>2]=d;c[a+4>>2]=C;a=c[Ib>>2]|0;d=c[yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Aa;c[a>>2]=d;c[a+4>>2]=C;a=c[Jb>>2]|0;d=c[wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=qa;c[a>>2]=d;c[a+4>>2]=C;a=c[Ib>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ga;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=N;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[Hb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=D;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[Db>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=lb;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[Cb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=bb;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[Bb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ta;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[Ab>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ja;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[zb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=za;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=pa;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=fa;c[a>>2]=d;c[a+4>>2]=C;a=c[Gb>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=X;c[a>>2]=d;c[a+4>>2]=C;a=c[xb>>2]|0;d=c[Fb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=B;c[a>>2]=d;c[a+4>>2]=C;a=c[vb>>2]|0;d=c[Eb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=kb;c[a>>2]=d;c[a+4>>2]=C;a=c[xb>>2]|0;d=c[Db>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ab;c[a>>2]=d;c[a+4>>2]=C;a=c[vb>>2]|0;d=c[Cb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Sa;c[a>>2]=d;c[a+4>>2]=C;a=c[xb>>2]|0;d=c[Bb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=Ia;c[a>>2]=d;c[a+4>>2]=C;a=c[vb>>2]|0;d=c[Ab>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ya;c[a>>2]=d;c[a+4>>2]=C;a=c[xb>>2]|0;d=c[zb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=oa;c[a>>2]=d;c[a+4>>2]=C;a=c[vb>>2]|0;d=c[yb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=ea;c[a>>2]=d;c[a+4>>2]=C;a=c[xb>>2]|0;d=c[wb>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=W;c[a>>2]=d;c[a+4>>2]=C;a=c[vb>>2]|0;d=c[ub>>2]|0;d=_h(a|0,((a|0)<0)<<31>>31|0,d|0,((d|0)<0)<<31>>31|0)|0;a=M;c[a>>2]=d;c[a+4>>2]=C;a=tb;d=sb;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=rb;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=qb;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=pb;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=ob;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=nb;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=mb;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=lb;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=kb;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=q;c[a>>2]=d;c[a+4>>2]=C;a=jb;d=ib;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=hb;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=gb;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=fb;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=eb;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=db;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=cb;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=bb;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=ab;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=p;c[a>>2]=d;c[a+4>>2]=C;a=$a;d=_a;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Za;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Ya;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Xa;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Wa;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Va;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Ua;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Ta;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Sa;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=o;c[a>>2]=d;c[a+4>>2]=C;a=Ra;d=Qa;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Pa;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Oa;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Na;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Ma;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=La;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Ka;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Ja;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Ia;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=n;c[a>>2]=d;c[a+4>>2]=C;a=Ha;d=Ga;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Fa;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Ea;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Da;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Ca;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Ba;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Aa;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=za;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=ya;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=m;c[a>>2]=d;c[a+4>>2]=C;a=xa;d=wa;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=va;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=ua;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=ta;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=sa;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=ra;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=qa;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=pa;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=oa;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=l;c[a>>2]=d;c[a+4>>2]=C;a=na;d=ma;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=la;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=ka;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=ja;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=ia;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=ha;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=ga;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=fa;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=ea;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=k;c[a>>2]=d;c[a+4>>2]=C;a=da;d=ca;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=ba;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=aa;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=$;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=_;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=Z;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Y;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=X;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=W;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=j;c[a>>2]=d;c[a+4>>2]=C;a=V;d=U;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=T;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=S;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=R;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=Q;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=P;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=O;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=N;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=M;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=h;c[a>>2]=d;c[a+4>>2]=C;a=L;d=K;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=J;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=I;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=H;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=G;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=F;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=E;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=D;a=Qh(d|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=B;d=Qh(a|0,C|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=g;c[a>>2]=d;c[a+4>>2]=C;a=q;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;d=r;c[d>>2]=a;c[d+4>>2]=C;d=r;a=p;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=p;c[a>>2]=d;c[a+4>>2]=C;a=r;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;d=q;a=Ph(c[d>>2]|0,c[d+4>>2]|0,a|0,C|0)|0;d=q;c[d>>2]=a;c[d+4>>2]=C;d=m;d=Qh(c[d>>2]|0,c[d+4>>2]|0,33554432,0)|0;d=Rh(d|0,C|0,26)|0;a=u;c[a>>2]=d;c[a+4>>2]=C;a=u;d=l;a=Qh(c[d>>2]|0,c[d+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=l;c[d>>2]=a;c[d+4>>2]=C;d=u;d=Uh(c[d>>2]|0,c[d+4>>2]|0,26)|0;a=m;d=Ph(c[a>>2]|0,c[a+4>>2]|0,d|0,C|0)|0;a=m;c[a>>2]=d;c[a+4>>2]=C;a=p;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;d=A;c[d>>2]=a;c[d+4>>2]=C;d=A;a=o;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=o;c[a>>2]=d;c[a+4>>2]=C;a=A;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;d=p;a=Ph(c[d>>2]|0,c[d+4>>2]|0,a|0,C|0)|0;d=p;c[d>>2]=a;c[d+4>>2]=C;d=l;d=Qh(c[d>>2]|0,c[d+4>>2]|0,16777216,0)|0;d=Rh(d|0,C|0,25)|0;a=z;c[a>>2]=d;c[a+4>>2]=C;a=z;d=k;a=Qh(c[d>>2]|0,c[d+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=k;c[d>>2]=a;c[d+4>>2]=C;d=z;d=Uh(c[d>>2]|0,c[d+4>>2]|0,25)|0;a=l;d=Ph(c[a>>2]|0,c[a+4>>2]|0,d|0,C|0)|0;a=l;c[a>>2]=d;c[a+4>>2]=C;a=o;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;d=y;c[d>>2]=a;c[d+4>>2]=C;d=y;a=n;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=n;c[a>>2]=d;c[a+4>>2]=C;a=y;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;d=o;a=Ph(c[d>>2]|0,c[d+4>>2]|0,a|0,C|0)|0;d=o;c[d>>2]=a;c[d+4>>2]=C;d=k;d=Qh(c[d>>2]|0,c[d+4>>2]|0,33554432,0)|0;d=Rh(d|0,C|0,26)|0;a=x;c[a>>2]=d;c[a+4>>2]=C;a=x;d=j;a=Qh(c[d>>2]|0,c[d+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=j;c[d>>2]=a;c[d+4>>2]=C;d=x;d=Uh(c[d>>2]|0,c[d+4>>2]|0,26)|0;a=k;d=Ph(c[a>>2]|0,c[a+4>>2]|0,d|0,C|0)|0;a=k;c[a>>2]=d;c[a+4>>2]=C;a=n;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;d=w;c[d>>2]=a;c[d+4>>2]=C;d=w;a=m;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=m;c[a>>2]=d;c[a+4>>2]=C;a=w;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;d=n;a=Ph(c[d>>2]|0,c[d+4>>2]|0,a|0,C|0)|0;d=n;c[d>>2]=a;c[d+4>>2]=C;d=j;d=Qh(c[d>>2]|0,c[d+4>>2]|0,16777216,0)|0;d=Rh(d|0,C|0,25)|0;a=v;c[a>>2]=d;c[a+4>>2]=C;a=v;d=h;a=Qh(c[d>>2]|0,c[d+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=h;c[d>>2]=a;c[d+4>>2]=C;d=v;d=Uh(c[d>>2]|0,c[d+4>>2]|0,25)|0;a=j;d=Ph(c[a>>2]|0,c[a+4>>2]|0,d|0,C|0)|0;a=j;c[a>>2]=d;c[a+4>>2]=C;a=m;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;d=u;c[d>>2]=a;c[d+4>>2]=C;d=u;a=l;d=Qh(c[a>>2]|0,c[a+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;a=l;c[a>>2]=d;c[a+4>>2]=C;a=u;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;d=m;a=Ph(c[d>>2]|0,c[d+4>>2]|0,a|0,C|0)|0;d=m;c[d>>2]=a;c[d+4>>2]=C;d=h;d=Qh(c[d>>2]|0,c[d+4>>2]|0,33554432,0)|0;d=Rh(d|0,C|0,26)|0;a=t;c[a>>2]=d;c[a+4>>2]=C;a=t;d=g;a=Qh(c[d>>2]|0,c[d+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=g;c[d>>2]=a;c[d+4>>2]=C;d=t;d=Uh(c[d>>2]|0,c[d+4>>2]|0,26)|0;a=h;d=Ph(c[a>>2]|0,c[a+4>>2]|0,d|0,C|0)|0;a=h;c[a>>2]=d;c[a+4>>2]=C;a=g;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;d=s;c[d>>2]=a;c[d+4>>2]=C;d=s;d=_h(c[d>>2]|0,c[d+4>>2]|0,19,0)|0;a=q;d=Qh(c[a>>2]|0,c[a+4>>2]|0,d|0,C|0)|0;a=q;c[a>>2]=d;c[a+4>>2]=C;a=s;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;d=g;a=Ph(c[d>>2]|0,c[d+4>>2]|0,a|0,C|0)|0;d=g;c[d>>2]=a;c[d+4>>2]=C;d=q;d=Qh(c[d>>2]|0,c[d+4>>2]|0,33554432,0)|0;d=Rh(d|0,C|0,26)|0;a=r;c[a>>2]=d;c[a+4>>2]=C;a=r;d=p;a=Qh(c[d>>2]|0,c[d+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;d=p;c[d>>2]=a;c[d+4>>2]=C;d=r;d=Uh(c[d>>2]|0,c[d+4>>2]|0,26)|0;a=q;d=Ph(c[a>>2]|0,c[a+4>>2]|0,d|0,C|0)|0;a=q;c[a>>2]=d;c[a+4>>2]=C;c[c[f>>2]>>2]=c[q>>2];c[(c[f>>2]|0)+4>>2]=c[p>>2];c[(c[f>>2]|0)+8>>2]=c[o>>2];c[(c[f>>2]|0)+12>>2]=c[n>>2];c[(c[f>>2]|0)+16>>2]=c[m>>2];c[(c[f>>2]|0)+20>>2]=c[l>>2];c[(c[f>>2]|0)+24>>2]=c[k>>2];c[(c[f>>2]|0)+28>>2]=c[j>>2];c[(c[f>>2]|0)+32>>2]=c[h>>2];c[(c[f>>2]|0)+36>>2]=c[g>>2];i=e;return}function Wf(a){a=a|0;var b=0,e=0,f=0;e=i;i=i+48|0;f=e;b=e+8|0;c[f>>2]=a;Xf(b,c[f>>2]|0);i=e;return (d[b>>0]|0)&1|0}function Xf(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;e=i;i=i+96|0;f=e+88|0;C=e+84|0;q=e+80|0;p=e+76|0;o=e+72|0;n=e+68|0;m=e+64|0;l=e+60|0;k=e+56|0;j=e+52|0;h=e+48|0;g=e+44|0;B=e+40|0;A=e+36|0;z=e+32|0;y=e+28|0;x=e+24|0;w=e+20|0;v=e+16|0;u=e+12|0;t=e+8|0;s=e+4|0;r=e;c[f>>2]=b;c[C>>2]=d;c[q>>2]=c[c[C>>2]>>2];c[p>>2]=c[(c[C>>2]|0)+4>>2];c[o>>2]=c[(c[C>>2]|0)+8>>2];c[n>>2]=c[(c[C>>2]|0)+12>>2];c[m>>2]=c[(c[C>>2]|0)+16>>2];c[l>>2]=c[(c[C>>2]|0)+20>>2];c[k>>2]=c[(c[C>>2]|0)+24>>2];c[j>>2]=c[(c[C>>2]|0)+28>>2];c[h>>2]=c[(c[C>>2]|0)+32>>2];c[g>>2]=c[(c[C>>2]|0)+36>>2];c[B>>2]=((c[g>>2]|0)*19|0)+16777216>>25;c[B>>2]=(c[q>>2]|0)+(c[B>>2]|0)>>26;c[B>>2]=(c[p>>2]|0)+(c[B>>2]|0)>>25;c[B>>2]=(c[o>>2]|0)+(c[B>>2]|0)>>26;c[B>>2]=(c[n>>2]|0)+(c[B>>2]|0)>>25;c[B>>2]=(c[m>>2]|0)+(c[B>>2]|0)>>26;c[B>>2]=(c[l>>2]|0)+(c[B>>2]|0)>>25;c[B>>2]=(c[k>>2]|0)+(c[B>>2]|0)>>26;c[B>>2]=(c[j>>2]|0)+(c[B>>2]|0)>>25;c[B>>2]=(c[h>>2]|0)+(c[B>>2]|0)>>26;c[B>>2]=(c[g>>2]|0)+(c[B>>2]|0)>>25;c[q>>2]=(c[q>>2]|0)+((c[B>>2]|0)*19|0);c[A>>2]=c[q>>2]>>26;c[p>>2]=(c[p>>2]|0)+(c[A>>2]|0);c[q>>2]=(c[q>>2]|0)-(c[A>>2]<<26);c[z>>2]=c[p>>2]>>25;c[o>>2]=(c[o>>2]|0)+(c[z>>2]|0);c[p>>2]=(c[p>>2]|0)-(c[z>>2]<<25);c[y>>2]=c[o>>2]>>26;c[n>>2]=(c[n>>2]|0)+(c[y>>2]|0);c[o>>2]=(c[o>>2]|0)-(c[y>>2]<<26);c[x>>2]=c[n>>2]>>25;c[m>>2]=(c[m>>2]|0)+(c[x>>2]|0);c[n>>2]=(c[n>>2]|0)-(c[x>>2]<<25);c[w>>2]=c[m>>2]>>26;c[l>>2]=(c[l>>2]|0)+(c[w>>2]|0);c[m>>2]=(c[m>>2]|0)-(c[w>>2]<<26);c[v>>2]=c[l>>2]>>25;c[k>>2]=(c[k>>2]|0)+(c[v>>2]|0);c[l>>2]=(c[l>>2]|0)-(c[v>>2]<<25);c[u>>2]=c[k>>2]>>26;c[j>>2]=(c[j>>2]|0)+(c[u>>2]|0);c[k>>2]=(c[k>>2]|0)-(c[u>>2]<<26);c[t>>2]=c[j>>2]>>25;c[h>>2]=(c[h>>2]|0)+(c[t>>2]|0);c[j>>2]=(c[j>>2]|0)-(c[t>>2]<<25);c[s>>2]=c[h>>2]>>26;c[g>>2]=(c[g>>2]|0)+(c[s>>2]|0);c[h>>2]=(c[h>>2]|0)-(c[s>>2]<<26);c[r>>2]=c[g>>2]>>25;c[g>>2]=(c[g>>2]|0)-(c[r>>2]<<25);a[c[f>>2]>>0]=c[q>>2]>>0;a[(c[f>>2]|0)+1>>0]=c[q>>2]>>8;a[(c[f>>2]|0)+2>>0]=c[q>>2]>>16;a[(c[f>>2]|0)+3>>0]=c[q>>2]>>24|c[p>>2]<<2;a[(c[f>>2]|0)+4>>0]=c[p>>2]>>6;a[(c[f>>2]|0)+5>>0]=c[p>>2]>>14;a[(c[f>>2]|0)+6>>0]=c[p>>2]>>22|c[o>>2]<<3;a[(c[f>>2]|0)+7>>0]=c[o>>2]>>5;a[(c[f>>2]|0)+8>>0]=c[o>>2]>>13;a[(c[f>>2]|0)+9>>0]=c[o>>2]>>21|c[n>>2]<<5;a[(c[f>>2]|0)+10>>0]=c[n>>2]>>3;a[(c[f>>2]|0)+11>>0]=c[n>>2]>>11;a[(c[f>>2]|0)+12>>0]=c[n>>2]>>19|c[m>>2]<<6;a[(c[f>>2]|0)+13>>0]=c[m>>2]>>2;a[(c[f>>2]|0)+14>>0]=c[m>>2]>>10;a[(c[f>>2]|0)+15>>0]=c[m>>2]>>18;a[(c[f>>2]|0)+16>>0]=c[l>>2]>>0;a[(c[f>>2]|0)+17>>0]=c[l>>2]>>8;a[(c[f>>2]|0)+18>>0]=c[l>>2]>>16;a[(c[f>>2]|0)+19>>0]=c[l>>2]>>24|c[k>>2]<<1;a[(c[f>>2]|0)+20>>0]=c[k>>2]>>7;a[(c[f>>2]|0)+21>>0]=c[k>>2]>>15;a[(c[f>>2]|0)+22>>0]=c[k>>2]>>23|c[j>>2]<<3;a[(c[f>>2]|0)+23>>0]=c[j>>2]>>5;a[(c[f>>2]|0)+24>>0]=c[j>>2]>>13;a[(c[f>>2]|0)+25>>0]=c[j>>2]>>21|c[h>>2]<<4;a[(c[f>>2]|0)+26>>0]=c[h>>2]>>4;a[(c[f>>2]|0)+27>>0]=c[h>>2]>>12;a[(c[f>>2]|0)+28>>0]=c[h>>2]>>20|c[g>>2]<<6;a[(c[f>>2]|0)+29>>0]=c[g>>2]>>2;a[(c[f>>2]|0)+30>>0]=c[g>>2]>>10;a[(c[f>>2]|0)+31>>0]=c[g>>2]>>18;i=e;return}function Yf(b){b=b|0;var e=0,f=0,g=0,h=0;f=i;i=i+48|0;h=f;g=f+8|0;e=f+4|0;c[h>>2]=b;Xf(g,c[h>>2]|0);a[e>>0]=a[g>>0]|0;a[e>>0]=d[e>>0]|0|(d[g+1>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+2>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+3>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+4>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+5>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+6>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+7>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+8>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+9>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+10>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+11>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+12>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+13>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+14>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+15>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+16>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+17>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+18>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+19>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+20>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+21>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+22>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+23>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+24>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+25>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+26>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+27>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+28>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+29>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+30>>0]|0);a[e>>0]=d[e>>0]|0|(d[g+31>>0]|0);i=f;return (d[e>>0]|0|0)!=0|0}function Zf(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;d=i;i=i+96|0;e=d+84|0;A=d+80|0;z=d+76|0;y=d+72|0;x=d+68|0;w=d+64|0;v=d+60|0;u=d+56|0;t=d+52|0;s=d+48|0;r=d+44|0;q=d+40|0;p=d+36|0;o=d+32|0;n=d+28|0;m=d+24|0;l=d+20|0;k=d+16|0;j=d+12|0;h=d+8|0;g=d+4|0;f=d;c[e>>2]=a;c[A>>2]=b;c[z>>2]=c[c[A>>2]>>2];c[y>>2]=c[(c[A>>2]|0)+4>>2];c[x>>2]=c[(c[A>>2]|0)+8>>2];c[w>>2]=c[(c[A>>2]|0)+12>>2];c[v>>2]=c[(c[A>>2]|0)+16>>2];c[u>>2]=c[(c[A>>2]|0)+20>>2];c[t>>2]=c[(c[A>>2]|0)+24>>2];c[s>>2]=c[(c[A>>2]|0)+28>>2];c[r>>2]=c[(c[A>>2]|0)+32>>2];c[q>>2]=c[(c[A>>2]|0)+36>>2];c[p>>2]=0-(c[z>>2]|0);c[o>>2]=0-(c[y>>2]|0);c[n>>2]=0-(c[x>>2]|0);c[m>>2]=0-(c[w>>2]|0);c[l>>2]=0-(c[v>>2]|0);c[k>>2]=0-(c[u>>2]|0);c[j>>2]=0-(c[t>>2]|0);c[h>>2]=0-(c[s>>2]|0);c[g>>2]=0-(c[r>>2]|0);c[f>>2]=0-(c[q>>2]|0);c[c[e>>2]>>2]=c[p>>2];c[(c[e>>2]|0)+4>>2]=c[o>>2];c[(c[e>>2]|0)+8>>2]=c[n>>2];c[(c[e>>2]|0)+12>>2]=c[m>>2];c[(c[e>>2]|0)+16>>2]=c[l>>2];c[(c[e>>2]|0)+20>>2]=c[k>>2];c[(c[e>>2]|0)+24>>2]=c[j>>2];c[(c[e>>2]|0)+28>>2]=c[h>>2];c[(c[e>>2]|0)+32>>2]=c[g>>2];c[(c[e>>2]|0)+36>>2]=c[f>>2];i=d;return}function _f(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;k=i;i=i+144|0;d=k+132|0;e=k+128|0;g=k+88|0;h=k+48|0;j=k+8|0;f=k;c[d>>2]=a;c[e>>2]=b;Uf(g,c[e>>2]|0);c[f>>2]=1;while(1){if((c[f>>2]|0)>=1)break;Uf(g,g);c[f>>2]=(c[f>>2]|0)+1}Uf(h,g);c[f>>2]=1;while(1){if((c[f>>2]|0)>=2)break;Uf(h,h);c[f>>2]=(c[f>>2]|0)+1}Vf(h,c[e>>2]|0,h);Vf(g,g,h);Uf(g,g);c[f>>2]=1;while(1){if((c[f>>2]|0)>=1)break;Uf(g,g);c[f>>2]=(c[f>>2]|0)+1}Vf(g,h,g);Uf(h,g);c[f>>2]=1;while(1){if((c[f>>2]|0)>=5)break;Uf(h,h);c[f>>2]=(c[f>>2]|0)+1}Vf(g,h,g);Uf(h,g);c[f>>2]=1;while(1){if((c[f>>2]|0)>=10)break;Uf(h,h);c[f>>2]=(c[f>>2]|0)+1}Vf(h,h,g);Uf(j,h);c[f>>2]=1;while(1){if((c[f>>2]|0)>=20)break;Uf(j,j);c[f>>2]=(c[f>>2]|0)+1}Vf(h,j,h);Uf(h,h);c[f>>2]=1;while(1){if((c[f>>2]|0)>=10)break;Uf(h,h);c[f>>2]=(c[f>>2]|0)+1}Vf(g,h,g);Uf(h,g);c[f>>2]=1;while(1){if((c[f>>2]|0)>=50)break;Uf(h,h);c[f>>2]=(c[f>>2]|0)+1}Vf(h,h,g);Uf(j,h);c[f>>2]=1;while(1){if((c[f>>2]|0)>=100)break;Uf(j,j);c[f>>2]=(c[f>>2]|0)+1}Vf(h,j,h);Uf(h,h);c[f>>2]=1;while(1){if((c[f>>2]|0)>=50)break;Uf(h,h);c[f>>2]=(c[f>>2]|0)+1}Vf(g,h,g);Uf(g,g);c[f>>2]=1;while(1){if((c[f>>2]|0)>=2)break;Uf(g,g);c[f>>2]=(c[f>>2]|0)+1}Vf(c[d>>2]|0,g,c[e>>2]|0);i=k;return}function $f(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0;d=i;i=i+704|0;e=d+696|0;Za=d+692|0;Ya=d+688|0;Wa=d+684|0;Ta=d+680|0;Sa=d+676|0;Pa=d+672|0;Oa=d+668|0;Ja=d+664|0;Ia=d+660|0;Ea=d+656|0;Da=d+652|0;Xa=d+648|0;Va=d+644|0;Ua=d+640|0;Ra=d+636|0;Qa=d+632|0;Ma=d+628|0;Ka=d+624|0;Ga=d+620|0;Na=d+616|0;La=d+612|0;Ha=d+608|0;Fa=d+604|0;Ca=d+600|0;Ba=d+592|0;va=d+584|0;qa=d+576|0;ka=d+568|0;fa=d+560|0;$=d+552|0;W=d+544|0;Q=d+536|0;L=d+528|0;F=d+520|0;pa=d+512|0;ja=d+504|0;ea=d+496|0;_=d+488|0;V=d+480|0;P=d+472|0;K=d+464|0;E=d+456|0;Aa=d+448|0;da=d+440|0;Z=d+432|0;U=d+424|0;O=d+416|0;J=d+408|0;D=d+400|0;za=d+392|0;ua=d+384|0;T=d+376|0;N=d+368|0;I=d+360|0;B=d+352|0;ya=d+344|0;ta=d+336|0;oa=d+328|0;H=d+320|0;A=d+312|0;xa=d+304|0;sa=d+296|0;na=d+288|0;ia=d+280|0;wa=d+272|0;ra=d+264|0;ma=d+256|0;ha=d+248|0;ca=d+240|0;la=d+232|0;ga=d+224|0;ba=d+216|0;Y=d+208|0;aa=d+200|0;X=d+192|0;S=d+184|0;R=d+176|0;M=d+168|0;G=d+160|0;p=d+152|0;o=d+144|0;n=d+136|0;m=d+128|0;l=d+120|0;k=d+112|0;j=d+104|0;h=d+96|0;g=d+88|0;f=d+80|0;q=d+72|0;z=d+64|0;x=d+56|0;v=d+48|0;t=d+40|0;y=d+32|0;w=d+24|0;u=d+16|0;s=d+8|0;r=d;c[e>>2]=a;c[Za>>2]=b;c[Ya>>2]=c[c[Za>>2]>>2];c[Wa>>2]=c[(c[Za>>2]|0)+4>>2];c[Ta>>2]=c[(c[Za>>2]|0)+8>>2];c[Sa>>2]=c[(c[Za>>2]|0)+12>>2];c[Pa>>2]=c[(c[Za>>2]|0)+16>>2];c[Oa>>2]=c[(c[Za>>2]|0)+20>>2];c[Ja>>2]=c[(c[Za>>2]|0)+24>>2];c[Ia>>2]=c[(c[Za>>2]|0)+28>>2];c[Ea>>2]=c[(c[Za>>2]|0)+32>>2];c[Da>>2]=c[(c[Za>>2]|0)+36>>2];c[Xa>>2]=c[Ya>>2]<<1;c[Va>>2]=c[Wa>>2]<<1;c[Ua>>2]=c[Ta>>2]<<1;c[Ra>>2]=c[Sa>>2]<<1;c[Qa>>2]=c[Pa>>2]<<1;c[Ma>>2]=c[Oa>>2]<<1;c[Ka>>2]=c[Ja>>2]<<1;c[Ga>>2]=c[Ia>>2]<<1;c[Na>>2]=(c[Oa>>2]|0)*38;c[La>>2]=(c[Ja>>2]|0)*19;c[Ha>>2]=(c[Ia>>2]|0)*38;c[Fa>>2]=(c[Ea>>2]|0)*19;c[Ca>>2]=(c[Da>>2]|0)*38;b=c[Ya>>2]|0;a=c[Ya>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Ba;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Wa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=va;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Ta>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=qa;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Sa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ka;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=fa;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Oa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=$;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Ja>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=W;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Ia>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Q;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Ea>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=L;c[b>>2]=a;c[b+4>>2]=C;b=c[Xa>>2]|0;a=c[Da>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=F;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Wa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=pa;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ta>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ja;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ra>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ea;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=_;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ma>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=V;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ja>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=P;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ga>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=K;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ea>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=E;c[b>>2]=a;c[b+4>>2]=C;b=c[Va>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Aa;c[b>>2]=a;c[b+4>>2]=C;b=c[Ta>>2]|0;a=c[Ta>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=da;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Sa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Z;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=U;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Oa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=O;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Ja>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=J;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Ia>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=D;c[b>>2]=a;c[b+4>>2]=C;b=c[Ua>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=za;c[b>>2]=a;c[b+4>>2]=C;b=c[Ta>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ua;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Sa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=T;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=N;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Ma>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=I;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Ja>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=B;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ya;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ta;c[b>>2]=a;c[b+4>>2]=C;b=c[Ra>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=oa;c[b>>2]=a;c[b+4>>2]=C;b=c[Pa>>2]|0;a=c[Pa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=H;c[b>>2]=a;c[b+4>>2]=C;b=c[Qa>>2]|0;a=c[Oa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=A;c[b>>2]=a;c[b+4>>2]=C;b=c[Qa>>2]|0;a=c[La>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=xa;c[b>>2]=a;c[b+4>>2]=C;b=c[Pa>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=sa;c[b>>2]=a;c[b+4>>2]=C;b=c[Qa>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=na;c[b>>2]=a;c[b+4>>2]=C;b=c[Pa>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ia;c[b>>2]=a;c[b+4>>2]=C;b=c[Oa>>2]|0;a=c[Na>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=wa;c[b>>2]=a;c[b+4>>2]=C;b=c[Ma>>2]|0;a=c[La>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ra;c[b>>2]=a;c[b+4>>2]=C;b=c[Ma>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ma;c[b>>2]=a;c[b+4>>2]=C;b=c[Ma>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ha;c[b>>2]=a;c[b+4>>2]=C;b=c[Ma>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ca;c[b>>2]=a;c[b+4>>2]=C;b=c[Ja>>2]|0;a=c[La>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=la;c[b>>2]=a;c[b+4>>2]=C;b=c[Ja>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ga;c[b>>2]=a;c[b+4>>2]=C;b=c[Ka>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=ba;c[b>>2]=a;c[b+4>>2]=C;b=c[Ja>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=Y;c[b>>2]=a;c[b+4>>2]=C;b=c[Ia>>2]|0;a=c[Ha>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=aa;c[b>>2]=a;c[b+4>>2]=C;b=c[Ga>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=X;c[b>>2]=a;c[b+4>>2]=C;b=c[Ga>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=S;c[b>>2]=a;c[b+4>>2]=C;b=c[Ea>>2]|0;a=c[Fa>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=R;c[b>>2]=a;c[b+4>>2]=C;b=c[Ea>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=M;c[b>>2]=a;c[b+4>>2]=C;b=c[Da>>2]|0;a=c[Ca>>2]|0;a=_h(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;b=G;c[b>>2]=a;c[b+4>>2]=C;b=Ba;a=Aa;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=za;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ya;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=xa;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=wa;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=p;c[b>>2]=a;c[b+4>>2]=C;b=va;a=ua;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=ta;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=sa;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=ra;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=o;c[a>>2]=b;c[a+4>>2]=C;a=qa;b=pa;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=oa;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=na;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ma;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=la;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=n;c[a>>2]=b;c[a+4>>2]=C;a=ka;b=ja;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ia;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=ha;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ga;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=m;c[b>>2]=a;c[b+4>>2]=C;b=fa;a=ea;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=da;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=ca;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=ba;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=aa;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=l;c[b>>2]=a;c[b+4>>2]=C;b=$;a=_;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=Z;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=Y;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=X;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=k;c[a>>2]=b;c[a+4>>2]=C;a=W;b=V;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=U;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=T;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=S;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=R;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=j;c[a>>2]=b;c[a+4>>2]=C;a=Q;b=P;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=O;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=N;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=M;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=h;c[b>>2]=a;c[b+4>>2]=C;b=L;a=K;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=J;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=I;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=H;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=G;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=g;c[b>>2]=a;c[b+4>>2]=C;b=F;a=E;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=D;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=B;a=Qh(b|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=A;b=Qh(a|0,C|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=f;c[a>>2]=b;c[a+4>>2]=C;a=p;b=p;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=p;c[b>>2]=a;c[b+4>>2]=C;b=o;a=o;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=o;c[a>>2]=b;c[a+4>>2]=C;a=n;b=n;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=n;c[b>>2]=a;c[b+4>>2]=C;b=m;a=m;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=m;c[a>>2]=b;c[a+4>>2]=C;a=l;b=l;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=l;c[b>>2]=a;c[b+4>>2]=C;b=k;a=k;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=k;c[a>>2]=b;c[a+4>>2]=C;a=j;b=j;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=j;c[b>>2]=a;c[b+4>>2]=C;b=h;a=h;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=h;c[a>>2]=b;c[a+4>>2]=C;a=g;b=g;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=g;c[b>>2]=a;c[b+4>>2]=C;b=f;a=f;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=f;c[a>>2]=b;c[a+4>>2]=C;a=p;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=q;c[b>>2]=a;c[b+4>>2]=C;b=q;a=o;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=o;c[a>>2]=b;c[a+4>>2]=C;a=q;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=p;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=p;c[b>>2]=a;c[b+4>>2]=C;b=l;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=t;c[a>>2]=b;c[a+4>>2]=C;a=t;b=k;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=k;c[b>>2]=a;c[b+4>>2]=C;b=t;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=l;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=l;c[a>>2]=b;c[a+4>>2]=C;a=o;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;b=z;c[b>>2]=a;c[b+4>>2]=C;b=z;a=n;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=n;c[a>>2]=b;c[a+4>>2]=C;a=z;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;b=o;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=o;c[b>>2]=a;c[b+4>>2]=C;b=k;b=Qh(c[b>>2]|0,c[b+4>>2]|0,16777216,0)|0;b=Rh(b|0,C|0,25)|0;a=y;c[a>>2]=b;c[a+4>>2]=C;a=y;b=j;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=j;c[b>>2]=a;c[b+4>>2]=C;b=y;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;a=k;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=k;c[a>>2]=b;c[a+4>>2]=C;a=n;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=x;c[b>>2]=a;c[b+4>>2]=C;b=x;a=m;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=m;c[a>>2]=b;c[a+4>>2]=C;a=x;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=n;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=n;c[b>>2]=a;c[b+4>>2]=C;b=j;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=w;c[a>>2]=b;c[a+4>>2]=C;a=w;b=h;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=h;c[b>>2]=a;c[b+4>>2]=C;b=w;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=j;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=j;c[a>>2]=b;c[a+4>>2]=C;a=m;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;b=v;c[b>>2]=a;c[b+4>>2]=C;b=v;a=l;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=l;c[a>>2]=b;c[a+4>>2]=C;a=v;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;b=m;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=m;c[b>>2]=a;c[b+4>>2]=C;b=h;b=Qh(c[b>>2]|0,c[b+4>>2]|0,16777216,0)|0;b=Rh(b|0,C|0,25)|0;a=u;c[a>>2]=b;c[a+4>>2]=C;a=u;b=g;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=g;c[b>>2]=a;c[b+4>>2]=C;b=u;b=Uh(c[b>>2]|0,c[b+4>>2]|0,25)|0;a=h;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=h;c[a>>2]=b;c[a+4>>2]=C;a=l;a=Qh(c[a>>2]|0,c[a+4>>2]|0,33554432,0)|0;a=Rh(a|0,C|0,26)|0;b=t;c[b>>2]=a;c[b+4>>2]=C;b=t;a=k;b=Qh(c[a>>2]|0,c[a+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;a=k;c[a>>2]=b;c[a+4>>2]=C;a=t;a=Uh(c[a>>2]|0,c[a+4>>2]|0,26)|0;b=l;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=l;c[b>>2]=a;c[b+4>>2]=C;b=g;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=s;c[a>>2]=b;c[a+4>>2]=C;a=s;b=f;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=f;c[b>>2]=a;c[b+4>>2]=C;b=s;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=g;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=g;c[a>>2]=b;c[a+4>>2]=C;a=f;a=Qh(c[a>>2]|0,c[a+4>>2]|0,16777216,0)|0;a=Rh(a|0,C|0,25)|0;b=r;c[b>>2]=a;c[b+4>>2]=C;b=r;b=_h(c[b>>2]|0,c[b+4>>2]|0,19,0)|0;a=p;b=Qh(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=p;c[a>>2]=b;c[a+4>>2]=C;a=r;a=Uh(c[a>>2]|0,c[a+4>>2]|0,25)|0;b=f;a=Ph(c[b>>2]|0,c[b+4>>2]|0,a|0,C|0)|0;b=f;c[b>>2]=a;c[b+4>>2]=C;b=p;b=Qh(c[b>>2]|0,c[b+4>>2]|0,33554432,0)|0;b=Rh(b|0,C|0,26)|0;a=q;c[a>>2]=b;c[a+4>>2]=C;a=q;b=o;a=Qh(c[b>>2]|0,c[b+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;b=o;c[b>>2]=a;c[b+4>>2]=C;b=q;b=Uh(c[b>>2]|0,c[b+4>>2]|0,26)|0;a=p;b=Ph(c[a>>2]|0,c[a+4>>2]|0,b|0,C|0)|0;a=p;c[a>>2]=b;c[a+4>>2]=C;c[c[e>>2]>>2]=c[p>>2];c[(c[e>>2]|0)+4>>2]=c[o>>2];c[(c[e>>2]|0)+8>>2]=c[n>>2];c[(c[e>>2]|0)+12>>2]=c[m>>2];c[(c[e>>2]|0)+16>>2]=c[l>>2];c[(c[e>>2]|0)+20>>2]=c[k>>2];c[(c[e>>2]|0)+24>>2]=c[j>>2];c[(c[e>>2]|0)+28>>2]=c[h>>2];c[(c[e>>2]|0)+32>>2]=c[g>>2];c[(c[e>>2]|0)+36>>2]=c[f>>2];i=d;return}function ag(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;e=i;i=i+144|0;f=e+128|0;M=e+124|0;L=e+120|0;K=e+116|0;I=e+112|0;G=e+108|0;E=e+104|0;C=e+100|0;A=e+96|0;y=e+92|0;w=e+88|0;u=e+84|0;s=e+80|0;J=e+76|0;H=e+72|0;F=e+68|0;D=e+64|0;B=e+60|0;z=e+56|0;x=e+52|0;v=e+48|0;t=e+44|0;r=e+40|0;q=e+36|0;p=e+32|0;o=e+28|0;n=e+24|0;m=e+20|0;l=e+16|0;k=e+12|0;j=e+8|0;h=e+4|0;g=e;c[f>>2]=a;c[M>>2]=b;c[L>>2]=d;c[K>>2]=c[c[M>>2]>>2];c[I>>2]=c[(c[M>>2]|0)+4>>2];c[G>>2]=c[(c[M>>2]|0)+8>>2];c[E>>2]=c[(c[M>>2]|0)+12>>2];c[C>>2]=c[(c[M>>2]|0)+16>>2];c[A>>2]=c[(c[M>>2]|0)+20>>2];c[y>>2]=c[(c[M>>2]|0)+24>>2];c[w>>2]=c[(c[M>>2]|0)+28>>2];c[u>>2]=c[(c[M>>2]|0)+32>>2];c[s>>2]=c[(c[M>>2]|0)+36>>2];c[J>>2]=c[c[L>>2]>>2];c[H>>2]=c[(c[L>>2]|0)+4>>2];c[F>>2]=c[(c[L>>2]|0)+8>>2];c[D>>2]=c[(c[L>>2]|0)+12>>2];c[B>>2]=c[(c[L>>2]|0)+16>>2];c[z>>2]=c[(c[L>>2]|0)+20>>2];c[x>>2]=c[(c[L>>2]|0)+24>>2];c[v>>2]=c[(c[L>>2]|0)+28>>2];c[t>>2]=c[(c[L>>2]|0)+32>>2];c[r>>2]=c[(c[L>>2]|0)+36>>2];c[q>>2]=(c[K>>2]|0)-(c[J>>2]|0);c[p>>2]=(c[I>>2]|0)-(c[H>>2]|0);c[o>>2]=(c[G>>2]|0)-(c[F>>2]|0);c[n>>2]=(c[E>>2]|0)-(c[D>>2]|0);c[m>>2]=(c[C>>2]|0)-(c[B>>2]|0);c[l>>2]=(c[A>>2]|0)-(c[z>>2]|0);c[k>>2]=(c[y>>2]|0)-(c[x>>2]|0);c[j>>2]=(c[w>>2]|0)-(c[v>>2]|0);c[h>>2]=(c[u>>2]|0)-(c[t>>2]|0);c[g>>2]=(c[s>>2]|0)-(c[r>>2]|0);c[c[f>>2]>>2]=c[q>>2];c[(c[f>>2]|0)+4>>2]=c[p>>2];c[(c[f>>2]|0)+8>>2]=c[o>>2];c[(c[f>>2]|0)+12>>2]=c[n>>2];c[(c[f>>2]|0)+16>>2]=c[m>>2];c[(c[f>>2]|0)+20>>2]=c[l>>2];c[(c[f>>2]|0)+24>>2]=c[k>>2];c[(c[f>>2]|0)+28>>2]=c[j>>2];c[(c[f>>2]|0)+32>>2]=c[h>>2];c[(c[f>>2]|0)+36>>2]=c[g>>2];i=e;return}function bg(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0;d=i;i=i+336|0;e=d+328|0;q=d+320|0;r=d+312|0;o=d+304|0;p=d+296|0;m=d+288|0;n=d+280|0;l=d+272|0;k=d+264|0;h=d+256|0;j=d+248|0;g=d+240|0;f=d+232|0;E=d+224|0;G=d+216|0;H=d+208|0;I=d+200|0;J=d+192|0;K=d+184|0;Q=d+176|0;R=d+168|0;S=d+160|0;T=d+152|0;U=d+144|0;V=d+136|0;D=d+128|0;B=d+120|0;A=d+112|0;z=d+104|0;y=d+96|0;x=d+88|0;w=d+80|0;v=d+72|0;u=d+64|0;t=d+56|0;s=d+48|0;F=d+40|0;P=d+32|0;M=d+24|0;O=d+16|0;L=d+8|0;N=d;c[e>>2]=b;b=Sf(c[e>>2]|0)|0;W=q;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Rf((c[e>>2]|0)+2|0)|0;W=Th(W|0,C|0,5)|0;b=r;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Sf((c[e>>2]|0)+5|0)|0;b=Th(b|0,C|0,2)|0;W=o;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Rf((c[e>>2]|0)+7|0)|0;W=Th(W|0,C|0,7)|0;b=p;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Rf((c[e>>2]|0)+10|0)|0;b=Th(b|0,C|0,4)|0;W=m;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Sf((c[e>>2]|0)+13|0)|0;W=Th(W|0,C|0,1)|0;b=n;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Rf((c[e>>2]|0)+15|0)|0;b=Th(b|0,C|0,6)|0;W=l;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Sf((c[e>>2]|0)+18|0)|0;W=Th(W|0,C|0,3)|0;b=k;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Sf((c[e>>2]|0)+21|0)|0;W=h;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Rf((c[e>>2]|0)+23|0)|0;W=Th(W|0,C|0,5)|0;b=j;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Sf((c[e>>2]|0)+26|0)|0;b=Th(b|0,C|0,2)|0;W=g;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Rf((c[e>>2]|0)+28|0)|0;W=Th(W|0,C|0,7)|0;b=f;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Rf((c[e>>2]|0)+31|0)|0;b=Th(b|0,C|0,4)|0;W=E;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Sf((c[e>>2]|0)+34|0)|0;W=Th(W|0,C|0,1)|0;b=G;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Rf((c[e>>2]|0)+36|0)|0;b=Th(b|0,C|0,6)|0;W=H;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Sf((c[e>>2]|0)+39|0)|0;W=Th(W|0,C|0,3)|0;b=I;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Sf((c[e>>2]|0)+42|0)|0;W=J;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Rf((c[e>>2]|0)+44|0)|0;W=Th(W|0,C|0,5)|0;b=K;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Sf((c[e>>2]|0)+47|0)|0;b=Th(b|0,C|0,2)|0;W=Q;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Rf((c[e>>2]|0)+49|0)|0;W=Th(W|0,C|0,7)|0;b=R;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Rf((c[e>>2]|0)+52|0)|0;b=Th(b|0,C|0,4)|0;W=S;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Sf((c[e>>2]|0)+55|0)|0;W=Th(W|0,C|0,1)|0;b=T;c[b>>2]=2097151&W;c[b+4>>2]=0;b=Rf((c[e>>2]|0)+57|0)|0;b=Th(b|0,C|0,6)|0;W=U;c[W>>2]=2097151&b;c[W+4>>2]=0;W=Rf((c[e>>2]|0)+60|0)|0;W=Th(W|0,C|0,3)|0;b=V;c[b>>2]=W;c[b+4>>2]=C;b=V;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;W=f;b=Qh(c[W>>2]|0,c[W+4>>2]|0,b|0,C|0)|0;W=f;c[W>>2]=b;c[W+4>>2]=C;W=V;W=_h(c[W>>2]|0,c[W+4>>2]|0,470296,0)|0;b=E;W=Qh(c[b>>2]|0,c[b+4>>2]|0,W|0,C|0)|0;b=E;c[b>>2]=W;c[b+4>>2]=C;b=V;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;W=G;b=Qh(c[W>>2]|0,c[W+4>>2]|0,b|0,C|0)|0;W=G;c[W>>2]=b;c[W+4>>2]=C;W=V;W=_h(c[W>>2]|0,c[W+4>>2]|0,997805,0)|0;b=H;W=Ph(c[b>>2]|0,c[b+4>>2]|0,W|0,C|0)|0;b=H;c[b>>2]=W;c[b+4>>2]=C;b=V;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;W=I;b=Qh(c[W>>2]|0,c[W+4>>2]|0,b|0,C|0)|0;W=I;c[W>>2]=b;c[W+4>>2]=C;W=V;W=_h(c[W>>2]|0,c[W+4>>2]|0,683901,0)|0;b=J;W=Ph(c[b>>2]|0,c[b+4>>2]|0,W|0,C|0)|0;b=J;c[b>>2]=W;c[b+4>>2]=C;b=V;c[b>>2]=0;c[b+4>>2]=0;b=U;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;V=g;b=Qh(c[V>>2]|0,c[V+4>>2]|0,b|0,C|0)|0;V=g;c[V>>2]=b;c[V+4>>2]=C;V=U;V=_h(c[V>>2]|0,c[V+4>>2]|0,470296,0)|0;b=f;V=Qh(c[b>>2]|0,c[b+4>>2]|0,V|0,C|0)|0;b=f;c[b>>2]=V;c[b+4>>2]=C;b=U;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;V=E;b=Qh(c[V>>2]|0,c[V+4>>2]|0,b|0,C|0)|0;V=E;c[V>>2]=b;c[V+4>>2]=C;V=U;V=_h(c[V>>2]|0,c[V+4>>2]|0,997805,0)|0;b=G;V=Ph(c[b>>2]|0,c[b+4>>2]|0,V|0,C|0)|0;b=G;c[b>>2]=V;c[b+4>>2]=C;b=U;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;V=H;b=Qh(c[V>>2]|0,c[V+4>>2]|0,b|0,C|0)|0;V=H;c[V>>2]=b;c[V+4>>2]=C;V=U;V=_h(c[V>>2]|0,c[V+4>>2]|0,683901,0)|0;b=I;V=Ph(c[b>>2]|0,c[b+4>>2]|0,V|0,C|0)|0;b=I;c[b>>2]=V;c[b+4>>2]=C;b=U;c[b>>2]=0;c[b+4>>2]=0;b=T;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;U=j;b=Qh(c[U>>2]|0,c[U+4>>2]|0,b|0,C|0)|0;U=j;c[U>>2]=b;c[U+4>>2]=C;U=T;U=_h(c[U>>2]|0,c[U+4>>2]|0,470296,0)|0;b=g;U=Qh(c[b>>2]|0,c[b+4>>2]|0,U|0,C|0)|0;b=g;c[b>>2]=U;c[b+4>>2]=C;b=T;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;U=f;b=Qh(c[U>>2]|0,c[U+4>>2]|0,b|0,C|0)|0;U=f;c[U>>2]=b;c[U+4>>2]=C;U=T;U=_h(c[U>>2]|0,c[U+4>>2]|0,997805,0)|0;b=E;U=Ph(c[b>>2]|0,c[b+4>>2]|0,U|0,C|0)|0;b=E;c[b>>2]=U;c[b+4>>2]=C;b=T;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;U=G;b=Qh(c[U>>2]|0,c[U+4>>2]|0,b|0,C|0)|0;U=G;c[U>>2]=b;c[U+4>>2]=C;U=T;U=_h(c[U>>2]|0,c[U+4>>2]|0,683901,0)|0;b=H;U=Ph(c[b>>2]|0,c[b+4>>2]|0,U|0,C|0)|0;b=H;c[b>>2]=U;c[b+4>>2]=C;b=T;c[b>>2]=0;c[b+4>>2]=0;b=S;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;T=h;b=Qh(c[T>>2]|0,c[T+4>>2]|0,b|0,C|0)|0;T=h;c[T>>2]=b;c[T+4>>2]=C;T=S;T=_h(c[T>>2]|0,c[T+4>>2]|0,470296,0)|0;b=j;T=Qh(c[b>>2]|0,c[b+4>>2]|0,T|0,C|0)|0;b=j;c[b>>2]=T;c[b+4>>2]=C;b=S;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;T=g;b=Qh(c[T>>2]|0,c[T+4>>2]|0,b|0,C|0)|0;T=g;c[T>>2]=b;c[T+4>>2]=C;T=S;T=_h(c[T>>2]|0,c[T+4>>2]|0,997805,0)|0;b=f;T=Ph(c[b>>2]|0,c[b+4>>2]|0,T|0,C|0)|0;b=f;c[b>>2]=T;c[b+4>>2]=C;b=S;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;T=E;b=Qh(c[T>>2]|0,c[T+4>>2]|0,b|0,C|0)|0;T=E;c[T>>2]=b;c[T+4>>2]=C;T=S;T=_h(c[T>>2]|0,c[T+4>>2]|0,683901,0)|0;b=G;T=Ph(c[b>>2]|0,c[b+4>>2]|0,T|0,C|0)|0;b=G;c[b>>2]=T;c[b+4>>2]=C;b=S;c[b>>2]=0;c[b+4>>2]=0;b=R;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;S=k;b=Qh(c[S>>2]|0,c[S+4>>2]|0,b|0,C|0)|0;S=k;c[S>>2]=b;c[S+4>>2]=C;S=R;S=_h(c[S>>2]|0,c[S+4>>2]|0,470296,0)|0;b=h;S=Qh(c[b>>2]|0,c[b+4>>2]|0,S|0,C|0)|0;b=h;c[b>>2]=S;c[b+4>>2]=C;b=R;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;S=j;b=Qh(c[S>>2]|0,c[S+4>>2]|0,b|0,C|0)|0;S=j;c[S>>2]=b;c[S+4>>2]=C;S=R;S=_h(c[S>>2]|0,c[S+4>>2]|0,997805,0)|0;b=g;S=Ph(c[b>>2]|0,c[b+4>>2]|0,S|0,C|0)|0;b=g;c[b>>2]=S;c[b+4>>2]=C;b=R;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;S=f;b=Qh(c[S>>2]|0,c[S+4>>2]|0,b|0,C|0)|0;S=f;c[S>>2]=b;c[S+4>>2]=C;S=R;S=_h(c[S>>2]|0,c[S+4>>2]|0,683901,0)|0;b=E;S=Ph(c[b>>2]|0,c[b+4>>2]|0,S|0,C|0)|0;b=E;c[b>>2]=S;c[b+4>>2]=C;b=R;c[b>>2]=0;c[b+4>>2]=0;b=Q;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;R=l;b=Qh(c[R>>2]|0,c[R+4>>2]|0,b|0,C|0)|0;R=l;c[R>>2]=b;c[R+4>>2]=C;R=Q;R=_h(c[R>>2]|0,c[R+4>>2]|0,470296,0)|0;b=k;R=Qh(c[b>>2]|0,c[b+4>>2]|0,R|0,C|0)|0;b=k;c[b>>2]=R;c[b+4>>2]=C;b=Q;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;R=h;b=Qh(c[R>>2]|0,c[R+4>>2]|0,b|0,C|0)|0;R=h;c[R>>2]=b;c[R+4>>2]=C;R=Q;R=_h(c[R>>2]|0,c[R+4>>2]|0,997805,0)|0;b=j;R=Ph(c[b>>2]|0,c[b+4>>2]|0,R|0,C|0)|0;b=j;c[b>>2]=R;c[b+4>>2]=C;b=Q;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;R=g;b=Qh(c[R>>2]|0,c[R+4>>2]|0,b|0,C|0)|0;R=g;c[R>>2]=b;c[R+4>>2]=C;R=Q;R=_h(c[R>>2]|0,c[R+4>>2]|0,683901,0)|0;b=f;R=Ph(c[b>>2]|0,c[b+4>>2]|0,R|0,C|0)|0;b=f;c[b>>2]=R;c[b+4>>2]=C;c[Q>>2]=0;c[Q+4>>2]=0;Q=l;Q=Qh(c[Q>>2]|0,c[Q+4>>2]|0,1048576,0)|0;Q=Rh(Q|0,C|0,21)|0;b=w;c[b>>2]=Q;c[b+4>>2]=C;b=w;Q=k;b=Qh(c[Q>>2]|0,c[Q+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;Q=k;c[Q>>2]=b;c[Q+4>>2]=C;Q=w;Q=Uh(c[Q>>2]|0,c[Q+4>>2]|0,21)|0;b=l;Q=Ph(c[b>>2]|0,c[b+4>>2]|0,Q|0,C|0)|0;b=l;c[b>>2]=Q;c[b+4>>2]=C;b=h;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;Q=u;c[Q>>2]=b;c[Q+4>>2]=C;Q=u;b=j;Q=Qh(c[b>>2]|0,c[b+4>>2]|0,c[Q>>2]|0,c[Q+4>>2]|0)|0;b=j;c[b>>2]=Q;c[b+4>>2]=C;b=u;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;Q=h;b=Ph(c[Q>>2]|0,c[Q+4>>2]|0,b|0,C|0)|0;Q=h;c[Q>>2]=b;c[Q+4>>2]=C;Q=g;Q=Qh(c[Q>>2]|0,c[Q+4>>2]|0,1048576,0)|0;Q=Rh(Q|0,C|0,21)|0;b=s;c[b>>2]=Q;c[b+4>>2]=C;b=s;Q=f;b=Qh(c[Q>>2]|0,c[Q+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;Q=f;c[Q>>2]=b;c[Q+4>>2]=C;Q=s;Q=Uh(c[Q>>2]|0,c[Q+4>>2]|0,21)|0;b=g;Q=Ph(c[b>>2]|0,c[b+4>>2]|0,Q|0,C|0)|0;b=g;c[b>>2]=Q;c[b+4>>2]=C;b=E;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;Q=P;c[Q>>2]=b;c[Q+4>>2]=C;Q=P;b=G;Q=Qh(c[b>>2]|0,c[b+4>>2]|0,c[Q>>2]|0,c[Q+4>>2]|0)|0;b=G;c[b>>2]=Q;c[b+4>>2]=C;P=Uh(c[P>>2]|0,c[P+4>>2]|0,21)|0;b=E;P=Ph(c[b>>2]|0,c[b+4>>2]|0,P|0,C|0)|0;b=E;c[b>>2]=P;c[b+4>>2]=C;b=H;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;P=O;c[P>>2]=b;c[P+4>>2]=C;P=O;b=I;P=Qh(c[b>>2]|0,c[b+4>>2]|0,c[P>>2]|0,c[P+4>>2]|0)|0;b=I;c[b>>2]=P;c[b+4>>2]=C;O=Uh(c[O>>2]|0,c[O+4>>2]|0,21)|0;b=H;O=Ph(c[b>>2]|0,c[b+4>>2]|0,O|0,C|0)|0;b=H;c[b>>2]=O;c[b+4>>2]=C;b=J;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;O=N;c[O>>2]=b;c[O+4>>2]=C;O=N;b=K;O=Qh(c[b>>2]|0,c[b+4>>2]|0,c[O>>2]|0,c[O+4>>2]|0)|0;b=K;c[b>>2]=O;c[b+4>>2]=C;b=N;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;N=J;b=Ph(c[N>>2]|0,c[N+4>>2]|0,b|0,C|0)|0;N=J;c[N>>2]=b;c[N+4>>2]=C;N=k;N=Qh(c[N>>2]|0,c[N+4>>2]|0,1048576,0)|0;N=Rh(N|0,C|0,21)|0;b=v;c[b>>2]=N;c[b+4>>2]=C;b=v;N=h;b=Qh(c[N>>2]|0,c[N+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;N=h;c[N>>2]=b;c[N+4>>2]=C;N=v;N=Uh(c[N>>2]|0,c[N+4>>2]|0,21)|0;b=k;N=Ph(c[b>>2]|0,c[b+4>>2]|0,N|0,C|0)|0;b=k;c[b>>2]=N;c[b+4>>2]=C;b=j;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;N=t;c[N>>2]=b;c[N+4>>2]=C;N=t;b=g;N=Qh(c[b>>2]|0,c[b+4>>2]|0,c[N>>2]|0,c[N+4>>2]|0)|0;b=g;c[b>>2]=N;c[b+4>>2]=C;b=t;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;N=j;b=Ph(c[N>>2]|0,c[N+4>>2]|0,b|0,C|0)|0;N=j;c[N>>2]=b;c[N+4>>2]=C;N=f;N=Qh(c[N>>2]|0,c[N+4>>2]|0,1048576,0)|0;N=Rh(N|0,C|0,21)|0;b=F;c[b>>2]=N;c[b+4>>2]=C;b=F;N=E;b=Qh(c[N>>2]|0,c[N+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;N=E;c[N>>2]=b;c[N+4>>2]=C;N=F;N=Uh(c[N>>2]|0,c[N+4>>2]|0,21)|0;b=f;N=Ph(c[b>>2]|0,c[b+4>>2]|0,N|0,C|0)|0;b=f;c[b>>2]=N;c[b+4>>2]=C;b=G;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;N=M;c[N>>2]=b;c[N+4>>2]=C;N=M;b=H;N=Qh(c[b>>2]|0,c[b+4>>2]|0,c[N>>2]|0,c[N+4>>2]|0)|0;b=H;c[b>>2]=N;c[b+4>>2]=C;M=Uh(c[M>>2]|0,c[M+4>>2]|0,21)|0;b=G;M=Ph(c[b>>2]|0,c[b+4>>2]|0,M|0,C|0)|0;b=G;c[b>>2]=M;c[b+4>>2]=C;b=I;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;M=L;c[M>>2]=b;c[M+4>>2]=C;M=L;b=J;M=Qh(c[b>>2]|0,c[b+4>>2]|0,c[M>>2]|0,c[M+4>>2]|0)|0;b=J;c[b>>2]=M;c[b+4>>2]=C;L=Uh(c[L>>2]|0,c[L+4>>2]|0,21)|0;b=I;L=Ph(c[b>>2]|0,c[b+4>>2]|0,L|0,C|0)|0;b=I;c[b>>2]=L;c[b+4>>2]=C;b=K;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;L=n;b=Qh(c[L>>2]|0,c[L+4>>2]|0,b|0,C|0)|0;L=n;c[L>>2]=b;c[L+4>>2]=C;L=K;L=_h(c[L>>2]|0,c[L+4>>2]|0,470296,0)|0;b=l;L=Qh(c[b>>2]|0,c[b+4>>2]|0,L|0,C|0)|0;b=l;c[b>>2]=L;c[b+4>>2]=C;b=K;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;L=k;b=Qh(c[L>>2]|0,c[L+4>>2]|0,b|0,C|0)|0;L=k;c[L>>2]=b;c[L+4>>2]=C;L=K;L=_h(c[L>>2]|0,c[L+4>>2]|0,997805,0)|0;b=h;L=Ph(c[b>>2]|0,c[b+4>>2]|0,L|0,C|0)|0;b=h;c[b>>2]=L;c[b+4>>2]=C;b=K;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;L=j;b=Qh(c[L>>2]|0,c[L+4>>2]|0,b|0,C|0)|0;L=j;c[L>>2]=b;c[L+4>>2]=C;L=K;L=_h(c[L>>2]|0,c[L+4>>2]|0,683901,0)|0;b=g;L=Ph(c[b>>2]|0,c[b+4>>2]|0,L|0,C|0)|0;b=g;c[b>>2]=L;c[b+4>>2]=C;b=K;c[b>>2]=0;c[b+4>>2]=0;b=J;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;K=m;b=Qh(c[K>>2]|0,c[K+4>>2]|0,b|0,C|0)|0;K=m;c[K>>2]=b;c[K+4>>2]=C;K=J;K=_h(c[K>>2]|0,c[K+4>>2]|0,470296,0)|0;b=n;K=Qh(c[b>>2]|0,c[b+4>>2]|0,K|0,C|0)|0;b=n;c[b>>2]=K;c[b+4>>2]=C;b=J;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;K=l;b=Qh(c[K>>2]|0,c[K+4>>2]|0,b|0,C|0)|0;K=l;c[K>>2]=b;c[K+4>>2]=C;K=J;K=_h(c[K>>2]|0,c[K+4>>2]|0,997805,0)|0;b=k;K=Ph(c[b>>2]|0,c[b+4>>2]|0,K|0,C|0)|0;b=k;c[b>>2]=K;c[b+4>>2]=C;b=J;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;K=h;b=Qh(c[K>>2]|0,c[K+4>>2]|0,b|0,C|0)|0;K=h;c[K>>2]=b;c[K+4>>2]=C;K=J;K=_h(c[K>>2]|0,c[K+4>>2]|0,683901,0)|0;b=j;K=Ph(c[b>>2]|0,c[b+4>>2]|0,K|0,C|0)|0;b=j;c[b>>2]=K;c[b+4>>2]=C;b=J;c[b>>2]=0;c[b+4>>2]=0;b=I;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;J=p;b=Qh(c[J>>2]|0,c[J+4>>2]|0,b|0,C|0)|0;J=p;c[J>>2]=b;c[J+4>>2]=C;J=I;J=_h(c[J>>2]|0,c[J+4>>2]|0,470296,0)|0;b=m;J=Qh(c[b>>2]|0,c[b+4>>2]|0,J|0,C|0)|0;b=m;c[b>>2]=J;c[b+4>>2]=C;b=I;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;J=n;b=Qh(c[J>>2]|0,c[J+4>>2]|0,b|0,C|0)|0;J=n;c[J>>2]=b;c[J+4>>2]=C;J=I;J=_h(c[J>>2]|0,c[J+4>>2]|0,997805,0)|0;b=l;J=Ph(c[b>>2]|0,c[b+4>>2]|0,J|0,C|0)|0;b=l;c[b>>2]=J;c[b+4>>2]=C;b=I;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;J=k;b=Qh(c[J>>2]|0,c[J+4>>2]|0,b|0,C|0)|0;J=k;c[J>>2]=b;c[J+4>>2]=C;J=I;J=_h(c[J>>2]|0,c[J+4>>2]|0,683901,0)|0;b=h;J=Ph(c[b>>2]|0,c[b+4>>2]|0,J|0,C|0)|0;b=h;c[b>>2]=J;c[b+4>>2]=C;b=I;c[b>>2]=0;c[b+4>>2]=0;b=H;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;I=o;b=Qh(c[I>>2]|0,c[I+4>>2]|0,b|0,C|0)|0;I=o;c[I>>2]=b;c[I+4>>2]=C;I=H;I=_h(c[I>>2]|0,c[I+4>>2]|0,470296,0)|0;b=p;I=Qh(c[b>>2]|0,c[b+4>>2]|0,I|0,C|0)|0;b=p;c[b>>2]=I;c[b+4>>2]=C;b=H;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;I=m;b=Qh(c[I>>2]|0,c[I+4>>2]|0,b|0,C|0)|0;I=m;c[I>>2]=b;c[I+4>>2]=C;I=H;I=_h(c[I>>2]|0,c[I+4>>2]|0,997805,0)|0;b=n;I=Ph(c[b>>2]|0,c[b+4>>2]|0,I|0,C|0)|0;b=n;c[b>>2]=I;c[b+4>>2]=C;b=H;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;I=l;b=Qh(c[I>>2]|0,c[I+4>>2]|0,b|0,C|0)|0;I=l;c[I>>2]=b;c[I+4>>2]=C;I=H;I=_h(c[I>>2]|0,c[I+4>>2]|0,683901,0)|0;b=k;I=Ph(c[b>>2]|0,c[b+4>>2]|0,I|0,C|0)|0;b=k;c[b>>2]=I;c[b+4>>2]=C;b=H;c[b>>2]=0;c[b+4>>2]=0;b=G;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;H=r;b=Qh(c[H>>2]|0,c[H+4>>2]|0,b|0,C|0)|0;H=r;c[H>>2]=b;c[H+4>>2]=C;H=G;H=_h(c[H>>2]|0,c[H+4>>2]|0,470296,0)|0;b=o;H=Qh(c[b>>2]|0,c[b+4>>2]|0,H|0,C|0)|0;b=o;c[b>>2]=H;c[b+4>>2]=C;b=G;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;H=p;b=Qh(c[H>>2]|0,c[H+4>>2]|0,b|0,C|0)|0;H=p;c[H>>2]=b;c[H+4>>2]=C;H=G;H=_h(c[H>>2]|0,c[H+4>>2]|0,997805,0)|0;b=m;H=Ph(c[b>>2]|0,c[b+4>>2]|0,H|0,C|0)|0;b=m;c[b>>2]=H;c[b+4>>2]=C;b=G;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;H=n;b=Qh(c[H>>2]|0,c[H+4>>2]|0,b|0,C|0)|0;H=n;c[H>>2]=b;c[H+4>>2]=C;H=G;H=_h(c[H>>2]|0,c[H+4>>2]|0,683901,0)|0;b=l;H=Ph(c[b>>2]|0,c[b+4>>2]|0,H|0,C|0)|0;b=l;c[b>>2]=H;c[b+4>>2]=C;c[G>>2]=0;c[G+4>>2]=0;G=E;G=_h(c[G>>2]|0,c[G+4>>2]|0,666643,0)|0;b=q;G=Qh(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=q;c[b>>2]=G;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,470296,0)|0;G=r;b=Qh(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=r;c[G>>2]=b;c[G+4>>2]=C;G=E;G=_h(c[G>>2]|0,c[G+4>>2]|0,654183,0)|0;b=o;G=Qh(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=o;c[b>>2]=G;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,997805,0)|0;G=p;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=p;c[G>>2]=b;c[G+4>>2]=C;G=E;G=_h(c[G>>2]|0,c[G+4>>2]|0,136657,0)|0;b=m;G=Qh(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=m;c[b>>2]=G;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,683901,0)|0;G=n;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=n;c[G>>2]=b;c[G+4>>2]=C;G=E;c[G>>2]=0;c[G+4>>2]=0;G=q;G=Qh(c[G>>2]|0,c[G+4>>2]|0,1048576,0)|0;G=Rh(G|0,C|0,21)|0;b=D;c[b>>2]=G;c[b+4>>2]=C;b=D;G=r;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=r;c[G>>2]=b;c[G+4>>2]=C;G=D;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=q;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=q;c[b>>2]=G;c[b+4>>2]=C;b=o;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;G=A;c[G>>2]=b;c[G+4>>2]=C;G=A;b=p;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=p;c[b>>2]=G;c[b+4>>2]=C;b=A;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=o;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=o;c[G>>2]=b;c[G+4>>2]=C;G=m;G=Qh(c[G>>2]|0,c[G+4>>2]|0,1048576,0)|0;G=Rh(G|0,C|0,21)|0;b=y;c[b>>2]=G;c[b+4>>2]=C;b=y;G=n;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=n;c[G>>2]=b;c[G+4>>2]=C;G=y;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=m;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=m;c[b>>2]=G;c[b+4>>2]=C;b=l;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;G=w;c[G>>2]=b;c[G+4>>2]=C;G=w;b=k;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=k;c[b>>2]=G;c[b+4>>2]=C;b=w;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=l;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=l;c[G>>2]=b;c[G+4>>2]=C;G=h;G=Qh(c[G>>2]|0,c[G+4>>2]|0,1048576,0)|0;G=Rh(G|0,C|0,21)|0;b=u;c[b>>2]=G;c[b+4>>2]=C;b=u;G=j;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=j;c[G>>2]=b;c[G+4>>2]=C;G=u;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=h;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=h;c[b>>2]=G;c[b+4>>2]=C;b=g;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;G=s;c[G>>2]=b;c[G+4>>2]=C;G=s;b=f;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=f;c[b>>2]=G;c[b+4>>2]=C;b=s;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=g;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=g;c[G>>2]=b;c[G+4>>2]=C;G=r;G=Qh(c[G>>2]|0,c[G+4>>2]|0,1048576,0)|0;G=Rh(G|0,C|0,21)|0;b=B;c[b>>2]=G;c[b+4>>2]=C;b=B;G=o;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=o;c[G>>2]=b;c[G+4>>2]=C;G=B;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=r;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=r;c[b>>2]=G;c[b+4>>2]=C;b=p;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;G=z;c[G>>2]=b;c[G+4>>2]=C;G=z;b=m;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=m;c[b>>2]=G;c[b+4>>2]=C;b=z;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=p;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=p;c[G>>2]=b;c[G+4>>2]=C;G=n;G=Qh(c[G>>2]|0,c[G+4>>2]|0,1048576,0)|0;G=Rh(G|0,C|0,21)|0;b=x;c[b>>2]=G;c[b+4>>2]=C;b=x;G=l;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=l;c[G>>2]=b;c[G+4>>2]=C;G=x;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=n;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=n;c[b>>2]=G;c[b+4>>2]=C;b=k;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;G=v;c[G>>2]=b;c[G+4>>2]=C;G=v;b=h;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=h;c[b>>2]=G;c[b+4>>2]=C;b=v;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=k;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=k;c[G>>2]=b;c[G+4>>2]=C;G=j;G=Qh(c[G>>2]|0,c[G+4>>2]|0,1048576,0)|0;G=Rh(G|0,C|0,21)|0;b=t;c[b>>2]=G;c[b+4>>2]=C;b=t;G=g;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=g;c[G>>2]=b;c[G+4>>2]=C;G=t;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=j;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=j;c[b>>2]=G;c[b+4>>2]=C;b=f;b=Qh(c[b>>2]|0,c[b+4>>2]|0,1048576,0)|0;b=Rh(b|0,C|0,21)|0;G=F;c[G>>2]=b;c[G+4>>2]=C;G=F;b=E;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=E;c[b>>2]=G;c[b+4>>2]=C;b=F;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=f;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=f;c[G>>2]=b;c[G+4>>2]=C;G=E;G=_h(c[G>>2]|0,c[G+4>>2]|0,666643,0)|0;b=q;G=Qh(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=q;c[b>>2]=G;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,470296,0)|0;G=r;b=Qh(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=r;c[G>>2]=b;c[G+4>>2]=C;G=E;G=_h(c[G>>2]|0,c[G+4>>2]|0,654183,0)|0;b=o;G=Qh(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=o;c[b>>2]=G;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,997805,0)|0;G=p;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=p;c[G>>2]=b;c[G+4>>2]=C;G=E;G=_h(c[G>>2]|0,c[G+4>>2]|0,136657,0)|0;b=m;G=Qh(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=m;c[b>>2]=G;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,683901,0)|0;G=n;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=n;c[G>>2]=b;c[G+4>>2]=C;G=E;c[G>>2]=0;c[G+4>>2]=0;G=q;G=Rh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=D;c[b>>2]=G;c[b+4>>2]=C;b=D;G=r;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=r;c[G>>2]=b;c[G+4>>2]=C;G=D;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=q;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=q;c[b>>2]=G;c[b+4>>2]=C;b=r;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=B;c[G>>2]=b;c[G+4>>2]=C;G=B;b=o;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=o;c[b>>2]=G;c[b+4>>2]=C;b=B;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=r;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=r;c[G>>2]=b;c[G+4>>2]=C;G=o;G=Rh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=A;c[b>>2]=G;c[b+4>>2]=C;b=A;G=p;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=p;c[G>>2]=b;c[G+4>>2]=C;G=A;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=o;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=o;c[b>>2]=G;c[b+4>>2]=C;b=p;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=z;c[G>>2]=b;c[G+4>>2]=C;G=z;b=m;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=m;c[b>>2]=G;c[b+4>>2]=C;b=z;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=p;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=p;c[G>>2]=b;c[G+4>>2]=C;G=m;G=Rh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=y;c[b>>2]=G;c[b+4>>2]=C;b=y;G=n;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=n;c[G>>2]=b;c[G+4>>2]=C;G=y;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=m;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=m;c[b>>2]=G;c[b+4>>2]=C;b=n;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=x;c[G>>2]=b;c[G+4>>2]=C;G=x;b=l;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=l;c[b>>2]=G;c[b+4>>2]=C;b=x;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=n;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=n;c[G>>2]=b;c[G+4>>2]=C;G=l;G=Rh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=w;c[b>>2]=G;c[b+4>>2]=C;b=w;G=k;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=k;c[G>>2]=b;c[G+4>>2]=C;G=w;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=l;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=l;c[b>>2]=G;c[b+4>>2]=C;b=k;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=v;c[G>>2]=b;c[G+4>>2]=C;G=v;b=h;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=h;c[b>>2]=G;c[b+4>>2]=C;b=v;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=k;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=k;c[G>>2]=b;c[G+4>>2]=C;G=h;G=Rh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=u;c[b>>2]=G;c[b+4>>2]=C;b=u;G=j;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=j;c[G>>2]=b;c[G+4>>2]=C;G=u;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=h;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=h;c[b>>2]=G;c[b+4>>2]=C;b=j;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=t;c[G>>2]=b;c[G+4>>2]=C;G=t;b=g;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=g;c[b>>2]=G;c[b+4>>2]=C;b=t;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=j;b=Ph(c[G>>2]|0,c[G+4>>2]|0,b|0,C|0)|0;G=j;c[G>>2]=b;c[G+4>>2]=C;G=g;G=Rh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=s;c[b>>2]=G;c[b+4>>2]=C;b=s;G=f;b=Qh(c[G>>2]|0,c[G+4>>2]|0,c[b>>2]|0,c[b+4>>2]|0)|0;G=f;c[G>>2]=b;c[G+4>>2]=C;G=s;G=Uh(c[G>>2]|0,c[G+4>>2]|0,21)|0;b=g;G=Ph(c[b>>2]|0,c[b+4>>2]|0,G|0,C|0)|0;b=g;c[b>>2]=G;c[b+4>>2]=C;b=f;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;G=F;c[G>>2]=b;c[G+4>>2]=C;G=F;b=E;G=Qh(c[b>>2]|0,c[b+4>>2]|0,c[G>>2]|0,c[G+4>>2]|0)|0;b=E;c[b>>2]=G;c[b+4>>2]=C;F=Uh(c[F>>2]|0,c[F+4>>2]|0,21)|0;b=f;F=Ph(c[b>>2]|0,c[b+4>>2]|0,F|0,C|0)|0;b=f;c[b>>2]=F;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,666643,0)|0;F=q;b=Qh(c[F>>2]|0,c[F+4>>2]|0,b|0,C|0)|0;F=q;c[F>>2]=b;c[F+4>>2]=C;F=E;F=_h(c[F>>2]|0,c[F+4>>2]|0,470296,0)|0;b=r;F=Qh(c[b>>2]|0,c[b+4>>2]|0,F|0,C|0)|0;b=r;c[b>>2]=F;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,654183,0)|0;F=o;b=Qh(c[F>>2]|0,c[F+4>>2]|0,b|0,C|0)|0;F=o;c[F>>2]=b;c[F+4>>2]=C;F=E;F=_h(c[F>>2]|0,c[F+4>>2]|0,997805,0)|0;b=p;F=Ph(c[b>>2]|0,c[b+4>>2]|0,F|0,C|0)|0;b=p;c[b>>2]=F;c[b+4>>2]=C;b=E;b=_h(c[b>>2]|0,c[b+4>>2]|0,136657,0)|0;F=m;b=Qh(c[F>>2]|0,c[F+4>>2]|0,b|0,C|0)|0;F=m;c[F>>2]=b;c[F+4>>2]=C;F=E;F=_h(c[F>>2]|0,c[F+4>>2]|0,683901,0)|0;b=n;F=Ph(c[b>>2]|0,c[b+4>>2]|0,F|0,C|0)|0;b=n;c[b>>2]=F;c[b+4>>2]=C;b=E;c[b>>2]=0;c[b+4>>2]=0;b=q;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;E=D;c[E>>2]=b;c[E+4>>2]=C;E=D;b=r;E=Qh(c[b>>2]|0,c[b+4>>2]|0,c[E>>2]|0,c[E+4>>2]|0)|0;b=r;c[b>>2]=E;c[b+4>>2]=C;D=Uh(c[D>>2]|0,c[D+4>>2]|0,21)|0;b=q;D=Ph(c[b>>2]|0,c[b+4>>2]|0,D|0,C|0)|0;b=q;c[b>>2]=D;c[b+4>>2]=C;b=r;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;D=B;c[D>>2]=b;c[D+4>>2]=C;D=B;b=o;D=Qh(c[b>>2]|0,c[b+4>>2]|0,c[D>>2]|0,c[D+4>>2]|0)|0;b=o;c[b>>2]=D;c[b+4>>2]=C;B=Uh(c[B>>2]|0,c[B+4>>2]|0,21)|0;b=r;B=Ph(c[b>>2]|0,c[b+4>>2]|0,B|0,C|0)|0;b=r;c[b>>2]=B;c[b+4>>2]=C;b=o;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;B=A;c[B>>2]=b;c[B+4>>2]=C;B=A;b=p;B=Qh(c[b>>2]|0,c[b+4>>2]|0,c[B>>2]|0,c[B+4>>2]|0)|0;b=p;c[b>>2]=B;c[b+4>>2]=C;A=Uh(c[A>>2]|0,c[A+4>>2]|0,21)|0;b=o;A=Ph(c[b>>2]|0,c[b+4>>2]|0,A|0,C|0)|0;b=o;c[b>>2]=A;c[b+4>>2]=C;b=p;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;A=z;c[A>>2]=b;c[A+4>>2]=C;A=z;b=m;A=Qh(c[b>>2]|0,c[b+4>>2]|0,c[A>>2]|0,c[A+4>>2]|0)|0;b=m;c[b>>2]=A;c[b+4>>2]=C;z=Uh(c[z>>2]|0,c[z+4>>2]|0,21)|0;b=p;z=Ph(c[b>>2]|0,c[b+4>>2]|0,z|0,C|0)|0;b=p;c[b>>2]=z;c[b+4>>2]=C;b=m;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;z=y;c[z>>2]=b;c[z+4>>2]=C;z=y;b=n;z=Qh(c[b>>2]|0,c[b+4>>2]|0,c[z>>2]|0,c[z+4>>2]|0)|0;b=n;c[b>>2]=z;c[b+4>>2]=C;y=Uh(c[y>>2]|0,c[y+4>>2]|0,21)|0;b=m;y=Ph(c[b>>2]|0,c[b+4>>2]|0,y|0,C|0)|0;b=m;c[b>>2]=y;c[b+4>>2]=C;b=n;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;y=x;c[y>>2]=b;c[y+4>>2]=C;y=x;b=l;y=Qh(c[b>>2]|0,c[b+4>>2]|0,c[y>>2]|0,c[y+4>>2]|0)|0;b=l;c[b>>2]=y;c[b+4>>2]=C;x=Uh(c[x>>2]|0,c[x+4>>2]|0,21)|0;b=n;x=Ph(c[b>>2]|0,c[b+4>>2]|0,x|0,C|0)|0;b=n;c[b>>2]=x;c[b+4>>2]=C;b=l;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;x=w;c[x>>2]=b;c[x+4>>2]=C;x=w;b=k;x=Qh(c[b>>2]|0,c[b+4>>2]|0,c[x>>2]|0,c[x+4>>2]|0)|0;b=k;c[b>>2]=x;c[b+4>>2]=C;w=Uh(c[w>>2]|0,c[w+4>>2]|0,21)|0;b=l;w=Ph(c[b>>2]|0,c[b+4>>2]|0,w|0,C|0)|0;b=l;c[b>>2]=w;c[b+4>>2]=C;b=k;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;w=v;c[w>>2]=b;c[w+4>>2]=C;w=v;b=h;w=Qh(c[b>>2]|0,c[b+4>>2]|0,c[w>>2]|0,c[w+4>>2]|0)|0;b=h;c[b>>2]=w;c[b+4>>2]=C;v=Uh(c[v>>2]|0,c[v+4>>2]|0,21)|0;b=k;v=Ph(c[b>>2]|0,c[b+4>>2]|0,v|0,C|0)|0;b=k;c[b>>2]=v;c[b+4>>2]=C;b=h;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;v=u;c[v>>2]=b;c[v+4>>2]=C;v=u;b=j;v=Qh(c[b>>2]|0,c[b+4>>2]|0,c[v>>2]|0,c[v+4>>2]|0)|0;b=j;c[b>>2]=v;c[b+4>>2]=C;u=Uh(c[u>>2]|0,c[u+4>>2]|0,21)|0;b=h;u=Ph(c[b>>2]|0,c[b+4>>2]|0,u|0,C|0)|0;b=h;c[b>>2]=u;c[b+4>>2]=C;b=j;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;u=t;c[u>>2]=b;c[u+4>>2]=C;u=t;b=g;u=Qh(c[b>>2]|0,c[b+4>>2]|0,c[u>>2]|0,c[u+4>>2]|0)|0;b=g;c[b>>2]=u;c[b+4>>2]=C;t=Uh(c[t>>2]|0,c[t+4>>2]|0,21)|0;b=j;t=Ph(c[b>>2]|0,c[b+4>>2]|0,t|0,C|0)|0;b=j;c[b>>2]=t;c[b+4>>2]=C;b=g;b=Rh(c[b>>2]|0,c[b+4>>2]|0,21)|0;t=s;c[t>>2]=b;c[t+4>>2]=C;t=s;b=f;t=Qh(c[b>>2]|0,c[b+4>>2]|0,c[t>>2]|0,c[t+4>>2]|0)|0;b=f;c[b>>2]=t;c[b+4>>2]=C;b=s;b=Uh(c[b>>2]|0,c[b+4>>2]|0,21)|0;s=g;b=Ph(c[s>>2]|0,c[s+4>>2]|0,b|0,C|0)|0;s=g;c[s>>2]=b;c[s+4>>2]=C;s=q;s=Rh(c[s>>2]|0,c[s+4>>2]|0,0)|0;a[c[e>>2]>>0]=s;s=q;s=Rh(c[s>>2]|0,c[s+4>>2]|0,8)|0;a[(c[e>>2]|0)+1>>0]=s;q=Rh(c[q>>2]|0,c[q+4>>2]|0,16)|0;s=C;b=r;b=Uh(c[b>>2]|0,c[b+4>>2]|0,5)|0;a[(c[e>>2]|0)+2>>0]=q|b;b=r;b=Rh(c[b>>2]|0,c[b+4>>2]|0,3)|0;a[(c[e>>2]|0)+3>>0]=b;b=r;b=Rh(c[b>>2]|0,c[b+4>>2]|0,11)|0;a[(c[e>>2]|0)+4>>0]=b;b=r;b=Rh(c[b>>2]|0,c[b+4>>2]|0,19)|0;r=C;q=o;q=Uh(c[q>>2]|0,c[q+4>>2]|0,2)|0;a[(c[e>>2]|0)+5>>0]=b|q;q=o;q=Rh(c[q>>2]|0,c[q+4>>2]|0,6)|0;a[(c[e>>2]|0)+6>>0]=q;o=Rh(c[o>>2]|0,c[o+4>>2]|0,14)|0;q=C;b=p;b=Uh(c[b>>2]|0,c[b+4>>2]|0,7)|0;a[(c[e>>2]|0)+7>>0]=o|b;b=p;b=Rh(c[b>>2]|0,c[b+4>>2]|0,1)|0;a[(c[e>>2]|0)+8>>0]=b;b=p;b=Rh(c[b>>2]|0,c[b+4>>2]|0,9)|0;a[(c[e>>2]|0)+9>>0]=b;b=p;b=Rh(c[b>>2]|0,c[b+4>>2]|0,17)|0;p=C;o=m;o=Uh(c[o>>2]|0,c[o+4>>2]|0,4)|0;a[(c[e>>2]|0)+10>>0]=b|o;o=m;o=Rh(c[o>>2]|0,c[o+4>>2]|0,4)|0;a[(c[e>>2]|0)+11>>0]=o;o=m;o=Rh(c[o>>2]|0,c[o+4>>2]|0,12)|0;a[(c[e>>2]|0)+12>>0]=o;m=Rh(c[m>>2]|0,c[m+4>>2]|0,20)|0;o=C;b=n;b=Uh(c[b>>2]|0,c[b+4>>2]|0,1)|0;a[(c[e>>2]|0)+13>>0]=m|b;b=n;b=Rh(c[b>>2]|0,c[b+4>>2]|0,7)|0;a[(c[e>>2]|0)+14>>0]=b;b=n;b=Rh(c[b>>2]|0,c[b+4>>2]|0,15)|0;n=C;m=l;m=Uh(c[m>>2]|0,c[m+4>>2]|0,6)|0;a[(c[e>>2]|0)+15>>0]=b|m;m=l;m=Rh(c[m>>2]|0,c[m+4>>2]|0,2)|0;a[(c[e>>2]|0)+16>>0]=m;m=l;m=Rh(c[m>>2]|0,c[m+4>>2]|0,10)|0;a[(c[e>>2]|0)+17>>0]=m;l=Rh(c[l>>2]|0,c[l+4>>2]|0,18)|0;m=C;b=k;b=Uh(c[b>>2]|0,c[b+4>>2]|0,3)|0;a[(c[e>>2]|0)+18>>0]=l|b;b=k;b=Rh(c[b>>2]|0,c[b+4>>2]|0,5)|0;a[(c[e>>2]|0)+19>>0]=b;k=Rh(c[k>>2]|0,c[k+4>>2]|0,13)|0;a[(c[e>>2]|0)+20>>0]=k;k=h;k=Rh(c[k>>2]|0,c[k+4>>2]|0,0)|0;a[(c[e>>2]|0)+21>>0]=k;k=h;k=Rh(c[k>>2]|0,c[k+4>>2]|0,8)|0;a[(c[e>>2]|0)+22>>0]=k;h=Rh(c[h>>2]|0,c[h+4>>2]|0,16)|0;k=C;b=j;b=Uh(c[b>>2]|0,c[b+4>>2]|0,5)|0;a[(c[e>>2]|0)+23>>0]=h|b;b=j;b=Rh(c[b>>2]|0,c[b+4>>2]|0,3)|0;a[(c[e>>2]|0)+24>>0]=b;b=j;b=Rh(c[b>>2]|0,c[b+4>>2]|0,11)|0;a[(c[e>>2]|0)+25>>0]=b;b=j;b=Rh(c[b>>2]|0,c[b+4>>2]|0,19)|0;j=C;h=g;h=Uh(c[h>>2]|0,c[h+4>>2]|0,2)|0;a[(c[e>>2]|0)+26>>0]=b|h;h=g;h=Rh(c[h>>2]|0,c[h+4>>2]|0,6)|0;a[(c[e>>2]|0)+27>>0]=h;g=Rh(c[g>>2]|0,c[g+4>>2]|0,14)|0;h=C;b=f;b=Uh(c[b>>2]|0,c[b+4>>2]|0,7)|0;a[(c[e>>2]|0)+28>>0]=g|b;b=f;b=Rh(c[b>>2]|0,c[b+4>>2]|0,1)|0;a[(c[e>>2]|0)+29>>0]=b;b=f;b=Rh(c[b>>2]|0,c[b+4>>2]|0,9)|0;a[(c[e>>2]|0)+30>>0]=b;b=f;b=Rh(c[b>>2]|0,c[b+4>>2]|0,17)|0;a[(c[e>>2]|0)+31>>0]=b;i=d;return} +function Ih(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0;j=i;i=i+160|0;d=j;u=c[b>>2]|0;R=Rh(0,u|0,32)|0;N=C;z=_h(R|0,N|0,R|0,N|0)|0;E=d;c[E>>2]=z;c[E+4>>2]=C;u=Rh(0,u|0,31)|0;E=C;z=b+8|0;F=c[z>>2]|0;D=Rh(0,F|0,32)|0;x=C;y=_h(D|0,x|0,u|0,E|0)|0;h=d+8|0;e=h;c[e>>2]=y;c[e+4>>2]=C;e=_h(D|0,x|0,D|0,x|0)|0;y=C;l=b+16|0;m=Rh(0,c[l>>2]|0,32)|0;H=C;q=_h(m|0,H|0,R|0,N|0)|0;y=Qh(q|0,C|0,e|0,y|0)|0;y=Uh(y|0,C|0,1)|0;e=d+16|0;q=e;c[q>>2]=y;c[q+4>>2]=C;q=_h(m|0,H|0,D|0,x|0)|0;y=C;G=b+24|0;K=Rh(0,c[G>>2]|0,32)|0;O=C;t=_h(K|0,O|0,R|0,N|0)|0;y=Qh(t|0,C|0,q|0,y|0)|0;y=Uh(y|0,C|0,1)|0;q=d+24|0;t=q;c[t>>2]=y;c[t+4>>2]=C;t=_h(m|0,H|0,m|0,H|0)|0;y=C;f=Rh(0,F|0,30)|0;f=_h(K|0,O|0,f|0,C|0)|0;y=Qh(f|0,C|0,t|0,y|0)|0;t=C;f=b+32|0;r=Rh(0,c[f>>2]|0,32)|0;k=C;E=_h(r|0,k|0,u|0,E|0)|0;E=Qh(y|0,t|0,E|0,C|0)|0;t=d+32|0;y=t;c[y>>2]=E;c[y+4>>2]=C;y=_h(K|0,O|0,m|0,H|0)|0;E=C;u=_h(r|0,k|0,D|0,x|0)|0;E=Qh(u|0,C|0,y|0,E|0)|0;y=C;u=b+40|0;v=Rh(0,c[u>>2]|0,32)|0;g=C;M=_h(v|0,g|0,R|0,N|0)|0;M=Qh(E|0,y|0,M|0,C|0)|0;M=Uh(M|0,C|0,1)|0;y=d+40|0;E=y;c[E>>2]=M;c[E+4>>2]=C;E=_h(K|0,O|0,K|0,O|0)|0;M=C;B=_h(r|0,k|0,m|0,H|0)|0;M=Qh(B|0,C|0,E|0,M|0)|0;E=C;B=b+48|0;p=Rh(0,c[B>>2]|0,32)|0;o=C;J=_h(p|0,o|0,R|0,N|0)|0;J=Qh(M|0,E|0,J|0,C|0)|0;E=C;F=Rh(0,F|0,31)|0;F=_h(v|0,g|0,F|0,C|0)|0;F=Qh(J|0,E|0,F|0,C|0)|0;F=Uh(F|0,C|0,1)|0;E=d+48|0;J=E;c[J>>2]=F;c[J+4>>2]=C;J=_h(r|0,k|0,K|0,O|0)|0;F=C;M=_h(v|0,g|0,m|0,H|0)|0;F=Qh(M|0,C|0,J|0,F|0)|0;J=C;M=_h(p|0,o|0,D|0,x|0)|0;M=Qh(F|0,J|0,M|0,C|0)|0;J=C;F=b+56|0;s=Rh(0,c[F>>2]|0,32)|0;n=C;A=_h(s|0,n|0,R|0,N|0)|0;A=Qh(M|0,J|0,A|0,C|0)|0;A=Uh(A|0,C|0,1)|0;J=d+56|0;M=J;c[M>>2]=A;c[M+4>>2]=C;M=_h(r|0,k|0,r|0,k|0)|0;A=C;P=_h(p|0,o|0,m|0,H|0)|0;Q=C;L=b+64|0;I=Rh(0,c[L>>2]|0,32)|0;w=C;N=_h(I|0,w|0,R|0,N|0)|0;Q=Qh(N|0,C|0,P|0,Q|0)|0;P=C;x=_h(s|0,n|0,D|0,x|0)|0;D=C;N=_h(v|0,g|0,K|0,O|0)|0;D=Qh(N|0,C|0,x|0,D|0)|0;D=Uh(D|0,C|0,1)|0;D=Qh(Q|0,P|0,D|0,C|0)|0;D=Uh(D|0,C|0,1)|0;A=Qh(D|0,C|0,M|0,A|0)|0;M=d+64|0;D=M;c[D>>2]=A;c[D+4>>2]=C;D=_h(v|0,g|0,r|0,k|0)|0;A=C;O=_h(p|0,o|0,K|0,O|0)|0;A=Qh(O|0,C|0,D|0,A|0)|0;D=C;H=_h(s|0,n|0,m|0,H|0)|0;H=Qh(A|0,D|0,H|0,C|0)|0;D=C;z=Rh(0,c[z>>2]|0,32)|0;A=C;m=_h(I|0,w|0,z|0,A|0)|0;m=Qh(H|0,D|0,m|0,C|0)|0;D=C;H=Rh(0,c[b>>2]|0,32)|0;O=C;K=c[b+72>>2]|0;P=Rh(0,K|0,32)|0;Q=C;O=_h(P|0,Q|0,H|0,O|0)|0;O=Qh(m|0,D|0,O|0,C|0)|0;O=Uh(O|0,C|0,1)|0;b=d+72|0;c[b>>2]=O;c[b+4>>2]=C;b=_h(v|0,g|0,v|0,g|0)|0;O=C;k=_h(p|0,o|0,r|0,k|0)|0;O=Qh(k|0,C|0,b|0,O|0)|0;b=C;l=Rh(0,c[l>>2]|0,32)|0;k=C;r=_h(I|0,w|0,l|0,k|0)|0;r=Qh(O|0,b|0,r|0,C|0)|0;b=C;G=Rh(0,c[G>>2]|0,32)|0;O=C;D=_h(s|0,n|0,G|0,O|0)|0;m=C;A=_h(P|0,Q|0,z|0,A|0)|0;m=Qh(A|0,C|0,D|0,m|0)|0;m=Uh(m|0,C|0,1)|0;m=Qh(r|0,b|0,m|0,C|0)|0;m=Uh(m|0,C|0,1)|0;b=d+80|0;r=b;c[r>>2]=m;c[r+4>>2]=C;g=_h(p|0,o|0,v|0,g|0)|0;v=C;f=Rh(0,c[f>>2]|0,32)|0;r=C;m=_h(s|0,n|0,f|0,r|0)|0;v=Qh(m|0,C|0,g|0,v|0)|0;g=C;m=_h(I|0,w|0,G|0,O|0)|0;m=Qh(v|0,g|0,m|0,C|0)|0;g=C;k=_h(P|0,Q|0,l|0,k|0)|0;k=Qh(m|0,g|0,k|0,C|0)|0;g=C;m=Uh(k|0,g|0,1)|0;l=C;v=d+88|0;c[v>>2]=m;c[v+4>>2]=l;o=_h(p|0,o|0,p|0,o|0)|0;p=C;v=_h(I|0,w|0,f|0,r|0)|0;D=C;u=c[u>>2]|0;A=Rh(0,u|0,32)|0;z=C;H=_h(s|0,n|0,A|0,z|0)|0;x=C;O=_h(P|0,Q|0,G|0,O|0)|0;x=Qh(O|0,C|0,H|0,x|0)|0;x=Uh(x|0,C|0,1)|0;D=Qh(x|0,C|0,v|0,D|0)|0;D=Uh(D|0,C|0,1)|0;p=Qh(D|0,C|0,o|0,p|0)|0;o=C;D=d+96|0;c[D>>2]=p;c[D+4>>2]=o;B=Rh(0,c[B>>2]|0,32)|0;D=C;n=_h(s|0,n|0,B|0,D|0)|0;s=C;z=_h(I|0,w|0,A|0,z|0)|0;s=Qh(z|0,C|0,n|0,s|0)|0;n=C;r=_h(P|0,Q|0,f|0,r|0)|0;r=Qh(s|0,n|0,r|0,C|0)|0;n=C;s=Uh(r|0,n|0,1)|0;f=C;z=d+104|0;c[z>>2]=s;c[z+4>>2]=f;F=c[F>>2]|0;z=Rh(0,F|0,32)|0;A=C;v=_h(z|0,A|0,z|0,A|0)|0;x=C;w=_h(I|0,w|0,B|0,D|0)|0;x=Qh(w|0,C|0,v|0,x|0)|0;v=C;u=Rh(0,u|0,31)|0;u=_h(P|0,Q|0,u|0,C|0)|0;u=Qh(x|0,v|0,u|0,C|0)|0;v=C;x=Uh(u|0,v|0,1)|0;w=C;I=d+112|0;c[I>>2]=x;c[I+4>>2]=w;L=c[L>>2]|0;I=Rh(0,L|0,32)|0;H=C;A=_h(I|0,H|0,z|0,A|0)|0;z=C;D=_h(P|0,Q|0,B|0,D|0)|0;z=Qh(D|0,C|0,A|0,z|0)|0;A=C;D=Uh(z|0,A|0,1)|0;B=C;O=d+120|0;c[O>>2]=D;c[O+4>>2]=B;H=_h(I|0,H|0,I|0,H|0)|0;I=C;F=Rh(0,F|0,30)|0;F=_h(P|0,Q|0,F|0,C|0)|0;I=Qh(F|0,C|0,H|0,I|0)|0;H=C;F=d+128|0;c[F>>2]=I;c[F+4>>2]=H;L=Rh(0,L|0,31)|0;L=_h(P|0,Q|0,L|0,C|0)|0;F=C;O=d+136|0;c[O>>2]=L;c[O+4>>2]=F;K=Rh(0,K|0,31)|0;Q=_h(K|0,C|0,P|0,Q|0)|0;P=C;K=d+144|0;c[K>>2]=Q;c[K+4>>2]=P;K=M;O=c[K>>2]|0;K=c[K+4>>2]|0;G=_h(Q|0,P|0,18,0)|0;N=C;K=Qh(Q|0,P|0,O|0,K|0)|0;N=Qh(K|0,C|0,G|0,N|0)|0;c[M>>2]=N;c[M+4>>2]=C;M=J;N=c[M>>2]|0;M=c[M+4>>2]|0;G=_h(L|0,F|0,18,0)|0;K=C;F=Qh(N|0,M|0,L|0,F|0)|0;K=Qh(F|0,C|0,G|0,K|0)|0;c[J>>2]=K;c[J+4>>2]=C;J=E;K=c[J>>2]|0;J=c[J+4>>2]|0;G=_h(I|0,H|0,18,0)|0;F=C;H=Qh(K|0,J|0,I|0,H|0)|0;F=Qh(H|0,C|0,G|0,F|0)|0;c[E>>2]=F;c[E+4>>2]=C;E=y;F=c[E>>2]|0;E=c[E+4>>2]|0;A=_h(z|0,A|0,36,0)|0;z=C;B=Qh(F|0,E|0,D|0,B|0)|0;z=Qh(B|0,C|0,A|0,z|0)|0;c[y>>2]=z;c[y+4>>2]=C;y=t;z=c[y>>2]|0;y=c[y+4>>2]|0;v=_h(u|0,v|0,36,0)|0;u=C;w=Qh(z|0,y|0,x|0,w|0)|0;u=Qh(w|0,C|0,v|0,u|0)|0;c[t>>2]=u;c[t+4>>2]=C;t=q;u=c[t>>2]|0;t=c[t+4>>2]|0;n=_h(r|0,n|0,36,0)|0;r=C;f=Qh(u|0,t|0,s|0,f|0)|0;r=Qh(f|0,C|0,n|0,r|0)|0;c[q>>2]=r;c[q+4>>2]=C;q=e;r=c[q>>2]|0;q=c[q+4>>2]|0;n=_h(p|0,o|0,18,0)|0;f=C;o=Qh(r|0,q|0,p|0,o|0)|0;f=Qh(o|0,C|0,n|0,f|0)|0;c[e>>2]=f;c[e+4>>2]=C;e=h;f=c[e>>2]|0;e=c[e+4>>2]|0;g=_h(k|0,g|0,36,0)|0;k=C;l=Qh(f|0,e|0,m|0,l|0)|0;k=Qh(l|0,C|0,g|0,k|0)|0;g=h;c[g>>2]=k;c[g+4>>2]=C;g=b;k=c[g>>2]|0;g=c[g+4>>2]|0;l=d;m=c[l>>2]|0;l=c[l+4>>2]|0;e=_h(k|0,g|0,18,0)|0;f=C;g=Qh(m|0,l|0,k|0,g|0)|0;f=Qh(g|0,C|0,e|0,f|0)|0;e=C;g=d;c[g>>2]=f;c[g+4>>2]=e;g=b;c[g>>2]=0;c[g+4>>2]=0;g=0;do{O=Qh(e>>31>>>6|0,0,f|0,e|0)|0;O=Rh(O|0,C|0,26)|0;N=C;M=Uh(O|0,N|0,26)|0;M=Ph(f|0,e|0,M|0,C|0)|0;R=d+(g<<3)|0;c[R>>2]=M;c[R+4>>2]=C;R=d+((g|1)<<3)|0;M=R;M=Qh(O|0,N|0,c[M>>2]|0,c[M+4>>2]|0)|0;N=C;O=Qh(N>>31>>>7|0,0,M|0,N|0)|0;O=Rh(O|0,C|0,25)|0;P=C;Q=Uh(O|0,P|0,25)|0;Q=Ph(M|0,N|0,Q|0,C|0)|0;c[R>>2]=Q;c[R+4>>2]=C;g=g+2|0;R=d+(g<<3)|0;Q=R;f=Qh(O|0,P|0,c[Q>>2]|0,c[Q+4>>2]|0)|0;e=C;c[R>>2]=f;c[R+4>>2]=e}while(g>>>0<10);Q=b;P=c[Q>>2]|0;Q=c[Q+4>>2]|0;N=d;M=c[N>>2]|0;N=c[N+4>>2]|0;R=_h(P|0,Q|0,18,0)|0;O=C;Q=Qh(M|0,N|0,P|0,Q|0)|0;O=Qh(Q|0,C|0,R|0,O|0)|0;R=C;Q=b;c[Q>>2]=0;c[Q+4>>2]=0;Q=Qh(R>>31>>>6|0,0,O|0,R|0)|0;Q=Rh(Q|0,C|0,26)|0;b=C;P=Uh(Q|0,b|0,26)|0;P=Ph(O|0,R|0,P|0,C|0)|0;R=d;c[R>>2]=P;c[R+4>>2]=C;R=h;R=Qh(Q|0,b|0,c[R>>2]|0,c[R+4>>2]|0)|0;b=h;c[b>>2]=R;c[b+4>>2]=C;b=a+80|0;do{c[a>>2]=c[d>>2];a=a+4|0;d=d+4|0}while((a|0)<(b|0));i=j;return}function Jh(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;j=i;i=i+160|0;e=j;Hh(e,b,d);b=e+144|0;f=c[b>>2]|0;b=c[b+4>>2]|0;d=e+64|0;k=d;h=c[k>>2]|0;k=c[k+4>>2]|0;m=_h(f|0,b|0,18,0)|0;l=C;b=Qh(h|0,k|0,f|0,b|0)|0;l=Qh(b|0,C|0,m|0,l|0)|0;c[d>>2]=l;c[d+4>>2]=C;d=e+136|0;l=c[d>>2]|0;d=c[d+4>>2]|0;m=e+56|0;b=m;f=c[b>>2]|0;b=c[b+4>>2]|0;k=_h(l|0,d|0,18,0)|0;h=C;d=Qh(f|0,b|0,l|0,d|0)|0;h=Qh(d|0,C|0,k|0,h|0)|0;c[m>>2]=h;c[m+4>>2]=C;m=e+128|0;h=c[m>>2]|0;m=c[m+4>>2]|0;k=e+48|0;d=k;l=c[d>>2]|0;d=c[d+4>>2]|0;b=_h(h|0,m|0,18,0)|0;f=C;m=Qh(l|0,d|0,h|0,m|0)|0;f=Qh(m|0,C|0,b|0,f|0)|0;c[k>>2]=f;c[k+4>>2]=C;k=e+120|0;f=c[k>>2]|0;k=c[k+4>>2]|0;b=e+40|0;m=b;h=c[m>>2]|0;m=c[m+4>>2]|0;d=_h(f|0,k|0,18,0)|0;l=C;k=Qh(h|0,m|0,f|0,k|0)|0;l=Qh(k|0,C|0,d|0,l|0)|0;c[b>>2]=l;c[b+4>>2]=C;b=e+112|0;l=c[b>>2]|0;b=c[b+4>>2]|0;d=e+32|0;k=d;f=c[k>>2]|0;k=c[k+4>>2]|0;m=_h(l|0,b|0,18,0)|0;h=C;b=Qh(f|0,k|0,l|0,b|0)|0;h=Qh(b|0,C|0,m|0,h|0)|0;c[d>>2]=h;c[d+4>>2]=C;d=e+104|0;h=c[d>>2]|0;d=c[d+4>>2]|0;m=e+24|0;b=m;l=c[b>>2]|0;b=c[b+4>>2]|0;k=_h(h|0,d|0,18,0)|0;f=C;d=Qh(l|0,b|0,h|0,d|0)|0;f=Qh(d|0,C|0,k|0,f|0)|0;c[m>>2]=f;c[m+4>>2]=C;m=e+96|0;f=c[m>>2]|0;m=c[m+4>>2]|0;k=e+16|0;d=k;h=c[d>>2]|0;d=c[d+4>>2]|0;b=_h(f|0,m|0,18,0)|0;l=C;m=Qh(h|0,d|0,f|0,m|0)|0;l=Qh(m|0,C|0,b|0,l|0)|0;c[k>>2]=l;c[k+4>>2]=C;k=e+88|0;l=c[k>>2]|0;k=c[k+4>>2]|0;b=e+8|0;m=b;f=c[m>>2]|0;m=c[m+4>>2]|0;d=_h(l|0,k|0,18,0)|0;h=C;k=Qh(f|0,m|0,l|0,k|0)|0;h=Qh(k|0,C|0,d|0,h|0)|0;d=b;c[d>>2]=h;c[d+4>>2]=C;d=e+80|0;h=d;k=c[h>>2]|0;h=c[h+4>>2]|0;l=e;m=c[l>>2]|0;l=c[l+4>>2]|0;f=_h(k|0,h|0,18,0)|0;g=C;h=Qh(m|0,l|0,k|0,h|0)|0;g=Qh(h|0,C|0,f|0,g|0)|0;f=C;h=e;c[h>>2]=g;c[h+4>>2]=f;h=d;c[h>>2]=0;c[h+4>>2]=0;h=0;do{n=Qh(f>>31>>>6|0,0,g|0,f|0)|0;n=Rh(n|0,C|0,26)|0;o=C;p=Uh(n|0,o|0,26)|0;p=Ph(g|0,f|0,p|0,C|0)|0;m=e+(h<<3)|0;c[m>>2]=p;c[m+4>>2]=C;m=e+((h|1)<<3)|0;p=m;p=Qh(n|0,o|0,c[p>>2]|0,c[p+4>>2]|0)|0;o=C;n=Qh(o>>31>>>7|0,0,p|0,o|0)|0;n=Rh(n|0,C|0,25)|0;k=C;l=Uh(n|0,k|0,25)|0;l=Ph(p|0,o|0,l|0,C|0)|0;c[m>>2]=l;c[m+4>>2]=C;h=h+2|0;m=e+(h<<3)|0;l=m;g=Qh(n|0,k|0,c[l>>2]|0,c[l+4>>2]|0)|0;f=C;c[m>>2]=g;c[m+4>>2]=f}while(h>>>0<10);o=d;n=c[o>>2]|0;o=c[o+4>>2]|0;l=e;k=c[l>>2]|0;l=c[l+4>>2]|0;p=_h(n|0,o|0,18,0)|0;m=C;o=Qh(k|0,l|0,n|0,o|0)|0;m=Qh(o|0,C|0,p|0,m|0)|0;p=C;o=d;c[o>>2]=0;c[o+4>>2]=0;o=Qh(p>>31>>>6|0,0,m|0,p|0)|0;o=Rh(o|0,C|0,26)|0;d=C;n=Uh(o|0,d|0,26)|0;n=Ph(m|0,p|0,n|0,C|0)|0;p=e;c[p>>2]=n;c[p+4>>2]=C;p=b;p=Qh(o|0,d|0,c[p>>2]|0,c[p+4>>2]|0)|0;d=b;c[d>>2]=p;c[d+4>>2]=C;d=a;b=d+80|0;do{c[d>>2]=c[e>>2];d=d+4|0;e=e+4|0}while((d|0)<(b|0));i=j;return}function Kh(){var a=0;if(!(c[8876]|0))a=35548;else a=c[(ga()|0)+64>>2]|0;return a|0}function Lh(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;a:do if(!d)d=0;else{f=d;e=b;while(1){b=a[e>>0]|0;d=a[c>>0]|0;if(b<<24>>24!=d<<24>>24)break;f=f+-1|0;if(!f){d=0;break a}else{e=e+1|0;c=c+1|0}}d=(b&255)-(d&255)|0}while(0);return d|0}function Mh(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0;do if(a>>>0<245){o=a>>>0<11?16:a+11&-8;a=o>>>3;j=c[8888]|0;b=j>>>a;if(b&3|0){b=(b&1^1)+a|0;d=35592+(b<<1<<2)|0;e=d+8|0;f=c[e>>2]|0;g=f+8|0;h=c[g>>2]|0;do if((d|0)!=(h|0)){if(h>>>0<(c[8892]|0)>>>0)ha();a=h+12|0;if((c[a>>2]|0)==(f|0)){c[a>>2]=d;c[e>>2]=h;break}else ha()}else c[8888]=j&~(1<>2]=L|3;L=f+L+4|0;c[L>>2]=c[L>>2]|1;L=g;return L|0}h=c[8890]|0;if(o>>>0>h>>>0){if(b|0){d=2<>>12&16;d=d>>>i;f=d>>>5&8;d=d>>>f;g=d>>>2&4;d=d>>>g;e=d>>>1&2;d=d>>>e;b=d>>>1&1;b=(f|i|g|e|b)+(d>>>b)|0;d=35592+(b<<1<<2)|0;e=d+8|0;g=c[e>>2]|0;i=g+8|0;f=c[i>>2]|0;do if((d|0)!=(f|0)){if(f>>>0<(c[8892]|0)>>>0)ha();a=f+12|0;if((c[a>>2]|0)==(g|0)){c[a>>2]=d;c[e>>2]=f;k=c[8890]|0;break}else ha()}else{c[8888]=j&~(1<>2]=o|3;e=g+o|0;c[e+4>>2]=h|1;c[e+h>>2]=h;if(k|0){f=c[8893]|0;b=k>>>3;d=35592+(b<<1<<2)|0;a=c[8888]|0;b=1<>2]|0;if(b>>>0<(c[8892]|0)>>>0)ha();else{l=a;m=b}}else{c[8888]=a|b;l=d+8|0;m=d}c[l>>2]=f;c[m+12>>2]=f;c[f+8>>2]=m;c[f+12>>2]=d}c[8890]=h;c[8893]=e;L=i;return L|0}a=c[8889]|0;if(a){d=(a&0-a)+-1|0;K=d>>>12&16;d=d>>>K;J=d>>>5&8;d=d>>>J;L=d>>>2&4;d=d>>>L;b=d>>>1&2;d=d>>>b;e=d>>>1&1;e=c[35856+((J|K|L|b|e)+(d>>>e)<<2)>>2]|0;d=(c[e+4>>2]&-8)-o|0;b=e;while(1){a=c[b+16>>2]|0;if(!a){a=c[b+20>>2]|0;if(!a){j=e;break}}b=(c[a+4>>2]&-8)-o|0;L=b>>>0>>0;d=L?b:d;b=a;e=L?a:e}g=c[8892]|0;if(j>>>0>>0)ha();i=j+o|0;if(j>>>0>=i>>>0)ha();h=c[j+24>>2]|0;e=c[j+12>>2]|0;do if((e|0)==(j|0)){b=j+20|0;a=c[b>>2]|0;if(!a){b=j+16|0;a=c[b>>2]|0;if(!a){n=0;break}}while(1){e=a+20|0;f=c[e>>2]|0;if(f|0){a=f;b=e;continue}e=a+16|0;f=c[e>>2]|0;if(!f)break;else{a=f;b=e}}if(b>>>0>>0)ha();else{c[b>>2]=0;n=a;break}}else{f=c[j+8>>2]|0;if(f>>>0>>0)ha();a=f+12|0;if((c[a>>2]|0)!=(j|0))ha();b=e+8|0;if((c[b>>2]|0)==(j|0)){c[a>>2]=e;c[b>>2]=f;n=e;break}else ha()}while(0);do if(h|0){a=c[j+28>>2]|0;b=35856+(a<<2)|0;if((j|0)==(c[b>>2]|0)){c[b>>2]=n;if(!n){c[8889]=c[8889]&~(1<>>0<(c[8892]|0)>>>0)ha();a=h+16|0;if((c[a>>2]|0)==(j|0))c[a>>2]=n;else c[h+20>>2]=n;if(!n)break}b=c[8892]|0;if(n>>>0>>0)ha();c[n+24>>2]=h;a=c[j+16>>2]|0;do if(a|0)if(a>>>0>>0)ha();else{c[n+16>>2]=a;c[a+24>>2]=n;break}while(0);a=c[j+20>>2]|0;if(a|0)if(a>>>0<(c[8892]|0)>>>0)ha();else{c[n+20>>2]=a;c[a+24>>2]=n;break}}while(0);if(d>>>0<16){L=d+o|0;c[j+4>>2]=L|3;L=j+L+4|0;c[L>>2]=c[L>>2]|1}else{c[j+4>>2]=o|3;c[i+4>>2]=d|1;c[i+d>>2]=d;a=c[8890]|0;if(a|0){f=c[8893]|0;b=a>>>3;e=35592+(b<<1<<2)|0;a=c[8888]|0;b=1<>2]|0;if(b>>>0<(c[8892]|0)>>>0)ha();else{p=a;q=b}}else{c[8888]=a|b;p=e+8|0;q=e}c[p>>2]=f;c[q+12>>2]=f;c[f+8>>2]=q;c[f+12>>2]=e}c[8890]=d;c[8893]=i}L=j+8|0;return L|0}}}else if(a>>>0<=4294967231){a=a+11|0;o=a&-8;j=c[8889]|0;if(j){d=0-o|0;a=a>>>8;if(a)if(o>>>0>16777215)i=31;else{q=(a+1048320|0)>>>16&8;E=a<>>16&4;E=E<>>16&2;i=14-(p|q|i)+(E<>>15)|0;i=o>>>(i+7|0)&1|i<<1}else i=0;b=c[35856+(i<<2)>>2]|0;a:do if(!b){a=0;b=0;E=86}else{f=d;a=0;g=o<<((i|0)==31?0:25-(i>>>1)|0);h=b;b=0;while(1){e=c[h+4>>2]&-8;d=e-o|0;if(d>>>0>>0)if((e|0)==(o|0)){a=h;b=h;E=90;break a}else b=h;else d=f;e=c[h+20>>2]|0;h=c[h+16+(g>>>31<<2)>>2]|0;a=(e|0)==0|(e|0)==(h|0)?a:e;e=(h|0)==0;if(e){E=86;break}else{f=d;g=g<<(e&1^1)}}}while(0);if((E|0)==86){if((a|0)==0&(b|0)==0){a=2<>>12&16;q=q>>>m;l=q>>>5&8;q=q>>>l;n=q>>>2&4;q=q>>>n;p=q>>>1&2;q=q>>>p;a=q>>>1&1;a=c[35856+((l|m|n|p|a)+(q>>>a)<<2)>>2]|0}if(!a){i=d;j=b}else E=90}if((E|0)==90)while(1){E=0;q=(c[a+4>>2]&-8)-o|0;e=q>>>0>>0;d=e?q:d;b=e?a:b;e=c[a+16>>2]|0;if(e|0){a=e;E=90;continue}a=c[a+20>>2]|0;if(!a){i=d;j=b;break}else E=90}if((j|0)!=0?i>>>0<((c[8890]|0)-o|0)>>>0:0){f=c[8892]|0;if(j>>>0>>0)ha();h=j+o|0;if(j>>>0>=h>>>0)ha();g=c[j+24>>2]|0;d=c[j+12>>2]|0;do if((d|0)==(j|0)){b=j+20|0;a=c[b>>2]|0;if(!a){b=j+16|0;a=c[b>>2]|0;if(!a){s=0;break}}while(1){d=a+20|0;e=c[d>>2]|0;if(e|0){a=e;b=d;continue}d=a+16|0;e=c[d>>2]|0;if(!e)break;else{a=e;b=d}}if(b>>>0>>0)ha();else{c[b>>2]=0;s=a;break}}else{e=c[j+8>>2]|0;if(e>>>0>>0)ha();a=e+12|0;if((c[a>>2]|0)!=(j|0))ha();b=d+8|0;if((c[b>>2]|0)==(j|0)){c[a>>2]=d;c[b>>2]=e;s=d;break}else ha()}while(0);do if(g|0){a=c[j+28>>2]|0;b=35856+(a<<2)|0;if((j|0)==(c[b>>2]|0)){c[b>>2]=s;if(!s){c[8889]=c[8889]&~(1<>>0<(c[8892]|0)>>>0)ha();a=g+16|0;if((c[a>>2]|0)==(j|0))c[a>>2]=s;else c[g+20>>2]=s;if(!s)break}b=c[8892]|0;if(s>>>0>>0)ha();c[s+24>>2]=g;a=c[j+16>>2]|0;do if(a|0)if(a>>>0>>0)ha();else{c[s+16>>2]=a;c[a+24>>2]=s;break}while(0);a=c[j+20>>2]|0;if(a|0)if(a>>>0<(c[8892]|0)>>>0)ha();else{c[s+20>>2]=a;c[a+24>>2]=s;break}}while(0);do if(i>>>0>=16){c[j+4>>2]=o|3;c[h+4>>2]=i|1;c[h+i>>2]=i;a=i>>>3;if(i>>>0<256){d=35592+(a<<1<<2)|0;b=c[8888]|0;a=1<>2]|0;if(b>>>0<(c[8892]|0)>>>0)ha();else{u=a;v=b}}else{c[8888]=b|a;u=d+8|0;v=d}c[u>>2]=h;c[v+12>>2]=h;c[h+8>>2]=v;c[h+12>>2]=d;break}a=i>>>8;if(a)if(i>>>0>16777215)d=31;else{K=(a+1048320|0)>>>16&8;L=a<>>16&4;L=L<>>16&2;d=14-(J|K|d)+(L<>>15)|0;d=i>>>(d+7|0)&1|d<<1}else d=0;e=35856+(d<<2)|0;c[h+28>>2]=d;a=h+16|0;c[a+4>>2]=0;c[a>>2]=0;a=c[8889]|0;b=1<>2]=h;c[h+24>>2]=e;c[h+12>>2]=h;c[h+8>>2]=h;break}f=i<<((d|0)==31?0:25-(d>>>1)|0);a=c[e>>2]|0;while(1){if((c[a+4>>2]&-8|0)==(i|0)){d=a;E=148;break}b=a+16+(f>>>31<<2)|0;d=c[b>>2]|0;if(!d){E=145;break}else{f=f<<1;a=d}}if((E|0)==145)if(b>>>0<(c[8892]|0)>>>0)ha();else{c[b>>2]=h;c[h+24>>2]=a;c[h+12>>2]=h;c[h+8>>2]=h;break}else if((E|0)==148){a=d+8|0;b=c[a>>2]|0;L=c[8892]|0;if(b>>>0>=L>>>0&d>>>0>=L>>>0){c[b+12>>2]=h;c[a>>2]=h;c[h+8>>2]=b;c[h+12>>2]=d;c[h+24>>2]=0;break}else ha()}}else{L=i+o|0;c[j+4>>2]=L|3;L=j+L+4|0;c[L>>2]=c[L>>2]|1}while(0);L=j+8|0;return L|0}}}else o=-1;while(0);d=c[8890]|0;if(d>>>0>=o>>>0){a=d-o|0;b=c[8893]|0;if(a>>>0>15){L=b+o|0;c[8893]=L;c[8890]=a;c[L+4>>2]=a|1;c[L+a>>2]=a;c[b+4>>2]=o|3}else{c[8890]=0;c[8893]=0;c[b+4>>2]=d|3;L=b+d+4|0;c[L>>2]=c[L>>2]|1}L=b+8|0;return L|0}a=c[8891]|0;if(a>>>0>o>>>0){J=a-o|0;c[8891]=J;L=c[8894]|0;K=L+o|0;c[8894]=K;c[K+4>>2]=J|1;c[L+4>>2]=o|3;L=L+8|0;return L|0}do if(!(c[9006]|0)){a=pa(30)|0;if(!(a+-1&a)){c[9008]=a;c[9007]=a;c[9009]=-1;c[9010]=-1;c[9011]=0;c[8999]=0;c[9006]=(la(0)|0)&-16^1431655768;break}else ha()}while(0);h=o+48|0;g=c[9008]|0;i=o+47|0;f=g+i|0;g=0-g|0;j=f&g;if(j>>>0<=o>>>0){L=0;return L|0}a=c[8998]|0;if(a|0?(u=c[8996]|0,v=u+j|0,v>>>0<=u>>>0|v>>>0>a>>>0):0){L=0;return L|0}b:do if(!(c[8999]&4)){a=c[8894]|0;c:do if(a){d=36e3;while(1){b=c[d>>2]|0;if(b>>>0<=a>>>0?(r=d+4|0,(b+(c[r>>2]|0)|0)>>>0>a>>>0):0){e=d;d=r;break}d=c[d+8>>2]|0;if(!d){E=173;break c}}a=f-(c[8891]|0)&g;if(a>>>0<2147483647){b=ka(a|0)|0;if((b|0)==((c[e>>2]|0)+(c[d>>2]|0)|0)){if((b|0)!=(-1|0)){h=b;f=a;E=193;break b}}else E=183}}else E=173;while(0);do if((E|0)==173?(t=ka(0)|0,(t|0)!=(-1|0)):0){a=t;b=c[9007]|0;d=b+-1|0;if(!(d&a))a=j;else a=j-a+(d+a&0-b)|0;b=c[8996]|0;d=b+a|0;if(a>>>0>o>>>0&a>>>0<2147483647){v=c[8998]|0;if(v|0?d>>>0<=b>>>0|d>>>0>v>>>0:0)break;b=ka(a|0)|0;if((b|0)==(t|0)){h=t;f=a;E=193;break b}else E=183}}while(0);d:do if((E|0)==183){d=0-a|0;do if(h>>>0>a>>>0&(a>>>0<2147483647&(b|0)!=(-1|0))?(w=c[9008]|0,w=i-a+w&0-w,w>>>0<2147483647):0)if((ka(w|0)|0)==(-1|0)){ka(d|0)|0;break d}else{a=w+a|0;break}while(0);if((b|0)!=(-1|0)){h=b;f=a;E=193;break b}}while(0);c[8999]=c[8999]|4;E=190}else E=190;while(0);if((((E|0)==190?j>>>0<2147483647:0)?(x=ka(j|0)|0,y=ka(0)|0,x>>>0>>0&((x|0)!=(-1|0)&(y|0)!=(-1|0))):0)?(z=y-x|0,z>>>0>(o+40|0)>>>0):0){h=x;f=z;E=193}if((E|0)==193){a=(c[8996]|0)+f|0;c[8996]=a;if(a>>>0>(c[8997]|0)>>>0)c[8997]=a;i=c[8894]|0;do if(i){e=36e3;do{a=c[e>>2]|0;b=e+4|0;d=c[b>>2]|0;if((h|0)==(a+d|0)){A=a;B=b;C=d;D=e;E=203;break}e=c[e+8>>2]|0}while((e|0)!=0);if(((E|0)==203?(c[D+12>>2]&8|0)==0:0)?i>>>0>>0&i>>>0>=A>>>0:0){c[B>>2]=C+f;L=i+8|0;L=(L&7|0)==0?0:0-L&7;K=i+L|0;L=f-L+(c[8891]|0)|0;c[8894]=K;c[8891]=L;c[K+4>>2]=L|1;c[K+L+4>>2]=40;c[8895]=c[9010];break}a=c[8892]|0;if(h>>>0>>0){c[8892]=h;j=h}else j=a;d=h+f|0;a=36e3;while(1){if((c[a>>2]|0)==(d|0)){b=a;E=211;break}a=c[a+8>>2]|0;if(!a){b=36e3;break}}if((E|0)==211)if(!(c[a+12>>2]&8)){c[b>>2]=h;l=a+4|0;c[l>>2]=(c[l>>2]|0)+f;l=h+8|0;l=h+((l&7|0)==0?0:0-l&7)|0;a=d+8|0;a=d+((a&7|0)==0?0:0-a&7)|0;k=l+o|0;g=a-l-o|0;c[l+4>>2]=o|3;do if((a|0)!=(i|0)){if((a|0)==(c[8893]|0)){L=(c[8890]|0)+g|0;c[8890]=L;c[8893]=k;c[k+4>>2]=L|1;c[k+L>>2]=L;break}b=c[a+4>>2]|0;if((b&3|0)==1){i=b&-8;f=b>>>3;e:do if(b>>>0>=256){h=c[a+24>>2]|0;e=c[a+12>>2]|0;do if((e|0)==(a|0)){d=a+16|0;e=d+4|0;b=c[e>>2]|0;if(!b){b=c[d>>2]|0;if(!b){J=0;break}}else d=e;while(1){e=b+20|0;f=c[e>>2]|0;if(f|0){b=f;d=e;continue}e=b+16|0;f=c[e>>2]|0;if(!f)break;else{b=f;d=e}}if(d>>>0>>0)ha();else{c[d>>2]=0;J=b;break}}else{f=c[a+8>>2]|0;if(f>>>0>>0)ha();b=f+12|0;if((c[b>>2]|0)!=(a|0))ha();d=e+8|0;if((c[d>>2]|0)==(a|0)){c[b>>2]=e;c[d>>2]=f;J=e;break}else ha()}while(0);if(!h)break;b=c[a+28>>2]|0;d=35856+(b<<2)|0;do if((a|0)!=(c[d>>2]|0)){if(h>>>0<(c[8892]|0)>>>0)ha();b=h+16|0;if((c[b>>2]|0)==(a|0))c[b>>2]=J;else c[h+20>>2]=J;if(!J)break e}else{c[d>>2]=J;if(J|0)break;c[8889]=c[8889]&~(1<>>0>>0)ha();c[J+24>>2]=h;b=a+16|0;d=c[b>>2]|0;do if(d|0)if(d>>>0>>0)ha();else{c[J+16>>2]=d;c[d+24>>2]=J;break}while(0);b=c[b+4>>2]|0;if(!b)break;if(b>>>0<(c[8892]|0)>>>0)ha();else{c[J+20>>2]=b;c[b+24>>2]=J;break}}else{d=c[a+8>>2]|0;e=c[a+12>>2]|0;b=35592+(f<<1<<2)|0;do if((d|0)!=(b|0)){if(d>>>0>>0)ha();if((c[d+12>>2]|0)==(a|0))break;ha()}while(0);if((e|0)==(d|0)){c[8888]=c[8888]&~(1<>>0>>0)ha();b=e+8|0;if((c[b>>2]|0)==(a|0)){G=b;break}ha()}while(0);c[d+12>>2]=e;c[G>>2]=d}while(0);a=a+i|0;g=i+g|0}a=a+4|0;c[a>>2]=c[a>>2]&-2;c[k+4>>2]=g|1;c[k+g>>2]=g;a=g>>>3;if(g>>>0<256){d=35592+(a<<1<<2)|0;b=c[8888]|0;a=1<>2]|0;if(b>>>0>=(c[8892]|0)>>>0){K=a;L=b;break}ha()}while(0);c[K>>2]=k;c[L+12>>2]=k;c[k+8>>2]=L;c[k+12>>2]=d;break}a=g>>>8;do if(!a)d=0;else{if(g>>>0>16777215){d=31;break}K=(a+1048320|0)>>>16&8;L=a<>>16&4;L=L<>>16&2;d=14-(J|K|d)+(L<>>15)|0;d=g>>>(d+7|0)&1|d<<1}while(0);e=35856+(d<<2)|0;c[k+28>>2]=d;a=k+16|0;c[a+4>>2]=0;c[a>>2]=0;a=c[8889]|0;b=1<>2]=k;c[k+24>>2]=e;c[k+12>>2]=k;c[k+8>>2]=k;break}f=g<<((d|0)==31?0:25-(d>>>1)|0);a=c[e>>2]|0;while(1){if((c[a+4>>2]&-8|0)==(g|0)){d=a;E=281;break}b=a+16+(f>>>31<<2)|0;d=c[b>>2]|0;if(!d){E=278;break}else{f=f<<1;a=d}}if((E|0)==278)if(b>>>0<(c[8892]|0)>>>0)ha();else{c[b>>2]=k;c[k+24>>2]=a;c[k+12>>2]=k;c[k+8>>2]=k;break}else if((E|0)==281){a=d+8|0;b=c[a>>2]|0;L=c[8892]|0;if(b>>>0>=L>>>0&d>>>0>=L>>>0){c[b+12>>2]=k;c[a>>2]=k;c[k+8>>2]=b;c[k+12>>2]=d;c[k+24>>2]=0;break}else ha()}}else{L=(c[8891]|0)+g|0;c[8891]=L;c[8894]=k;c[k+4>>2]=L|1}while(0);L=l+8|0;return L|0}else b=36e3;while(1){a=c[b>>2]|0;if(a>>>0<=i>>>0?(F=a+(c[b+4>>2]|0)|0,F>>>0>i>>>0):0){b=F;break}b=c[b+8>>2]|0}g=b+-47|0;d=g+8|0;d=g+((d&7|0)==0?0:0-d&7)|0;g=i+16|0;d=d>>>0>>0?i:d;a=d+8|0;e=h+8|0;e=(e&7|0)==0?0:0-e&7;L=h+e|0;e=f+-40-e|0;c[8894]=L;c[8891]=e;c[L+4>>2]=e|1;c[L+e+4>>2]=40;c[8895]=c[9010];e=d+4|0;c[e>>2]=27;c[a>>2]=c[9e3];c[a+4>>2]=c[9001];c[a+8>>2]=c[9002];c[a+12>>2]=c[9003];c[9e3]=h;c[9001]=f;c[9003]=0;c[9002]=a;a=d+24|0;do{a=a+4|0;c[a>>2]=7}while((a+4|0)>>>0>>0);if((d|0)!=(i|0)){h=d-i|0;c[e>>2]=c[e>>2]&-2;c[i+4>>2]=h|1;c[d>>2]=h;a=h>>>3;if(h>>>0<256){d=35592+(a<<1<<2)|0;b=c[8888]|0;a=1<>2]|0;if(b>>>0<(c[8892]|0)>>>0)ha();else{H=a;I=b}}else{c[8888]=b|a;H=d+8|0;I=d}c[H>>2]=i;c[I+12>>2]=i;c[i+8>>2]=I;c[i+12>>2]=d;break}a=h>>>8;if(a)if(h>>>0>16777215)d=31;else{K=(a+1048320|0)>>>16&8;L=a<>>16&4;L=L<>>16&2;d=14-(J|K|d)+(L<>>15)|0;d=h>>>(d+7|0)&1|d<<1}else d=0;f=35856+(d<<2)|0;c[i+28>>2]=d;c[i+20>>2]=0;c[g>>2]=0;a=c[8889]|0;b=1<>2]=i;c[i+24>>2]=f;c[i+12>>2]=i;c[i+8>>2]=i;break}e=h<<((d|0)==31?0:25-(d>>>1)|0);a=c[f>>2]|0;while(1){if((c[a+4>>2]&-8|0)==(h|0)){d=a;E=307;break}b=a+16+(e>>>31<<2)|0;d=c[b>>2]|0;if(!d){E=304;break}else{e=e<<1;a=d}}if((E|0)==304)if(b>>>0<(c[8892]|0)>>>0)ha();else{c[b>>2]=i;c[i+24>>2]=a;c[i+12>>2]=i;c[i+8>>2]=i;break}else if((E|0)==307){a=d+8|0;b=c[a>>2]|0;L=c[8892]|0;if(b>>>0>=L>>>0&d>>>0>=L>>>0){c[b+12>>2]=i;c[a>>2]=i;c[i+8>>2]=b;c[i+12>>2]=d;c[i+24>>2]=0;break}else ha()}}}else{L=c[8892]|0;if((L|0)==0|h>>>0>>0)c[8892]=h;c[9e3]=h;c[9001]=f;c[9003]=0;c[8897]=c[9006];c[8896]=-1;a=0;do{L=35592+(a<<1<<2)|0;c[L+12>>2]=L;c[L+8>>2]=L;a=a+1|0}while((a|0)!=32);L=h+8|0;L=(L&7|0)==0?0:0-L&7;K=h+L|0;L=f+-40-L|0;c[8894]=K;c[8891]=L;c[K+4>>2]=L|1;c[K+L+4>>2]=40;c[8895]=c[9010]}while(0);a=c[8891]|0;if(a>>>0>o>>>0){J=a-o|0;c[8891]=J;L=c[8894]|0;K=L+o|0;c[8894]=K;c[K+4>>2]=J|1;c[L+4>>2]=o|3;L=L+8|0;return L|0}}c[(Kh()|0)>>2]=12;L=0;return L|0}function Nh(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;if(!a)return;d=a+-8|0;h=c[8892]|0;if(d>>>0>>0)ha();a=c[a+-4>>2]|0;b=a&3;if((b|0)==1)ha();e=a&-8;m=d+e|0;do if(!(a&1)){a=c[d>>2]|0;if(!b)return;k=d+(0-a)|0;j=a+e|0;if(k>>>0>>0)ha();if((k|0)==(c[8893]|0)){a=m+4|0;b=c[a>>2]|0;if((b&3|0)!=3){q=k;g=j;break}c[8890]=j;c[a>>2]=b&-2;c[k+4>>2]=j|1;c[k+j>>2]=j;return}e=a>>>3;if(a>>>0<256){b=c[k+8>>2]|0;d=c[k+12>>2]|0;a=35592+(e<<1<<2)|0;if((b|0)!=(a|0)){if(b>>>0>>0)ha();if((c[b+12>>2]|0)!=(k|0))ha()}if((d|0)==(b|0)){c[8888]=c[8888]&~(1<>>0>>0)ha();a=d+8|0;if((c[a>>2]|0)==(k|0))f=a;else ha()}else f=d+8|0;c[b+12>>2]=d;c[f>>2]=b;q=k;g=j;break}f=c[k+24>>2]|0;d=c[k+12>>2]|0;do if((d|0)==(k|0)){b=k+16|0;d=b+4|0;a=c[d>>2]|0;if(!a){a=c[b>>2]|0;if(!a){i=0;break}}else b=d;while(1){d=a+20|0;e=c[d>>2]|0;if(e|0){a=e;b=d;continue}d=a+16|0;e=c[d>>2]|0;if(!e)break;else{a=e;b=d}}if(b>>>0>>0)ha();else{c[b>>2]=0;i=a;break}}else{e=c[k+8>>2]|0;if(e>>>0>>0)ha();a=e+12|0;if((c[a>>2]|0)!=(k|0))ha();b=d+8|0;if((c[b>>2]|0)==(k|0)){c[a>>2]=d;c[b>>2]=e;i=d;break}else ha()}while(0);if(f){a=c[k+28>>2]|0;b=35856+(a<<2)|0;if((k|0)==(c[b>>2]|0)){c[b>>2]=i;if(!i){c[8889]=c[8889]&~(1<>>0<(c[8892]|0)>>>0)ha();a=f+16|0;if((c[a>>2]|0)==(k|0))c[a>>2]=i;else c[f+20>>2]=i;if(!i){q=k;g=j;break}}d=c[8892]|0;if(i>>>0>>0)ha();c[i+24>>2]=f;a=k+16|0;b=c[a>>2]|0;do if(b|0)if(b>>>0>>0)ha();else{c[i+16>>2]=b;c[b+24>>2]=i;break}while(0);a=c[a+4>>2]|0;if(a)if(a>>>0<(c[8892]|0)>>>0)ha();else{c[i+20>>2]=a;c[a+24>>2]=i;q=k;g=j;break}else{q=k;g=j}}else{q=k;g=j}}else{q=d;g=e}while(0);if(q>>>0>=m>>>0)ha();a=m+4|0;b=c[a>>2]|0;if(!(b&1))ha();if(!(b&2)){if((m|0)==(c[8894]|0)){p=(c[8891]|0)+g|0;c[8891]=p;c[8894]=q;c[q+4>>2]=p|1;if((q|0)!=(c[8893]|0))return;c[8893]=0;c[8890]=0;return}if((m|0)==(c[8893]|0)){p=(c[8890]|0)+g|0;c[8890]=p;c[8893]=q;c[q+4>>2]=p|1;c[q+p>>2]=p;return}g=(b&-8)+g|0;e=b>>>3;do if(b>>>0>=256){f=c[m+24>>2]|0;a=c[m+12>>2]|0;do if((a|0)==(m|0)){b=m+16|0;d=b+4|0;a=c[d>>2]|0;if(!a){a=c[b>>2]|0;if(!a){n=0;break}}else b=d;while(1){d=a+20|0;e=c[d>>2]|0;if(e|0){a=e;b=d;continue}d=a+16|0;e=c[d>>2]|0;if(!e)break;else{a=e;b=d}}if(b>>>0<(c[8892]|0)>>>0)ha();else{c[b>>2]=0;n=a;break}}else{b=c[m+8>>2]|0;if(b>>>0<(c[8892]|0)>>>0)ha();d=b+12|0;if((c[d>>2]|0)!=(m|0))ha();e=a+8|0;if((c[e>>2]|0)==(m|0)){c[d>>2]=a;c[e>>2]=b;n=a;break}else ha()}while(0);if(f|0){a=c[m+28>>2]|0;b=35856+(a<<2)|0;if((m|0)==(c[b>>2]|0)){c[b>>2]=n;if(!n){c[8889]=c[8889]&~(1<>>0<(c[8892]|0)>>>0)ha();a=f+16|0;if((c[a>>2]|0)==(m|0))c[a>>2]=n;else c[f+20>>2]=n;if(!n)break}d=c[8892]|0;if(n>>>0>>0)ha();c[n+24>>2]=f;a=m+16|0;b=c[a>>2]|0;do if(b|0)if(b>>>0>>0)ha();else{c[n+16>>2]=b;c[b+24>>2]=n;break}while(0);a=c[a+4>>2]|0;if(a|0)if(a>>>0<(c[8892]|0)>>>0)ha();else{c[n+20>>2]=a;c[a+24>>2]=n;break}}}else{b=c[m+8>>2]|0;d=c[m+12>>2]|0;a=35592+(e<<1<<2)|0;if((b|0)!=(a|0)){if(b>>>0<(c[8892]|0)>>>0)ha();if((c[b+12>>2]|0)!=(m|0))ha()}if((d|0)==(b|0)){c[8888]=c[8888]&~(1<>>0<(c[8892]|0)>>>0)ha();a=d+8|0;if((c[a>>2]|0)==(m|0))l=a;else ha()}else l=d+8|0;c[b+12>>2]=d;c[l>>2]=b}while(0);c[q+4>>2]=g|1;c[q+g>>2]=g;if((q|0)==(c[8893]|0)){c[8890]=g;return}}else{c[a>>2]=b&-2;c[q+4>>2]=g|1;c[q+g>>2]=g}a=g>>>3;if(g>>>0<256){d=35592+(a<<1<<2)|0;b=c[8888]|0;a=1<>2]|0;if(b>>>0<(c[8892]|0)>>>0)ha();else{o=a;p=b}}else{c[8888]=b|a;o=d+8|0;p=d}c[o>>2]=q;c[p+12>>2]=q;c[q+8>>2]=p;c[q+12>>2]=d;return}a=g>>>8;if(a)if(g>>>0>16777215)d=31;else{o=(a+1048320|0)>>>16&8;p=a<>>16&4;p=p<>>16&2;d=14-(n|o|d)+(p<>>15)|0;d=g>>>(d+7|0)&1|d<<1}else d=0;e=35856+(d<<2)|0;c[q+28>>2]=d;c[q+20>>2]=0;c[q+16>>2]=0;a=c[8889]|0;b=1<>>1)|0);a=c[e>>2]|0;while(1){if((c[a+4>>2]&-8|0)==(g|0)){d=a;e=130;break}b=a+16+(f>>>31<<2)|0;d=c[b>>2]|0;if(!d){e=127;break}else{f=f<<1;a=d}}if((e|0)==127)if(b>>>0<(c[8892]|0)>>>0)ha();else{c[b>>2]=q;c[q+24>>2]=a;c[q+12>>2]=q;c[q+8>>2]=q;break}else if((e|0)==130){a=d+8|0;b=c[a>>2]|0;p=c[8892]|0;if(b>>>0>=p>>>0&d>>>0>=p>>>0){c[b+12>>2]=q;c[a>>2]=q;c[q+8>>2]=b;c[q+12>>2]=d;c[q+24>>2]=0;break}else ha()}}else{c[8889]=a|b;c[e>>2]=q;c[q+24>>2]=e;c[q+12>>2]=q;c[q+8>>2]=q}while(0);q=(c[8896]|0)+-1|0;c[8896]=q;if(!q)a=36008;else return;while(1){a=c[a>>2]|0;if(!a)break;else a=a+8|0}c[8896]=-1;return}function Oh(){}function Ph(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;d=b-d-(c>>>0>a>>>0|0)>>>0;return (C=d,a-c>>>0|0)|0}function Qh(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;c=a+c>>>0;return (C=b+d+(c>>>0>>0|0)>>>0,c|0)|0}function Rh(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>c;return a>>>c|(b&(1<>c-32|0}function Sh(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function Th(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>>c;return a>>>c|(b&(1<>>c-32|0}function Uh(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b<>>32-c;return a<=4096)return na(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function Wh(b){b=b|0;var c=0;c=a[m+(b&255)>>0]|0;if((c|0)<8)return c|0;c=a[m+(b>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[m+(b>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return (a[m+(b>>>24)>>0]|0)+24|0}function Xh(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;f=a&65535;e=b&65535;c=_(e,f)|0;d=a>>>16;a=(c>>>16)+(_(e,d)|0)|0;e=b>>>16;b=_(e,f)|0;return (C=(a>>>16)+(_(e,d)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|c&65535|0)|0}function Yh(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;j=b>>31|((b|0)<0?-1:0)<<1;i=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;f=d>>31|((d|0)<0?-1:0)<<1;e=((d|0)<0?-1:0)>>31|((d|0)<0?-1:0)<<1;h=Ph(j^a|0,i^b|0,j|0,i|0)|0;g=C;a=f^j;b=e^i;return Ph((bi(h,g,Ph(f^c|0,e^d|0,f|0,e|0)|0,C,0)|0)^a|0,C^b|0,a|0,b|0)|0}function Zh(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;f=i;i=i+16|0;j=f|0;h=b>>31|((b|0)<0?-1:0)<<1;g=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;l=e>>31|((e|0)<0?-1:0)<<1;k=((e|0)<0?-1:0)>>31|((e|0)<0?-1:0)<<1;a=Ph(h^a|0,g^b|0,h|0,g|0)|0;b=C;bi(a,b,Ph(l^d|0,k^e|0,l|0,k|0)|0,C,j)|0;e=Ph(c[j>>2]^h|0,c[j+4>>2]^g|0,h|0,g|0)|0;d=C;i=f;return (C=d,e)|0}function _h(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;f=c;c=Xh(e,f)|0;a=C;return (C=(_(b,f)|0)+(_(d,e)|0)+a|a&0,c|0|0)|0}function $h(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return bi(a,b,c,d,0)|0}function ai(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=i;i=i+16|0;f=g|0;bi(a,b,d,e,f)|0;i=g;return (C=c[f+4>>2]|0,c[f>>2]|0)|0}function bi(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=a;j=b;k=j;h=d;n=e;i=n;if(!k){g=(f|0)!=0;if(!i){if(g){c[f>>2]=(l>>>0)%(h>>>0);c[f+4>>2]=0}n=0;f=(l>>>0)/(h>>>0)>>>0;return (C=n,f)|0}else{if(!g){n=0;f=0;return (C=n,f)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;f=0;return (C=n,f)|0}}g=(i|0)==0;do if(h){if(!g){g=(aa(i|0)|0)-(aa(k|0)|0)|0;if(g>>>0<=31){m=g+1|0;i=31-g|0;b=g-31>>31;h=m;a=l>>>(m>>>0)&b|k<>>(m>>>0)&b;g=0;i=l<>2]=a|0;c[f+4>>2]=j|b&0;n=0;f=0;return (C=n,f)|0}g=h-1|0;if(g&h|0){i=(aa(h|0)|0)+33-(aa(k|0)|0)|0;p=64-i|0;m=32-i|0;j=m>>31;o=i-32|0;b=o>>31;h=i;a=m-1>>31&k>>>(o>>>0)|(k<>>(i>>>0))&b;b=b&k>>>(i>>>0);g=l<>>(o>>>0))&j|l<>31;break}if(f|0){c[f>>2]=g&l;c[f+4>>2]=0}if((h|0)==1){o=j|b&0;p=a|0|0;return (C=o,p)|0}else{p=Wh(h|0)|0;o=k>>>(p>>>0)|0;p=k<<32-p|l>>>(p>>>0)|0;return (C=o,p)|0}}else{if(g){if(f|0){c[f>>2]=(k>>>0)%(h>>>0);c[f+4>>2]=0}o=0;p=(k>>>0)/(h>>>0)>>>0;return (C=o,p)|0}if(!l){if(f|0){c[f>>2]=0;c[f+4>>2]=(k>>>0)%(i>>>0)}o=0;p=(k>>>0)/(i>>>0)>>>0;return (C=o,p)|0}g=i-1|0;if(!(g&i)){if(f|0){c[f>>2]=a|0;c[f+4>>2]=g&k|b&0}o=0;p=k>>>((Wh(i|0)|0)>>>0);return (C=o,p)|0}g=(aa(i|0)|0)-(aa(k|0)|0)|0;if(g>>>0<=30){b=g+1|0;i=31-g|0;h=b;a=k<>>(b>>>0);b=k>>>(b>>>0);g=0;i=l<>2]=a|0;c[f+4>>2]=j|b&0;o=0;p=0;return (C=o,p)|0}while(0);if(!h){k=i;j=0;i=0}else{m=d|0|0;l=n|e&0;k=Qh(m|0,l|0,-1,-1)|0;d=C;j=i;i=0;do{e=j;j=g>>>31|j<<1;g=i|g<<1;e=a<<1|e>>>31|0;n=a>>>31|b<<1|0;Ph(k|0,d|0,e|0,n|0)|0;p=C;o=p>>31|((p|0)<0?-1:0)<<1;i=o&1;a=Ph(e|0,n|0,o&m|0,(((p|0)<0?-1:0)>>31|((p|0)<0?-1:0)<<1)&l|0)|0;b=C;h=h-1|0}while((h|0)!=0);k=j;j=0}h=0;if(f|0){c[f>>2]=a;c[f+4>>2]=b}o=(g|0)>>>31|(k|h)<<1|(h<<1|g>>>31)&0|j;p=(g<<1|0>>>31)&-2|i;return (C=o,p)|0}function ci(a,b){a=a|0;b=b|0;return ra[a&1](b|0)|0}function di(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;return sa[a&3](b|0,c|0,d|0,e|0,f|0,g|0,h|0,i|0,j|0)|0}function ei(a,b,c){a=a|0;b=b|0;c=c|0;return ta[a&3](b|0,c|0)|0}function fi(a){a=a|0;ba(0);return 0}function gi(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;ba(1);return 0}function hi(a,b){a=a|0;b=b|0;ba(2);return 0} + +// EMSCRIPTEN_END_FUNCS +var ra=[fi,rd];var sa=[gi,td,zd,gi];var ta=[hi,sd,yd,hi];return{_olm_create_inbound_session_from:cd,_olm_unpickle_outbound_group_session:lh,_olm_inbound_group_session:Ug,_olm_clear_utility:Cc,_olm_account_identity_keys:Oc,_olm_create_account:Mc,_olm_account_generate_one_time_keys:Zc,_olm_outbound_group_session_last_error:hh,_olm_group_encrypt_message_length:oh,_olm_session_size:sc,_olm_account_sign:Rc,_free:Nh,_olm_pickle_inbound_group_session_length:Yg,_olm_clear_account:Ac,_olm_group_decrypt_max_plaintext_length:ah,_olm_decrypt_max_plaintext_length:md,_olm_create_outbound_session_random_length:_c,_olm_account_size:rc,_olm_session:wc,_olm_account_one_time_keys:Vc,_i64Add:Qh,_olm_group_encrypt:qh,_olm_account_last_error:lc,_olm_group_decrypt:ch,_olm_init_inbound_group_session:Xg,_olm_matches_inbound_session:fd,_olm_remove_one_time_keys:hd,_bitshift64Ashr:Rh,_olm_ed25519_verify:qd,_memset:Sh,_olm_create_inbound_session:ad,_olm_utility_size:tc,_olm_pickle_outbound_group_session:kh,_olm_outbound_group_session_id_length:sh,_memcpy:Vh,_olm_sha256:pd,_olm_error:kc,_olm_clear_outbound_group_session:gh,_olm_account_generate_one_time_keys_random_length:Yc,_bitshift64Shl:Uh,_olm_outbound_group_session_key:wh,_olm_clear_inbound_group_session:Vg,_olm_pickle_account_length:Dc,_i64Subtract:Ph,_olm_outbound_group_session_message_index:uh,_olm_account_one_time_keys_length:Uc,_olm_session_id_length:dd,_olm_unpickle_account:Jc,_olm_unpickle_inbound_group_session:$g,_olm_clear_session:Bc,_olm_encrypt_random_length:jd,_olm_pickle_session:Ic,_olm_inbound_group_session_last_error:Wg,_olm_pickle_outbound_group_session_length:ih,_olm_create_account_random_length:Lc,_olm_encrypt:ld,_olm_pickle_session_length:Ec,_olm_outbound_group_session_size:eh,_olm_outbound_group_session:fh,_olm_utility_last_error:pc,_olm_pickle_inbound_group_session:_g,_olm_encrypt_message_length:kd,_olm_create_outbound_session:$c,_olm_session_id:ed,_olm_inbound_group_session_size:Tg,_olm_init_outbound_group_session_random_length:mh,_olm_outbound_group_session_id:th,_olm_sha256_length:od,_olm_outbound_group_session_key_length:vh,_olm_account_signature_length:Pc,_olm_pickle_account:Fc,_olm_unpickle_session:Kc,_olm_account_max_number_of_one_time_keys:Xc,_olm_account_mark_keys_as_published:Wc,_malloc:Mh,_olm_init_outbound_group_session:nh,_olm_account:uc,_olm_matches_inbound_session_from:gd,_olm_encrypt_message_type:id,_bitshift64Lshr:Th,_olm_decrypt:nd,_olm_session_last_error:nc,_olm_account_identity_keys_length:Nc,_olm_utility:yc,runPostSets:Oh,stackAlloc:ua,stackSave:va,stackRestore:wa,establishStackSpace:xa,setThrew:ya,setTempRet0:Ba,getTempRet0:Ca,dynCall_ii:ci,dynCall_iiiiiiiiii:di,dynCall_iii:ei}}) + + +// EMSCRIPTEN_END_ASM +(a.t,a.u,u);a._olm_create_inbound_session_from=d._olm_create_inbound_session_from;a._olm_unpickle_outbound_group_session=d._olm_unpickle_outbound_group_session;a._olm_pickle_session_length= +d._olm_pickle_session_length;a._olm_clear_utility=d._olm_clear_utility;a._olm_pickle_account_length=d._olm_pickle_account_length;a._olm_create_account=d._olm_create_account;a._olm_account_generate_one_time_keys=d._olm_account_generate_one_time_keys;a._olm_outbound_group_session_message_index=d._olm_outbound_group_session_message_index;a._olm_encrypt_random_length=d._olm_encrypt_random_length;a._olm_session_size=d._olm_session_size;a._olm_account_sign=d._olm_account_sign;var mb=a._bitshift64Lshr=d._bitshift64Lshr; +a._olm_pickle_inbound_group_session_length=d._olm_pickle_inbound_group_session_length;a._olm_clear_account=d._olm_clear_account;a._olm_matches_inbound_session_from=d._olm_matches_inbound_session_from;a._olm_utility_last_error=d._olm_utility_last_error;a._olm_decrypt_max_plaintext_length=d._olm_decrypt_max_plaintext_length;a._olm_group_decrypt=d._olm_group_decrypt;a._olm_account_size=d._olm_account_size;a._olm_session=d._olm_session;a._olm_account_one_time_keys=d._olm_account_one_time_keys;a._olm_decrypt= +d._olm_decrypt;a._olm_outbound_group_session_id_length=d._olm_outbound_group_session_id_length;a._olm_group_decrypt_max_plaintext_length=d._olm_group_decrypt_max_plaintext_length;a._olm_init_inbound_group_session=d._olm_init_inbound_group_session;a._olm_matches_inbound_session=d._olm_matches_inbound_session;a._olm_remove_one_time_keys=d._olm_remove_one_time_keys;var kb=a._bitshift64Ashr=d._bitshift64Ashr;a._olm_ed25519_verify=d._olm_ed25519_verify;var lb=a._memset=d._memset;a._olm_create_inbound_session= +d._olm_create_inbound_session;a._olm_create_outbound_session_random_length=d._olm_create_outbound_session_random_length;a._olm_pickle_outbound_group_session=d._olm_pickle_outbound_group_session;a._olm_unpickle_account=d._olm_unpickle_account;var ob=a._memcpy=d._memcpy;a._olm_session_last_error=d._olm_session_last_error;a._olm_group_encrypt_message_length=d._olm_group_encrypt_message_length;a._olm_error=d._olm_error;a._olm_clear_outbound_group_session=d._olm_clear_outbound_group_session;a._olm_account_generate_one_time_keys_random_length= +d._olm_account_generate_one_time_keys_random_length;a._olm_account_identity_keys_length=d._olm_account_identity_keys_length;var nb=a._bitshift64Shl=d._bitshift64Shl;a._olm_outbound_group_session_key=d._olm_outbound_group_session_key;a._olm_group_encrypt=d._olm_group_encrypt;a._olm_account_identity_keys=d._olm_account_identity_keys;var ib=a._i64Subtract=d._i64Subtract;a._olm_clear_inbound_group_session=d._olm_clear_inbound_group_session;a._olm_session_id_length=d._olm_session_id_length;var jb=a._i64Add= +d._i64Add;a._olm_unpickle_inbound_group_session=d._olm_unpickle_inbound_group_session;a._olm_clear_session=d._olm_clear_session;a._olm_account_last_error=d._olm_account_last_error;a._olm_pickle_session=d._olm_pickle_session;a._olm_inbound_group_session_last_error=d._olm_inbound_group_session_last_error;a._olm_pickle_outbound_group_session_length=d._olm_pickle_outbound_group_session_length;a._olm_create_account_random_length=d._olm_create_account_random_length;a._olm_encrypt=d._olm_encrypt;a._olm_inbound_group_session= +d._olm_inbound_group_session;a._olm_outbound_group_session_last_error=d._olm_outbound_group_session_last_error;a._olm_outbound_group_session=d._olm_outbound_group_session;a._olm_sha256=d._olm_sha256;a._olm_pickle_inbound_group_session=d._olm_pickle_inbound_group_session;a._olm_encrypt_message_length=d._olm_encrypt_message_length;a._olm_create_outbound_session=d._olm_create_outbound_session;a._olm_session_id=d._olm_session_id;a._olm_inbound_group_session_size=d._olm_inbound_group_session_size;a._olm_init_outbound_group_session_random_length= +d._olm_init_outbound_group_session_random_length;a._olm_utility_size=d._olm_utility_size;var ra=a._free=d._free;a.runPostSets=d.runPostSets;a._olm_account_signature_length=d._olm_account_signature_length;a._olm_pickle_account=d._olm_pickle_account;a._olm_unpickle_session=d._olm_unpickle_session;a._olm_account_max_number_of_one_time_keys=d._olm_account_max_number_of_one_time_keys;a._olm_account_mark_keys_as_published=d._olm_account_mark_keys_as_published;var S=a._malloc=d._malloc;a._olm_init_outbound_group_session= +d._olm_init_outbound_group_session;a._olm_account=d._olm_account;a._olm_outbound_group_session_key_length=d._olm_outbound_group_session_key_length;a._olm_encrypt_message_type=d._olm_encrypt_message_type;a._olm_sha256_length=d._olm_sha256_length;a._olm_account_one_time_keys_length=d._olm_account_one_time_keys_length;a._olm_outbound_group_session_size=d._olm_outbound_group_session_size;a._olm_outbound_group_session_id=d._olm_outbound_group_session_id;a._olm_utility=d._olm_utility;a.dynCall_ii=d.dynCall_ii; +a.dynCall_iiiiiiiiii=d.dynCall_iiiiiiiiii;a.dynCall_iii=d.dynCall_iii;f.j=d.stackAlloc;f.f=d.stackSave;f.d=d.stackRestore;f.J=d.establishStackSpace;f.C=d.setTempRet0;f.A=d.getTempRet0;O.prototype=Error();O.prototype.constructor=O;var gb,Na=null,aa=function b(){a.calledRun||ta();a.calledRun||(aa=b)};a.callMain=a.H=function(b){function c(){for(var a=0;3>a;a++)d.push(0)}b=b||[];T||(T=!0,N(ja));var e=b.length+1,d=[G(ga(a.thisProgram),"i8",0)];c();for(var h=0;h tag, or a module + // using CommonJS and NodeJS or RequireJS module formats. In + // Common/Node/RequireJS, the module exports the Q API and when + // executed as a simple