├── public ├── message.proto ├── index.html ├── axios.min.js ├── long.js └── bytebuffer.js ├── package.json └── index.js /public/message.proto: -------------------------------------------------------------------------------- 1 | message Message { 2 | required string text = 1; 3 | required string lang = 2; 4 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proto-buffer-api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Azat Mardan", 10 | "license": "MIT", 11 | "dependencies": { 12 | "express": "^4.13.4", 13 | "protobufjs": "^5.0.1" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

10 |     
11 |     
45 |   
46 | 


--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
 1 | let path = require('path')
 2 | let express = require('express')
 3 | let app = express()
 4 | let messages = [
 5 |   {text: 'hey', lang: 'english'},
 6 |   {text: 'isänme', lang: 'tatar'},
 7 |   {text: 'hej', lang: 'swedish'}
 8 | ]
 9 | let publicFolderName = 'public'
10 | app.use(express.static(publicFolderName))
11 | app.use (function(req, res, next) {
12 |   if (!req.is('application/octet-stream')) return next()
13 |   var data = [] // List of Buffer objects
14 |   req.on('data', function(chunk) {
15 |       data.push(chunk) // Append Buffer object
16 |   })
17 |   req.on('end', function() {
18 |     if (data.length <= 0 ) return next()
19 |     data = Buffer.concat(data) // Make one large Buffer of it
20 |     console.log('Received buffer', data)
21 |     req.raw = data
22 |     next()
23 |   })
24 | })
25 | let ProtoBuf = require('protobufjs')
26 | let builder = ProtoBuf.loadProtoFile(
27 |   path.join(__dirname,
28 |   publicFolderName,
29 |   'message.proto')
30 | )
31 | let Message = builder.build('Message')
32 | 
33 | app.get('/api/messages', (req, res, next)=>{
34 |   let msg = new Message(messages[Math.round(Math.random()*2)])
35 |   console.log('Encode and decode: ',
36 |     Message.decode(msg.encode().toBuffer()))
37 |   console.log('Buffer we are sending: ', msg.encode().toBuffer())
38 |   // res.end(msg.encode().toBuffer(), 'binary') // alternative
39 |   res.send(msg.encode().toBuffer())
40 |   // res.end(Buffer.from(msg.toArrayBuffer()), 'binary') // alternative
41 | })
42 | 
43 | app.post('/api/messages', (req, res, next)=>{
44 |   if (req.raw) {
45 |     try {
46 |         // Decode the Message
47 |       var msg = Message.decode(req.raw)
48 |       console.log('Received "%s" in %s', msg.text, msg.lang)
49 |     } catch (err) {
50 |       console.log('Processing failed:', err)
51 |       next(err)
52 |     }
53 |   } else {
54 |     console.log("Not binary data")
55 |   }
56 | })
57 | 
58 | app.all('*', (req, res)=>{
59 |   res.status(400).send('Not supported')
60 | })
61 | 
62 | app.listen(3000)


--------------------------------------------------------------------------------
/public/axios.min.js:
--------------------------------------------------------------------------------
1 | /* axios v0.11.1 | (c) 2016 by Matt Zabriskie */
2 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(e,t,r){"use strict";function n(e){this.defaults=i.merge({},e),this.interceptors={request:new u,response:new u}}var o=r(2),i=r(3),s=r(4),u=r(13),a=r(14),c=r(15),f=r(16),p=r(8);n.prototype.request=function(e){"string"==typeof e&&(e=i.merge({url:arguments[0]},arguments[1])),e=i.merge(o,this.defaults,{method:"get"},e),e.baseURL&&!a(e.url)&&(e.url=c(e.baseURL,e.url)),e.withCredentials=e.withCredentials||this.defaults.withCredentials,e.data=p(e.data,e.headers,e.transformRequest),e.headers=i.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),i.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]});var t=[s,void 0],r=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)r=r.then(t.shift(),t.shift());return r};var d=new n(o),l=e.exports=f(n.prototype.request,d);e.exports.Axios=n,l.defaults=d.defaults,l.interceptors=d.interceptors,l.create=function(e){return new n(e)},l.all=function(e){return Promise.all(e)},l.spread=r(17),i.forEach(["delete","get","head"],function(e){n.prototype[e]=function(t,r){return this.request(i.merge(r||{},{method:e,url:t}))},l[e]=f(n.prototype[e],d)}),i.forEach(["post","put","patch"],function(e){n.prototype[e]=function(t,r,n){return this.request(i.merge(n||{},{method:e,url:t,data:r}))},l[e]=f(n.prototype[e],d)})},function(e,t,r){"use strict";var n=r(3),o=/^\)\]\}',?\n/,i={"Content-Type":"application/x-www-form-urlencoded"};e.exports={transformRequest:[function(e,t){return n.isFormData(e)||n.isArrayBuffer(e)||n.isStream(e)?e:n.isArrayBufferView(e)?e.buffer:!n.isObject(e)||n.isFile(e)||n.isBlob(e)?e:(n.isUndefined(t)||(n.forEach(t,function(e,r){"content-type"===r.toLowerCase()&&(t["Content-Type"]=e)}),n.isUndefined(t["Content-Type"])&&(t["Content-Type"]="application/json;charset=utf-8")),JSON.stringify(e))}],transformResponse:[function(e){if("string"==typeof e){e=e.replace(o,"");try{e=JSON.parse(e)}catch(t){}}return e}],headers:{common:{Accept:"application/json, text/plain, */*"},patch:n.merge(i),post:n.merge(i),put:n.merge(i)},timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&300>e}}},function(e,t){"use strict";function r(e){return"[object Array]"===v.call(e)}function n(e){return"[object ArrayBuffer]"===v.call(e)}function o(e){return"undefined"!=typeof FormData&&e instanceof FormData}function i(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function s(e){return"string"==typeof e}function u(e){return"number"==typeof e}function a(e){return"undefined"==typeof e}function c(e){return null!==e&&"object"==typeof e}function f(e){return"[object Date]"===v.call(e)}function p(e){return"[object File]"===v.call(e)}function d(e){return"[object Blob]"===v.call(e)}function l(e){return"[object Function]"===v.call(e)}function h(e){return c(e)&&l(e.pipe)}function m(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function y(){return"undefined"!=typeof window&&"undefined"!=typeof document&&"function"==typeof document.createElement}function w(e,t){if(null!==e&&"undefined"!=typeof e)if("object"==typeof e||r(e)||(e=[e]),r(e))for(var n=0,o=e.length;o>n;n++)t.call(null,e[n],n,e);else for(var i in e)e.hasOwnProperty(i)&&t.call(null,e[i],i,e)}function g(){function e(e,r){"object"==typeof t[r]&&"object"==typeof e?t[r]=g(t[r],e):t[r]=e}for(var t={},r=0,n=arguments.length;n>r;r++)w(arguments[r],e);return t}var v=Object.prototype.toString;e.exports={isArray:r,isArrayBuffer:n,isFormData:o,isArrayBufferView:i,isString:s,isNumber:u,isObject:c,isUndefined:a,isDate:f,isFile:p,isBlob:d,isFunction:l,isStream:h,isStandardBrowserEnv:y,forEach:w,merge:g,trim:m}},function(e,t,r){"use strict";e.exports=function(e){return new Promise(function(t,n){try{var o;"function"==typeof e.adapter?o=e.adapter:"undefined"!=typeof XMLHttpRequest?o=r(5):"undefined"!=typeof process&&(o=r(5)),"function"==typeof o&&o(t,n,e)}catch(i){n(i)}})}},function(e,t,r){"use strict";var n=r(3),o=r(6),i=r(7),s=r(8),u=r(9),a="undefined"!=typeof window&&window.btoa||r(10),c=r(11);e.exports=function(e,t,f){var p=f.data,d=f.headers;n.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest,h="onreadystatechange",m=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in l||u(f.url)||(l=new window.XDomainRequest,h="onload",m=!0,l.onprogress=function(){},l.ontimeout=function(){}),f.auth){var y=f.auth.username||"",w=f.auth.password||"";d.Authorization="Basic "+a(y+":"+w)}if(l.open(f.method.toUpperCase(),o(f.url,f.params,f.paramsSerializer),!0),l.timeout=f.timeout,l[h]=function(){if(l&&(4===l.readyState||m)&&0!==l.status){var r="getAllResponseHeaders"in l?i(l.getAllResponseHeaders()):null,n=f.responseType&&"text"!==f.responseType?l.response:l.responseText,o={data:s(n,r,f.transformResponse),status:1223===l.status?204:l.status,statusText:1223===l.status?"No Content":l.statusText,headers:r,config:f,request:l};c(e,t,o),l=null}},l.onerror=function(){t(new Error("Network Error")),l=null},l.ontimeout=function(){var e=new Error("timeout of "+f.timeout+"ms exceeded");e.timeout=f.timeout,e.code="ECONNABORTED",t(e),l=null},n.isStandardBrowserEnv()){var g=r(12),v=f.withCredentials||u(f.url)?g.read(f.xsrfCookieName):void 0;v&&(d[f.xsrfHeaderName]=v)}if("setRequestHeader"in l&&n.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),f.withCredentials&&(l.withCredentials=!0),f.responseType)try{l.responseType=f.responseType}catch(x){if("json"!==l.responseType)throw x}f.progress&&("post"===f.method||"put"===f.method?l.upload.addEventListener("progress",f.progress):"get"===f.method&&l.addEventListener("progress",f.progress)),void 0===p&&(p=null),l.send(p)}},function(e,t,r){"use strict";function n(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=r(3);e.exports=function(e,t,r){if(!t)return e;var i;if(r)i=r(t);else{var s=[];o.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(o.isArray(e)&&(t+="[]"),o.isArray(e)||(e=[e]),o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),s.push(n(t)+"="+n(e))}))}),i=s.join("&")}return i&&(e+=(-1===e.indexOf("?")?"?":"&")+i),e}},function(e,t,r){"use strict";var n=r(3);e.exports=function(e){var t,r,o,i={};return e?(n.forEach(e.split("\n"),function(e){o=e.indexOf(":"),t=n.trim(e.substr(0,o)).toLowerCase(),r=n.trim(e.substr(o+1)),t&&(i[t]=i[t]?i[t]+", "+r:r)}),i):i}},function(e,t,r){"use strict";var n=r(3);e.exports=function(e,t,r){return n.forEach(r,function(r){e=r(e,t)}),e}},function(e,t,r){"use strict";var n=r(3);e.exports=n.isStandardBrowserEnv()?function(){function e(e){var t=e;return r&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,r=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(r){var o=n.isString(r)?e(r):r;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t){"use strict";function r(){this.message="String contains an invalid character"}function n(e){for(var t,n,i=String(e),s="",u=0,a=o;i.charAt(0|u)||(a="=",u%1);s+=a.charAt(63&t>>8-u%1*8)){if(n=i.charCodeAt(u+=.75),n>255)throw new r;t=t<<8|n}return s}var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";r.prototype=new Error,r.prototype.code=5,r.prototype.name="InvalidCharacterError",e.exports=n},function(e,t){"use strict";e.exports=function(e,t,r){var n=r.config.validateStatus;r.status&&n&&!n(r.status)?t(r):e(r)}},function(e,t,r){"use strict";var n=r(3);e.exports=n.isStandardBrowserEnv()?function(){return{write:function(e,t,r,o,i,s){var u=[];u.push(e+"="+encodeURIComponent(t)),n.isNumber(r)&&u.push("expires="+new Date(r).toGMTString()),n.isString(o)&&u.push("path="+o),n.isString(i)&&u.push("domain="+i),s===!0&&u.push("secure"),document.cookie=u.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,r){"use strict";function n(){this.handlers=[]}var o=r(3);n.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},n.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},n.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=n},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,"")}},function(e,t){"use strict";e.exports=function(e,t){return function(){for(var r=new Array(arguments.length),n=0;n
   3 |  Copyright 2009 The Closure Library Authors. All Rights Reserved.
   4 | 
   5 |  Licensed under the Apache License, Version 2.0 (the "License");
   6 |  you may not use this file except in compliance with the License.
   7 |  You may obtain a copy of the License at
   8 | 
   9 |  http://www.apache.org/licenses/LICENSE-2.0
  10 | 
  11 |  Unless required by applicable law or agreed to in writing, software
  12 |  distributed under the License is distributed on an "AS-IS" BASIS,
  13 |  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 |  See the License for the specific language governing permissions and
  15 |  limitations under the License.
  16 |  */
  17 | 
  18 | /**
  19 |  * @license long.js (c) 2013 Daniel Wirtz 
  20 |  * Released under the Apache License, Version 2.0
  21 |  * see: https://github.com/dcodeIO/long.js for details
  22 |  */
  23 | (function(global, factory) {
  24 | 
  25 |     /* AMD */ if (typeof define === 'function' && define["amd"])
  26 |         define([], factory);
  27 |     /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
  28 |         module["exports"] = factory();
  29 |     /* Global */ else
  30 |         (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
  31 | 
  32 | })(this, function() {
  33 |     "use strict";
  34 | 
  35 |     /**
  36 |      * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
  37 |      *  See the from* functions below for more convenient ways of constructing Longs.
  38 |      * @exports Long
  39 |      * @class A Long class for representing a 64 bit two's-complement integer value.
  40 |      * @param {number} low The low (signed) 32 bits of the long
  41 |      * @param {number} high The high (signed) 32 bits of the long
  42 |      * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  43 |      * @constructor
  44 |      */
  45 |     function Long(low, high, unsigned) {
  46 | 
  47 |         /**
  48 |          * The low 32 bits as a signed value.
  49 |          * @type {number}
  50 |          * @expose
  51 |          */
  52 |         this.low = low | 0;
  53 | 
  54 |         /**
  55 |          * The high 32 bits as a signed value.
  56 |          * @type {number}
  57 |          * @expose
  58 |          */
  59 |         this.high = high | 0;
  60 | 
  61 |         /**
  62 |          * Whether unsigned or not.
  63 |          * @type {boolean}
  64 |          * @expose
  65 |          */
  66 |         this.unsigned = !!unsigned;
  67 |     }
  68 | 
  69 |     // The internal representation of a long is the two given signed, 32-bit values.
  70 |     // We use 32-bit pieces because these are the size of integers on which
  71 |     // Javascript performs bit-operations.  For operations like addition and
  72 |     // multiplication, we split each number into 16 bit pieces, which can easily be
  73 |     // multiplied within Javascript's floating-point representation without overflow
  74 |     // or change in sign.
  75 |     //
  76 |     // In the algorithms below, we frequently reduce the negative case to the
  77 |     // positive case by negating the input(s) and then post-processing the result.
  78 |     // Note that we must ALWAYS check specially whether those values are MIN_VALUE
  79 |     // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
  80 |     // a positive number, it overflows back into a negative).  Not handling this
  81 |     // case would often result in infinite recursion.
  82 |     //
  83 |     // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
  84 |     // methods on which they depend.
  85 | 
  86 |     /**
  87 |      * An indicator used to reliably determine if an object is a Long or not.
  88 |      * @type {boolean}
  89 |      * @const
  90 |      * @expose
  91 |      * @private
  92 |      */
  93 |     Long.prototype.__isLong__;
  94 | 
  95 |     Object.defineProperty(Long.prototype, "__isLong__", {
  96 |         value: true,
  97 |         enumerable: false,
  98 |         configurable: false
  99 |     });
 100 | 
 101 |     /**
 102 |      * @function
 103 |      * @param {*} obj Object
 104 |      * @returns {boolean}
 105 |      * @inner
 106 |      */
 107 |     function isLong(obj) {
 108 |         return (obj && obj["__isLong__"]) === true;
 109 |     }
 110 | 
 111 |     /**
 112 |      * Tests if the specified object is a Long.
 113 |      * @function
 114 |      * @param {*} obj Object
 115 |      * @returns {boolean}
 116 |      * @expose
 117 |      */
 118 |     Long.isLong = isLong;
 119 | 
 120 |     /**
 121 |      * A cache of the Long representations of small integer values.
 122 |      * @type {!Object}
 123 |      * @inner
 124 |      */
 125 |     var INT_CACHE = {};
 126 | 
 127 |     /**
 128 |      * A cache of the Long representations of small unsigned integer values.
 129 |      * @type {!Object}
 130 |      * @inner
 131 |      */
 132 |     var UINT_CACHE = {};
 133 | 
 134 |     /**
 135 |      * @param {number} value
 136 |      * @param {boolean=} unsigned
 137 |      * @returns {!Long}
 138 |      * @inner
 139 |      */
 140 |     function fromInt(value, unsigned) {
 141 |         var obj, cachedObj, cache;
 142 |         if (unsigned) {
 143 |             value >>>= 0;
 144 |             if (cache = (0 <= value && value < 256)) {
 145 |                 cachedObj = UINT_CACHE[value];
 146 |                 if (cachedObj)
 147 |                     return cachedObj;
 148 |             }
 149 |             obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
 150 |             if (cache)
 151 |                 UINT_CACHE[value] = obj;
 152 |             return obj;
 153 |         } else {
 154 |             value |= 0;
 155 |             if (cache = (-128 <= value && value < 128)) {
 156 |                 cachedObj = INT_CACHE[value];
 157 |                 if (cachedObj)
 158 |                     return cachedObj;
 159 |             }
 160 |             obj = fromBits(value, value < 0 ? -1 : 0, false);
 161 |             if (cache)
 162 |                 INT_CACHE[value] = obj;
 163 |             return obj;
 164 |         }
 165 |     }
 166 | 
 167 |     /**
 168 |      * Returns a Long representing the given 32 bit integer value.
 169 |      * @function
 170 |      * @param {number} value The 32 bit integer in question
 171 |      * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
 172 |      * @returns {!Long} The corresponding Long value
 173 |      * @expose
 174 |      */
 175 |     Long.fromInt = fromInt;
 176 | 
 177 |     /**
 178 |      * @param {number} value
 179 |      * @param {boolean=} unsigned
 180 |      * @returns {!Long}
 181 |      * @inner
 182 |      */
 183 |     function fromNumber(value, unsigned) {
 184 |         if (isNaN(value) || !isFinite(value))
 185 |             return unsigned ? UZERO : ZERO;
 186 |         if (unsigned) {
 187 |             if (value < 0)
 188 |                 return UZERO;
 189 |             if (value >= TWO_PWR_64_DBL)
 190 |                 return MAX_UNSIGNED_VALUE;
 191 |         } else {
 192 |             if (value <= -TWO_PWR_63_DBL)
 193 |                 return MIN_VALUE;
 194 |             if (value + 1 >= TWO_PWR_63_DBL)
 195 |                 return MAX_VALUE;
 196 |         }
 197 |         if (value < 0)
 198 |             return fromNumber(-value, unsigned).neg();
 199 |         return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
 200 |     }
 201 | 
 202 |     /**
 203 |      * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
 204 |      * @function
 205 |      * @param {number} value The number in question
 206 |      * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
 207 |      * @returns {!Long} The corresponding Long value
 208 |      * @expose
 209 |      */
 210 |     Long.fromNumber = fromNumber;
 211 | 
 212 |     /**
 213 |      * @param {number} lowBits
 214 |      * @param {number} highBits
 215 |      * @param {boolean=} unsigned
 216 |      * @returns {!Long}
 217 |      * @inner
 218 |      */
 219 |     function fromBits(lowBits, highBits, unsigned) {
 220 |         return new Long(lowBits, highBits, unsigned);
 221 |     }
 222 | 
 223 |     /**
 224 |      * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
 225 |      *  assumed to use 32 bits.
 226 |      * @function
 227 |      * @param {number} lowBits The low 32 bits
 228 |      * @param {number} highBits The high 32 bits
 229 |      * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
 230 |      * @returns {!Long} The corresponding Long value
 231 |      * @expose
 232 |      */
 233 |     Long.fromBits = fromBits;
 234 | 
 235 |     /**
 236 |      * @function
 237 |      * @param {number} base
 238 |      * @param {number} exponent
 239 |      * @returns {number}
 240 |      * @inner
 241 |      */
 242 |     var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
 243 | 
 244 |     /**
 245 |      * @param {string} str
 246 |      * @param {(boolean|number)=} unsigned
 247 |      * @param {number=} radix
 248 |      * @returns {!Long}
 249 |      * @inner
 250 |      */
 251 |     function fromString(str, unsigned, radix) {
 252 |         if (str.length === 0)
 253 |             throw Error('empty string');
 254 |         if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
 255 |             return ZERO;
 256 |         if (typeof unsigned === 'number') {
 257 |             // For goog.math.long compatibility
 258 |             radix = unsigned,
 259 |             unsigned = false;
 260 |         } else {
 261 |             unsigned = !! unsigned;
 262 |         }
 263 |         radix = radix || 10;
 264 |         if (radix < 2 || 36 < radix)
 265 |             throw RangeError('radix');
 266 | 
 267 |         var p;
 268 |         if ((p = str.indexOf('-')) > 0)
 269 |             throw Error('interior hyphen');
 270 |         else if (p === 0) {
 271 |             return fromString(str.substring(1), unsigned, radix).neg();
 272 |         }
 273 | 
 274 |         // Do several (8) digits each time through the loop, so as to
 275 |         // minimize the calls to the very expensive emulated div.
 276 |         var radixToPower = fromNumber(pow_dbl(radix, 8));
 277 | 
 278 |         var result = ZERO;
 279 |         for (var i = 0; i < str.length; i += 8) {
 280 |             var size = Math.min(8, str.length - i),
 281 |                 value = parseInt(str.substring(i, i + size), radix);
 282 |             if (size < 8) {
 283 |                 var power = fromNumber(pow_dbl(radix, size));
 284 |                 result = result.mul(power).add(fromNumber(value));
 285 |             } else {
 286 |                 result = result.mul(radixToPower);
 287 |                 result = result.add(fromNumber(value));
 288 |             }
 289 |         }
 290 |         result.unsigned = unsigned;
 291 |         return result;
 292 |     }
 293 | 
 294 |     /**
 295 |      * Returns a Long representation of the given string, written using the specified radix.
 296 |      * @function
 297 |      * @param {string} str The textual representation of the Long
 298 |      * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
 299 |      * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
 300 |      * @returns {!Long} The corresponding Long value
 301 |      * @expose
 302 |      */
 303 |     Long.fromString = fromString;
 304 | 
 305 |     /**
 306 |      * @function
 307 |      * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
 308 |      * @returns {!Long}
 309 |      * @inner
 310 |      */
 311 |     function fromValue(val) {
 312 |         if (val /* is compatible */ instanceof Long)
 313 |             return val;
 314 |         if (typeof val === 'number')
 315 |             return fromNumber(val);
 316 |         if (typeof val === 'string')
 317 |             return fromString(val);
 318 |         // Throws for non-objects, converts non-instanceof Long:
 319 |         return fromBits(val.low, val.high, val.unsigned);
 320 |     }
 321 | 
 322 |     /**
 323 |      * Converts the specified value to a Long.
 324 |      * @function
 325 |      * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
 326 |      * @returns {!Long}
 327 |      * @expose
 328 |      */
 329 |     Long.fromValue = fromValue;
 330 | 
 331 |     // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
 332 |     // no runtime penalty for these.
 333 | 
 334 |     /**
 335 |      * @type {number}
 336 |      * @const
 337 |      * @inner
 338 |      */
 339 |     var TWO_PWR_16_DBL = 1 << 16;
 340 | 
 341 |     /**
 342 |      * @type {number}
 343 |      * @const
 344 |      * @inner
 345 |      */
 346 |     var TWO_PWR_24_DBL = 1 << 24;
 347 | 
 348 |     /**
 349 |      * @type {number}
 350 |      * @const
 351 |      * @inner
 352 |      */
 353 |     var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
 354 | 
 355 |     /**
 356 |      * @type {number}
 357 |      * @const
 358 |      * @inner
 359 |      */
 360 |     var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
 361 | 
 362 |     /**
 363 |      * @type {number}
 364 |      * @const
 365 |      * @inner
 366 |      */
 367 |     var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
 368 | 
 369 |     /**
 370 |      * @type {!Long}
 371 |      * @const
 372 |      * @inner
 373 |      */
 374 |     var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
 375 | 
 376 |     /**
 377 |      * @type {!Long}
 378 |      * @inner
 379 |      */
 380 |     var ZERO = fromInt(0);
 381 | 
 382 |     /**
 383 |      * Signed zero.
 384 |      * @type {!Long}
 385 |      * @expose
 386 |      */
 387 |     Long.ZERO = ZERO;
 388 | 
 389 |     /**
 390 |      * @type {!Long}
 391 |      * @inner
 392 |      */
 393 |     var UZERO = fromInt(0, true);
 394 | 
 395 |     /**
 396 |      * Unsigned zero.
 397 |      * @type {!Long}
 398 |      * @expose
 399 |      */
 400 |     Long.UZERO = UZERO;
 401 | 
 402 |     /**
 403 |      * @type {!Long}
 404 |      * @inner
 405 |      */
 406 |     var ONE = fromInt(1);
 407 | 
 408 |     /**
 409 |      * Signed one.
 410 |      * @type {!Long}
 411 |      * @expose
 412 |      */
 413 |     Long.ONE = ONE;
 414 | 
 415 |     /**
 416 |      * @type {!Long}
 417 |      * @inner
 418 |      */
 419 |     var UONE = fromInt(1, true);
 420 | 
 421 |     /**
 422 |      * Unsigned one.
 423 |      * @type {!Long}
 424 |      * @expose
 425 |      */
 426 |     Long.UONE = UONE;
 427 | 
 428 |     /**
 429 |      * @type {!Long}
 430 |      * @inner
 431 |      */
 432 |     var NEG_ONE = fromInt(-1);
 433 | 
 434 |     /**
 435 |      * Signed negative one.
 436 |      * @type {!Long}
 437 |      * @expose
 438 |      */
 439 |     Long.NEG_ONE = NEG_ONE;
 440 | 
 441 |     /**
 442 |      * @type {!Long}
 443 |      * @inner
 444 |      */
 445 |     var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
 446 | 
 447 |     /**
 448 |      * Maximum signed value.
 449 |      * @type {!Long}
 450 |      * @expose
 451 |      */
 452 |     Long.MAX_VALUE = MAX_VALUE;
 453 | 
 454 |     /**
 455 |      * @type {!Long}
 456 |      * @inner
 457 |      */
 458 |     var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
 459 | 
 460 |     /**
 461 |      * Maximum unsigned value.
 462 |      * @type {!Long}
 463 |      * @expose
 464 |      */
 465 |     Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
 466 | 
 467 |     /**
 468 |      * @type {!Long}
 469 |      * @inner
 470 |      */
 471 |     var MIN_VALUE = fromBits(0, 0x80000000|0, false);
 472 | 
 473 |     /**
 474 |      * Minimum signed value.
 475 |      * @type {!Long}
 476 |      * @expose
 477 |      */
 478 |     Long.MIN_VALUE = MIN_VALUE;
 479 | 
 480 |     /**
 481 |      * @alias Long.prototype
 482 |      * @inner
 483 |      */
 484 |     var LongPrototype = Long.prototype;
 485 | 
 486 |     /**
 487 |      * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
 488 |      * @returns {number}
 489 |      * @expose
 490 |      */
 491 |     LongPrototype.toInt = function toInt() {
 492 |         return this.unsigned ? this.low >>> 0 : this.low;
 493 |     };
 494 | 
 495 |     /**
 496 |      * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
 497 |      * @returns {number}
 498 |      * @expose
 499 |      */
 500 |     LongPrototype.toNumber = function toNumber() {
 501 |         if (this.unsigned)
 502 |             return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
 503 |         return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
 504 |     };
 505 | 
 506 |     /**
 507 |      * Converts the Long to a string written in the specified radix.
 508 |      * @param {number=} radix Radix (2-36), defaults to 10
 509 |      * @returns {string}
 510 |      * @override
 511 |      * @throws {RangeError} If `radix` is out of range
 512 |      * @expose
 513 |      */
 514 |     LongPrototype.toString = function toString(radix) {
 515 |         radix = radix || 10;
 516 |         if (radix < 2 || 36 < radix)
 517 |             throw RangeError('radix');
 518 |         if (this.isZero())
 519 |             return '0';
 520 |         if (this.isNegative()) { // Unsigned Longs are never negative
 521 |             if (this.eq(MIN_VALUE)) {
 522 |                 // We need to change the Long value before it can be negated, so we remove
 523 |                 // the bottom-most digit in this base and then recurse to do the rest.
 524 |                 var radixLong = fromNumber(radix),
 525 |                     div = this.div(radixLong),
 526 |                     rem1 = div.mul(radixLong).sub(this);
 527 |                 return div.toString(radix) + rem1.toInt().toString(radix);
 528 |             } else
 529 |                 return '-' + this.neg().toString(radix);
 530 |         }
 531 | 
 532 |         // Do several (6) digits each time through the loop, so as to
 533 |         // minimize the calls to the very expensive emulated div.
 534 |         var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
 535 |             rem = this;
 536 |         var result = '';
 537 |         while (true) {
 538 |             var remDiv = rem.div(radixToPower),
 539 |                 intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
 540 |                 digits = intval.toString(radix);
 541 |             rem = remDiv;
 542 |             if (rem.isZero())
 543 |                 return digits + result;
 544 |             else {
 545 |                 while (digits.length < 6)
 546 |                     digits = '0' + digits;
 547 |                 result = '' + digits + result;
 548 |             }
 549 |         }
 550 |     };
 551 | 
 552 |     /**
 553 |      * Gets the high 32 bits as a signed integer.
 554 |      * @returns {number} Signed high bits
 555 |      * @expose
 556 |      */
 557 |     LongPrototype.getHighBits = function getHighBits() {
 558 |         return this.high;
 559 |     };
 560 | 
 561 |     /**
 562 |      * Gets the high 32 bits as an unsigned integer.
 563 |      * @returns {number} Unsigned high bits
 564 |      * @expose
 565 |      */
 566 |     LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
 567 |         return this.high >>> 0;
 568 |     };
 569 | 
 570 |     /**
 571 |      * Gets the low 32 bits as a signed integer.
 572 |      * @returns {number} Signed low bits
 573 |      * @expose
 574 |      */
 575 |     LongPrototype.getLowBits = function getLowBits() {
 576 |         return this.low;
 577 |     };
 578 | 
 579 |     /**
 580 |      * Gets the low 32 bits as an unsigned integer.
 581 |      * @returns {number} Unsigned low bits
 582 |      * @expose
 583 |      */
 584 |     LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
 585 |         return this.low >>> 0;
 586 |     };
 587 | 
 588 |     /**
 589 |      * Gets the number of bits needed to represent the absolute value of this Long.
 590 |      * @returns {number}
 591 |      * @expose
 592 |      */
 593 |     LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
 594 |         if (this.isNegative()) // Unsigned Longs are never negative
 595 |             return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
 596 |         var val = this.high != 0 ? this.high : this.low;
 597 |         for (var bit = 31; bit > 0; bit--)
 598 |             if ((val & (1 << bit)) != 0)
 599 |                 break;
 600 |         return this.high != 0 ? bit + 33 : bit + 1;
 601 |     };
 602 | 
 603 |     /**
 604 |      * Tests if this Long's value equals zero.
 605 |      * @returns {boolean}
 606 |      * @expose
 607 |      */
 608 |     LongPrototype.isZero = function isZero() {
 609 |         return this.high === 0 && this.low === 0;
 610 |     };
 611 | 
 612 |     /**
 613 |      * Tests if this Long's value is negative.
 614 |      * @returns {boolean}
 615 |      * @expose
 616 |      */
 617 |     LongPrototype.isNegative = function isNegative() {
 618 |         return !this.unsigned && this.high < 0;
 619 |     };
 620 | 
 621 |     /**
 622 |      * Tests if this Long's value is positive.
 623 |      * @returns {boolean}
 624 |      * @expose
 625 |      */
 626 |     LongPrototype.isPositive = function isPositive() {
 627 |         return this.unsigned || this.high >= 0;
 628 |     };
 629 | 
 630 |     /**
 631 |      * Tests if this Long's value is odd.
 632 |      * @returns {boolean}
 633 |      * @expose
 634 |      */
 635 |     LongPrototype.isOdd = function isOdd() {
 636 |         return (this.low & 1) === 1;
 637 |     };
 638 | 
 639 |     /**
 640 |      * Tests if this Long's value is even.
 641 |      * @returns {boolean}
 642 |      * @expose
 643 |      */
 644 |     LongPrototype.isEven = function isEven() {
 645 |         return (this.low & 1) === 0;
 646 |     };
 647 | 
 648 |     /**
 649 |      * Tests if this Long's value equals the specified's.
 650 |      * @param {!Long|number|string} other Other value
 651 |      * @returns {boolean}
 652 |      * @expose
 653 |      */
 654 |     LongPrototype.equals = function equals(other) {
 655 |         if (!isLong(other))
 656 |             other = fromValue(other);
 657 |         if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
 658 |             return false;
 659 |         return this.high === other.high && this.low === other.low;
 660 |     };
 661 | 
 662 |     /**
 663 |      * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
 664 |      * @function
 665 |      * @param {!Long|number|string} other Other value
 666 |      * @returns {boolean}
 667 |      * @expose
 668 |      */
 669 |     LongPrototype.eq = LongPrototype.equals;
 670 | 
 671 |     /**
 672 |      * Tests if this Long's value differs from the specified's.
 673 |      * @param {!Long|number|string} other Other value
 674 |      * @returns {boolean}
 675 |      * @expose
 676 |      */
 677 |     LongPrototype.notEquals = function notEquals(other) {
 678 |         return !this.eq(/* validates */ other);
 679 |     };
 680 | 
 681 |     /**
 682 |      * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
 683 |      * @function
 684 |      * @param {!Long|number|string} other Other value
 685 |      * @returns {boolean}
 686 |      * @expose
 687 |      */
 688 |     LongPrototype.neq = LongPrototype.notEquals;
 689 | 
 690 |     /**
 691 |      * Tests if this Long's value is less than the specified's.
 692 |      * @param {!Long|number|string} other Other value
 693 |      * @returns {boolean}
 694 |      * @expose
 695 |      */
 696 |     LongPrototype.lessThan = function lessThan(other) {
 697 |         return this.comp(/* validates */ other) < 0;
 698 |     };
 699 | 
 700 |     /**
 701 |      * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
 702 |      * @function
 703 |      * @param {!Long|number|string} other Other value
 704 |      * @returns {boolean}
 705 |      * @expose
 706 |      */
 707 |     LongPrototype.lt = LongPrototype.lessThan;
 708 | 
 709 |     /**
 710 |      * Tests if this Long's value is less than or equal the specified's.
 711 |      * @param {!Long|number|string} other Other value
 712 |      * @returns {boolean}
 713 |      * @expose
 714 |      */
 715 |     LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
 716 |         return this.comp(/* validates */ other) <= 0;
 717 |     };
 718 | 
 719 |     /**
 720 |      * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
 721 |      * @function
 722 |      * @param {!Long|number|string} other Other value
 723 |      * @returns {boolean}
 724 |      * @expose
 725 |      */
 726 |     LongPrototype.lte = LongPrototype.lessThanOrEqual;
 727 | 
 728 |     /**
 729 |      * Tests if this Long's value is greater than the specified's.
 730 |      * @param {!Long|number|string} other Other value
 731 |      * @returns {boolean}
 732 |      * @expose
 733 |      */
 734 |     LongPrototype.greaterThan = function greaterThan(other) {
 735 |         return this.comp(/* validates */ other) > 0;
 736 |     };
 737 | 
 738 |     /**
 739 |      * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
 740 |      * @function
 741 |      * @param {!Long|number|string} other Other value
 742 |      * @returns {boolean}
 743 |      * @expose
 744 |      */
 745 |     LongPrototype.gt = LongPrototype.greaterThan;
 746 | 
 747 |     /**
 748 |      * Tests if this Long's value is greater than or equal the specified's.
 749 |      * @param {!Long|number|string} other Other value
 750 |      * @returns {boolean}
 751 |      * @expose
 752 |      */
 753 |     LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
 754 |         return this.comp(/* validates */ other) >= 0;
 755 |     };
 756 | 
 757 |     /**
 758 |      * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
 759 |      * @function
 760 |      * @param {!Long|number|string} other Other value
 761 |      * @returns {boolean}
 762 |      * @expose
 763 |      */
 764 |     LongPrototype.gte = LongPrototype.greaterThanOrEqual;
 765 | 
 766 |     /**
 767 |      * Compares this Long's value with the specified's.
 768 |      * @param {!Long|number|string} other Other value
 769 |      * @returns {number} 0 if they are the same, 1 if the this is greater and -1
 770 |      *  if the given one is greater
 771 |      * @expose
 772 |      */
 773 |     LongPrototype.compare = function compare(other) {
 774 |         if (!isLong(other))
 775 |             other = fromValue(other);
 776 |         if (this.eq(other))
 777 |             return 0;
 778 |         var thisNeg = this.isNegative(),
 779 |             otherNeg = other.isNegative();
 780 |         if (thisNeg && !otherNeg)
 781 |             return -1;
 782 |         if (!thisNeg && otherNeg)
 783 |             return 1;
 784 |         // At this point the sign bits are the same
 785 |         if (!this.unsigned)
 786 |             return this.sub(other).isNegative() ? -1 : 1;
 787 |         // Both are positive if at least one is unsigned
 788 |         return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
 789 |     };
 790 | 
 791 |     /**
 792 |      * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
 793 |      * @function
 794 |      * @param {!Long|number|string} other Other value
 795 |      * @returns {number} 0 if they are the same, 1 if the this is greater and -1
 796 |      *  if the given one is greater
 797 |      * @expose
 798 |      */
 799 |     LongPrototype.comp = LongPrototype.compare;
 800 | 
 801 |     /**
 802 |      * Negates this Long's value.
 803 |      * @returns {!Long} Negated Long
 804 |      * @expose
 805 |      */
 806 |     LongPrototype.negate = function negate() {
 807 |         if (!this.unsigned && this.eq(MIN_VALUE))
 808 |             return MIN_VALUE;
 809 |         return this.not().add(ONE);
 810 |     };
 811 | 
 812 |     /**
 813 |      * Negates this Long's value. This is an alias of {@link Long#negate}.
 814 |      * @function
 815 |      * @returns {!Long} Negated Long
 816 |      * @expose
 817 |      */
 818 |     LongPrototype.neg = LongPrototype.negate;
 819 | 
 820 |     /**
 821 |      * Returns the sum of this and the specified Long.
 822 |      * @param {!Long|number|string} addend Addend
 823 |      * @returns {!Long} Sum
 824 |      * @expose
 825 |      */
 826 |     LongPrototype.add = function add(addend) {
 827 |         if (!isLong(addend))
 828 |             addend = fromValue(addend);
 829 | 
 830 |         // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
 831 | 
 832 |         var a48 = this.high >>> 16;
 833 |         var a32 = this.high & 0xFFFF;
 834 |         var a16 = this.low >>> 16;
 835 |         var a00 = this.low & 0xFFFF;
 836 | 
 837 |         var b48 = addend.high >>> 16;
 838 |         var b32 = addend.high & 0xFFFF;
 839 |         var b16 = addend.low >>> 16;
 840 |         var b00 = addend.low & 0xFFFF;
 841 | 
 842 |         var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
 843 |         c00 += a00 + b00;
 844 |         c16 += c00 >>> 16;
 845 |         c00 &= 0xFFFF;
 846 |         c16 += a16 + b16;
 847 |         c32 += c16 >>> 16;
 848 |         c16 &= 0xFFFF;
 849 |         c32 += a32 + b32;
 850 |         c48 += c32 >>> 16;
 851 |         c32 &= 0xFFFF;
 852 |         c48 += a48 + b48;
 853 |         c48 &= 0xFFFF;
 854 |         return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
 855 |     };
 856 | 
 857 |     /**
 858 |      * Returns the difference of this and the specified Long.
 859 |      * @param {!Long|number|string} subtrahend Subtrahend
 860 |      * @returns {!Long} Difference
 861 |      * @expose
 862 |      */
 863 |     LongPrototype.subtract = function subtract(subtrahend) {
 864 |         if (!isLong(subtrahend))
 865 |             subtrahend = fromValue(subtrahend);
 866 |         return this.add(subtrahend.neg());
 867 |     };
 868 | 
 869 |     /**
 870 |      * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
 871 |      * @function
 872 |      * @param {!Long|number|string} subtrahend Subtrahend
 873 |      * @returns {!Long} Difference
 874 |      * @expose
 875 |      */
 876 |     LongPrototype.sub = LongPrototype.subtract;
 877 | 
 878 |     /**
 879 |      * Returns the product of this and the specified Long.
 880 |      * @param {!Long|number|string} multiplier Multiplier
 881 |      * @returns {!Long} Product
 882 |      * @expose
 883 |      */
 884 |     LongPrototype.multiply = function multiply(multiplier) {
 885 |         if (this.isZero())
 886 |             return ZERO;
 887 |         if (!isLong(multiplier))
 888 |             multiplier = fromValue(multiplier);
 889 |         if (multiplier.isZero())
 890 |             return ZERO;
 891 |         if (this.eq(MIN_VALUE))
 892 |             return multiplier.isOdd() ? MIN_VALUE : ZERO;
 893 |         if (multiplier.eq(MIN_VALUE))
 894 |             return this.isOdd() ? MIN_VALUE : ZERO;
 895 | 
 896 |         if (this.isNegative()) {
 897 |             if (multiplier.isNegative())
 898 |                 return this.neg().mul(multiplier.neg());
 899 |             else
 900 |                 return this.neg().mul(multiplier).neg();
 901 |         } else if (multiplier.isNegative())
 902 |             return this.mul(multiplier.neg()).neg();
 903 | 
 904 |         // If both longs are small, use float multiplication
 905 |         if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
 906 |             return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
 907 | 
 908 |         // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
 909 |         // We can skip products that would overflow.
 910 | 
 911 |         var a48 = this.high >>> 16;
 912 |         var a32 = this.high & 0xFFFF;
 913 |         var a16 = this.low >>> 16;
 914 |         var a00 = this.low & 0xFFFF;
 915 | 
 916 |         var b48 = multiplier.high >>> 16;
 917 |         var b32 = multiplier.high & 0xFFFF;
 918 |         var b16 = multiplier.low >>> 16;
 919 |         var b00 = multiplier.low & 0xFFFF;
 920 | 
 921 |         var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
 922 |         c00 += a00 * b00;
 923 |         c16 += c00 >>> 16;
 924 |         c00 &= 0xFFFF;
 925 |         c16 += a16 * b00;
 926 |         c32 += c16 >>> 16;
 927 |         c16 &= 0xFFFF;
 928 |         c16 += a00 * b16;
 929 |         c32 += c16 >>> 16;
 930 |         c16 &= 0xFFFF;
 931 |         c32 += a32 * b00;
 932 |         c48 += c32 >>> 16;
 933 |         c32 &= 0xFFFF;
 934 |         c32 += a16 * b16;
 935 |         c48 += c32 >>> 16;
 936 |         c32 &= 0xFFFF;
 937 |         c32 += a00 * b32;
 938 |         c48 += c32 >>> 16;
 939 |         c32 &= 0xFFFF;
 940 |         c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
 941 |         c48 &= 0xFFFF;
 942 |         return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
 943 |     };
 944 | 
 945 |     /**
 946 |      * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
 947 |      * @function
 948 |      * @param {!Long|number|string} multiplier Multiplier
 949 |      * @returns {!Long} Product
 950 |      * @expose
 951 |      */
 952 |     LongPrototype.mul = LongPrototype.multiply;
 953 | 
 954 |     /**
 955 |      * Returns this Long divided by the specified. The result is signed if this Long is signed or
 956 |      *  unsigned if this Long is unsigned.
 957 |      * @param {!Long|number|string} divisor Divisor
 958 |      * @returns {!Long} Quotient
 959 |      * @expose
 960 |      */
 961 |     LongPrototype.divide = function divide(divisor) {
 962 |         if (!isLong(divisor))
 963 |             divisor = fromValue(divisor);
 964 |         if (divisor.isZero())
 965 |             throw Error('division by zero');
 966 |         if (this.isZero())
 967 |             return this.unsigned ? UZERO : ZERO;
 968 |         var approx, rem, res;
 969 |         if (!this.unsigned) {
 970 |             // This section is only relevant for signed longs and is derived from the
 971 |             // closure library as a whole.
 972 |             if (this.eq(MIN_VALUE)) {
 973 |                 if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
 974 |                     return MIN_VALUE;  // recall that -MIN_VALUE == MIN_VALUE
 975 |                 else if (divisor.eq(MIN_VALUE))
 976 |                     return ONE;
 977 |                 else {
 978 |                     // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
 979 |                     var halfThis = this.shr(1);
 980 |                     approx = halfThis.div(divisor).shl(1);
 981 |                     if (approx.eq(ZERO)) {
 982 |                         return divisor.isNegative() ? ONE : NEG_ONE;
 983 |                     } else {
 984 |                         rem = this.sub(divisor.mul(approx));
 985 |                         res = approx.add(rem.div(divisor));
 986 |                         return res;
 987 |                     }
 988 |                 }
 989 |             } else if (divisor.eq(MIN_VALUE))
 990 |                 return this.unsigned ? UZERO : ZERO;
 991 |             if (this.isNegative()) {
 992 |                 if (divisor.isNegative())
 993 |                     return this.neg().div(divisor.neg());
 994 |                 return this.neg().div(divisor).neg();
 995 |             } else if (divisor.isNegative())
 996 |                 return this.div(divisor.neg()).neg();
 997 |             res = ZERO;
 998 |         } else {
 999 |             // The algorithm below has not been made for unsigned longs. It's therefore
1000 |             // required to take special care of the MSB prior to running it.
1001 |             if (!divisor.unsigned)
1002 |                 divisor = divisor.toUnsigned();
1003 |             if (divisor.gt(this))
1004 |                 return UZERO;
1005 |             if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
1006 |                 return UONE;
1007 |             res = UZERO;
1008 |         }
1009 | 
1010 |         // Repeat the following until the remainder is less than other:  find a
1011 |         // floating-point that approximates remainder / other *from below*, add this
1012 |         // into the result, and subtract it from the remainder.  It is critical that
1013 |         // the approximate value is less than or equal to the real value so that the
1014 |         // remainder never becomes negative.
1015 |         rem = this;
1016 |         while (rem.gte(divisor)) {
1017 |             // Approximate the result of division. This may be a little greater or
1018 |             // smaller than the actual value.
1019 |             approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
1020 | 
1021 |             // We will tweak the approximate result by changing it in the 48-th digit or
1022 |             // the smallest non-fractional digit, whichever is larger.
1023 |             var log2 = Math.ceil(Math.log(approx) / Math.LN2),
1024 |                 delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
1025 | 
1026 |             // Decrease the approximation until it is smaller than the remainder.  Note
1027 |             // that if it is too large, the product overflows and is negative.
1028 |                 approxRes = fromNumber(approx),
1029 |                 approxRem = approxRes.mul(divisor);
1030 |             while (approxRem.isNegative() || approxRem.gt(rem)) {
1031 |                 approx -= delta;
1032 |                 approxRes = fromNumber(approx, this.unsigned);
1033 |                 approxRem = approxRes.mul(divisor);
1034 |             }
1035 | 
1036 |             // We know the answer can't be zero... and actually, zero would cause
1037 |             // infinite recursion since we would make no progress.
1038 |             if (approxRes.isZero())
1039 |                 approxRes = ONE;
1040 | 
1041 |             res = res.add(approxRes);
1042 |             rem = rem.sub(approxRem);
1043 |         }
1044 |         return res;
1045 |     };
1046 | 
1047 |     /**
1048 |      * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
1049 |      * @function
1050 |      * @param {!Long|number|string} divisor Divisor
1051 |      * @returns {!Long} Quotient
1052 |      * @expose
1053 |      */
1054 |     LongPrototype.div = LongPrototype.divide;
1055 | 
1056 |     /**
1057 |      * Returns this Long modulo the specified.
1058 |      * @param {!Long|number|string} divisor Divisor
1059 |      * @returns {!Long} Remainder
1060 |      * @expose
1061 |      */
1062 |     LongPrototype.modulo = function modulo(divisor) {
1063 |         if (!isLong(divisor))
1064 |             divisor = fromValue(divisor);
1065 |         return this.sub(this.div(divisor).mul(divisor));
1066 |     };
1067 | 
1068 |     /**
1069 |      * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
1070 |      * @function
1071 |      * @param {!Long|number|string} divisor Divisor
1072 |      * @returns {!Long} Remainder
1073 |      * @expose
1074 |      */
1075 |     LongPrototype.mod = LongPrototype.modulo;
1076 | 
1077 |     /**
1078 |      * Returns the bitwise NOT of this Long.
1079 |      * @returns {!Long}
1080 |      * @expose
1081 |      */
1082 |     LongPrototype.not = function not() {
1083 |         return fromBits(~this.low, ~this.high, this.unsigned);
1084 |     };
1085 | 
1086 |     /**
1087 |      * Returns the bitwise AND of this Long and the specified.
1088 |      * @param {!Long|number|string} other Other Long
1089 |      * @returns {!Long}
1090 |      * @expose
1091 |      */
1092 |     LongPrototype.and = function and(other) {
1093 |         if (!isLong(other))
1094 |             other = fromValue(other);
1095 |         return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
1096 |     };
1097 | 
1098 |     /**
1099 |      * Returns the bitwise OR of this Long and the specified.
1100 |      * @param {!Long|number|string} other Other Long
1101 |      * @returns {!Long}
1102 |      * @expose
1103 |      */
1104 |     LongPrototype.or = function or(other) {
1105 |         if (!isLong(other))
1106 |             other = fromValue(other);
1107 |         return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
1108 |     };
1109 | 
1110 |     /**
1111 |      * Returns the bitwise XOR of this Long and the given one.
1112 |      * @param {!Long|number|string} other Other Long
1113 |      * @returns {!Long}
1114 |      * @expose
1115 |      */
1116 |     LongPrototype.xor = function xor(other) {
1117 |         if (!isLong(other))
1118 |             other = fromValue(other);
1119 |         return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
1120 |     };
1121 | 
1122 |     /**
1123 |      * Returns this Long with bits shifted to the left by the given amount.
1124 |      * @param {number|!Long} numBits Number of bits
1125 |      * @returns {!Long} Shifted Long
1126 |      * @expose
1127 |      */
1128 |     LongPrototype.shiftLeft = function shiftLeft(numBits) {
1129 |         if (isLong(numBits))
1130 |             numBits = numBits.toInt();
1131 |         if ((numBits &= 63) === 0)
1132 |             return this;
1133 |         else if (numBits < 32)
1134 |             return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
1135 |         else
1136 |             return fromBits(0, this.low << (numBits - 32), this.unsigned);
1137 |     };
1138 | 
1139 |     /**
1140 |      * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
1141 |      * @function
1142 |      * @param {number|!Long} numBits Number of bits
1143 |      * @returns {!Long} Shifted Long
1144 |      * @expose
1145 |      */
1146 |     LongPrototype.shl = LongPrototype.shiftLeft;
1147 | 
1148 |     /**
1149 |      * Returns this Long with bits arithmetically shifted to the right by the given amount.
1150 |      * @param {number|!Long} numBits Number of bits
1151 |      * @returns {!Long} Shifted Long
1152 |      * @expose
1153 |      */
1154 |     LongPrototype.shiftRight = function shiftRight(numBits) {
1155 |         if (isLong(numBits))
1156 |             numBits = numBits.toInt();
1157 |         if ((numBits &= 63) === 0)
1158 |             return this;
1159 |         else if (numBits < 32)
1160 |             return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
1161 |         else
1162 |             return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
1163 |     };
1164 | 
1165 |     /**
1166 |      * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
1167 |      * @function
1168 |      * @param {number|!Long} numBits Number of bits
1169 |      * @returns {!Long} Shifted Long
1170 |      * @expose
1171 |      */
1172 |     LongPrototype.shr = LongPrototype.shiftRight;
1173 | 
1174 |     /**
1175 |      * Returns this Long with bits logically shifted to the right by the given amount.
1176 |      * @param {number|!Long} numBits Number of bits
1177 |      * @returns {!Long} Shifted Long
1178 |      * @expose
1179 |      */
1180 |     LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
1181 |         if (isLong(numBits))
1182 |             numBits = numBits.toInt();
1183 |         numBits &= 63;
1184 |         if (numBits === 0)
1185 |             return this;
1186 |         else {
1187 |             var high = this.high;
1188 |             if (numBits < 32) {
1189 |                 var low = this.low;
1190 |                 return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
1191 |             } else if (numBits === 32)
1192 |                 return fromBits(high, 0, this.unsigned);
1193 |             else
1194 |                 return fromBits(high >>> (numBits - 32), 0, this.unsigned);
1195 |         }
1196 |     };
1197 | 
1198 |     /**
1199 |      * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
1200 |      * @function
1201 |      * @param {number|!Long} numBits Number of bits
1202 |      * @returns {!Long} Shifted Long
1203 |      * @expose
1204 |      */
1205 |     LongPrototype.shru = LongPrototype.shiftRightUnsigned;
1206 | 
1207 |     /**
1208 |      * Converts this Long to signed.
1209 |      * @returns {!Long} Signed long
1210 |      * @expose
1211 |      */
1212 |     LongPrototype.toSigned = function toSigned() {
1213 |         if (!this.unsigned)
1214 |             return this;
1215 |         return fromBits(this.low, this.high, false);
1216 |     };
1217 | 
1218 |     /**
1219 |      * Converts this Long to unsigned.
1220 |      * @returns {!Long} Unsigned long
1221 |      * @expose
1222 |      */
1223 |     LongPrototype.toUnsigned = function toUnsigned() {
1224 |         if (this.unsigned)
1225 |             return this;
1226 |         return fromBits(this.low, this.high, true);
1227 |     };
1228 | 
1229 |     return Long;
1230 | });
1231 | 


--------------------------------------------------------------------------------
/public/bytebuffer.js:
--------------------------------------------------------------------------------
   1 | /*
   2 |  Copyright 2013-2014 Daniel Wirtz 
   3 | 
   4 |  Licensed under the Apache License, Version 2.0 (the "License");
   5 |  you may not use this file except in compliance with the License.
   6 |  You may obtain a copy of the License at
   7 | 
   8 |  http://www.apache.org/licenses/LICENSE-2.0
   9 | 
  10 |  Unless required by applicable law or agreed to in writing, software
  11 |  distributed under the License is distributed on an "AS IS" BASIS,
  12 |  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 |  See the License for the specific language governing permissions and
  14 |  limitations under the License.
  15 |  */
  16 | 
  17 | /**
  18 |  * @license bytebuffer.js (c) 2015 Daniel Wirtz 
  19 |  * Backing buffer: ArrayBuffer, Accessor: Uint8Array
  20 |  * Released under the Apache License, Version 2.0
  21 |  * see: https://github.com/dcodeIO/bytebuffer.js for details
  22 |  */
  23 | (function(global, factory) {
  24 | 
  25 |     /* AMD */ if (typeof define === 'function' && define["amd"])
  26 |         define(["long"], factory);
  27 |     /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
  28 |         module['exports'] = (function() {
  29 |             var Long; try { Long = require("long"); } catch (e) {}
  30 |             return factory(Long);
  31 |         })();
  32 |     /* Global */ else
  33 |         (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]);
  34 | 
  35 | })(this, function(Long) {
  36 |     "use strict";
  37 | 
  38 |     /**
  39 |      * Constructs a new ByteBuffer.
  40 |      * @class The swiss army knife for binary data in JavaScript.
  41 |      * @exports ByteBuffer
  42 |      * @constructor
  43 |      * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
  44 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  45 |      *  {@link ByteBuffer.DEFAULT_ENDIAN}.
  46 |      * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  47 |      *  {@link ByteBuffer.DEFAULT_NOASSERT}.
  48 |      * @expose
  49 |      */
  50 |     var ByteBuffer = function(capacity, littleEndian, noAssert) {
  51 |         if (typeof capacity === 'undefined')
  52 |             capacity = ByteBuffer.DEFAULT_CAPACITY;
  53 |         if (typeof littleEndian === 'undefined')
  54 |             littleEndian = ByteBuffer.DEFAULT_ENDIAN;
  55 |         if (typeof noAssert === 'undefined')
  56 |             noAssert = ByteBuffer.DEFAULT_NOASSERT;
  57 |         if (!noAssert) {
  58 |             capacity = capacity | 0;
  59 |             if (capacity < 0)
  60 |                 throw RangeError("Illegal capacity");
  61 |             littleEndian = !!littleEndian;
  62 |             noAssert = !!noAssert;
  63 |         }
  64 | 
  65 |         /**
  66 |          * Backing ArrayBuffer.
  67 |          * @type {!ArrayBuffer}
  68 |          * @expose
  69 |          */
  70 |         this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
  71 | 
  72 |         /**
  73 |          * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
  74 |          * @type {?Uint8Array}
  75 |          * @expose
  76 |          */
  77 |         this.view = capacity === 0 ? null : new Uint8Array(this.buffer);
  78 | 
  79 |         /**
  80 |          * Absolute read/write offset.
  81 |          * @type {number}
  82 |          * @expose
  83 |          * @see ByteBuffer#flip
  84 |          * @see ByteBuffer#clear
  85 |          */
  86 |         this.offset = 0;
  87 | 
  88 |         /**
  89 |          * Marked offset.
  90 |          * @type {number}
  91 |          * @expose
  92 |          * @see ByteBuffer#mark
  93 |          * @see ByteBuffer#reset
  94 |          */
  95 |         this.markedOffset = -1;
  96 | 
  97 |         /**
  98 |          * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
  99 |          * @type {number}
 100 |          * @expose
 101 |          * @see ByteBuffer#flip
 102 |          * @see ByteBuffer#clear
 103 |          */
 104 |         this.limit = capacity;
 105 | 
 106 |         /**
 107 |          * Whether to use little endian byte order, defaults to `false` for big endian.
 108 |          * @type {boolean}
 109 |          * @expose
 110 |          */
 111 |         this.littleEndian = littleEndian;
 112 | 
 113 |         /**
 114 |          * Whether to skip assertions of offsets and values, defaults to `false`.
 115 |          * @type {boolean}
 116 |          * @expose
 117 |          */
 118 |         this.noAssert = noAssert;
 119 |     };
 120 | 
 121 |     /**
 122 |      * ByteBuffer version.
 123 |      * @type {string}
 124 |      * @const
 125 |      * @expose
 126 |      */
 127 |     ByteBuffer.VERSION = "5.0.1";
 128 | 
 129 |     /**
 130 |      * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
 131 |      * @type {boolean}
 132 |      * @const
 133 |      * @expose
 134 |      */
 135 |     ByteBuffer.LITTLE_ENDIAN = true;
 136 | 
 137 |     /**
 138 |      * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
 139 |      * @type {boolean}
 140 |      * @const
 141 |      * @expose
 142 |      */
 143 |     ByteBuffer.BIG_ENDIAN = false;
 144 | 
 145 |     /**
 146 |      * Default initial capacity of `16`.
 147 |      * @type {number}
 148 |      * @expose
 149 |      */
 150 |     ByteBuffer.DEFAULT_CAPACITY = 16;
 151 | 
 152 |     /**
 153 |      * Default endianess of `false` for big endian.
 154 |      * @type {boolean}
 155 |      * @expose
 156 |      */
 157 |     ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
 158 | 
 159 |     /**
 160 |      * Default no assertions flag of `false`.
 161 |      * @type {boolean}
 162 |      * @expose
 163 |      */
 164 |     ByteBuffer.DEFAULT_NOASSERT = false;
 165 | 
 166 |     /**
 167 |      * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
 168 |      *  and int64 support is not available.
 169 |      * @type {?Long}
 170 |      * @const
 171 |      * @see https://github.com/dcodeIO/long.js
 172 |      * @expose
 173 |      */
 174 |     ByteBuffer.Long = Long || null;
 175 | 
 176 |     /**
 177 |      * @alias ByteBuffer.prototype
 178 |      * @inner
 179 |      */
 180 |     var ByteBufferPrototype = ByteBuffer.prototype;
 181 | 
 182 |     /**
 183 |      * An indicator used to reliably determine if an object is a ByteBuffer or not.
 184 |      * @type {boolean}
 185 |      * @const
 186 |      * @expose
 187 |      * @private
 188 |      */
 189 |     ByteBufferPrototype.__isByteBuffer__;
 190 | 
 191 |     Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", {
 192 |         value: true,
 193 |         enumerable: false,
 194 |         configurable: false
 195 |     });
 196 | 
 197 |     // helpers
 198 | 
 199 |     /**
 200 |      * @type {!ArrayBuffer}
 201 |      * @inner
 202 |      */
 203 |     var EMPTY_BUFFER = new ArrayBuffer(0);
 204 | 
 205 |     /**
 206 |      * String.fromCharCode reference for compile-time renaming.
 207 |      * @type {function(...number):string}
 208 |      * @inner
 209 |      */
 210 |     var stringFromCharCode = String.fromCharCode;
 211 | 
 212 |     /**
 213 |      * Creates a source function for a string.
 214 |      * @param {string} s String to read from
 215 |      * @returns {function():number|null} Source function returning the next char code respectively `null` if there are
 216 |      *  no more characters left.
 217 |      * @throws {TypeError} If the argument is invalid
 218 |      * @inner
 219 |      */
 220 |     function stringSource(s) {
 221 |         var i=0; return function() {
 222 |             return i < s.length ? s.charCodeAt(i++) : null;
 223 |         };
 224 |     }
 225 | 
 226 |     /**
 227 |      * Creates a destination function for a string.
 228 |      * @returns {function(number=):undefined|string} Destination function successively called with the next char code.
 229 |      *  Returns the final string when called without arguments.
 230 |      * @inner
 231 |      */
 232 |     function stringDestination() {
 233 |         var cs = [], ps = []; return function() {
 234 |             if (arguments.length === 0)
 235 |                 return ps.join('')+stringFromCharCode.apply(String, cs);
 236 |             if (cs.length + arguments.length > 1024)
 237 |                 ps.push(stringFromCharCode.apply(String, cs)),
 238 |                     cs.length = 0;
 239 |             Array.prototype.push.apply(cs, arguments);
 240 |         };
 241 |     }
 242 | 
 243 |     /**
 244 |      * Gets the accessor type.
 245 |      * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
 246 |      * @expose
 247 |      */
 248 |     ByteBuffer.accessor = function() {
 249 |         return Uint8Array;
 250 |     };
 251 |     /**
 252 |      * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
 253 |      * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
 254 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
 255 |      *  {@link ByteBuffer.DEFAULT_ENDIAN}.
 256 |      * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
 257 |      *  {@link ByteBuffer.DEFAULT_NOASSERT}.
 258 |      * @returns {!ByteBuffer}
 259 |      * @expose
 260 |      */
 261 |     ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
 262 |         return new ByteBuffer(capacity, littleEndian, noAssert);
 263 |     };
 264 | 
 265 |     /**
 266 |      * Concatenates multiple ByteBuffers into one.
 267 |      * @param {!Array.} buffers Buffers to concatenate
 268 |      * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
 269 |      *  defaults to "utf8")
 270 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
 271 |      *  to {@link ByteBuffer.DEFAULT_ENDIAN}.
 272 |      * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
 273 |      *  {@link ByteBuffer.DEFAULT_NOASSERT}.
 274 |      * @returns {!ByteBuffer} Concatenated ByteBuffer
 275 |      * @expose
 276 |      */
 277 |     ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
 278 |         if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
 279 |             noAssert = littleEndian;
 280 |             littleEndian = encoding;
 281 |             encoding = undefined;
 282 |         }
 283 |         var capacity = 0;
 284 |         for (var i=0, k=buffers.length, length; i 0) capacity += length;
 289 |         }
 290 |         if (capacity === 0)
 291 |             return new ByteBuffer(0, littleEndian, noAssert);
 292 |         var bb = new ByteBuffer(capacity, littleEndian, noAssert),
 293 |             bi;
 294 |         i=0; while (i} buffer Anything that can be wrapped
 327 |      * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
 328 |      *  "utf8")
 329 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
 330 |      *  {@link ByteBuffer.DEFAULT_ENDIAN}.
 331 |      * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
 332 |      *  {@link ByteBuffer.DEFAULT_NOASSERT}.
 333 |      * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
 334 |      * @expose
 335 |      */
 336 |     ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
 337 |         if (typeof encoding !== 'string') {
 338 |             noAssert = littleEndian;
 339 |             littleEndian = encoding;
 340 |             encoding = undefined;
 341 |         }
 342 |         if (typeof buffer === 'string') {
 343 |             if (typeof encoding === 'undefined')
 344 |                 encoding = "utf8";
 345 |             switch (encoding) {
 346 |                 case "base64":
 347 |                     return ByteBuffer.fromBase64(buffer, littleEndian);
 348 |                 case "hex":
 349 |                     return ByteBuffer.fromHex(buffer, littleEndian);
 350 |                 case "binary":
 351 |                     return ByteBuffer.fromBinary(buffer, littleEndian);
 352 |                 case "utf8":
 353 |                     return ByteBuffer.fromUTF8(buffer, littleEndian);
 354 |                 case "debug":
 355 |                     return ByteBuffer.fromDebug(buffer, littleEndian);
 356 |                 default:
 357 |                     throw Error("Unsupported encoding: "+encoding);
 358 |             }
 359 |         }
 360 |         if (buffer === null || typeof buffer !== 'object')
 361 |             throw TypeError("Illegal buffer");
 362 |         var bb;
 363 |         if (ByteBuffer.isByteBuffer(buffer)) {
 364 |             bb = ByteBufferPrototype.clone.call(buffer);
 365 |             bb.markedOffset = -1;
 366 |             return bb;
 367 |         }
 368 |         if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
 369 |             bb = new ByteBuffer(0, littleEndian, noAssert);
 370 |             if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
 371 |                 bb.buffer = buffer.buffer;
 372 |                 bb.offset = buffer.byteOffset;
 373 |                 bb.limit = buffer.byteOffset + buffer.byteLength;
 374 |                 bb.view = new Uint8Array(buffer.buffer);
 375 |             }
 376 |         } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
 377 |             bb = new ByteBuffer(0, littleEndian, noAssert);
 378 |             if (buffer.byteLength > 0) {
 379 |                 bb.buffer = buffer;
 380 |                 bb.offset = 0;
 381 |                 bb.limit = buffer.byteLength;
 382 |                 bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null;
 383 |             }
 384 |         } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
 385 |             bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
 386 |             bb.limit = buffer.length;
 387 |             for (var i=0; i} value Array of booleans to write
 397 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
 398 |      * @returns {!ByteBuffer}
 399 |      * @expose
 400 |      */
 401 |     ByteBufferPrototype.writeBitSet = function(value, offset) {
 402 |       var relative = typeof offset === 'undefined';
 403 |       if (relative) offset = this.offset;
 404 |       if (!this.noAssert) {
 405 |         if (!(value instanceof Array))
 406 |           throw TypeError("Illegal BitSet: Not an array");
 407 |         if (typeof offset !== 'number' || offset % 1 !== 0)
 408 |             throw TypeError("Illegal offset: "+offset+" (not an integer)");
 409 |         offset >>>= 0;
 410 |         if (offset < 0 || offset + 0 > this.buffer.byteLength)
 411 |             throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
 412 |       }
 413 | 
 414 |       var start = offset,
 415 |           bits = value.length,
 416 |           bytes = (bits >> 3),
 417 |           bit = 0,
 418 |           k;
 419 | 
 420 |       offset += this.writeVarint32(bits,offset);
 421 | 
 422 |       while(bytes--) {
 423 |         k = (!!value[bit++] & 1) |
 424 |             ((!!value[bit++] & 1) << 1) |
 425 |             ((!!value[bit++] & 1) << 2) |
 426 |             ((!!value[bit++] & 1) << 3) |
 427 |             ((!!value[bit++] & 1) << 4) |
 428 |             ((!!value[bit++] & 1) << 5) |
 429 |             ((!!value[bit++] & 1) << 6) |
 430 |             ((!!value[bit++] & 1) << 7);
 431 |         this.writeByte(k,offset++);
 432 |       }
 433 | 
 434 |       if(bit < bits) {
 435 |         var m = 0; k = 0;
 436 |         while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++));
 437 |         this.writeByte(k,offset++);
 438 |       }
 439 | 
 440 |       if (relative) {
 441 |         this.offset = offset;
 442 |         return this;
 443 |       }
 444 |       return offset - start;
 445 |     }
 446 | 
 447 |     /**
 448 |      * Reads a BitSet as an array of booleans.
 449 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
 450 |      * @returns {Array
 451 |      * @expose
 452 |      */
 453 |     ByteBufferPrototype.readBitSet = function(offset) {
 454 |       var relative = typeof offset === 'undefined';
 455 |       if (relative) offset = this.offset;
 456 | 
 457 |       var ret = this.readVarint32(offset),
 458 |           bits = ret.value,
 459 |           bytes = (bits >> 3),
 460 |           bit = 0,
 461 |           value = [],
 462 |           k;
 463 | 
 464 |       offset += ret.length;
 465 | 
 466 |       while(bytes--) {
 467 |         k = this.readByte(offset++);
 468 |         value[bit++] = !!(k & 0x01);
 469 |         value[bit++] = !!(k & 0x02);
 470 |         value[bit++] = !!(k & 0x04);
 471 |         value[bit++] = !!(k & 0x08);
 472 |         value[bit++] = !!(k & 0x10);
 473 |         value[bit++] = !!(k & 0x20);
 474 |         value[bit++] = !!(k & 0x40);
 475 |         value[bit++] = !!(k & 0x80);
 476 |       }
 477 | 
 478 |       if(bit < bits) {
 479 |         var m = 0;
 480 |         k = this.readByte(offset++);
 481 |         while(bit < bits) value[bit++] = !!((k >> (m++)) & 1);
 482 |       }
 483 | 
 484 |       if (relative) {
 485 |         this.offset = offset;
 486 |       }
 487 |       return value;
 488 |     }
 489 |     /**
 490 |      * Reads the specified number of bytes.
 491 |      * @param {number} length Number of bytes to read
 492 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
 493 |      * @returns {!ByteBuffer}
 494 |      * @expose
 495 |      */
 496 |     ByteBufferPrototype.readBytes = function(length, offset) {
 497 |         var relative = typeof offset === 'undefined';
 498 |         if (relative) offset = this.offset;
 499 |         if (!this.noAssert) {
 500 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 501 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 502 |             offset >>>= 0;
 503 |             if (offset < 0 || offset + length > this.buffer.byteLength)
 504 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
 505 |         }
 506 |         var slice = this.slice(offset, offset + length);
 507 |         if (relative) this.offset += length;
 508 |         return slice;
 509 |     };
 510 | 
 511 |     /**
 512 |      * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
 513 |      * @function
 514 |      * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
 515 |      *  will be modified according to the performed read operation.
 516 |      * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
 517 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
 518 |      *  written if omitted.
 519 |      * @returns {!ByteBuffer} this
 520 |      * @expose
 521 |      */
 522 |     ByteBufferPrototype.writeBytes = ByteBufferPrototype.append;
 523 | 
 524 |     // types/ints/int8
 525 | 
 526 |     /**
 527 |      * Writes an 8bit signed integer.
 528 |      * @param {number} value Value to write
 529 |      * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
 530 |      * @returns {!ByteBuffer} this
 531 |      * @expose
 532 |      */
 533 |     ByteBufferPrototype.writeInt8 = function(value, offset) {
 534 |         var relative = typeof offset === 'undefined';
 535 |         if (relative) offset = this.offset;
 536 |         if (!this.noAssert) {
 537 |             if (typeof value !== 'number' || value % 1 !== 0)
 538 |                 throw TypeError("Illegal value: "+value+" (not an integer)");
 539 |             value |= 0;
 540 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 541 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 542 |             offset >>>= 0;
 543 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
 544 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
 545 |         }
 546 |         offset += 1;
 547 |         var capacity0 = this.buffer.byteLength;
 548 |         if (offset > capacity0)
 549 |             this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
 550 |         offset -= 1;
 551 |         this.view[offset] = value;
 552 |         if (relative) this.offset += 1;
 553 |         return this;
 554 |     };
 555 | 
 556 |     /**
 557 |      * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
 558 |      * @function
 559 |      * @param {number} value Value to write
 560 |      * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
 561 |      * @returns {!ByteBuffer} this
 562 |      * @expose
 563 |      */
 564 |     ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
 565 | 
 566 |     /**
 567 |      * Reads an 8bit signed integer.
 568 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
 569 |      * @returns {number} Value read
 570 |      * @expose
 571 |      */
 572 |     ByteBufferPrototype.readInt8 = function(offset) {
 573 |         var relative = typeof offset === 'undefined';
 574 |         if (relative) offset = this.offset;
 575 |         if (!this.noAssert) {
 576 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 577 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 578 |             offset >>>= 0;
 579 |             if (offset < 0 || offset + 1 > this.buffer.byteLength)
 580 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
 581 |         }
 582 |         var value = this.view[offset];
 583 |         if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed
 584 |         if (relative) this.offset += 1;
 585 |         return value;
 586 |     };
 587 | 
 588 |     /**
 589 |      * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
 590 |      * @function
 591 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
 592 |      * @returns {number} Value read
 593 |      * @expose
 594 |      */
 595 |     ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
 596 | 
 597 |     /**
 598 |      * Writes an 8bit unsigned integer.
 599 |      * @param {number} value Value to write
 600 |      * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
 601 |      * @returns {!ByteBuffer} this
 602 |      * @expose
 603 |      */
 604 |     ByteBufferPrototype.writeUint8 = function(value, offset) {
 605 |         var relative = typeof offset === 'undefined';
 606 |         if (relative) offset = this.offset;
 607 |         if (!this.noAssert) {
 608 |             if (typeof value !== 'number' || value % 1 !== 0)
 609 |                 throw TypeError("Illegal value: "+value+" (not an integer)");
 610 |             value >>>= 0;
 611 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 612 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 613 |             offset >>>= 0;
 614 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
 615 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
 616 |         }
 617 |         offset += 1;
 618 |         var capacity1 = this.buffer.byteLength;
 619 |         if (offset > capacity1)
 620 |             this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
 621 |         offset -= 1;
 622 |         this.view[offset] = value;
 623 |         if (relative) this.offset += 1;
 624 |         return this;
 625 |     };
 626 | 
 627 |     /**
 628 |      * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
 629 |      * @function
 630 |      * @param {number} value Value to write
 631 |      * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
 632 |      * @returns {!ByteBuffer} this
 633 |      * @expose
 634 |      */
 635 |     ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8;
 636 | 
 637 |     /**
 638 |      * Reads an 8bit unsigned integer.
 639 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
 640 |      * @returns {number} Value read
 641 |      * @expose
 642 |      */
 643 |     ByteBufferPrototype.readUint8 = function(offset) {
 644 |         var relative = typeof offset === 'undefined';
 645 |         if (relative) offset = this.offset;
 646 |         if (!this.noAssert) {
 647 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 648 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 649 |             offset >>>= 0;
 650 |             if (offset < 0 || offset + 1 > this.buffer.byteLength)
 651 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
 652 |         }
 653 |         var value = this.view[offset];
 654 |         if (relative) this.offset += 1;
 655 |         return value;
 656 |     };
 657 | 
 658 |     /**
 659 |      * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
 660 |      * @function
 661 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
 662 |      * @returns {number} Value read
 663 |      * @expose
 664 |      */
 665 |     ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8;
 666 | 
 667 |     // types/ints/int16
 668 | 
 669 |     /**
 670 |      * Writes a 16bit signed integer.
 671 |      * @param {number} value Value to write
 672 |      * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
 673 |      * @throws {TypeError} If `offset` or `value` is not a valid number
 674 |      * @throws {RangeError} If `offset` is out of bounds
 675 |      * @expose
 676 |      */
 677 |     ByteBufferPrototype.writeInt16 = function(value, offset) {
 678 |         var relative = typeof offset === 'undefined';
 679 |         if (relative) offset = this.offset;
 680 |         if (!this.noAssert) {
 681 |             if (typeof value !== 'number' || value % 1 !== 0)
 682 |                 throw TypeError("Illegal value: "+value+" (not an integer)");
 683 |             value |= 0;
 684 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 685 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 686 |             offset >>>= 0;
 687 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
 688 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
 689 |         }
 690 |         offset += 2;
 691 |         var capacity2 = this.buffer.byteLength;
 692 |         if (offset > capacity2)
 693 |             this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
 694 |         offset -= 2;
 695 |         if (this.littleEndian) {
 696 |             this.view[offset+1] = (value & 0xFF00) >>> 8;
 697 |             this.view[offset  ] =  value & 0x00FF;
 698 |         } else {
 699 |             this.view[offset]   = (value & 0xFF00) >>> 8;
 700 |             this.view[offset+1] =  value & 0x00FF;
 701 |         }
 702 |         if (relative) this.offset += 2;
 703 |         return this;
 704 |     };
 705 | 
 706 |     /**
 707 |      * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
 708 |      * @function
 709 |      * @param {number} value Value to write
 710 |      * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
 711 |      * @throws {TypeError} If `offset` or `value` is not a valid number
 712 |      * @throws {RangeError} If `offset` is out of bounds
 713 |      * @expose
 714 |      */
 715 |     ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
 716 | 
 717 |     /**
 718 |      * Reads a 16bit signed integer.
 719 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
 720 |      * @returns {number} Value read
 721 |      * @throws {TypeError} If `offset` is not a valid number
 722 |      * @throws {RangeError} If `offset` is out of bounds
 723 |      * @expose
 724 |      */
 725 |     ByteBufferPrototype.readInt16 = function(offset) {
 726 |         var relative = typeof offset === 'undefined';
 727 |         if (relative) offset = this.offset;
 728 |         if (!this.noAssert) {
 729 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 730 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 731 |             offset >>>= 0;
 732 |             if (offset < 0 || offset + 2 > this.buffer.byteLength)
 733 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
 734 |         }
 735 |         var value = 0;
 736 |         if (this.littleEndian) {
 737 |             value  = this.view[offset  ];
 738 |             value |= this.view[offset+1] << 8;
 739 |         } else {
 740 |             value  = this.view[offset  ] << 8;
 741 |             value |= this.view[offset+1];
 742 |         }
 743 |         if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed
 744 |         if (relative) this.offset += 2;
 745 |         return value;
 746 |     };
 747 | 
 748 |     /**
 749 |      * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
 750 |      * @function
 751 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
 752 |      * @returns {number} Value read
 753 |      * @throws {TypeError} If `offset` is not a valid number
 754 |      * @throws {RangeError} If `offset` is out of bounds
 755 |      * @expose
 756 |      */
 757 |     ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
 758 | 
 759 |     /**
 760 |      * Writes a 16bit unsigned integer.
 761 |      * @param {number} value Value to write
 762 |      * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
 763 |      * @throws {TypeError} If `offset` or `value` is not a valid number
 764 |      * @throws {RangeError} If `offset` is out of bounds
 765 |      * @expose
 766 |      */
 767 |     ByteBufferPrototype.writeUint16 = function(value, offset) {
 768 |         var relative = typeof offset === 'undefined';
 769 |         if (relative) offset = this.offset;
 770 |         if (!this.noAssert) {
 771 |             if (typeof value !== 'number' || value % 1 !== 0)
 772 |                 throw TypeError("Illegal value: "+value+" (not an integer)");
 773 |             value >>>= 0;
 774 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 775 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 776 |             offset >>>= 0;
 777 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
 778 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
 779 |         }
 780 |         offset += 2;
 781 |         var capacity3 = this.buffer.byteLength;
 782 |         if (offset > capacity3)
 783 |             this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
 784 |         offset -= 2;
 785 |         if (this.littleEndian) {
 786 |             this.view[offset+1] = (value & 0xFF00) >>> 8;
 787 |             this.view[offset  ] =  value & 0x00FF;
 788 |         } else {
 789 |             this.view[offset]   = (value & 0xFF00) >>> 8;
 790 |             this.view[offset+1] =  value & 0x00FF;
 791 |         }
 792 |         if (relative) this.offset += 2;
 793 |         return this;
 794 |     };
 795 | 
 796 |     /**
 797 |      * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
 798 |      * @function
 799 |      * @param {number} value Value to write
 800 |      * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
 801 |      * @throws {TypeError} If `offset` or `value` is not a valid number
 802 |      * @throws {RangeError} If `offset` is out of bounds
 803 |      * @expose
 804 |      */
 805 |     ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16;
 806 | 
 807 |     /**
 808 |      * Reads a 16bit unsigned integer.
 809 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
 810 |      * @returns {number} Value read
 811 |      * @throws {TypeError} If `offset` is not a valid number
 812 |      * @throws {RangeError} If `offset` is out of bounds
 813 |      * @expose
 814 |      */
 815 |     ByteBufferPrototype.readUint16 = function(offset) {
 816 |         var relative = typeof offset === 'undefined';
 817 |         if (relative) offset = this.offset;
 818 |         if (!this.noAssert) {
 819 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 820 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 821 |             offset >>>= 0;
 822 |             if (offset < 0 || offset + 2 > this.buffer.byteLength)
 823 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
 824 |         }
 825 |         var value = 0;
 826 |         if (this.littleEndian) {
 827 |             value  = this.view[offset  ];
 828 |             value |= this.view[offset+1] << 8;
 829 |         } else {
 830 |             value  = this.view[offset  ] << 8;
 831 |             value |= this.view[offset+1];
 832 |         }
 833 |         if (relative) this.offset += 2;
 834 |         return value;
 835 |     };
 836 | 
 837 |     /**
 838 |      * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
 839 |      * @function
 840 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
 841 |      * @returns {number} Value read
 842 |      * @throws {TypeError} If `offset` is not a valid number
 843 |      * @throws {RangeError} If `offset` is out of bounds
 844 |      * @expose
 845 |      */
 846 |     ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16;
 847 | 
 848 |     // types/ints/int32
 849 | 
 850 |     /**
 851 |      * Writes a 32bit signed integer.
 852 |      * @param {number} value Value to write
 853 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
 854 |      * @expose
 855 |      */
 856 |     ByteBufferPrototype.writeInt32 = function(value, offset) {
 857 |         var relative = typeof offset === 'undefined';
 858 |         if (relative) offset = this.offset;
 859 |         if (!this.noAssert) {
 860 |             if (typeof value !== 'number' || value % 1 !== 0)
 861 |                 throw TypeError("Illegal value: "+value+" (not an integer)");
 862 |             value |= 0;
 863 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 864 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 865 |             offset >>>= 0;
 866 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
 867 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
 868 |         }
 869 |         offset += 4;
 870 |         var capacity4 = this.buffer.byteLength;
 871 |         if (offset > capacity4)
 872 |             this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
 873 |         offset -= 4;
 874 |         if (this.littleEndian) {
 875 |             this.view[offset+3] = (value >>> 24) & 0xFF;
 876 |             this.view[offset+2] = (value >>> 16) & 0xFF;
 877 |             this.view[offset+1] = (value >>>  8) & 0xFF;
 878 |             this.view[offset  ] =  value         & 0xFF;
 879 |         } else {
 880 |             this.view[offset  ] = (value >>> 24) & 0xFF;
 881 |             this.view[offset+1] = (value >>> 16) & 0xFF;
 882 |             this.view[offset+2] = (value >>>  8) & 0xFF;
 883 |             this.view[offset+3] =  value         & 0xFF;
 884 |         }
 885 |         if (relative) this.offset += 4;
 886 |         return this;
 887 |     };
 888 | 
 889 |     /**
 890 |      * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
 891 |      * @param {number} value Value to write
 892 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
 893 |      * @expose
 894 |      */
 895 |     ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
 896 | 
 897 |     /**
 898 |      * Reads a 32bit signed integer.
 899 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
 900 |      * @returns {number} Value read
 901 |      * @expose
 902 |      */
 903 |     ByteBufferPrototype.readInt32 = function(offset) {
 904 |         var relative = typeof offset === 'undefined';
 905 |         if (relative) offset = this.offset;
 906 |         if (!this.noAssert) {
 907 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 908 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 909 |             offset >>>= 0;
 910 |             if (offset < 0 || offset + 4 > this.buffer.byteLength)
 911 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
 912 |         }
 913 |         var value = 0;
 914 |         if (this.littleEndian) {
 915 |             value  = this.view[offset+2] << 16;
 916 |             value |= this.view[offset+1] <<  8;
 917 |             value |= this.view[offset  ];
 918 |             value += this.view[offset+3] << 24 >>> 0;
 919 |         } else {
 920 |             value  = this.view[offset+1] << 16;
 921 |             value |= this.view[offset+2] <<  8;
 922 |             value |= this.view[offset+3];
 923 |             value += this.view[offset  ] << 24 >>> 0;
 924 |         }
 925 |         value |= 0; // Cast to signed
 926 |         if (relative) this.offset += 4;
 927 |         return value;
 928 |     };
 929 | 
 930 |     /**
 931 |      * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
 932 |      * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
 933 |      * @returns {number} Value read
 934 |      * @expose
 935 |      */
 936 |     ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
 937 | 
 938 |     /**
 939 |      * Writes a 32bit unsigned integer.
 940 |      * @param {number} value Value to write
 941 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
 942 |      * @expose
 943 |      */
 944 |     ByteBufferPrototype.writeUint32 = function(value, offset) {
 945 |         var relative = typeof offset === 'undefined';
 946 |         if (relative) offset = this.offset;
 947 |         if (!this.noAssert) {
 948 |             if (typeof value !== 'number' || value % 1 !== 0)
 949 |                 throw TypeError("Illegal value: "+value+" (not an integer)");
 950 |             value >>>= 0;
 951 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 952 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 953 |             offset >>>= 0;
 954 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
 955 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
 956 |         }
 957 |         offset += 4;
 958 |         var capacity5 = this.buffer.byteLength;
 959 |         if (offset > capacity5)
 960 |             this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
 961 |         offset -= 4;
 962 |         if (this.littleEndian) {
 963 |             this.view[offset+3] = (value >>> 24) & 0xFF;
 964 |             this.view[offset+2] = (value >>> 16) & 0xFF;
 965 |             this.view[offset+1] = (value >>>  8) & 0xFF;
 966 |             this.view[offset  ] =  value         & 0xFF;
 967 |         } else {
 968 |             this.view[offset  ] = (value >>> 24) & 0xFF;
 969 |             this.view[offset+1] = (value >>> 16) & 0xFF;
 970 |             this.view[offset+2] = (value >>>  8) & 0xFF;
 971 |             this.view[offset+3] =  value         & 0xFF;
 972 |         }
 973 |         if (relative) this.offset += 4;
 974 |         return this;
 975 |     };
 976 | 
 977 |     /**
 978 |      * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
 979 |      * @function
 980 |      * @param {number} value Value to write
 981 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
 982 |      * @expose
 983 |      */
 984 |     ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32;
 985 | 
 986 |     /**
 987 |      * Reads a 32bit unsigned integer.
 988 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
 989 |      * @returns {number} Value read
 990 |      * @expose
 991 |      */
 992 |     ByteBufferPrototype.readUint32 = function(offset) {
 993 |         var relative = typeof offset === 'undefined';
 994 |         if (relative) offset = this.offset;
 995 |         if (!this.noAssert) {
 996 |             if (typeof offset !== 'number' || offset % 1 !== 0)
 997 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
 998 |             offset >>>= 0;
 999 |             if (offset < 0 || offset + 4 > this.buffer.byteLength)
1000 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
1001 |         }
1002 |         var value = 0;
1003 |         if (this.littleEndian) {
1004 |             value  = this.view[offset+2] << 16;
1005 |             value |= this.view[offset+1] <<  8;
1006 |             value |= this.view[offset  ];
1007 |             value += this.view[offset+3] << 24 >>> 0;
1008 |         } else {
1009 |             value  = this.view[offset+1] << 16;
1010 |             value |= this.view[offset+2] <<  8;
1011 |             value |= this.view[offset+3];
1012 |             value += this.view[offset  ] << 24 >>> 0;
1013 |         }
1014 |         if (relative) this.offset += 4;
1015 |         return value;
1016 |     };
1017 | 
1018 |     /**
1019 |      * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
1020 |      * @function
1021 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1022 |      * @returns {number} Value read
1023 |      * @expose
1024 |      */
1025 |     ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32;
1026 | 
1027 |     // types/ints/int64
1028 | 
1029 |     if (Long) {
1030 | 
1031 |         /**
1032 |          * Writes a 64bit signed integer.
1033 |          * @param {number|!Long} value Value to write
1034 |          * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1035 |          * @returns {!ByteBuffer} this
1036 |          * @expose
1037 |          */
1038 |         ByteBufferPrototype.writeInt64 = function(value, offset) {
1039 |             var relative = typeof offset === 'undefined';
1040 |             if (relative) offset = this.offset;
1041 |             if (!this.noAssert) {
1042 |                 if (typeof value === 'number')
1043 |                     value = Long.fromNumber(value);
1044 |                 else if (typeof value === 'string')
1045 |                     value = Long.fromString(value);
1046 |                 else if (!(value && value instanceof Long))
1047 |                     throw TypeError("Illegal value: "+value+" (not an integer or Long)");
1048 |                 if (typeof offset !== 'number' || offset % 1 !== 0)
1049 |                     throw TypeError("Illegal offset: "+offset+" (not an integer)");
1050 |                 offset >>>= 0;
1051 |                 if (offset < 0 || offset + 0 > this.buffer.byteLength)
1052 |                     throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1053 |             }
1054 |             if (typeof value === 'number')
1055 |                 value = Long.fromNumber(value);
1056 |             else if (typeof value === 'string')
1057 |                 value = Long.fromString(value);
1058 |             offset += 8;
1059 |             var capacity6 = this.buffer.byteLength;
1060 |             if (offset > capacity6)
1061 |                 this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
1062 |             offset -= 8;
1063 |             var lo = value.low,
1064 |                 hi = value.high;
1065 |             if (this.littleEndian) {
1066 |                 this.view[offset+3] = (lo >>> 24) & 0xFF;
1067 |                 this.view[offset+2] = (lo >>> 16) & 0xFF;
1068 |                 this.view[offset+1] = (lo >>>  8) & 0xFF;
1069 |                 this.view[offset  ] =  lo         & 0xFF;
1070 |                 offset += 4;
1071 |                 this.view[offset+3] = (hi >>> 24) & 0xFF;
1072 |                 this.view[offset+2] = (hi >>> 16) & 0xFF;
1073 |                 this.view[offset+1] = (hi >>>  8) & 0xFF;
1074 |                 this.view[offset  ] =  hi         & 0xFF;
1075 |             } else {
1076 |                 this.view[offset  ] = (hi >>> 24) & 0xFF;
1077 |                 this.view[offset+1] = (hi >>> 16) & 0xFF;
1078 |                 this.view[offset+2] = (hi >>>  8) & 0xFF;
1079 |                 this.view[offset+3] =  hi         & 0xFF;
1080 |                 offset += 4;
1081 |                 this.view[offset  ] = (lo >>> 24) & 0xFF;
1082 |                 this.view[offset+1] = (lo >>> 16) & 0xFF;
1083 |                 this.view[offset+2] = (lo >>>  8) & 0xFF;
1084 |                 this.view[offset+3] =  lo         & 0xFF;
1085 |             }
1086 |             if (relative) this.offset += 8;
1087 |             return this;
1088 |         };
1089 | 
1090 |         /**
1091 |          * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
1092 |          * @param {number|!Long} value Value to write
1093 |          * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1094 |          * @returns {!ByteBuffer} this
1095 |          * @expose
1096 |          */
1097 |         ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
1098 | 
1099 |         /**
1100 |          * Reads a 64bit signed integer.
1101 |          * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1102 |          * @returns {!Long}
1103 |          * @expose
1104 |          */
1105 |         ByteBufferPrototype.readInt64 = function(offset) {
1106 |             var relative = typeof offset === 'undefined';
1107 |             if (relative) offset = this.offset;
1108 |             if (!this.noAssert) {
1109 |                 if (typeof offset !== 'number' || offset % 1 !== 0)
1110 |                     throw TypeError("Illegal offset: "+offset+" (not an integer)");
1111 |                 offset >>>= 0;
1112 |                 if (offset < 0 || offset + 8 > this.buffer.byteLength)
1113 |                     throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
1114 |             }
1115 |             var lo = 0,
1116 |                 hi = 0;
1117 |             if (this.littleEndian) {
1118 |                 lo  = this.view[offset+2] << 16;
1119 |                 lo |= this.view[offset+1] <<  8;
1120 |                 lo |= this.view[offset  ];
1121 |                 lo += this.view[offset+3] << 24 >>> 0;
1122 |                 offset += 4;
1123 |                 hi  = this.view[offset+2] << 16;
1124 |                 hi |= this.view[offset+1] <<  8;
1125 |                 hi |= this.view[offset  ];
1126 |                 hi += this.view[offset+3] << 24 >>> 0;
1127 |             } else {
1128 |                 hi  = this.view[offset+1] << 16;
1129 |                 hi |= this.view[offset+2] <<  8;
1130 |                 hi |= this.view[offset+3];
1131 |                 hi += this.view[offset  ] << 24 >>> 0;
1132 |                 offset += 4;
1133 |                 lo  = this.view[offset+1] << 16;
1134 |                 lo |= this.view[offset+2] <<  8;
1135 |                 lo |= this.view[offset+3];
1136 |                 lo += this.view[offset  ] << 24 >>> 0;
1137 |             }
1138 |             var value = new Long(lo, hi, false);
1139 |             if (relative) this.offset += 8;
1140 |             return value;
1141 |         };
1142 | 
1143 |         /**
1144 |          * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
1145 |          * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1146 |          * @returns {!Long}
1147 |          * @expose
1148 |          */
1149 |         ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
1150 | 
1151 |         /**
1152 |          * Writes a 64bit unsigned integer.
1153 |          * @param {number|!Long} value Value to write
1154 |          * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1155 |          * @returns {!ByteBuffer} this
1156 |          * @expose
1157 |          */
1158 |         ByteBufferPrototype.writeUint64 = function(value, offset) {
1159 |             var relative = typeof offset === 'undefined';
1160 |             if (relative) offset = this.offset;
1161 |             if (!this.noAssert) {
1162 |                 if (typeof value === 'number')
1163 |                     value = Long.fromNumber(value);
1164 |                 else if (typeof value === 'string')
1165 |                     value = Long.fromString(value);
1166 |                 else if (!(value && value instanceof Long))
1167 |                     throw TypeError("Illegal value: "+value+" (not an integer or Long)");
1168 |                 if (typeof offset !== 'number' || offset % 1 !== 0)
1169 |                     throw TypeError("Illegal offset: "+offset+" (not an integer)");
1170 |                 offset >>>= 0;
1171 |                 if (offset < 0 || offset + 0 > this.buffer.byteLength)
1172 |                     throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1173 |             }
1174 |             if (typeof value === 'number')
1175 |                 value = Long.fromNumber(value);
1176 |             else if (typeof value === 'string')
1177 |                 value = Long.fromString(value);
1178 |             offset += 8;
1179 |             var capacity7 = this.buffer.byteLength;
1180 |             if (offset > capacity7)
1181 |                 this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
1182 |             offset -= 8;
1183 |             var lo = value.low,
1184 |                 hi = value.high;
1185 |             if (this.littleEndian) {
1186 |                 this.view[offset+3] = (lo >>> 24) & 0xFF;
1187 |                 this.view[offset+2] = (lo >>> 16) & 0xFF;
1188 |                 this.view[offset+1] = (lo >>>  8) & 0xFF;
1189 |                 this.view[offset  ] =  lo         & 0xFF;
1190 |                 offset += 4;
1191 |                 this.view[offset+3] = (hi >>> 24) & 0xFF;
1192 |                 this.view[offset+2] = (hi >>> 16) & 0xFF;
1193 |                 this.view[offset+1] = (hi >>>  8) & 0xFF;
1194 |                 this.view[offset  ] =  hi         & 0xFF;
1195 |             } else {
1196 |                 this.view[offset  ] = (hi >>> 24) & 0xFF;
1197 |                 this.view[offset+1] = (hi >>> 16) & 0xFF;
1198 |                 this.view[offset+2] = (hi >>>  8) & 0xFF;
1199 |                 this.view[offset+3] =  hi         & 0xFF;
1200 |                 offset += 4;
1201 |                 this.view[offset  ] = (lo >>> 24) & 0xFF;
1202 |                 this.view[offset+1] = (lo >>> 16) & 0xFF;
1203 |                 this.view[offset+2] = (lo >>>  8) & 0xFF;
1204 |                 this.view[offset+3] =  lo         & 0xFF;
1205 |             }
1206 |             if (relative) this.offset += 8;
1207 |             return this;
1208 |         };
1209 | 
1210 |         /**
1211 |          * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
1212 |          * @function
1213 |          * @param {number|!Long} value Value to write
1214 |          * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1215 |          * @returns {!ByteBuffer} this
1216 |          * @expose
1217 |          */
1218 |         ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64;
1219 | 
1220 |         /**
1221 |          * Reads a 64bit unsigned integer.
1222 |          * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1223 |          * @returns {!Long}
1224 |          * @expose
1225 |          */
1226 |         ByteBufferPrototype.readUint64 = function(offset) {
1227 |             var relative = typeof offset === 'undefined';
1228 |             if (relative) offset = this.offset;
1229 |             if (!this.noAssert) {
1230 |                 if (typeof offset !== 'number' || offset % 1 !== 0)
1231 |                     throw TypeError("Illegal offset: "+offset+" (not an integer)");
1232 |                 offset >>>= 0;
1233 |                 if (offset < 0 || offset + 8 > this.buffer.byteLength)
1234 |                     throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
1235 |             }
1236 |             var lo = 0,
1237 |                 hi = 0;
1238 |             if (this.littleEndian) {
1239 |                 lo  = this.view[offset+2] << 16;
1240 |                 lo |= this.view[offset+1] <<  8;
1241 |                 lo |= this.view[offset  ];
1242 |                 lo += this.view[offset+3] << 24 >>> 0;
1243 |                 offset += 4;
1244 |                 hi  = this.view[offset+2] << 16;
1245 |                 hi |= this.view[offset+1] <<  8;
1246 |                 hi |= this.view[offset  ];
1247 |                 hi += this.view[offset+3] << 24 >>> 0;
1248 |             } else {
1249 |                 hi  = this.view[offset+1] << 16;
1250 |                 hi |= this.view[offset+2] <<  8;
1251 |                 hi |= this.view[offset+3];
1252 |                 hi += this.view[offset  ] << 24 >>> 0;
1253 |                 offset += 4;
1254 |                 lo  = this.view[offset+1] << 16;
1255 |                 lo |= this.view[offset+2] <<  8;
1256 |                 lo |= this.view[offset+3];
1257 |                 lo += this.view[offset  ] << 24 >>> 0;
1258 |             }
1259 |             var value = new Long(lo, hi, true);
1260 |             if (relative) this.offset += 8;
1261 |             return value;
1262 |         };
1263 | 
1264 |         /**
1265 |          * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}.
1266 |          * @function
1267 |          * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1268 |          * @returns {!Long}
1269 |          * @expose
1270 |          */
1271 |         ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64;
1272 | 
1273 |     } // Long
1274 | 
1275 | 
1276 |     // types/floats/float32
1277 | 
1278 |     /*
1279 |      ieee754 - https://github.com/feross/ieee754
1280 | 
1281 |      The MIT License (MIT)
1282 | 
1283 |      Copyright (c) Feross Aboukhadijeh
1284 | 
1285 |      Permission is hereby granted, free of charge, to any person obtaining a copy
1286 |      of this software and associated documentation files (the "Software"), to deal
1287 |      in the Software without restriction, including without limitation the rights
1288 |      to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1289 |      copies of the Software, and to permit persons to whom the Software is
1290 |      furnished to do so, subject to the following conditions:
1291 | 
1292 |      The above copyright notice and this permission notice shall be included in
1293 |      all copies or substantial portions of the Software.
1294 | 
1295 |      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1296 |      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1297 |      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1298 |      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1299 |      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1300 |      OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1301 |      THE SOFTWARE.
1302 |     */
1303 | 
1304 |     /**
1305 |      * Reads an IEEE754 float from a byte array.
1306 |      * @param {!Array} buffer
1307 |      * @param {number} offset
1308 |      * @param {boolean} isLE
1309 |      * @param {number} mLen
1310 |      * @param {number} nBytes
1311 |      * @returns {number}
1312 |      * @inner
1313 |      */
1314 |     function ieee754_read(buffer, offset, isLE, mLen, nBytes) {
1315 |         var e, m,
1316 |             eLen = nBytes * 8 - mLen - 1,
1317 |             eMax = (1 << eLen) - 1,
1318 |             eBias = eMax >> 1,
1319 |             nBits = -7,
1320 |             i = isLE ? (nBytes - 1) : 0,
1321 |             d = isLE ? -1 : 1,
1322 |             s = buffer[offset + i];
1323 | 
1324 |         i += d;
1325 | 
1326 |         e = s & ((1 << (-nBits)) - 1);
1327 |         s >>= (-nBits);
1328 |         nBits += eLen;
1329 |         for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
1330 | 
1331 |         m = e & ((1 << (-nBits)) - 1);
1332 |         e >>= (-nBits);
1333 |         nBits += mLen;
1334 |         for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
1335 | 
1336 |         if (e === 0) {
1337 |             e = 1 - eBias;
1338 |         } else if (e === eMax) {
1339 |             return m ? NaN : ((s ? -1 : 1) * Infinity);
1340 |         } else {
1341 |             m = m + Math.pow(2, mLen);
1342 |             e = e - eBias;
1343 |         }
1344 |         return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
1345 |     }
1346 | 
1347 |     /**
1348 |      * Writes an IEEE754 float to a byte array.
1349 |      * @param {!Array} buffer
1350 |      * @param {number} value
1351 |      * @param {number} offset
1352 |      * @param {boolean} isLE
1353 |      * @param {number} mLen
1354 |      * @param {number} nBytes
1355 |      * @inner
1356 |      */
1357 |     function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) {
1358 |         var e, m, c,
1359 |             eLen = nBytes * 8 - mLen - 1,
1360 |             eMax = (1 << eLen) - 1,
1361 |             eBias = eMax >> 1,
1362 |             rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
1363 |             i = isLE ? 0 : (nBytes - 1),
1364 |             d = isLE ? 1 : -1,
1365 |             s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
1366 | 
1367 |         value = Math.abs(value);
1368 | 
1369 |         if (isNaN(value) || value === Infinity) {
1370 |             m = isNaN(value) ? 1 : 0;
1371 |             e = eMax;
1372 |         } else {
1373 |             e = Math.floor(Math.log(value) / Math.LN2);
1374 |             if (value * (c = Math.pow(2, -e)) < 1) {
1375 |                 e--;
1376 |                 c *= 2;
1377 |             }
1378 |             if (e + eBias >= 1) {
1379 |                 value += rt / c;
1380 |             } else {
1381 |                 value += rt * Math.pow(2, 1 - eBias);
1382 |             }
1383 |             if (value * c >= 2) {
1384 |                 e++;
1385 |                 c /= 2;
1386 |             }
1387 | 
1388 |             if (e + eBias >= eMax) {
1389 |                 m = 0;
1390 |                 e = eMax;
1391 |             } else if (e + eBias >= 1) {
1392 |                 m = (value * c - 1) * Math.pow(2, mLen);
1393 |                 e = e + eBias;
1394 |             } else {
1395 |                 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
1396 |                 e = 0;
1397 |             }
1398 |         }
1399 | 
1400 |         for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
1401 | 
1402 |         e = (e << mLen) | m;
1403 |         eLen += mLen;
1404 |         for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
1405 | 
1406 |         buffer[offset + i - d] |= s * 128;
1407 |     }
1408 | 
1409 |     /**
1410 |      * Writes a 32bit float.
1411 |      * @param {number} value Value to write
1412 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1413 |      * @returns {!ByteBuffer} this
1414 |      * @expose
1415 |      */
1416 |     ByteBufferPrototype.writeFloat32 = function(value, offset) {
1417 |         var relative = typeof offset === 'undefined';
1418 |         if (relative) offset = this.offset;
1419 |         if (!this.noAssert) {
1420 |             if (typeof value !== 'number')
1421 |                 throw TypeError("Illegal value: "+value+" (not a number)");
1422 |             if (typeof offset !== 'number' || offset % 1 !== 0)
1423 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1424 |             offset >>>= 0;
1425 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
1426 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1427 |         }
1428 |         offset += 4;
1429 |         var capacity8 = this.buffer.byteLength;
1430 |         if (offset > capacity8)
1431 |             this.resize((capacity8 *= 2) > offset ? capacity8 : offset);
1432 |         offset -= 4;
1433 |         ieee754_write(this.view, value, offset, this.littleEndian, 23, 4);
1434 |         if (relative) this.offset += 4;
1435 |         return this;
1436 |     };
1437 | 
1438 |     /**
1439 |      * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
1440 |      * @function
1441 |      * @param {number} value Value to write
1442 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1443 |      * @returns {!ByteBuffer} this
1444 |      * @expose
1445 |      */
1446 |     ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32;
1447 | 
1448 |     /**
1449 |      * Reads a 32bit float.
1450 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1451 |      * @returns {number}
1452 |      * @expose
1453 |      */
1454 |     ByteBufferPrototype.readFloat32 = function(offset) {
1455 |         var relative = typeof offset === 'undefined';
1456 |         if (relative) offset = this.offset;
1457 |         if (!this.noAssert) {
1458 |             if (typeof offset !== 'number' || offset % 1 !== 0)
1459 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1460 |             offset >>>= 0;
1461 |             if (offset < 0 || offset + 4 > this.buffer.byteLength)
1462 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
1463 |         }
1464 |         var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4);
1465 |         if (relative) this.offset += 4;
1466 |         return value;
1467 |     };
1468 | 
1469 |     /**
1470 |      * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
1471 |      * @function
1472 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1473 |      * @returns {number}
1474 |      * @expose
1475 |      */
1476 |     ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32;
1477 | 
1478 |     // types/floats/float64
1479 | 
1480 |     /**
1481 |      * Writes a 64bit float.
1482 |      * @param {number} value Value to write
1483 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1484 |      * @returns {!ByteBuffer} this
1485 |      * @expose
1486 |      */
1487 |     ByteBufferPrototype.writeFloat64 = function(value, offset) {
1488 |         var relative = typeof offset === 'undefined';
1489 |         if (relative) offset = this.offset;
1490 |         if (!this.noAssert) {
1491 |             if (typeof value !== 'number')
1492 |                 throw TypeError("Illegal value: "+value+" (not a number)");
1493 |             if (typeof offset !== 'number' || offset % 1 !== 0)
1494 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1495 |             offset >>>= 0;
1496 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
1497 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1498 |         }
1499 |         offset += 8;
1500 |         var capacity9 = this.buffer.byteLength;
1501 |         if (offset > capacity9)
1502 |             this.resize((capacity9 *= 2) > offset ? capacity9 : offset);
1503 |         offset -= 8;
1504 |         ieee754_write(this.view, value, offset, this.littleEndian, 52, 8);
1505 |         if (relative) this.offset += 8;
1506 |         return this;
1507 |     };
1508 | 
1509 |     /**
1510 |      * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
1511 |      * @function
1512 |      * @param {number} value Value to write
1513 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1514 |      * @returns {!ByteBuffer} this
1515 |      * @expose
1516 |      */
1517 |     ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64;
1518 | 
1519 |     /**
1520 |      * Reads a 64bit float.
1521 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1522 |      * @returns {number}
1523 |      * @expose
1524 |      */
1525 |     ByteBufferPrototype.readFloat64 = function(offset) {
1526 |         var relative = typeof offset === 'undefined';
1527 |         if (relative) offset = this.offset;
1528 |         if (!this.noAssert) {
1529 |             if (typeof offset !== 'number' || offset % 1 !== 0)
1530 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1531 |             offset >>>= 0;
1532 |             if (offset < 0 || offset + 8 > this.buffer.byteLength)
1533 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
1534 |         }
1535 |         var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8);
1536 |         if (relative) this.offset += 8;
1537 |         return value;
1538 |     };
1539 | 
1540 |     /**
1541 |      * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
1542 |      * @function
1543 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1544 |      * @returns {number}
1545 |      * @expose
1546 |      */
1547 |     ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64;
1548 | 
1549 | 
1550 |     // types/varints/varint32
1551 | 
1552 |     /**
1553 |      * Maximum number of bytes required to store a 32bit base 128 variable-length integer.
1554 |      * @type {number}
1555 |      * @const
1556 |      * @expose
1557 |      */
1558 |     ByteBuffer.MAX_VARINT32_BYTES = 5;
1559 | 
1560 |     /**
1561 |      * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer.
1562 |      * @param {number} value Value to encode
1563 |      * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES}
1564 |      * @expose
1565 |      */
1566 |     ByteBuffer.calculateVarint32 = function(value) {
1567 |         // ref: src/google/protobuf/io/coded_stream.cc
1568 |         value = value >>> 0;
1569 |              if (value < 1 << 7 ) return 1;
1570 |         else if (value < 1 << 14) return 2;
1571 |         else if (value < 1 << 21) return 3;
1572 |         else if (value < 1 << 28) return 4;
1573 |         else                      return 5;
1574 |     };
1575 | 
1576 |     /**
1577 |      * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding.
1578 |      * @param {number} n Signed 32bit integer
1579 |      * @returns {number} Unsigned zigzag encoded 32bit integer
1580 |      * @expose
1581 |      */
1582 |     ByteBuffer.zigZagEncode32 = function(n) {
1583 |         return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h
1584 |     };
1585 | 
1586 |     /**
1587 |      * Decodes a zigzag encoded signed 32bit integer.
1588 |      * @param {number} n Unsigned zigzag encoded 32bit integer
1589 |      * @returns {number} Signed 32bit integer
1590 |      * @expose
1591 |      */
1592 |     ByteBuffer.zigZagDecode32 = function(n) {
1593 |         return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h
1594 |     };
1595 | 
1596 |     /**
1597 |      * Writes a 32bit base 128 variable-length integer.
1598 |      * @param {number} value Value to write
1599 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1600 |      *  written if omitted.
1601 |      * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
1602 |      * @expose
1603 |      */
1604 |     ByteBufferPrototype.writeVarint32 = function(value, offset) {
1605 |         var relative = typeof offset === 'undefined';
1606 |         if (relative) offset = this.offset;
1607 |         if (!this.noAssert) {
1608 |             if (typeof value !== 'number' || value % 1 !== 0)
1609 |                 throw TypeError("Illegal value: "+value+" (not an integer)");
1610 |             value |= 0;
1611 |             if (typeof offset !== 'number' || offset % 1 !== 0)
1612 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1613 |             offset >>>= 0;
1614 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
1615 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1616 |         }
1617 |         var size = ByteBuffer.calculateVarint32(value),
1618 |             b;
1619 |         offset += size;
1620 |         var capacity10 = this.buffer.byteLength;
1621 |         if (offset > capacity10)
1622 |             this.resize((capacity10 *= 2) > offset ? capacity10 : offset);
1623 |         offset -= size;
1624 |         value >>>= 0;
1625 |         while (value >= 0x80) {
1626 |             b = (value & 0x7f) | 0x80;
1627 |             this.view[offset++] = b;
1628 |             value >>>= 7;
1629 |         }
1630 |         this.view[offset++] = value;
1631 |         if (relative) {
1632 |             this.offset = offset;
1633 |             return this;
1634 |         }
1635 |         return size;
1636 |     };
1637 | 
1638 |     /**
1639 |      * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer.
1640 |      * @param {number} value Value to write
1641 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1642 |      *  written if omitted.
1643 |      * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
1644 |      * @expose
1645 |      */
1646 |     ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) {
1647 |         return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset);
1648 |     };
1649 | 
1650 |     /**
1651 |      * Reads a 32bit base 128 variable-length integer.
1652 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1653 |      *  written if omitted.
1654 |      * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
1655 |      *  and the actual number of bytes read.
1656 |      * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available
1657 |      *  to fully decode the varint.
1658 |      * @expose
1659 |      */
1660 |     ByteBufferPrototype.readVarint32 = function(offset) {
1661 |         var relative = typeof offset === 'undefined';
1662 |         if (relative) offset = this.offset;
1663 |         if (!this.noAssert) {
1664 |             if (typeof offset !== 'number' || offset % 1 !== 0)
1665 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1666 |             offset >>>= 0;
1667 |             if (offset < 0 || offset + 1 > this.buffer.byteLength)
1668 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
1669 |         }
1670 |         var c = 0,
1671 |             value = 0 >>> 0,
1672 |             b;
1673 |         do {
1674 |             if (!this.noAssert && offset > this.limit) {
1675 |                 var err = Error("Truncated");
1676 |                 err['truncated'] = true;
1677 |                 throw err;
1678 |             }
1679 |             b = this.view[offset++];
1680 |             if (c < 5)
1681 |                 value |= (b & 0x7f) << (7*c);
1682 |             ++c;
1683 |         } while ((b & 0x80) !== 0);
1684 |         value |= 0;
1685 |         if (relative) {
1686 |             this.offset = offset;
1687 |             return value;
1688 |         }
1689 |         return {
1690 |             "value": value,
1691 |             "length": c
1692 |         };
1693 |     };
1694 | 
1695 |     /**
1696 |      * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer.
1697 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1698 |      *  written if omitted.
1699 |      * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
1700 |      *  and the actual number of bytes read.
1701 |      * @throws {Error} If it's not a valid varint
1702 |      * @expose
1703 |      */
1704 |     ByteBufferPrototype.readVarint32ZigZag = function(offset) {
1705 |         var val = this.readVarint32(offset);
1706 |         if (typeof val === 'object')
1707 |             val["value"] = ByteBuffer.zigZagDecode32(val["value"]);
1708 |         else
1709 |             val = ByteBuffer.zigZagDecode32(val);
1710 |         return val;
1711 |     };
1712 | 
1713 |     // types/varints/varint64
1714 | 
1715 |     if (Long) {
1716 | 
1717 |         /**
1718 |          * Maximum number of bytes required to store a 64bit base 128 variable-length integer.
1719 |          * @type {number}
1720 |          * @const
1721 |          * @expose
1722 |          */
1723 |         ByteBuffer.MAX_VARINT64_BYTES = 10;
1724 | 
1725 |         /**
1726 |          * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer.
1727 |          * @param {number|!Long} value Value to encode
1728 |          * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES}
1729 |          * @expose
1730 |          */
1731 |         ByteBuffer.calculateVarint64 = function(value) {
1732 |             if (typeof value === 'number')
1733 |                 value = Long.fromNumber(value);
1734 |             else if (typeof value === 'string')
1735 |                 value = Long.fromString(value);
1736 |             // ref: src/google/protobuf/io/coded_stream.cc
1737 |             var part0 = value.toInt() >>> 0,
1738 |                 part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
1739 |                 part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
1740 |             if (part2 == 0) {
1741 |                 if (part1 == 0) {
1742 |                     if (part0 < 1 << 14)
1743 |                         return part0 < 1 << 7 ? 1 : 2;
1744 |                     else
1745 |                         return part0 < 1 << 21 ? 3 : 4;
1746 |                 } else {
1747 |                     if (part1 < 1 << 14)
1748 |                         return part1 < 1 << 7 ? 5 : 6;
1749 |                     else
1750 |                         return part1 < 1 << 21 ? 7 : 8;
1751 |                 }
1752 |             } else
1753 |                 return part2 < 1 << 7 ? 9 : 10;
1754 |         };
1755 | 
1756 |         /**
1757 |          * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding.
1758 |          * @param {number|!Long} value Signed long
1759 |          * @returns {!Long} Unsigned zigzag encoded long
1760 |          * @expose
1761 |          */
1762 |         ByteBuffer.zigZagEncode64 = function(value) {
1763 |             if (typeof value === 'number')
1764 |                 value = Long.fromNumber(value, false);
1765 |             else if (typeof value === 'string')
1766 |                 value = Long.fromString(value, false);
1767 |             else if (value.unsigned !== false) value = value.toSigned();
1768 |             // ref: src/google/protobuf/wire_format_lite.h
1769 |             return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned();
1770 |         };
1771 | 
1772 |         /**
1773 |          * Decodes a zigzag encoded signed 64bit integer.
1774 |          * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number
1775 |          * @returns {!Long} Signed long
1776 |          * @expose
1777 |          */
1778 |         ByteBuffer.zigZagDecode64 = function(value) {
1779 |             if (typeof value === 'number')
1780 |                 value = Long.fromNumber(value, false);
1781 |             else if (typeof value === 'string')
1782 |                 value = Long.fromString(value, false);
1783 |             else if (value.unsigned !== false) value = value.toSigned();
1784 |             // ref: src/google/protobuf/wire_format_lite.h
1785 |             return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned();
1786 |         };
1787 | 
1788 |         /**
1789 |          * Writes a 64bit base 128 variable-length integer.
1790 |          * @param {number|Long} value Value to write
1791 |          * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1792 |          *  written if omitted.
1793 |          * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
1794 |          * @expose
1795 |          */
1796 |         ByteBufferPrototype.writeVarint64 = function(value, offset) {
1797 |             var relative = typeof offset === 'undefined';
1798 |             if (relative) offset = this.offset;
1799 |             if (!this.noAssert) {
1800 |                 if (typeof value === 'number')
1801 |                     value = Long.fromNumber(value);
1802 |                 else if (typeof value === 'string')
1803 |                     value = Long.fromString(value);
1804 |                 else if (!(value && value instanceof Long))
1805 |                     throw TypeError("Illegal value: "+value+" (not an integer or Long)");
1806 |                 if (typeof offset !== 'number' || offset % 1 !== 0)
1807 |                     throw TypeError("Illegal offset: "+offset+" (not an integer)");
1808 |                 offset >>>= 0;
1809 |                 if (offset < 0 || offset + 0 > this.buffer.byteLength)
1810 |                     throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1811 |             }
1812 |             if (typeof value === 'number')
1813 |                 value = Long.fromNumber(value, false);
1814 |             else if (typeof value === 'string')
1815 |                 value = Long.fromString(value, false);
1816 |             else if (value.unsigned !== false) value = value.toSigned();
1817 |             var size = ByteBuffer.calculateVarint64(value),
1818 |                 part0 = value.toInt() >>> 0,
1819 |                 part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
1820 |                 part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
1821 |             offset += size;
1822 |             var capacity11 = this.buffer.byteLength;
1823 |             if (offset > capacity11)
1824 |                 this.resize((capacity11 *= 2) > offset ? capacity11 : offset);
1825 |             offset -= size;
1826 |             switch (size) {
1827 |                 case 10: this.view[offset+9] = (part2 >>>  7) & 0x01;
1828 |                 case 9 : this.view[offset+8] = size !== 9 ? (part2       ) | 0x80 : (part2       ) & 0x7F;
1829 |                 case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F;
1830 |                 case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F;
1831 |                 case 6 : this.view[offset+5] = size !== 6 ? (part1 >>>  7) | 0x80 : (part1 >>>  7) & 0x7F;
1832 |                 case 5 : this.view[offset+4] = size !== 5 ? (part1       ) | 0x80 : (part1       ) & 0x7F;
1833 |                 case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F;
1834 |                 case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F;
1835 |                 case 2 : this.view[offset+1] = size !== 2 ? (part0 >>>  7) | 0x80 : (part0 >>>  7) & 0x7F;
1836 |                 case 1 : this.view[offset  ] = size !== 1 ? (part0       ) | 0x80 : (part0       ) & 0x7F;
1837 |             }
1838 |             if (relative) {
1839 |                 this.offset += size;
1840 |                 return this;
1841 |             } else {
1842 |                 return size;
1843 |             }
1844 |         };
1845 | 
1846 |         /**
1847 |          * Writes a zig-zag encoded 64bit base 128 variable-length integer.
1848 |          * @param {number|Long} value Value to write
1849 |          * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1850 |          *  written if omitted.
1851 |          * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
1852 |          * @expose
1853 |          */
1854 |         ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) {
1855 |             return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset);
1856 |         };
1857 | 
1858 |         /**
1859 |          * Reads a 64bit base 128 variable-length integer. Requires Long.js.
1860 |          * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1861 |          *  read if omitted.
1862 |          * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
1863 |          *  the actual number of bytes read.
1864 |          * @throws {Error} If it's not a valid varint
1865 |          * @expose
1866 |          */
1867 |         ByteBufferPrototype.readVarint64 = function(offset) {
1868 |             var relative = typeof offset === 'undefined';
1869 |             if (relative) offset = this.offset;
1870 |             if (!this.noAssert) {
1871 |                 if (typeof offset !== 'number' || offset % 1 !== 0)
1872 |                     throw TypeError("Illegal offset: "+offset+" (not an integer)");
1873 |                 offset >>>= 0;
1874 |                 if (offset < 0 || offset + 1 > this.buffer.byteLength)
1875 |                     throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
1876 |             }
1877 |             // ref: src/google/protobuf/io/coded_stream.cc
1878 |             var start = offset,
1879 |                 part0 = 0,
1880 |                 part1 = 0,
1881 |                 part2 = 0,
1882 |                 b  = 0;
1883 |             b = this.view[offset++]; part0  = (b & 0x7F)      ; if ( b & 0x80                                                   ) {
1884 |             b = this.view[offset++]; part0 |= (b & 0x7F) <<  7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1885 |             b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1886 |             b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1887 |             b = this.view[offset++]; part1  = (b & 0x7F)      ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1888 |             b = this.view[offset++]; part1 |= (b & 0x7F) <<  7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1889 |             b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1890 |             b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1891 |             b = this.view[offset++]; part2  = (b & 0x7F)      ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1892 |             b = this.view[offset++]; part2 |= (b & 0x7F) <<  7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
1893 |             throw Error("Buffer overrun"); }}}}}}}}}}
1894 |             var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
1895 |             if (relative) {
1896 |                 this.offset = offset;
1897 |                 return value;
1898 |             } else {
1899 |                 return {
1900 |                     'value': value,
1901 |                     'length': offset-start
1902 |                 };
1903 |             }
1904 |         };
1905 | 
1906 |         /**
1907 |          * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js.
1908 |          * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1909 |          *  read if omitted.
1910 |          * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
1911 |          *  the actual number of bytes read.
1912 |          * @throws {Error} If it's not a valid varint
1913 |          * @expose
1914 |          */
1915 |         ByteBufferPrototype.readVarint64ZigZag = function(offset) {
1916 |             var val = this.readVarint64(offset);
1917 |             if (val && val['value'] instanceof Long)
1918 |                 val["value"] = ByteBuffer.zigZagDecode64(val["value"]);
1919 |             else
1920 |                 val = ByteBuffer.zigZagDecode64(val);
1921 |             return val;
1922 |         };
1923 | 
1924 |     } // Long
1925 | 
1926 | 
1927 |     // types/strings/cstring
1928 | 
1929 |     /**
1930 |      * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL
1931 |      *  characters itself.
1932 |      * @param {string} str String to write
1933 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1934 |      *  contained in `str` + 1 if omitted.
1935 |      * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written
1936 |      * @expose
1937 |      */
1938 |     ByteBufferPrototype.writeCString = function(str, offset) {
1939 |         var relative = typeof offset === 'undefined';
1940 |         if (relative) offset = this.offset;
1941 |         var i,
1942 |             k = str.length;
1943 |         if (!this.noAssert) {
1944 |             if (typeof str !== 'string')
1945 |                 throw TypeError("Illegal str: Not a string");
1946 |             for (i=0; i>>= 0;
1953 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
1954 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1955 |         }
1956 |         // UTF8 strings do not contain zero bytes in between except for the zero character, so:
1957 |         k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
1958 |         offset += k+1;
1959 |         var capacity12 = this.buffer.byteLength;
1960 |         if (offset > capacity12)
1961 |             this.resize((capacity12 *= 2) > offset ? capacity12 : offset);
1962 |         offset -= k+1;
1963 |         utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
1964 |             this.view[offset++] = b;
1965 |         }.bind(this));
1966 |         this.view[offset++] = 0;
1967 |         if (relative) {
1968 |             this.offset = offset;
1969 |             return this;
1970 |         }
1971 |         return k;
1972 |     };
1973 | 
1974 |     /**
1975 |      * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters
1976 |      *  itself.
1977 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1978 |      *  read if omitted.
1979 |      * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
1980 |      *  read and the actual number of bytes read.
1981 |      * @expose
1982 |      */
1983 |     ByteBufferPrototype.readCString = function(offset) {
1984 |         var relative = typeof offset === 'undefined';
1985 |         if (relative) offset = this.offset;
1986 |         if (!this.noAssert) {
1987 |             if (typeof offset !== 'number' || offset % 1 !== 0)
1988 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1989 |             offset >>>= 0;
1990 |             if (offset < 0 || offset + 1 > this.buffer.byteLength)
1991 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
1992 |         }
1993 |         var start = offset,
1994 |             temp;
1995 |         // UTF8 strings do not contain zero bytes in between except for the zero character itself, so:
1996 |         var sd, b = -1;
1997 |         utfx.decodeUTF8toUTF16(function() {
1998 |             if (b === 0) return null;
1999 |             if (offset >= this.limit)
2000 |                 throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit);
2001 |             b = this.view[offset++];
2002 |             return b === 0 ? null : b;
2003 |         }.bind(this), sd = stringDestination(), true);
2004 |         if (relative) {
2005 |             this.offset = offset;
2006 |             return sd();
2007 |         } else {
2008 |             return {
2009 |                 "string": sd(),
2010 |                 "length": offset - start
2011 |             };
2012 |         }
2013 |     };
2014 | 
2015 |     // types/strings/istring
2016 | 
2017 |     /**
2018 |      * Writes a length as uint32 prefixed UTF8 encoded string.
2019 |      * @param {string} str String to write
2020 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2021 |      *  written if omitted.
2022 |      * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
2023 |      * @expose
2024 |      * @see ByteBuffer#writeVarint32
2025 |      */
2026 |     ByteBufferPrototype.writeIString = function(str, offset) {
2027 |         var relative = typeof offset === 'undefined';
2028 |         if (relative) offset = this.offset;
2029 |         if (!this.noAssert) {
2030 |             if (typeof str !== 'string')
2031 |                 throw TypeError("Illegal str: Not a string");
2032 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2033 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2034 |             offset >>>= 0;
2035 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
2036 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2037 |         }
2038 |         var start = offset,
2039 |             k;
2040 |         k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
2041 |         offset += 4+k;
2042 |         var capacity13 = this.buffer.byteLength;
2043 |         if (offset > capacity13)
2044 |             this.resize((capacity13 *= 2) > offset ? capacity13 : offset);
2045 |         offset -= 4+k;
2046 |         if (this.littleEndian) {
2047 |             this.view[offset+3] = (k >>> 24) & 0xFF;
2048 |             this.view[offset+2] = (k >>> 16) & 0xFF;
2049 |             this.view[offset+1] = (k >>>  8) & 0xFF;
2050 |             this.view[offset  ] =  k         & 0xFF;
2051 |         } else {
2052 |             this.view[offset  ] = (k >>> 24) & 0xFF;
2053 |             this.view[offset+1] = (k >>> 16) & 0xFF;
2054 |             this.view[offset+2] = (k >>>  8) & 0xFF;
2055 |             this.view[offset+3] =  k         & 0xFF;
2056 |         }
2057 |         offset += 4;
2058 |         utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
2059 |             this.view[offset++] = b;
2060 |         }.bind(this));
2061 |         if (offset !== start + 4 + k)
2062 |             throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k));
2063 |         if (relative) {
2064 |             this.offset = offset;
2065 |             return this;
2066 |         }
2067 |         return offset - start;
2068 |     };
2069 | 
2070 |     /**
2071 |      * Reads a length as uint32 prefixed UTF8 encoded string.
2072 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2073 |      *  read if omitted.
2074 |      * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
2075 |      *  read and the actual number of bytes read.
2076 |      * @expose
2077 |      * @see ByteBuffer#readVarint32
2078 |      */
2079 |     ByteBufferPrototype.readIString = function(offset) {
2080 |         var relative = typeof offset === 'undefined';
2081 |         if (relative) offset = this.offset;
2082 |         if (!this.noAssert) {
2083 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2084 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2085 |             offset >>>= 0;
2086 |             if (offset < 0 || offset + 4 > this.buffer.byteLength)
2087 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
2088 |         }
2089 |         var start = offset;
2090 |         var len = this.readUint32(offset);
2091 |         var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4);
2092 |         offset += str['length'];
2093 |         if (relative) {
2094 |             this.offset = offset;
2095 |             return str['string'];
2096 |         } else {
2097 |             return {
2098 |                 'string': str['string'],
2099 |                 'length': offset - start
2100 |             };
2101 |         }
2102 |     };
2103 | 
2104 |     // types/strings/utf8string
2105 | 
2106 |     /**
2107 |      * Metrics representing number of UTF8 characters. Evaluates to `c`.
2108 |      * @type {string}
2109 |      * @const
2110 |      * @expose
2111 |      */
2112 |     ByteBuffer.METRICS_CHARS = 'c';
2113 | 
2114 |     /**
2115 |      * Metrics representing number of bytes. Evaluates to `b`.
2116 |      * @type {string}
2117 |      * @const
2118 |      * @expose
2119 |      */
2120 |     ByteBuffer.METRICS_BYTES = 'b';
2121 | 
2122 |     /**
2123 |      * Writes an UTF8 encoded string.
2124 |      * @param {string} str String to write
2125 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
2126 |      * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
2127 |      * @expose
2128 |      */
2129 |     ByteBufferPrototype.writeUTF8String = function(str, offset) {
2130 |         var relative = typeof offset === 'undefined';
2131 |         if (relative) offset = this.offset;
2132 |         if (!this.noAssert) {
2133 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2134 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2135 |             offset >>>= 0;
2136 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
2137 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2138 |         }
2139 |         var k;
2140 |         var start = offset;
2141 |         k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
2142 |         offset += k;
2143 |         var capacity14 = this.buffer.byteLength;
2144 |         if (offset > capacity14)
2145 |             this.resize((capacity14 *= 2) > offset ? capacity14 : offset);
2146 |         offset -= k;
2147 |         utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
2148 |             this.view[offset++] = b;
2149 |         }.bind(this));
2150 |         if (relative) {
2151 |             this.offset = offset;
2152 |             return this;
2153 |         }
2154 |         return offset - start;
2155 |     };
2156 | 
2157 |     /**
2158 |      * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}.
2159 |      * @function
2160 |      * @param {string} str String to write
2161 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
2162 |      * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
2163 |      * @expose
2164 |      */
2165 |     ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String;
2166 | 
2167 |     /**
2168 |      * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's
2169 |      *  `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF.
2170 |      * @param {string} str String to calculate
2171 |      * @returns {number} Number of UTF8 characters
2172 |      * @expose
2173 |      */
2174 |     ByteBuffer.calculateUTF8Chars = function(str) {
2175 |         return utfx.calculateUTF16asUTF8(stringSource(str))[0];
2176 |     };
2177 | 
2178 |     /**
2179 |      * Calculates the number of UTF8 bytes of a string.
2180 |      * @param {string} str String to calculate
2181 |      * @returns {number} Number of UTF8 bytes
2182 |      * @expose
2183 |      */
2184 |     ByteBuffer.calculateUTF8Bytes = function(str) {
2185 |         return utfx.calculateUTF16asUTF8(stringSource(str))[1];
2186 |     };
2187 | 
2188 |     /**
2189 |      * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}.
2190 |      * @function
2191 |      * @param {string} str String to calculate
2192 |      * @returns {number} Number of UTF8 bytes
2193 |      * @expose
2194 |      */
2195 |     ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes;
2196 | 
2197 |     /**
2198 |      * Reads an UTF8 encoded string.
2199 |      * @param {number} length Number of characters or bytes to read.
2200 |      * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to
2201 |      *  {@link ByteBuffer.METRICS_CHARS}.
2202 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2203 |      *  read if omitted.
2204 |      * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
2205 |      *  read and the actual number of bytes read.
2206 |      * @expose
2207 |      */
2208 |     ByteBufferPrototype.readUTF8String = function(length, metrics, offset) {
2209 |         if (typeof metrics === 'number') {
2210 |             offset = metrics;
2211 |             metrics = undefined;
2212 |         }
2213 |         var relative = typeof offset === 'undefined';
2214 |         if (relative) offset = this.offset;
2215 |         if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS;
2216 |         if (!this.noAssert) {
2217 |             if (typeof length !== 'number' || length % 1 !== 0)
2218 |                 throw TypeError("Illegal length: "+length+" (not an integer)");
2219 |             length |= 0;
2220 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2221 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2222 |             offset >>>= 0;
2223 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
2224 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2225 |         }
2226 |         var i = 0,
2227 |             start = offset,
2228 |             sd;
2229 |         if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser
2230 |             sd = stringDestination();
2231 |             utfx.decodeUTF8(function() {
2232 |                 return i < length && offset < this.limit ? this.view[offset++] : null;
2233 |             }.bind(this), function(cp) {
2234 |                 ++i; utfx.UTF8toUTF16(cp, sd);
2235 |             });
2236 |             if (i !== length)
2237 |                 throw RangeError("Illegal range: Truncated data, "+i+" == "+length);
2238 |             if (relative) {
2239 |                 this.offset = offset;
2240 |                 return sd();
2241 |             } else {
2242 |                 return {
2243 |                     "string": sd(),
2244 |                     "length": offset - start
2245 |                 };
2246 |             }
2247 |         } else if (metrics === ByteBuffer.METRICS_BYTES) {
2248 |             if (!this.noAssert) {
2249 |                 if (typeof offset !== 'number' || offset % 1 !== 0)
2250 |                     throw TypeError("Illegal offset: "+offset+" (not an integer)");
2251 |                 offset >>>= 0;
2252 |                 if (offset < 0 || offset + length > this.buffer.byteLength)
2253 |                     throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
2254 |             }
2255 |             var k = offset + length;
2256 |             utfx.decodeUTF8toUTF16(function() {
2257 |                 return offset < k ? this.view[offset++] : null;
2258 |             }.bind(this), sd = stringDestination(), this.noAssert);
2259 |             if (offset !== k)
2260 |                 throw RangeError("Illegal range: Truncated data, "+offset+" == "+k);
2261 |             if (relative) {
2262 |                 this.offset = offset;
2263 |                 return sd();
2264 |             } else {
2265 |                 return {
2266 |                     'string': sd(),
2267 |                     'length': offset - start
2268 |                 };
2269 |             }
2270 |         } else
2271 |             throw TypeError("Unsupported metrics: "+metrics);
2272 |     };
2273 | 
2274 |     /**
2275 |      * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}.
2276 |      * @function
2277 |      * @param {number} length Number of characters or bytes to read
2278 |      * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to
2279 |      *  {@link ByteBuffer.METRICS_CHARS}.
2280 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2281 |      *  read if omitted.
2282 |      * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
2283 |      *  read and the actual number of bytes read.
2284 |      * @expose
2285 |      */
2286 |     ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String;
2287 | 
2288 |     // types/strings/vstring
2289 | 
2290 |     /**
2291 |      * Writes a length as varint32 prefixed UTF8 encoded string.
2292 |      * @param {string} str String to write
2293 |      * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2294 |      *  written if omitted.
2295 |      * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
2296 |      * @expose
2297 |      * @see ByteBuffer#writeVarint32
2298 |      */
2299 |     ByteBufferPrototype.writeVString = function(str, offset) {
2300 |         var relative = typeof offset === 'undefined';
2301 |         if (relative) offset = this.offset;
2302 |         if (!this.noAssert) {
2303 |             if (typeof str !== 'string')
2304 |                 throw TypeError("Illegal str: Not a string");
2305 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2306 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2307 |             offset >>>= 0;
2308 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
2309 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2310 |         }
2311 |         var start = offset,
2312 |             k, l;
2313 |         k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
2314 |         l = ByteBuffer.calculateVarint32(k);
2315 |         offset += l+k;
2316 |         var capacity15 = this.buffer.byteLength;
2317 |         if (offset > capacity15)
2318 |             this.resize((capacity15 *= 2) > offset ? capacity15 : offset);
2319 |         offset -= l+k;
2320 |         offset += this.writeVarint32(k, offset);
2321 |         utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
2322 |             this.view[offset++] = b;
2323 |         }.bind(this));
2324 |         if (offset !== start+k+l)
2325 |             throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l));
2326 |         if (relative) {
2327 |             this.offset = offset;
2328 |             return this;
2329 |         }
2330 |         return offset - start;
2331 |     };
2332 | 
2333 |     /**
2334 |      * Reads a length as varint32 prefixed UTF8 encoded string.
2335 |      * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2336 |      *  read if omitted.
2337 |      * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
2338 |      *  read and the actual number of bytes read.
2339 |      * @expose
2340 |      * @see ByteBuffer#readVarint32
2341 |      */
2342 |     ByteBufferPrototype.readVString = function(offset) {
2343 |         var relative = typeof offset === 'undefined';
2344 |         if (relative) offset = this.offset;
2345 |         if (!this.noAssert) {
2346 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2347 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2348 |             offset >>>= 0;
2349 |             if (offset < 0 || offset + 1 > this.buffer.byteLength)
2350 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
2351 |         }
2352 |         var start = offset;
2353 |         var len = this.readVarint32(offset);
2354 |         var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']);
2355 |         offset += str['length'];
2356 |         if (relative) {
2357 |             this.offset = offset;
2358 |             return str['string'];
2359 |         } else {
2360 |             return {
2361 |                 'string': str['string'],
2362 |                 'length': offset - start
2363 |             };
2364 |         }
2365 |     };
2366 | 
2367 | 
2368 |     /**
2369 |      * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
2370 |      *  data's length.
2371 |      * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets
2372 |      *  will be modified according to the performed read operation.
2373 |      * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
2374 |      * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2375 |      *  written if omitted.
2376 |      * @returns {!ByteBuffer} this
2377 |      * @expose
2378 |      * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
2379 |      * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
2380 |      */
2381 |     ByteBufferPrototype.append = function(source, encoding, offset) {
2382 |         if (typeof encoding === 'number' || typeof encoding !== 'string') {
2383 |             offset = encoding;
2384 |             encoding = undefined;
2385 |         }
2386 |         var relative = typeof offset === 'undefined';
2387 |         if (relative) offset = this.offset;
2388 |         if (!this.noAssert) {
2389 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2390 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2391 |             offset >>>= 0;
2392 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
2393 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2394 |         }
2395 |         if (!(source instanceof ByteBuffer))
2396 |             source = ByteBuffer.wrap(source, encoding);
2397 |         var length = source.limit - source.offset;
2398 |         if (length <= 0) return this; // Nothing to append
2399 |         offset += length;
2400 |         var capacity16 = this.buffer.byteLength;
2401 |         if (offset > capacity16)
2402 |             this.resize((capacity16 *= 2) > offset ? capacity16 : offset);
2403 |         offset -= length;
2404 |         this.view.set(source.view.subarray(source.offset, source.limit), offset);
2405 |         source.offset += length;
2406 |         if (relative) this.offset += length;
2407 |         return this;
2408 |     };
2409 | 
2410 |     /**
2411 |      * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
2412 |         specified offset up to the length of this ByteBuffer's data.
2413 |      * @param {!ByteBuffer} target Target ByteBuffer
2414 |      * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2415 |      *  read if omitted.
2416 |      * @returns {!ByteBuffer} this
2417 |      * @expose
2418 |      * @see ByteBuffer#append
2419 |      */
2420 |     ByteBufferPrototype.appendTo = function(target, offset) {
2421 |         target.append(this, offset);
2422 |         return this;
2423 |     };
2424 | 
2425 |     /**
2426 |      * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
2427 |      *  disable them if your code already makes sure that everything is valid.
2428 |      * @param {boolean} assert `true` to enable assertions, otherwise `false`
2429 |      * @returns {!ByteBuffer} this
2430 |      * @expose
2431 |      */
2432 |     ByteBufferPrototype.assert = function(assert) {
2433 |         this.noAssert = !assert;
2434 |         return this;
2435 |     };
2436 | 
2437 |     /**
2438 |      * Gets the capacity of this ByteBuffer's backing buffer.
2439 |      * @returns {number} Capacity of the backing buffer
2440 |      * @expose
2441 |      */
2442 |     ByteBufferPrototype.capacity = function() {
2443 |         return this.buffer.byteLength;
2444 |     };
2445 |     /**
2446 |      * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
2447 |      *  backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
2448 |      * @returns {!ByteBuffer} this
2449 |      * @expose
2450 |      */
2451 |     ByteBufferPrototype.clear = function() {
2452 |         this.offset = 0;
2453 |         this.limit = this.buffer.byteLength;
2454 |         this.markedOffset = -1;
2455 |         return this;
2456 |     };
2457 | 
2458 |     /**
2459 |      * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
2460 |      *  {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
2461 |      * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
2462 |      * @returns {!ByteBuffer} Cloned instance
2463 |      * @expose
2464 |      */
2465 |     ByteBufferPrototype.clone = function(copy) {
2466 |         var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
2467 |         if (copy) {
2468 |             bb.buffer = new ArrayBuffer(this.buffer.byteLength);
2469 |             bb.view = new Uint8Array(bb.buffer);
2470 |         } else {
2471 |             bb.buffer = this.buffer;
2472 |             bb.view = this.view;
2473 |         }
2474 |         bb.offset = this.offset;
2475 |         bb.markedOffset = this.markedOffset;
2476 |         bb.limit = this.limit;
2477 |         return bb;
2478 |     };
2479 | 
2480 |     /**
2481 |      * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
2482 |      *  between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
2483 |      *  adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
2484 |      * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
2485 |      * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
2486 |      * @returns {!ByteBuffer} this
2487 |      * @expose
2488 |      */
2489 |     ByteBufferPrototype.compact = function(begin, end) {
2490 |         if (typeof begin === 'undefined') begin = this.offset;
2491 |         if (typeof end === 'undefined') end = this.limit;
2492 |         if (!this.noAssert) {
2493 |             if (typeof begin !== 'number' || begin % 1 !== 0)
2494 |                 throw TypeError("Illegal begin: Not an integer");
2495 |             begin >>>= 0;
2496 |             if (typeof end !== 'number' || end % 1 !== 0)
2497 |                 throw TypeError("Illegal end: Not an integer");
2498 |             end >>>= 0;
2499 |             if (begin < 0 || begin > end || end > this.buffer.byteLength)
2500 |                 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
2501 |         }
2502 |         if (begin === 0 && end === this.buffer.byteLength)
2503 |             return this; // Already compacted
2504 |         var len = end - begin;
2505 |         if (len === 0) {
2506 |             this.buffer = EMPTY_BUFFER;
2507 |             this.view = null;
2508 |             if (this.markedOffset >= 0) this.markedOffset -= begin;
2509 |             this.offset = 0;
2510 |             this.limit = 0;
2511 |             return this;
2512 |         }
2513 |         var buffer = new ArrayBuffer(len);
2514 |         var view = new Uint8Array(buffer);
2515 |         view.set(this.view.subarray(begin, end));
2516 |         this.buffer = buffer;
2517 |         this.view = view;
2518 |         if (this.markedOffset >= 0) this.markedOffset -= begin;
2519 |         this.offset = 0;
2520 |         this.limit = len;
2521 |         return this;
2522 |     };
2523 | 
2524 |     /**
2525 |      * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
2526 |      *  {@link ByteBuffer#limit}.
2527 |      * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
2528 |      * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
2529 |      * @returns {!ByteBuffer} Copy
2530 |      * @expose
2531 |      */
2532 |     ByteBufferPrototype.copy = function(begin, end) {
2533 |         if (typeof begin === 'undefined') begin = this.offset;
2534 |         if (typeof end === 'undefined') end = this.limit;
2535 |         if (!this.noAssert) {
2536 |             if (typeof begin !== 'number' || begin % 1 !== 0)
2537 |                 throw TypeError("Illegal begin: Not an integer");
2538 |             begin >>>= 0;
2539 |             if (typeof end !== 'number' || end % 1 !== 0)
2540 |                 throw TypeError("Illegal end: Not an integer");
2541 |             end >>>= 0;
2542 |             if (begin < 0 || begin > end || end > this.buffer.byteLength)
2543 |                 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
2544 |         }
2545 |         if (begin === end)
2546 |             return new ByteBuffer(0, this.littleEndian, this.noAssert);
2547 |         var capacity = end - begin,
2548 |             bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
2549 |         bb.offset = 0;
2550 |         bb.limit = capacity;
2551 |         if (bb.markedOffset >= 0) bb.markedOffset -= begin;
2552 |         this.copyTo(bb, 0, begin, end);
2553 |         return bb;
2554 |     };
2555 | 
2556 |     /**
2557 |      * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
2558 |      *  {@link ByteBuffer#limit}.
2559 |      * @param {!ByteBuffer} target Target ByteBuffer
2560 |      * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
2561 |      *  by the number of bytes copied if omitted.
2562 |      * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
2563 |      *  number of bytes copied if omitted.
2564 |      * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
2565 |      * @returns {!ByteBuffer} this
2566 |      * @expose
2567 |      */
2568 |     ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
2569 |         var relative,
2570 |             targetRelative;
2571 |         if (!this.noAssert) {
2572 |             if (!ByteBuffer.isByteBuffer(target))
2573 |                 throw TypeError("Illegal target: Not a ByteBuffer");
2574 |         }
2575 |         targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
2576 |         sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
2577 |         sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
2578 | 
2579 |         if (targetOffset < 0 || targetOffset > target.buffer.byteLength)
2580 |             throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength);
2581 |         if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength)
2582 |             throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength);
2583 | 
2584 |         var len = sourceLimit - sourceOffset;
2585 |         if (len === 0)
2586 |             return target; // Nothing to copy
2587 | 
2588 |         target.ensureCapacity(targetOffset + len);
2589 | 
2590 |         target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset);
2591 | 
2592 |         if (relative) this.offset += len;
2593 |         if (targetRelative) target.offset += len;
2594 | 
2595 |         return this;
2596 |     };
2597 | 
2598 |     /**
2599 |      * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
2600 |      *  current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
2601 |      *  the required capacity will be used instead.
2602 |      * @param {number} capacity Required capacity
2603 |      * @returns {!ByteBuffer} this
2604 |      * @expose
2605 |      */
2606 |     ByteBufferPrototype.ensureCapacity = function(capacity) {
2607 |         var current = this.buffer.byteLength;
2608 |         if (current < capacity)
2609 |             return this.resize((current *= 2) > capacity ? current : capacity);
2610 |         return this;
2611 |     };
2612 | 
2613 |     /**
2614 |      * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
2615 |      *  {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
2616 |      * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
2617 |      * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2618 |      *  written if omitted. defaults to {@link ByteBuffer#offset}.
2619 |      * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
2620 |      * @returns {!ByteBuffer} this
2621 |      * @expose
2622 |      * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
2623 |      */
2624 |     ByteBufferPrototype.fill = function(value, begin, end) {
2625 |         var relative = typeof begin === 'undefined';
2626 |         if (relative) begin = this.offset;
2627 |         if (typeof value === 'string' && value.length > 0)
2628 |             value = value.charCodeAt(0);
2629 |         if (typeof begin === 'undefined') begin = this.offset;
2630 |         if (typeof end === 'undefined') end = this.limit;
2631 |         if (!this.noAssert) {
2632 |             if (typeof value !== 'number' || value % 1 !== 0)
2633 |                 throw TypeError("Illegal value: "+value+" (not an integer)");
2634 |             value |= 0;
2635 |             if (typeof begin !== 'number' || begin % 1 !== 0)
2636 |                 throw TypeError("Illegal begin: Not an integer");
2637 |             begin >>>= 0;
2638 |             if (typeof end !== 'number' || end % 1 !== 0)
2639 |                 throw TypeError("Illegal end: Not an integer");
2640 |             end >>>= 0;
2641 |             if (begin < 0 || begin > end || end > this.buffer.byteLength)
2642 |                 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
2643 |         }
2644 |         if (begin >= end)
2645 |             return this; // Nothing to fill
2646 |         while (begin < end) this.view[begin++] = value;
2647 |         if (relative) this.offset = begin;
2648 |         return this;
2649 |     };
2650 | 
2651 |     /**
2652 |      * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
2653 |      *  `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
2654 |      * @returns {!ByteBuffer} this
2655 |      * @expose
2656 |      */
2657 |     ByteBufferPrototype.flip = function() {
2658 |         this.limit = this.offset;
2659 |         this.offset = 0;
2660 |         return this;
2661 |     };
2662 |     /**
2663 |      * Marks an offset on this ByteBuffer to be used later.
2664 |      * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
2665 |      * @returns {!ByteBuffer} this
2666 |      * @throws {TypeError} If `offset` is not a valid number
2667 |      * @throws {RangeError} If `offset` is out of bounds
2668 |      * @see ByteBuffer#reset
2669 |      * @expose
2670 |      */
2671 |     ByteBufferPrototype.mark = function(offset) {
2672 |         offset = typeof offset === 'undefined' ? this.offset : offset;
2673 |         if (!this.noAssert) {
2674 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2675 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2676 |             offset >>>= 0;
2677 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
2678 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2679 |         }
2680 |         this.markedOffset = offset;
2681 |         return this;
2682 |     };
2683 |     /**
2684 |      * Sets the byte order.
2685 |      * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
2686 |      * @returns {!ByteBuffer} this
2687 |      * @expose
2688 |      */
2689 |     ByteBufferPrototype.order = function(littleEndian) {
2690 |         if (!this.noAssert) {
2691 |             if (typeof littleEndian !== 'boolean')
2692 |                 throw TypeError("Illegal littleEndian: Not a boolean");
2693 |         }
2694 |         this.littleEndian = !!littleEndian;
2695 |         return this;
2696 |     };
2697 | 
2698 |     /**
2699 |      * Switches (to) little endian byte order.
2700 |      * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
2701 |      * @returns {!ByteBuffer} this
2702 |      * @expose
2703 |      */
2704 |     ByteBufferPrototype.LE = function(littleEndian) {
2705 |         this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
2706 |         return this;
2707 |     };
2708 | 
2709 |     /**
2710 |      * Switches (to) big endian byte order.
2711 |      * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
2712 |      * @returns {!ByteBuffer} this
2713 |      * @expose
2714 |      */
2715 |     ByteBufferPrototype.BE = function(bigEndian) {
2716 |         this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
2717 |         return this;
2718 |     };
2719 |     /**
2720 |      * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
2721 |      *  prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
2722 |      *  will be resized and its contents moved accordingly.
2723 |      * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
2724 |      *  modified according to the performed read operation.
2725 |      * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
2726 |      * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
2727 |      *  prepended if omitted.
2728 |      * @returns {!ByteBuffer} this
2729 |      * @expose
2730 |      * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
2731 |      * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
2732 |      */
2733 |     ByteBufferPrototype.prepend = function(source, encoding, offset) {
2734 |         if (typeof encoding === 'number' || typeof encoding !== 'string') {
2735 |             offset = encoding;
2736 |             encoding = undefined;
2737 |         }
2738 |         var relative = typeof offset === 'undefined';
2739 |         if (relative) offset = this.offset;
2740 |         if (!this.noAssert) {
2741 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2742 |                 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2743 |             offset >>>= 0;
2744 |             if (offset < 0 || offset + 0 > this.buffer.byteLength)
2745 |                 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2746 |         }
2747 |         if (!(source instanceof ByteBuffer))
2748 |             source = ByteBuffer.wrap(source, encoding);
2749 |         var len = source.limit - source.offset;
2750 |         if (len <= 0) return this; // Nothing to prepend
2751 |         var diff = len - offset;
2752 |         if (diff > 0) { // Not enough space before offset, so resize + move
2753 |             var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
2754 |             var view = new Uint8Array(buffer);
2755 |             view.set(this.view.subarray(offset, this.buffer.byteLength), len);
2756 |             this.buffer = buffer;
2757 |             this.view = view;
2758 |             this.offset += diff;
2759 |             if (this.markedOffset >= 0) this.markedOffset += diff;
2760 |             this.limit += diff;
2761 |             offset += diff;
2762 |         } else {
2763 |             var arrayView = new Uint8Array(this.buffer);
2764 |         }
2765 |         this.view.set(source.view.subarray(source.offset, source.limit), offset - len);
2766 | 
2767 |         source.offset = source.limit;
2768 |         if (relative)
2769 |             this.offset -= len;
2770 |         return this;
2771 |     };
2772 | 
2773 |     /**
2774 |      * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
2775 |      *  prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
2776 |      *  will be resized and its contents moved accordingly.
2777 |      * @param {!ByteBuffer} target Target ByteBuffer
2778 |      * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
2779 |      *  prepended if omitted.
2780 |      * @returns {!ByteBuffer} this
2781 |      * @expose
2782 |      * @see ByteBuffer#prepend
2783 |      */
2784 |     ByteBufferPrototype.prependTo = function(target, offset) {
2785 |         target.prepend(this, offset);
2786 |         return this;
2787 |     };
2788 |     /**
2789 |      * Prints debug information about this ByteBuffer's contents.
2790 |      * @param {function(string)=} out Output function to call, defaults to console.log
2791 |      * @expose
2792 |      */
2793 |     ByteBufferPrototype.printDebug = function(out) {
2794 |         if (typeof out !== 'function') out = console.log.bind(console);
2795 |         out(
2796 |             this.toString()+"\n"+
2797 |             "-------------------------------------------------------------------\n"+
2798 |             this.toDebug(/* columns */ true)
2799 |         );
2800 |     };
2801 | 
2802 |     /**
2803 |      * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
2804 |      *  {@link ByteBuffer#limit}, so this returns `limit - offset`.
2805 |      * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
2806 |      * @expose
2807 |      */
2808 |     ByteBufferPrototype.remaining = function() {
2809 |         return this.limit - this.offset;
2810 |     };
2811 |     /**
2812 |      * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
2813 |      *  before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
2814 |      *  marked, sets `offset = 0`.
2815 |      * @returns {!ByteBuffer} this
2816 |      * @see ByteBuffer#mark
2817 |      * @expose
2818 |      */
2819 |     ByteBufferPrototype.reset = function() {
2820 |         if (this.markedOffset >= 0) {
2821 |             this.offset = this.markedOffset;
2822 |             this.markedOffset = -1;
2823 |         } else {
2824 |             this.offset = 0;
2825 |         }
2826 |         return this;
2827 |     };
2828 |     /**
2829 |      * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
2830 |      *  large or larger.
2831 |      * @param {number} capacity Capacity required
2832 |      * @returns {!ByteBuffer} this
2833 |      * @throws {TypeError} If `capacity` is not a number
2834 |      * @throws {RangeError} If `capacity < 0`
2835 |      * @expose
2836 |      */
2837 |     ByteBufferPrototype.resize = function(capacity) {
2838 |         if (!this.noAssert) {
2839 |             if (typeof capacity !== 'number' || capacity % 1 !== 0)
2840 |                 throw TypeError("Illegal capacity: "+capacity+" (not an integer)");
2841 |             capacity |= 0;
2842 |             if (capacity < 0)
2843 |                 throw RangeError("Illegal capacity: 0 <= "+capacity);
2844 |         }
2845 |         if (this.buffer.byteLength < capacity) {
2846 |             var buffer = new ArrayBuffer(capacity);
2847 |             var view = new Uint8Array(buffer);
2848 |             view.set(this.view);
2849 |             this.buffer = buffer;
2850 |             this.view = view;
2851 |         }
2852 |         return this;
2853 |     };
2854 |     /**
2855 |      * Reverses this ByteBuffer's contents.
2856 |      * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
2857 |      * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
2858 |      * @returns {!ByteBuffer} this
2859 |      * @expose
2860 |      */
2861 |     ByteBufferPrototype.reverse = function(begin, end) {
2862 |         if (typeof begin === 'undefined') begin = this.offset;
2863 |         if (typeof end === 'undefined') end = this.limit;
2864 |         if (!this.noAssert) {
2865 |             if (typeof begin !== 'number' || begin % 1 !== 0)
2866 |                 throw TypeError("Illegal begin: Not an integer");
2867 |             begin >>>= 0;
2868 |             if (typeof end !== 'number' || end % 1 !== 0)
2869 |                 throw TypeError("Illegal end: Not an integer");
2870 |             end >>>= 0;
2871 |             if (begin < 0 || begin > end || end > this.buffer.byteLength)
2872 |                 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
2873 |         }
2874 |         if (begin === end)
2875 |             return this; // Nothing to reverse
2876 |         Array.prototype.reverse.call(this.view.subarray(begin, end));
2877 |         return this;
2878 |     };
2879 |     /**
2880 |      * Skips the next `length` bytes. This will just advance
2881 |      * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
2882 |      * @returns {!ByteBuffer} this
2883 |      * @expose
2884 |      */
2885 |     ByteBufferPrototype.skip = function(length) {
2886 |         if (!this.noAssert) {
2887 |             if (typeof length !== 'number' || length % 1 !== 0)
2888 |                 throw TypeError("Illegal length: "+length+" (not an integer)");
2889 |             length |= 0;
2890 |         }
2891 |         var offset = this.offset + length;
2892 |         if (!this.noAssert) {
2893 |             if (offset < 0 || offset > this.buffer.byteLength)
2894 |                 throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength);
2895 |         }
2896 |         this.offset = offset;
2897 |         return this;
2898 |     };
2899 | 
2900 |     /**
2901 |      * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
2902 |      * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
2903 |      * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
2904 |      * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
2905 |      * @expose
2906 |      */
2907 |     ByteBufferPrototype.slice = function(begin, end) {
2908 |         if (typeof begin === 'undefined') begin = this.offset;
2909 |         if (typeof end === 'undefined') end = this.limit;
2910 |         if (!this.noAssert) {
2911 |             if (typeof begin !== 'number' || begin % 1 !== 0)
2912 |                 throw TypeError("Illegal begin: Not an integer");
2913 |             begin >>>= 0;
2914 |             if (typeof end !== 'number' || end % 1 !== 0)
2915 |                 throw TypeError("Illegal end: Not an integer");
2916 |             end >>>= 0;
2917 |             if (begin < 0 || begin > end || end > this.buffer.byteLength)
2918 |                 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
2919 |         }
2920 |         var bb = this.clone();
2921 |         bb.offset = begin;
2922 |         bb.limit = end;
2923 |         return bb;
2924 |     };
2925 |     /**
2926 |      * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
2927 |      *  {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
2928 |      * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
2929 |      *  possible. Defaults to `false`
2930 |      * @returns {!ArrayBuffer} Contents as an ArrayBuffer
2931 |      * @expose
2932 |      */
2933 |     ByteBufferPrototype.toBuffer = function(forceCopy) {
2934 |         var offset = this.offset,
2935 |             limit = this.limit;
2936 |         if (!this.noAssert) {
2937 |             if (typeof offset !== 'number' || offset % 1 !== 0)
2938 |                 throw TypeError("Illegal offset: Not an integer");
2939 |             offset >>>= 0;
2940 |             if (typeof limit !== 'number' || limit % 1 !== 0)
2941 |                 throw TypeError("Illegal limit: Not an integer");
2942 |             limit >>>= 0;
2943 |             if (offset < 0 || offset > limit || limit > this.buffer.byteLength)
2944 |                 throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength);
2945 |         }
2946 |         // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
2947 |         // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
2948 |         if (!forceCopy && offset === 0 && limit === this.buffer.byteLength)
2949 |             return this.buffer;
2950 |         if (offset === limit)
2951 |             return EMPTY_BUFFER;
2952 |         var buffer = new ArrayBuffer(limit - offset);
2953 |         new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
2954 |         return buffer;
2955 |     };
2956 | 
2957 |     /**
2958 |      * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
2959 |      *  {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
2960 |      * @function
2961 |      * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
2962 |      *  Defaults to `false`
2963 |      * @returns {!ArrayBuffer} Contents as an ArrayBuffer
2964 |      * @expose
2965 |      */
2966 |     ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
2967 | 
2968 |     /**
2969 |      * Converts the ByteBuffer's contents to a string.
2970 |      * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
2971 |      *  direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
2972 |      *  highlighted offsets.
2973 |      * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
2974 |      * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
2975 |      * @returns {string} String representation
2976 |      * @throws {Error} If `encoding` is invalid
2977 |      * @expose
2978 |      */
2979 |     ByteBufferPrototype.toString = function(encoding, begin, end) {
2980 |         if (typeof encoding === 'undefined')
2981 |             return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
2982 |         if (typeof encoding === 'number')
2983 |             encoding = "utf8",
2984 |             begin = encoding,
2985 |             end = begin;
2986 |         switch (encoding) {
2987 |             case "utf8":
2988 |                 return this.toUTF8(begin, end);
2989 |             case "base64":
2990 |                 return this.toBase64(begin, end);
2991 |             case "hex":
2992 |                 return this.toHex(begin, end);
2993 |             case "binary":
2994 |                 return this.toBinary(begin, end);
2995 |             case "debug":
2996 |                 return this.toDebug();
2997 |             case "columns":
2998 |                 return this.toColumns();
2999 |             default:
3000 |                 throw Error("Unsupported encoding: "+encoding);
3001 |         }
3002 |     };
3003 | 
3004 |     // lxiv-embeddable
3005 | 
3006 |     /**
3007 |      * lxiv-embeddable (c) 2014 Daniel Wirtz 
3008 |      * Released under the Apache License, Version 2.0
3009 |      * see: https://github.com/dcodeIO/lxiv for details
3010 |      */
3011 |     var lxiv = function() {
3012 |         "use strict";
3013 | 
3014 |         /**
3015 |          * lxiv namespace.
3016 |          * @type {!Object.}
3017 |          * @exports lxiv
3018 |          */
3019 |         var lxiv = {};
3020 | 
3021 |         /**
3022 |          * Character codes for output.
3023 |          * @type {!Array.}
3024 |          * @inner
3025 |          */
3026 |         var aout = [
3027 |             65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
3028 |             81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
3029 |             103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
3030 |             119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
3031 |         ];
3032 | 
3033 |         /**
3034 |          * Character codes for input.
3035 |          * @type {!Array.}
3036 |          * @inner
3037 |          */
3038 |         var ain = [];
3039 |         for (var i=0, k=aout.length; i>2)&0x3f]);
3053 |                 t = (b&0x3)<<4;
3054 |                 if ((b = src()) !== null) {
3055 |                     t |= (b>>4)&0xf;
3056 |                     dst(aout[(t|((b>>4)&0xf))&0x3f]);
3057 |                     t = (b&0xf)<<2;
3058 |                     if ((b = src()) !== null)
3059 |                         dst(aout[(t|((b>>6)&0x3))&0x3f]),
3060 |                         dst(aout[b&0x3f]);
3061 |                     else
3062 |                         dst(aout[t&0x3f]),
3063 |                         dst(61);
3064 |                 } else
3065 |                     dst(aout[t&0x3f]),
3066 |                     dst(61),
3067 |                     dst(61);
3068 |             }
3069 |         };
3070 | 
3071 |         /**
3072 |          * Decodes base64 char codes to bytes.
3073 |          * @param {!function():number|null} src Characters source as a function returning the next char code respectively
3074 |          *  `null` if there are no more characters left.
3075 |          * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
3076 |          * @throws {Error} If a character code is invalid
3077 |          */
3078 |         lxiv.decode = function(src, dst) {
3079 |             var c, t1, t2;
3080 |             function fail(c) {
3081 |                 throw Error("Illegal character code: "+c);
3082 |             }
3083 |             while ((c = src()) !== null) {
3084 |                 t1 = ain[c];
3085 |                 if (typeof t1 === 'undefined') fail(c);
3086 |                 if ((c = src()) !== null) {
3087 |                     t2 = ain[c];
3088 |                     if (typeof t2 === 'undefined') fail(c);
3089 |                     dst((t1<<2)>>>0|(t2&0x30)>>4);
3090 |                     if ((c = src()) !== null) {
3091 |                         t1 = ain[c];
3092 |                         if (typeof t1 === 'undefined')
3093 |                             if (c === 61) break; else fail(c);
3094 |                         dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2);
3095 |                         if ((c = src()) !== null) {
3096 |                             t2 = ain[c];
3097 |                             if (typeof t2 === 'undefined')
3098 |                                 if (c === 61) break; else fail(c);
3099 |                             dst(((t1&0x3)<<6)>>>0|t2);
3100 |                         }
3101 |                     }
3102 |                 }
3103 |             }
3104 |         };
3105 | 
3106 |         /**
3107 |          * Tests if a string is valid base64.
3108 |          * @param {string} str String to test
3109 |          * @returns {boolean} `true` if valid, otherwise `false`
3110 |          */
3111 |         lxiv.test = function(str) {
3112 |             return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str);
3113 |         };
3114 | 
3115 |         return lxiv;
3116 |     }();
3117 | 
3118 |     // encodings/base64
3119 | 
3120 |     /**
3121 |      * Encodes this ByteBuffer's contents to a base64 encoded string.
3122 |      * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}.
3123 |      * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}.
3124 |      * @returns {string} Base64 encoded string
3125 |      * @throws {RangeError} If `begin` or `end` is out of bounds
3126 |      * @expose
3127 |      */
3128 |     ByteBufferPrototype.toBase64 = function(begin, end) {
3129 |         if (typeof begin === 'undefined')
3130 |             begin = this.offset;
3131 |         if (typeof end === 'undefined')
3132 |             end = this.limit;
3133 |         begin = begin | 0; end = end | 0;
3134 |         if (begin < 0 || end > this.capacity || begin > end)
3135 |             throw RangeError("begin, end");
3136 |         var sd; lxiv.encode(function() {
3137 |             return begin < end ? this.view[begin++] : null;
3138 |         }.bind(this), sd = stringDestination());
3139 |         return sd();
3140 |     };
3141 | 
3142 |     /**
3143 |      * Decodes a base64 encoded string to a ByteBuffer.
3144 |      * @param {string} str String to decode
3145 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
3146 |      *  {@link ByteBuffer.DEFAULT_ENDIAN}.
3147 |      * @returns {!ByteBuffer} ByteBuffer
3148 |      * @expose
3149 |      */
3150 |     ByteBuffer.fromBase64 = function(str, littleEndian) {
3151 |         if (typeof str !== 'string')
3152 |             throw TypeError("str");
3153 |         var bb = new ByteBuffer(str.length/4*3, littleEndian),
3154 |             i = 0;
3155 |         lxiv.decode(stringSource(str), function(b) {
3156 |             bb.view[i++] = b;
3157 |         });
3158 |         bb.limit = i;
3159 |         return bb;
3160 |     };
3161 | 
3162 |     /**
3163 |      * Encodes a binary string to base64 like `window.btoa` does.
3164 |      * @param {string} str Binary string
3165 |      * @returns {string} Base64 encoded string
3166 |      * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
3167 |      * @expose
3168 |      */
3169 |     ByteBuffer.btoa = function(str) {
3170 |         return ByteBuffer.fromBinary(str).toBase64();
3171 |     };
3172 | 
3173 |     /**
3174 |      * Decodes a base64 encoded string to binary like `window.atob` does.
3175 |      * @param {string} b64 Base64 encoded string
3176 |      * @returns {string} Binary string
3177 |      * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
3178 |      * @expose
3179 |      */
3180 |     ByteBuffer.atob = function(b64) {
3181 |         return ByteBuffer.fromBase64(b64).toBinary();
3182 |     };
3183 | 
3184 |     // encodings/binary
3185 | 
3186 |     /**
3187 |      * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes.
3188 |      * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
3189 |      * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
3190 |      * @returns {string} Binary encoded string
3191 |      * @throws {RangeError} If `offset > limit`
3192 |      * @expose
3193 |      */
3194 |     ByteBufferPrototype.toBinary = function(begin, end) {
3195 |         if (typeof begin === 'undefined')
3196 |             begin = this.offset;
3197 |         if (typeof end === 'undefined')
3198 |             end = this.limit;
3199 |         begin |= 0; end |= 0;
3200 |         if (begin < 0 || end > this.capacity() || begin > end)
3201 |             throw RangeError("begin, end");
3202 |         if (begin === end)
3203 |             return "";
3204 |         var chars = [],
3205 |             parts = [];
3206 |         while (begin < end) {
3207 |             chars.push(this.view[begin++]);
3208 |             if (chars.length >= 1024)
3209 |                 parts.push(String.fromCharCode.apply(String, chars)),
3210 |                 chars = [];
3211 |         }
3212 |         return parts.join('') + String.fromCharCode.apply(String, chars);
3213 |     };
3214 | 
3215 |     /**
3216 |      * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer.
3217 |      * @param {string} str String to decode
3218 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
3219 |      *  {@link ByteBuffer.DEFAULT_ENDIAN}.
3220 |      * @returns {!ByteBuffer} ByteBuffer
3221 |      * @expose
3222 |      */
3223 |     ByteBuffer.fromBinary = function(str, littleEndian) {
3224 |         if (typeof str !== 'string')
3225 |             throw TypeError("str");
3226 |         var i = 0,
3227 |             k = str.length,
3228 |             charCode,
3229 |             bb = new ByteBuffer(k, littleEndian);
3230 |         while (i 0xff)
3233 |                 throw RangeError("illegal char code: "+charCode);
3234 |             bb.view[i++] = charCode;
3235 |         }
3236 |         bb.limit = k;
3237 |         return bb;
3238 |     };
3239 | 
3240 |     // encodings/debug
3241 | 
3242 |     /**
3243 |      * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are:
3244 |      * * `<` : offset,
3245 |      * * `'` : markedOffset,
3246 |      * * `>` : limit,
3247 |      * * `|` : offset and limit,
3248 |      * * `[` : offset and markedOffset,
3249 |      * * `]` : markedOffset and limit,
3250 |      * * `!` : offset, markedOffset and limit
3251 |      * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false`
3252 |      * @returns {string|!Array.} Debug string or array of lines if `asArray = true`
3253 |      * @expose
3254 |      * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3`
3255 |      * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4`
3256 |      * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1`
3257 |      * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1`
3258 |      */
3259 |     ByteBufferPrototype.toDebug = function(columns) {
3260 |         var i = -1,
3261 |             k = this.buffer.byteLength,
3262 |             b,
3263 |             hex = "",
3264 |             asc = "",
3265 |             out = "";
3266 |         while (i 32 && b < 127 ? String.fromCharCode(b) : '.';
3273 |             }
3274 |             ++i;
3275 |             if (columns) {
3276 |                 if (i > 0 && i % 16 === 0 && i !== k) {
3277 |                     while (hex.length < 3*16+3) hex += " ";
3278 |                     out += hex+asc+"\n";
3279 |                     hex = asc = "";
3280 |                 }
3281 |             }
3282 |             if (i === this.offset && i === this.limit)
3283 |                 hex += i === this.markedOffset ? "!" : "|";
3284 |             else if (i === this.offset)
3285 |                 hex += i === this.markedOffset ? "[" : "<";
3286 |             else if (i === this.limit)
3287 |                 hex += i === this.markedOffset ? "]" : ">";
3288 |             else
3289 |                 hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : "");
3290 |         }
3291 |         if (columns && hex !== " ") {
3292 |             while (hex.length < 3*16+3)
3293 |                 hex += " ";
3294 |             out += hex + asc + "\n";
3295 |         }
3296 |         return columns ? out : hex;
3297 |     };
3298 | 
3299 |     /**
3300 |      * Decodes a hex encoded string with marked offsets to a ByteBuffer.
3301 |      * @param {string} str Debug string to decode (not be generated with `columns = true`)
3302 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
3303 |      *  {@link ByteBuffer.DEFAULT_ENDIAN}.
3304 |      * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
3305 |      *  {@link ByteBuffer.DEFAULT_NOASSERT}.
3306 |      * @returns {!ByteBuffer} ByteBuffer
3307 |      * @expose
3308 |      * @see ByteBuffer#toDebug
3309 |      */
3310 |     ByteBuffer.fromDebug = function(str, littleEndian, noAssert) {
3311 |         var k = str.length,
3312 |             bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert);
3313 |         var i = 0, j = 0, ch, b,
3314 |             rs = false, // Require symbol next
3315 |             ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)?
3316 |             fail = false;
3317 |         while (i':
3375 |                     if (!noAssert) {
3376 |                         if (hl) {
3377 |                             fail = true;
3378 |                             break;
3379 |                         }
3380 |                         hl = true;
3381 |                     }
3382 |                     bb.limit = j;
3383 |                     rs = false;
3384 |                     break;
3385 |                 case "'":
3386 |                     if (!noAssert) {
3387 |                         if (hm) {
3388 |                             fail = true;
3389 |                             break;
3390 |                         }
3391 |                         hm = true;
3392 |                     }
3393 |                     bb.markedOffset = j;
3394 |                     rs = false;
3395 |                     break;
3396 |                 case ' ':
3397 |                     rs = false;
3398 |                     break;
3399 |                 default:
3400 |                     if (!noAssert) {
3401 |                         if (rs) {
3402 |                             fail = true;
3403 |                             break;
3404 |                         }
3405 |                     }
3406 |                     b = parseInt(ch+str.charAt(i++), 16);
3407 |                     if (!noAssert) {
3408 |                         if (isNaN(b) || b < 0 || b > 255)
3409 |                             throw TypeError("Illegal str: Not a debug encoded string");
3410 |                     }
3411 |                     bb.view[j++] = b;
3412 |                     rs = true;
3413 |             }
3414 |             if (fail)
3415 |                 throw TypeError("Illegal str: Invalid symbol at "+i);
3416 |         }
3417 |         if (!noAssert) {
3418 |             if (!ho || !hl)
3419 |                 throw TypeError("Illegal str: Missing offset or limit");
3420 |             if (j>>= 0;
3442 |             if (typeof end !== 'number' || end % 1 !== 0)
3443 |                 throw TypeError("Illegal end: Not an integer");
3444 |             end >>>= 0;
3445 |             if (begin < 0 || begin > end || end > this.buffer.byteLength)
3446 |                 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
3447 |         }
3448 |         var out = new Array(end - begin),
3449 |             b;
3450 |         while (begin < end) {
3451 |             b = this.view[begin++];
3452 |             if (b < 0x10)
3453 |                 out.push("0", b.toString(16));
3454 |             else out.push(b.toString(16));
3455 |         }
3456 |         return out.join('');
3457 |     };
3458 | 
3459 |     /**
3460 |      * Decodes a hex encoded string to a ByteBuffer.
3461 |      * @param {string} str String to decode
3462 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
3463 |      *  {@link ByteBuffer.DEFAULT_ENDIAN}.
3464 |      * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
3465 |      *  {@link ByteBuffer.DEFAULT_NOASSERT}.
3466 |      * @returns {!ByteBuffer} ByteBuffer
3467 |      * @expose
3468 |      */
3469 |     ByteBuffer.fromHex = function(str, littleEndian, noAssert) {
3470 |         if (!noAssert) {
3471 |             if (typeof str !== 'string')
3472 |                 throw TypeError("Illegal str: Not a string");
3473 |             if (str.length % 2 !== 0)
3474 |                 throw TypeError("Illegal str: Length not a multiple of 2");
3475 |         }
3476 |         var k = str.length,
3477 |             bb = new ByteBuffer((k / 2) | 0, littleEndian),
3478 |             b;
3479 |         for (var i=0, j=0; i 255)
3483 |                     throw TypeError("Illegal str: Contains non-hex characters");
3484 |             bb.view[j++] = b;
3485 |         }
3486 |         bb.limit = j;
3487 |         return bb;
3488 |     };
3489 | 
3490 |     // utfx-embeddable
3491 | 
3492 |     /**
3493 |      * utfx-embeddable (c) 2014 Daniel Wirtz 
3494 |      * Released under the Apache License, Version 2.0
3495 |      * see: https://github.com/dcodeIO/utfx for details
3496 |      */
3497 |     var utfx = function() {
3498 |         "use strict";
3499 | 
3500 |         /**
3501 |          * utfx namespace.
3502 |          * @inner
3503 |          * @type {!Object.}
3504 |          */
3505 |         var utfx = {};
3506 | 
3507 |         /**
3508 |          * Maximum valid code point.
3509 |          * @type {number}
3510 |          * @const
3511 |          */
3512 |         utfx.MAX_CODEPOINT = 0x10FFFF;
3513 | 
3514 |         /**
3515 |          * Encodes UTF8 code points to UTF8 bytes.
3516 |          * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
3517 |          *  respectively `null` if there are no more code points left or a single numeric code point.
3518 |          * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
3519 |          */
3520 |         utfx.encodeUTF8 = function(src, dst) {
3521 |             var cp = null;
3522 |             if (typeof src === 'number')
3523 |                 cp = src,
3524 |                 src = function() { return null; };
3525 |             while (cp !== null || (cp = src()) !== null) {
3526 |                 if (cp < 0x80)
3527 |                     dst(cp&0x7F);
3528 |                 else if (cp < 0x800)
3529 |                     dst(((cp>>6)&0x1F)|0xC0),
3530 |                     dst((cp&0x3F)|0x80);
3531 |                 else if (cp < 0x10000)
3532 |                     dst(((cp>>12)&0x0F)|0xE0),
3533 |                     dst(((cp>>6)&0x3F)|0x80),
3534 |                     dst((cp&0x3F)|0x80);
3535 |                 else
3536 |                     dst(((cp>>18)&0x07)|0xF0),
3537 |                     dst(((cp>>12)&0x3F)|0x80),
3538 |                     dst(((cp>>6)&0x3F)|0x80),
3539 |                     dst((cp&0x3F)|0x80);
3540 |                 cp = null;
3541 |             }
3542 |         };
3543 | 
3544 |         /**
3545 |          * Decodes UTF8 bytes to UTF8 code points.
3546 |          * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
3547 |          *  are no more bytes left.
3548 |          * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
3549 |          * @throws {RangeError} If a starting byte is invalid in UTF8
3550 |          * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
3551 |          *  remaining bytes.
3552 |          */
3553 |         utfx.decodeUTF8 = function(src, dst) {
3554 |             var a, b, c, d, fail = function(b) {
3555 |                 b = b.slice(0, b.indexOf(null));
3556 |                 var err = Error(b.toString());
3557 |                 err.name = "TruncatedError";
3558 |                 err['bytes'] = b;
3559 |                 throw err;
3560 |             };
3561 |             while ((a = src()) !== null) {
3562 |                 if ((a&0x80) === 0)
3563 |                     dst(a);
3564 |                 else if ((a&0xE0) === 0xC0)
3565 |                     ((b = src()) === null) && fail([a, b]),
3566 |                     dst(((a&0x1F)<<6) | (b&0x3F));
3567 |                 else if ((a&0xF0) === 0xE0)
3568 |                     ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
3569 |                     dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
3570 |                 else if ((a&0xF8) === 0xF0)
3571 |                     ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
3572 |                     dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
3573 |                 else throw RangeError("Illegal starting byte: "+a);
3574 |             }
3575 |         };
3576 | 
3577 |         /**
3578 |          * Converts UTF16 characters to UTF8 code points.
3579 |          * @param {!function():number|null} src Characters source as a function returning the next char code respectively
3580 |          *  `null` if there are no more characters left.
3581 |          * @param {!function(number)} dst Code points destination as a function successively called with each converted code
3582 |          *  point.
3583 |          */
3584 |         utfx.UTF16toUTF8 = function(src, dst) {
3585 |             var c1, c2 = null;
3586 |             while (true) {
3587 |                 if ((c1 = c2 !== null ? c2 : src()) === null)
3588 |                     break;
3589 |                 if (c1 >= 0xD800 && c1 <= 0xDFFF) {
3590 |                     if ((c2 = src()) !== null) {
3591 |                         if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
3592 |                             dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
3593 |                             c2 = null; continue;
3594 |                         }
3595 |                     }
3596 |                 }
3597 |                 dst(c1);
3598 |             }
3599 |             if (c2 !== null) dst(c2);
3600 |         };
3601 | 
3602 |         /**
3603 |          * Converts UTF8 code points to UTF16 characters.
3604 |          * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
3605 |          *  respectively `null` if there are no more code points left or a single numeric code point.
3606 |          * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
3607 |          * @throws {RangeError} If a code point is out of range
3608 |          */
3609 |         utfx.UTF8toUTF16 = function(src, dst) {
3610 |             var cp = null;
3611 |             if (typeof src === 'number')
3612 |                 cp = src, src = function() { return null; };
3613 |             while (cp !== null || (cp = src()) !== null) {
3614 |                 if (cp <= 0xFFFF)
3615 |                     dst(cp);
3616 |                 else
3617 |                     cp -= 0x10000,
3618 |                     dst((cp>>10)+0xD800),
3619 |                     dst((cp%0x400)+0xDC00);
3620 |                 cp = null;
3621 |             }
3622 |         };
3623 | 
3624 |         /**
3625 |          * Converts and encodes UTF16 characters to UTF8 bytes.
3626 |          * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
3627 |          *  if there are no more characters left.
3628 |          * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
3629 |          */
3630 |         utfx.encodeUTF16toUTF8 = function(src, dst) {
3631 |             utfx.UTF16toUTF8(src, function(cp) {
3632 |                 utfx.encodeUTF8(cp, dst);
3633 |             });
3634 |         };
3635 | 
3636 |         /**
3637 |          * Decodes and converts UTF8 bytes to UTF16 characters.
3638 |          * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
3639 |          *  are no more bytes left.
3640 |          * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
3641 |          * @throws {RangeError} If a starting byte is invalid in UTF8
3642 |          * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
3643 |          */
3644 |         utfx.decodeUTF8toUTF16 = function(src, dst) {
3645 |             utfx.decodeUTF8(src, function(cp) {
3646 |                 utfx.UTF8toUTF16(cp, dst);
3647 |             });
3648 |         };
3649 | 
3650 |         /**
3651 |          * Calculates the byte length of an UTF8 code point.
3652 |          * @param {number} cp UTF8 code point
3653 |          * @returns {number} Byte length
3654 |          */
3655 |         utfx.calculateCodePoint = function(cp) {
3656 |             return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
3657 |         };
3658 | 
3659 |         /**
3660 |          * Calculates the number of UTF8 bytes required to store UTF8 code points.
3661 |          * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
3662 |          *  `null` if there are no more code points left.
3663 |          * @returns {number} The number of UTF8 bytes required
3664 |          */
3665 |         utfx.calculateUTF8 = function(src) {
3666 |             var cp, l=0;
3667 |             while ((cp = src()) !== null)
3668 |                 l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
3669 |             return l;
3670 |         };
3671 | 
3672 |         /**
3673 |          * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
3674 |          * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
3675 |          *  `null` if there are no more characters left.
3676 |          * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
3677 |          */
3678 |         utfx.calculateUTF16asUTF8 = function(src) {
3679 |             var n=0, l=0;
3680 |             utfx.UTF16toUTF8(src, function(cp) {
3681 |                 ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
3682 |             });
3683 |             return [n,l];
3684 |         };
3685 | 
3686 |         return utfx;
3687 |     }();
3688 | 
3689 |     // encodings/utf8
3690 | 
3691 |     /**
3692 |      * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded
3693 |      *  string.
3694 |      * @returns {string} Hex encoded string
3695 |      * @throws {RangeError} If `offset > limit`
3696 |      * @expose
3697 |      */
3698 |     ByteBufferPrototype.toUTF8 = function(begin, end) {
3699 |         if (typeof begin === 'undefined') begin = this.offset;
3700 |         if (typeof end === 'undefined') end = this.limit;
3701 |         if (!this.noAssert) {
3702 |             if (typeof begin !== 'number' || begin % 1 !== 0)
3703 |                 throw TypeError("Illegal begin: Not an integer");
3704 |             begin >>>= 0;
3705 |             if (typeof end !== 'number' || end % 1 !== 0)
3706 |                 throw TypeError("Illegal end: Not an integer");
3707 |             end >>>= 0;
3708 |             if (begin < 0 || begin > end || end > this.buffer.byteLength)
3709 |                 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
3710 |         }
3711 |         var sd; try {
3712 |             utfx.decodeUTF8toUTF16(function() {
3713 |                 return begin < end ? this.view[begin++] : null;
3714 |             }.bind(this), sd = stringDestination());
3715 |         } catch (e) {
3716 |             if (begin !== end)
3717 |                 throw RangeError("Illegal range: Truncated data, "+begin+" != "+end);
3718 |         }
3719 |         return sd();
3720 |     };
3721 | 
3722 |     /**
3723 |      * Decodes an UTF8 encoded string to a ByteBuffer.
3724 |      * @param {string} str String to decode
3725 |      * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
3726 |      *  {@link ByteBuffer.DEFAULT_ENDIAN}.
3727 |      * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
3728 |      *  {@link ByteBuffer.DEFAULT_NOASSERT}.
3729 |      * @returns {!ByteBuffer} ByteBuffer
3730 |      * @expose
3731 |      */
3732 |     ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) {
3733 |         if (!noAssert)
3734 |             if (typeof str !== 'string')
3735 |                 throw TypeError("Illegal str: Not a string");
3736 |         var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert),
3737 |             i = 0;
3738 |         utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3739 |             bb.view[i++] = b;
3740 |         });
3741 |         bb.limit = i;
3742 |         return bb;
3743 |     };
3744 | 
3745 |     return ByteBuffer;
3746 | });
3747 | 


--------------------------------------------------------------------------------