diff --git a/.gitignore b/.gitignore index c4d159d2..9ada4fd9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ CMakeCache.txt CMakeFiles Makefile compile_commands.json +moc_* +*.moc libraries/utilities/git_revision.cpp diff --git a/README.md b/README.md index 53f74942..fa374b92 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Witness node The role of the witness node is to broadcast transactions, download blocks, and optionally sign them. ``` -./witness_node --rpc-endpoint "127.0.0.1:8090" --enable-stale-production -w \""1.6.0"\" \""1.6.1"\" \""1.6.2"\" \""1.6.3"\" \""1.6.4"\" +./witness_node --rpc-endpoint 127.0.0.1:8090 --enable-stale-production -w '"1.6.0"' '"1.6.1"' '"1.6.2"' '"1.6.3"' '"1.6.4"' '"1.6.5"' '"1.6.6"' '"1.6.7"' '"1.6.8"' '"1.6.9"' '"1.6.10"' '"1.6.11"' '"1.6.12"' '"1.6.13"' '"1.6.14"' '"1.6.15"' '"1.6.16"' '"1.6.17"' '"1.6.18"' '"1.6.19"' '"1.6.20"' '"1.6.21"' '"1.6.22"' '"1.6.23"' '"1.6.24"' '"1.6.25"' '"1.6.26"' '"1.6.27"' '"1.6.28"' '"1.6.29"' '"1.6.30"' '"1.6.31"' '"1.6.32"' '"1.6.33"' '"1.6.34"' '"1.6.35"' '"1.6.36"' '"1.6.37"' '"1.6.38"' '"1.6.39"' '"1.6.40"' '"1.6.41"' '"1.6.42"' '"1.6.43"' '"1.6.44"' '"1.6.45"' '"1.6.46"' '"1.6.47"' '"1.6.48"' '"1.6.49"' '"1.6.50"' '"1.6.51"' '"1.6.52"' '"1.6.53"' '"1.6.54"' '"1.6.55"' '"1.6.56"' '"1.6.57"' '"1.6.58"' '"1.6.59"' '"1.6.60"' '"1.6.61"' '"1.6.62"' '"1.6.63"' '"1.6.64"' '"1.6.65"' '"1.6.66"' '"1.6.67"' '"1.6.68"' '"1.6.69"' '"1.6.70"' '"1.6.71"' '"1.6.72"' '"1.6.73"' '"1.6.74"' '"1.6.75"' '"1.6.76"' '"1.6.77"' '"1.6.78"' '"1.6.79"' '"1.6.80"' '"1.6.81"' '"1.6.82"' '"1.6.83"' '"1.6.84"' '"1.6.85"' '"1.6.86"' '"1.6.87"' '"1.6.88"' '"1.6.89"' '"1.6.90"' '"1.6.91"' '"1.6.92"' '"1.6.93"' '"1.6.94"' '"1.6.95"' '"1.6.96"' '"1.6.97"' '"1.6.98"' '"1.6.99"' '"1.6.100"' ``` Running specific tests @@ -99,20 +99,17 @@ When running `witness_node`, initially two API's are available: API 0 provides read-only access to the database, while API 1 is used to login and gain access to additional, restricted API's. -TODO: the following examples use the old authority definition and thus do not work. They need to be updated. - Here is an example using `wscat` package from `npm` for websockets: $ npm install -g wscat $ wscat -c ws://127.0.0.1:8090 > {"id":1, "method":"call", "params":[0,"get_accounts",[["1.2.0"]]]} - < {"id":1,"result":[{"id":"1.2.0","annotations":[],"registrar":"1.2.0","referrer":"1.2.0","referrer_percent":0,"name":"genesis","owner":{"weight_threshold":1,"key_auths":[["PUBLIC_KEY",1]]},"active":{"weight_threshold":1,"key_auths":[["PUBLIC_KEY",1]]},"memo_key":"PUBLIC_KEY","voting_account":"1.2.0","num_witness":0,"num_committee":0,"votes":[],"statistics":"2.7.0","whitelisting_accounts":[],"blacklisting_accounts":[]}]} - $ + < {"id":1,"result":[{"id":"1.2.0","annotations":[],"membership_expiration_date":"1969-12-31T23:59:59","registrar":"1.2.0","referrer":"1.2.0","lifetime_referrer":"1.2.0","network_fee_percentage":2000,"lifetime_referrer_fee_percentage":8000,"referrer_rewards_percentage":0,"name":"committee-account","owner":{"weight_threshold":1,"account_auths":[],"key_auths":[],"address_auths":[]},"active":{"weight_threshold":6,"account_auths":[["1.2.5",1],["1.2.6",1],["1.2.7",1],["1.2.8",1],["1.2.9",1],["1.2.10",1],["1.2.11",1],["1.2.12",1],["1.2.13",1],["1.2.14",1]],"key_auths":[],"address_auths":[]},"options":{"memo_key":"GPH1111111111111111111111111111111114T1Anm","voting_account":"1.2.0","num_witness":0,"num_committee":0,"votes":[],"extensions":[]},"statistics":"2.7.0","whitelisting_accounts":[],"blacklisting_accounts":[]}]} We can do the same thing using an HTTP client such as `curl` for API's which do not require login or other session state: $ curl --data '{"jsonrpc": "2.0", "method": "call", "params": [0, "get_accounts", [["1.2.0"]]], "id": 1}' http://127.0.0.1:8090/rpc - {"id":1,"result":[{"id":"1.2.0","annotations":[],"registrar":"1.2.0","referrer":"1.2.0","referrer_percent":0,"name":"genesis","owner":{"weight_threshold":1,"key_auths":[["PUBLIC_KEY",1]]},"active":{"weight_threshold":1,"key_auths":[["PUBLIC_KEY",1]]},"memo_key":"PUBLIC_KEY","voting_account":"1.2.0","num_witness":0,"num_committee":0,"votes":[],"statistics":"2.7.0","whitelisting_accounts":[],"blacklisting_accounts":[]}]} + {"id":1,"result":[{"id":"1.2.0","annotations":[],"membership_expiration_date":"1969-12-31T23:59:59","registrar":"1.2.0","referrer":"1.2.0","lifetime_referrer":"1.2.0","network_fee_percentage":2000,"lifetime_referrer_fee_percentage":8000,"referrer_rewards_percentage":0,"name":"committee-account","owner":{"weight_threshold":1,"account_auths":[],"key_auths":[],"address_auths":[]},"active":{"weight_threshold":6,"account_auths":[["1.2.5",1],["1.2.6",1],["1.2.7",1],["1.2.8",1],["1.2.9",1],["1.2.10",1],["1.2.11",1],["1.2.12",1],["1.2.13",1],["1.2.14",1]],"key_auths":[],"address_auths":[]},"options":{"memo_key":"GPH1111111111111111111111111111111114T1Anm","voting_account":"1.2.0","num_witness":0,"num_committee":0,"votes":[],"extensions":[]},"statistics":"2.7.0","whitelisting_accounts":[],"blacklisting_accounts":[]}]} API 0 is accessible using regular JSON-RPC: @@ -122,7 +119,8 @@ Accessing restricted API's -------------------------- You can restrict API's to particular users by specifying an `apiaccess` file in `config.ini`. Here is an example `apiaccess` file which allows -user `bytemaster` with password `supersecret` to access four different API's: +user `bytemaster` with password `supersecret` to access four different API's, while allowing any other user to access the three public API's +necessary to use the wallet: { "permission_map" : @@ -134,6 +132,14 @@ user `bytemaster` with password `supersecret` to access four different API's: "password_salt_b64" : "INDdM6iCi/8=", "allowed_apis" : ["database_api", "network_broadcast_api", "history_api", "network_node_api"] } + ], + [ + "*", + { + "password_hash_b64" : "*", + "password_salt_b64" : "*", + "allowed_apis" : ["database_api", "network_broadcast_api", "history_api"] + } ] ] } @@ -159,29 +165,7 @@ it is fairly simple to write API methods to expose database methods. Running private testnet ----------------------- -Normally `witness_node` assumes it won't be producing blocks from -genesis, or against very old chain state. We need to get `witness_node` -to discard this assumption if we actually want to start a new chain, -so we will need to specify in `config.ini`: - - enable-stale-production = true - -We also need to specify which witnesses will produce blocks locally; -`witness_node` does not assume that it should produce blocks for a given -witness just because it has the correct private key to do so. There are -ten witnesses at genesis of the testnet, block production can be -enabled for all of them by specifying multiple times in `config.ini`: - - witness-id = "1.6.0" - witness-id = "1.6.1" - witness-id = "1.6.2" - witness-id = "1.6.3" - witness-id = "1.6.4" - witness-id = "1.6.5" - witness-id = "1.6.6" - witness-id = "1.6.7" - witness-id = "1.6.8" - witness-id = "1.6.9" +See the [documentation](https://github.com/cryptonomex/graphene/wiki/private-testnet) if you want to run a private testnet. Questions --------- @@ -223,7 +207,7 @@ Questions The second number specifies the *type*. The type of the object determines what fields it has. For a complete list of type ID's, see `enum object_type` and `enum impl_object_type` in - [types.hpp](https://github.com/cryptonomex/graphene/blob/master/libraries/chain/include/graphene/chain/types.hpp). + [types.hpp](https://github.com/cryptonomex/graphene/blob/master/libraries/chain/include/graphene/chain/protocol/types.hpp). The third number specifies the *instance*. The instance of the object is different for each individual object. @@ -240,3 +224,16 @@ Questions The first and second number together identify the kind of thing you're talking about (`1.2` for accounts, `1.3` for assets). The third number identifies the particular thing. + +- How do I get the `network_add_nodes` command to work? Why is it so complicated? + + You need to follow the instructions in the "Accessing restricted API's" section to + allow a username/password access to the `network_node` API. Then you need + to pass the username/password to the `cli_wallet` on the command line or in a config file. + + It's set up this way so that the default configuration is secure even if the RPC port is + publicly accessible. It's fine if your `witness_node` allows the general public to query + the database or broadcast transactions (in fact, this is how the hosted web UI works). It's + less fine if your `witness_node` allows the general public to control which p2p nodes it's + connecting to. Therefore the API to add p2p connections needs to be set up with proper access + controls. diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000..a47c45c0 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,112 @@ +# Configures Ubuntu 14.04 VM to be used with BitShares 2.0 (Graphene) +# Downloads and builds all necessary software to run witness node and web GUI +# Use with Vagrant (http://docs.vagrantup.com/v2/getting-started/index.html) +# or just execute the shell script below. +# Vagrant setup supports the following providers: Virtual Box, Digital Ocean, Amazon EC2 + +$script = < + + + diff --git a/programs/full_web_node/web/vendors.js b/programs/full_web_node/web/vendors.js new file mode 100644 index 00000000..879f4571 --- /dev/null +++ b/programs/full_web_node/web/vendors.js @@ -0,0 +1,80 @@ +!function(e){function t(n){if(r[n])return r[n].exports;var a=r[n]={exports:{},id:n,loaded:!1};return e[n].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n=window.webpackJsonp;window.webpackJsonp=function(o,i){for(var s,l,u=0,c=[];u1)for(var n=1;n-1?t:e}function u(e,t){if(t=t||{},this.url=e,this.credentials=t.credentials||"omit",this.headers=new n(t.headers),this.method=l(t.method||"GET"),this.mode=t.mode||null,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&t.body)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(t.body)}function c(e){var t=new FormData;return e.trim().split("&").forEach(function(e){if(e){var n=e.split("="),r=n.shift().replace(/\+/g," "),a=n.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(a))}}),t}function d(e){var t=new n,r=e.getAllResponseHeaders().trim().split("\n");return r.forEach(function(e){var n=e.trim().split(":"),r=n.shift().trim(),a=n.join(":").trim();t.append(r,a)}),t}function p(e,t){t||(t={}),this._initBody(e),this.type="default",this.url=null,this.status=t.status,this.ok=this.status>=200&&this.status<300,this.statusText=t.statusText,this.headers=t.headers instanceof n?t.headers:new n(t.headers),this.url=t.url||""}if(!self.fetch){n.prototype.append=function(n,r){n=e(n),r=t(r);var a=this.map[n];a||(a=[],this.map[n]=a),a.push(r)},n.prototype["delete"]=function(t){delete this.map[e(t)]},n.prototype.get=function(t){var n=this.map[e(t)];return n?n[0]:null},n.prototype.getAll=function(t){return this.map[e(t)]||[]},n.prototype.has=function(t){return this.map.hasOwnProperty(e(t))},n.prototype.set=function(n,r){this.map[e(n)]=[t(r)]},n.prototype.forEach=function(e,t){Object.getOwnPropertyNames(this.map).forEach(function(n){this.map[n].forEach(function(r){e.call(t,r,n,this)},this)},this)};var f={blob:"FileReader"in self&&"Blob"in self&&function(){try{return new Blob,!0}catch(e){return!1}}(),formData:"FormData"in self},h=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];s.call(u.prototype),s.call(p.prototype),self.Headers=n,self.Request=u,self.Response=p,self.fetch=function(e,t){var n;return n=u.prototype.isPrototypeOf(e)&&!t?e:new u(e,t),new Promise(function(e,t){function r(){return"responseURL"in a?a.responseURL:/^X-Request-URL:/m.test(a.getAllResponseHeaders())?a.getResponseHeader("X-Request-URL"):void 0}var a=new XMLHttpRequest;a.onload=function(){var n=1223===a.status?204:a.status;if(100>n||n>599)return void t(new TypeError("Network request failed"));var o={status:n,statusText:a.statusText,headers:d(a),url:r()},i="response"in a?a.response:a.responseText;e(new p(i,o))},a.onerror=function(){t(new TypeError("Network request failed"))},a.open(n.method,n.url,!0),"include"===n.credentials&&(a.withCredentials=!0),"responseType"in a&&f.blob&&(a.responseType="blob"),n.headers.forEach(function(e,t){a.setRequestHeader(t,e)}),a.send("undefined"==typeof n._bodyInit?null:n._bodyInit)})},self.fetch.polyfill=!0}}()},,,,,,,,,,,,,,,,,,,,function(e,t,n){e.exports=n(197)},function(e,t,n){(function(t){"use strict";var r=n(198),a=n(202),o=n(216),i=n(231),s=n(206),l=n(211),u=n(205),c=n(226),d=n(234),p=n(236),f=n(285),h=n(213),m=n(261),g=n(222),y=n(316),b=n(223),v=n(348),_=n(207),w=n(305),k=n(350);f.inject();var E=u.createElement,x=u.createFactory,O=u.cloneElement;"production"!==t.env.NODE_ENV&&(E=c.createElement,x=c.createFactory,O=c.cloneElement);var S=g.measure("React","render",m.render),P={Children:{map:a.map,forEach:a.forEach,count:a.count,only:k},Component:o,DOM:d,PropTypes:y,initializeTouchEvents:function(e){r.useTouchEvents=e},createClass:i.createClass,createElement:E,cloneElement:O,createFactory:x,createMixin:function(e){return e},constructAndRenderComponent:m.constructAndRenderComponent,constructAndRenderComponentByID:m.constructAndRenderComponentByID,findDOMNode:w,render:S,renderToString:v.renderToString,renderToStaticMarkup:v.renderToStaticMarkup,unmountComponentAtNode:m.unmountComponentAtNode,isValidElement:u.isValidElement,withContext:s.withContext,__spread:_};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject&&__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({CurrentOwner:l,InstanceHandles:h,Mount:m,Reconciler:b,TextComponent:p}),"production"!==t.env.NODE_ENV){var A=n(245);if(A.canUseDOM&&window.top===window.self){navigator.userAgent.indexOf("Chrome")>-1&&"undefined"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&console.debug("Download the React DevTools for a better development experience: https://fb.me/react-devtools");for(var j=[Array.isArray,Array.prototype.every,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.map,Date.now,Function.prototype.bind,Object.keys,String.prototype.split,String.prototype.trim,Object.create,Object.freeze],C=0;C1){for(var p=Array(c),f=0;c>f;f++)p[f]=arguments[f+2];a.children=p}if(e&&e.defaultProps){var h=e.defaultProps;for(r in h)"undefined"==typeof a[r]&&(a[r]=h[r])}return new d(e,s,l,i.current,o.current,a)},d.createFactory=function(e){var t=d.createElement.bind(null,e);return t.type=e,t},d.cloneAndReplaceProps=function(e,n){var r=new d(e.type,e.key,e.ref,e._owner,e._context,n);return"production"!==t.env.NODE_ENV&&(r._store.validated=e._store.validated),r},d.cloneElement=function(e,t,n){var r,a=s({},e.props),o=e.key,l=e.ref,c=e._owner;if(null!=t){void 0!==t.ref&&(l=t.ref,c=i.current),void 0!==t.key&&(o=""+t.key);for(r in t)t.hasOwnProperty(r)&&!u.hasOwnProperty(r)&&(a[r]=t[r])}var p=arguments.length-2;if(1===p)a.children=n;else if(p>1){for(var f=Array(p),h=0;p>h;h++)f[h]=arguments[h+2];a.children=f}return new d(e.type,o,l,c,e._context,a)},d.isValidElement=function(e){var t=!(!e||!e._isReactElement);return t},e.exports=d}).call(t,n(175))},function(e,t,n){(function(t){"use strict";var r=n(207),a=n(208),o=n(209),i=!1,s={current:a,withContext:function(e,n){"production"!==t.env.NODE_ENV&&("production"!==t.env.NODE_ENV?o(i,"withContext is deprecated and will be removed in a future version. Use a wrapper component with getChildContext instead."):null,i=!0);var a,l=s.current;s.current=r({},l,e);try{a=n()}finally{s.current=l}return a}};e.exports=s}).call(t,n(175))},function(e,t){"use strict";function n(e,t){if(null==e)throw new TypeError("Object.assign target cannot be null or undefined");for(var n=Object(e),r=Object.prototype.hasOwnProperty,a=1;ar;r++)n.push(arguments[r]);if(void 0===t)throw new Error("`warning(condition, format, ...args)` requires a warning message argument");if(t.length<10||/^[s\W]*$/.test(t))throw new Error("The warning format should be able to uniquely identify this warning. Please, use a more descriptive format than: "+t);if(0!==t.indexOf("Failed Composite propType: ")&&!e){var o=0,i="Warning: "+t.replace(/%s/g,function(){return n[o++]});console.warn(i);try{throw new Error(i)}catch(s){}}}),e.exports=a}).call(t,n(175))},function(e,t){function n(e){return function(){return e}}function r(){}r.thatReturns=n,r.thatReturnsFalse=n(!1),r.thatReturnsTrue=n(!0),r.thatReturnsNull=n(null),r.thatReturnsThis=function(){return this},r.thatReturnsArgument=function(e){return e},e.exports=r},function(e,t){"use strict";var n={current:null};e.exports=n},function(e,t,n){(function(t){"use strict";function r(e){return y[e]}function a(e,t){return e&&null!=e.key?i(e.key):t.toString(36)}function o(e){return(""+e).replace(b,r)}function i(e){return"$"+o(e)}function s(e,n,r,o,l){var d=typeof e;if(("undefined"===d||"boolean"===d)&&(e=null),null===e||"string"===d||"number"===d||u.isValidElement(e))return o(l,e,""===n?m+a(e,0):n,r),1;var y,b,_,w=0;if(Array.isArray(e))for(var k=0;k=s;s++)if(a(e,s)&&a(n,s))i=s;else if(e.charAt(s)!==n.charAt(s))break;var l=e.substr(0,i);return"production"!==t.env.NODE_ENV?p(o(l),"getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s",e,n,l):p(o(l)),l}function c(e,n,r,a,o,u){e=e||"",n=n||"","production"!==t.env.NODE_ENV?p(e!==n,"traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.",e):p(e!==n);var c=i(n,e);"production"!==t.env.NODE_ENV?p(c||i(e,n),"traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do not have a parent path.",e,n):p(c||i(e,n));for(var d=0,f=c?s:l,h=e;;h=f(h,n)){var g;if(o&&h===e||u&&h===n||(g=r(h,c,a)),g===!1||h===n)break;"production"!==t.env.NODE_ENV?p(d++1){var t=e.indexOf(f,1);return t>-1?e.substr(0,t):e}return null},traverseEnterLeave:function(e,t,n,r,a){var o=u(e,t);o!==e&&c(e,o,n,r,!1,!0),o!==t&&c(o,t,n,a,!0,!1)},traverseTwoPhase:function(e,t,n){e&&(c("",e,t,n,!0,!1),c(e,"",t,n,!1,!0))},traverseAncestors:function(e,t,n){c("",e,t,n,!0,!1)},_getFirstCommonAncestorID:u,_getNextDescendantID:l,isAncestorIDOf:i,SEPARATOR:f};e.exports=g}).call(t,n(175))},function(e,t){"use strict";var n={injectCreateReactRootIndex:function(e){r.createReactRootIndex=e}},r={createReactRootIndex:null,injection:n};e.exports=r},function(e,t){"use strict";function n(e){var t=e&&(r&&e[r]||e[a]);return"function"==typeof t?t:void 0}var r="function"==typeof Symbol&&Symbol.iterator,a="@@iterator";e.exports=n},function(e,t,n){(function(t){"use strict";function r(e,t){this.props=e,this.context=t}var a=n(217),o=n(201),i=n(209);if(r.prototype.setState=function(e,n){"production"!==t.env.NODE_ENV?o("object"==typeof e||"function"==typeof e||null==e,"setState(...): takes an object of state variables to update or a function which returns an object of state variables."):o("object"==typeof e||"function"==typeof e||null==e),"production"!==t.env.NODE_ENV&&("production"!==t.env.NODE_ENV?i(null!=e,"setState(...): You passed an undefined or null state object; instead, use forceUpdate()."):null),a.enqueueSetState(this,e),n&&a.enqueueCallback(this,n)},r.prototype.forceUpdate=function(e){a.enqueueForceUpdate(this),e&&a.enqueueCallback(this,e)},"production"!==t.env.NODE_ENV){var s={getDOMNode:["getDOMNode","Use React.findDOMNode(component) instead."],isMounted:["isMounted","Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."],replaceProps:["replaceProps","Instead, call React.render again at the top level."],replaceState:["replaceState","Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."],setProps:["setProps","Instead, call React.render again at the top level."]},l=function(e,n){try{Object.defineProperty(r.prototype,e,{get:function(){return void("production"!==t.env.NODE_ENV?i(!1,"%s(...) is deprecated in plain JavaScript React classes. %s",n[0],n[1]):null)}})}catch(a){}};for(var u in s)s.hasOwnProperty(u)&&l(u,s[u])}e.exports=r}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(e){e!==o.currentlyMountingInstance&&u.enqueueUpdate(e)}function a(e,n){"production"!==t.env.NODE_ENV?d(null==i.current,"%s(...): Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.",n):d(null==i.current);var r=l.get(e);return r?r===o.currentlyUnmountingInstance?null:r:("production"!==t.env.NODE_ENV&&("production"!==t.env.NODE_ENV?p(!n,"%s(...): Can only update a mounted or mounting component. This usually means you called %s() on an unmounted component. This is a no-op.",n,n):null),null)}var o=n(218),i=n(211),s=n(205),l=n(219),u=n(220),c=n(207),d=n(201),p=n(209),f={enqueueCallback:function(e,n){"production"!==t.env.NODE_ENV?d("function"==typeof n,"enqueueCallback(...): You called `setProps`, `replaceProps`, `setState`, `replaceState`, or `forceUpdate` with a callback that isn't callable."):d("function"==typeof n);var i=a(e);return i&&i!==o.currentlyMountingInstance?(i._pendingCallbacks?i._pendingCallbacks.push(n):i._pendingCallbacks=[n],void r(i)):null},enqueueCallbackInternal:function(e,n){"production"!==t.env.NODE_ENV?d("function"==typeof n,"enqueueCallback(...): You called `setProps`, `replaceProps`, `setState`, `replaceState`, or `forceUpdate` with a callback that isn't callable."):d("function"==typeof n),e._pendingCallbacks?e._pendingCallbacks.push(n):e._pendingCallbacks=[n],r(e)},enqueueForceUpdate:function(e){var t=a(e,"forceUpdate");t&&(t._pendingForceUpdate=!0,r(t))},enqueueReplaceState:function(e,t){var n=a(e,"replaceState");n&&(n._pendingStateQueue=[t],n._pendingReplaceState=!0,r(n))},enqueueSetState:function(e,t){var n=a(e,"setState");if(n){var o=n._pendingStateQueue||(n._pendingStateQueue=[]);o.push(t),r(n)}},enqueueSetProps:function(e,n){var o=a(e,"setProps");if(o){"production"!==t.env.NODE_ENV?d(o._isTopLevel,"setProps(...): You called `setProps` on a component with a parent. This is an anti-pattern since props will get reactively updated when rendered. Instead, change the owner's `render` method to pass the correct value as props to the component where it is created."):d(o._isTopLevel);var i=o._pendingElement||o._currentElement,l=c({},i.props,n);o._pendingElement=s.cloneAndReplaceProps(i,l),r(o)}},enqueueReplaceProps:function(e,n){var o=a(e,"replaceProps");if(o){"production"!==t.env.NODE_ENV?d(o._isTopLevel,"replaceProps(...): You called `replaceProps` on a component with a parent. This is an anti-pattern since props will get reactively updated when rendered. Instead, change the owner's `render` method to pass the correct value as props to the component where it is created."):d(o._isTopLevel);var i=o._pendingElement||o._currentElement;o._pendingElement=s.cloneAndReplaceProps(i,n),r(o)}},enqueueElementInternal:function(e,t){e._pendingElement=t,r(e)}};e.exports=f}).call(t,n(175))},function(e,t){"use strict";var n={currentlyMountingInstance:null,currentlyUnmountingInstance:null};e.exports=n},function(e,t){"use strict";var n={remove:function(e){e._reactInternalInstance=void 0},get:function(e){return e._reactInternalInstance},has:function(e){return void 0!==e._reactInternalInstance},set:function(e,t){e._reactInternalInstance=t}};e.exports=n},function(e,t,n){(function(t){"use strict";function r(){"production"!==t.env.NODE_ENV?y(A.ReactReconcileTransaction&&k,"ReactUpdates: must inject a reconcile transaction class and batching strategy"):y(A.ReactReconcileTransaction&&k)}function a(){this.reinitializeTransaction(),this.dirtyComponentsLength=null,this.callbackQueue=c.getPooled(),this.reconcileTransaction=A.ReactReconcileTransaction.getPooled()}function o(e,t,n,a,o){r(),k.batchedUpdates(e,t,n,a,o)}function i(e,t){return e._mountOrder-t._mountOrder}function s(e){var n=e.dirtyComponentsLength;"production"!==t.env.NODE_ENV?y(n===v.length,"Expected flush transaction's stored dirty-components length (%s) to match dirty-components array length (%s).",n,v.length):y(n===v.length),v.sort(i);for(var r=0;n>r;r++){var a=v[r],o=a._pendingCallbacks;if(a._pendingCallbacks=null,h.performUpdateIfNecessary(a,e.reconcileTransaction),o)for(var s=0;sr;r++)e[r].call(n[r]);e.length=0,n.length=0}},reset:function(){this._callbacks=null,this._contexts=null},destructor:function(){this.reset()}}),a.addPoolingTo(r),e.exports=r}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function n(e,t,n){return n}var r={enableMeasure:!1,storedMeasure:n,measureMethods:function(e,n,a){if("production"!==t.env.NODE_ENV)for(var o in a)a.hasOwnProperty(o)&&(e[o]=r.measure(n,a[o],e[o]))},measure:function(e,n,a){if("production"!==t.env.NODE_ENV){var o=null,i=function(){return r.enableMeasure?(o||(o=r.storedMeasure(e,n,a)),o.apply(this,arguments)):a.apply(this,arguments)};return i.displayName=e+"_"+n,i}return a},injection:{injectMeasure:function(e){r.storedMeasure=e}}};e.exports=r}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(){a.attachRefs(this,this._currentElement)}var a=n(224),o=n(226),i={mountComponent:function(e,n,a,i){var s=e.mountComponent(n,a,i);return"production"!==t.env.NODE_ENV&&o.checkAndWarnForMutatedProps(e._currentElement),a.getReactMountReady().enqueue(r,e),s},unmountComponent:function(e){a.detachRefs(e,e._currentElement),e.unmountComponent()},receiveComponent:function(e,n,i,s){var l=e._currentElement;if(n!==l||null==n._owner){"production"!==t.env.NODE_ENV&&o.checkAndWarnForMutatedProps(n);var u=a.shouldUpdateRefs(l,n);u&&a.detachRefs(e,l),e.receiveComponent(n,i,s),u&&i.getReactMountReady().enqueue(r,e)}},performUpdateIfNecessary:function(e,t){e.performUpdateIfNecessary(t)}};e.exports=i}).call(t,n(175))},function(e,t,n){"use strict";function r(e,t,n){"function"==typeof e?e(t.getPublicInstance()):o.addComponentAsRefTo(t,e,n)}function a(e,t,n){"function"==typeof e?e(null):o.removeComponentAsRefFrom(t,e,n)}var o=n(225),i={};i.attachRefs=function(e,t){var n=t.ref;null!=n&&r(n,e,t._owner)},i.shouldUpdateRefs=function(e,t){return t._owner!==e._owner||t.ref!==e.ref},i.detachRefs=function(e,t){var n=t.ref;null!=n&&a(n,e,t._owner)},e.exports=i},function(e,t,n){(function(t){"use strict";var r=n(201),a={isValidOwner:function(e){return!(!e||"function"!=typeof e.attachRef||"function"!=typeof e.detachRef)},addComponentAsRefTo:function(e,n,o){"production"!==t.env.NODE_ENV?r(a.isValidOwner(o),"addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). Try rendering this component inside of a new top-level component which will hold the ref."):r(a.isValidOwner(o)),o.attachRef(n,e)},removeComponentAsRefFrom:function(e,n,o){"production"!==t.env.NODE_ENV?r(a.isValidOwner(o),"removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This usually means that you're trying to remove a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). Try rendering this component inside of a new top-level component which will hold the ref."):r(a.isValidOwner(o)),o.getPublicInstance().refs[n]===e.getPublicInstance()&&o.detachRef(n)}};e.exports=a}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(){if(v.current){var e=v.current.getName();if(e)return" Check the render method of `"+e+"`."}return""}function a(e){var t=e&&e.getPublicInstance();if(!t)return void 0;var n=t.constructor;return n?n.displayName||n.name||void 0:void 0}function o(){var e=v.current;return e&&a(e)||void 0}function i(e,t){e._store.validated||null!=e.key||(e._store.validated=!0,l('Each child in an array or iterator should have a unique "key" prop.',e,t))}function s(e,t,n){S.test(e)&&l("Child objects should have non-numeric keys so ordering is preserved.",t,n)}function l(e,n,r){var i=o(),s="string"==typeof r?r:r.displayName||r.name,l=i||s,u=x[e]||(x[e]={});if(!u.hasOwnProperty(l)){u[l]=!0;var c=i?" Check the render method of "+i+".":s?" Check the React.render call using <"+s+">.":"",d="";if(n&&n._owner&&n._owner!==v.current){var p=a(n._owner);d=" It was passed a child from "+p+"."}"production"!==t.env.NODE_ENV?E(!1,e+"%s%s See https://fb.me/react-warning-keys for more information.",c,d):null}}function u(e,t){if(Array.isArray(e))for(var n=0;n");var l="";o&&(l=" The element was created by "+o+"."),"production"!==t.env.NODE_ENV?E(!1,"Don't set .props.%s of the React component%s. Instead, specify the correct value when initially creating the element or use React.cloneElement to make a new element with updated props.%s",e,s,l):null}}function p(e,t){return e!==e?t!==t:0===e&&0===t?1/e===1/t:e===t}function f(e){if(e._store){var t=e._store.originalProps,n=e.props;for(var r in n)n.hasOwnProperty(r)&&(t.hasOwnProperty(r)&&p(t[r],n[r])||(d(r,e),t[r]=n[r]))}}function h(e){if(null!=e.type){var n=_.getComponentClassForElement(e),r=n.displayName||n.name;n.propTypes&&c(r,n.propTypes,e.props,y.prop),"function"==typeof n.getDefaultProps&&("production"!==t.env.NODE_ENV?E(n.getDefaultProps.isReactClassApproved,"getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead."):null)}}var m=n(205),g=n(204),y=n(227),b=n(228),v=n(211),_=n(229),w=n(215),k=n(201),E=n(209),x={},O={},S=/^\d+$/,P={},A={checkAndWarnForMutatedProps:f,createElement:function(e,n,r){"production"!==t.env.NODE_ENV?E(null!=e,"React.createElement: type should not be null or undefined. It should be a string (for DOM elements) or a ReactClass (for composite components)."):null;var a=m.createElement.apply(this,arguments);if(null==a)return a;for(var o=2;ol;l++)s.push(arguments[l]);if(i!==e&&null!==i)"production"!==t.env.NODE_ENV?O(!1,"bind(): React component methods may only be bound to the component instance. See %s",a):null;else if(!s.length)return"production"!==t.env.NODE_ENV?O(!1,"bind(): You are binding a component method to the component. React does this for you automatically in a high-performance way, so you can safely remove this call. See %s",a):null,r;var c=o.apply(r,arguments);return c.__reactBoundContext=e,c.__reactBoundMethod=n,c.__reactBoundArguments=s,c}}return r}function d(e){for(var t in e.__reactAutoBindMap)if(e.__reactAutoBindMap.hasOwnProperty(t)){var n=e.__reactAutoBindMap[t];e[t]=c(e,m.guard(n,e.constructor.displayName+"."+t))}}var p=n(216),f=n(211),h=n(205),m=n(232),g=n(219),y=n(218),b=n(227),v=n(228),_=n(217),w=n(207),k=n(201),E=n(200),x=n(233),O=n(209),S=x({mixins:null}),P=E({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),A=[],j={mixins:P.DEFINE_MANY,statics:P.DEFINE_MANY,propTypes:P.DEFINE_MANY,contextTypes:P.DEFINE_MANY,childContextTypes:P.DEFINE_MANY,getDefaultProps:P.DEFINE_MANY_MERGED,getInitialState:P.DEFINE_MANY_MERGED,getChildContext:P.DEFINE_MANY_MERGED,render:P.DEFINE_ONCE,componentWillMount:P.DEFINE_MANY,componentDidMount:P.DEFINE_MANY,componentWillReceiveProps:P.DEFINE_MANY,shouldComponentUpdate:P.DEFINE_ONCE,componentWillUpdate:P.DEFINE_MANY,componentDidUpdate:P.DEFINE_MANY,componentWillUnmount:P.DEFINE_MANY,updateComponent:P.OVERRIDE_BASE},C={displayName:function(e,t){e.displayName=t},mixins:function(e,t){if(t)for(var n=0;n"+a+""},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;n!==this._stringText&&(this._stringText=n,o.BackendIDOperations.updateTextContentByID(this._rootNodeID,n))}},unmountComponent:function(){a.unmountIDFromEnvironment(this._rootNodeID)}}),e.exports=l},function(e,t,n){(function(t){"use strict";function r(e,t){return null==t||a.hasBooleanValue[e]&&!t||a.hasNumericValue[e]&&isNaN(t)||a.hasPositiveNumericValue[e]&&1>t||a.hasOverloadedBooleanValue[e]&&t===!1}var a=n(238),o=n(239),i=n(209);if("production"!==t.env.NODE_ENV)var s={children:!0,dangerouslySetInnerHTML:!0,key:!0,ref:!0},l={},u=function(e){if(!(s.hasOwnProperty(e)&&s[e]||l.hasOwnProperty(e)&&l[e])){l[e]=!0;var n=e.toLowerCase(),r=a.isCustomAttribute(n)?n:a.getPossibleStandardName.hasOwnProperty(n)?a.getPossibleStandardName[n]:null;"production"!==t.env.NODE_ENV?i(null==r,"Unknown DOM property %s. Did you mean %s?",e,r):null}};var c={createMarkupForID:function(e){return a.ID_ATTRIBUTE_NAME+"="+o(e)},createMarkupForProperty:function(e,n){if(a.isStandardName.hasOwnProperty(e)&&a.isStandardName[e]){if(r(e,n))return"";var i=a.getAttributeName[e];return a.hasBooleanValue[e]||a.hasOverloadedBooleanValue[e]&&n===!0?i:i+"="+o(n)}return a.isCustomAttribute(e)?null==n?"":e+"="+o(n):("production"!==t.env.NODE_ENV&&u(e),null)},setValueForProperty:function(e,n,o){if(a.isStandardName.hasOwnProperty(n)&&a.isStandardName[n]){var i=a.getMutationMethod[n];if(i)i(e,o);else if(r(n,o))this.deleteValueForProperty(e,n);else if(a.mustUseAttribute[n])e.setAttribute(a.getAttributeName[n],""+o);else{var s=a.getPropertyName[n];a.hasSideEffects[n]&&""+e[s]==""+o||(e[s]=o)}}else a.isCustomAttribute(n)?null==o?e.removeAttribute(n):e.setAttribute(n,""+o):"production"!==t.env.NODE_ENV&&u(n)},deleteValueForProperty:function(e,n){if(a.isStandardName.hasOwnProperty(n)&&a.isStandardName[n]){var r=a.getMutationMethod[n];if(r)r(e,void 0);else if(a.mustUseAttribute[n])e.removeAttribute(a.getAttributeName[n]);else{var o=a.getPropertyName[n],i=a.getDefaultValueForProperty(e.nodeName,o);a.hasSideEffects[n]&&""+e[o]===i||(e[o]=i)}}else a.isCustomAttribute(n)?e.removeAttribute(n):"production"!==t.env.NODE_ENV&&u(n)}};e.exports=c}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(e,t){return(e&t)===t}var a=n(201),o={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(e){var n=e.Properties||{},i=e.DOMAttributeNames||{},l=e.DOMPropertyNames||{},u=e.DOMMutationMethods||{};e.isCustomAttribute&&s._isCustomAttributeFunctions.push(e.isCustomAttribute);for(var c in n){"production"!==t.env.NODE_ENV?a(!s.isStandardName.hasOwnProperty(c),"injectDOMPropertyConfig(...): You're trying to inject DOM property '%s' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.",c):a(!s.isStandardName.hasOwnProperty(c)),s.isStandardName[c]=!0;var d=c.toLowerCase();if(s.getPossibleStandardName[d]=c,i.hasOwnProperty(c)){var p=i[c];s.getPossibleStandardName[p]=c,s.getAttributeName[c]=p}else s.getAttributeName[c]=d;s.getPropertyName[c]=l.hasOwnProperty(c)?l[c]:c,u.hasOwnProperty(c)?s.getMutationMethod[c]=u[c]:s.getMutationMethod[c]=null;var f=n[c];s.mustUseAttribute[c]=r(f,o.MUST_USE_ATTRIBUTE),s.mustUseProperty[c]=r(f,o.MUST_USE_PROPERTY),s.hasSideEffects[c]=r(f,o.HAS_SIDE_EFFECTS),s.hasBooleanValue[c]=r(f,o.HAS_BOOLEAN_VALUE),s.hasNumericValue[c]=r(f,o.HAS_NUMERIC_VALUE),s.hasPositiveNumericValue[c]=r(f,o.HAS_POSITIVE_NUMERIC_VALUE),s.hasOverloadedBooleanValue[c]=r(f,o.HAS_OVERLOADED_BOOLEAN_VALUE),"production"!==t.env.NODE_ENV?a(!s.mustUseAttribute[c]||!s.mustUseProperty[c],"DOMProperty: Cannot require using both attribute and property: %s",c):a(!s.mustUseAttribute[c]||!s.mustUseProperty[c]),"production"!==t.env.NODE_ENV?a(s.mustUseProperty[c]||!s.hasSideEffects[c],"DOMProperty: Properties that have side effects must use property: %s",c):a(s.mustUseProperty[c]||!s.hasSideEffects[c]),"production"!==t.env.NODE_ENV?a(!!s.hasBooleanValue[c]+!!s.hasNumericValue[c]+!!s.hasOverloadedBooleanValue[c]<=1,"DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s",c):a(!!s.hasBooleanValue[c]+!!s.hasNumericValue[c]+!!s.hasOverloadedBooleanValue[c]<=1)}}},i={},s={ID_ATTRIBUTE_NAME:"data-reactid",isStandardName:{},getPossibleStandardName:{},getAttributeName:{},getPropertyName:{},getMutationMethod:{},mustUseAttribute:{},mustUseProperty:{},hasSideEffects:{},hasBooleanValue:{},hasNumericValue:{},hasPositiveNumericValue:{},hasOverloadedBooleanValue:{},_isCustomAttributeFunctions:[],isCustomAttribute:function(e){for(var t=0;t":">","<":"<",'"':""","'":"'"},o=/[&><"']/g;e.exports=r},function(e,t,n){"use strict";var r=n(242),a=n(261),o={processChildrenUpdates:r.dangerouslyProcessChildrenUpdates,replaceNodeWithMarkupByID:r.dangerouslyReplaceNodeWithMarkupByID,unmountIDFromEnvironment:function(e){a.purgeID(e)}};e.exports=o},function(e,t,n){(function(t){"use strict";var r=n(243),a=n(252),o=n(237),i=n(261),s=n(222),l=n(201),u=n(260),c={dangerouslySetInnerHTML:"`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.",style:"`style` must be set using `updateStylesByID()`."},d={updatePropertyByID:function(e,n,r){var a=i.getNode(e);"production"!==t.env.NODE_ENV?l(!c.hasOwnProperty(n),"updatePropertyByID(...): %s",c[n]):l(!c.hasOwnProperty(n)),null!=r?o.setValueForProperty(a,n,r):o.deleteValueForProperty(a,n)},deletePropertyByID:function(e,n,r){var a=i.getNode(e);"production"!==t.env.NODE_ENV?l(!c.hasOwnProperty(n),"updatePropertyByID(...): %s",c[n]):l(!c.hasOwnProperty(n)),o.deleteValueForProperty(a,n,r)},updateStylesByID:function(e,t){var n=i.getNode(e);r.setValueForStyles(n,t)},updateInnerHTMLByID:function(e,t){var n=i.getNode(e);u(n,t)},updateTextContentByID:function(e,t){var n=i.getNode(e);a.updateTextContent(n,t)},dangerouslyReplaceNodeWithMarkupByID:function(e,t){var n=i.getNode(e);a.dangerouslyReplaceNodeWithMarkup(n,t)},dangerouslyProcessChildrenUpdates:function(e,t){for(var n=0;n-1?g(e):p.test(e)?y(e):f.test(t)&&b(e,t)};var _={createMarkupForStyles:function(e){var n="";for(var r in e)if(e.hasOwnProperty(r)){var a=e[r];"production"!==t.env.NODE_ENV&&v(r,a),null!=a&&(n+=c(r)+":",n+=i(r,a)+";")}return n||null},setValueForStyles:function(e,n){var a=e.style;for(var o in n)if(n.hasOwnProperty(o)){"production"!==t.env.NODE_ENV&&v(o,n[o]);var s=i(o,n[o]);if("float"===o&&(o=d),s)a[o]=s;else{var l=r.shorthandPropertyExpansions[o];if(l)for(var u in l)a[u]="";else a[o]=""}}}};e.exports=_}).call(t,n(175))},function(e,t){"use strict";function n(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}var r={boxFlex:!0,boxFlexGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0},a=["Webkit","ms","Moz","O"];Object.keys(r).forEach(function(e){a.forEach(function(t){r[n(t,e)]=r[e]})});var o={background:{backgroundImage:!0,backgroundPosition:!0,backgroundRepeat:!0,backgroundColor:!0},border:{borderWidth:!0,borderStyle:!0,borderColor:!0},borderBottom:{borderBottomWidth:!0,borderBottomStyle:!0,borderBottomColor:!0},borderLeft:{borderLeftWidth:!0,borderLeftStyle:!0,borderLeftColor:!0},borderRight:{borderRightWidth:!0,borderRightStyle:!0,borderRightColor:!0},borderTop:{borderTopWidth:!0,borderTopStyle:!0,borderTopColor:!0},font:{fontStyle:!0,fontVariant:!0, +fontWeight:!0,fontSize:!0,lineHeight:!0,fontFamily:!0}},i={isUnitlessNumber:r,shorthandPropertyExpansions:o};e.exports=i},function(e,t){"use strict";var n=!("undefined"==typeof window||!window.document||!window.document.createElement),r={canUseDOM:n,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:n&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:n&&!!window.screen,isInWorker:!n};e.exports=r},function(e,t,n){"use strict";function r(e){return a(e.replace(o,"ms-"))}var a=n(247),o=/^-ms-/;e.exports=r},function(e,t){function n(e){return e.replace(r,function(e,t){return t.toUpperCase()})}var r=/-(.)/g;e.exports=n},function(e,t,n){"use strict";function r(e,t){var n=null==t||"boolean"==typeof t||""===t;if(n)return"";var r=isNaN(t);return r||0===t||o.hasOwnProperty(e)&&o[e]?""+t:("string"==typeof t&&(t=t.trim()),t+"px")}var a=n(244),o=a.isUnitlessNumber;e.exports=r},function(e,t,n){"use strict";function r(e){return a(e).replace(o,"-ms-")}var a=n(250),o=/^ms-/;e.exports=r},function(e,t){function n(e){return e.replace(r,"-$1").toLowerCase()}var r=/([A-Z])/g;e.exports=n},function(e,t){"use strict";function n(e){var t={};return function(n){return t.hasOwnProperty(n)||(t[n]=e.call(this,n)),t[n]}}e.exports=n},function(e,t,n){(function(t){"use strict";function r(e,t,n){e.insertBefore(t,e.childNodes[n]||null)}var a=n(253),o=n(258),i=n(259),s=n(201),l={dangerouslyReplaceNodeWithMarkup:a.dangerouslyReplaceNodeWithMarkup,updateTextContent:i,processUpdates:function(e,n){for(var l,u=null,c=null,d=0;d when using tables, nesting tags like
,

, or , or using non-SVG elements in an parent. Try inspecting the child nodes of the element with React ID `%s`.",p,h):s(f),u=u||{},u[h]=u[h]||[],u[h][p]=f,c=c||[],c.push(f)}var m=a.dangerouslyRenderMarkup(n);if(c)for(var g=0;g]+)/,c="data-danger-index",d={dangerouslyRenderMarkup:function(e){"production"!==t.env.NODE_ENV?l(a.canUseDOM,"dangerouslyRenderMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use React.renderToString for server rendering."):l(a.canUseDOM);for(var n,d={},p=0;p node. This is because browser quirks make this unreliable and/or slow. If you want to render to the root you must use server rendering. See React.renderToString()."):l("html"!==e.tagName.toLowerCase());var r=o(n,i)[0];e.parentNode.replaceChild(r,e)}};e.exports=d}).call(t,n(175))},function(e,t,n){(function(t){function r(e){var t=e.match(c);return t&&t[1].toLowerCase()}function a(e,n){var a=u;"production"!==t.env.NODE_ENV?l(!!u,"createNodesFromMarkup dummy not initialized"):l(!!u);var o=r(e),c=o&&s(o);if(c){a.innerHTML=c[1]+e+c[2];for(var d=c[0];d--;)a=a.lastChild}else a.innerHTML=e;var p=a.getElementsByTagName("script");p.length&&("production"!==t.env.NODE_ENV?l(n,"createNodesFromMarkup(...): Unexpected ","
"],c=[3,"","
"],d=[1,"",""],p={"*":[1,"?

"],area:[1,"",""],col:[2,"","
"],legend:[1,"
","
"],param:[1,"",""],tr:[2,"","
"],optgroup:l,option:l,caption:u,colgroup:u,tbody:u,tfoot:u,thead:u,td:c,th:c,circle:d,clipPath:d,defs:d,ellipse:d,g:d,line:d,linearGradient:d,path:d,polygon:d,polyline:d,radialGradient:d,rect:d,stop:d,text:d};e.exports=r}).call(t,n(175))},function(e,t,n){"use strict";var r=n(200),a=r({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,TEXT_CONTENT:null});e.exports=a},function(e,t,n){"use strict";var r=n(245),a=n(240),o=n(260),i=function(e,t){e.textContent=t};r.canUseDOM&&("textContent"in document.documentElement||(i=function(e,t){o(e,a(t))})),e.exports=i},function(e,t,n){"use strict";var r=n(245),a=/^[ \r\n\t\f]/,o=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,i=function(e,t){e.innerHTML=t};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(i=function(e,t){MSApp.execUnsafeLocalFunction(function(){e.innerHTML=t})}),r.canUseDOM){var s=document.createElement("div");s.innerHTML=" ",""===s.innerHTML&&(i=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),a.test(t)||"<"===t[0]&&o.test(t)){e.innerHTML="\ufeff"+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t})}e.exports=i},function(e,t,n){(function(t){"use strict";function r(e,t){for(var n=Math.min(e.length,t.length),r=0;n>r;r++)if(e.charAt(r)!==t.charAt(r))return r;return e.length===t.length?-1:n}function a(e){var t=T(e);return t&&G.getID(t)}function o(e){var n=i(e);if(n)if(L.hasOwnProperty(n)){var r=L[n];r!==e&&("production"!==t.env.NODE_ENV?M(!c(r,n),"ReactMount: Two valid but unequal nodes with the same `%s`: %s",B,n):M(!c(r,n)),L[n]=e)}else L[n]=e;return n}function i(e){return e&&e.getAttribute&&e.getAttribute(B)||""}function s(e,t){var n=i(e);n!==t&&delete L[n],e.setAttribute(B,t),L[t]=e}function l(e){return L.hasOwnProperty(e)&&c(L[e],e)||(L[e]=G.findReactNodeByID(e)),L[e]}function u(e){var t=E.get(e)._rootNodeID;return w.isNullComponentID(t)?null:(L.hasOwnProperty(t)&&c(L[t],t)||(L[t]=G.findReactNodeByID(t)),L[t])}function c(e,n){if(e){"production"!==t.env.NODE_ENV?M(i(e)===n,"ReactMount: Unexpected modification of `%s`",B):M(i(e)===n);var r=G.findReactContainerForID(n);if(r&&C(r,e))return!0}return!1}function d(e){delete L[e]}function p(e){var t=L[e];return t&&c(t,e)?void(K=t):!1}function f(e){K=null,k.traverseAncestors(e,p);var t=K;return K=null,t}function h(e,t,n,r,a){var o=S.mountComponent(e,t,r,j);e._isTopLevel=!0,G._mountImageIntoNode(o,n,a)}function m(e,t,n,r){var a=A.ReactReconcileTransaction.getPooled();a.perform(h,null,e,t,n,a,r),A.ReactReconcileTransaction.release(a)}var g=n(238),y=n(262),b=n(211),v=n(205),_=n(226),w=n(270),k=n(213),E=n(219),x=n(271),O=n(222),S=n(223),P=n(217),A=n(220),j=n(208),C=n(273),T=n(276),D=n(277),M=n(201),N=n(260),z=n(280),I=n(209),R=k.SEPARATOR,B=g.ID_ATTRIBUTE_NAME,L={},q=1,F=9,U={},H={};if("production"!==t.env.NODE_ENV)var W={};var V=[],K=null,G={_instancesByReactRootID:U,scrollMonitor:function(e,t){t()},_updateRootComponent:function(e,n,r,o){return"production"!==t.env.NODE_ENV&&_.checkAndWarnForMutatedProps(n),G.scrollMonitor(r,function(){P.enqueueElementInternal(e,n),o&&P.enqueueCallbackInternal(e,o)}),"production"!==t.env.NODE_ENV&&(W[a(r)]=T(r)),e},_registerComponent:function(e,n){"production"!==t.env.NODE_ENV?M(n&&(n.nodeType===q||n.nodeType===F),"_registerComponent(...): Target container is not a DOM element."):M(n&&(n.nodeType===q||n.nodeType===F)),y.ensureScrollValueMonitoring();var r=G.registerContainer(n);return U[r]=e,r},_renderNewRootComponent:function(e,n,r){"production"!==t.env.NODE_ENV?I(null==b.current,"_renderNewRootComponent(): Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate."):null;var a=D(e,null),o=G._registerComponent(a,n);return A.batchedUpdates(m,a,o,n,r),"production"!==t.env.NODE_ENV&&(W[o]=T(n)),a},render:function(e,n,r){"production"!==t.env.NODE_ENV?M(v.isValidElement(e),"React.render(): Invalid component element.%s","string"==typeof e?" Instead of passing an element string, make sure to instantiate it by passing it to React.createElement.":"function"==typeof e?" Instead of passing a component class, make sure to instantiate it by passing it to React.createElement.":null!=e&&void 0!==e.props?" This may be caused by unintentionally loading two independent copies of React.":""):M(v.isValidElement(e));var o=U[a(n)];if(o){var i=o._currentElement;if(z(i,e))return G._updateRootComponent(o,e,n,r).getPublicInstance();G.unmountComponentAtNode(n)}var s=T(n),l=s&&G.isRenderedByReact(s);if("production"!==t.env.NODE_ENV&&(!l||s.nextSibling))for(var u=s;u;){if(G.isRenderedByReact(u)){"production"!==t.env.NODE_ENV?I(!1,"render(): Target node has markup rendered by React, but there are unrelated nodes as well. This is most commonly caused by white-space inserted around server-rendered markup."):null;break}u=u.nextSibling}var c=l&&!o,d=G._renderNewRootComponent(e,n,c).getPublicInstance();return r&&r.call(d),d},constructAndRenderComponent:function(e,t,n){var r=v.createElement(e,t);return G.render(r,n)},constructAndRenderComponentByID:function(e,n,r){var a=document.getElementById(r);return"production"!==t.env.NODE_ENV?M(a,'Tried to get element with id of "%s" but it is not present on the page.',r):M(a),G.constructAndRenderComponent(e,n,a)},registerContainer:function(e){var t=a(e);return t&&(t=k.getReactRootIDFromNodeID(t)),t||(t=k.createReactRootID()),H[t]=e,t},unmountComponentAtNode:function(e){"production"!==t.env.NODE_ENV?I(null==b.current,"unmountComponentAtNode(): Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate."):null,"production"!==t.env.NODE_ENV?M(e&&(e.nodeType===q||e.nodeType===F),"unmountComponentAtNode(...): Target container is not a DOM element."):M(e&&(e.nodeType===q||e.nodeType===F));var n=a(e),r=U[n];return r?(G.unmountComponentFromNode(r,e),delete U[n],delete H[n],"production"!==t.env.NODE_ENV&&delete W[n],!0):!1},unmountComponentFromNode:function(e,t){for(S.unmountComponent(e),t.nodeType===F&&(t=t.documentElement);t.lastChild;)t.removeChild(t.lastChild)},findReactContainerForID:function(e){var n=k.getReactRootIDFromNodeID(e),r=H[n];if("production"!==t.env.NODE_ENV){var a=W[n];if(a&&a.parentNode!==r){"production"!==t.env.NODE_ENV?M(i(a)===n,"ReactMount: Root element ID differed from reactRootID."):M(i(a)===n);var o=r.firstChild;o&&n===i(o)?W[n]=o:"production"!==t.env.NODE_ENV?I(!1,"ReactMount: Root element has been removed from its original container. New container:",a.parentNode):null}}return r},findReactNodeByID:function(e){var t=G.findReactContainerForID(e);return G.findComponentRoot(t,e)},isRenderedByReact:function(e){if(1!==e.nodeType)return!1;var t=G.getID(e);return t?t.charAt(0)===R:!1},getFirstReactDOM:function(e){for(var t=e;t&&t.parentNode!==t;){if(G.isRenderedByReact(t))return t;t=t.parentNode}return null},findComponentRoot:function(e,n){var r=V,a=0,o=f(n)||e;for(r[0]=o.firstChild,r.length=1;a when using tables, nesting tags like ,

, or , or using non-SVG elements in an parent. Try inspecting the child nodes of the element with React ID `%s`.",n,G.getID(e)):M(!1)},_mountImageIntoNode:function(e,n,a){if("production"!==t.env.NODE_ENV?M(n&&(n.nodeType===q||n.nodeType===F),"mountComponentIntoNode(...): Target container is not valid."):M(n&&(n.nodeType===q||n.nodeType===F)),a){var o=T(n);if(x.canReuseMarkup(e,o))return;var i=o.getAttribute(x.CHECKSUM_ATTR_NAME);o.removeAttribute(x.CHECKSUM_ATTR_NAME);var s=o.outerHTML;o.setAttribute(x.CHECKSUM_ATTR_NAME,i);var l=r(e,s),u=" (client) "+e.substring(l-20,l+20)+"\n (server) "+s.substring(l-20,l+20);"production"!==t.env.NODE_ENV?M(n.nodeType!==F,"You're trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure. React cannot handle this case due to cross-browser quirks by rendering at the document root. You should look for environment dependent code in your components and ensure the props are the same client and server side:\n%s",u):M(n.nodeType!==F),"production"!==t.env.NODE_ENV&&("production"!==t.env.NODE_ENV?I(!1,"React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:\n%s",u):null)}"production"!==t.env.NODE_ENV?M(n.nodeType!==F,"You're trying to render a component to the document but you didn't use server rendering. We can't do this without using server rendering due to cross-browser quirks. See React.renderToString() for server rendering."):M(n.nodeType!==F),N(n,e)},getReactRootID:a,getID:o,setID:s,getNode:l,getNodeFromInstance:u,purgeID:d};O.measureMethods(G,"ReactMount",{_renderNewRootComponent:"_renderNewRootComponent",_mountImageIntoNode:"_mountImageIntoNode"}),e.exports=G}).call(t,n(175))},function(e,t,n){"use strict";function r(e){return Object.prototype.hasOwnProperty.call(e,m)||(e[m]=f++,d[e[m]]={}),d[e[m]]}var a=n(199),o=n(263),i=n(264),s=n(267),l=n(268),u=n(207),c=n(269),d={},p=!1,f=0,h={topBlur:"blur",topChange:"change",topClick:"click",topCompositionEnd:"compositionend",topCompositionStart:"compositionstart",topCompositionUpdate:"compositionupdate",topContextMenu:"contextmenu",topCopy:"copy",topCut:"cut",topDoubleClick:"dblclick",topDrag:"drag",topDragEnd:"dragend",topDragEnter:"dragenter",topDragExit:"dragexit",topDragLeave:"dragleave",topDragOver:"dragover",topDragStart:"dragstart",topDrop:"drop",topFocus:"focus",topInput:"input",topKeyDown:"keydown",topKeyPress:"keypress",topKeyUp:"keyup",topMouseDown:"mousedown",topMouseMove:"mousemove",topMouseOut:"mouseout",topMouseOver:"mouseover",topMouseUp:"mouseup",topPaste:"paste",topScroll:"scroll",topSelectionChange:"selectionchange",topTextInput:"textInput",topTouchCancel:"touchcancel",topTouchEnd:"touchend",topTouchMove:"touchmove",topTouchStart:"touchstart",topWheel:"wheel"},m="_reactListenersID"+String(Math.random()).slice(2),g=u({},s,{ReactEventListener:null,injection:{injectReactEventListener:function(e){e.setHandleTopLevel(g.handleTopLevel),g.ReactEventListener=e}},setEnabled:function(e){g.ReactEventListener&&g.ReactEventListener.setEnabled(e)},isEnabled:function(){return!(!g.ReactEventListener||!g.ReactEventListener.isEnabled())},listenTo:function(e,t){for(var n=t,o=r(n),s=i.registrationNameDependencies[e],l=a.topLevelTypes,u=0,d=s.length;d>u;u++){var p=s[u];o.hasOwnProperty(p)&&o[p]||(p===l.topWheel?c("wheel")?g.ReactEventListener.trapBubbledEvent(l.topWheel,"wheel",n):c("mousewheel")?g.ReactEventListener.trapBubbledEvent(l.topWheel,"mousewheel",n):g.ReactEventListener.trapBubbledEvent(l.topWheel,"DOMMouseScroll",n):p===l.topScroll?c("scroll",!0)?g.ReactEventListener.trapCapturedEvent(l.topScroll,"scroll",n):g.ReactEventListener.trapBubbledEvent(l.topScroll,"scroll",g.ReactEventListener.WINDOW_HANDLE):p===l.topFocus||p===l.topBlur?(c("focus",!0)?(g.ReactEventListener.trapCapturedEvent(l.topFocus,"focus",n),g.ReactEventListener.trapCapturedEvent(l.topBlur,"blur",n)):c("focusin")&&(g.ReactEventListener.trapBubbledEvent(l.topFocus,"focusin",n),g.ReactEventListener.trapBubbledEvent(l.topBlur,"focusout",n)),o[l.topBlur]=!0,o[l.topFocus]=!0):h.hasOwnProperty(p)&&g.ReactEventListener.trapBubbledEvent(p,h[p],n),o[p]=!0)}},trapBubbledEvent:function(e,t,n){return g.ReactEventListener.trapBubbledEvent(e,t,n)},trapCapturedEvent:function(e,t,n){return g.ReactEventListener.trapCapturedEvent(e,t,n)},ensureScrollValueMonitoring:function(){if(!p){var e=l.refreshScrollValues;g.ReactEventListener.monitorScrollValue(e),p=!0}},eventNameDispatchConfigs:o.eventNameDispatchConfigs,registrationNameModules:o.registrationNameModules,putListener:o.putListener,getListener:o.getListener,deleteListener:o.deleteListener,deleteAllListeners:o.deleteAllListeners});e.exports=g},function(e,t,n){(function(t){"use strict";function r(){var e=p&&p.traverseTwoPhase&&p.traverseEnterLeave;"production"!==t.env.NODE_ENV?l(e,"InstanceHandle not injected before use!"):l(e)}var a=n(264),o=n(198),i=n(265),s=n(266),l=n(201),u={},c=null,d=function(e){if(e){var t=o.executeDispatch,n=a.getPluginModuleForEvent(e);n&&n.executeDispatch&&(t=n.executeDispatch),o.executeDispatchesInOrder(e,t),e.isPersistent()||e.constructor.release(e)}},p=null,f={injection:{injectMount:o.injection.injectMount,injectInstanceHandle:function(e){p=e,"production"!==t.env.NODE_ENV&&r()},getInstanceHandle:function(){return"production"!==t.env.NODE_ENV&&r(),p},injectEventPluginOrder:a.injectEventPluginOrder,injectEventPluginsByName:a.injectEventPluginsByName},eventNameDispatchConfigs:a.eventNameDispatchConfigs,registrationNameModules:a.registrationNameModules,putListener:function(e,n,r){"production"!==t.env.NODE_ENV?l(!r||"function"==typeof r,"Expected %s listener to be a function, instead got type %s",n,typeof r):l(!r||"function"==typeof r);var a=u[n]||(u[n]={});a[e]=r},getListener:function(e,t){var n=u[t];return n&&n[e]},deleteListener:function(e,t){var n=u[t];n&&delete n[e]},deleteAllListeners:function(e){for(var t in u)delete u[t][e]},extractEvents:function(e,t,n,r){for(var o,s=a.plugins,l=0,u=s.length;u>l;l++){var c=s[l];if(c){var d=c.extractEvents(e,t,n,r);d&&(o=i(o,d))}}return o},enqueueEvents:function(e){e&&(c=i(c,e))},processEventQueue:function(){var e=c;c=null,s(e,d),"production"!==t.env.NODE_ENV?l(!c,"processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented."):l(!c)},__purge:function(){u={}},__getListenerBank:function(){return u}};e.exports=f}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(){if(s)for(var e in l){var n=l[e],r=s.indexOf(e);if("production"!==t.env.NODE_ENV?i(r>-1,"EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.",e):i(r>-1),!u.plugins[r]){"production"!==t.env.NODE_ENV?i(n.extractEvents,"EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.",e):i(n.extractEvents),u.plugins[r]=n;var o=n.eventTypes;for(var c in o)"production"!==t.env.NODE_ENV?i(a(o[c],n,c),"EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.",c,e):i(a(o[c],n,c))}}}function a(e,n,r){"production"!==t.env.NODE_ENV?i(!u.eventNameDispatchConfigs.hasOwnProperty(r),"EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.",r):i(!u.eventNameDispatchConfigs.hasOwnProperty(r)),u.eventNameDispatchConfigs[r]=e;var a=e.phasedRegistrationNames;if(a){for(var s in a)if(a.hasOwnProperty(s)){var l=a[s];o(l,n,r)}return!0}return e.registrationName?(o(e.registrationName,n,r),!0):!1}function o(e,n,r){"production"!==t.env.NODE_ENV?i(!u.registrationNameModules[e],"EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.",e):i(!u.registrationNameModules[e]),u.registrationNameModules[e]=n,u.registrationNameDependencies[e]=n.eventTypes[r].dependencies}var i=n(201),s=null,l={},u={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(e){"production"!==t.env.NODE_ENV?i(!s,"EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React."):i(!s),s=Array.prototype.slice.call(e),r()},injectEventPluginsByName:function(e){var n=!1;for(var a in e)if(e.hasOwnProperty(a)){var o=e[a];l.hasOwnProperty(a)&&l[a]===o||("production"!==t.env.NODE_ENV?i(!l[a],"EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.",a):i(!l[a]),l[a]=o,n=!0)}n&&r()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return u.registrationNameModules[t.registrationName]||null;for(var n in t.phasedRegistrationNames)if(t.phasedRegistrationNames.hasOwnProperty(n)){var r=u.registrationNameModules[t.phasedRegistrationNames[n]];if(r)return r}return null},_resetEventPlugins:function(){s=null;for(var e in l)l.hasOwnProperty(e)&&delete l[e];u.plugins.length=0;var t=u.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=u.registrationNameModules;for(var a in r)r.hasOwnProperty(a)&&delete r[a]}};e.exports=u}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(e,n){if("production"!==t.env.NODE_ENV?a(null!=n,"accumulateInto(...): Accumulated items must not be null or undefined."):a(null!=n),null==e)return n;var r=Array.isArray(e),o=Array.isArray(n);return r&&o?(e.push.apply(e,n),e):r?(e.push(n),e):o?[e].concat(n):[e,n]}var a=n(201);e.exports=r}).call(t,n(175))},function(e,t){"use strict";var n=function(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)};e.exports=n},function(e,t,n){"use strict";function r(e){a.enqueueEvents(e),a.processEventQueue()}var a=n(263),o={handleTopLevel:function(e,t,n,o){var i=a.extractEvents(e,t,n,o);r(i)}};e.exports=o},function(e,t){"use strict";var n={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(e){n.currentScrollLeft=e.x,n.currentScrollTop=e.y}};e.exports=n},function(e,t,n){"use strict";/** + * Checks if an event is supported in the current execution environment. + * + * NOTE: This will not work correctly for non-generic events such as `change`, + * `reset`, `load`, `error`, and `select`. + * + * Borrows from Modernizr. + * + * @param {string} eventNameSuffix Event name, e.g. "click". + * @param {?boolean} capture Check if the capture phase is supported. + * @return {boolean} True if the event is supported. + * @internal + * @license Modernizr 3.0.0pre (Custom Build) | MIT + */ +function r(e,t){if(!o.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,r=n in document;if(!r){var i=document.createElement("div");i.setAttribute(n,"return;"),r="function"==typeof i[n]}return!r&&a&&"wheel"===e&&(r=document.implementation.hasFeature("Events.wheel","3.0")),r}var a,o=n(245);o.canUseDOM&&(a=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),e.exports=r},function(e,t,n){(function(t){"use strict";function r(e){c[e]=!0}function a(e){delete c[e]}function o(e){return!!c[e]}var i,s=n(205),l=n(219),u=n(201),c={},d={injectEmptyComponent:function(e){i=s.createFactory(e)}},p=function(){};p.prototype.componentDidMount=function(){var e=l.get(this);e&&r(e._rootNodeID)},p.prototype.componentWillUnmount=function(){var e=l.get(this);e&&a(e._rootNodeID)},p.prototype.render=function(){return"production"!==t.env.NODE_ENV?u(i,"Trying to return null from a render, but no null placeholder component was injected."):u(i),i()};var f=s.createElement(p),h={emptyElement:f,injection:d,isNullComponentID:o};e.exports=h}).call(t,n(175))},function(e,t,n){"use strict";var r=n(272),a={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return e.replace(">"," "+a.CHECKSUM_ATTR_NAME+'="'+t+'">')},canReuseMarkup:function(e,t){var n=t.getAttribute(a.CHECKSUM_ATTR_NAME);n=n&&parseInt(n,10);var o=r(e);return o===n}};e.exports=a},function(e,t){"use strict";function n(e){for(var t=1,n=0,a=0;a is being rendered by both %s and %s using the same key (%s) in the same place. Currently, this means that they don't preserve state. This behavior should be very rare so we're considering deprecating it. Please contact the React team and explain your use case so that we can take that into consideration.",u||"Unknown Component",s||"[Unknown]",l||"[Unknown]",e.key):null))),i}}return!1}var a=n(209);e.exports=r}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(e){e&&(null!=e.dangerouslySetInnerHTML&&("production"!==t.env.NODE_ENV?y(null==e.children,"Can only set one of `children` or `props.dangerouslySetInnerHTML`."):y(null==e.children),"production"!==t.env.NODE_ENV?y("object"==typeof e.dangerouslySetInnerHTML&&"__html"in e.dangerouslySetInnerHTML,"`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information."):y("object"==typeof e.dangerouslySetInnerHTML&&"__html"in e.dangerouslySetInnerHTML)),"production"!==t.env.NODE_ENV&&("production"!==t.env.NODE_ENV?_(null==e.innerHTML,"Directly setting property `innerHTML` is not permitted. For more information, lookup documentation on `dangerouslySetInnerHTML`."):null,"production"!==t.env.NODE_ENV?_(!e.contentEditable||null==e.children,"A component is `contentEditable` and contains `children` managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional."):null),"production"!==t.env.NODE_ENV?y(null==e.style||"object"==typeof e.style,"The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX."):y(null==e.style||"object"==typeof e.style))}function a(e,n,r,a){"production"!==t.env.NODE_ENV&&("production"!==t.env.NODE_ENV?_("onScroll"!==n||b("scroll",!0),"This browser doesn't support the `onScroll` event"):null);var o=p.findReactContainerForID(e);if(o){var i=o.nodeType===S?o.ownerDocument:o;k(n,i)}a.getPutListenerQueue().enqueuePutListener(e,n,r)}function o(e){T.call(C,e)||("production"!==t.env.NODE_ENV?y(j.test(e),"Invalid tag: %s",e):y(j.test(e)),C[e]=!0)}function i(e){o(e),this._tag=e,this._renderedChildren=null,this._previousStyleCopy=null,this._rootNodeID=null}var s=n(243),l=n(238),u=n(237),c=n(262),d=n(241),p=n(261),f=n(282),h=n(222),m=n(207),g=n(240),y=n(201),b=n(269),v=n(233),_=n(209),w=c.deleteListener,k=c.listenTo,E=c.registrationNameModules,x={string:!0,number:!0},O=v({style:null}),S=1,P=null,A={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},j=/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/,C={},T={}.hasOwnProperty;i.displayName="ReactDOMComponent",i.Mixin={construct:function(e){this._currentElement=e},mountComponent:function(e,t,n){this._rootNodeID=e,r(this._currentElement.props);var a=A[this._tag]?"":"";return this._createOpenTagMarkupAndPutListeners(t)+this._createContentMarkup(t,n)+a},_createOpenTagMarkupAndPutListeners:function(e){var t=this._currentElement.props,n="<"+this._tag;for(var r in t)if(t.hasOwnProperty(r)){var o=t[r];if(null!=o)if(E.hasOwnProperty(r))a(this._rootNodeID,r,o,e);else{r===O&&(o&&(o=this._previousStyleCopy=m({},t.style)),o=s.createMarkupForStyles(o));var i=u.createMarkupForProperty(r,o);i&&(n+=" "+i)}}if(e.renderToStaticMarkup)return n+">";var l=u.createMarkupForID(this._rootNodeID);return n+" "+l+">"},_createContentMarkup:function(e,t){var n="";("listing"===this._tag||"pre"===this._tag||"textarea"===this._tag)&&(n="\n");var r=this._currentElement.props,a=r.dangerouslySetInnerHTML;if(null!=a){if(null!=a.__html)return n+a.__html}else{var o=x[typeof r.children]?r.children:null,i=null!=o?null:r.children;if(null!=o)return n+g(o);if(null!=i){var s=this.mountChildren(i,e,t);return n+s.join("")}}return n},receiveComponent:function(e,t,n){var r=this._currentElement;this._currentElement=e,this.updateComponent(t,r,e,n)},updateComponent:function(e,t,n,a){r(this._currentElement.props),this._updateDOMProperties(t.props,e),this._updateDOMChildren(t.props,e,a)},_updateDOMProperties:function(e,t){var n,r,o,i=this._currentElement.props;for(n in e)if(!i.hasOwnProperty(n)&&e.hasOwnProperty(n))if(n===O){var s=this._previousStyleCopy;for(r in s)s.hasOwnProperty(r)&&(o=o||{},o[r]="");this._previousStyleCopy=null}else E.hasOwnProperty(n)?w(this._rootNodeID,n):(l.isStandardName[n]||l.isCustomAttribute(n))&&P.deletePropertyByID(this._rootNodeID,n);for(n in i){var u=i[n],c=n===O?this._previousStyleCopy:e[n];if(i.hasOwnProperty(n)&&u!==c)if(n===O)if(u?u=this._previousStyleCopy=m({},u):this._previousStyleCopy=null,c){for(r in c)!c.hasOwnProperty(r)||u&&u.hasOwnProperty(r)||(o=o||{},o[r]="");for(r in u)u.hasOwnProperty(r)&&c[r]!==u[r]&&(o=o||{},o[r]=u[r])}else o=u;else E.hasOwnProperty(n)?a(this._rootNodeID,n,u,t):(l.isStandardName[n]||l.isCustomAttribute(n))&&P.updatePropertyByID(this._rootNodeID,n,u)}o&&P.updateStylesByID(this._rootNodeID,o)},_updateDOMChildren:function(e,t,n){var r=this._currentElement.props,a=x[typeof e.children]?e.children:null,o=x[typeof r.children]?r.children:null,i=e.dangerouslySetInnerHTML&&e.dangerouslySetInnerHTML.__html,s=r.dangerouslySetInnerHTML&&r.dangerouslySetInnerHTML.__html,l=null!=a?null:e.children,u=null!=o?null:r.children,c=null!=a||null!=i,d=null!=o||null!=s;null!=l&&null==u?this.updateChildren(null,t,n):c&&!d&&this.updateTextContent(""),null!=o?a!==o&&this.updateTextContent(""+o):null!=s?i!==s&&P.updateInnerHTMLByID(this._rootNodeID,s):null!=u&&this.updateChildren(u,t,n)},unmountComponent:function(){this.unmountChildren(),c.deleteAllListeners(this._rootNodeID),d.unmountIDFromEnvironment(this._rootNodeID),this._rootNodeID=null}},h.measureMethods(i,"ReactDOMComponent",{mountComponent:"mountComponent",updateComponent:"updateComponent"}),m(i.prototype,i.Mixin,f.Mixin),i.injection={injectIDOperations:function(e){i.BackendIDOperations=P=e}},e.exports=i}).call(t,n(175))},function(e,t,n){"use strict";function r(e,t,n){h.push({parentID:e,parentNode:null,type:c.INSERT_MARKUP,markupIndex:m.push(t)-1,textContent:null,fromIndex:null,toIndex:n})}function a(e,t,n){h.push({parentID:e,parentNode:null,type:c.MOVE_EXISTING,markupIndex:null,textContent:null,fromIndex:t,toIndex:n})}function o(e,t){h.push({parentID:e,parentNode:null,type:c.REMOVE_NODE,markupIndex:null,textContent:null,fromIndex:t,toIndex:null})}function i(e,t){h.push({parentID:e,parentNode:null,type:c.TEXT_CONTENT,markupIndex:null,textContent:t,fromIndex:null,toIndex:null})}function s(){h.length&&(u.processChildrenUpdates(h,m),l())}function l(){h.length=0,m.length=0}var u=n(279),c=n(258),d=n(223),p=n(283),f=0,h=[],m=[],g={Mixin:{mountChildren:function(e,t,n){var r=p.instantiateChildren(e,t,n);this._renderedChildren=r;var a=[],o=0;for(var i in r)if(r.hasOwnProperty(i)){var s=r[i],l=this._rootNodeID+i,u=d.mountComponent(s,l,t,n);s._mountIndex=o,a.push(u),o++}return a},updateTextContent:function(e){f++;var t=!0;try{var n=this._renderedChildren;p.unmountChildren(n);for(var r in n)n.hasOwnProperty(r)&&this._unmountChildByName(n[r],r);this.setTextContent(e),t=!1}finally{f--,f||(t?l():s())}},updateChildren:function(e,t,n){f++;var r=!0;try{this._updateChildren(e,t,n),r=!1}finally{f--,f||(r?l():s())}},_updateChildren:function(e,t,n){var r=this._renderedChildren,a=p.updateChildren(r,e,t,n);if(this._renderedChildren=a,a||r){var o,i=0,s=0;for(o in a)if(a.hasOwnProperty(o)){var l=r&&r[o],u=a[o];l===u?(this.moveChild(l,s,i),i=Math.max(l._mountIndex,i),l._mountIndex=s):(l&&(i=Math.max(l._mountIndex,i),this._unmountChildByName(l,o)),this._mountChildByNameAtIndex(u,o,s,t,n)),s++}for(o in r)!r.hasOwnProperty(o)||a&&a.hasOwnProperty(o)||this._unmountChildByName(r[o],o)}},unmountChildren:function(){var e=this._renderedChildren;p.unmountChildren(e),this._renderedChildren=null},moveChild:function(e,t,n){e._mountIndex8&&11>=E),S=32,P=String.fromCharCode(S),A=f.topLevelTypes,j={beforeInput:{phasedRegistrationNames:{bubbled:v({onBeforeInput:null}),captured:v({onBeforeInputCapture:null})},dependencies:[A.topCompositionEnd,A.topKeyPress,A.topTextInput,A.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:v({onCompositionEnd:null}),captured:v({onCompositionEndCapture:null})},dependencies:[A.topBlur,A.topCompositionEnd,A.topKeyDown,A.topKeyPress,A.topKeyUp,A.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:v({onCompositionStart:null}),captured:v({onCompositionStartCapture:null})},dependencies:[A.topBlur,A.topCompositionStart,A.topKeyDown,A.topKeyPress,A.topKeyUp,A.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:v({onCompositionUpdate:null}),captured:v({onCompositionUpdateCapture:null})},dependencies:[A.topBlur,A.topCompositionUpdate,A.topKeyDown,A.topKeyPress,A.topKeyUp,A.topMouseDown]}},C=!1,T=null,D={eventTypes:j,extractEvents:function(e,t,n,r){return[u(e,t,n,r),p(e,t,n,r)]}};e.exports=D},function(e,t,n){(function(t){"use strict";function r(e,t,n){var r=t.dispatchConfig.phasedRegistrationNames[n];return g(e,r)}function a(e,n,a){if("production"!==t.env.NODE_ENV&&!e)throw new Error("Dispatching id must not be null");var o=n?m.bubbled:m.captured,i=r(e,a,o);i&&(a._dispatchListeners=f(a._dispatchListeners,i),a._dispatchIDs=f(a._dispatchIDs,e))}function o(e){e&&e.dispatchConfig.phasedRegistrationNames&&p.injection.getInstanceHandle().traverseTwoPhase(e.dispatchMarker,a,e)}function i(e,t,n){if(n&&n.dispatchConfig.registrationName){var r=n.dispatchConfig.registrationName,a=g(e,r);a&&(n._dispatchListeners=f(n._dispatchListeners,a),n._dispatchIDs=f(n._dispatchIDs,e))}}function s(e){e&&e.dispatchConfig.registrationName&&i(e.dispatchMarker,null,e)}function l(e){h(e,o)}function u(e,t,n,r){p.injection.getInstanceHandle().traverseEnterLeave(n,r,i,e,t)}function c(e){h(e,s)}var d=n(199),p=n(263),f=n(265),h=n(266),m=d.PropagationPhases,g=p.getListener,y={accumulateTwoPhaseDispatches:l,accumulateDirectDispatches:c,accumulateEnterLeaveDispatches:u};e.exports=y}).call(t,n(175))},function(e,t,n){"use strict";function r(e){this._root=e,this._startText=this.getText(),this._fallbackText=null}var a=n(203),o=n(207),i=n(289);o(r.prototype,{getText:function(){return"value"in this._root?this._root.value:this._root[i()]},getData:function(){if(this._fallbackText)return this._fallbackText;var e,t,n=this._startText,r=n.length,a=this.getText(),o=a.length;for(e=0;r>e&&n[e]===a[e];e++);var i=r-e;for(t=1;i>=t&&n[r-t]===a[o-t];t++);var s=t>1?1-t:void 0;return this._fallbackText=a.slice(e,s),this._fallbackText}}),a.addPoolingTo(r),e.exports=r},function(e,t,n){"use strict";function r(){return!o&&a.canUseDOM&&(o="textContent"in document.documentElement?"textContent":"innerText"),o}var a=n(245),o=null;e.exports=r},function(e,t,n){"use strict";function r(e,t,n){a.call(this,e,t,n)}var a=n(291),o={data:null};a.augmentClass(r,o),e.exports=r},function(e,t,n){"use strict";function r(e,t,n){this.dispatchConfig=e,this.dispatchMarker=t,this.nativeEvent=n;var r=this.constructor.Interface;for(var a in r)if(r.hasOwnProperty(a)){ +var o=r[a];o?this[a]=o(n):this[a]=n[a]}var s=null!=n.defaultPrevented?n.defaultPrevented:n.returnValue===!1;s?this.isDefaultPrevented=i.thatReturnsTrue:this.isDefaultPrevented=i.thatReturnsFalse,this.isPropagationStopped=i.thatReturnsFalse}var a=n(203),o=n(207),i=n(210),s=n(292),l={type:null,target:s,currentTarget:i.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};o(r.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e.preventDefault?e.preventDefault():e.returnValue=!1,this.isDefaultPrevented=i.thatReturnsTrue},stopPropagation:function(){var e=this.nativeEvent;e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,this.isPropagationStopped=i.thatReturnsTrue},persist:function(){this.isPersistent=i.thatReturnsTrue},isPersistent:i.thatReturnsFalse,destructor:function(){var e=this.constructor.Interface;for(var t in e)this[t]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),r.Interface=l,r.augmentClass=function(e,t){var n=this,r=Object.create(n.prototype);o(r,e.prototype),e.prototype=r,e.prototype.constructor=e,e.Interface=o({},n.Interface,t),e.augmentClass=n.augmentClass,a.addPoolingTo(e,a.threeArgumentPooler)},a.addPoolingTo(r,a.threeArgumentPooler),e.exports=r},function(e,t){"use strict";function n(e){var t=e.target||e.srcElement||window;return 3===t.nodeType?t.parentNode:t}e.exports=n},function(e,t,n){"use strict";function r(e,t,n){a.call(this,e,t,n)}var a=n(291),o={data:null};a.augmentClass(r,o),e.exports=r},function(e,t,n){"use strict";function r(e){return"SELECT"===e.nodeName||"INPUT"===e.nodeName&&"file"===e.type}function a(e){var t=E.getPooled(A.change,C,e);_.accumulateTwoPhaseDispatches(t),k.batchedUpdates(o,t)}function o(e){v.enqueueEvents(e),v.processEventQueue()}function i(e,t){j=e,C=t,j.attachEvent("onchange",a)}function s(){j&&(j.detachEvent("onchange",a),j=null,C=null)}function l(e,t,n){return e===P.topChange?n:void 0}function u(e,t,n){e===P.topFocus?(s(),i(t,n)):e===P.topBlur&&s()}function c(e,t){j=e,C=t,T=e.value,D=Object.getOwnPropertyDescriptor(e.constructor.prototype,"value"),Object.defineProperty(j,"value",z),j.attachEvent("onpropertychange",p)}function d(){j&&(delete j.value,j.detachEvent("onpropertychange",p),j=null,C=null,T=null,D=null)}function p(e){if("value"===e.propertyName){var t=e.srcElement.value;t!==T&&(T=t,a(e))}}function f(e,t,n){return e===P.topInput?n:void 0}function h(e,t,n){e===P.topFocus?(d(),c(t,n)):e===P.topBlur&&d()}function m(e,t,n){return e!==P.topSelectionChange&&e!==P.topKeyUp&&e!==P.topKeyDown||!j||j.value===T?void 0:(T=j.value,C)}function g(e){return"INPUT"===e.nodeName&&("checkbox"===e.type||"radio"===e.type)}function y(e,t,n){return e===P.topClick?n:void 0}var b=n(199),v=n(263),_=n(287),w=n(245),k=n(220),E=n(291),x=n(269),O=n(295),S=n(233),P=b.topLevelTypes,A={change:{phasedRegistrationNames:{bubbled:S({onChange:null}),captured:S({onChangeCapture:null})},dependencies:[P.topBlur,P.topChange,P.topClick,P.topFocus,P.topInput,P.topKeyDown,P.topKeyUp,P.topSelectionChange]}},j=null,C=null,T=null,D=null,M=!1;w.canUseDOM&&(M=x("change")&&(!("documentMode"in document)||document.documentMode>8));var N=!1;w.canUseDOM&&(N=x("input")&&(!("documentMode"in document)||document.documentMode>9));var z={get:function(){return D.get.call(this)},set:function(e){T=""+e,D.set.call(this,e)}},I={eventTypes:A,extractEvents:function(e,t,n,a){var o,i;if(r(t)?M?o=l:i=u:O(t)?N?o=f:(o=m,i=h):g(t)&&(o=y),o){var s=o(e,t,n);if(s){var c=E.getPooled(A.change,s,a);return _.accumulateTwoPhaseDispatches(c),c}}i&&i(e,t,n)}};e.exports=I},function(e,t){"use strict";function n(e){return e&&("INPUT"===e.nodeName&&r[e.type]||"TEXTAREA"===e.nodeName)}var r={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};e.exports=n},function(e,t){"use strict";var n=0,r={createReactRootIndex:function(){return n++}};e.exports=r},function(e,t,n){"use strict";var r=n(233),a=[r({ResponderEventPlugin:null}),r({SimpleEventPlugin:null}),r({TapEventPlugin:null}),r({EnterLeaveEventPlugin:null}),r({ChangeEventPlugin:null}),r({SelectEventPlugin:null}),r({BeforeInputEventPlugin:null}),r({AnalyticsEventPlugin:null}),r({MobileSafariClickEventPlugin:null})];e.exports=a},function(e,t,n){"use strict";var r=n(199),a=n(287),o=n(299),i=n(261),s=n(233),l=r.topLevelTypes,u=i.getFirstReactDOM,c={mouseEnter:{registrationName:s({onMouseEnter:null}),dependencies:[l.topMouseOut,l.topMouseOver]},mouseLeave:{registrationName:s({onMouseLeave:null}),dependencies:[l.topMouseOut,l.topMouseOver]}},d=[null,null],p={eventTypes:c,extractEvents:function(e,t,n,r){if(e===l.topMouseOver&&(r.relatedTarget||r.fromElement))return null;if(e!==l.topMouseOut&&e!==l.topMouseOver)return null;var s;if(t.window===t)s=t;else{var p=t.ownerDocument;s=p?p.defaultView||p.parentWindow:window}var f,h;if(e===l.topMouseOut?(f=t,h=u(r.relatedTarget||r.toElement)||s):(f=s,h=t),f===h)return null;var m=f?i.getID(f):"",g=h?i.getID(h):"",y=o.getPooled(c.mouseLeave,m,r);y.type="mouseleave",y.target=f,y.relatedTarget=h;var b=o.getPooled(c.mouseEnter,g,r);return b.type="mouseenter",b.target=h,b.relatedTarget=f,a.accumulateEnterLeaveDispatches(y,b,m,g),d[0]=y,d[1]=b,d}};e.exports=p},function(e,t,n){"use strict";function r(e,t,n){a.call(this,e,t,n)}var a=n(300),o=n(268),i=n(301),s={screenX:null,screenY:null,clientX:null,clientY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:i,button:function(e){var t=e.button;return"which"in e?t:2===t?2:4===t?1:0},buttons:null,relatedTarget:function(e){return e.relatedTarget||(e.fromElement===e.srcElement?e.toElement:e.fromElement)},pageX:function(e){return"pageX"in e?e.pageX:e.clientX+o.currentScrollLeft},pageY:function(e){return"pageY"in e?e.pageY:e.clientY+o.currentScrollTop}};a.augmentClass(r,s),e.exports=r},function(e,t,n){"use strict";function r(e,t,n){a.call(this,e,t,n)}var a=n(291),o=n(292),i={view:function(e){if(e.view)return e.view;var t=o(e);if(null!=t&&t.window===t)return t;var n=t.ownerDocument;return n?n.defaultView||n.parentWindow:window},detail:function(e){return e.detail||0}};a.augmentClass(r,i),e.exports=r},function(e,t){"use strict";function n(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=a[e];return r?!!n[r]:!1}function r(e){return n}var a={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};e.exports=r},function(e,t,n){"use strict";var r,a=n(238),o=n(245),i=a.injection.MUST_USE_ATTRIBUTE,s=a.injection.MUST_USE_PROPERTY,l=a.injection.HAS_BOOLEAN_VALUE,u=a.injection.HAS_SIDE_EFFECTS,c=a.injection.HAS_NUMERIC_VALUE,d=a.injection.HAS_POSITIVE_NUMERIC_VALUE,p=a.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(o.canUseDOM){var f=document.implementation;r=f&&f.hasFeature&&f.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var h={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:i|l,allowTransparency:i,alt:null,async:l,autoComplete:null,autoPlay:l,cellPadding:null,cellSpacing:null,charSet:i,checked:s|l,classID:i,className:r?i:s,cols:i|d,colSpan:null,content:null,contentEditable:null,contextMenu:i,controls:s|l,coords:null,crossOrigin:null,data:null,dateTime:i,defer:l,dir:null,disabled:i|l,download:p,draggable:null,encType:null,form:i,formAction:i,formEncType:i,formMethod:i,formNoValidate:l,formTarget:i,frameBorder:i,headers:null,height:i,hidden:i|l,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:s,label:null,lang:null,list:i,loop:s|l,low:null,manifest:i,marginHeight:null,marginWidth:null,max:null,maxLength:i,media:i,mediaGroup:null,method:null,min:null,multiple:s|l,muted:s|l,name:null,noValidate:l,open:l,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:s|l,rel:null,required:l,role:i,rows:i|d,rowSpan:null,sandbox:null,scope:null,scoped:l,scrolling:null,seamless:i|l,selected:s|l,shape:null,size:i|d,sizes:i,span:d,spellCheck:null,src:null,srcDoc:s,srcSet:i,start:c,step:null,style:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:s|u,width:i,wmode:i,autoCapitalize:null,autoCorrect:null,itemProp:i,itemScope:i|l,itemType:i,itemID:i,itemRef:i,property:null,unselectable:i},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoCorrect:"autocorrect",autoFocus:"autofocus",autoPlay:"autoplay",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};e.exports=h},function(e,t,n){"use strict";var r=n(199),a=n(210),o=r.topLevelTypes,i={eventTypes:null,extractEvents:function(e,t,n,r){if(e===o.topTouchStart){var i=r.target;i&&!i.onclick&&(i.onclick=a)}}};e.exports=i},function(e,t,n){"use strict";var r=n(305),a={getDOMNode:function(){return r(this)}};e.exports=a},function(e,t,n){(function(t){"use strict";function r(e){if("production"!==t.env.NODE_ENV){var n=a.current;null!==n&&("production"!==t.env.NODE_ENV?u(n._warnedAboutRefsInRender,"%s is accessing getDOMNode or findDOMNode inside its render(). render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.",n.getName()||"A component"):null,n._warnedAboutRefsInRender=!0)}return null==e?null:l(e)?e:o.has(e)?i.getNodeFromInstance(e):("production"!==t.env.NODE_ENV?s(null==e.render||"function"!=typeof e.render,"Component (with keys: %s) contains `render` method but is not mounted in the DOM",Object.keys(e)):s(null==e.render||"function"!=typeof e.render),void("production"!==t.env.NODE_ENV?s(!1,"Element appears to be neither ReactComponent nor DOMNode (keys: %s)",Object.keys(e)):s(!1)))}var a=n(211),o=n(219),i=n(261),s=n(201),l=n(275),u=n(209);e.exports=r}).call(t,n(175))},function(e,t,n){"use strict";function r(){this.reinitializeTransaction()}var a=n(220),o=n(230),i=n(207),s=n(210),l={initialize:s,close:function(){p.isBatchingUpdates=!1}},u={initialize:s,close:a.flushBatchedUpdates.bind(a)},c=[u,l];i(r.prototype,o.Mixin,{getTransactionWrappers:function(){return c}});var d=new r,p={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,a){var o=p.isBatchingUpdates;p.isBatchingUpdates=!0,o?e(t,n,r,a):d.perform(e,null,t,n,r,a)}};e.exports=p},function(e,t,n){"use strict";var r=n(308),a=n(304),o=n(231),i=n(205),s=n(200),l=i.createFactory("button"),u=s({onClick:!0,onDoubleClick:!0,onMouseDown:!0,onMouseMove:!0,onMouseUp:!0,onClickCapture:!0,onDoubleClickCapture:!0,onMouseDownCapture:!0,onMouseMoveCapture:!0,onMouseUpCapture:!0}),c=o.createClass({displayName:"ReactDOMButton",tagName:"BUTTON",mixins:[r,a],render:function(){var e={};for(var t in this.props)!this.props.hasOwnProperty(t)||this.props.disabled&&u[t]||(e[t]=this.props[t]);return l(e,this.props.children)}});e.exports=c},function(e,t,n){"use strict";var r=n(309),a={componentDidMount:function(){this.props.autoFocus&&r(this.getDOMNode())}};e.exports=a},function(e,t){"use strict";function n(e){try{e.focus()}catch(t){}}e.exports=n},function(e,t,n){"use strict";var r=n(199),a=n(311),o=n(304),i=n(231),s=n(205),l=s.createFactory("form"),u=i.createClass({displayName:"ReactDOMForm",tagName:"FORM",mixins:[o,a],render:function(){return l(this.props)},componentDidMount:function(){this.trapBubbledEvent(r.topLevelTypes.topReset,"reset"),this.trapBubbledEvent(r.topLevelTypes.topSubmit,"submit")}});e.exports=u},function(e,t,n){(function(t){"use strict";function r(e){e.remove()}var a=n(262),o=n(265),i=n(266),s=n(201),l={trapBubbledEvent:function(e,n){"production"!==t.env.NODE_ENV?s(this.isMounted(),"Must be mounted to trap events"):s(this.isMounted());var r=this.getDOMNode();"production"!==t.env.NODE_ENV?s(r,"LocalEventTrapMixin.trapBubbledEvent(...): Requires node to be rendered."):s(r);var i=a.trapBubbledEvent(e,n,r);this._localEventListeners=o(this._localEventListeners,i)},componentWillUnmount:function(){this._localEventListeners&&i(this._localEventListeners,r)}};e.exports=l}).call(t,n(175))},function(e,t,n){"use strict";var r=n(199),a=n(311),o=n(304),i=n(231),s=n(205),l=s.createFactory("img"),u=i.createClass({displayName:"ReactDOMImg",tagName:"IMG",mixins:[o,a],render:function(){return l(this.props)},componentDidMount:function(){this.trapBubbledEvent(r.topLevelTypes.topLoad,"load"),this.trapBubbledEvent(r.topLevelTypes.topError,"error")}});e.exports=u},function(e,t,n){"use strict";var r=n(199),a=n(311),o=n(304),i=n(231),s=n(205),l=s.createFactory("iframe"),u=i.createClass({displayName:"ReactDOMIframe",tagName:"IFRAME",mixins:[o,a],render:function(){return l(this.props)},componentDidMount:function(){this.trapBubbledEvent(r.topLevelTypes.topLoad,"load")}});e.exports=u},function(e,t,n){(function(t){"use strict";function r(){this.isMounted()&&this.forceUpdate()}var a=n(308),o=n(237),i=n(315),s=n(304),l=n(231),u=n(205),c=n(261),d=n(220),p=n(207),f=n(201),h=u.createFactory("input"),m={},g=l.createClass({displayName:"ReactDOMInput",tagName:"INPUT",mixins:[a,i.Mixin,s],getInitialState:function(){var e=this.props.defaultValue;return{initialChecked:this.props.defaultChecked||!1,initialValue:null!=e?e:null}},render:function(){var e=p({},this.props);e.defaultChecked=null,e.defaultValue=null;var t=i.getValue(this);e.value=null!=t?t:this.state.initialValue;var n=i.getChecked(this);return e.checked=null!=n?n:this.state.initialChecked,e.onChange=this._handleChange,h(e,this.props.children)},componentDidMount:function(){var e=c.getID(this.getDOMNode());m[e]=this},componentWillUnmount:function(){var e=this.getDOMNode(),t=c.getID(e);delete m[t]},componentDidUpdate:function(e,t,n){var r=this.getDOMNode();null!=this.props.checked&&o.setValueForProperty(r,"checked",this.props.checked||!1);var a=i.getValue(this);null!=a&&o.setValueForProperty(r,"value",""+a)},_handleChange:function(e){var n,a=i.getOnChange(this);a&&(n=a.call(this,e)),d.asap(r,this);var o=this.props.name;if("radio"===this.props.type&&null!=o){for(var s=this.getDOMNode(),l=s;l.parentNode;)l=l.parentNode;for(var u=l.querySelectorAll("input[name="+JSON.stringify(""+o)+'][type="radio"]'),p=0,h=u.length;h>p;p++){var g=u[p];if(g!==s&&g.form===s.form){var y=c.getID(g);"production"!==t.env.NODE_ENV?f(y,"ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported."):f(y);var b=m[y];"production"!==t.env.NODE_ENV?f(b,"ReactDOMInput: Unknown radio button ID %s.",y):f(b),d.asap(r,b)}}}return n}});e.exports=g}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(e){"production"!==t.env.NODE_ENV?u(null==e.props.checkedLink||null==e.props.valueLink,"Cannot provide a checkedLink and a valueLink. If you want to use checkedLink, you probably don't want to use valueLink and vice versa."):u(null==e.props.checkedLink||null==e.props.valueLink)}function a(e){r(e),"production"!==t.env.NODE_ENV?u(null==e.props.value&&null==e.props.onChange,"Cannot provide a valueLink and a value or onChange event. If you want to use value or onChange, you probably don't want to use valueLink."):u(null==e.props.value&&null==e.props.onChange)}function o(e){r(e),"production"!==t.env.NODE_ENV?u(null==e.props.checked&&null==e.props.onChange,"Cannot provide a checkedLink and a checked property or onChange event. If you want to use checked or onChange, you probably don't want to use checkedLink"):u(null==e.props.checked&&null==e.props.onChange)}function i(e){this.props.valueLink.requestChange(e.target.value)}function s(e){this.props.checkedLink.requestChange(e.target.checked)}var l=n(316),u=n(201),c={button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0},d={Mixin:{propTypes:{value:function(e,t,n){return!e[t]||c[e.type]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.")},checked:function(e,t,n){return!e[t]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.")},onChange:l.func}},getValue:function(e){return e.props.valueLink?(a(e),e.props.valueLink.value):e.props.value},getChecked:function(e){return e.props.checkedLink?(o(e),e.props.checkedLink.value):e.props.checked},getOnChange:function(e){return e.props.valueLink?(a(e),i):e.props.checkedLink?(o(e),s):e.props.onChange}};e.exports=d}).call(t,n(175))},function(e,t,n){"use strict";function r(e){function t(t,n,r,a,o){if(a=a||w,null==n[r]){var i=v[o];return t?new Error("Required "+i+" `"+r+"` was not specified in "+("`"+a+"`.")):null}return e(n,r,a,o)}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function a(e){function t(t,n,r,a){var o=t[n],i=m(o);if(i!==e){var s=v[a],l=g(o);return new Error("Invalid "+s+" `"+n+"` of type `"+l+"` "+("supplied to `"+r+"`, expected `"+e+"`."))}return null}return r(t)}function o(){return r(_.thatReturns(null))}function i(e){function t(t,n,r,a){var o=t[n];if(!Array.isArray(o)){var i=v[a],s=m(o);return new Error("Invalid "+i+" `"+n+"` of type "+("`"+s+"` supplied to `"+r+"`, expected an array."))}for(var l=0;l>",k=s(),E=p(),x={array:a("array"),bool:a("boolean"),func:a("function"),number:a("number"),object:a("object"),string:a("string"),any:o(),arrayOf:i,element:k,instanceOf:l,node:E,objectOf:c,oneOf:u,oneOfType:d,shape:f};e.exports=x},function(e,t,n){(function(t){"use strict";var r=n(304),a=n(231),o=n(205),i=n(209),s=o.createFactory("option"),l=a.createClass({displayName:"ReactDOMOption",tagName:"OPTION",mixins:[r],componentWillMount:function(){"production"!==t.env.NODE_ENV&&("production"!==t.env.NODE_ENV?i(null==this.props.selected,"Use the `defaultValue` or `value` props on , and ) reliably and efficiently. To fix this, have a single top-level component that never unmounts render these elements.",this.constructor.displayName):i(!1)},render:function(){return n(this.props)}});return r}var a=n(231),o=n(205),i=n(201);e.exports=r}).call(t,n(175))},function(e,t,n){"use strict";function r(e){return Math.floor(100*e)/100}function a(e,t,n){e[t]=(e[t]||0)+n}var o=n(238),i=n(345),s=n(261),l=n(222),u=n(346),c={_allMeasurements:[],_mountStack:[0],_injected:!1,start:function(){c._injected||l.injection.injectMeasure(c.measure),c._allMeasurements.length=0,l.enableMeasure=!0},stop:function(){l.enableMeasure=!1},getLastMeasurements:function(){return c._allMeasurements},printExclusive:function(e){e=e||c._allMeasurements;var t=i.getExclusiveSummary(e);console.table(t.map(function(e){return{"Component class name":e.componentName,"Total inclusive time (ms)":r(e.inclusive),"Exclusive mount time (ms)":r(e.exclusive),"Exclusive render time (ms)":r(e.render),"Mount time per instance (ms)":r(e.exclusive/e.count),"Render time per instance (ms)":r(e.render/e.count),Instances:e.count}}))},printInclusive:function(e){e=e||c._allMeasurements;var t=i.getInclusiveSummary(e);console.table(t.map(function(e){return{"Owner > component":e.componentName,"Inclusive time (ms)":r(e.time),Instances:e.count}})),console.log("Total time:",i.getTotalTime(e).toFixed(2)+" ms")},getMeasurementsSummaryMap:function(e){var t=i.getInclusiveSummary(e,!0);return t.map(function(e){return{"Owner > component":e.componentName,"Wasted time (ms)":e.time,Instances:e.count}})},printWasted:function(e){e=e||c._allMeasurements,console.table(c.getMeasurementsSummaryMap(e)),console.log("Total time:",i.getTotalTime(e).toFixed(2)+" ms")},printDOM:function(e){e=e||c._allMeasurements;var t=i.getDOMSummary(e);console.table(t.map(function(e){var t={};return t[o.ID_ATTRIBUTE_NAME]=e.id,t.type=e.type,t.args=JSON.stringify(e.args),t})),console.log("Total time:",i.getTotalTime(e).toFixed(2)+" ms")},_recordWrite:function(e,t,n,r){var a=c._allMeasurements[c._allMeasurements.length-1].writes;a[e]=a[e]||[],a[e].push({type:t,time:n,args:r})},measure:function(e,t,n){return function(){for(var r=[],o=0,i=arguments.length;i>o;o++)r.push(arguments[o]);var l,d,p;if("_renderNewRootComponent"===t||"flushBatchedUpdates"===t)return c._allMeasurements.push({exclusive:{},inclusive:{},render:{},counts:{},writes:{},displayNames:{},totalTime:0}),p=u(),d=n.apply(this,r),c._allMeasurements[c._allMeasurements.length-1].totalTime=u()-p,d;if("_mountImageIntoNode"===t||"ReactDOMIDOperations"===e){if(p=u(),d=n.apply(this,r),l=u()-p,"_mountImageIntoNode"===t){var f=s.getID(r[1]);c._recordWrite(f,t,l,r[0])}else"dangerouslyProcessChildrenUpdates"===t?r[0].forEach(function(e){var t={};null!==e.fromIndex&&(t.fromIndex=e.fromIndex),null!==e.toIndex&&(t.toIndex=e.toIndex),null!==e.textContent&&(t.textContent=e.textContent),null!==e.markupIndex&&(t.markup=r[1][e.markupIndex]),c._recordWrite(e.parentID,e.type,l,t)}):c._recordWrite(r[0],t,l,Array.prototype.slice.call(r,1));return d}if("ReactCompositeComponent"!==e||"mountComponent"!==t&&"updateComponent"!==t&&"_renderValidatedComponent"!==t)return n.apply(this,r);if("string"==typeof this._currentElement.type)return n.apply(this,r);var h="mountComponent"===t?r[0]:this._rootNodeID,m="_renderValidatedComponent"===t,g="mountComponent"===t,y=c._mountStack,b=c._allMeasurements[c._allMeasurements.length-1];if(m?a(b.counts,h,1):g&&y.push(0),p=u(),d=n.apply(this,r),l=u()-p,m)a(b.render,h,l);else if(g){var v=y.pop();y[y.length-1]+=l,a(b.exclusive,h,l-v),a(b.inclusive,h,l)}else a(b.inclusive,h,l);return b.displayNames[h]={current:this.getName(),owner:this._currentElement._owner?this._currentElement._owner.getName():""},d}}};e.exports=c},function(e,t,n){function r(e){for(var t=0,n=0;n=u&&s.push(n[t]);return s.sort(function(e,t){return t.exclusive-e.exclusive}),s}function i(e,t){for(var n,r={},a=0;a "+p.current,r[n]=r[n]||{componentName:n,time:0,count:0},i.inclusive[d]&&(r[n].time+=i.inclusive[d]),i.counts[d]&&(r[n].count+=i.counts[d])}}var f=[];for(n in r)r[n].time>=u&&f.push(r[n]);return f.sort(function(e,t){return t.time-e.time}),f}function s(e){var t={},n=Object.keys(e.writes),r=l({},e.exclusive,e.inclusive);for(var a in r){for(var o=!1,i=0;i0&&(t[a]=!0)}return t}var l=n(207),u=1.2,c={_mountImageIntoNode:"set innerHTML",INSERT_MARKUP:"set innerHTML",MOVE_EXISTING:"move",REMOVE_NODE:"remove",TEXT_CONTENT:"set textContent",updatePropertyByID:"update attribute",deletePropertyByID:"delete attribute",updateStylesByID:"update styles",updateInnerHTMLByID:"set innerHTML",dangerouslyReplaceNodeWithMarkupByID:"replace"},d={getExclusiveSummary:o,getInclusiveSummary:i,getDOMSummary:a,getTotalTime:r};e.exports=d},function(e,t,n){var r=n(347);r&&r.now||(r=Date);var a=r.now.bind(r);e.exports=a},function(e,t,n){"use strict";var r,a=n(245);a.canUseDOM&&(r=window.performance||window.msPerformance||window.webkitPerformance),e.exports=r||{}},function(e,t,n){(function(t){"use strict";function r(e){"production"!==t.env.NODE_ENV?d(o.isValidElement(e),"renderToString(): You must pass a valid ReactElement."):d(o.isValidElement(e));var n;try{var r=i.createReactRootID();return n=l.getPooled(!1),n.perform(function(){var t=c(e,null),a=t.mountComponent(r,n,u);return s.addChecksumToMarkup(a)},null)}finally{l.release(n)}}function a(e){"production"!==t.env.NODE_ENV?d(o.isValidElement(e),"renderToStaticMarkup(): You must pass a valid ReactElement."):d(o.isValidElement(e));var n;try{var r=i.createReactRootID();return n=l.getPooled(!0),n.perform(function(){var t=c(e,null);return t.mountComponent(r,n,u)},null)}finally{l.release(n)}}var o=n(205),i=n(213),s=n(271),l=n(349),u=n(208),c=n(277),d=n(201);e.exports={renderToString:r,renderToStaticMarkup:a}}).call(t,n(175))},function(e,t,n){"use strict";function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=e,this.reactMountReady=o.getPooled(null),this.putListenerQueue=i.getPooled()}var a=n(203),o=n(221),i=n(329),s=n(230),l=n(207),u=n(210),c={initialize:function(){this.reactMountReady.reset()},close:u},d={initialize:function(){this.putListenerQueue.reset()},close:u},p=[d,c],f={getTransactionWrappers:function(){return p},getReactMountReady:function(){return this.reactMountReady},getPutListenerQueue:function(){return this.putListenerQueue},destructor:function(){o.release(this.reactMountReady),this.reactMountReady=null,i.release(this.putListenerQueue),this.putListenerQueue=null}};l(r.prototype,s.Mixin,f),a.addPoolingTo(r),e.exports=r},function(e,t,n){(function(t){"use strict";function r(e){return"production"!==t.env.NODE_ENV?o(a.isValidElement(e),"onlyChild must be passed a children with exactly one child."):o(a.isValidElement(e)),e}var a=n(205),o=n(201);e.exports=r}).call(t,n(175))},function(e,t,n){"use strict";t.DefaultRoute=n(352),t.Link=n(365),t.NotFoundRoute=n(366),t.Redirect=n(367),t.Route=n(364),t.ActiveHandler=n(362),t.RouteHandler=t.ActiveHandler,t.HashLocation=n(368),t.HistoryLocation=n(371),t.RefreshLocation=n(372),t.StaticLocation=n(373),t.TestLocation=n(374),t.ImitateBrowserBehavior=n(375),t.ScrollToTopBehavior=n(376),t.History=n(370),t.Navigation=n(377),t.State=n(378),t.createRoute=n(354).createRoute,t.createDefaultRoute=n(354).createDefaultRoute,t.createNotFoundRoute=n(354).createNotFoundRoute,t.createRedirect=n(354).createRedirect,t.createRoutesFromReactChildren=n(379),t.create=n(380),t.run=n(389)},function(e,t,n){"use strict";var r=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},a=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(e.__proto__=t)},o=n(353),i=n(362),s=n(364),l=function(e){function t(){r(this,t),null!=e&&e.apply(this,arguments)}return a(t,e),t}(s);l.propTypes={name:o.string,path:o.falsy,children:o.falsy,handler:o.func.isRequired},l.defaultProps={handler:i},e.exports=l},function(e,t,n){"use strict";var r=n(207),a=n(196).PropTypes,o=n(354),i=r({},a,{falsy:function(e,t,n){return e[t]?new Error("<"+n+'> should not have a "'+t+'" prop'):void 0},route:a.instanceOf(o),router:a.func});e.exports=i},function(e,t,n){"use strict";var r,a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},o=function(){function e(e,t){for(var n=0;n'}}],[{key:"createRoute",value:function(t,n){t=t||{},"string"==typeof t&&(t={path:t});var a=r;a?l(null==t.parentRoute||t.parentRoute===a,"You should not use parentRoute with createRoute inside another route's child callback; it is ignored"):a=t.parentRoute;var o=t.name,i=t.path||o;!i||t.isDefault||t.isNotFound?i=a?a.path:"/":u.isAbsolute(i)?a&&s(i===a.path||0===a.paramNames.length,'You cannot nest path "%s" inside "%s"; the parent requires URL parameters',i,a.path):i=a?u.join(a.path,i):"/"+i,t.isNotFound&&!/\*$/.test(i)&&(i+="*");var c=new e(o,i,t.ignoreScrollBehavior,t.isDefault,t.isNotFound,t.onEnter,t.onLeave,t.handler);if(a&&(c.isDefault?(s(null==a.defaultRoute,"%s may not have more than one default route",a),a.defaultRoute=c):c.isNotFound&&(s(null==a.notFoundRoute,"%s may not have more than one not found route",a),a.notFoundRoute=c),a.appendChild(c)),"function"==typeof n){var d=r;r=c,n.call(c,c),r=d}return c}},{key:"createDefaultRoute",value:function(t){return e.createRoute(i({},t,{isDefault:!0}))}},{key:"createNotFoundRoute",value:function(t){return e.createRoute(i({},t,{isNotFound:!0}))}},{key:"createRedirect",value:function(t){return e.createRoute(i({},t,{path:t.path||t.from||"*",onEnter:function(e,n,r){e.redirect(t.to,t.params||n,t.query||r)}}))}}]),e}();e.exports=c},function(e,t,n){"use strict";function r(e){if(!(e in d)){var t=[],n=e.replace(s,function(e,n){return n?(t.push(n),"([^/?#]+)"):"*"===e?(t.push("splat"),"(.*?)"):"\\"+e});d[e]={matcher:new RegExp("^"+n+"$","i"),paramNames:t}}return d[e]}var a=n(201),o=n(356),i=n(357),s=/:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g,l=/:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g,u=/\/\/\?|\/\?\/|\/\?/g,c=/\?(.*)$/,d={},p={isAbsolute:function(e){return"/"===e.charAt(0)},join:function(e,t){return e.replace(/\/*$/,"/")+t},extractParamNames:function(e){return r(e).paramNames},extractParams:function(e,t){var n=r(e),a=n.matcher,o=n.paramNames,i=t.match(a);if(!i)return null;var s={};return o.forEach(function(e,t){s[e]=i[t+1]}),s},injectParams:function(e,t){t=t||{};var n=0;return e.replace(l,function(r,o){if(o=o||"splat","?"===o.slice(-1)){if(o=o.slice(0,-1),null==t[o])return""}else a(null!=t[o],'Missing "%s" parameter for path "%s"',o,e);var i;return"splat"===o&&Array.isArray(t[o])?(i=t[o][n++],a(null!=i,'Missing splat # %s for path "%s"',n,e)):i=t[o],i}).replace(u,"/")},extractQuery:function(e){var t=e.match(c);return t&&i.parse(t[1])},withoutQuery:function(e){return e.replace(c,"")},withQuery:function(e,t){var n=p.extractQuery(e);n&&(t=t?o(n,t):n);var r=i.stringify(t,{arrayFormat:"brackets"});return r?p.withoutQuery(e)+"?"+r:p.withoutQuery(e)}};e.exports=p},function(e,t){"use strict";function n(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=Object.assign||function(e,t){for(var r,a,o=n(e),i=1;is;++s){var u=i[s];o=Array.isArray(e)?o.concat(a.stringify(e[u],n(t,u),n)):o.concat(a.stringify(e[u],t+"["+u+"]",n))}return o},e.exports=function(e,t){t=t||{};var n="undefined"==typeof t.delimiter?a.delimiter:t.delimiter,r=[];if("object"!=typeof e||null===e)return"";var o;o=t.arrayFormat in a.arrayPrefixGenerators?t.arrayFormat:"indices"in t?t.indices?"indices":"repeat":"indices";for(var i=a.arrayPrefixGenerators[o],s=Object.keys(e),l=0,u=s.length;u>l;++l){var c=s[l];r=r.concat(a.stringify(e[c],c,i))}return r.join(n)}},function(e,t){t.arrayToObject=function(e){for(var t={},n=0,r=e.length;r>n;++n)"undefined"!=typeof e[n]&&(t[n]=e[n]);return t},t.merge=function(e,n){if(!n)return e;if("object"!=typeof n)return Array.isArray(e)?e.push(n):e[n]=!0,e;if("object"!=typeof e)return e=[e].concat(n);Array.isArray(e)&&!Array.isArray(n)&&(e=t.arrayToObject(e));for(var r=Object.keys(n),a=0,o=r.length;o>a;++a){var i=r[a],s=n[i];e[i]?e[i]=t.merge(e[i],s):e[i]=s}return e},t.decode=function(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(t){return e}},t.compact=function(e,n){if("object"!=typeof e||null===e)return e;n=n||[];var r=n.indexOf(e);if(-1!==r)return n[r];if(n.push(e),Array.isArray(e)){for(var a=[],o=0,i=e.length;i>o;++o)"undefined"!=typeof e[o]&&a.push(e[o]);return a}var s=Object.keys(e);for(o=0,i=s.length;i>o;++o){var l=s[o];e[l]=t.compact(e[l],n)}return e},t.isRegExp=function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},t.isBuffer=function(e){return null===e||"undefined"==typeof e?!1:!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))}},function(e,t,n){var r=n(360),a={delimiter:"&",depth:5,arrayLimit:20,parameterLimit:1e3};a.parseValues=function(e,t){for(var n={},a=e.split(t.delimiter,t.parameterLimit===1/0?void 0:t.parameterLimit),o=0,i=a.length;i>o;++o){var s=a[o],l=-1===s.indexOf("]=")?s.indexOf("="):s.indexOf("]=")+1;if(-1===l)n[r.decode(s)]="";else{var u=r.decode(s.slice(0,l)),c=r.decode(s.slice(l+1));if(Object.prototype.hasOwnProperty(u))continue;n.hasOwnProperty(u)?n[u]=[].concat(n[u]).concat(c):n[u]=c}}return n},a.parseObject=function(e,t,n){if(!e.length)return t;var r=e.shift(),o={};if("[]"===r)o=[],o=o.concat(a.parseObject(e,t,n));else{var i="["===r[0]&&"]"===r[r.length-1]?r.slice(1,r.length-1):r,s=parseInt(i,10),l=""+s;!isNaN(s)&&r!==i&&l===i&&s>=0&&s<=n.arrayLimit?(o=[],o[s]=a.parseObject(e,t,n)):o[i]=a.parseObject(e,t,n)}return o},a.parseKeys=function(e,t,n){if(e){var r=/^([^\[\]]*)/,o=/(\[[^\[\]]*\])/g,i=r.exec(e);if(!Object.prototype.hasOwnProperty(i[1])){var s=[];i[1]&&s.push(i[1]);for(var l=0;null!==(i=o.exec(e))&&ls;++s){var u=i[s],c=a.parseKeys(u,n[u],t);o=r.merge(o,c)}return r.compact(o)}},function(e,t,n){"use strict";var r=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},a=function(){function e(e,t){for(var n=0;n"}};e.exports=d},function(e,t){"use strict";var n={PUSH:"push",REPLACE:"replace",POP:"pop"};e.exports=n},function(e,t,n){"use strict";var r=n(201),a=n(245).canUseDOM,o={length:1,back:function(){r(a,"Cannot use History.back without a DOM"),o.length-=1,window.history.back()}};e.exports=o},function(e,t,n){"use strict";function r(e){var t={path:u.getCurrentPath(),type:e};s.forEach(function(e){e.call(u,t)})}function a(e){void 0!==e.state&&r(o.POP)}var o=n(369),i=n(370),s=[],l=!1,u={addChangeListener:function(e){s.push(e),l||(window.addEventListener?window.addEventListener("popstate",a,!1):window.attachEvent("onpopstate",a),l=!0)},removeChangeListener:function(e){s=s.filter(function(t){return t!==e}),0===s.length&&(window.addEventListener?window.removeEventListener("popstate",a,!1):window.removeEvent("onpopstate",a),l=!1)},push:function(e){window.history.pushState({path:e},"",e),i.length+=1,r(o.PUSH)},replace:function(e){window.history.replaceState({path:e},"",e),r(o.REPLACE)},pop:i.back,getCurrentPath:function(){return decodeURI(window.location.pathname+window.location.search)},toString:function(){return""}};e.exports=u},function(e,t,n){"use strict";var r=n(371),a=n(370),o={push:function(e){window.location=e},replace:function(e){window.location.replace(e)},pop:a.back,getCurrentPath:r.getCurrentPath,toString:function(){return""}};e.exports=o},function(e,t,n){"use strict";function r(){i(!1,"You cannot modify a static location")}var a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},o=function(){function e(e,t){for(var n=0;n'}}]),e}();s.prototype.push=r,s.prototype.replace=r,s.prototype.pop=r,e.exports=s},function(e,t,n){"use strict";var r=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},a=function(){function e(e,t){for(var n=0;nn;++n)this.listeners[n].call(this,t)}},{key:"addChangeListener",value:function(e){this.listeners.push(e)}},{key:"removeChangeListener",value:function(e){this.listeners=this.listeners.filter(function(t){return t!==e})}},{key:"push",value:function(e){this.history.push(e),this._updateHistoryLength(),this._notifyChange(i.PUSH)}},{key:"replace",value:function(e){o(this.history.length,"You cannot replace the current path with no history"),this.history[this.history.length-1]=e,this._notifyChange(i.REPLACE)}},{key:"pop",value:function(){this.history.pop(),this._updateHistoryLength(),this._notifyChange(i.POP)}},{key:"getCurrentPath",value:function(){return this.history[this.history.length-1]}},{key:"toString",value:function(){return""}}]),e}();e.exports=l},function(e,t,n){"use strict";var r=n(369),a={updateScrollPosition:function(e,t){switch(t){case r.PUSH:case r.REPLACE:window.scrollTo(0,0);break;case r.POP:e?window.scrollTo(e.x,e.y):window.scrollTo(0,0)}}};e.exports=a},function(e,t){"use strict";var n={updateScrollPosition:function(){window.scrollTo(0,0)}};e.exports=n},function(e,t,n){"use strict";var r=n(353),a={contextTypes:{router:r.router.isRequired},makePath:function(e,t,n){return this.context.router.makePath(e,t,n)},makeHref:function(e,t,n){return this.context.router.makeHref(e,t,n)},transitionTo:function(e,t,n){this.context.router.transitionTo(e,t,n)},replaceWith:function(e,t,n){this.context.router.replaceWith(e,t,n)},goBack:function(){return this.context.router.goBack()}};e.exports=a},function(e,t,n){"use strict";var r=n(353),a={contextTypes:{router:r.router.isRequired},getPath:function(){return this.context.router.getCurrentPath()},getPathname:function(){return this.context.router.getCurrentPathname()},getParams:function(){return this.context.router.getCurrentParams()},getQuery:function(){return this.context.router.getCurrentQuery()},getRoutes:function(){return this.context.router.getCurrentRoutes()},isActive:function(e,t,n){return this.context.router.isActive(e,t,n)}};e.exports=a},function(e,t,n){"use strict";function r(e,t,n){e=e||"UnknownComponent";for(var r in t)if(t.hasOwnProperty(r)){var a=t[r](n,r,e);a instanceof Error&&u(!1,a.message)}}function a(e){var t=l({},e),n=t.handler;return n&&(t.onEnter=n.willTransitionTo,t.onLeave=n.willTransitionFrom),t}function o(e){if(s.isValidElement(e)){var t=e.type,n=l({},t.defaultProps,e.props);return t.propTypes&&r(t.displayName,t.propTypes,n),t===c?f.createDefaultRoute(a(n)):t===d?f.createNotFoundRoute(a(n)):t===p?f.createRedirect(a(n)):f.createRoute(a(n),function(){n.children&&i(n.children)})}}function i(e){var t=[];return s.Children.forEach(e,function(e){(e=o(e))&&t.push(e)}),t}var s=n(196),l=n(207),u=n(209),c=n(352),d=n(366),p=n(367),f=n(354);e.exports=i},function(e,t,n){(function(t){"use strict";function r(e,t){for(var n in t)if(t.hasOwnProperty(n)&&e[n]!==t[n])return!1;return!0}function a(e,t,n,a,o,i){return e.some(function(e){if(e!==t)return!1;for(var s,l=t.paramNames,u=0,c=l.length;c>u;++u)if(s=l[u],a[s]!==n[s])return!1;return r(o,i)&&r(i,o)})}function o(e,t){for(var n,r=0,a=e.length;a>r;++r)n=e[r],n.name&&(p(null==t[n.name],'You may not have more than one route named "%s"',n.name),t[n.name]=n),n.childRoutes&&o(n.childRoutes,t)}function i(e,t){return e.some(function(e){return e.name===t})}function s(e,t){for(var n in t)if(String(e[n])!==String(t[n]))return!1;return!0}function l(e,t){for(var n in t)if(String(e[n])!==String(t[n]))return!1;return!0}function u(e){e=e||{},k(e)&&(e={routes:e});var n=[],r=e.location||D,u=e.scrollBehavior||M,m={},N={},z=null,I=null;"string"==typeof r&&(r=new v(r)),r instanceof v?d(!f||"test"===t.env.NODE_ENV,"You should not use a static location in a DOM environment because the router will not be kept in sync with the current URL"):p(f||r.needsDOM===!1,"You cannot use %s without a DOM",r),r!==y||C()||(r=b);var R=c.createClass({displayName:"Router",statics:{isRunning:!1,cancelPendingTransition:function(){z&&(z.cancel(),z=null)},clearAllRoutes:function(){R.cancelPendingTransition(),R.namedRoutes={},R.routes=[]},addRoutes:function(e){k(e)&&(e=w(e)),o(e,R.namedRoutes),R.routes.push.apply(R.routes,e)},replaceRoutes:function(e){R.clearAllRoutes(),R.addRoutes(e),R.refresh()},match:function(e){return A.findMatch(R.routes,e)},makePath:function(e,t,n){var r;if(T.isAbsolute(e))r=e;else{var a=e instanceof j?e:R.namedRoutes[e];p(a instanceof j,'Cannot find a route named "%s"',e),r=a.path}return T.withQuery(T.injectParams(r,t),n)},makeHref:function(e,t,n){var a=R.makePath(e,t,n);return r===g?"#"+a:a},transitionTo:function(e,t,n){var a=R.makePath(e,t,n);z?r.replace(a):r.push(a)},replaceWith:function(e,t,n){r.replace(R.makePath(e,t,n))},goBack:function(){return S.length>1||r===b?(r.pop(),!0):(d(!1,"goBack() was ignored because there is no router history"),!1)},handleAbort:e.onAbort||function(e){if(r instanceof v)throw new Error("Unhandled aborted transition! Reason: "+e);e instanceof P||(e instanceof O?r.replace(R.makePath(e.to,e.params,e.query)):r.pop())},handleError:e.onError||function(e){throw e},handleLocationChange:function(e){R.dispatch(e.path,e.type)},dispatch:function(e,t){R.cancelPendingTransition();var r=m.path,o=null==t;if(r!==e||o){r&&t===h.PUSH&&R.recordScrollPosition(r);var i=R.match(e);d(null!=i,'No route matches path "%s". Make sure you have somewhere in your routes',e,e),null==i&&(i={});var s,l,u=m.routes||[],c=m.params||{},p=m.query||{},f=i.routes||[],g=i.params||{},y=i.query||{};u.length?(s=u.filter(function(e){return!a(f,e,c,g,p,y)}),l=f.filter(function(e){return!a(u,e,c,g,p,y)})):(s=[],l=f);var b=new E(e,R.replaceWith.bind(R,e));z=b;var v=n.slice(u.length-s.length);E.from(b,s,v,function(n){return n||b.abortReason?I.call(R,n,b):void E.to(b,l,g,y,function(n){I.call(R,n,b,{path:e,action:t,pathname:i.pathname,routes:f,params:g,query:y})})})}},run:function(e){p(!R.isRunning,"Router is already running"),I=function(t,n,r){t&&R.handleError(t),z===n&&(z=null,n.abortReason?R.handleAbort(n.abortReason):e.call(R,R,N=r))},r instanceof v||(r.addChangeListener&&r.addChangeListener(R.handleLocationChange),R.isRunning=!0),R.refresh()},refresh:function(){R.dispatch(r.getCurrentPath(),null)},stop:function(){R.cancelPendingTransition(),r.removeChangeListener&&r.removeChangeListener(R.handleLocationChange),R.isRunning=!1},getLocation:function(){return r},getScrollBehavior:function(){return u},getRouteAtDepth:function(e){var t=m.routes;return t&&t[e]},setRouteComponentAtDepth:function(e,t){n[e]=t},getCurrentPath:function(){return m.path},getCurrentPathname:function(){return m.pathname},getCurrentParams:function(){return m.params},getCurrentQuery:function(){return m.query},getCurrentRoutes:function(){return m.routes},isActive:function(e,t,n){return T.isAbsolute(e)?e===m.path:i(m.routes,e)&&s(m.params,t)&&(null==n||l(m.query,n))}},mixins:[_],propTypes:{children:x.falsy},childContextTypes:{routeDepth:x.number.isRequired,router:x.router.isRequired},getChildContext:function(){return{routeDepth:1,router:R}},getInitialState:function(){return m=N},componentWillReceiveProps:function(){this.setState(m=N)},componentWillUnmount:function(){R.stop()},render:function(){var e=R.getRouteAtDepth(0);return e?c.createElement(e.handler,this.props):null}});return R.clearAllRoutes(),e.routes&&R.addRoutes(e.routes),R}var c=n(196),d=n(209),p=n(201),f=n(245).canUseDOM,h=n(369),m=n(375),g=n(368),y=n(371),b=n(372),v=n(373),_=n(381),w=n(379),k=n(383),E=n(384),x=n(353),O=n(386),S=n(370),P=n(385),A=n(387),j=n(354),C=n(388),T=n(355),D=f?g:"/",M=f?m:null;e.exports=u}).call(t,n(175))},function(e,t,n){"use strict";function r(e,t){if(!t)return!0;if(e.pathname===t.pathname)return!1;var n=e.routes,r=t.routes,a=n.filter(function(e){return-1!==r.indexOf(e)});return!a.some(function(e){return e.ignoreScrollBehavior})}var a=n(201),o=n(245).canUseDOM,i=n(382),s={statics:{recordScrollPosition:function(e){this.scrollHistory||(this.scrollHistory={}),this.scrollHistory[e]=i()},getScrollPosition:function(e){return this.scrollHistory||(this.scrollHistory={}),this.scrollHistory[e]||null}},componentWillMount:function(){a(null==this.constructor.getScrollBehavior()||o,"Cannot use scroll behavior without a DOM")},componentDidMount:function(){this._updateScroll()},componentDidUpdate:function(e,t){this._updateScroll(t)},_updateScroll:function(e){if(r(this.state,e)){var t=this.constructor.getScrollBehavior();t&&t.updateScrollPosition(this.constructor.getScrollPosition(this.state.path),this.state.action)}}};e.exports=s},function(e,t,n){"use strict";function r(){return a(o,"Cannot get current scroll position without a DOM"),{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}}var a=n(201),o=n(245).canUseDOM;e.exports=r},function(e,t,n){"use strict";function r(e){return null==e||o.isValidElement(e)}function a(e){return r(e)||Array.isArray(e)&&e.every(r)}var o=n(196);e.exports=a},function(e,t,n){"use strict";function r(e,t){this.path=e,this.abortReason=null,this.retry=t.bind(this)}var a=n(385),o=n(386);r.prototype.abort=function(e){null==this.abortReason&&(this.abortReason=e||"ABORT")},r.prototype.redirect=function(e,t,n){this.abort(new o(e,t,n))},r.prototype.cancel=function(){this.abort(new a)},r.from=function(e,t,n,r){t.reduce(function(t,r,a){return function(o){if(o||e.abortReason)t(o);else if(r.onLeave)try{r.onLeave(e,n[a],t),r.onLeave.length<3&&t()}catch(i){t(i)}else t()}},r)()},r.to=function(e,t,n,r,a){t.reduceRight(function(t,a){return function(o){if(o||e.abortReason)t(o);else if(a.onEnter)try{a.onEnter(e,n,r,t),a.onEnter.length<4&&t()}catch(i){t(i)}else t()}},a)()},e.exports=r},function(e,t){"use strict";function n(){}e.exports=n},function(e,t){"use strict";function n(e,t,n){this.to=e,this.params=t,this.query=n}e.exports=n},function(e,t,n){"use strict";function r(e,t,n){var a=e.childRoutes;if(a)for(var o,l,u=0,c=a.length;c>u;++u)if(l=a[u],!l.isDefault&&!l.isNotFound&&(o=r(l,t,n)))return o.routes.unshift(e),o;var d=e.defaultRoute;if(d&&(f=i.extractParams(d.path,t)))return new s(t,f,n,[e,d]);var p=e.notFoundRoute;if(p&&(f=i.extractParams(p.path,t)))return new s(t,f,n,[e,p]);var f=i.extractParams(e.path,t);return f?new s(t,f,n,[e]):null}var a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},o=function(){function e(e,t){for(var n=0;ns;++s)o=r(e[s],n,a);return o}}]),e}();e.exports=s},function(e,t){"use strict";function n(){/*! taken from modernizr + * https://github.com/Modernizr/Modernizr/blob/master/LICENSE + * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js + * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 + */ +var e=navigator.userAgent;return-1===e.indexOf("Android 2.")&&-1===e.indexOf("Android 4.0")||-1===e.indexOf("Mobile Safari")||-1!==e.indexOf("Chrome")||-1!==e.indexOf("Windows Phone")?window.history&&"pushState"in window.history:!1}e.exports=n},function(e,t,n){"use strict";function r(e,t,n){"function"==typeof t&&(n=t,t=null);var r=a({routes:e,location:t});return r.run(n),r}var a=n(380);e.exports=r},,,,,,,,,,,,,,,,,,function(e,t,n){"use strict";function r(e){return"string"==typeof e||"[object String]"===Object.prototype.toString.call(e)}function a(e){return"function"==typeof e||"[object Function]"===Object.prototype.toString.call(e)}function o(e){return null===e?!1:"[object Object]"===Object.prototype.toString.call(e)}function i(e){return r(e)&&":"===e[0]}function s(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e,t){return t.reduce(function(e,t){return o(e)&&s(e,t)?e[t]:null},e)}function u(){this._registry={locale:"en",interpolate:!0,fallbackLocale:null,scope:null,translations:{},interpolations:{},normalizedKeys:{},separator:"."},this.registerTranslations("en",n(419)),this.setMaxListeners(0)}function c(){return v.translate.apply(v,arguments)}var d=n(408),p=n(409).isArray,f=n(409).isDate,h=n(412).sprintf,m=n(413),g=n(414),y=n(416),b="counterpart";d(u.prototype,m.EventEmitter.prototype),u.prototype.getLocale=function(){return this._registry.locale},u.prototype.setLocale=function(e){var t=this._registry.locale;return t!=e&&(this._registry.locale=e,this.emit("localechange",e,t)),t},u.prototype.getFallbackLocale=function(){return this._registry.fallbackLocale},u.prototype.setFallbackLocale=function(e){var t=this._registry.fallbackLocale;return this._registry.fallbackLocale=e,t},u.prototype.getAvailableLocales=function(){return this._registry.availableLocales||Object.keys(this._registry.translations)},u.prototype.setAvailableLocales=function(e){var t=this.getAvailableLocales();return this._registry.availableLocales=e,t},u.prototype.getSeparator=function(){return this._registry.separator},u.prototype.setSeparator=function(e){var t=this._registry.separator;return this._registry.separator=e,t},u.prototype.setInterpolate=function(e){var t=this._registry.interpolate;return this._registry.interpolate=e,t},u.prototype.getInterpolate=function(){return this._registry.interpolate},u.prototype.registerTranslations=function(e,t){var n={};return n[e]=t,d(!0,this._registry.translations,n),n},u.prototype.registerInterpolations=function(e){return d(!0,this._registry.interpolations,e)},u.prototype.onLocaleChange=u.prototype.addLocaleChangeListener=function(e){this.addListener("localechange",e)},u.prototype.offLocaleChange=u.prototype.removeLocaleChangeListener=function(e){this.removeListener("localechange",e)},u.prototype.translate=function(e,t){if(!p(e)&&!r(e)||!e.length)throw new Error("invalid argument: key");i(e)&&(e=e.substr(1)),t=d(!0,{},t);var n=t.locale||this._registry.locale;delete t.locale;var a=t.scope||this._registry.scope;delete t.scope;var o=t.separator||this._registry.separator;delete t.separator;var s=t.fallbackLocale||this._registry.fallbackLocale;delete t.fallbackLocale;var u=this._normalizeKeys(n,a,e,o),c=l(this._registry.translations,u);if(null===c&&t.fallback&&(c=this._fallback(n,a,e,t.fallback,t)),null===c&&s&&n!==s){var f=this._normalizeKeys(s,a,e,o);c=l(this._registry.translations,f),c&&(n=s)}return null===c&&(c="missing translation: "+u.join(o)),c=this._pluralize(n,c,t.count),this._registry.interpolate!==!1&&t.interpolate!==!1&&(c=this._interpolate(c,t)),c},u.prototype.localize=function(e,t){if(!f(e))throw new Error("invalid argument: object must be a date");t=d(!0,{},t);var n=t.locale||this._registry.locale,r=t.scope||b,a=t.type||"datetime",o=t.format||"default";return t={locale:n,scope:r,interpolate:!1},o=this.translate(["formats",a,o],d(!0,{},t)),y(e,o,this.translate("names",t))},u.prototype._pluralize=function(e,t,n){if("object"!=typeof t||null===t||"number"!=typeof n)return t;var r=this.translate("pluralize",{locale:e,scope:b});return"[object Function]"!==Object.prototype.toString.call(r)?r:r(t,n)},u.prototype.withLocale=function(e,t,n){var r=this._registry.locale;this._registry.locale=e;var a=t.call(n);return this._registry.locale=r,a},u.prototype.withScope=function(e,t,n){var r=this._registry.scope;this._registry.scope=e;var a=t.call(n);return this._registry.scope=r,a},u.prototype.withSeparator=function(e,t,n){var r=this.setSeparator(e),a=t.call(n);return this.setSeparator(r),a},u.prototype._normalizeKeys=function(e,t,n,r){var a=[];return a=a.concat(this._normalizeKey(e,r)),a=a.concat(this._normalizeKey(t,r)),a=a.concat(this._normalizeKey(n,r))},u.prototype._normalizeKey=function(e,t){return this._registry.normalizedKeys[t]=this._registry.normalizedKeys[t]||{},this._registry.normalizedKeys[t][e]=this._registry.normalizedKeys[t][e]||function(e){if(p(e)){var n=e.map(function(e){return this._normalizeKey(e,t)}.bind(this));return[].concat.apply([],n)}if("undefined"==typeof e||null===e)return[];for(var r=e.split(t),a=r.length-1;a>=0;a--)""===r[a]&&r.splice(a,1);return r}.bind(this)(e),this._registry.normalizedKeys[t][e]},u.prototype._interpolate=function(e,t){return"string"!=typeof e?e:h(e,d({},this._registry.interpolations,t))},u.prototype._resolve=function(e,t,n,r,o){if(o=o||{},o.resolve===!1)return r;var s;if(i(r))s=this.translate(r,d({},o,{locale:e,scope:t}));else if(a(r)){var l;o.object?(l=o.object,delete o.object):l=n,s=this._resolve(e,t,n,r(l,o))}else s=r;return/^missing translation:/.test(s)?null:s},u.prototype._fallback=function(e,t,n,r,a){if(a=g(a,"fallback"),p(r)){for(var o=0,i=r.length;i>o;o++){var s=this._resolve(e,t,n,r[o],a);if(s)return s}return null}return this._resolve(e,t,n,r,a)};var v=new u;d(c,v,{Instance:u}),e.exports=c},function(e,t){"use strict";var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString,a=function(e){return"function"==typeof Array.isArray?Array.isArray(e):"[object Array]"===r.call(e)},o=function(e){if(!e||"[object Object]"!==r.call(e))return!1;var t=n.call(e,"constructor"),a=e.constructor&&e.constructor.prototype&&n.call(e.constructor.prototype,"isPrototypeOf");if(e.constructor&&!t&&!a)return!1;var o;for(o in e);return"undefined"==typeof o||n.call(e,o)};e.exports=function i(){var e,t,n,r,s,l,u=arguments[0],c=1,d=arguments.length,p=!1;for("boolean"==typeof u?(p=u,u=arguments[1]||{},c=2):("object"!=typeof u&&"function"!=typeof u||null==u)&&(u={});d>c;++c)if(e=arguments[c],null!=e)for(t in e)n=u[t],r=e[t],u!==r&&(p&&r&&(o(r)||(s=a(r)))?(s?(s=!1,l=n&&a(n)?n:[]):l=n&&o(n)?n:{},u[t]=i(p,l,r)):"undefined"!=typeof r&&(u[t]=r));return u}},function(e,t,n){(function(e,r){function a(e,n){var r={seen:[],stylize:i};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),m(n)?r.showHidden=n:n&&t._extend(r,n),w(r.showHidden)&&(r.showHidden=!1),w(r.depth)&&(r.depth=2),w(r.colors)&&(r.colors=!1),w(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=o),l(r,e,r.depth)}function o(e,t){var n=a.styles[t];return n?"["+a.colors[n][0]+"m"+e+"["+a.colors[n][1]+"m":e}function i(e,t){return e}function s(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function l(e,n,r){if(e.customInspect&&n&&S(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var a=n.inspect(r,e);return v(a)||(a=l(e,a,r)),a}var o=u(e,n);if(o)return o;var i=Object.keys(n),m=s(i);if(e.showHidden&&(i=Object.getOwnPropertyNames(n)),O(n)&&(i.indexOf("message")>=0||i.indexOf("description")>=0))return c(n);if(0===i.length){if(S(n)){var g=n.name?": "+n.name:"";return e.stylize("[Function"+g+"]","special")}if(k(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(x(n))return e.stylize(Date.prototype.toString.call(n),"date");if(O(n))return c(n)}var y="",b=!1,_=["{","}"];if(h(n)&&(b=!0,_=["[","]"]),S(n)){var w=n.name?": "+n.name:"";y=" [Function"+w+"]"}if(k(n)&&(y=" "+RegExp.prototype.toString.call(n)),x(n)&&(y=" "+Date.prototype.toUTCString.call(n)),O(n)&&(y=" "+c(n)),0===i.length&&(!b||0==n.length))return _[0]+y+_[1];if(0>r)return k(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special");e.seen.push(n);var E;return E=b?d(e,n,r,m,i):i.map(function(t){return p(e,n,r,m,t,b)}),e.seen.pop(),f(E,y,_)}function u(e,t){if(w(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}return b(t)?e.stylize(""+t,"number"):m(t)?e.stylize(""+t,"boolean"):g(t)?e.stylize("null","null"):void 0}function c(e){return"["+Error.prototype.toString.call(e)+"]"}function d(e,t,n,r,a){for(var o=[],i=0,s=t.length;s>i;++i)T(t,String(i))?o.push(p(e,t,n,r,String(i),!0)):o.push("");return a.forEach(function(a){a.match(/^\d+$/)||o.push(p(e,t,n,r,a,!0))}),o}function p(e,t,n,r,a,o){var i,s,u;if(u=Object.getOwnPropertyDescriptor(t,a)||{value:t[a]},u.get?s=u.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):u.set&&(s=e.stylize("[Setter]","special")),T(r,a)||(i="["+a+"]"),s||(e.seen.indexOf(u.value)<0?(s=g(n)?l(e,u.value,null):l(e,u.value,n-1),s.indexOf("\n")>-1&&(s=o?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n"))):s=e.stylize("[Circular]","special")),w(i)){if(o&&a.match(/^\d+$/))return s;i=JSON.stringify(""+a),i.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(i=i.substr(1,i.length-2),i=e.stylize(i,"name")):(i=i.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),i=e.stylize(i,"string"))}return i+": "+s}function f(e,t,n){var r=0,a=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return a>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function h(e){return Array.isArray(e)}function m(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return null==e}function b(e){return"number"==typeof e}function v(e){return"string"==typeof e}function _(e){return"symbol"==typeof e}function w(e){return void 0===e}function k(e){return E(e)&&"[object RegExp]"===A(e)}function E(e){return"object"==typeof e&&null!==e}function x(e){return E(e)&&"[object Date]"===A(e)}function O(e){return E(e)&&("[object Error]"===A(e)||e instanceof Error)}function S(e){return"function"==typeof e}function P(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function A(e){return Object.prototype.toString.call(e)}function j(e){return 10>e?"0"+e.toString(10):e.toString(10)}function C(){var e=new Date,t=[j(e.getHours()),j(e.getMinutes()),j(e.getSeconds())].join(":");return[e.getDate(),z[e.getMonth()],t].join(" ")}function T(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var D=/%[sdj%]/g;t.format=function(e){if(!v(e)){for(var t=[],n=0;n=o)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"}default:return e}}),s=r[n];o>n;s=r[++n])i+=g(s)||!E(s)?" "+s:" "+a(s);return i},t.deprecate=function(n,a){function o(){if(!i){if(r.throwDeprecation)throw new Error(a);r.traceDeprecation?console.trace(a):console.error(a),i=!0}return n.apply(this,arguments)}if(w(e.process))return function(){return t.deprecate(n,a).apply(this,arguments)};if(r.noDeprecation===!0)return n;var i=!1;return o};var M,N={};t.debuglog=function(e){if(w(M)&&(M=r.env.NODE_DEBUG||""),e=e.toUpperCase(),!N[e])if(new RegExp("\\b"+e+"\\b","i").test(M)){var n=r.pid;N[e]=function(){var r=t.format.apply(t,arguments);console.error("%s %d: %s",e,n,r)}}else N[e]=function(){};return N[e]},t.inspect=a,a.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},a.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=h,t.isBoolean=m,t.isNull=g,t.isNullOrUndefined=y,t.isNumber=b,t.isString=v,t.isSymbol=_,t.isUndefined=w,t.isRegExp=k,t.isObject=E,t.isDate=x,t.isError=O,t.isFunction=S,t.isPrimitive=P,t.isBuffer=n(410);var z=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];t.log=function(){console.log("%s - %s",C(),t.format.apply(t,arguments))},t.inherits=n(411),t._extend=function(e,t){if(!t||!E(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e}}).call(t,function(){return this}(),n(175))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},function(e,t){var n=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}function t(e,t){for(var n=[];t>0;n[--t]=e);return n.join("")}var r=function(){return r.cache.hasOwnProperty(arguments[0])||(r.cache[arguments[0]]=r.parse(arguments[0])),r.format.call(null,r.cache[arguments[0]],arguments)};return r.object_stringify=function(e,t,n,a){var o="";if(null!=e)switch(typeof e){case"function":return"[Function"+(e.name?": "+e.name:"")+"]";case"object":if(e instanceof Error)return"["+e.toString()+"]";if(t>=n)return"[Object]";if(a&&(a=a.slice(0),a.push(e)),null!=e.length){o+="[";var i=[];for(var s in e)a&&a.indexOf(e[s])>=0?i.push("[Circular]"):i.push(r.object_stringify(e[s],t+1,n,a));o+=i.join(", ")+"]"}else{if("getMonth"in e)return"Date("+e+")";o+="{";var i=[];for(var l in e)e.hasOwnProperty(l)&&(a&&a.indexOf(e[l])>=0?i.push(l+": [Circular]"):i.push(l+": "+r.object_stringify(e[l],t+1,n,a)));o+=i.join(", ")+"}"}return o;case"string":return'"'+e+'"'}return""+e},r.format=function(a,o){var i,s,l,u,c,d,p,f=1,h=a.length,m="",g=[];for(s=0;h>s;s++)if(m=e(a[s]),"string"===m)g.push(a[s]);else if("array"===m){if(u=a[s],u[2])for(i=o[f],l=0;l=0?"+"+i:i,d=u[4]?"0"==u[4]?"0":u[4].charAt(1):" ",p=u[6]-String(i).length,c=u[6]?t(d,p):"",g.push(u[5]?i+c:c+i)}return g.join("")},r.cache={},r.parse=function(e){for(var t=e,n=[],r=[],a=0;t;){if(null!==(n=/^[^\x25]+/.exec(t)))r.push(n[0]);else if(null!==(n=/^\x25{2}/.exec(t)))r.push("%");else{if(null===(n=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosOuxX])/.exec(t)))throw new Error("[sprintf] "+t);if(n[2]){a|=1;var o=[],i=n[2],s=[];if(null===(s=/^([a-z_][a-z_\d]*)/i.exec(i)))throw new Error("[sprintf] "+i);for(o.push(s[1]);""!==(i=i.substring(s[0].length));)if(null!==(s=/^\.([a-z_][a-z_\d]*)/i.exec(i)))o.push(s[1]);else{if(null===(s=/^\[(\d+)\]/.exec(i)))throw new Error("[sprintf] "+i);o.push(s[1])}n[2]=o}else a|=2;if(3===a)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");r.push(n)}t=t.substring(n[0].length)}return r},r}(),r=function(e,t){var r=t.slice();return r.unshift(e),n.apply(null,r)};e.exports=n,n.sprintf=n,n.vsprintf=r},function(e,t){function n(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function a(e){return"number"==typeof e}function o(e){return"object"==typeof e&&null!==e}function i(e){return void 0===e}e.exports=n,n.EventEmitter=n,n.prototype._events=void 0,n.prototype._maxListeners=void 0,n.defaultMaxListeners=10,n.prototype.setMaxListeners=function(e){if(!a(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},n.prototype.emit=function(e){var t,n,a,s,l,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;throw TypeError('Uncaught, unspecified "error" event.')}if(n=this._events[e],i(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:for(a=arguments.length,s=new Array(a-1),l=1;a>l;l++)s[l-1]=arguments[l];n.apply(this,s)}else if(o(n)){for(a=arguments.length,s=new Array(a-1),l=1;a>l;l++)s[l-1]=arguments[l];for(u=n.slice(),a=u.length,l=0;a>l;l++)u[l].apply(this,s)}return!0},n.prototype.addListener=function(e,t){var a;if(!r(t))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,r(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,o(this._events[e])&&!this._events[e].warned){var a;a=i(this._maxListeners)?n.defaultMaxListeners:this._maxListeners,a&&a>0&&this._events[e].length>a&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())}return this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(e,t){function n(){this.removeListener(e,n),a||(a=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var a=!1;return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var n,a,i,s;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],i=n.length,a=-1,n===t||r(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(s=i;s-->0;)if(n[s]===t||n[s].listener&&n[s].listener===t){a=s;break}if(0>a)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(a,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},n.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],r(n))this.removeListener(e,n);else for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},n.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},n.listenerCount=function(e,t){var n;return n=e._events&&e._events[t]?r(e._events[t])?1:e._events[t].length:0}},[859,415],function(e,t){var n=[].indexOf;e.exports=function(e,t){if(n)return e.indexOf(t);for(var r=0;r0?"-":"+")+a(Math.round(Math.abs(f/60)),2)+":"+a(f%60,2);default:return l}})}function a(e,t,n){"number"==typeof t&&(n=t,t="0"),null===t&&(t="0"),n=n||2;var r=String(e);if(t)for(;r.length12&&(t-=12),t}function i(e){var t=e%10,n=e%100;if(n>=11&&13>=n||0===t||t>=4)return"th";switch(t){case 1:return"st";case 2:return"nd";case 3:return"rd"}}function s(e,t){t=t||"sunday";var n=e.getDay();"monday"==t&&(0===n?n=6:n--);var r=new Date(e.getFullYear(),0,1),a=(e-r)/864e5,o=(a+7-n)/7;return Math.floor(o)}var l=n(417);e.exports=r},function(e,t,n){e.exports=n(418)},function(e,t){e.exports={__locale:"en",days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviated_days:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviated_months:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],am:"AM",pm:"PM"}},function(e,t,n){e.exports={counterpart:{names:n(418),pluralize:n(420),formats:{date:{"default":"%a, %e %b %Y","long":"%A, %B %o, %Y","short":"%b %e"},time:{"default":"%H:%M","long":"%H:%M:%S %z","short":"%H:%M"},datetime:{"default":"%a, %e %b %Y %H:%M","long":"%A, %B %o, %Y %H:%M:%S %z","short":"%e %b %H:%M"}}}}},function(e,t){"use strict";e.exports=function(e,t){var n;return 0===t&&"zero"in e&&(n="zero"),n=n||(1===t?"one":"other"),e[n]}},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){var r,r;!function(t){e.exports=t()}(function(){var e;return function t(e,n,a){function o(s,l){if(!n[s]){if(!e[s]){var u="function"==typeof r&&r;if(!l&&u)return r(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var d=n[s]={exports:{}};e[s][0].call(d.exports,function(t){var n=e[s][1][t];return o(n?n:t)},d,d.exports,t,e,n,a)}return n[s].exports}for(var i="function"==typeof r&&r,s=0;s + * This version of ByteBuffer.js uses an ArrayBuffer (AB) as its backing buffer and is compatible with modern browsers. + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/ByteBuffer.js for details + */ +!function(a){"use strict";function o(e){function t(e){var t=0;return function(){return t1024&&(t.push(s.apply(String,e)),e.length=0),void Array.prototype.push.apply(e,arguments))}}var r=function c(e,t,n){if("undefined"==typeof e&&(e=c.DEFAULT_CAPACITY),"undefined"==typeof t&&(t=c.DEFAULT_ENDIAN),"undefined"==typeof n&&(n=c.DEFAULT_NOASSERT),!n){if(e=0|e,0>e)throw RangeError("Illegal capacity");t=!!t,n=!!n}this.buffer=0===e?o:new ArrayBuffer(e),this.view=0===e?null:new DataView(this.buffer),this.offset=0,this.markedOffset=-1,this.limit=e,this.littleEndian="undefined"!=typeof t?!!t:!1,this.noAssert=!!n};r.VERSION="3.5.4",r.LITTLE_ENDIAN=!0,r.BIG_ENDIAN=!1,r.DEFAULT_CAPACITY=16,r.DEFAULT_ENDIAN=r.BIG_ENDIAN,r.DEFAULT_NOASSERT=!1,r.Long=e||null;var a=r.prototype,o=new ArrayBuffer(0),s=String.fromCharCode;r.allocate=function(e,t,n){return new r(e,t,n)},r.concat=function(e,t,n,a){("boolean"==typeof t||"string"!=typeof t)&&(a=n,n=t,t=void 0);for(var o,i=0,s=0,l=e.length;l>s;++s)r.isByteBuffer(e[s])||(e[s]=r.wrap(e[s],t)),o=e[s].limit-e[s].offset,o>0&&(i+=o);if(0===i)return new r(0,n,a);var u,c=new r(i,n,a),d=new Uint8Array(c.buffer);for(s=0;l>s;)u=e[s++],o=u.limit-u.offset,0>=o||(d.set(new Uint8Array(u.buffer).subarray(u.offset,u.limit),c.offset),c.offset+=o);return c.limit=c.offset,c.offset=0,c},r.isByteBuffer=function(e){return(e&&e instanceof r)===!0},r.type=function(){return ArrayBuffer},r.wrap=function(e,t,n,o){if("string"!=typeof t&&(o=n,n=t,t=void 0),"string"==typeof e)switch("undefined"==typeof t&&(t="utf8"),t){case"base64":return r.fromBase64(e,n);case"hex":return r.fromHex(e,n);case"binary":return r.fromBinary(e,n);case"utf8":return r.fromUTF8(e,n);case"debug":return r.fromDebug(e,n);default:throw Error("Unsupported encoding: "+t)}if(null===e||"object"!=typeof e)throw TypeError("Illegal buffer");var s;if(r.isByteBuffer(e))return s=a.clone.call(e),s.markedOffset=-1,s;if(e instanceof Uint8Array)s=new r(0,n,o),e.length>0&&(s.buffer=e.buffer,s.offset=e.byteOffset,s.limit=e.byteOffset+e.length,s.view=e.length>0?new DataView(e.buffer):null);else if(e instanceof ArrayBuffer)s=new r(0,n,o),e.byteLength>0&&(s.buffer=e,s.offset=0,s.limit=e.byteLength,s.view=e.byteLength>0?new DataView(e):null);else{if("[object Array]"!==Object.prototype.toString.call(e))throw TypeError("Illegal buffer");for(s=new r(e.length,n,o),s.limit=e.length,i=0;i>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var r=this.buffer.byteLength;return t>r&&this.resize((r*=2)>t?r:t),t-=1,this.view.setInt8(t,e),n&&(this.offset+=1),this},a.writeByte=a.writeInt8,a.readInt8=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var n=this.view.getInt8(e);return t&&(this.offset+=1),n},a.readByte=a.readInt8,a.writeUint8=function(e,t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var r=this.buffer.byteLength;return t>r&&this.resize((r*=2)>t?r:t),t-=1,this.view.setUint8(t,e),n&&(this.offset+=1),this},a.readUint8=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var n=this.view.getUint8(e);return t&&(this.offset+=1),n},a.writeInt16=function(e,t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var r=this.buffer.byteLength;return t>r&&this.resize((r*=2)>t?r:t),t-=2,this.view.setInt16(t,e,this.littleEndian),n&&(this.offset+=2),this},a.writeShort=a.writeInt16,a.readInt16=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var n=this.view.getInt16(e,this.littleEndian);return t&&(this.offset+=2),n},a.readShort=a.readInt16,a.writeUint16=function(e,t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var r=this.buffer.byteLength;return t>r&&this.resize((r*=2)>t?r:t),t-=2,this.view.setUint16(t,e,this.littleEndian),n&&(this.offset+=2),this},a.readUint16=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var n=this.view.getUint16(e,this.littleEndian);return t&&(this.offset+=2),n},a.writeInt32=function(e,t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var r=this.buffer.byteLength;return t>r&&this.resize((r*=2)>t?r:t),t-=4,this.view.setInt32(t,e,this.littleEndian),n&&(this.offset+=4),this},a.writeInt=a.writeInt32,a.readInt32=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var n=this.view.getInt32(e,this.littleEndian);return t&&(this.offset+=4),n},a.readInt=a.readInt32,a.writeUint32=function(e,t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var r=this.buffer.byteLength;return t>r&&this.resize((r*=2)>t?r:t),t-=4,this.view.setUint32(t,e,this.littleEndian),n&&(this.offset+=4),this},a.readUint32=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var n=this.view.getUint32(e,this.littleEndian);return t&&(this.offset+=4),n},e&&(a.writeInt64=function(t,n){var r="undefined"==typeof n;if(r&&(n=this.offset),!this.noAssert){if("number"==typeof t)t=e.fromNumber(t);else if(!(t&&t instanceof e))throw TypeError("Illegal value: "+t+" (not an integer or Long)");if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}"number"==typeof t&&(t=e.fromNumber(t)),n+=8;var a=this.buffer.byteLength;return n>a&&this.resize((a*=2)>n?a:n),n-=8,this.littleEndian?(this.view.setInt32(n,t.low,!0),this.view.setInt32(n+4,t.high,!0)):(this.view.setInt32(n,t.high,!1),this.view.setInt32(n+4,t.low,!1)),r&&(this.offset+=8),this},a.writeLong=a.writeInt64,a.readInt64=function(t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+8) <= "+this.buffer.byteLength)}var r=this.littleEndian?new e(this.view.getInt32(t,!0),this.view.getInt32(t+4,!0),!1):new e(this.view.getInt32(t+4,!1),this.view.getInt32(t,!1),!1);return n&&(this.offset+=8),r},a.readLong=a.readInt64,a.writeUint64=function(t,n){var r="undefined"==typeof n;if(r&&(n=this.offset),!this.noAssert){if("number"==typeof t)t=e.fromNumber(t);else if(!(t&&t instanceof e))throw TypeError("Illegal value: "+t+" (not an integer or Long)");if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}"number"==typeof t&&(t=e.fromNumber(t)),n+=8;var a=this.buffer.byteLength;return n>a&&this.resize((a*=2)>n?a:n),n-=8,this.littleEndian?(this.view.setInt32(n,t.low,!0),this.view.setInt32(n+4,t.high,!0)):(this.view.setInt32(n,t.high,!1),this.view.setInt32(n+4,t.low,!1)),r&&(this.offset+=8),this},a.readUint64=function(t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+8) <= "+this.buffer.byteLength)}var r=this.littleEndian?new e(this.view.getInt32(t,!0),this.view.getInt32(t+4,!0),!0):new e(this.view.getInt32(t+4,!1),this.view.getInt32(t,!1),!0);return n&&(this.offset+=8),r}),a.writeFloat32=function(e,t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var r=this.buffer.byteLength;return t>r&&this.resize((r*=2)>t?r:t),t-=4,this.view.setFloat32(t,e,this.littleEndian),n&&(this.offset+=4),this},a.writeFloat=a.writeFloat32,a.readFloat32=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var n=this.view.getFloat32(e,this.littleEndian);return t&&(this.offset+=4),n},a.readFloat=a.readFloat32,a.writeFloat64=function(e,t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=8;var r=this.buffer.byteLength;return t>r&&this.resize((r*=2)>t?r:t),t-=8,this.view.setFloat64(t,e,this.littleEndian),n&&(this.offset+=8),this},a.writeDouble=a.writeFloat64,a.readFloat64=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var n=this.view.getFloat64(e,this.littleEndian);return t&&(this.offset+=8),n},a.readDouble=a.readFloat64,r.MAX_VARINT32_BYTES=5,r.calculateVarint32=function(e){return e>>>=0,128>e?1:16384>e?2:1<<21>e?3:1<<28>e?4:5},r.zigZagEncode32=function(e){return((e|=0)<<1^e>>31)>>>0},r.zigZagDecode32=function(e){return e>>>1^-(1&e)|0},a.writeVarint32=function(e,t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var a,o=r.calculateVarint32(e);t+=o;var i=this.buffer.byteLength;return t>i&&this.resize((i*=2)>t?i:t),t-=o,this.view.setUint8(t,a=128|e),e>>>=0,e>=128?(a=e>>7|128,this.view.setUint8(t+1,a),e>=16384?(a=e>>14|128,this.view.setUint8(t+2,a),e>=1<<21?(a=e>>21|128,this.view.setUint8(t+3,a),e>=1<<28?(this.view.setUint8(t+4,e>>28&15),o=5):(this.view.setUint8(t+3,127&a),o=4)):(this.view.setUint8(t+2,127&a),o=3)):(this.view.setUint8(t+1,127&a),o=2)):(this.view.setUint8(t,127&a),o=1),n?(this.offset+=o,this):o},a.writeVarint32ZigZag=function(e,t){return this.writeVarint32(r.zigZagEncode32(e),t)},a.readVarint32=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var n,r,a=0,o=0;do{if(r=e+a,!this.noAssert&&r>this.limit){var i=Error("Truncated");throw i.truncated=!0,i}n=this.view.getUint8(r),5>a&&(o|=(127&n)<<7*a>>>0),++a}while(128===(128&n));return o=0|o,t?(this.offset+=a,o):{value:o,length:a}},a.readVarint32ZigZag=function(e){var t=this.readVarint32(e);return"object"==typeof t?t.value=r.zigZagDecode32(t.value):t=r.zigZagDecode32(t),t},e&&(r.MAX_VARINT64_BYTES=10,r.calculateVarint64=function(t){"number"==typeof t&&(t=e.fromNumber(t));var n=t.toInt()>>>0,r=t.shiftRightUnsigned(28).toInt()>>>0,a=t.shiftRightUnsigned(56).toInt()>>>0;return 0==a?0==r?16384>n?128>n?1:2:1<<21>n?3:4:16384>r?128>r?5:6:1<<21>r?7:8:128>a?9:10},r.zigZagEncode64=function(t){return"number"==typeof t?t=e.fromNumber(t,!1):t.unsigned!==!1&&(t=t.toSigned()),t.shiftLeft(1).xor(t.shiftRight(63)).toUnsigned()},r.zigZagDecode64=function(t){return"number"==typeof t?t=e.fromNumber(t,!1):t.unsigned!==!1&&(t=t.toSigned()),t.shiftRightUnsigned(1).xor(t.and(e.ONE).toSigned().negate()).toSigned()},a.writeVarint64=function(t,n){var a="undefined"==typeof n;if(a&&(n=this.offset),!this.noAssert){if("number"==typeof t)t=e.fromNumber(t);else if(!(t&&t instanceof e))throw TypeError("Illegal value: "+t+" (not an integer or Long)");if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}"number"==typeof t?t=e.fromNumber(t,!1):t.unsigned!==!1&&(t=t.toSigned());var o=r.calculateVarint64(t),i=t.toInt()>>>0,s=t.shiftRightUnsigned(28).toInt()>>>0,l=t.shiftRightUnsigned(56).toInt()>>>0;n+=o;var u=this.buffer.byteLength;switch(n>u&&this.resize((u*=2)>n?u:n),n-=o,o){case 10:this.view.setUint8(n+9,l>>>7&1);case 9:this.view.setUint8(n+8,9!==o?128|l:127&l);case 8:this.view.setUint8(n+7,8!==o?s>>>21|128:s>>>21&127);case 7:this.view.setUint8(n+6,7!==o?s>>>14|128:s>>>14&127);case 6:this.view.setUint8(n+5,6!==o?s>>>7|128:s>>>7&127);case 5:this.view.setUint8(n+4,5!==o?128|s:127&s);case 4:this.view.setUint8(n+3,4!==o?i>>>21|128:i>>>21&127);case 3:this.view.setUint8(n+2,3!==o?i>>>14|128:i>>>14&127);case 2:this.view.setUint8(n+1,2!==o?i>>>7|128:i>>>7&127);case 1:this.view.setUint8(n,1!==o?128|i:127&i)}return a?(this.offset+=o,this):o},a.writeVarint64ZigZag=function(e,t){return this.writeVarint64(r.zigZagEncode64(e),t)},a.readVarint64=function(t){var n="undefined"==typeof t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: "+t+" (not an integer)");if(t>>>=0,0>t||t+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+1) <= "+this.buffer.byteLength)}var r=t,a=0,o=0,i=0,s=0;if(s=this.view.getUint8(t++),a=127&s,128&s&&(s=this.view.getUint8(t++),a|=(127&s)<<7,128&s&&(s=this.view.getUint8(t++),a|=(127&s)<<14,128&s&&(s=this.view.getUint8(t++),a|=(127&s)<<21,128&s&&(s=this.view.getUint8(t++),o=127&s,128&s&&(s=this.view.getUint8(t++),o|=(127&s)<<7,128&s&&(s=this.view.getUint8(t++),o|=(127&s)<<14,128&s&&(s=this.view.getUint8(t++),o|=(127&s)<<21,128&s&&(s=this.view.getUint8(t++),i=127&s,128&s&&(s=this.view.getUint8(t++),i|=(127&s)<<7,128&s))))))))))throw Error("Buffer overrun");var l=e.fromBits(a|o<<28,o>>>4|i<<24,!1);return n?(this.offset=t,l):{value:l,length:t-r}},a.readVarint64ZigZag=function(t){var n=this.readVarint64(t);return n&&n.value instanceof e?n.value=r.zigZagDecode64(n.value):n=r.zigZagDecode64(n),n}),a.writeCString=function(e,n){var r="undefined"==typeof n;r&&(n=this.offset);var a,o=e.length;if(!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");for(a=0;o>a;++a)if(0===e.charCodeAt(a))throw RangeError("Illegal str: Contains NULL-characters");if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}var i=n;o=u.calculateUTF16asUTF8(t(e))[1],n+=o+1;var s=this.buffer.byteLength;return n>s&&this.resize((s*=2)>n?s:n),n-=o+1,u.encodeUTF16toUTF8(t(e),function(e){this.view.setUint8(n++,e)}.bind(this)),this.view.setUint8(n++,0),r?(this.offset=n-i,this):o},a.readCString=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,a=e,o=-1;return u.decodeUTF8toUTF16(function(){if(0===o)return null;if(e>=this.limit)throw RangeError("Illegal range: Truncated data, "+e+" < "+this.limit);return 0===(o=this.view.getUint8(e++))?null:o}.bind(this),r=n(),!0),t?(this.offset=e,r()):{string:r(),length:e-a}},a.writeIString=function(e,n){var r="undefined"==typeof n;if(r&&(n=this.offset),!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}var a,o=n;a=u.calculateUTF16asUTF8(t(e),this.noAssert)[1],n+=4+a;var i=this.buffer.byteLength;if(n>i&&this.resize((i*=2)>n?i:n),n-=4+a,this.view.setUint32(n,a,this.littleEndian),n+=4,u.encodeUTF16toUTF8(t(e),function(e){this.view.setUint8(n++,e)}.bind(this)),n!==o+4+a)throw RangeError("Illegal range: Truncated data, "+n+" == "+(n+4+a));return r?(this.offset=n,this):n-o},a.readIString=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r,a=0,o=e;a=this.view.getUint32(e,this.littleEndian),e+=4;var i,s=e+a;return u.decodeUTF8toUTF16(function(){return s>e?this.view.getUint8(e++):null}.bind(this),i=n(),this.noAssert),r=i(),t?(this.offset=e,r):{string:r,length:e-o}},r.METRICS_CHARS="c",r.METRICS_BYTES="b",a.writeUTF8String=function(e,n){var r="undefined"==typeof n;if(r&&(n=this.offset),!this.noAssert){if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}var a,o=n;a=u.calculateUTF16asUTF8(t(e))[1],n+=a;var i=this.buffer.byteLength;return n>i&&this.resize((i*=2)>n?i:n),n-=a,u.encodeUTF16toUTF8(t(e),function(e){this.view.setUint8(n++,e)}.bind(this)),r?(this.offset=n,this):n-o},a.writeString=a.writeUTF8String,r.calculateUTF8Chars=function(e){return u.calculateUTF16asUTF8(t(e))[0]},r.calculateUTF8Bytes=function(e){return u.calculateUTF16asUTF8(t(e))[1]},a.readUTF8String=function(e,t,a){"number"==typeof t&&(a=t,t=void 0);var o="undefined"==typeof a;if(o&&(a=this.offset),"undefined"==typeof t&&(t=r.METRICS_CHARS),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal length: "+e+" (not an integer)");if(e|=0,"number"!=typeof a||a%1!==0)throw TypeError("Illegal offset: "+a+" (not an integer)");if(a>>>=0,0>a||a+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+0) <= "+this.buffer.byteLength)}var i,s=0,l=a;if(t===r.METRICS_CHARS){if(i=n(),u.decodeUTF8(function(){return e>s&&a>>=0,0>a||a+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+"+e+") <= "+this.buffer.byteLength)}var c=a+e;if(u.decodeUTF8toUTF16(function(){return c>a?this.view.getUint8(a++):null}.bind(this),i=n(),this.noAssert),a!==c)throw RangeError("Illegal range: Truncated data, "+a+" == "+c);return o?(this.offset=a,i()):{string:i(),length:a-l}}throw TypeError("Unsupported metrics: "+t)},a.readString=a.readUTF8String,a.writeVString=function(e,n){var a="undefined"==typeof n;if(a&&(n=this.offset),!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}var o,i,s=n;o=u.calculateUTF16asUTF8(t(e),this.noAssert)[1],i=r.calculateVarint32(o),n+=i+o;var l=this.buffer.byteLength;if(n>l&&this.resize((l*=2)>n?l:n),n-=i+o,n+=this.writeVarint32(o,n),u.encodeUTF16toUTF8(t(e),function(e){this.view.setUint8(n++,e)}.bind(this)),n!==s+o+i)throw RangeError("Illegal range: Truncated data, "+n+" == "+(n+o+i));return a?(this.offset=n,this):n-s},a.readVString=function(e){var t="undefined"==typeof e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,a=this.readVarint32(e),o=e;e+=a.length,a=a.value;var i=e+a,s=n();return u.decodeUTF8toUTF16(function(){return i>e?this.view.getUint8(e++):null}.bind(this),s,this.noAssert),r=s(),t?(this.offset=e,r):{string:r,length:e-o}},a.append=function(e,t,n){("number"==typeof t||"string"!=typeof t)&&(n=t,t=void 0);var a="undefined"==typeof n;if(a&&(n=this.offset),!this.noAssert){if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}e instanceof r||(e=r.wrap(e,t));var o=e.limit-e.offset;if(0>=o)return this;n+=o;var i=this.buffer.byteLength;return n>i&&this.resize((i*=2)>n?i:n),n-=o,new Uint8Array(this.buffer,n).set(new Uint8Array(e.buffer).subarray(e.offset,e.limit)),e.offset+=o,a&&(this.offset+=o),this},a.appendTo=function(e,t){return e.append(this,t),this},a.assert=function(e){return this.noAssert=!e,this},a.capacity=function(){return this.buffer.byteLength},a.clear=function(){return this.offset=0,this.limit=this.buffer.byteLength,this.markedOffset=-1,this},a.clone=function(e){var t=new r(0,this.littleEndian,this.noAssert);if(e){var n=new ArrayBuffer(this.buffer.byteLength);new Uint8Array(n).set(this.buffer),t.buffer=n,t.view=new DataView(n)}else t.buffer=this.buffer,t.view=this.view;return t.offset=this.offset,t.markedOffset=this.markedOffset,t.limit=this.limit,t},a.compact=function(e,t){if("undefined"==typeof e&&(e=this.offset),"undefined"==typeof t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,0>e||e>t||t>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(0===e&&t===this.buffer.byteLength)return this;var n=t-e;if(0===n)return this.buffer=o,this.view=null,this.markedOffset>=0&&(this.markedOffset-=e),this.offset=0,this.limit=0,this;var r=new ArrayBuffer(n);return new Uint8Array(r).set(new Uint8Array(this.buffer).subarray(e,t)),this.buffer=r,this.view=new DataView(r),this.markedOffset>=0&&(this.markedOffset-=e),this.offset=0,this.limit=n,this},a.copy=function(e,t){if("undefined"==typeof e&&(e=this.offset),"undefined"==typeof t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,0>e||e>t||t>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(e===t)return new r(0,this.littleEndian,this.noAssert);var n=t-e,a=new r(n,this.littleEndian,this.noAssert);return a.offset=0,a.limit=n,a.markedOffset>=0&&(a.markedOffset-=e),this.copyTo(a,0,e,t),a},a.copyTo=function(e,t,n,a){var o,i;if(!this.noAssert&&!r.isByteBuffer(e))throw TypeError("Illegal target: Not a ByteBuffer");if(t=(i="undefined"==typeof t)?e.offset:0|t,n=(o="undefined"==typeof n)?this.offset:0|n,a="undefined"==typeof a?this.limit:0|a,0>t||t>e.buffer.byteLength)throw RangeError("Illegal target range: 0 <= "+t+" <= "+e.buffer.byteLength);if(0>n||a>this.buffer.byteLength)throw RangeError("Illegal source range: 0 <= "+n+" <= "+this.buffer.byteLength);var s=a-n;return 0===s?e:(e.ensureCapacity(t+s),new Uint8Array(e.buffer).set(new Uint8Array(this.buffer).subarray(n,a),t),o&&(this.offset+=s),i&&(e.offset+=s),this)},a.ensureCapacity=function(e){var t=this.buffer.byteLength;return e>t?this.resize((t*=2)>e?t:e):this},a.fill=function(e,t,n){var r="undefined"==typeof t;if(r&&(t=this.offset),"string"==typeof e&&e.length>0&&(e=e.charCodeAt(0)),"undefined"==typeof t&&(t=this.offset),"undefined"==typeof n&&(n=this.limit),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof n||n%1!==0)throw TypeError("Illegal end: Not an integer");if(n>>>=0,0>t||t>n||n>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+n+" <= "+this.buffer.byteLength)}if(t>=n)return this;for(;n>t;)this.view.setUint8(t++,e);return r&&(this.offset=t),this},a.flip=function(){return this.limit=this.offset,this.offset=0,this},a.mark=function(e){if(e="undefined"==typeof e?this.offset:e,!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal offset: "+e+" (not an integer)");if(e>>>=0,0>e||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}return this.markedOffset=e,this},a.order=function(e){if(!this.noAssert&&"boolean"!=typeof e)throw TypeError("Illegal littleEndian: Not a boolean");return this.littleEndian=!!e,this},a.LE=function(e){return this.littleEndian="undefined"!=typeof e?!!e:!0,this},a.BE=function(e){return this.littleEndian="undefined"!=typeof e?!e:!1,this},a.prepend=function(e,t,n){("number"==typeof t||"string"!=typeof t)&&(n=t,t=void 0);var a="undefined"==typeof n;if(a&&(n=this.offset),!this.noAssert){if("number"!=typeof n||n%1!==0)throw TypeError("Illegal offset: "+n+" (not an integer)");if(n>>>=0,0>n||n+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+n+" (+0) <= "+this.buffer.byteLength)}e instanceof r||(e=r.wrap(e,t));var o=e.limit-e.offset;if(0>=o)return this;var i,s=o-n;if(s>0){var l=new ArrayBuffer(this.buffer.byteLength+s);i=new Uint8Array(l),i.set(new Uint8Array(this.buffer).subarray(n,this.buffer.byteLength),o),this.buffer=l,this.view=new DataView(l),this.offset+=s,this.markedOffset>=0&&(this.markedOffset+=s),this.limit+=s,n+=s}else i=new Uint8Array(this.buffer);return i.set(new Uint8Array(e.buffer).subarray(e.offset,e.limit),n-o),e.offset=e.limit,a&&(this.offset-=o),this},a.prependTo=function(e,t){return e.prepend(this,t),this},a.printDebug=function(e){"function"!=typeof e&&(e=console.log.bind(console)),e(this.toString()+"\n-------------------------------------------------------------------\n"+this.toDebug(!0))},a.remaining=function(){return this.limit-this.offset},a.reset=function(){return this.markedOffset>=0?(this.offset=this.markedOffset,this.markedOffset=-1):this.offset=0,this},a.resize=function(e){if(!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal capacity: "+e+" (not an integer)");if(e|=0,0>e)throw RangeError("Illegal capacity: 0 <= "+e)}if(this.buffer.byteLength>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,0>e||e>t||t>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}return e===t?this:(Array.prototype.reverse.call(new Uint8Array(this.buffer).subarray(e,t)),this.view=new DataView(this.buffer),this)},a.skip=function(e){if(!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal length: "+e+" (not an integer)");e|=0}var t=this.offset+e;if(!this.noAssert&&(0>t||t>this.buffer.byteLength))throw RangeError("Illegal length: 0 <= "+this.offset+" + "+e+" <= "+this.buffer.byteLength);return this.offset=t,this},a.slice=function(e,t){if("undefined"==typeof e&&(e=this.offset),"undefined"==typeof t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,0>e||e>t||t>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}var n=this.clone();return n.offset=e,n.limit=t,n},a.toBuffer=function(e){var t=this.offset,n=this.limit;if(t>n){var r=t;t=n,n=r}if(!this.noAssert){if("number"!=typeof t||t%1!==0)throw TypeError("Illegal offset: Not an integer");if(t>>>=0,"number"!=typeof n||n%1!==0)throw TypeError("Illegal limit: Not an integer");if(n>>>=0,0>t||t>n||n>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+n+" <= "+this.buffer.byteLength)}if(!e&&0===t&&n===this.buffer.byteLength)return this.buffer;if(t===n)return o;var a=new ArrayBuffer(n-t);return new Uint8Array(a).set(new Uint8Array(this.buffer).subarray(t,n),0),a},a.toArrayBuffer=a.toBuffer,a.toString=function(e,t,n){if("undefined"==typeof e)return"ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")"; +switch("number"==typeof e&&(e="utf8",t=e,n=t),e){case"utf8":return this.toUTF8(t,n);case"base64":return this.toBase64(t,n);case"hex":return this.toHex(t,n);case"binary":return this.toBinary(t,n);case"debug":return this.toDebug();case"columns":return this.toColumns();default:throw Error("Unsupported encoding: "+e)}};var l=function(){for(var e={},t=[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47],n=[],r=0,a=t.length;a>r;++r)n[t[r]]=r;return e.encode=function(e,n){for(var r,a;null!==(r=e());)n(t[r>>2&63]),a=(3&r)<<4,null!==(r=e())?(a|=r>>4&15,n(t[63&(a|r>>4&15)]),a=(15&r)<<2,null!==(r=e())?(n(t[63&(a|r>>6&3)]),n(t[63&r])):(n(t[63&a]),n(61))):(n(t[63&a]),n(61),n(61))},e.decode=function(e,t){function r(e){throw Error("Illegal character code: "+e)}for(var a,o,i;null!==(a=e());)if(o=n[a],"undefined"==typeof o&&r(a),null!==(a=e())&&(i=n[a],"undefined"==typeof i&&r(a),t(o<<2>>>0|(48&i)>>4),null!==(a=e()))){if(o=n[a],"undefined"==typeof o){if(61===a)break;r(a)}if(t((15&i)<<4>>>0|(60&o)>>2),null!==(a=e())){if(i=n[a],"undefined"==typeof i){if(61===a)break;r(a)}t((3&o)<<6>>>0|i)}}},e.test=function(e){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e)},e}();a.toBase64=function(e,t){if("undefined"==typeof e&&(e=this.offset),"undefined"==typeof t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,0>e||e>t||t>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}var r;return l.encode(function(){return t>e?this.view.getUint8(e++):null}.bind(this),r=n()),r()},r.fromBase64=function(e,n,a){if(!a){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");if(e.length%4!==0)throw TypeError("Illegal str: Length not a multiple of 4")}var o=new r(e.length/4*3,n,a),i=0;return l.decode(t(e),function(e){o.view.setUint8(i++,e)}),o.limit=i,o},r.btoa=function(e){return r.fromBinary(e).toBase64()},r.atob=function(e){return r.fromBase64(e).toBinary()},a.toBinary=function(e,t){if(e="undefined"==typeof e?this.offset:e,t="undefined"==typeof t?this.limit:t,!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,0>e||e>t||t>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(e===t)return"";for(var n=[],r=[];t>e;)n.push(this.view.getUint8(e++)),n.length>=1024&&(r.push(String.fromCharCode.apply(String,n)),n=[]);return r.join("")+String.fromCharCode.apply(String,n)},r.fromBinary=function(e,t,n){if(!n&&"string"!=typeof e)throw TypeError("Illegal str: Not a string");for(var a,o=0,i=e.length,s=new r(i,t,n);i>o;){if(a=e.charCodeAt(o),!n&&a>255)throw RangeError("Illegal charCode at "+o+": 0 <= "+a+" <= 255");s.view.setUint8(o++,a)}return s.limit=i,s},a.toDebug=function(e){for(var t,n=-1,r=this.buffer.byteLength,a="",o="",i="";r>n;){if(-1!==n&&(t=this.view.getUint8(n),a+=16>t?"0"+t.toString(16).toUpperCase():t.toString(16).toUpperCase(),e&&(o+=t>32&&127>t?String.fromCharCode(t):".")),++n,e&&n>0&&n%16===0&&n!==r){for(;a.length<51;)a+=" ";i+=a+o+"\n",a=o=""}a+=n===this.offset&&n===this.limit?n===this.markedOffset?"!":"|":n===this.offset?n===this.markedOffset?"[":"<":n===this.limit?n===this.markedOffset?"]":">":n===this.markedOffset?"'":e||0!==n&&n!==r?" ":""}if(e&&" "!==a){for(;a.length<51;)a+=" ";i+=a+o+"\n"}return e?i:a},r.fromDebug=function(e,t,n){for(var a,o,i=e.length,s=new r((i+1)/3|0,t,n),l=0,u=0,c=!1,d=!1,p=!1,f=!1,h=!1;i>l;){switch(a=e.charAt(l++)){case"!":if(!n){if(d||p||f){h=!0;break}d=p=f=!0}s.offset=s.markedOffset=s.limit=u,c=!1;break;case"|":if(!n){if(d||f){h=!0;break}d=f=!0}s.offset=s.limit=u,c=!1;break;case"[":if(!n){if(d||p){h=!0;break}d=p=!0}s.offset=s.markedOffset=u,c=!1;break;case"<":if(!n){if(d){h=!0;break}d=!0}s.offset=u,c=!1;break;case"]":if(!n){if(f||p){h=!0;break}f=p=!0}s.limit=s.markedOffset=u,c=!1;break;case">":if(!n){if(f){h=!0;break}f=!0}s.limit=u,c=!1;break;case"'":if(!n){if(p){h=!0;break}p=!0}s.markedOffset=u,c=!1;break;case" ":c=!1;break;default:if(!n&&c){h=!0;break}if(o=parseInt(a+e.charAt(l++),16),!n&&(isNaN(o)||0>o||o>255))throw TypeError("Illegal str: Not a debug encoded string");s.view.setUint8(u++,o),c=!0}if(h)throw TypeError("Illegal str: Invalid symbol at "+l)}if(!n){if(!d||!f)throw TypeError("Illegal str: Missing offset or limit");if(u>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,0>e||e>t||t>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}for(var n,r=new Array(t-e);t>e;)n=this.view.getUint8(e++),16>n?r.push("0",n.toString(16)):r.push(n.toString(16));return r.join("")},r.fromHex=function(e,t,n){if(!n){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");if(e.length%2!==0)throw TypeError("Illegal str: Length not a multiple of 2")}for(var a,o=e.length,i=new r(o/2|0,t),s=0,l=0;o>s;s+=2){if(a=parseInt(e.substring(s,s+2),16),!n&&(!isFinite(a)||0>a||a>255))throw TypeError("Illegal str: Contains non-hex characters");i.view.setUint8(l++,a)}return i.limit=l,i};var u=function(){var e={};return e.MAX_CODEPOINT=1114111,e.encodeUTF8=function(e,t){var n=null;for("number"==typeof e&&(n=e,e=function(){return null});null!==n||null!==(n=e());)128>n?t(127&n):2048>n?(t(n>>6&31|192),t(63&n|128)):65536>n?(t(n>>12&15|224),t(n>>6&63|128),t(63&n|128)):(t(n>>18&7|240),t(n>>12&63|128),t(n>>6&63|128),t(63&n|128)),n=null},e.decodeUTF8=function(e,t){for(var n,r,a,o,i=function(e){e=e.slice(0,e.indexOf(null));var t=Error(e.toString());throw t.name="TruncatedError",t.bytes=e,t};null!==(n=e());)if(0===(128&n))t(n);else if(192===(224&n))null===(r=e())&&i([n,r]),t((31&n)<<6|63&r);else if(224===(240&n))(null===(r=e())||null===(a=e()))&&i([n,r,a]),t((15&n)<<12|(63&r)<<6|63&a);else{if(240!==(248&n))throw RangeError("Illegal starting byte: "+n);(null===(r=e())||null===(a=e())||null===(o=e()))&&i([n,r,a,o]),t((7&n)<<18|(63&r)<<12|(63&a)<<6|63&o)}},e.UTF16toUTF8=function(e,t){for(var n,r=null;;){if(null===(n=null!==r?r:e()))break;n>=55296&&57343>=n&&null!==(r=e())&&r>=56320&&57343>=r?(t(1024*(n-55296)+r-56320+65536),r=null):t(n)}null!==r&&t(r)},e.UTF8toUTF16=function(e,t){var n=null;for("number"==typeof e&&(n=e,e=function(){return null});null!==n||null!==(n=e());)65535>=n?t(n):(n-=65536,t((n>>10)+55296),t(n%1024+56320)),n=null},e.encodeUTF16toUTF8=function(t,n){e.UTF16toUTF8(t,function(t){e.encodeUTF8(t,n)})},e.decodeUTF8toUTF16=function(t,n){e.decodeUTF8(t,function(t){e.UTF8toUTF16(t,n)})},e.calculateCodePoint=function(e){return 128>e?1:2048>e?2:65536>e?3:4},e.calculateUTF8=function(t){for(var n,r=0;null!==(n=t());)r+=e.calculateCodePoint(n);return r},e.calculateUTF16asUTF8=function(t){var n=0,r=0;return e.UTF16toUTF8(t,function(t){++n,r+=e.calculateCodePoint(t)}),[n,r]},e}();return a.toUTF8=function(e,t){if("undefined"==typeof e&&(e=this.offset),"undefined"==typeof t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!==0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!==0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,0>e||e>t||t>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}var r;try{u.decodeUTF8toUTF16(function(){return t>e?this.view.getUint8(e++):null}.bind(this),r=n())}catch(a){if(e!==t)throw RangeError("Illegal range: Truncated data, "+e+" != "+t)}return r()},r.fromUTF8=function(e,n,a){if(!a&&"string"!=typeof e)throw TypeError("Illegal str: Not a string");var o=new r(u.calculateUTF16asUTF8(t(e),!0)[1],n,a),i=0;return u.encodeUTF16toUTF8(t(e),function(e){o.view.setUint8(i++,e)}),o.limit=i,o},r}"function"==typeof t&&"object"==typeof n&&n&&"object"==typeof r&&r?n.exports=function(){var e;try{e=t("long")}catch(n){}return o(e)}():"function"==typeof e&&e.amd?e("ByteBuffer",["Long"],function(e){return o(e)}):(a.dcodeIO=a.dcodeIO||{}).ByteBuffer=o(a.dcodeIO.Long)}(this)},{"long":3}],2:[function(t,n,r){!function(a){"use strict";var o=function(e,t,n){this.low=0|e,this.high=0|t,this.unsigned=!!n};o.isLong=function(e){return(e&&e instanceof o)===!0};var i={},s={};o.fromInt=function(e,t){var n,r;return t?(e>>>=0,e>=0&&256>e&&(r=s[e])?r:(n=new o(e,0>(0|e)?-1:0,!0),e>=0&&256>e&&(s[e]=n),n)):(e=0|e,e>=-128&&128>e&&(r=i[e])?r:(n=new o(e,0>e?-1:0,!1),e>=-128&&128>e&&(i[e]=n),n))},o.fromNumber=function(e,t){return t=!!t,isNaN(e)||!isFinite(e)?o.ZERO:!t&&-p>=e?o.MIN_VALUE:!t&&e+1>=p?o.MAX_VALUE:t&&e>=d?o.MAX_UNSIGNED_VALUE:0>e?o.fromNumber(-e,t).negate():new o(e%c|0,e/c|0,t)},o.fromBits=function(e,t,n){return new o(e,t,n)},o.fromString=function(e,t,n){if(0===e.length)throw Error("number format error: empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return o.ZERO;if("number"==typeof t&&(n=t,t=!1),n=n||10,2>n||n>36)throw Error("radix out of range: "+n);var r;if((r=e.indexOf("-"))>0)throw Error('number format error: interior "-" character: '+e);if(0===r)return o.fromString(e.substring(1),t,n).negate();for(var a=o.fromNumber(Math.pow(n,8)),i=o.ZERO,s=0;sl){var c=o.fromNumber(Math.pow(n,l));i=i.multiply(c).add(o.fromNumber(u))}else i=i.multiply(a),i=i.add(o.fromNumber(u))}return i.unsigned=t,i},o.fromValue=function(e){return"number"==typeof e?o.fromNumber(e):"string"==typeof e?o.fromString(e):o.isLong(e)?e:new o(e.low,e.high,e.unsigned)};var l=65536,u=1<<24,c=l*l,d=c*c,p=d/2,f=o.fromInt(u);o.ZERO=o.fromInt(0),o.UZERO=o.fromInt(0,!0),o.ONE=o.fromInt(1),o.UONE=o.fromInt(1,!0),o.NEG_ONE=o.fromInt(-1),o.MAX_VALUE=o.fromBits(-1,2147483647,!1),o.MAX_UNSIGNED_VALUE=o.fromBits(-1,-1,!0),o.MIN_VALUE=o.fromBits(0,-2147483648,!1),o.prototype.toInt=function(){return this.unsigned?this.low>>>0:this.low},o.prototype.toNumber=function(){return this.unsigned?(this.high>>>0)*c+(this.low>>>0):this.high*c+(this.low>>>0)},o.prototype.toString=function(e){if(e=e||10,2>e||e>36)throw RangeError("radix out of range: "+e);if(this.isZero())return"0";var t;if(this.isNegative()){if(this.equals(o.MIN_VALUE)){var n=o.fromNumber(e),r=this.div(n);return t=r.multiply(n).subtract(this),r.toString(e)+t.toInt().toString(e)}return"-"+this.negate().toString(e)}var a=o.fromNumber(Math.pow(e,6),this.unsigned);t=this;for(var i="";;){var s=t.div(a),l=t.subtract(s.multiply(a)).toInt()>>>0,u=l.toString(e);if(t=s,t.isZero())return u+i;for(;u.length<6;)u="0"+u;i=""+u+i}},o.prototype.getHighBits=function(){return this.high},o.prototype.getHighBitsUnsigned=function(){return this.high>>>0},o.prototype.getLowBits=function(){return this.low},o.prototype.getLowBitsUnsigned=function(){return this.low>>>0},o.prototype.getNumBitsAbs=function(){if(this.isNegative())return this.equals(o.MIN_VALUE)?64:this.negate().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;t>0&&0==(e&1<=0},o.prototype.isOdd=function(){return 1===(1&this.low)},o.prototype.isEven=function(){return 0===(1&this.low)},o.prototype.equals=function(e){return o.isLong(e)||(e=o.fromValue(e)),this.unsigned!==e.unsigned&&this.high>>>31===1&&e.high>>>31===1?!1:this.high===e.high&&this.low===e.low},o.prototype.notEquals=function(e){return o.isLong(e)||(e=o.fromValue(e)),!this.equals(e)},o.prototype.lessThan=function(e){return o.isLong(e)||(e=o.fromValue(e)),this.compare(e)<0},o.prototype.lessThanOrEqual=function(e){return o.isLong(e)||(e=o.fromValue(e)),this.compare(e)<=0},o.prototype.greaterThan=function(e){return o.isLong(e)||(e=o.fromValue(e)),this.compare(e)>0},o.prototype.greaterThanOrEqual=function(e){return this.compare(e)>=0},o.prototype.compare=function(e){if(this.equals(e))return 0;var t=this.isNegative(),n=e.isNegative();return t&&!n?-1:!t&&n?1:this.unsigned?e.high>>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.subtract(e).isNegative()?-1:1},o.prototype.negate=function(){return!this.unsigned&&this.equals(o.MIN_VALUE)?o.MIN_VALUE:this.not().add(o.ONE)},o.prototype.add=function(e){o.isLong(e)||(e=o.fromValue(e));var t=this.high>>>16,n=65535&this.high,r=this.low>>>16,a=65535&this.low,i=e.high>>>16,s=65535&e.high,l=e.low>>>16,u=65535&e.low,c=0,d=0,p=0,f=0;return f+=a+u,p+=f>>>16,f&=65535,p+=r+l,d+=p>>>16,p&=65535,d+=n+s,c+=d>>>16,d&=65535,c+=t+i,c&=65535,o.fromBits(p<<16|f,c<<16|d,this.unsigned)},o.prototype.subtract=function(e){return o.isLong(e)||(e=o.fromValue(e)),this.add(e.negate())},o.prototype.multiply=function(e){if(this.isZero())return o.ZERO;if(o.isLong(e)||(e=o.fromValue(e)),e.isZero())return o.ZERO;if(this.equals(o.MIN_VALUE))return e.isOdd()?o.MIN_VALUE:o.ZERO;if(e.equals(o.MIN_VALUE))return this.isOdd()?o.MIN_VALUE:o.ZERO;if(this.isNegative())return e.isNegative()?this.negate().multiply(e.negate()):this.negate().multiply(e).negate();if(e.isNegative())return this.multiply(e.negate()).negate();if(this.lessThan(f)&&e.lessThan(f))return o.fromNumber(this.toNumber()*e.toNumber(),this.unsigned);var t=this.high>>>16,n=65535&this.high,r=this.low>>>16,a=65535&this.low,i=e.high>>>16,s=65535&e.high,l=e.low>>>16,u=65535&e.low,c=0,d=0,p=0,h=0;return h+=a*u,p+=h>>>16,h&=65535,p+=r*u,d+=p>>>16,p&=65535,p+=a*l,d+=p>>>16,p&=65535,d+=n*u,c+=d>>>16,d&=65535,d+=r*l,c+=d>>>16,d&=65535,d+=a*s,c+=d>>>16,d&=65535,c+=t*u+n*l+r*s+a*i,c&=65535,o.fromBits(p<<16|h,c<<16|d,this.unsigned)},o.prototype.div=function(e){if(o.isLong(e)||(e=o.fromValue(e)),e.isZero())throw new Error("division by zero");if(this.isZero())return this.unsigned?o.UZERO:o.ZERO;var t,n,r;if(this.equals(o.MIN_VALUE)){if(e.equals(o.ONE)||e.equals(o.NEG_ONE))return o.MIN_VALUE;if(e.equals(o.MIN_VALUE))return o.ONE;var a=this.shiftRight(1);return t=a.div(e).shiftLeft(1),t.equals(o.ZERO)?e.isNegative()?o.ONE:o.NEG_ONE:(n=this.subtract(e.multiply(t)),r=t.add(n.div(e)))}if(e.equals(o.MIN_VALUE))return this.unsigned?o.UZERO:o.ZERO;if(this.isNegative())return e.isNegative()?this.negate().div(e.negate()):this.negate().div(e).negate();if(e.isNegative())return this.div(e.negate()).negate();for(r=o.ZERO,n=this;n.greaterThanOrEqual(e);){t=Math.max(1,Math.floor(n.toNumber()/e.toNumber()));for(var i=Math.ceil(Math.log(t)/Math.LN2),s=48>=i?1:Math.pow(2,i-48),l=o.fromNumber(t),u=l.multiply(e);u.isNegative()||u.greaterThan(n);)t-=s,l=o.fromNumber(t,this.unsigned),u=l.multiply(e);l.isZero()&&(l=o.ONE),r=r.add(l),n=n.subtract(u)}return r},o.prototype.modulo=function(e){return o.isLong(e)||(e=o.fromValue(e)),this.subtract(this.div(e).multiply(e))},o.prototype.not=function(){return o.fromBits(~this.low,~this.high,this.unsigned)},o.prototype.and=function(e){return o.isLong(e)||(e=o.fromValue(e)),o.fromBits(this.low&e.low,this.high&e.high,this.unsigned)},o.prototype.or=function(e){return o.isLong(e)||(e=o.fromValue(e)),o.fromBits(this.low|e.low,this.high|e.high,this.unsigned)},o.prototype.xor=function(e){return o.isLong(e)||(e=o.fromValue(e)),o.fromBits(this.low^e.low,this.high^e.high,this.unsigned)},o.prototype.shiftLeft=function(e){return o.isLong(e)&&(e=e.toInt()),0===(e&=63)?this:32>e?o.fromBits(this.low<>>32-e,this.unsigned):o.fromBits(0,this.low<e?o.fromBits(this.low>>>e|this.high<<32-e,this.high>>e,this.unsigned):o.fromBits(this.high>>e-32,this.high>=0?0:-1,this.unsigned)},o.prototype.shiftRightUnsigned=function(e){if(o.isLong(e)&&(e=e.toInt()),e&=63,0===e)return this;var t=this.high;if(32>e){var n=this.low;return o.fromBits(n>>>e|t<<32-e,t>>>e,this.unsigned)}return 32===e?o.fromBits(t,0,this.unsigned):o.fromBits(t>>>e-32,0,this.unsigned)},o.prototype.toSigned=function(){return this.unsigned?new o(this.low,this.high,!1):this},o.prototype.toUnsigned=function(){return this.unsigned?this:new o(this.low,this.high,!0)},"function"==typeof t&&"object"==typeof n&&n&&"object"==typeof r&&r?n.exports=o:"function"==typeof e&&e.amd?e(function(){return o}):(a.dcodeIO=a.dcodeIO||{}).Long=o}(this)},{}],3:[function(e,t,n){t.exports=e("./dist/Long.js")},{"./dist/Long.js":2}],4:[function(e,t,n){t.exports=e("bytebuffer")},{bytebuffer:1}]},{},[4])(4)})},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){e.exports=n(565)},function(e,t,n){(function(t){"use strict";var r=n(566),a=n(197),o=n(569),i=n(570),s=n(204),l=n(571),u=n(220),c=n(579),d=n(573),p=n(580);a.addons={CSSTransitionGroup:i,LinkedStateMixin:r,PureRenderMixin:o,TransitionGroup:l,batchedUpdates:u.batchedUpdates,classSet:c,cloneWithProps:d,createFragment:s.create,update:p},"production"!==t.env.NODE_ENV&&(a.addons.Perf=n(344),a.addons.TestUtils=n(581)),e.exports=a}).call(t,n(175))},function(e,t,n){"use strict";var r=n(567),a=n(568),o={linkState:function(e){return new r(this.state[e],a.createStateKeySetter(this,e))}};e.exports=o},function(e,t,n){"use strict";function r(e,t){this.value=e,this.requestChange=t}function a(e){var t={value:"undefined"==typeof e?o.PropTypes.any.isRequired:e.isRequired,requestChange:o.PropTypes.func.isRequired};return o.PropTypes.shape(t)}var o=n(197);r.PropTypes={link:a},e.exports=r},function(e,t){"use strict";function n(e,t){var n={};return function(r){n[t]=r,e.setState(n)}}var r={createStateSetter:function(e,t){return function(n,r,a,o,i,s){var l=t.call(e,n,r,a,o,i,s);l&&e.setState(l)}},createStateKeySetter:function(e,t){var r=e.__keySetters||(e.__keySetters={});return r[t]||(r[t]=n(e,t))}};r.Mixin={createStateSetter:function(e){return r.createStateSetter(this,e)},createStateKeySetter:function(e){return r.createStateKeySetter(this,e)}},e.exports=r},function(e,t,n){"use strict";var r=n(331),a={shouldComponentUpdate:function(e,t){return!r(this.props,e)||!r(this.state,t)}};e.exports=a},function(e,t,n){"use strict";var r=n(197),a=n(207),o=r.createFactory(n(571)),i=r.createFactory(n(576)),s=r.createClass({displayName:"ReactCSSTransitionGroup",propTypes:{transitionName:r.PropTypes.string.isRequired,transitionAppear:r.PropTypes.bool,transitionEnter:r.PropTypes.bool,transitionLeave:r.PropTypes.bool},getDefaultProps:function(){return{transitionAppear:!1,transitionEnter:!0,transitionLeave:!0}},_wrapChild:function(e){return i({name:this.props.transitionName,appear:this.props.transitionAppear,enter:this.props.transitionEnter,leave:this.props.transitionLeave},e)},render:function(){return o(a({},this.props,{childFactory:this._wrapChild}))}});e.exports=s},function(e,t,n){"use strict";var r=n(197),a=n(572),o=n(207),i=n(573),s=n(210),l=r.createClass({displayName:"ReactTransitionGroup",propTypes:{component:r.PropTypes.any,childFactory:r.PropTypes.func},getDefaultProps:function(){return{component:"span",childFactory:s.thatReturnsArgument}},getInitialState:function(){return{children:a.getChildMapping(this.props.children)}},componentWillMount:function(){this.currentlyTransitioningKeys={},this.keysToEnter=[],this.keysToLeave=[]},componentDidMount:function(){var e=this.state.children;for(var t in e)e[t]&&this.performAppear(t)},componentWillReceiveProps:function(e){var t=a.getChildMapping(e.children),n=this.state.children;this.setState({children:a.mergeChildMappings(n,t)});var r;for(r in t){var o=n&&n.hasOwnProperty(r);!t[r]||o||this.currentlyTransitioningKeys[r]||this.keysToEnter.push(r)}for(r in n){var i=t&&t.hasOwnProperty(r);!n[r]||i||this.currentlyTransitioningKeys[r]||this.keysToLeave.push(r)}},componentDidUpdate:function(){var e=this.keysToEnter;this.keysToEnter=[],e.forEach(this.performEnter);var t=this.keysToLeave;this.keysToLeave=[],t.forEach(this.performLeave)},performAppear:function(e){this.currentlyTransitioningKeys[e]=!0;var t=this.refs[e];t.componentWillAppear?t.componentWillAppear(this._handleDoneAppearing.bind(this,e)):this._handleDoneAppearing(e)},_handleDoneAppearing:function(e){var t=this.refs[e];t.componentDidAppear&&t.componentDidAppear(),delete this.currentlyTransitioningKeys[e];var n=a.getChildMapping(this.props.children);n&&n.hasOwnProperty(e)||this.performLeave(e)},performEnter:function(e){this.currentlyTransitioningKeys[e]=!0;var t=this.refs[e];t.componentWillEnter?t.componentWillEnter(this._handleDoneEntering.bind(this,e)):this._handleDoneEntering(e)},_handleDoneEntering:function(e){var t=this.refs[e];t.componentDidEnter&&t.componentDidEnter(),delete this.currentlyTransitioningKeys[e];var n=a.getChildMapping(this.props.children);n&&n.hasOwnProperty(e)||this.performLeave(e)},performLeave:function(e){this.currentlyTransitioningKeys[e]=!0;var t=this.refs[e];t.componentWillLeave?t.componentWillLeave(this._handleDoneLeaving.bind(this,e)):this._handleDoneLeaving(e)},_handleDoneLeaving:function(e){var t=this.refs[e];t.componentDidLeave&&t.componentDidLeave(),delete this.currentlyTransitioningKeys[e];var n=a.getChildMapping(this.props.children);if(n&&n.hasOwnProperty(e))this.performEnter(e);else{var r=o({},this.state.children);delete r[e],this.setState({children:r})}},render:function(){var e=[];for(var t in this.state.children){var n=this.state.children[t];n&&e.push(i(this.props.childFactory(n),{ref:t,key:t}))}return r.createElement(this.props.component,this.props,e)}});e.exports=l},function(e,t,n){"use strict";var r=n(202),a=n(204),o={getChildMapping:function(e){return e?a.extract(r.map(e,function(e){return e})):e},mergeChildMappings:function(e,t){function n(n){return t.hasOwnProperty(n)?t[n]:e[n]}e=e||{},t=t||{};var r={},a=[];for(var o in e)t.hasOwnProperty(o)?a.length&&(r[o]=a,a=[]):a.push(o);var i,s={};for(var l in t){if(r.hasOwnProperty(l))for(i=0;i1)for(var r=1;n>r;r++)t=arguments[r],t&&(e=(e?e+" ":"")+t);return e}e.exports=n},function(e,t,n){(function(t){"use strict";var r=n(197),a=n(577),o=n(578),i=n(350),s=n(209),l=17,u=5e3,c=null;"production"!==t.env.NODE_ENV&&(c=function(){"production"!==t.env.NODE_ENV?s(!1,"transition(): tried to perform an animation without an animationend or transitionend event after timeout (%sms). You should either disable this transition in JS or add a CSS animation/transition.",u):null});var d=r.createClass({displayName:"ReactCSSTransitionGroupChild",transition:function(e,n){var r=this.getDOMNode(),i=this.props.name+"-"+e,s=i+"-active",l=null,d=function(e){e&&e.target!==r||("production"!==t.env.NODE_ENV&&clearTimeout(l),a.removeClass(r,i),a.removeClass(r,s),o.removeEndEventListener(r,d),n&&n())};o.addEndEventListener(r,d),a.addClass(r,i),this.queueClass(s),"production"!==t.env.NODE_ENV&&(l=setTimeout(c,u))},queueClass:function(e){this.classNameQueue.push(e),this.timeout||(this.timeout=setTimeout(this.flushClassNameQueue,l))},flushClassNameQueue:function(){this.isMounted()&&this.classNameQueue.forEach(a.addClass.bind(a,this.getDOMNode())),this.classNameQueue.length=0,this.timeout=null},componentWillMount:function(){this.classNameQueue=[]},componentWillUnmount:function(){this.timeout&&clearTimeout(this.timeout)},componentWillAppear:function(e){this.props.appear?this.transition("appear",e):e()},componentWillEnter:function(e){this.props.enter?this.transition("enter",e):e()},componentWillLeave:function(e){this.props.leave?this.transition("leave",e):e()},render:function(){return i(this.props.children)}});e.exports=d}).call(t,n(175))},function(e,t,n){(function(t){var r=n(201),a={addClass:function(e,n){return"production"!==t.env.NODE_ENV?r(!/\s/.test(n),'CSSCore.addClass takes only a single class name. "%s" contains multiple classes.',n):r(!/\s/.test(n)),n&&(e.classList?e.classList.add(n):a.hasClass(e,n)||(e.className=e.className+" "+n)),e},removeClass:function(e,n){return"production"!==t.env.NODE_ENV?r(!/\s/.test(n),'CSSCore.removeClass takes only a single class name. "%s" contains multiple classes.',n):r(!/\s/.test(n)),n&&(e.classList?e.classList.remove(n):a.hasClass(e,n)&&(e.className=e.className.replace(new RegExp("(^|\\s)"+n+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,""))),e},conditionClass:function(e,t,n){return(n?a.addClass:a.removeClass)(e,t)},hasClass:function(e,n){return"production"!==t.env.NODE_ENV?r(!/\s/.test(n),"CSS.hasClass takes only a single class name."):r(!/\s/.test(n)),e.classList?!!n&&e.classList.contains(n):(" "+e.className+" ").indexOf(" "+n+" ")>-1}};e.exports=a}).call(t,n(175))},function(e,t,n){"use strict";function r(){var e=document.createElement("div"),t=e.style;"AnimationEvent"in window||delete s.animationend.animation,"TransitionEvent"in window||delete s.transitionend.transition;for(var n in s){var r=s[n];for(var a in r)if(a in t){l.push(r[a]);break}}}function a(e,t,n){e.addEventListener(t,n,!1)}function o(e,t,n){e.removeEventListener(t,n,!1)}var i=n(245),s={transitionend:{transition:"transitionend",WebkitTransition:"webkitTransitionEnd",MozTransition:"mozTransitionEnd",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd"},animationend:{animation:"animationend",WebkitAnimation:"webkitAnimationEnd",MozAnimation:"mozAnimationEnd",OAnimation:"oAnimationEnd",msAnimation:"MSAnimationEnd"}},l=[];i.canUseDOM&&r();var u={addEndEventListener:function(e,t){return 0===l.length?void window.setTimeout(t,0):void l.forEach(function(n){a(e,n,t)})},removeEndEventListener:function(e,t){0!==l.length&&l.forEach(function(n){o(e,n,t)})}};e.exports=u},function(e,t,n){(function(t){"use strict";function r(e){return"production"!==t.env.NODE_ENV&&("production"!==t.env.NODE_ENV?a(o,"React.addons.classSet will be deprecated in a future version. See http://fb.me/react-addons-classset"):null,o=!0),"object"==typeof e?Object.keys(e).filter(function(t){return e[t]}).join(" "):Array.prototype.join.call(arguments," ")}var a=n(209),o=!1;e.exports=r}).call(t,n(175))},function(e,t,n){(function(t){"use strict";function r(e){return Array.isArray(e)?e.concat():e&&"object"==typeof e?i(new e.constructor,e):e}function a(e,n,r){"production"!==t.env.NODE_ENV?l(Array.isArray(e),"update(): expected target of %s to be an array; got %s.",r,e):l(Array.isArray(e));var a=n[r];"production"!==t.env.NODE_ENV?l(Array.isArray(a),"update(): expected spec of %s to be an array; got %s. Did you forget to wrap your parameter in an array?",r,a):l(Array.isArray(a))}function o(e,n){if("production"!==t.env.NODE_ENV?l("object"==typeof n,"update(): You provided a key path to update() that did not contain one of %s. Did you forget to include {%s: ...}?",g.join(", "),f):l("object"==typeof n),u.call(n,f))return"production"!==t.env.NODE_ENV?l(1===Object.keys(n).length,"Cannot have more than one key in an object with %s",f):l(1===Object.keys(n).length),n[f];var s=r(e);if(u.call(n,h)){var b=n[h];"production"!==t.env.NODE_ENV?l(b&&"object"==typeof b,"update(): %s expects a spec of type 'object'; got %s",h,b):l(b&&"object"==typeof b),"production"!==t.env.NODE_ENV?l(s&&"object"==typeof s,"update(): %s expects a target of type 'object'; got %s",h,s):l(s&&"object"==typeof s),i(s,n[h])}u.call(n,c)&&(a(e,n,c),n[c].forEach(function(e){s.push(e)})),u.call(n,d)&&(a(e,n,d),n[d].forEach(function(e){s.unshift(e)})),u.call(n,p)&&("production"!==t.env.NODE_ENV?l(Array.isArray(e),"Expected %s target to be an array; got %s",p,e):l(Array.isArray(e)),"production"!==t.env.NODE_ENV?l(Array.isArray(n[p]),"update(): expected spec of %s to be an array of arrays; got %s. Did you forget to wrap your parameters in an array?",p,n[p]):l(Array.isArray(n[p])),n[p].forEach(function(e){"production"!==t.env.NODE_ENV?l(Array.isArray(e),"update(): expected spec of %s to be an array of arrays; got %s. Did you forget to wrap your parameters in an array?",p,n[p]):l(Array.isArray(e)),s.splice.apply(s,e)})),u.call(n,m)&&("production"!==t.env.NODE_ENV?l("function"==typeof n[m],"update(): expected spec of %s to be a function; got %s.",m,n[m]):l("function"==typeof n[m]),s=n[m](s));for(var v in n)y.hasOwnProperty(v)&&y[v]||(s[v]=o(e[v],n[v]));return s}var i=n(207),s=n(233),l=n(201),u={}.hasOwnProperty,c=s({$push:null}),d=s({$unshift:null}),p=s({$splice:null}),f=s({$set:null}),h=s({$merge:null}),m=s({$apply:null}),g=[c,d,p,f,h,m],y={};g.forEach(function(e){y[e]=!0}),e.exports=o}).call(t,n(175))},function(e,t,n){"use strict";function r(e){}function a(e){return function(t,n){var a;E.isDOMComponent(t)?a=t.getDOMNode():t.tagName&&(a=t);var o=new r;o.target=a;var i=new v(f.eventNameDispatchConfigs[e],y.getID(a),o);_(i,n),u.accumulateTwoPhaseDispatches(i),b.batchedUpdates(function(){l.enqueueEvents(i),l.processEventQueue()})}}function o(){E.Simulate={};var e;for(e in f.eventNameDispatchConfigs)E.Simulate[e]=a(e)}function i(e){return function(t,n){var a=new r(e);_(a,n),E.isDOMComponent(t)?E.simulateNativeEventOnDOMComponent(e,t,a):t.tagName&&E.simulateNativeEventOnNode(e,t,a)}}var s=n(199),l=n(263),u=n(287),c=n(197),d=n(205),p=n(270),f=n(262),h=n(278),m=n(213),g=n(219),y=n(261),b=n(220),v=n(291),_=n(207),w=n(208),k=s.topLevelTypes,E={renderIntoDocument:function(e){var t=document.createElement("div");return c.render(e,t)},isElement:function(e){return d.isValidElement(e)},isElementOfType:function(e,t){return d.isValidElement(e)&&e.type===t},isDOMComponent:function(e){return!!(e&&e.tagName&&e.getDOMNode)},isDOMComponentElement:function(e){return!!(e&&d.isValidElement(e)&&e.tagName)},isCompositeComponent:function(e){return"function"==typeof e.render&&"function"==typeof e.setState},isCompositeComponentWithType:function(e,t){return!(!E.isCompositeComponent(e)||e.constructor!==t)},isCompositeComponentElement:function(e){if(!d.isValidElement(e))return!1;var t=e.type.prototype;return"function"==typeof t.render&&"function"==typeof t.setState},isCompositeComponentElementWithType:function(e,t){return!(!E.isCompositeComponentElement(e)||e.constructor!==t)},getRenderedChildOfCompositeComponent:function(e){if(!E.isCompositeComponent(e))return null;var t=g.get(e);return t._renderedComponent.getPublicInstance()},findAllInRenderedTree:function(e,t){if(!e)return[];var n=t(e)?[e]:[];if(E.isDOMComponent(e)){var r,a=g.get(e),o=a._renderedComponent._renderedChildren;for(r in o)o.hasOwnProperty(r)&&o[r].getPublicInstance&&(n=n.concat(E.findAllInRenderedTree(o[r].getPublicInstance(),t)))}else E.isCompositeComponent(e)&&(n=n.concat(E.findAllInRenderedTree(E.getRenderedChildOfCompositeComponent(e),t)));return n},scryRenderedDOMComponentsWithClass:function(e,t){ +return E.findAllInRenderedTree(e,function(e){var n=e.props.className;return E.isDOMComponent(e)&&n&&-1!==(" "+n+" ").indexOf(" "+t+" ")})},findRenderedDOMComponentWithClass:function(e,t){var n=E.scryRenderedDOMComponentsWithClass(e,t);if(1!==n.length)throw new Error("Did not find exactly one match (found: "+n.length+") for class:"+t);return n[0]},scryRenderedDOMComponentsWithTag:function(e,t){return E.findAllInRenderedTree(e,function(e){return E.isDOMComponent(e)&&e.tagName===t.toUpperCase()})},findRenderedDOMComponentWithTag:function(e,t){var n=E.scryRenderedDOMComponentsWithTag(e,t);if(1!==n.length)throw new Error("Did not find exactly one match for tag:"+t);return n[0]},scryRenderedComponentsWithType:function(e,t){return E.findAllInRenderedTree(e,function(e){return E.isCompositeComponentWithType(e,t)})},findRenderedComponentWithType:function(e,t){var n=E.scryRenderedComponentsWithType(e,t);if(1!==n.length)throw new Error("Did not find exactly one match for componentType:"+t);return n[0]},mockComponent:function(e,t){return t=t||e.mockTagName||"div",e.prototype.render.mockImplementation(function(){return c.createElement(t,null,this.props.children)}),this},simulateNativeEventOnNode:function(e,t,n){n.target=t,f.ReactEventListener.dispatchEvent(e,n)},simulateNativeEventOnDOMComponent:function(e,t,n){E.simulateNativeEventOnNode(e,t.getDOMNode(),n)},nativeTouchData:function(e,t){return{touches:[{pageX:e,pageY:t}]}},createRenderer:function(){return new x},Simulate:null,SimulateNative:{}},x=function(){this._instance=null};x.prototype.getRenderOutput=function(){return this._instance&&this._instance._renderedComponent&&this._instance._renderedComponent._renderedOutput||null};var O=function(e){this._renderedOutput=e,this._currentElement=null===e||e===!1?p.emptyElement:e};O.prototype={mountComponent:function(){},receiveComponent:function(e){this._renderedOutput=e,this._currentElement=null===e||e===!1?p.emptyElement:e},unmountComponent:function(){}};var S=function(){};_(S.prototype,h.Mixin,{_instantiateReactComponent:function(e){return new O(e)},_replaceNodeWithMarkupByID:function(){},_renderValidatedComponent:h.Mixin._renderValidatedComponentWithoutOwnerOrContext}),x.prototype.render=function(e,t){t||(t=w);var n=b.ReactReconcileTransaction.getPooled();this._render(e,n,t),b.ReactReconcileTransaction.release(n)},x.prototype.unmount=function(){this._instance&&this._instance.unmountComponent()},x.prototype._render=function(e,t,n){if(this._instance)this._instance.receiveComponent(e,t,n);else{var r=m.createReactRootID(),a=new S(e.type);a.construct(e),a.mountComponent(r,t,n),this._instance=a}};var P=l.injection.injectEventPluginOrder;l.injection.injectEventPluginOrder=function(){P.apply(this,arguments),o()};var A=l.injection.injectEventPluginsByName;l.injection.injectEventPluginsByName=function(){A.apply(this,arguments),o()},o();var j;for(j in k){var C=0===j.indexOf("top")?j.charAt(3).toLowerCase()+j.substr(4):j;E.SimulateNative[C]=i(j)}e.exports=E},,,function(e,t){"use strict";function n(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof e.then}function r(e,t){t.forEach(function(t){Object.keys(Object(t)).forEach(function(n){e(n,t[n])})})}function a(e){for(var t=arguments.length,n=Array(t>1?t-1:0),a=1;t>a;a++)n[a-1]=arguments[a];return r(function(t,n){return e[t]=n},n),e}Object.defineProperty(t,"__esModule",{value:!0}),t.isPromise=n,t.eachObject=r,t.assign=a;var o=function(e){return"function"==typeof e};t.isFunction=o},,function(e,t,n){!function(t,n){e.exports=n()}(this,function(){"use strict";function e(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function t(e){return e.value=!1,e}function n(e){e&&(e.value=!0)}function r(){}function a(e,t){t=t||0;for(var n=Math.max(0,e.length-t),r=new Array(n),a=0;n>a;a++)r[a]=e[a+t];return r}function o(e){return void 0===e.size&&(e.size=e.__iterate(s)),e.size}function i(e,t){return t>=0?+t:o(e)+ +t}function s(){return!0}function l(e,t,n){return(0===e||void 0!==n&&-n>=e)&&(void 0===t||void 0!==n&&t>=n)}function u(e,t){return d(e,t,0)}function c(e,t){return d(e,t,t)}function d(e,t,n){return void 0===e?n:0>e?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}function p(e){return g(e)?e:j(e)}function f(e){return y(e)?e:C(e)}function h(e){return b(e)?e:T(e)}function m(e){return g(e)&&!v(e)?e:D(e)}function g(e){return!(!e||!e[mn])}function y(e){return!(!e||!e[gn])}function b(e){return!(!e||!e[yn])}function v(e){return y(e)||b(e)}function _(e){return!(!e||!e[bn])}function w(e){this.next=e}function k(e,t,n,r){var a=0===e?t:1===e?n:[t,n];return r?r.value=a:r={value:a,done:!1},r}function E(){return{value:void 0,done:!0}}function x(e){return!!P(e)}function O(e){return e&&"function"==typeof e.next}function S(e){var t=P(e);return t&&t.call(e)}function P(e){var t=e&&(kn&&e[kn]||e[En]);return"function"==typeof t?t:void 0}function A(e){return e&&"number"==typeof e.length}function j(e){return null===e||void 0===e?B():g(e)?e.toSeq():F(e)}function C(e){return null===e||void 0===e?B().toKeyedSeq():g(e)?y(e)?e.toSeq():e.fromEntrySeq():L(e)}function T(e){return null===e||void 0===e?B():g(e)?y(e)?e.entrySeq():e.toIndexedSeq():q(e)}function D(e){return(null===e||void 0===e?B():g(e)?y(e)?e.entrySeq():e:q(e)).toSetSeq()}function M(e){this._array=e,this.size=e.length}function N(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function z(e){this._iterable=e,this.size=e.length||e.size}function I(e){this._iterator=e,this._iteratorCache=[]}function R(e){return!(!e||!e[On])}function B(){return Sn||(Sn=new M([]))}function L(e){var t=Array.isArray(e)?new M(e).fromEntrySeq():O(e)?new I(e).fromEntrySeq():x(e)?new z(e).fromEntrySeq():"object"==typeof e?new N(e):void 0;if(!t)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+e);return t}function q(e){var t=U(e);if(!t)throw new TypeError("Expected Array or iterable object of values: "+e);return t}function F(e){var t=U(e)||"object"==typeof e&&new N(e);if(!t)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+e);return t}function U(e){return A(e)?new M(e):O(e)?new I(e):x(e)?new z(e):void 0}function H(e,t,n,r){var a=e._cache;if(a){for(var o=a.length-1,i=0;o>=i;i++){var s=a[n?o-i:i];if(t(s[1],r?s[0]:i,e)===!1)return i+1}return i}return e.__iterateUncached(t,n)}function W(e,t,n,r){var a=e._cache;if(a){var o=a.length-1,i=0;return new w(function(){var e=a[n?o-i:i];return i++>o?E():k(t,r?e[0]:i-1,e[1])})}return e.__iteratorUncached(t,n)}function V(){throw TypeError("Abstract")}function K(){}function G(){}function Y(){}function X(e,t){if(e===t||e!==e&&t!==t)return!0;if(!e||!t)return!1;if("function"==typeof e.valueOf&&"function"==typeof t.valueOf){if(e=e.valueOf(),t=t.valueOf(),e===t||e!==e&&t!==t)return!0;if(!e||!t)return!1}return"function"==typeof e.equals&&"function"==typeof t.equals&&e.equals(t)?!0:!1}function J(e,t){return t?$(t,e,"",{"":e}):Z(e)}function $(e,t,n,r){return Array.isArray(t)?e.call(r,n,T(t).map(function(n,r){return $(e,n,r,t)})):Q(t)?e.call(r,n,C(t).map(function(n,r){return $(e,n,r,t)})):t}function Z(e){return Array.isArray(e)?T(e).map(Z).toList():Q(e)?C(e).map(Z).toMap():e}function Q(e){return e&&(e.constructor===Object||void 0===e.constructor)}function ee(e){return e>>>1&1073741824|3221225471&e}function te(e){if(e===!1||null===e||void 0===e)return 0;if("function"==typeof e.valueOf&&(e=e.valueOf(),e===!1||null===e||void 0===e))return 0;if(e===!0)return 1;var t=typeof e;if("number"===t){var n=0|e;for(n!==e&&(n^=4294967295*e);e>4294967295;)e/=4294967295,n^=e;return ee(n)}return"string"===t?e.length>Nn?ne(e):re(e):"function"==typeof e.hashCode?e.hashCode():ae(e)}function ne(e){var t=Rn[e];return void 0===t&&(t=re(e),In===zn&&(In=0,Rn={}),In++,Rn[e]=t),t}function re(e){for(var t=0,n=0;n0)switch(e.nodeType){case 1:return e.uniqueID;case 9:return e.documentElement&&e.documentElement.uniqueID}}function ie(e,t){if(!e)throw new Error(t)}function se(e){ie(e!==1/0,"Cannot perform this action with an infinite size.")}function le(e,t){this._iter=e,this._useKeys=t,this.size=e.size}function ue(e){this._iter=e,this.size=e.size}function ce(e){this._iter=e,this.size=e.size}function de(e){this._iter=e,this.size=e.size}function pe(e){var t=Me(e);return t._iter=e,t.size=e.size,t.flip=function(){return e},t.reverse=function(){var t=e.reverse.apply(this);return t.flip=function(){return e.reverse()},t},t.has=function(t){return e.includes(t)},t.includes=function(t){return e.has(t)},t.cacheResult=Ne,t.__iterateUncached=function(t,n){var r=this;return e.__iterate(function(e,n){return t(n,e,r)!==!1},n)},t.__iteratorUncached=function(t,n){if(t===wn){var r=e.__iterator(t,n);return new w(function(){var e=r.next();if(!e.done){var t=e.value[0];e.value[0]=e.value[1],e.value[1]=t}return e})}return e.__iterator(t===_n?vn:_n,n)},t}function fe(e,t,n){var r=Me(e);return r.size=e.size,r.has=function(t){return e.has(t)},r.get=function(r,a){var o=e.get(r,pn);return o===pn?a:t.call(n,o,r,e)},r.__iterateUncached=function(r,a){var o=this;return e.__iterate(function(e,a,i){return r(t.call(n,e,a,i),a,o)!==!1},a)},r.__iteratorUncached=function(r,a){var o=e.__iterator(wn,a);return new w(function(){var a=o.next();if(a.done)return a;var i=a.value,s=i[0];return k(r,s,t.call(n,i[1],s,e),a)})},r}function he(e,t){var n=Me(e);return n._iter=e,n.size=e.size,n.reverse=function(){return e},e.flip&&(n.flip=function(){var t=pe(e);return t.reverse=function(){return e.flip()},t}),n.get=function(n,r){return e.get(t?n:-1-n,r)},n.has=function(n){return e.has(t?n:-1-n)},n.includes=function(t){return e.includes(t)},n.cacheResult=Ne,n.__iterate=function(t,n){var r=this;return e.__iterate(function(e,n){return t(e,n,r)},!n)},n.__iterator=function(t,n){return e.__iterator(t,!n)},n}function me(e,t,n,r){var a=Me(e);return r&&(a.has=function(r){var a=e.get(r,pn);return a!==pn&&!!t.call(n,a,r,e)},a.get=function(r,a){var o=e.get(r,pn);return o!==pn&&t.call(n,o,r,e)?o:a}),a.__iterateUncached=function(a,o){var i=this,s=0;return e.__iterate(function(e,o,l){return t.call(n,e,o,l)?(s++,a(e,r?o:s-1,i)):void 0},o),s},a.__iteratorUncached=function(a,o){var i=e.__iterator(wn,o),s=0;return new w(function(){for(;;){var o=i.next();if(o.done)return o;var l=o.value,u=l[0],c=l[1];if(t.call(n,c,u,e))return k(a,r?u:s++,c,o)}})},a}function ge(e,t,n){var r=Re().asMutable();return e.__iterate(function(a,o){r.update(t.call(n,a,o,e),0,function(e){return e+1})}),r.asImmutable()}function ye(e,t,n){var r=y(e),a=(_(e)?Et():Re()).asMutable();e.__iterate(function(o,i){a.update(t.call(n,o,i,e),function(e){return e=e||[],e.push(r?[i,o]:o),e})});var o=De(e);return a.map(function(t){return je(e,o(t))})}function be(e,t,n,r){var a=e.size;if(l(t,n,a))return e;var o=u(t,a),s=c(n,a);if(o!==o||s!==s)return be(e.toSeq().cacheResult(),t,n,r);var d,p=s-o;p===p&&(d=0>p?0:p);var f=Me(e);return f.size=d,!r&&R(e)&&d>=0&&(f.get=function(t,n){return t=i(this,t),t>=0&&d>t?e.get(t+o,n):n}),f.__iterateUncached=function(t,n){var a=this;if(0===d)return 0;if(n)return this.cacheResult().__iterate(t,n);var i=0,s=!0,l=0;return e.__iterate(function(e,n){return s&&(s=i++d)return E();var e=a.next();return r||t===_n?e:t===vn?k(t,s-1,void 0,e):k(t,s-1,e.value[1],e)})},f}function ve(e,t,n){var r=Me(e);return r.__iterateUncached=function(r,a){var o=this;if(a)return this.cacheResult().__iterate(r,a);var i=0;return e.__iterate(function(e,a,s){return t.call(n,e,a,s)&&++i&&r(e,a,o)}),i},r.__iteratorUncached=function(r,a){var o=this;if(a)return this.cacheResult().__iterator(r,a);var i=e.__iterator(wn,a),s=!0;return new w(function(){if(!s)return E();var e=i.next();if(e.done)return e;var a=e.value,l=a[0],u=a[1];return t.call(n,u,l,o)?r===wn?e:k(r,l,u,e):(s=!1,E())})},r}function _e(e,t,n,r){var a=Me(e);return a.__iterateUncached=function(a,o){var i=this;if(o)return this.cacheResult().__iterate(a,o);var s=!0,l=0;return e.__iterate(function(e,o,u){return s&&(s=t.call(n,e,o,u))?void 0:(l++,a(e,r?o:l-1,i))}),l},a.__iteratorUncached=function(a,o){var i=this;if(o)return this.cacheResult().__iterator(a,o);var s=e.__iterator(wn,o),l=!0,u=0;return new w(function(){var e,o,c;do{if(e=s.next(),e.done)return r||a===_n?e:a===vn?k(a,u++,void 0,e):k(a,u++,e.value[1],e);var d=e.value;o=d[0],c=d[1],l&&(l=t.call(n,c,o,i))}while(l);return a===wn?e:k(a,o,c,e)})},a}function we(e,t){var n=y(e),r=[e].concat(t).map(function(e){return g(e)?n&&(e=f(e)):e=n?L(e):q(Array.isArray(e)?e:[e]),e}).filter(function(e){return 0!==e.size});if(0===r.length)return e;if(1===r.length){var a=r[0];if(a===e||n&&y(a)||b(e)&&b(a))return a}var o=new M(r);return n?o=o.toKeyedSeq():b(e)||(o=o.toSetSeq()),o=o.flatten(!0),o.size=r.reduce(function(e,t){if(void 0!==e){var n=t.size;if(void 0!==n)return e+n}},0),o}function ke(e,t,n){var r=Me(e);return r.__iterateUncached=function(r,a){function o(e,l){var u=this;e.__iterate(function(e,a){return(!t||t>l)&&g(e)?o(e,l+1):r(e,n?a:i++,u)===!1&&(s=!0),!s},a)}var i=0,s=!1;return o(e,0),i},r.__iteratorUncached=function(r,a){var o=e.__iterator(r,a),i=[],s=0;return new w(function(){for(;o;){var e=o.next();if(e.done===!1){var l=e.value;if(r===wn&&(l=l[1]),t&&!(i.length0}function Ae(e,t,n){var r=Me(e);return r.size=new M(n).map(function(e){return e.size}).min(),r.__iterate=function(e,t){for(var n,r=this.__iterator(_n,t),a=0;!(n=r.next()).done&&e(n.value,a++,this)!==!1;);return a},r.__iteratorUncached=function(e,r){var a=n.map(function(e){return e=p(e),S(r?e.reverse():e)}),o=0,i=!1;return new w(function(){var n;return i||(n=a.map(function(e){return e.next()}),i=n.some(function(e){return e.done})),i?E():k(e,o++,t.apply(null,n.map(function(e){return e.value})))})},r}function je(e,t){return R(e)?t:e.constructor(t)}function Ce(e){if(e!==Object(e))throw new TypeError("Expected [K, V] tuple: "+e)}function Te(e){return se(e.size),o(e)}function De(e){return y(e)?f:b(e)?h:m}function Me(e){return Object.create((y(e)?C:b(e)?T:D).prototype)}function Ne(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):j.prototype.cacheResult.call(this)}function ze(e,t){return e>t?1:t>e?-1:0}function Ie(e){var t=S(e);if(!t){if(!A(e))throw new TypeError("Expected iterable or array-like: "+e);t=S(p(e))}return t}function Re(e){return null===e||void 0===e?Ye():Be(e)?e:Ye().withMutations(function(t){var n=f(e);se(n.size),n.forEach(function(e,n){return t.set(n,e)})})}function Be(e){return!(!e||!e[Bn])}function Le(e,t){this.ownerID=e,this.entries=t}function qe(e,t,n){this.ownerID=e,this.bitmap=t,this.nodes=n}function Fe(e,t,n){this.ownerID=e,this.count=t,this.nodes=n}function Ue(e,t,n){this.ownerID=e,this.keyHash=t,this.entries=n}function He(e,t,n){this.ownerID=e,this.keyHash=t,this.entry=n}function We(e,t,n){this._type=t,this._reverse=n,this._stack=e._root&&Ke(e._root)}function Ve(e,t){return k(e,t[0],t[1])}function Ke(e,t){return{node:e,index:0,__prev:t}}function Ge(e,t,n,r){var a=Object.create(Ln);return a.size=e,a._root=t,a.__ownerID=n,a.__hash=r,a.__altered=!1,a}function Ye(){return qn||(qn=Ge(0))}function Xe(e,n,r){var a,o;if(e._root){var i=t(fn),s=t(hn);if(a=Je(e._root,e.__ownerID,0,void 0,n,r,i,s),!s.value)return e;o=e.size+(i.value?r===pn?-1:1:0)}else{if(r===pn)return e;o=1,a=new Le(e.__ownerID,[[n,r]])}return e.__ownerID?(e.size=o,e._root=a,e.__hash=void 0,e.__altered=!0,e):a?Ge(o,a):Ye()}function Je(e,t,r,a,o,i,s,l){return e?e.update(t,r,a,o,i,s,l):i===pn?e:(n(l),n(s),new He(t,a,[o,i]))}function $e(e){return e.constructor===He||e.constructor===Ue}function Ze(e,t,n,r,a){if(e.keyHash===r)return new Ue(t,r,[e.entry,a]);var o,i=(0===n?e.keyHash:e.keyHash>>>n)&dn,s=(0===n?r:r>>>n)&dn,l=i===s?[Ze(e,t,n+un,r,a)]:(o=new He(t,r,a),s>i?[e,o]:[o,e]);return new qe(t,1<s;s++,l<<=1){var c=t[s];void 0!==c&&s!==r&&(a|=l,i[o++]=c)}return new qe(e,a,i)}function tt(e,t,n,r,a){for(var o=0,i=new Array(cn),s=0;0!==n;s++,n>>>=1)i[s]=1&n?t[o++]:void 0;return i[r]=a,new Fe(e,o+1,i)}function nt(e,t,n){for(var r=[],a=0;a>1&1431655765,e=(858993459&e)+(e>>2&858993459),e=e+(e>>4)&252645135,e+=e>>8,e+=e>>16,127&e}function st(e,t,n,r){var o=r?e:a(e);return o[t]=n,o}function lt(e,t,n,r){var a=e.length+1;if(r&&t+1===a)return e[t]=n,e;for(var o=new Array(a),i=0,s=0;a>s;s++)s===t?(o[s]=n,i=-1):o[s]=e[s+i];return o}function ut(e,t,n){var r=e.length-1;if(n&&t===r)return e.pop(),e;for(var a=new Array(r),o=0,i=0;r>i;i++)i===t&&(o=1),a[i]=e[i+o];return a}function ct(e){var t=mt();if(null===e||void 0===e)return t;if(dt(e))return e;var n=h(e),r=n.size;return 0===r?t:(se(r),r>0&&cn>r?ht(0,r,un,null,new pt(n.toArray())):t.withMutations(function(e){e.setSize(r),n.forEach(function(t,n){return e.set(n,t)})}))}function dt(e){return!(!e||!e[Wn])}function pt(e,t){this.array=e,this.ownerID=t}function ft(e,t){function n(e,t,n){return 0===t?r(e,n):a(e,t,n)}function r(e,n){var r=n===s?l&&l.array:e&&e.array,a=n>o?0:o-n,u=i-n;return u>cn&&(u=cn),function(){if(a===u)return Gn;var e=t?--u:a++;return r&&r[e]}}function a(e,r,a){var s,l=e&&e.array,u=a>o?0:o-a>>r,c=(i-a>>r)+1;return c>cn&&(c=cn),function(){for(;;){if(s){var e=s();if(e!==Gn)return e;s=null}if(u===c)return Gn;var o=t?--c:u++;s=n(l&&l[o],r-un,a+(o<=e.size||0>n)return e.withMutations(function(e){0>n?_t(e,n).set(0,r):_t(e,0,n+1).set(n,r)});n+=e._origin;var a=e._tail,o=e._root,s=t(hn);return n>=kt(e._capacity)?a=yt(a,e.__ownerID,0,n,r,s):o=yt(o,e.__ownerID,e._level,n,r,s),s.value?e.__ownerID?(e._root=o,e._tail=a,e.__hash=void 0,e.__altered=!0,e):ht(e._origin,e._capacity,e._level,o,a):e}function yt(e,t,r,a,o,i){var s=a>>>r&dn,l=e&&s0){var c=e&&e.array[s],d=yt(c,t,r-un,a,o,i);return d===c?e:(u=bt(e,t),u.array[s]=d,u)}return l&&e.array[s]===o?e:(n(i),u=bt(e,t),void 0===o&&s===u.array.length-1?u.array.pop():u.array[s]=o,u)}function bt(e,t){return t&&e&&t===e.ownerID?e:new pt(e?e.array.slice():[],t)}function vt(e,t){if(t>=kt(e._capacity))return e._tail;if(t<1<0;)n=n.array[t>>>r&dn],r-=un;return n}}function _t(e,t,n){var a=e.__ownerID||new r,o=e._origin,i=e._capacity,s=o+t,l=void 0===n?i:0>n?i+n:o+n;if(s===o&&l===i)return e;if(s>=l)return e.clear();for(var u=e._level,c=e._root,d=0;0>s+d;)c=new pt(c&&c.array.length?[void 0,c]:[],a),u+=un,d+=1<=1<f?vt(e,l-1):f>p?new pt([],a):h;if(h&&f>p&&i>s&&h.array.length){c=bt(c,a);for(var g=c,y=u;y>un;y-=un){var b=p>>>y&dn;g=g.array[b]=bt(g.array[b],a)}g.array[p>>>un&dn]=h}if(i>l&&(m=m&&m.removeAfter(a,0,l)),s>=f)s-=f,l-=f,u=un,c=null,m=m&&m.removeBefore(a,0,s);else if(s>o||p>f){for(d=0;c;){var v=s>>>u&dn;if(v!==f>>>u&dn)break;v&&(d+=(1<o&&(c=c.removeBefore(a,u,s-d)),c&&p>f&&(c=c.removeAfter(a,u,f-d)),d&&(s-=d,l-=d)}return e.__ownerID?(e.size=l-s,e._origin=s,e._capacity=l,e._level=u,e._root=c,e._tail=m,e.__hash=void 0,e.__altered=!0,e):ht(s,l,u,c,m)}function wt(e,t,n){for(var r=[],a=0,o=0;oa&&(a=s.size),g(i)||(s=s.map(function(e){return J(e)})),r.push(s)}return a>e.size&&(e=e.setSize(a)),at(e,t,r)}function kt(e){return cn>e?0:e-1>>>un<=cn&&i.size>=2*o.size?(a=i.filter(function(e,t){return void 0!==e&&s!==t}),r=a.toKeyedSeq().map(function(e){return e[0]}).flip().toMap(),e.__ownerID&&(r.__ownerID=a.__ownerID=e.__ownerID)):(r=o.remove(t),a=s===i.size-1?i.pop():i.set(s,void 0))}else if(l){if(n===i.get(s)[1])return e;r=o,a=i.set(s,[t,n])}else r=o.set(t,i.size),a=i.set(i.size,[t,n]);return e.__ownerID?(e.size=r.size,e._map=r,e._list=a,e.__hash=void 0,e):Ot(r,a)}function At(e){return null===e||void 0===e?Tt():jt(e)?e:Tt().unshiftAll(e)}function jt(e){return!(!e||!e[Xn])}function Ct(e,t,n,r){var a=Object.create(Jn);return a.size=e,a._head=t,a.__ownerID=n,a.__hash=r,a.__altered=!1,a}function Tt(){return $n||($n=Ct(0))}function Dt(e){return null===e||void 0===e?It():Mt(e)?e:It().withMutations(function(t){var n=m(e);se(n.size),n.forEach(function(e){return t.add(e)})})}function Mt(e){return!(!e||!e[Zn])}function Nt(e,t){return e.__ownerID?(e.size=t.size,e._map=t,e):t===e._map?e:0===t.size?e.__empty():e.__make(t)}function zt(e,t){var n=Object.create(Qn);return n.size=e?e.size:0,n._map=e,n.__ownerID=t,n}function It(){return er||(er=zt(Ye()))}function Rt(e){return null===e||void 0===e?qt():Bt(e)?e:qt().withMutations(function(t){var n=m(e);se(n.size),n.forEach(function(e){return t.add(e)})})}function Bt(e){return Mt(e)&&_(e)}function Lt(e,t){var n=Object.create(tr);return n.size=e?e.size:0,n._map=e,n.__ownerID=t,n}function qt(){return nr||(nr=Lt(St()))}function Ft(e,t){var n,r=function(o){if(o instanceof r)return o;if(!(this instanceof r))return new r(o);if(!n){n=!0;var i=Object.keys(e);Wt(a,i),a.size=i.length,a._name=t,a._keys=i,a._defaultValues=e}this._map=Re(o)},a=r.prototype=Object.create(rr);return a.constructor=r,r}function Ut(e,t,n){var r=Object.create(Object.getPrototypeOf(e));return r._map=t,r.__ownerID=n,r}function Ht(e){return e._name||e.constructor.name||"Record"}function Wt(e,t){try{t.forEach(Vt.bind(void 0,e))}catch(n){}}function Vt(e,t){Object.defineProperty(e,t,{get:function(){return this.get(t)},set:function(e){ie(this.__ownerID,"Cannot set on an immutable record."),this.set(t,e)}})}function Kt(e,t){if(e===t)return!0;if(!g(t)||void 0!==e.size&&void 0!==t.size&&e.size!==t.size||void 0!==e.__hash&&void 0!==t.__hash&&e.__hash!==t.__hash||y(e)!==y(t)||b(e)!==b(t)||_(e)!==_(t))return!1;if(0===e.size&&0===t.size)return!0;var n=!v(e);if(_(e)){var r=e.entries();return t.every(function(e,t){var a=r.next().value;return a&&X(a[1],e)&&(n||X(a[0],t))})&&r.next().done}var a=!1;if(void 0===e.size)if(void 0===t.size)"function"==typeof e.cacheResult&&e.cacheResult();else{a=!0;var o=e;e=t,t=o}var i=!0,s=t.__iterate(function(t,r){return(n?e.has(t):a?X(t,e.get(r,pn)):X(e.get(r,pn),t))?void 0:(i=!1,!1)});return i&&e.size===s}function Gt(e,t,n){if(!(this instanceof Gt))return new Gt(e,t,n);if(ie(0!==n,"Cannot step a Range by 0"),e=e||0,void 0===t&&(t=1/0),n=void 0===n?1:Math.abs(n),e>t&&(n=-n),this._start=e,this._end=t,this._step=n,this.size=Math.max(0,Math.ceil((t-e)/n-1)+1),0===this.size){if(ar)return ar;ar=this}}function Yt(e,t){if(!(this instanceof Yt))return new Yt(e,t);if(this._value=e,this.size=void 0===t?1/0:Math.max(0,t),0===this.size){if(or)return or;or=this}}function Xt(e,t){var n=function(n){e.prototype[n]=t[n]};return Object.keys(t).forEach(n),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(t).forEach(n),e}function Jt(e,t){return t}function $t(e,t){return[t,e]}function Zt(e){return function(){return!e.apply(this,arguments)}}function Qt(e){return function(){return-e.apply(this,arguments)}}function en(e){return"string"==typeof e?JSON.stringify(e):e}function tn(){return a(arguments)}function nn(e,t){return t>e?1:e>t?-1:0}function rn(e){if(e.size===1/0)return 0;var t=_(e),n=y(e),r=t?1:0,a=e.__iterate(n?t?function(e,t){r=31*r+on(te(e),te(t))|0}:function(e,t){r=r+on(te(e),te(t))|0}:t?function(e){r=31*r+te(e)|0}:function(e){r=r+te(e)|0});return an(a,r)}function an(e,t){return t=An(t,3432918353),t=An(t<<15|t>>>-15,461845907),t=An(t<<13|t>>>-13,5),t=(t+3864292196|0)^e,t=An(t^t>>>16,2246822507),t=An(t^t>>>13,3266489909),t=ee(t^t>>>16)}function on(e,t){return e^t+2654435769+(e<<6)+(e>>2)|0}var sn=Array.prototype.slice,ln="delete",un=5,cn=1<=a;a++)if(e(n[t?r-a:a],a,this)===!1)return a+1;return a},M.prototype.__iterator=function(e,t){var n=this._array,r=n.length-1,a=0;return new w(function(){return a>r?E():k(e,a,n[t?r-a++:a++])})},e(N,C),N.prototype.get=function(e,t){return void 0===t||this.has(e)?this._object[e]:t},N.prototype.has=function(e){return this._object.hasOwnProperty(e)},N.prototype.__iterate=function(e,t){for(var n=this._object,r=this._keys,a=r.length-1,o=0;a>=o;o++){var i=r[t?a-o:o];if(e(n[i],i,this)===!1)return o+1}return o},N.prototype.__iterator=function(e,t){var n=this._object,r=this._keys,a=r.length-1,o=0;return new w(function(){var i=r[t?a-o:o];return o++>a?E():k(e,i,n[i])})},N.prototype[bn]=!0,e(z,T),z.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);var n=this._iterable,r=S(n),a=0;if(O(r))for(var o;!(o=r.next()).done&&e(o.value,a++,this)!==!1;);return a},z.prototype.__iteratorUncached=function(e,t){if(t)return this.cacheResult().__iterator(e,t);var n=this._iterable,r=S(n);if(!O(r))return new w(E);var a=0;return new w(function(){var t=r.next();return t.done?t:k(e,a++,t.value)})},e(I,T),I.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);for(var n=this._iterator,r=this._iteratorCache,a=0;a=r.length){var t=n.next();if(t.done)return t;r[a]=t.value}return k(e,a,r[a++])})};var Sn;e(V,p),e(K,V),e(G,V),e(Y,V),V.Keyed=K,V.Indexed=G,V.Set=Y;var Pn,An="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(e,t){e=0|e,t=0|t;var n=65535&e,r=65535&t;return n*r+((e>>>16)*r+n*(t>>>16)<<16>>>0)|0},jn=Object.isExtensible,Cn=function(){try{return Object.defineProperty({},"@",{}),!0}catch(e){return!1}}(),Tn="function"==typeof WeakMap;Tn&&(Pn=new WeakMap);var Dn=0,Mn="__immutablehash__";"function"==typeof Symbol&&(Mn=Symbol(Mn));var Nn=16,zn=255,In=0,Rn={};e(le,C),le.prototype.get=function(e,t){return this._iter.get(e,t)},le.prototype.has=function(e){return this._iter.has(e)},le.prototype.valueSeq=function(){return this._iter.valueSeq()},le.prototype.reverse=function(){var e=this,t=he(this,!0);return this._useKeys||(t.valueSeq=function(){return e._iter.toSeq().reverse()}),t},le.prototype.map=function(e,t){var n=this,r=fe(this,e,t);return this._useKeys||(r.valueSeq=function(){return n._iter.toSeq().map(e,t)}),r},le.prototype.__iterate=function(e,t){var n,r=this;return this._iter.__iterate(this._useKeys?function(t,n){return e(t,n,r)}:(n=t?Te(this):0,function(a){return e(a,t?--n:n++,r)}),t)},le.prototype.__iterator=function(e,t){if(this._useKeys)return this._iter.__iterator(e,t);var n=this._iter.__iterator(_n,t),r=t?Te(this):0;return new w(function(){ +var a=n.next();return a.done?a:k(e,t?--r:r++,a.value,a)})},le.prototype[bn]=!0,e(ue,T),ue.prototype.includes=function(e){return this._iter.includes(e)},ue.prototype.__iterate=function(e,t){var n=this,r=0;return this._iter.__iterate(function(t){return e(t,r++,n)},t)},ue.prototype.__iterator=function(e,t){var n=this._iter.__iterator(_n,t),r=0;return new w(function(){var t=n.next();return t.done?t:k(e,r++,t.value,t)})},e(ce,D),ce.prototype.has=function(e){return this._iter.includes(e)},ce.prototype.__iterate=function(e,t){var n=this;return this._iter.__iterate(function(t){return e(t,t,n)},t)},ce.prototype.__iterator=function(e,t){var n=this._iter.__iterator(_n,t);return new w(function(){var t=n.next();return t.done?t:k(e,t.value,t.value,t)})},e(de,C),de.prototype.entrySeq=function(){return this._iter.toSeq()},de.prototype.__iterate=function(e,t){var n=this;return this._iter.__iterate(function(t){if(t){Ce(t);var r=g(t);return e(r?t.get(1):t[1],r?t.get(0):t[0],n)}},t)},de.prototype.__iterator=function(e,t){var n=this._iter.__iterator(_n,t);return new w(function(){for(;;){var t=n.next();if(t.done)return t;var r=t.value;if(r){Ce(r);var a=g(r);return k(e,a?r.get(0):r[0],a?r.get(1):r[1],t)}}})},ue.prototype.cacheResult=le.prototype.cacheResult=ce.prototype.cacheResult=de.prototype.cacheResult=Ne,e(Re,K),Re.prototype.toString=function(){return this.__toString("Map {","}")},Re.prototype.get=function(e,t){return this._root?this._root.get(0,void 0,e,t):t},Re.prototype.set=function(e,t){return Xe(this,e,t)},Re.prototype.setIn=function(e,t){return this.updateIn(e,pn,function(){return t})},Re.prototype.remove=function(e){return Xe(this,e,pn)},Re.prototype.deleteIn=function(e){return this.updateIn(e,function(){return pn})},Re.prototype.update=function(e,t,n){return 1===arguments.length?e(this):this.updateIn([e],t,n)},Re.prototype.updateIn=function(e,t,n){n||(n=t,t=void 0);var r=ot(this,Ie(e),t,n);return r===pn?void 0:r},Re.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):Ye()},Re.prototype.merge=function(){return nt(this,void 0,arguments)},Re.prototype.mergeWith=function(e){var t=sn.call(arguments,1);return nt(this,e,t)},Re.prototype.mergeIn=function(e){var t=sn.call(arguments,1);return this.updateIn(e,Ye(),function(e){return"function"==typeof e.merge?e.merge.apply(e,t):t[t.length-1]})},Re.prototype.mergeDeep=function(){return nt(this,rt(void 0),arguments)},Re.prototype.mergeDeepWith=function(e){var t=sn.call(arguments,1);return nt(this,rt(e),t)},Re.prototype.mergeDeepIn=function(e){var t=sn.call(arguments,1);return this.updateIn(e,Ye(),function(e){return"function"==typeof e.mergeDeep?e.mergeDeep.apply(e,t):t[t.length-1]})},Re.prototype.sort=function(e){return Et(Oe(this,e))},Re.prototype.sortBy=function(e,t){return Et(Oe(this,t,e))},Re.prototype.withMutations=function(e){var t=this.asMutable();return e(t),t.wasAltered()?t.__ensureOwner(this.__ownerID):this},Re.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new r)},Re.prototype.asImmutable=function(){return this.__ensureOwner()},Re.prototype.wasAltered=function(){return this.__altered},Re.prototype.__iterator=function(e,t){return new We(this,e,t)},Re.prototype.__iterate=function(e,t){var n=this,r=0;return this._root&&this._root.iterate(function(t){return r++,e(t[1],t[0],n)},t),r},Re.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?Ge(this.size,this._root,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},Re.isMap=Be;var Bn="@@__IMMUTABLE_MAP__@@",Ln=Re.prototype;Ln[Bn]=!0,Ln[ln]=Ln.remove,Ln.removeIn=Ln.deleteIn,Le.prototype.get=function(e,t,n,r){for(var a=this.entries,o=0,i=a.length;i>o;o++)if(X(n,a[o][0]))return a[o][1];return r},Le.prototype.update=function(e,t,r,o,i,s,l){for(var u=i===pn,c=this.entries,d=0,p=c.length;p>d&&!X(o,c[d][0]);d++);var f=p>d;if(f?c[d][1]===i:u)return this;if(n(l),(u||!f)&&n(s),!u||1!==c.length){if(!f&&!u&&c.length>=Fn)return Qe(e,c,o,i);var h=e&&e===this.ownerID,m=h?c:a(c);return f?u?d===p-1?m.pop():m[d]=m.pop():m[d]=[o,i]:m.push([o,i]),h?(this.entries=m,this):new Le(e,m)}},qe.prototype.get=function(e,t,n,r){void 0===t&&(t=te(n));var a=1<<((0===e?t:t>>>e)&dn),o=this.bitmap;return 0===(o&a)?r:this.nodes[it(o&a-1)].get(e+un,t,n,r)},qe.prototype.update=function(e,t,n,r,a,o,i){void 0===n&&(n=te(r));var s=(0===t?n:n>>>t)&dn,l=1<=Un)return tt(e,p,u,s,h);if(c&&!h&&2===p.length&&$e(p[1^d]))return p[1^d];if(c&&h&&1===p.length&&$e(h))return h;var m=e&&e===this.ownerID,g=c?h?u:u^l:u|l,y=c?h?st(p,d,h,m):ut(p,d,m):lt(p,d,h,m);return m?(this.bitmap=g,this.nodes=y,this):new qe(e,g,y)},Fe.prototype.get=function(e,t,n,r){void 0===t&&(t=te(n));var a=(0===e?t:t>>>e)&dn,o=this.nodes[a];return o?o.get(e+un,t,n,r):r},Fe.prototype.update=function(e,t,n,r,a,o,i){void 0===n&&(n=te(r));var s=(0===t?n:n>>>t)&dn,l=a===pn,u=this.nodes,c=u[s];if(l&&!c)return this;var d=Je(c,e,t+un,n,r,a,o,i);if(d===c)return this;var p=this.count;if(c){if(!d&&(p--,Hn>p))return et(e,u,p,s)}else p++;var f=e&&e===this.ownerID,h=st(u,s,d,f);return f?(this.count=p,this.nodes=h,this):new Fe(e,p,h)},Ue.prototype.get=function(e,t,n,r){for(var a=this.entries,o=0,i=a.length;i>o;o++)if(X(n,a[o][0]))return a[o][1];return r},Ue.prototype.update=function(e,t,r,o,i,s,l){void 0===r&&(r=te(o));var u=i===pn;if(r!==this.keyHash)return u?this:(n(l),n(s),Ze(this,e,t,r,[o,i]));for(var c=this.entries,d=0,p=c.length;p>d&&!X(o,c[d][0]);d++);var f=p>d;if(f?c[d][1]===i:u)return this;if(n(l),(u||!f)&&n(s),u&&2===p)return new He(e,this.keyHash,c[1^d]);var h=e&&e===this.ownerID,m=h?c:a(c);return f?u?d===p-1?m.pop():m[d]=m.pop():m[d]=[o,i]:m.push([o,i]),h?(this.entries=m,this):new Ue(e,this.keyHash,m)},He.prototype.get=function(e,t,n,r){return X(n,this.entry[0])?this.entry[1]:r},He.prototype.update=function(e,t,r,a,o,i,s){var l=o===pn,u=X(a,this.entry[0]);return(u?o===this.entry[1]:l)?this:(n(s),l?void n(i):u?e&&e===this.ownerID?(this.entry[1]=o,this):new He(e,this.keyHash,[a,o]):(n(i),Ze(this,e,t,te(a),[a,o])))},Le.prototype.iterate=Ue.prototype.iterate=function(e,t){for(var n=this.entries,r=0,a=n.length-1;a>=r;r++)if(e(n[t?a-r:r])===!1)return!1},qe.prototype.iterate=Fe.prototype.iterate=function(e,t){for(var n=this.nodes,r=0,a=n.length-1;a>=r;r++){var o=n[t?a-r:r];if(o&&o.iterate(e,t)===!1)return!1}},He.prototype.iterate=function(e,t){return e(this.entry)},e(We,w),We.prototype.next=function(){for(var e=this._type,t=this._stack;t;){var n,r=t.node,a=t.index++;if(r.entry){if(0===a)return Ve(e,r.entry)}else if(r.entries){if(n=r.entries.length-1,n>=a)return Ve(e,r.entries[this._reverse?n-a:a])}else if(n=r.nodes.length-1,n>=a){var o=r.nodes[this._reverse?n-a:a];if(o){if(o.entry)return Ve(e,o.entry);t=this._stack=Ke(o,t)}continue}t=this._stack=this._stack.__prev}return E()};var qn,Fn=cn/4,Un=cn/2,Hn=cn/4;e(ct,G),ct.of=function(){return this(arguments)},ct.prototype.toString=function(){return this.__toString("List [","]")},ct.prototype.get=function(e,t){if(e=i(this,e),0>e||e>=this.size)return t;e+=this._origin;var n=vt(this,e);return n&&n.array[e&dn]},ct.prototype.set=function(e,t){return gt(this,e,t)},ct.prototype.remove=function(e){return this.has(e)?0===e?this.shift():e===this.size-1?this.pop():this.splice(e,1):this},ct.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=un,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):mt()},ct.prototype.push=function(){var e=arguments,t=this.size;return this.withMutations(function(n){_t(n,0,t+e.length);for(var r=0;r>>t&dn;if(r>=this.array.length)return new pt([],e);var a,o=0===r;if(t>0){var i=this.array[r];if(a=i&&i.removeBefore(e,t-un,n),a===i&&o)return this}if(o&&!a)return this;var s=bt(this,e);if(!o)for(var l=0;r>l;l++)s.array[l]=void 0;return a&&(s.array[r]=a),s},pt.prototype.removeAfter=function(e,t,n){if(n===t?1<>>t&dn;if(r>=this.array.length)return this;var a,o=r===this.array.length-1;if(t>0){var i=this.array[r];if(a=i&&i.removeAfter(e,t-un,n),a===i&&o)return this}if(o&&!a)return this;var s=bt(this,e);return o||s.array.pop(),a&&(s.array[r]=a),s};var Kn,Gn={};e(Et,Re),Et.of=function(){return this(arguments)},Et.prototype.toString=function(){return this.__toString("OrderedMap {","}")},Et.prototype.get=function(e,t){var n=this._map.get(e);return void 0!==n?this._list.get(n)[1]:t},Et.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._map.clear(),this._list.clear(),this):St()},Et.prototype.set=function(e,t){return Pt(this,e,t)},Et.prototype.remove=function(e){return Pt(this,e,pn)},Et.prototype.wasAltered=function(){return this._map.wasAltered()||this._list.wasAltered()},Et.prototype.__iterate=function(e,t){var n=this;return this._list.__iterate(function(t){return t&&e(t[1],t[0],n)},t)},Et.prototype.__iterator=function(e,t){return this._list.fromEntrySeq().__iterator(e,t)},Et.prototype.__ensureOwner=function(e){if(e===this.__ownerID)return this;var t=this._map.__ensureOwner(e),n=this._list.__ensureOwner(e);return e?Ot(t,n,e,this.__hash):(this.__ownerID=e,this._map=t,this._list=n,this)},Et.isOrderedMap=xt,Et.prototype[bn]=!0,Et.prototype[ln]=Et.prototype.remove;var Yn;e(At,G),At.of=function(){return this(arguments)},At.prototype.toString=function(){return this.__toString("Stack [","]")},At.prototype.get=function(e,t){var n=this._head;for(e=i(this,e);n&&e--;)n=n.next;return n?n.value:t},At.prototype.peek=function(){return this._head&&this._head.value},At.prototype.push=function(){if(0===arguments.length)return this;for(var e=this.size+arguments.length,t=this._head,n=arguments.length-1;n>=0;n--)t={value:arguments[n],next:t};return this.__ownerID?(this.size=e,this._head=t,this.__hash=void 0,this.__altered=!0,this):Ct(e,t)},At.prototype.pushAll=function(e){if(e=h(e),0===e.size)return this;se(e.size);var t=this.size,n=this._head;return e.reverse().forEach(function(e){t++,n={value:e,next:n}}),this.__ownerID?(this.size=t,this._head=n,this.__hash=void 0,this.__altered=!0,this):Ct(t,n)},At.prototype.pop=function(){return this.slice(1)},At.prototype.unshift=function(){return this.push.apply(this,arguments)},At.prototype.unshiftAll=function(e){return this.pushAll(e)},At.prototype.shift=function(){return this.pop.apply(this,arguments)},At.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Tt()},At.prototype.slice=function(e,t){if(l(e,t,this.size))return this;var n=u(e,this.size),r=c(t,this.size);if(r!==this.size)return G.prototype.slice.call(this,e,t);for(var a=this.size-n,o=this._head;n--;)o=o.next;return this.__ownerID?(this.size=a,this._head=o,this.__hash=void 0,this.__altered=!0,this):Ct(a,o)},At.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?Ct(this.size,this._head,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},At.prototype.__iterate=function(e,t){if(t)return this.reverse().__iterate(e);for(var n=0,r=this._head;r&&e(r.value,n++,this)!==!1;)r=r.next;return n},At.prototype.__iterator=function(e,t){if(t)return this.reverse().__iterator(e);var n=0,r=this._head;return new w(function(){if(r){var t=r.value;return r=r.next,k(e,n++,t)}return E()})},At.isStack=jt;var Xn="@@__IMMUTABLE_STACK__@@",Jn=At.prototype;Jn[Xn]=!0,Jn.withMutations=Ln.withMutations,Jn.asMutable=Ln.asMutable,Jn.asImmutable=Ln.asImmutable,Jn.wasAltered=Ln.wasAltered;var $n;e(Dt,Y),Dt.of=function(){return this(arguments)},Dt.fromKeys=function(e){return this(f(e).keySeq())},Dt.prototype.toString=function(){return this.__toString("Set {","}")},Dt.prototype.has=function(e){return this._map.has(e)},Dt.prototype.add=function(e){return Nt(this,this._map.set(e,!0))},Dt.prototype.remove=function(e){return Nt(this,this._map.remove(e))},Dt.prototype.clear=function(){return Nt(this,this._map.clear())},Dt.prototype.union=function(){var e=sn.call(arguments,0);return e=e.filter(function(e){return 0!==e.size}),0===e.length?this:0!==this.size||this.__ownerID||1!==e.length?this.withMutations(function(t){for(var n=0;n1?" by "+this._step:"")+" ]"},Gt.prototype.get=function(e,t){return this.has(e)?this._start+i(this,e)*this._step:t},Gt.prototype.includes=function(e){var t=(e-this._start)/this._step;return t>=0&&t=t?new Gt(0,0):new Gt(this.get(e,this._end),this.get(t,this._end),this._step))},Gt.prototype.indexOf=function(e){var t=e-this._start;if(t%this._step===0){var n=t/this._step;if(n>=0&&n=o;o++){if(e(a,o,this)===!1)return o+1;a+=t?-r:r}return o},Gt.prototype.__iterator=function(e,t){var n=this.size-1,r=this._step,a=t?this._start+n*r:this._start,o=0;return new w(function(){var i=a;return a+=t?-r:r,o>n?E():k(e,o++,i)})},Gt.prototype.equals=function(e){return e instanceof Gt?this._start===e._start&&this._end===e._end&&this._step===e._step:Kt(this,e)};var ar;e(Yt,T),Yt.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},Yt.prototype.get=function(e,t){return this.has(e)?this._value:t},Yt.prototype.includes=function(e){return X(this._value,e)},Yt.prototype.slice=function(e,t){var n=this.size;return l(e,t,n)?this:new Yt(this._value,c(t,n)-u(e,n))},Yt.prototype.reverse=function(){return this},Yt.prototype.indexOf=function(e){return X(this._value,e)?0:-1},Yt.prototype.lastIndexOf=function(e){return X(this._value,e)?this.size:-1},Yt.prototype.__iterate=function(e,t){for(var n=0;ne||this.size===1/0||void 0!==this.size&&e>this.size?t:this.find(function(t,n){return n===e},void 0,t)},has:function(e){return e=i(this,e),e>=0&&(void 0!==this.size?this.size===1/0||en;n+=1)if(o=e[n],"string"!=typeof o){if(i=o.id,!t||!a.hop.call(t,i))throw new Error("A value must be provided for: "+i);s=t[i],l+=o.options?this._format(o.getOption(s),t):o.format(s)}else l+=o;return l},r.prototype._mergeFormats=function(e,t){var n,r,i={};for(n in e)a.hop.call(e,n)&&(i[n]=r=o.objCreate(e[n]),t&&a.hop.call(t,n)&&a.extend(r,t[n]));return i},r.prototype._resolveLocale=function(e){"string"==typeof e&&(e=[e]),e=(e||[]).concat(r.defaultLocale);var t,n,a,o,i=r.__localeData__;for(t=0,n=e.length;n>t;t+=1)for(a=e[t].toLowerCase().split("-");a.length;){if(o=i[a.join("-")])return o.locale;a.pop()}var s=e.pop();throw new Error("No locale data has been added to IntlMessageFormat for: "+e.join(", ")+", or the default locale: "+s)}},function(e,t){"use strict";function n(e){var t,n,a,o,i=Array.prototype.slice.call(arguments,1);for(t=0,n=i.length;n>t;t+=1)if(a=i[t])for(o in a)r.call(a,o)&&(e[o]=a[o]);return e}t.extend=n;var r=Object.prototype.hasOwnProperty;t.hop=r},function(e,t,n){"use strict";var r=n(597),a=function(){try{return!!Object.defineProperty({},"a",{})}catch(e){return!1}}(),o=(!a&&!Object.prototype.__defineGetter__,a?Object.defineProperty:function(e,t,n){"get"in n&&e.__defineGetter__?e.__defineGetter__(t,n.get):(!r.hop.call(e,t)||"value"in n)&&(e[t]=n.value)}),i=Object.create||function(e,t){function n(){}var a,i;n.prototype=e,a=new n;for(i in t)r.hop.call(t,i)&&o(a,i,t[i]);return a};t.defineProperty=o, +t.objCreate=i},function(e,t){"use strict";function n(e,t,n){this.locales=e,this.formats=t,this.pluralFn=n}function r(e){this.id=e}function a(e,t,n,r,a){this.id=e,this.useOrdinal=t,this.offset=n,this.options=r,this.pluralFn=a}function o(e,t,n,r){this.id=e,this.offset=t,this.numberFormat=n,this.string=r}function i(e,t){this.id=e,this.options=t}t["default"]=n,n.prototype.compile=function(e){return this.pluralStack=[],this.currentPlural=null,this.pluralNumberFormat=null,this.compileMessage(e)},n.prototype.compileMessage=function(e){if(!e||"messageFormatPattern"!==e.type)throw new Error('Message AST is not of type: "messageFormatPattern"');var t,n,r,a=e.elements,o=[];for(t=0,n=a.length;n>t;t+=1)switch(r=a[t],r.type){case"messageTextElement":o.push(this.compileMessageText(r));break;case"argumentElement":o.push(this.compileArgument(r));break;default:throw new Error("Message element does not have a valid type")}return o},n.prototype.compileMessageText=function(e){return this.currentPlural&&/(^|[^\\])#/g.test(e.value)?(this.pluralNumberFormat||(this.pluralNumberFormat=new Intl.NumberFormat(this.locales)),new o(this.currentPlural.id,this.currentPlural.format.offset,this.pluralNumberFormat,e.value)):e.value.replace(/\\#/g,"#")},n.prototype.compileArgument=function(e){var t=e.format;if(!t)return new r(e.id);var n,o=this.formats,s=this.locales,l=this.pluralFn;switch(t.type){case"numberFormat":return n=o.number[t.style],{id:e.id,format:new Intl.NumberFormat(s,n).format};case"dateFormat":return n=o.date[t.style],{id:e.id,format:new Intl.DateTimeFormat(s,n).format};case"timeFormat":return n=o.time[t.style],{id:e.id,format:new Intl.DateTimeFormat(s,n).format};case"pluralFormat":return n=this.compileOptions(e),new a(e.id,t.ordinal,t.offset,n,l);case"selectFormat":return n=this.compileOptions(e),new i(e.id,n);default:throw new Error("Message element does not have a valid format type")}},n.prototype.compileOptions=function(e){var t=e.format,n=t.options,r={};this.pluralStack.push(this.currentPlural),this.currentPlural="pluralFormat"===t.type?e:null;var a,o,i;for(a=0,o=n.length;o>a;a+=1)i=n[a],r[i.selector]=this.compileMessage(i.value);return this.currentPlural=this.pluralStack.pop(),r},r.prototype.format=function(e){return e?"string"==typeof e?e:String(e):""},a.prototype.getOption=function(e){var t=this.options,n=t["="+e]||t[this.pluralFn(e-this.offset,this.useOrdinal)];return n||t.other},o.prototype.format=function(e){var t=this.numberFormat.format(e-this.offset);return this.string.replace(/(^|[^\\])#/g,"$1"+t).replace(/\\#/g,"#")},i.prototype.getOption=function(e){var t=this.options;return t[e]||t.other}},function(e,t,n){"use strict";t=e.exports=n(601)["default"],t["default"]=t},function(e,t){"use strict";t["default"]=function(){function e(e,t){function n(){this.constructor=e}n.prototype=t.prototype,e.prototype=new n}function t(e,t,n,r,a,o){this.message=e,this.expected=t,this.found=n,this.offset=r,this.line=a,this.column=o,this.name="SyntaxError"}function n(e){function n(t){function n(t,n,r){var a,o;for(a=n;r>a;a++)o=e.charAt(a),"\n"===o?(t.seenCR||t.line++,t.column=1,t.seenCR=!1):"\r"===o||"\u2028"===o||"\u2029"===o?(t.line++,t.column=1,t.seenCR=!0):(t.column++,t.seenCR=!1)}return Ke!==t&&(Ke>t&&(Ke=0,Ge={line:1,column:1,seenCR:!1}),n(Ge,Ke,t),Ke=t),Ge}function r(e){Ye>We||(We>Ye&&(Ye=We,Xe=[]),Xe.push(e))}function a(r,a,o){function i(e){var t=1;for(e.sort(function(e,t){return e.descriptiont.description?1:0});t1?i.slice(0,-1).join(", ")+" or "+i[e.length-1]:i[0],a=t?'"'+n(t)+'"':"end of input","Expected "+r+" but "+a+" found."}var l=n(o),u=o1?arguments[1]:{},C={},T={start:o},D=o,M=function(e){return{type:"messageFormatPattern",elements:e}},N=C,z=function(e){var t,n,r,a,o,i="";for(t=0,r=e.length;r>t;t+=1)for(a=e[t],n=0,o=a.length;o>n;n+=1)i+=a[n];return i},I=function(e){return{type:"messageTextElement",value:e}},R=/^[^ \t\n\r,.+={}#]/,B={type:"class",value:"[^ \\t\\n\\r,.+={}#]",description:"[^ \\t\\n\\r,.+={}#]"},L="{",q={type:"literal",value:"{",description:'"{"'},F=null,U=",",H={type:"literal",value:",",description:'","'},W="}",V={type:"literal",value:"}",description:'"}"'},K=function(e,t){return{type:"argumentElement",id:e,format:t&&t[2]}},G="number",Y={type:"literal",value:"number",description:'"number"'},X="date",J={type:"literal",value:"date",description:'"date"'},$="time",Z={type:"literal",value:"time",description:'"time"'},Q=function(e,t){return{type:e+"Format",style:t&&t[2]}},ee="plural",te={type:"literal",value:"plural",description:'"plural"'},ne=function(e){return{type:e.type,ordinal:!1,offset:e.offset||0,options:e.options}},re="selectordinal",ae={type:"literal",value:"selectordinal",description:'"selectordinal"'},oe=function(e){return{type:e.type,ordinal:!0,offset:e.offset||0,options:e.options}},ie="select",se={type:"literal",value:"select",description:'"select"'},le=function(e){return{type:"selectFormat",options:e}},ue="=",ce={type:"literal",value:"=",description:'"="'},de=function(e,t){return{type:"optionalFormatPattern",selector:e,value:t}},pe="offset:",fe={type:"literal",value:"offset:",description:'"offset:"'},he=function(e){return e},me=function(e,t){return{type:"pluralFormat",offset:e,options:t}},ge={type:"other",description:"whitespace"},ye=/^[ \t\n\r]/,be={type:"class",value:"[ \\t\\n\\r]",description:"[ \\t\\n\\r]"},ve={type:"other",description:"optionalWhitespace"},_e=/^[0-9]/,we={type:"class",value:"[0-9]",description:"[0-9]"},ke=/^[0-9a-f]/i,Ee={type:"class",value:"[0-9a-f]i",description:"[0-9a-f]i"},xe="0",Oe={type:"literal",value:"0",description:'"0"'},Se=/^[1-9]/,Pe={type:"class",value:"[1-9]",description:"[1-9]"},Ae=function(e){return parseInt(e,10)},je=/^[^{}\\\0-\x1F \t\n\r]/,Ce={type:"class",value:"[^{}\\\\\\0-\\x1F \\t\\n\\r]",description:"[^{}\\\\\\0-\\x1F \\t\\n\\r]"},Te="\\#",De={type:"literal",value:"\\#",description:'"\\\\#"'},Me=function(){return"\\#"},Ne="\\{",ze={type:"literal",value:"\\{",description:'"\\\\{"'},Ie=function(){return"{"},Re="\\}",Be={type:"literal",value:"\\}",description:'"\\\\}"'},Le=function(){return"}"},qe="\\u",Fe={type:"literal",value:"\\u",description:'"\\\\u"'},Ue=function(e){return String.fromCharCode(parseInt(e,16))},He=function(e){return e.join("")},We=0,Ve=0,Ke=0,Ge={line:1,column:1,seenCR:!1},Ye=0,Xe=[],Je=0;if("startRule"in j){if(!(j.startRule in T))throw new Error("Can't start parsing from rule \""+j.startRule+'".');D=T[j.startRule]}if(A=D(),A!==C&&We===e.length)return A;throw A!==C&&Wes?"past":"future"})},r.prototype._isValidUnits=function(e){if(!e||i.arrIndexOf.call(s,e)>=0)return!0;if("string"==typeof e){var t=/s$/.test(e)&&e.substr(0,e.length-1);if(t&&i.arrIndexOf.call(s,t)>=0)throw new Error('"'+e+'" is not a valid IntlRelativeFormat `units` value, did you mean: '+t)}throw new Error('"'+e+'" is not a valid IntlRelativeFormat `units` value, it must be one of: "'+s.join('", "')+'"')},r.prototype._resolveLocale=function(e){"string"==typeof e&&(e=[e]),e=(e||[]).concat(r.defaultLocale);var t,n,a,o,i=r.__localeData__;for(t=0,n=e.length;n>t;t+=1)for(a=e[t].toLowerCase().split("-");a.length;){if(o=i[a.join("-")])return o.locale;a.pop()}var s=e.pop();throw new Error("No locale data has been added to IntlRelativeFormat for: "+e.join(", ")+", or the default locale: "+s)},r.prototype._resolveStyle=function(e){if(!e)return l[0];if(i.arrIndexOf.call(l,e)>=0)return e;throw new Error('"'+e+'" is not a valid IntlRelativeFormat `style` value, it must be one of: "'+l.join('", "')+'"')},r.prototype._selectUnits=function(e){var t,n,a;for(t=0,n=s.length;n>t&&(a=s[t],!(Math.abs(e[a])r;r++)if(n[r]===e)return r;return-1},l=Array.isArray||function(e){return"[object Array]"===r.call(e)},u=Date.now||function(){return(new Date).getTime()};t.defineProperty=o,t.objCreate=i,t.arrIndexOf=s,t.isArray=l,t.dateNow=u},function(e,t){"use strict";t["default"]={locale:"en",pluralRuleFunction:function(e,t){var n=String(e).split("."),r=!n[1],a=Number(n[0])==e,o=a&&n[0].slice(-1),i=a&&n[0].slice(-2);return t?1==o&&11!=i?"one":2==o&&12!=i?"two":3==o&&13!=i?"few":"other":1==e&&r?"one":"other"},fields:{year:{displayName:"Year",relative:{0:"this year",1:"next year","-1":"last year"},relativeTime:{future:{one:"in {0} year",other:"in {0} years"},past:{one:"{0} year ago",other:"{0} years ago"}}},month:{displayName:"Month",relative:{0:"this month",1:"next month","-1":"last month"},relativeTime:{future:{one:"in {0} month",other:"in {0} months"},past:{one:"{0} month ago",other:"{0} months ago"}}},day:{displayName:"Day",relative:{0:"today",1:"tomorrow","-1":"yesterday"},relativeTime:{future:{one:"in {0} day",other:"in {0} days"},past:{one:"{0} day ago",other:"{0} days ago"}}},hour:{displayName:"Hour",relativeTime:{future:{one:"in {0} hour",other:"in {0} hours"},past:{one:"{0} hour ago",other:"{0} hours ago"}}},minute:{displayName:"Minute",relativeTime:{future:{one:"in {0} minute",other:"in {0} minutes"},past:{one:"{0} minute ago",other:"{0} minutes ago"}}},second:{displayName:"Second",relative:{0:"now"},relativeTime:{future:{one:"in {0} second",other:"in {0} seconds"},past:{one:"{0} second ago",other:"{0} seconds ago"}}}}}},603,609,function(e,t,n){"use strict";function r(e,t){if(!isFinite(e))throw new TypeError(t)}var a=n(613),o=n(594),i=n(604),s=n(614),l={locales:a["default"].PropTypes.oneOfType([a["default"].PropTypes.string,a["default"].PropTypes.array]),formats:a["default"].PropTypes.object,messages:a["default"].PropTypes.object};t["default"]={statics:{filterFormatOptions:function(e,t){return t||(t={}),(this.formatOptions||[]).reduce(function(n,r){return e.hasOwnProperty(r)?n[r]=e[r]:t.hasOwnProperty(r)&&(n[r]=t[r]),n},{})}},propTypes:l,contextTypes:l,childContextTypes:l,getNumberFormat:s["default"](Intl.NumberFormat),getDateTimeFormat:s["default"](Intl.DateTimeFormat),getMessageFormat:s["default"](o["default"]),getRelativeFormat:s["default"](i["default"]),getChildContext:function(){var e=this.context,t=this.props;return{locales:t.locales||e.locales,formats:t.formats||e.formats,messages:t.messages||e.messages}},formatDate:function(e,t){return e=new Date(e),r(e,"A date or timestamp must be provided to formatDate()"),this._format("date",e,t)},formatTime:function(e,t){return e=new Date(e),r(e,"A date or timestamp must be provided to formatTime()"),this._format("time",e,t)},formatRelative:function(e,t,n){return e=new Date(e),r(e,"A date or timestamp must be provided to formatRelative()"),this._format("relative",e,t,n)},formatNumber:function(e,t){return this._format("number",e,t)},formatMessage:function(e,t){var n=this.props.locales||this.context.locales,r=this.props.formats||this.context.formats;return"function"==typeof e?e(t):("string"==typeof e&&(e=this.getMessageFormat(e,n,r)),e.format(t))},getIntlMessage:function(e){var t,n=this.props.messages||this.context.messages,r=e.split(".");try{t=r.reduce(function(e,t){return e[t]},n)}finally{if(void 0===t)throw new ReferenceError("Could not find Intl message: "+e)}return t},getNamedFormat:function(e,t){var n=this.props.formats||this.context.formats,r=null;try{r=n[e][t]}finally{if(!r)throw new ReferenceError("No "+e+" format named: "+t)}return r},_format:function(e,t,n,r){var a=this.props.locales||this.context.locales;switch(n&&"string"==typeof n&&(n=this.getNamedFormat(e,n)),e){case"date":case"time":return this.getDateTimeFormat(a,n).format(t);case"number":return this.getNumberFormat(a,n).format(t);case"relative":return this.getRelativeFormat(a,n).format(t,r);default:throw new Error("Unrecognized format type: "+e)}}}},function(e,t){"use strict";t["default"]=React},function(e,t,n){"use strict";t=e.exports=n(615)["default"],t["default"]=t},function(e,t,n){"use strict";function r(e){var t=i.objCreate(null);return function(){var n=Array.prototype.slice.call(arguments),r=a(n),o=r&&t[r];return o||(o=i.objCreate(e.prototype),e.apply(o,n),r&&(t[r]=o)),o}}function a(e){if("undefined"!=typeof JSON){var t,n,r,a=[];for(t=0,n=e.length;n>t;t+=1)r=e[t],r&&"object"==typeof r?a.push(o(r)):a.push(r);return JSON.stringify(a)}}function o(e){var t,n,r,a,o=[],i=[];for(t in e)e.hasOwnProperty(t)&&i.push(t);var s=i.sort();for(n=0,r=s.length;r>n;n+=1)t=s[n],a={},a[t]=e[t],o[n]=a;return o}var i=n(616);t["default"]=r},function(e,t){"use strict";var n=Object.prototype.hasOwnProperty,r=function(){try{return!!Object.defineProperty({},"a",{})}catch(e){return!1}}(),a=(!r&&!Object.prototype.__defineGetter__,r?Object.defineProperty:function(e,t,r){"get"in r&&e.__defineGetter__?e.__defineGetter__(t,r.get):(!n.call(e,t)||"value"in r)&&(e[t]=r.value)}),o=Object.create||function(e,t){function r(){}var o,i;r.prototype=e,o=new r;for(i in t)n.call(t,i)&&a(o,i,t[i]);return o};t.defineProperty=a,t.objCreate=o},function(e,t,n){"use strict";var r=n(613),a=n(612),o=r["default"].createClass({displayName:"FormattedDate",mixins:[a["default"]],statics:{formatOptions:["localeMatcher","timeZone","hour12","formatMatcher","weekday","era","year","month","day","hour","minute","second","timeZoneName"]},propTypes:{format:r["default"].PropTypes.string,value:r["default"].PropTypes.any.isRequired},render:function(){var e=this.props,t=e.value,n=e.format,a=n&&this.getNamedFormat("date",n),i=o.filterFormatOptions(e,a);return r["default"].DOM.span(null,this.formatDate(t,i))}});t["default"]=o},function(e,t,n){"use strict";var r=n(613),a=n(612),o=r["default"].createClass({displayName:"FormattedTime",mixins:[a["default"]],statics:{formatOptions:["localeMatcher","timeZone","hour12","formatMatcher","weekday","era","year","month","day","hour","minute","second","timeZoneName"]},propTypes:{format:r["default"].PropTypes.string,value:r["default"].PropTypes.any.isRequired},render:function(){var e=this.props,t=e.value,n=e.format,a=n&&this.getNamedFormat("time",n),i=o.filterFormatOptions(e,a);return r["default"].DOM.span(null,this.formatTime(t,i))}});t["default"]=o},function(e,t,n){"use strict";var r=n(613),a=n(612),o=r["default"].createClass({displayName:"FormattedRelative",mixins:[a["default"]],statics:{formatOptions:["style","units"]},propTypes:{format:r["default"].PropTypes.string,value:r["default"].PropTypes.any.isRequired,now:r["default"].PropTypes.any},render:function(){var e=this.props,t=e.value,n=e.format,a=n&&this.getNamedFormat("relative",n),i=o.filterFormatOptions(e,a),s=this.formatRelative(t,i,{now:e.now});return r["default"].DOM.span(null,s)}});t["default"]=o},function(e,t,n){"use strict";var r=n(613),a=n(612),o=r["default"].createClass({displayName:"FormattedNumber",mixins:[a["default"]],statics:{formatOptions:["localeMatcher","style","currency","currencyDisplay","useGrouping","minimumIntegerDigits","minimumFractionDigits","maximumFractionDigits","minimumSignificantDigits","maximumSignificantDigits"]},propTypes:{format:r["default"].PropTypes.string,value:r["default"].PropTypes.any.isRequired},render:function(){var e=this.props,t=e.value,n=e.format,a=n&&this.getNamedFormat("number",n),i=o.filterFormatOptions(e,a);return r["default"].DOM.span(null,this.formatNumber(t,i))}});t["default"]=o},function(e,t,n){"use strict";var r=n(613),a=n(612),o=r["default"].createClass({displayName:"FormattedMessage",mixins:[a["default"]],propTypes:{tagName:r["default"].PropTypes.string,message:r["default"].PropTypes.string.isRequired},getDefaultProps:function(){return{tagName:"span"}},render:function(){var e=this.props,t=e.tagName,n=e.message,a=Math.floor(1099511627776*Math.random()).toString(16),o=new RegExp("(@__ELEMENT-"+a+"-\\d+__@)","g"),i={},s=function(){var e=0;return function(){return"@__ELEMENT-"+a+"-"+(e+=1)+"__@"}}(),l=Object.keys(e).reduce(function(t,n){var a,o=e[n];return r["default"].isValidElement(o)?(a=s(),t[n]=a,i[a]=o):t[n]=o,t},{}),u=this.formatMessage(n,l),c=u.split(o).filter(function(e){return!!e}).map(function(e){return i[e]||e}),d=[t,null].concat(c);return r["default"].createElement.apply(null,d)}});t["default"]=o},function(e,t,n){"use strict";var r=n(613),a=n(623),o=n(612),i=r["default"].createClass({displayName:"FormattedHTMLMessage",mixins:[o["default"]],propTypes:{tagName:r["default"].PropTypes.string,message:r["default"].PropTypes.string.isRequired},getDefaultProps:function(){return{tagName:"span"}},render:function(){var e=this.props,t=e.tagName,n=e.message,o=Object.keys(e).reduce(function(t,n){var o=e[n];return"string"==typeof o?o=a["default"](o):r["default"].isValidElement(o)&&(o=r["default"].renderToStaticMarkup(o)),t[n]=o,t},{});return r["default"].DOM[t]({dangerouslySetInnerHTML:{__html:this.formatMessage(n,o)}})}});t["default"]=i},function(e,t){"use strict";var n={"&":"&",">":">","<":"<",'"':""","'":"'"},r=/[&><"']/g;t["default"]=function(e){return(""+e).replace(r,function(e){return n[e]})}},603,,,,,function(e,t){function n(){}function r(e,t,n,r){this._x=e,this._y=t,this._size=n,this._rotation=r}function a(e,t){this._ctx=e,this._transform=t||r.noTransform,e.beginPath()}function o(e,t,n){var r=(e="string"==typeof e?document.querySelector(e):e).getContext("2d"),a=Math.min(e.width)*(1-2*(n===u?.08:n));r.save(),r.clearRect(0,0,e.width,e.height),r.translate(0|(e.width-a)/2,0|(e.height-a)/2),i(r,t||e.getAttribute(d),a),r.restore()}function i(e,t,o){function i(e,n,o,i,s){var l,u,d,p=i?parseInt(t.charAt(i),16):0,f=n[parseInt(t.charAt(o),16)%n.length];for(l=0;l=0)for(var t=0;t=0)return!0}function l(t){e.fillStyle=p[m[t]].toString()}if(30>o)throw new Error("Jdenticon cannot render identicons smaller than 30 pixels.");if(!/^[0-9a-f]{10,}$/i.test(t))throw new Error("Invalid hash passed to Jdenticon.");o=0|o;for(var u,c=2*(0|o/8),d=parseInt(t.substr(-7),16)/268435455,p=[n.rgb(76,76,76),n.correctedHsl(d,.5,.6),n.rgb(230,230,230),n.correctedHsl(d,.5,.8),n.hsl(d,.5,.4)],m=[],g=0;3>g;g++)u=parseInt(t.charAt(8+g),16)%p.length,(s([0,4])||s([2,3]))&&(u=1),m.push(u);e.clearRect(0,0,o,o),l(0),i(e,h,2,3,[[1,0],[2,0],[2,3],[1,3],[0,1],[3,1],[3,2],[0,2]]),l(1),i(e,h,4,5,[[0,0],[3,0],[3,3],[0,3]]),l(2),i(e,f,1,null,[[1,1],[2,1],[2,2],[1,2]])}function s(e){var t,n=document.getElementById(e);t=n.getAttribute(d),t&&o(n,t,0)}function l(){for(var e,t=document.getElementsByTagName("canvas"),n=0;n=0;r+=n)a.lineTo.apply(a,this._transform.transformPoint(e[r],e[r+1]));a.closePath()},addEllipse:function(e,t,n,r,a){var o=this._ctx,i=.5522848,s=this._transform.transformPoint(e,t,n,r),e=s[0],t=s[1],l=n/2*i,u=r/2*i,c=e+n,d=t+r,p=e+n/2,f=t+r/2;a&&(d=t,t+=r,u=-u),o.moveTo(e,f),o.bezierCurveTo(e,f-u,p-l,t,p,t),o.bezierCurveTo(p+l,t,c,f-u,c,f),o.bezierCurveTo(c,f+u,p+l,d,p,d),o.bezierCurveTo(p-l,d,e,f+u,e,f),o.closePath()},addRectangle:function(e,t,n,r,a){this.addPolygon([e,t,e+n,t,e+n,t+r,e,t+r],a)},addTriangle:function(e,t,n,r,a,o){var i=[e+n,t,e+n,t+r,e,t+r,e,t];i.splice((a||0)%4*2,2),this.addPolygon(i,o)},addRhombus:function(e,t,n,r,a){this.addPolygon([e+n/2,t,e+n,t+r/2,e+n/2,t+r,e,t+r/2],a)},fill:function(){this._ctx.fill()}};var f=[function(e,t,n){var r=.42*t;e.addPolygon([0,0,t,0,t,t-2*r,t-r,t,0,t])},function(e,t,n){var r=0|.5*t,a=0|.8*t;e.addTriangle(t-r,0,r,a,2)},function(e,t,n){var r=0|t/3;e.addRectangle(r,r,t-r,t-r)},function(e,t,n){var r=0|.1*t,a=0|.25*t;e.addRectangle(a,a,t-r-a,t-r-a)},function(e,t,n){var r=0|.15*t,a=0|.5*t;e.addEllipse(t-a-r,t-a-r,a,a)},function(e,t,n){var r=.1*t,a=4*r;e.addRectangle(0,0,t,t),e.addPolygon([a,a,t-r,a,a+(t-a-r)/2,t-r],!0)},function(e,t,n){e.addPolygon([0,0,t,0,t,.7*t,.4*t,.4*t,.7*t,t,0,t])},function(e,t,n){e.addTriangle(t/2,t/2,t/2,t/2,3)},function(e,t,n){e.addRectangle(0,0,t,t/2),e.addRectangle(0,t/2,t/2,t/2),e.addTriangle(t/2,t/2,t/2,t/2,1)},function(e,t,n){var r=0|.14*t,a=0|.35*t;e.addRectangle(0,0,t,t),e.addRectangle(a,a,t-a-r,t-a-r,!0)},function(e,t,n){var r=.12*t,a=3*r;e.addRectangle(0,0,t,t),e.addEllipse(a,a,t-r-a,t-r-a,!0)},function(e,t,n){e.addTriangle(t/2,t/2,t/2,t/2,3)},function(e,t,n){var r=.25*t;e.addRectangle(0,0,t,t),e.addRhombus(r,r,t-r,t-r,!0)},function(e,t,n){var r=.4*t,a=1.2*t;n||e.addEllipse(r,r,a,a)}],h=[function(e,t,n){e.addTriangle(0,0,t,t,0)},function(e,t,n){e.addTriangle(0,t/2,t,t/2,0)},function(e,t,n){e.addRhombus(0,0,t,t)},function(e,t,n){var r=t/6;e.addEllipse(r,r,t-2*r,t-2*r)}];l.drawIcon=i,l.update=o,l.version=c,p&&(p.fn.jdenticon=function(e,t){return this.each(function(n,r){o(r,e,t)}),this}),e.exports={jdenticon:l,updateById:s}},,function(e,t,n){"use strict";var r=n(196),a=n(632),o=n(407),i=n(635),s=r.PropTypes,l=s.shape({getLocale:s.func,onLocaleChange:s.func,offLocaleChange:s.func,translate:s.func}),u=r.createClass({displayName:"Translate",contextTypes:{translator:l},propTypes:{locale:s.string,count:s.number,content:s.oneOfType([s.string,s.arrayOf(s.string)]),scope:s.oneOfType([s.string,s.arrayOf(s.string)]),attributes:s.object},statics:{textContentComponents:["title","option","textarea"]},getDefaultProps:function(){ +return{component:"span"}},getInitialState:function(){return{locale:this.getTranslator().getLocale()}},getTranslator:function(){return this.context.translator||o},componentDidMount:function(){this.props.locale||this.getTranslator().onLocaleChange(this.localeChanged)},componentWillUnmount:function(){this.props.locale||this.getTranslator().offLocaleChange(this.localeChanged)},localeChanged:function(e){this.setState({locale:e})},render:function(){var e=this.getTranslator(),t=u.textContentComponents.indexOf(this.props.component)>-1,n=t||this.props.unsafe===!0,o=i({locale:this.state.locale},this.props,{interpolate:n});if(o.attributes){for(var s in o.attributes)o.attributes[s]&&(o[s]=e.translate(o.attributes[s],o));delete o.attributes}if(o.content){var l=e.translate(o.content,o);return delete o.content,delete o.locale,delete o.scope,delete o.children,delete o.interpolate,r.createElement(a,o,l)}return delete o.locale,delete o.scope,delete o.interpolate,r.createElement(o.component,o)}});e.exports=u,e.exports.translate=function(e,t){return r.createElement(u,i({},t,{content:e}))},e.exports.translatorType=l},function(e,t,n){"use strict";function r(e){return"[object String]"===Object.prototype.toString.call(e)}var a=n(196),o=n(201),i=n(633),s=/\%\((.+?)\)s/,l=["children","format","component","unsafe"],u=a.createClass({displayName:"Interpolate",getDefaultProps:function(){return{component:"span"}},render:function(){var e=this.props.children||this.props.format,t=this.props.component,n=this.props.unsafe===!0,u=i(this.props,l),c=[],d=[];if(o(r(e),"Interpolate expects either a format string as only child or a `format` prop with a string value"),n){var p=e.split(s).reduce(function(e,t,n){var r;if(n%2===0?r=t:(r=u[t],c.push(t)),a.isValidElement(r))throw new Error("cannot interpolate a React component into unsafe text");return e+=r},"");u.dangerouslySetInnerHTML={__html:p}}else e.split(s).reduce(function(e,t,n){var r;if(n%2===0){if(0===t.length)return e;r=t}else r=u[t],c.push(t);return e.push(r),e},d);return u=i(u,c),a.createElement.apply(this,[t,u].concat(d))}});e.exports=u},[859,634],415,356,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){var r=n(196),a=r.DOM,o=n(671),i=r.createFactory(o),s=n(675),l=r.createFactory(s),u=n(679),c=n(681),d=n(682),p=n(678);e.exports=r.createClass({propTypes:{data:r.PropTypes.object.isRequired,search:r.PropTypes.component,onClick:r.PropTypes.func,validateQuery:r.PropTypes.func,isExpanded:r.PropTypes.func,filterOptions:r.PropTypes.object},getDefaultProps:function(){return{data:null,search:l,className:"",id:"json-"+Date.now(),onClick:p,filterOptions:{},validateQuery:function(e){return e.length>=2},isExpanded:function(e,t){return!1}}},getInitialState:function(){return{query:""}},render:function(){var e=this.props,t=this.state,n=t.query?t.filterer(t.query):e.data,r=i({data:n,onClick:e.onClick,id:e.id,getOriginal:this.getOriginal,query:t.query,label:"root",root:!0,isExpanded:e.isExpanded,interactiveLabel:e.interactiveLabel}),o=a.div({className:"json-inspector__not-found"},"Nothing found");return a.div({className:"json-inspector "+e.className},this.renderToolbar(),c(n)?o:r)},renderToolbar:function(){var e=this.props.search;return e?a.div({className:"json-inspector__toolbar"},e({onChange:this.search,data:this.props.data})):void 0},search:function(e){(""===e||this.props.validateQuery(e))&&this.setState({query:e})},componentDidMount:function(){this.createFilterer(this.props.data,this.props.filterOptions)},componentWillReceiveProps:function(e){this.createFilterer(e.data,e.filterOptions)},shouldComponentUpdate:function(e,t){return t.query!==this.state.query||e.data!==this.props.data||e.onClick!==this.props.onClick},createFilterer:function(e,t){this.setState({filterer:u(e,t)})},getOriginal:function(e){return d(this.props.data,e)}})},function(e,t,n){function r(e){return e+(1===e?" item":" items")}function a(e,t){return i(t)?e+":"+t:e+"["+c(t)+"]"}function o(e,t){return-1!==e.indexOf(t)}function i(e){var t=c(e);return"Object"!==t&&"Array"!==t}var s=n(196),l=s.DOM,u=n(672),c=n(673),d=n(674),p=s.createFactory(d),f=".root.",h=s.createClass({getInitialState:function(){return{expanded:this._isInitiallyExpanded(this.props)}},getDefaultProps:function(){return{root:!1,prefix:""}},render:function(){var e="id_"+u(),t=this.props,n={path:this.keypath(),key:t.label.toString(),value:t.data},r=this._onClick.bind(this,n);return l.div({className:this.getClassName(),id:"leaf-"+this._rootPath()},l.input({className:"json-inspector__radio",type:"radio",name:t.id,id:e,tabIndex:-1}),l.label({className:"json-inspector__line",htmlFor:e,onClick:r},l.div({className:"json-inspector__flatpath"},n.path),l.span({className:"json-inspector__key"},this.format(n.key),":",this.renderInteractiveLabel(n.key,!0)),this.renderTitle(),this.renderShowOriginalButton()),this.renderChildren())},renderTitle:function(){var e=this.data(),t=c(e);switch(t){case"Array":return l.span({className:"json-inspector__value json-inspector__value_helper"},"[] "+r(e.length));case"Object":return l.span({className:"json-inspector__value json-inspector__value_helper"},"{} "+r(Object.keys(e).length));default:return l.span({className:"json-inspector__value json-inspector__value_"+t.toLowerCase()},this.format(String(e)),this.renderInteractiveLabel(e,!1))}},renderChildren:function(){var e=this.props,t=this._rootPath(),n=this.data();return this.state.expanded&&!i(n)?Object.keys(n).map(function(r){var o=n[r];return m({data:o,label:r,prefix:t,onClick:e.onClick,id:e.id,query:e.query,getOriginal:this.state.original?null:e.getOriginal,key:a(r,o),isExpanded:e.isExpanded,interactiveLabel:e.interactiveLabel})},this):null},renderShowOriginalButton:function(){var e=this.props;return i(e.data)||this.state.original||!e.getOriginal||!e.query||o(this.keypath(),e.query)?null:l.span({className:"json-inspector__show-original",onClick:this._onShowOriginalClick})},renderInteractiveLabel:function(e,t){return"function"==typeof this.props.interactiveLabel?this.props.interactiveLabel({value:String(e),originalValue:e,isKey:t,keypath:this.keypath()}):null},componentWillReceiveProps:function(e){e.query&&this.setState({expanded:!o(e.label,e.query)}),this.props.query&&!e.query&&this.setState({expanded:this._isInitiallyExpanded(e)})},_rootPath:function(){return this.props.prefix+"."+this.props.label},keypath:function(){return this._rootPath().substr(f.length)},data:function(){return this.state.original||this.props.data},format:function(e){return p({string:e,highlight:this.props.query})},getClassName:function(){var e="json-inspector__leaf";return this.props.root&&(e+=" json-inspector__leaf_root"),this.state.expanded&&(e+=" json-inspector__leaf_expanded"),i(this.props.data)||(e+=" json-inspector__leaf_composite"),e},toggle:function(){this.setState({expanded:!this.state.expanded})},_onClick:function(e,t){this.toggle(),this.props.onClick(e),t.stopPropagation()},_onShowOriginalClick:function(e){this.setState({original:this.props.getOriginal(this.keypath())}),e.stopPropagation()},_isInitiallyExpanded:function(e){var t=this.keypath();return e.root?!0:""===e.query?e.isExpanded(t,e.data):!o(t,e.query)&&"function"==typeof e.getOriginal}}),m=s.createFactory(h);e.exports=h},function(e,t){var n=Math.ceil(10*Math.random());e.exports=function(){return++n}},function(e,t){e.exports=function(e){return Object.prototype.toString.call(e).slice(8,-1)}},function(e,t,n){var r=n(196),a=r.DOM.span;e.exports=r.createClass({getDefaultProps:function(){return{string:"",highlight:""}},shouldComponentUpdate:function(e){return e.highlight!==this.props.highlight},render:function(){var e=this.props;return e.highlight&&-1!==e.string.indexOf(e.highlight)?a(null,e.string.split(e.highlight).map(function(t,n){return a({key:n},n>0?a({className:"json-inspector__hl"},e.highlight):null,t)})):a(null,e.string)}})},function(e,t,n){var r=n(676),a=n(196),o=a.DOM.input,i=n(678);e.exports=a.createClass({getDefaultProps:function(){return{timeout:100,onChange:i}},render:function(){return o({className:"json-inspector__search",type:"search",placeholder:"Search",ref:"query",onChange:r(this.update,this.props.timeout)})},update:function(){this.props.onChange(this.refs.query.getDOMNode().value)}})},function(e,t,n){var r=n(677);e.exports=function(e,t,n){function a(){var c=r()-l;t>c&&c>0?o=setTimeout(a,t-c):(o=null,n||(u=e.apply(s,i),o||(s=i=null)))}var o,i,s,l,u;return null==t&&(t=100),function(){s=this,i=arguments,l=r();var c=n&&!o;return o||(o=setTimeout(a,t)),c&&(u=e.apply(s,i),s=i=null),u}}},function(e,t){function n(){return(new Date).getTime()}e.exports=Date.now||n},function(e,t){e.exports=function(){}},function(e,t,n){function r(e,t,n){return l(e).reduce(function(l,u){var d,p=e[u];return o(p)?(a(t,u,n)||a(t,p,n))&&(l[u]=p):a(t,u,n)?l[u]=p:(d=r(p,t,n),c(d)||s(l,i(u,d))),l},{})}function a(e,t,n){return n.ignoreCase?(e=String(e).toLowerCase(),t&&-1!==String(t).toLowerCase().indexOf(e)):t&&-1!==String(t).indexOf(e)}function o(e){var t=u(e);return"Object"!==t&&"Array"!==t}function i(e,t){var n={};return n[e]=t,n}var s=n(680),l=Object.keys,u=n(673),c=n(681);e.exports=function(e,t){t||(t={});var n={};return function(a){var o;if(!n[a])for(var i=a.length-1;i>0;i-=1)if(o=a.substr(0,i),n[o]){n[a]=r(n[o],a,t);break}return n[a]||(n[a]=r(e,a,t)),n[a]}}},356,function(e,t){e.exports=function(e){return 0===Object.keys(e).length}},function(e,t,n){function r(e,t){var n=t.split(i),s=n.shift();if(!s)return e;var l=o(e);return"Array"===l&&e[a(s)]?r(e[a(s)],n.join(i)):"Object"===l&&e[s]?r(e[s],n.join(i)):void 0}function a(e){return parseInt(e,10)}var o=n(673),i=".";e.exports=r},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){var r;/*! + Copyright (c) 2015 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames + */ +!function(){"use strict";function a(){for(var e="",t=0;t=0&&n.splice(r,1),e.className=n.join(" ")}t.add=function(e,t){e.classList?e.classList.add(t):n(e,t)},t.remove=function(e,t){e.classList?e.classList.remove(t):r(e,t)},t.list=function(e){return e.classList?e.classList:e.className.split(" ")}},function(e,t,n){"use strict";function r(e){var t=this;t.settings=d.clone(l),t.containerWidth=null,t.containerHeight=null,t.contentWidth=null,t.contentHeight=null,t.isRtl="rtl"===s.css(e,"direction"),t.isNegativeScroll=function(){var t=e.scrollLeft,n=null;return e.scrollLeft=-1,n=e.scrollLeft<0,e.scrollLeft=t,n}(),t.negativeScrollAdjustment=t.isNegativeScroll?e.scrollWidth-e.clientWidth:0,t.event=new u,t.ownerDocument=e.ownerDocument||document,t.scrollbarXRail=s.appendTo(s.e("div","ps-scrollbar-x-rail"),e),t.scrollbarX=s.appendTo(s.e("div","ps-scrollbar-x"),t.scrollbarXRail),t.scrollbarXActive=null,t.scrollbarXWidth=null,t.scrollbarXLeft=null,t.scrollbarXBottom=d.toInt(s.css(t.scrollbarXRail,"bottom")),t.isScrollbarXUsingBottom=t.scrollbarXBottom===t.scrollbarXBottom,t.scrollbarXTop=t.isScrollbarXUsingBottom?null:d.toInt(s.css(t.scrollbarXRail,"top")),t.railBorderXWidth=d.toInt(s.css(t.scrollbarXRail,"borderLeftWidth"))+d.toInt(s.css(t.scrollbarXRail,"borderRightWidth")),s.css(t.scrollbarXRail,"display","block"),t.railXMarginWidth=d.toInt(s.css(t.scrollbarXRail,"marginLeft"))+d.toInt(s.css(t.scrollbarXRail,"marginRight")),s.css(t.scrollbarXRail,"display",""),t.railXWidth=null,t.railXRatio=null,t.scrollbarYRail=s.appendTo(s.e("div","ps-scrollbar-y-rail"),e),t.scrollbarY=s.appendTo(s.e("div","ps-scrollbar-y"),t.scrollbarYRail),t.scrollbarYActive=null,t.scrollbarYHeight=null,t.scrollbarYTop=null,t.scrollbarYRight=d.toInt(s.css(t.scrollbarYRail,"right")),t.isScrollbarYUsingRight=t.scrollbarYRight===t.scrollbarYRight,t.scrollbarYLeft=t.isScrollbarYUsingRight?null:d.toInt(s.css(t.scrollbarYRail,"left")),t.scrollbarYOuterWidth=t.isRtl?d.outerWidth(t.scrollbarY):null,t.railBorderYWidth=d.toInt(s.css(t.scrollbarYRail,"borderTopWidth"))+d.toInt(s.css(t.scrollbarYRail,"borderBottomWidth")),s.css(t.scrollbarYRail,"display","block"),t.railYMarginHeight=d.toInt(s.css(t.scrollbarYRail,"marginTop"))+d.toInt(s.css(t.scrollbarYRail,"marginBottom")),s.css(t.scrollbarYRail,"display",""),t.railYHeight=null,t.railYRatio=null}function a(e){return"undefined"==typeof e.dataset?e.getAttribute("data-ps-id"):e.dataset.psId}function o(e,t){"undefined"==typeof e.dataset?e.setAttribute("data-ps-id",t):e.dataset.psId=t}function i(e){"undefined"==typeof e.dataset?e.removeAttribute("data-ps-id"):delete e.dataset.psId}var s=n(754),l=n(758),u=n(759),c=n(760),d=n(755),p={};t.add=function(e){var t=c();return o(e,t),p[t]=new r(e),p[t]},t.remove=function(e){delete p[a(e)],i(e)},t.get=function(e){return p[a(e)]}},function(e,t){"use strict";e.exports={wheelSpeed:1,wheelPropagation:!1,swipePropagation:!0,minScrollbarLength:null,maxScrollbarLength:null,useBothWheelAxes:!1,useKeyboard:!0,suppressScrollX:!1,suppressScrollY:!1,scrollXMarginOffset:0,scrollYMarginOffset:0,stopPropagationOnClick:!0}},function(e,t){"use strict";var n=function(e){this.element=e,this.events={}};n.prototype.bind=function(e,t){"undefined"==typeof this.events[e]&&(this.events[e]=[]),this.events[e].push(t),this.element.addEventListener(e,t,!1)},n.prototype.unbind=function(e,t){var n="undefined"!=typeof t;this.events[e]=this.events[e].filter(function(r){return n&&r!==t?!0:(this.element.removeEventListener(e,r,!1),!1)},this)},n.prototype.unbindAll=function(){for(var e in this.events)this.unbind(e)};var r=function(){this.eventElements=[]};r.prototype.eventElement=function(e){var t=this.eventElements.filter(function(t){return t.element===e})[0];return"undefined"==typeof t&&(t=new n(e),this.eventElements.push(t)),t},r.prototype.bind=function(e,t,n){this.eventElement(e).bind(t,n)},r.prototype.unbind=function(e,t,n){this.eventElement(e).unbind(t,n)},r.prototype.unbindAll=function(){for(var e=0;e=t.railXWidth-t.scrollbarXWidth&&(t.scrollbarXLeft=t.railXWidth-t.scrollbarXWidth),t.scrollbarYTop>=t.railYHeight-t.scrollbarYHeight&&(t.scrollbarYTop=t.railYHeight-t.scrollbarYHeight),a(e,t),o[t.scrollbarXActive?"add":"remove"](e,"ps-active-x"),o[t.scrollbarYActive?"add":"remove"](e,"ps-active-y")}},function(e,t,n){"use strict";function r(e,t){function n(e){return e.getBoundingClientRect()}var r=window.Event.prototype.stopPropagation.bind;t.settings.stopPropagationOnClick&&t.event.bind(t.scrollbarY,"click",r),t.event.bind(t.scrollbarYRail,"click",function(r){var o=a.toInt(t.scrollbarYHeight/2),s=t.railYRatio*(r.pageY-window.scrollY-n(t.scrollbarYRail).top-o),l=t.railYRatio*(t.railYHeight-t.scrollbarYHeight),u=s/l;0>u?u=0:u>1&&(u=1),e.scrollTop=(t.contentHeight-t.containerHeight)*u,i(e),r.stopPropagation()}),t.settings.stopPropagationOnClick&&t.event.bind(t.scrollbarX,"click",r),t.event.bind(t.scrollbarXRail,"click",function(r){var o=a.toInt(t.scrollbarXWidth/2),s=t.railXRatio*(r.pageX-window.scrollX-n(t.scrollbarXRail).left-o),l=t.railXRatio*(t.railXWidth-t.scrollbarXWidth),u=s/l;0>u?u=0:u>1&&(u=1),e.scrollLeft=(t.contentWidth-t.containerWidth)*u-t.negativeScrollAdjustment,i(e),r.stopPropagation()})}var a=n(755),o=n(757),i=n(762);e.exports=function(e){var t=o.get(e);r(e,t)}},function(e,t,n){"use strict";function r(e,t){function n(n){var a=r+n*t.railXRatio,o=t.scrollbarXRail.getBoundingClientRect().left+t.railXRatio*(t.railXWidth-t.scrollbarXWidth);0>a?t.scrollbarXLeft=0:a>o?t.scrollbarXLeft=o:t.scrollbarXLeft=a;var s=i.toInt(t.scrollbarXLeft*(t.contentWidth-t.containerWidth)/(t.containerWidth-t.railXRatio*t.scrollbarXWidth))-t.negativeScrollAdjustment;e.scrollLeft=s}var r=null,a=null,s=function(t){n(t.pageX-a),l(e),t.stopPropagation(),t.preventDefault()},u=function(){i.stopScrolling(e,"x"),t.event.unbind(t.ownerDocument,"mousemove",s)};t.event.bind(t.scrollbarX,"mousedown",function(n){a=n.pageX,r=i.toInt(o.css(t.scrollbarX,"left"))*t.railXRatio,i.startScrolling(e,"x"),t.event.bind(t.ownerDocument,"mousemove",s),t.event.once(t.ownerDocument,"mouseup",u),n.stopPropagation(),n.preventDefault()})}function a(e,t){function n(n){var a=r+n*t.railYRatio,o=t.scrollbarYRail.getBoundingClientRect().top+t.railYRatio*(t.railYHeight-t.scrollbarYHeight);0>a?t.scrollbarYTop=0:a>o?t.scrollbarYTop=o:t.scrollbarYTop=a;var s=i.toInt(t.scrollbarYTop*(t.contentHeight-t.containerHeight)/(t.containerHeight-t.railYRatio*t.scrollbarYHeight));e.scrollTop=s}var r=null,a=null,s=function(t){n(t.pageY-a),l(e),t.stopPropagation(),t.preventDefault()},u=function(){i.stopScrolling(e,"y"),t.event.unbind(t.ownerDocument,"mousemove",s)};t.event.bind(t.scrollbarY,"mousedown",function(n){a=n.pageY,r=i.toInt(o.css(t.scrollbarY,"top"))*t.railYRatio,i.startScrolling(e,"y"),t.event.bind(t.ownerDocument,"mousemove",s),t.event.once(t.ownerDocument,"mouseup",u),n.stopPropagation(),n.preventDefault()})}var o=n(754),i=n(755),s=n(757),l=n(762);e.exports=function(e){var t=s.get(e);r(e,t),a(e,t)}},function(e,t,n){"use strict";function r(e,t){function n(n,r){var a=e.scrollTop;if(0===n){if(!t.scrollbarYActive)return!1;if(0===a&&r>0||a>=t.contentHeight-t.containerHeight&&0>r)return!t.settings.wheelPropagation}var o=e.scrollLeft;if(0===r){if(!t.scrollbarXActive)return!1;if(0===o&&0>n||o>=t.contentWidth-t.containerWidth&&n>0)return!t.settings.wheelPropagation}return!0}var r=!1;t.event.bind(e,"mouseenter",function(){r=!0}),t.event.bind(e,"mouseleave",function(){r=!1});var o=!1;t.event.bind(t.ownerDocument,"keydown",function(s){if((!s.isDefaultPrevented||!s.isDefaultPrevented())&&r){var l=document.activeElement?document.activeElement:t.ownerDocument.activeElement;if(l){for(;l.shadowRoot;)l=l.shadowRoot.activeElement;if(a.isEditable(l))return}var u=0,c=0;switch(s.which){case 37:u=-30;break;case 38:c=30;break;case 39:u=30;break;case 40:c=-30;break;case 33:c=90;break;case 32:case 34:c=-90;break;case 35:c=s.ctrlKey?-t.contentHeight:-t.containerHeight;break;case 36:c=s.ctrlKey?e.scrollTop:t.containerHeight;break;default:return}e.scrollTop=e.scrollTop-c,e.scrollLeft=e.scrollLeft+u,i(e),o=n(u,c),o&&s.preventDefault()}})}var a=n(755),o=n(757),i=n(762);e.exports=function(e){var t=o.get(e);r(e,t)}},function(e,t,n){"use strict";function r(e,t){function n(n,r){var a=e.scrollTop;if(0===n){if(!t.scrollbarYActive)return!1;if(0===a&&r>0||a>=t.contentHeight-t.containerHeight&&0>r)return!t.settings.wheelPropagation}var o=e.scrollLeft;if(0===r){if(!t.scrollbarXActive)return!1;if(0===o&&0>n||o>=t.contentWidth-t.containerWidth&&n>0)return!t.settings.wheelPropagation}return!0}function r(e){var t=e.deltaX,n=-1*e.deltaY;return("undefined"==typeof t||"undefined"==typeof n)&&(t=-1*e.wheelDeltaX/6,n=e.wheelDeltaY/6),e.deltaMode&&1===e.deltaMode&&(t*=10,n*=10),t!==t&&n!==n&&(t=0,n=e.wheelDelta),[t,n]}function o(t,n){var r=e.querySelector("textarea:hover");if(r){var a=r.scrollHeight-r.clientHeight;if(a>0&&!(0===r.scrollTop&&n>0||r.scrollTop===a&&0>n))return!0;var o=r.scrollLeft-r.clientWidth;if(o>0&&!(0===r.scrollLeft&&0>t||r.scrollLeft===o&&t>0))return!0}return!1}function s(s){if(a.env.isWebKit||!e.querySelector("select:focus")){var u=r(s),c=u[0],d=u[1];o(c,d)||(l=!1,t.settings.useBothWheelAxes?t.scrollbarYActive&&!t.scrollbarXActive?(d?e.scrollTop=e.scrollTop-d*t.settings.wheelSpeed:e.scrollTop=e.scrollTop+c*t.settings.wheelSpeed,l=!0):t.scrollbarXActive&&!t.scrollbarYActive&&(c?e.scrollLeft=e.scrollLeft+c*t.settings.wheelSpeed:e.scrollLeft=e.scrollLeft-d*t.settings.wheelSpeed,l=!0):(e.scrollTop=e.scrollTop-d*t.settings.wheelSpeed,e.scrollLeft=e.scrollLeft+c*t.settings.wheelSpeed),i(e),l=l||n(c,d),l&&(s.stopPropagation(),s.preventDefault()))}}var l=!1;"undefined"!=typeof window.onwheel?t.event.bind(e,"wheel",s):"undefined"!=typeof window.onmousewheel&&t.event.bind(e,"mousewheel",s)}var a=n(755),o=n(757),i=n(762);e.exports=function(e){var t=o.get(e);r(e,t)}},function(e,t,n){"use strict";function r(e,t){t.event.bind(e,"scroll",function(){o(e)})}var a=n(757),o=n(762);e.exports=function(e){var t=a.get(e);r(e,t)}},function(e,t,n){"use strict";function r(e,t){function n(){var e=window.getSelection?window.getSelection():document.getSelection?document.getSelection():"";return 0===e.toString().length?null:e.getRangeAt(0).commonAncestorContainer}function r(){l||(l=setInterval(function(){return o.get(e)?(e.scrollTop=e.scrollTop+u.top,e.scrollLeft=e.scrollLeft+u.left,void i(e)):void clearInterval(l)},50))}function s(){l&&(clearInterval(l),l=null),a.stopScrolling(e)}var l=null,u={top:0,left:0},c=!1;t.event.bind(t.ownerDocument,"selectionchange",function(){e.contains(n())?c=!0:(c=!1,s())}),t.event.bind(window,"mouseup",function(){c&&(c=!1,s())}),t.event.bind(window,"mousemove",function(t){if(c){var n={x:t.pageX,y:t.pageY},o={left:e.offsetLeft,right:e.offsetLeft+e.offsetWidth,top:e.offsetTop,bottom:e.offsetTop+e.offsetHeight};n.xo.right-3?(u.left=5,a.startScrolling(e,"x")):u.left=0,n.yo.bottom-3?(n.y-o.bottom+3<5?u.top=5:u.top=20,a.startScrolling(e,"y")):u.top=0,0===u.top&&0===u.left?s():r()}})}var a=n(755),o=n(757),i=n(762);e.exports=function(e){var t=o.get(e);r(e,t)}},function(e,t,n){"use strict";function r(e,t,n,r){function i(n,r){var a=e.scrollTop,o=e.scrollLeft,i=Math.abs(n),s=Math.abs(r);if(s>i){if(0>r&&a===t.contentHeight-t.containerHeight||r>0&&0===a)return!t.settings.swipePropagation}else if(i>s&&(0>n&&o===t.contentWidth-t.containerWidth||n>0&&0===o))return!t.settings.swipePropagation;return!0}function s(t,n){e.scrollTop=e.scrollTop-n,e.scrollLeft=e.scrollLeft-t,o(e)}function l(){v=!0}function u(){v=!1}function c(e){return e.targetTouches?e.targetTouches[0]:e}function d(e){return e.targetTouches&&1===e.targetTouches.length?!0:e.pointerType&&"mouse"!==e.pointerType&&e.pointerType!==e.MSPOINTER_TYPE_MOUSE?!0:!1}function p(e){if(d(e)){_=!0;var t=c(e);m.pageX=t.pageX,m.pageY=t.pageY,g=(new Date).getTime(),null!==b&&clearInterval(b),e.stopPropagation()}}function f(e){if(!v&&_&&d(e)){var t=c(e),n={pageX:t.pageX,pageY:t.pageY},r=n.pageX-m.pageX,a=n.pageY-m.pageY;s(r,a),m=n;var o=(new Date).getTime(),l=o-g;l>0&&(y.x=r/l,y.y=a/l,g=o),i(r,a)&&(e.stopPropagation(),e.preventDefault())}}function h(){!v&&_&&(_=!1,clearInterval(b),b=setInterval(function(){return a.get(e)?Math.abs(y.x)<.01&&Math.abs(y.y)<.01?void clearInterval(b):(s(30*y.x,30*y.y),y.x*=.8,void(y.y*=.8)):void clearInterval(b)},10))}var m={},g=0,y={},b=null,v=!1,_=!1;n&&(t.event.bind(window,"touchstart",l),t.event.bind(window,"touchend",u),t.event.bind(e,"touchstart",p),t.event.bind(e,"touchmove",f),t.event.bind(e,"touchend",h)),r&&(window.PointerEvent?(t.event.bind(window,"pointerdown",l),t.event.bind(window,"pointerup",u),t.event.bind(e,"pointerdown",p),t.event.bind(e,"pointermove",f),t.event.bind(e,"pointerup",h)):window.MSPointerEvent&&(t.event.bind(window,"MSPointerDown",l),t.event.bind(window,"MSPointerUp",u),t.event.bind(e,"MSPointerDown",p),t.event.bind(e,"MSPointerMove",f),t.event.bind(e,"MSPointerUp",h)))}var a=n(757),o=n(762);e.exports=function(e,t,n){var o=a.get(e);r(e,o,t,n)}},function(e,t,n){"use strict";var r=n(754),a=n(755),o=n(757),i=n(762);e.exports=function(e){var t=o.get(e);t&&(t.negativeScrollAdjustment=t.isNegativeScroll?e.scrollWidth-e.clientWidth:0,r.css(t.scrollbarXRail,"display","block"),r.css(t.scrollbarYRail,"display","block"),t.railXMarginWidth=a.toInt(r.css(t.scrollbarXRail,"marginLeft"))+a.toInt(r.css(t.scrollbarXRail,"marginRight")),t.railYMarginHeight=a.toInt(r.css(t.scrollbarYRail,"marginTop"))+a.toInt(r.css(t.scrollbarYRail,"marginBottom")),r.css(t.scrollbarXRail,"display","none"),r.css(t.scrollbarYRail,"display","none"),i(e),r.css(t.scrollbarXRail,"display",""),r.css(t.scrollbarYRail,"display",""))}},,,,,,,,function(e,t,n){!function(t,r){e.exports=r(n(196),n(564))}(this,function(e,t){return function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(7)},,function(e,t){/** + * @license @product.name@ JS v@product.version@ (@product.date@) + * + * Standalone Highcharts Framework + * + * License: MIT License + */ +var n=function(){function e(e){function r(e,t,n){e.removeEventListener(t,n,!1)}function a(e,t,n){n=e.HCProxiedMethods[n.toString()],e.detachEvent("on"+t,n)}function o(e,t){var n,o,i,s,l=e.HCEvents;if(e.removeEventListener)n=r;else{if(!e.attachEvent)return;n=a}t?(o={},o[t]=!0):o=l;for(s in o)if(l[s])for(i=l[s].length;i--;)n(e,s,l[s][i])}return e.HCExtended||Highcharts.extend(e,{HCExtended:!0,HCEvents:{},bind:function(e,n){var r,a=this,o=this.HCEvents;a.addEventListener?a.addEventListener(e,n,!1):a.attachEvent&&(r=function(e){e.target=e.srcElement||window,n.call(a,e)},a.HCProxiedMethods||(a.HCProxiedMethods={}),a.HCProxiedMethods[n.toString()]=r,a.attachEvent("on"+e,r)),o[e]===t&&(o[e]=[]),o[e].push(n)},unbind:function(e,t){var i,s;e?(i=this.HCEvents[e]||[],t?(s=n.inArray(t,i),s>-1&&(i.splice(s,1),this.HCEvents[e]=i),this.removeEventListener?r(this,e,t):this.attachEvent&&a(this,e,t)):(o(this,e),this.HCEvents[e]=[])):(o(this),this.HCEvents={})},trigger:function(e,t){var n,r,a,o=this.HCEvents[e]||[],i=this,s=o.length;for(r=function(){t.defaultPrevented=!0},n=0;s>n;n++){if(a=o[n],t.stopped)return;t.preventDefault=r,t.target=i,t.type||(t.type=e),a.call(this,t)===!1&&t.preventDefault()}}}),e}var t,r,a,o=document,i=[],s=[],l={};return Math.easeInOutSine=function(e,t,n,r){return-n/2*(Math.cos(Math.PI*e/r)-1)+t},{init:function(e){o.defaultView||(this._getStyle=function(e,t){var n;return e.style[t]?e.style[t]:("opacity"===t&&(t="filter"),n=e.currentStyle[t.replace(/\-(\w)/g,function(e,t){return t.toUpperCase()})],"filter"===t&&(n=n.replace(/alpha\(opacity=([0-9]+)\)/,function(e,t){return t/100})),""===n?1:n)},this.adapterRun=function(e,t){var r={width:"clientWidth",height:"clientHeight"}[t];return r?(e.style.zoom=1,e[r]-2*parseInt(n._getStyle(e,"padding"),10)):void 0}),Array.prototype.forEach||(this.each=function(e,t){for(var n=0,r=e.length;r>n;n++)if(t.call(e[n],e[n],n,e)===!1)return n}),Array.prototype.indexOf||(this.inArray=function(e,t){var n,r=0;if(t)for(n=t.length;n>r;r++)if(t[r]===e)return r;return-1}),Array.prototype.filter||(this.grep=function(e,t){for(var n=[],r=0,a=e.length;a>r;r++)t(e[r],r)&&n.push(e[r]);return n}),a=function(e,t,n){this.options=t,this.elem=e,this.prop=n},a.prototype={update:function(){var t,n=this.paths,r=this.elem,a=r.element;l[this.prop]?l[this.prop](this):n&&a?r.attr("d",e.step(n[0],n[1],this.now,this.toD)):r.attr?a&&r.attr(this.prop,this.now):(t={},t[this.prop]=this.now+this.unit,Highcharts.css(r,t)),this.options.step&&this.options.step.call(this.elem,this.now,this)},custom:function(e,t,n){var a,o=this,i=function(e){return o.step(e)};this.startTime=+new Date,this.start=e,this.end=t,this.unit=n,this.now=this.start,this.pos=this.state=0,i.elem=this.elem,i()&&1===s.push(i)&&(r=setInterval(function(){for(a=0;a=o.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),this.options.curAnim[this.prop]=!0,n=!0;for(r in o.curAnim)o.curAnim[r]!==!0&&(n=!1);n&&o.complete&&o.complete.call(i),t=!1}else{var s=a-this.startTime;this.state=s/o.duration,this.pos=o.easing(s,0,1,o.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update(),t=!0}return t}},this.animate=function(t,r,o){var i,s,l,u,c,d="";t.stopAnimation=!1,("object"!=typeof o||null===o)&&(u=arguments,o={duration:u[2],easing:u[3],complete:u[4]}),"number"!=typeof o.duration&&(o.duration=400),o.easing=Math[o.easing]||Math.easeInOutSine,o.curAnim=Highcharts.extend({},r);for(c in r)l=new a(t,o,c),s=null,"d"===c?(l.paths=e.init(t,t.d,r.d),l.toD=r.d,i=0,s=1):t.attr?i=t.attr(c):(i=parseFloat(n._getStyle(t,c))||0,"opacity"!==c&&(d="px")),s||(s=r[c]),l.custom(i,s,d)}},_getStyle:function(e,t){return window.getComputedStyle(e,void 0).getPropertyValue(t)},addAnimSetter:function(e,t){l[e]=t},getScript:function(e,t){var n=o.getElementsByTagName("head")[0],r=o.createElement("script");r.type="text/javascript",r.src=e,r.onload=t,n.appendChild(r)},inArray:function(e,t){return t.indexOf?t.indexOf(e):i.indexOf.call(t,e)},adapterRun:function(e,t){return parseInt(n._getStyle(e,t),10)},grep:function(e,t){return i.filter.call(e,t)},map:function(e,t){for(var n=[],r=0,a=e.length;a>r;r++)n[r]=t.call(e[r],e[r],r,e);return n},offset:function(e){var t=document.documentElement,n=e.getBoundingClientRect();return{top:n.top+(window.pageYOffset||t.scrollTop)-(t.clientTop||0),left:n.left+(window.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}},addEvent:function(t,n,r){e(t).bind(n,r)},removeEvent:function(t,n,r){e(t).unbind(n,r)},fireEvent:function(e,t,n,r){var a;o.createEvent&&(e.dispatchEvent||e.fireEvent)?(a=o.createEvent("Events"),a.initEvent(t,!0,!0),a.target=e,Highcharts.extend(a,n),e.dispatchEvent?e.dispatchEvent(a):e.fireEvent(t,a)):e.HCExtended===!0&&(n=n||{},e.trigger(t,n)),n&&n.defaultPrevented&&(r=null),r&&r(n)},washMouseEvent:function(e){return e},stop:function(e){e.stopAnimation=!0},each:function(e,t){return Array.prototype.forEach.call(e,t)}}}();e.exports=n},,function(t,n){t.exports=e},function(e,n){e.exports=t},,function(e,t,n){(function(t){t.HighchartsAdapter=n(2);var r=n(8),a=n(4),o=n(5).addons.update;e.exports=a.createClass({displayName:"Highcharts",renderChart:function(){if(!this.props.config)throw new Error("Config has to be specified, for the Highchart component");var e=this.props.config,t=this.refs.chart.getDOMNode();e.chart||(e=o(e,{chart:{$set:{}}})),e=o(e,{chart:{renderTo:{$set:t}}}),new r.Chart(e)},componentDidMount:function(){this.renderChart()},componentDidUpdate:function(){this.renderChart()},render:function(){return a.createElement("div",{className:"chart",ref:"chart"})}}),e.exports.Highcharts=r}).call(t,function(){return this}())},function(e,t){/** + * @license Highstock JS v2.1.6-modified () + * + * (c) 2009-2014 Torstein Honsi + * + * License: www.highcharts.com/license + */ +!function(){function e(){var e,t,n=arguments,r={},a=function(e,t){var n,r;"object"!=typeof e&&(e={});for(r in t)t.hasOwnProperty(r)&&(n=t[r],n&&"object"==typeof n&&"[object Array]"!==Object.prototype.toString.call(n)&&"renderTo"!==r&&"number"!=typeof n.nodeType?e[r]=a(e[r]||{},n):e[r]=t[r]);return e};for(n[0]===!0&&(r=n[1],n=Array.prototype.slice.call(n,2)),t=n.length,e=0;t>e;e++)r=a(r,n[e]);return r}function t(e,t){return parseInt(e,t||10)}function n(e){return"string"==typeof e}function r(e){return e&&"object"==typeof e}function a(e){return"[object Array]"===Object.prototype.toString.call(e)}function o(e){return"number"==typeof e}function i(e){return he.log(e)/he.LN10}function s(e){return he.pow(10,e)}function l(e,t){for(var n=e.length;n--;)if(e[n]===t){e.splice(n,1);break}}function u(e){return e!==B&&null!==e}function c(e,t,a){var o,i;if(n(t))u(a)?e.setAttribute(t,a):e&&e.getAttribute&&(i=e.getAttribute(t));else if(u(t)&&r(t))for(o in t)e.setAttribute(o,t[o]);return i}function d(e){return a(e)?e:[e]}function p(e,t){Pe&&!Me&&t&&t.opacity!==B&&(t.filter="alpha(opacity="+100*t.opacity+")"),it(e.style,t)}function f(e,t,n,r,a){var o=pe.createElement(e);return t&&it(o,t),a&&p(o,{padding:0,border:Je,margin:0}),n&&p(o,n),r&&r.appendChild(o),o}function h(e,t){var n=function(){return B};return n.prototype=new e,it(n.prototype,t),n}function m(e,t){return new Array((t||2)+1-String(e).length).join(0)+e}function g(e,t){return/%$/.test(e)?t*parseFloat(e)/100:parseFloat(e)}function y(e){return 6e4*($&&$(e)||J||0)}function b(e,t){var n,r=/f$/,a=/\.([0-9])/,o=U.lang;return r.test(e)?(n=e.match(a),n=n?n[1]:-1,null!==t&&(t=de.numberFormat(t,n,o.decimalPoint,e.indexOf(",")>-1?o.thousandsSep:""))):t=H(e,t),t}function v(e,t){for(var n,r,a,o,i,s,l,u="{",c=!1,d=[];-1!==(l=e.indexOf(u));){if(n=e.slice(0,l),c){for(r=n.split(":"),a=r.shift().split("."),i=a.length,s=t,o=0;i>o;o++)s=s[a[o]];r.length&&(s=b(r.join(":"),s)),d.push(s)}else d.push(n);e=e.slice(l+1),c=!c,u=c?"}":"{"}return d.push(e),d.join("")}function _(e){return he.pow(10,ge(he.log(e)/he.LN10))}function w(e,t,n,r,a){var o,i,s=e;for(n=st(n,1),o=e/n,t||(t=[1,2,2.5,5,10],r===!1&&(1===n?t=[1,2,5,10]:.1>=n&&(t=[1/n]))),i=0;i=e||!a&&o<=(t[i]+(t[i+1]||t[i]))/2));i++);return s*=n}function k(e,t){var n,r,a=e.length;for(r=0;a>r;r++)e[r].ss_i=r;for(e.sort(function(e,r){return n=t(e,r),0===n?e.ss_i-r.ss_i:n}),r=0;a>r;r++)delete e[r].ss_i}function E(e){for(var t=e.length,n=e[0];t--;)e[t]n&&(n=e[t]);return n}function O(e,t){var n;for(n in e)e[n]&&e[n]!==t&&e[n].destroy&&e[n].destroy(),delete e[n]}function S(e){F||(F=f(He)),e&&F.appendChild(e),F.innerHTML=""}function P(e,t){var n="Highcharts error #"+e+": www.highcharts.com/errors/"+e;if(t)throw n;fe.console&&console.log(n)}function A(e){return parseFloat(e.toPrecision(14))}function j(e,t){W=st(e,t.animation)}function C(){var e=U.global,t=e.useUTC,n=t?"getUTC":"get",r=t?"setUTC":"set";Y=e.Date||window.Date,J=t&&e.timezoneOffset,$=t&&e.getTimezoneOffset,X=function(e,n,r,a,o,i){var s;return t?(s=Y.UTC.apply(0,arguments),s+=y(s)):s=new Y(e,n,st(r,1),st(a,0),st(o,0),st(i,0)).getTime(),s},Z=n+"Minutes",Q=n+"Hours",ee=n+"Day",te=n+"Date",ne=n+"Month",re=n+"FullYear",ae=r+"Milliseconds",oe=r+"Seconds",ie=r+"Minutes",se=r+"Hours",le=r+"Date",ue=r+"Month",ce=r+"FullYear"}function T(t){return U=e(!0,U,t),C(),U}function D(){return U}function M(){}function N(e,t,n,r){this.axis=e,this.pos=t,this.type=n||"",this.isNew=!0,n||r||this.addLabel()}function z(e,t,n,r,a){var o=e.chart.inverted;this.axis=e,this.isNegative=n,this.options=t,this.x=r,this.total=null,this.points={},this.stack=a,this.alignOptions={align:t.align||(o?n?"left":"right":"center"),verticalAlign:t.verticalAlign||(o?"middle":n?"bottom":"top"),y:st(t.y,o?4:n?14:-6),x:st(t.x,o?n?-6:6:0)},this.textAlign=t.textAlign||(o?n?"right":"left":"center")}function I(e){var t=e.options,n=t.navigator,r=n.enabled,a=t.scrollbar,o=a.enabled,i=r?n.height:0,s=o?a.height:0;this.handles=[],this.scrollbarButtons=[],this.elementsToDestroy=[],this.chart=e,this.setBaseSeries(),this.height=i,this.scrollbarHeight=s,this.scrollbarEnabled=o,this.navigatorEnabled=r,this.navigatorOptions=n,this.scrollbarOptions=a,this.outlineHeight=i+s,this.init()}function R(e){this.init(e)}var B,L,q,F,U,H,W,V,K,G,Y,X,J,$,Z,Q,ee,te,ne,re,ae,oe,ie,se,le,ue,ce,de,pe=document,fe=window,he=Math,me=he.round,ge=he.floor,ye=he.ceil,be=he.max,ve=he.min,_e=he.abs,we=he.cos,ke=he.sin,Ee=he.PI,xe=2*Ee/360,Oe=navigator.userAgent,Se=fe.opera,Pe=/(msie|trident)/i.test(Oe)&&!Se,Ae=8===pe.documentMode,je=/AppleWebKit/.test(Oe),Ce=/Firefox/.test(Oe),Te=/(Mobile|Android|Windows Phone)/.test(Oe),De="http://www.w3.org/2000/svg",Me=!!pe.createElementNS&&!!pe.createElementNS(De,"svg").createSVGRect,Ne=Ce&&parseInt(Oe.split("Firefox/")[1],10)<4,ze=!Me&&!Pe&&!!pe.createElement("canvas").getContext,Ie={},Re=0,Be=function(){return B},Le=[],qe=0,Fe="Highstock",Ue="2.1.6-modified",He="div",We="absolute",Ve="relative",Ke="hidden",Ge="highcharts-",Ye="visible",Xe="px",Je="none",$e="M",Ze="L",Qe=/^[0-9]+$/,et="",tt="hover",nt="select",rt=["plotTop","marginRight","marginBottom","plotLeft"],at="stroke-width",ot={};de=fe.Highcharts=fe.Highcharts?P(16,!0):{},de.seriesTypes=ot;var it=de.extend=function(e,t){var n;e||(e={});for(n in t)e[n]=t[n];return e},st=de.pick=function(){var e,t,n=arguments,r=n.length;for(e=0;r>e;e++)if(t=n[e],t!==B&&null!==t)return t},lt=de.wrap=function(e,t,n){var r=e[t];e[t]=function(){var e=Array.prototype.slice.call(arguments);return e.unshift(r),n.apply(this,e)}};H=function(e,t,n){if(!u(t)||isNaN(t))return"Invalid date";e=st(e,"%Y-%m-%d %H:%M:%S");var r,a=new Y(t-y(t)),o=a[Q](),i=a[ee](),s=a[te](),l=a[ne](),c=a[re](),d=U.lang,p=d.weekdays,f=it({a:p[i].substr(0,3),A:p[i],d:m(s),e:s,w:i,b:d.shortMonths[l],B:d.months[l],m:m(l+1),y:c.toString().substr(2,2),Y:c,H:m(o),I:m(o%12||12),l:o%12||12,M:m(a[Z]()),p:12>o?"AM":"PM",P:12>o?"am":"pm",S:m(a.getSeconds()),L:m(me(t%1e3),3)},de.dateFormats);for(r in f)for(;-1!==e.indexOf("%"+r);)e=e.replace("%"+r,"function"==typeof f[r]?f[r](t):f[r]);return n?e.substr(0,1).toUpperCase()+e.substr(1):e},K={millisecond:1,second:1e3,minute:6e4,hour:36e5,day:864e5,week:6048e5,month:24192e5,year:314496e5},de.numberFormat=function(e,n,r,a){var o=U.lang,i=+e||0,s=-1===n?ve((i.toString().split(".")[1]||"").length,20):isNaN(n=_e(n))?2:n,l=void 0===r?o.decimalPoint:r,u=void 0===a?o.thousandsSep:a,c=0>i?"-":"",d=String(t(i=_e(i).toFixed(s))),p=d.length>3?d.length%3:0;return c+(p?d.substr(0,p)+u:"")+d.substr(p).replace(/(\d{3})(?=\d)/g,"$1"+u)+(s?l+_e(i-d).toFixed(s).slice(2):"")},V={init:function(e,t,n){t=t||"";var r,a,o,i,s,l=e.shift,u=t.indexOf("C")>-1,c=u?7:3,d=t.split(" "),p=[].concat(n),f=function(e){for(o=e.length;o--;)e[o]===$e&&e.splice(o+1,0,e[o+1],e[o+2],e[o+1],e[o+2])};if(u&&(f(d),f(p)),e.isArea&&(i=d.splice(d.length-6,6),s=p.splice(p.length-6,6)),l<=p.length/c&&d.length===p.length)for(;l--;)p=[].concat(p).splice(0,c).concat(p);if(e.shift=0,d.length)for(r=p.length;d.lengthn)for(;i--;)a=parseFloat(e[i]),o[i]=isNaN(a)?e[i]:n*parseFloat(t[i]-a)+a;else o=t;return o}},function(e){fe.HighchartsAdapter=fe.HighchartsAdapter||e&&{init:function(t){var r=e.fx;e.extend(e.easing,{easeOutQuad:function(e,t,n,r,a){return-r*(t/=a)*(t-2)+n}}),e.each(["cur","_default","width","height","opacity"],function(t,n){var a,o=r.step;"cur"===n?o=r.prototype:"_default"===n&&e.Tween&&(o=e.Tween.propHooks[n],n="set"),a=o[n],a&&(o[n]=function(e){var r;return e=t?e:this,"align"!==e.prop?(r=e.elem,r.attr?r.attr(e.prop,"cur"===n?B:e.now):a.apply(this,arguments)):void 0})}),lt(e.cssHooks.opacity,"get",function(e,t,n){return t.attr?t.opacity||0:e.call(this,t,n)}),this.addAnimSetter("d",function(e){var n,r=e.elem;e.started||(n=t.init(r,r.d,r.toD),e.start=n[0],e.end=n[1],e.started=!0),r.attr("d",t.step(e.start,e.end,e.pos,r.toD))}),this.each=Array.prototype.forEach?function(e,t){return Array.prototype.forEach.call(e,t)}:function(e,t){var n,r=e.length;for(n=0;r>n;n++)if(t.call(e[n],e[n],n,e)===!1)return n},e.fn.highcharts=function(){var e,t,r,a="Chart",o=arguments;return this[0]&&(n(o[0])&&(a=o[0],o=Array.prototype.slice.call(o,1)),e=o[0],e!==B&&(e.chart=e.chart||{},e.chart.renderTo=this[0],r=new de[a](e,o[1]),t=this),e===B&&(t=Le[c(this[0],"data-highcharts-chart")])),t}},addAnimSetter:function(t,n){e.Tween?e.Tween.propHooks[t]={set:n}:e.fx.step[t]=n},getScript:e.getScript,inArray:e.inArray,adapterRun:function(t,n){return e(t)[n]()},grep:e.grep,map:function(e,t){for(var n=[],r=0,a=e.length;a>r;r++)n[r]=t.call(e[r],e[r],r,e);return n},offset:function(t){return e(t).offset()},addEvent:function(t,n,r){e(t).bind(n,r)},removeEvent:function(t,n,r){var a=pe.removeEventListener?"removeEventListener":"detachEvent";pe[a]&&t&&!t[a]&&(t[a]=function(){}),e(t).unbind(n,r)},fireEvent:function(t,n,r,a){var o,i=e.Event(n),s="detached"+n;!Pe&&r&&(delete r.layerX,delete r.layerY,delete r.returnValue),it(i,r),t[n]&&(t[s]=t[n],t[n]=null),e.each(["preventDefault","stopPropagation"],function(e,t){var n=i[t];i[t]=function(){try{n.call(i)}catch(e){"preventDefault"===t&&(o=!0)}}}),e(t).trigger(i),t[s]&&(t[n]=t[s],t[s]=null),!a||i.isDefaultPrevented()||o||a(i)},washMouseEvent:function(e){var t=e.originalEvent||e;return t.pageX===B&&(t.pageX=e.pageX,t.pageY=e.pageY),t},animate:function(t,n,r){var a=e(t);t.style||(t.style={}),n.d&&(t.toD=n.d,n.d=1),a.stop(),n.opacity!==B&&t.attr&&(n.opacity+="px"),t.hasAnim=1,a.animate(n,r)},stop:function(t){t.hasAnim&&e(t).stop()}}}(fe.jQuery);var ut=fe.HighchartsAdapter,ct=ut||{};ut&&ut.init.call(ut,V);var dt=ct.adapterRun,pt=ct.getScript,ft=ct.inArray,ht=de.each=ct.each,mt=ct.grep,gt=ct.offset,yt=ct.map,bt=ct.addEvent,vt=ct.removeEvent,_t=ct.fireEvent,wt=ct.washMouseEvent,kt=ct.animate,Et=ct.stop;U={colors:["#7cb5ec","#434348","#90ed7d","#f7a35c","#8085e9","#f15c80","#e4d354","#2b908f","#f45b5b","#91e8e1"],symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],decimalPoint:".",numericSymbols:["k","M","G","T","P","E"],resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:" "},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/stock/2.1.6-modified/modules/canvas-tools.js",VMLRadialGradientURL:"http://code.highcharts.com/stock/2.1.6-modified/gfx/vml-radial-gradient.png"},chart:{borderColor:"#4572A7",borderRadius:0,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacing:[10,10,15,10],backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0",resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",margin:15,style:{color:"#333333",fontSize:"18px"}},subtitle:{text:"",align:"center",style:{color:"#555555"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1e3},events:{},lineWidth:2,marker:{lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{enabled:!0,lineWidthPlus:1,radiusPlus:2},select:{fillColor:"#FFFFFF",lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:{align:"center",formatter:function(){return null===this.y?"":de.numberFormat(this.y,-1)},style:{color:"contrast",fontSize:"11px",fontWeight:"bold",textShadow:"0 0 6px contrast, 0 0 3px contrast"},verticalAlign:"bottom",x:0,y:0,padding:5},cropThreshold:300,pointRange:0,states:{hover:{lineWidthPlus:1,marker:{},halo:{size:10,opacity:.25}},select:{marker:{}}},stickyTracking:!0,turboThreshold:1e3}},labels:{style:{position:We,color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderColor:"#909090",borderRadius:0,navigation:{activeColor:"#274b6d",inactiveColor:"#CCC"},shadow:!1,itemStyle:{color:"#333333",fontSize:"12px",fontWeight:"bold"},itemHoverStyle:{color:"#000"},itemHiddenStyle:{color:"#CCC"},itemCheckboxStyle:{position:We,width:"13px",height:"13px"},symbolPadding:5,verticalAlign:"bottom",x:0,y:0,title:{style:{fontWeight:"bold"}}},loading:{labelStyle:{fontWeight:"bold",position:Ve,top:"45%"},style:{position:We,backgroundColor:"white",opacity:.5,textAlign:"center"}},tooltip:{enabled:!0,animation:Me,backgroundColor:"rgba(249, 249, 249, .85)",borderWidth:1,borderRadius:3,dateTimeLabelFormats:{millisecond:"%A, %b %e, %H:%M:%S.%L",second:"%A, %b %e, %H:%M:%S",minute:"%A, %b %e, %H:%M",hour:"%A, %b %e, %H:%M",day:"%A, %b %e, %Y",week:"Week from %A, %b %e, %Y",month:"%B %Y",year:"%Y"},footerFormat:"",headerFormat:'{point.key}
',pointFormat:' {series.name}: {point.y}
',shadow:!0,snap:Te?25:10,style:{color:"#333333",cursor:"default",fontSize:"12px",padding:"8px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"9px"}}};var xt=U.plotOptions,Ot=xt.line;C();var St=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/,Pt=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,At=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/,jt=function(n){function r(e){e&&e.stops?u=yt(e.stops,function(e){return jt(e[1])}):(l=St.exec(e),l?c=[t(l[1]),t(l[2]),t(l[3]),parseFloat(l[4],10)]:(l=Pt.exec(e),l?c=[t(l[1],16),t(l[2],16),t(l[3],16),1]:(l=At.exec(e),l&&(c=[t(l[1]),t(l[2]),t(l[3]),1]))))}function a(t){var r;return u?(r=e(n),r.stops=[].concat(r.stops),ht(u,function(e,n){r.stops[n]=[r.stops[n][0],e.get(t)]})):r=c&&!isNaN(c[0])?"rgb"===t?"rgb("+c[0]+","+c[1]+","+c[2]+")":"a"===t?c[3]:"rgba("+c.join(",")+")":n,r}function i(e){if(u)ht(u,function(t){t.brighten(e)});else if(o(e)&&0!==e){var n;for(n=0;3>n;n++)c[n]+=t(255*e),c[n]<0&&(c[n]=0),c[n]>255&&(c[n]=255)}return this}function s(e){return c[3]=e,this}var l,u,c=[];return r(n),{get:a,brighten:i,rgba:c,setOpacity:s,raw:n}};M.prototype={opacity:1,textProps:["fontSize","fontWeight","fontFamily","fontStyle","color","lineHeight","width","textDecoration","textShadow"],init:function(e,t){var n=this;n.element="span"===t?f(t):pe.createElementNS(De,t),n.renderer=e},animate:function(t,n,r){var a=st(n,W,!0);return Et(this),a?(a=e(a,{}),r&&(a.complete=r),kt(this,t,a)):(this.attr(t),r&&r()),this},colorGradient:function(t,n,r){var o,i,s,l,c,d,p,f,h,m,g,y=this.renderer,b=[];if(t.linearGradient?i="linearGradient":t.radialGradient&&(i="radialGradient"),i){s=t[i],l=y.gradients,d=t.stops,h=r.radialReference,a(s)&&(t[i]=s={x1:s[0],y1:s[1],x2:s[2],y2:s[3],gradientUnits:"userSpaceOnUse"}),"radialGradient"===i&&h&&!u(s.gradientUnits)&&(s=e(s,{cx:h[0]-h[2]/2+s.cx*h[2],cy:h[1]-h[2]/2+s.cy*h[2],r:s.r*h[2],gradientUnits:"userSpaceOnUse"}));for(m in s)"id"!==m&&b.push(m,s[m]);for(m in d)b.push(d[m]);b=b.join(","),l[b]?g=l[b].attr("id"):(s.id=g=Ge+Re++,l[b]=c=y.createElement(i).attr(s).add(y.defs),c.stops=[],ht(d,function(e){var t;0===e[1].indexOf("rgba")?(o=jt(e[1]),p=o.get("rgb"),f=o.get("a")):(p=e[1],f=1),t=y.createElement("stop").attr({offset:e[0],"stop-color":p,"stop-opacity":f}).add(c),c.stops.push(t)})),r.setAttribute(n,"url("+y.url+"#"+g+")")}},applyTextShadow:function(e){var n,r=this.element,a=-1!==e.indexOf("contrast"),o={},i=this.renderer.forExport||r.style.textShadow!==B&&!Pe;a&&(o.textShadow=e=e.replace(/contrast/g,this.renderer.getContrast(r.style.fill))),je&&(o.textRendering="geometricPrecision"),i?p(r,o):(this.fakeTS=!0,this.ySetter=this.xSetter,n=[].slice.call(r.getElementsByTagName("tspan")),ht(e.split(/\s?,\s?/g),function(e){var a,o,i=r.firstChild;e=e.split(" "),a=e[e.length-1],o=e[e.length-2],o&&ht(n,function(e,n){var s;0===n&&(e.setAttribute("x",r.getAttribute("x")),n=r.getAttribute("y"),e.setAttribute("y",n||0),null===n&&r.setAttribute("y",0)),s=e.cloneNode(1),c(s,{"class":Ge+"text-shadow",fill:a,stroke:a,"stroke-opacity":1/be(t(o),3),"stroke-width":o,"stroke-linejoin":"round"}),r.insertBefore(s,i)})}))},attr:function(e,t){var n,r,a,o,i=this.element,s=this;if("string"==typeof e&&t!==B&&(n=e,e={},e[n]=t),"string"==typeof e)s=(this[e+"Getter"]||this._defaultGetter).call(this,e,i);else{for(n in e)r=e[n],o=!1,this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(n)&&(a||(this.symbolAttr(e),a=!0),o=!0),!this.rotation||"x"!==n&&"y"!==n||(this.doTransform=!0),o||(this[n+"Setter"]||this._defaultSetter).call(this,r,n,i),this.shadows&&/^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(n)&&this.updateShadows(n,r);this.doTransform&&(this.updateTransform(),this.doTransform=!1)}return s},updateShadows:function(e,t){for(var n=this.shadows,r=n.length;r--;)n[r].setAttribute(e,"height"===e?be(t-(n[r].cutHeight||0),0):"d"===e?this.d:t)},addClass:function(e){var t=this.element,n=c(t,"class")||"";return-1===n.indexOf(e)&&c(t,"class",n+" "+e),this},symbolAttr:function(e){var t=this;ht(["x","y","r","start","end","width","height","innerR","anchorX","anchorY"],function(n){t[n]=st(e[n],t[n])}),t.attr({d:t.renderer.symbols[t.symbolName](t.x,t.y,t.width,t.height,t)})},clip:function(e){return this.attr("clip-path",e?"url("+this.renderer.url+"#"+e.id+")":Je)},crisp:function(e){var t,n,r=this,a={},o=e.strokeWidth||r.strokeWidth||0;n=me(o)%2/2,e.x=ge(e.x||r.x||0)+n,e.y=ge(e.y||r.y||0)+n,e.width=ge((e.width||r.width||0)-2*n),e.height=ge((e.height||r.height||0)-2*n),e.strokeWidth=o;for(t in e)r[t]!==e[t]&&(r[t]=a[t]=e[t]);return a},css:function(e){var n,r,a,o=this,i=o.styles,s={},l=o.element,u="",d=!i;if(e&&e.color&&(e.fill=e.color),i)for(r in e)e[r]!==i[r]&&(s[r]=e[r],d=!0);if(d){if(n=o.textWidth=e&&e.width&&"text"===l.nodeName.toLowerCase()&&t(e.width)||o.textWidth,i&&(e=it(i,s)),o.styles=e,n&&(ze||!Me&&o.renderer.forExport)&&delete e.width,Pe&&!Me)p(o.element,e);else{a=function(e,t){return"-"+t.toLowerCase()};for(r in e)u+=r.replace(/([A-Z])/g,a)+":"+e[r]+";";c(l,"style",u)}n&&o.added&&o.renderer.buildText(o)}return o},on:function(e,t){var n=this,r=n.element;return q&&"click"===e?(r.ontouchstart=function(e){n.touchEventFired=Y.now(),e.preventDefault(),t.call(r,e)},r.onclick=function(e){(-1===Oe.indexOf("Android")||Y.now()-(n.touchEventFired||0)>1100)&&t.call(r,e)}):r["on"+e]=t,this},setRadialReference:function(e){return this.element.radialReference=e,this},translate:function(e,t){return this.attr({translateX:e,translateY:t})},invert:function(){var e=this;return e.inverted=!0,e.updateTransform(),e},updateTransform:function(){var e,t=this,n=t.translateX||0,r=t.translateY||0,a=t.scaleX,o=t.scaleY,i=t.inverted,s=t.rotation,l=t.element;i&&(n+=t.attr("width"),r+=t.attr("height")),e=["translate("+n+","+r+")"],i?e.push("rotate(90) scale(-1,1)"):s&&e.push("rotate("+s+" "+(l.getAttribute("x")||0)+" "+(l.getAttribute("y")||0)+")"),(u(a)||u(o))&&e.push("scale("+st(a,1)+" "+st(o,1)+")"),e.length&&l.setAttribute("transform",e.join(" "))},toFront:function(){var e=this.element;return e.parentNode.appendChild(e),this},align:function(e,t,r){var a,o,i,s,u,c={},d=this.renderer,p=d.alignedObjects;return e?(this.alignOptions=e,this.alignByTranslate=t,(!r||n(r))&&(this.alignTo=u=r||"renderer",l(p,this),p.push(this),r=null)):(e=this.alignOptions,t=this.alignByTranslate,u=this.alignTo),r=st(r,d[u],d),a=e.align,o=e.verticalAlign,i=(r.x||0)+(e.x||0),s=(r.y||0)+(e.y||0),("right"===a||"center"===a)&&(i+=(r.width-(e.width||0))/{right:1,center:2}[a]),c[t?"translateX":"x"]=me(i),("bottom"===o||"middle"===o)&&(s+=(r.height-(e.height||0))/({bottom:1,middle:2}[o]||1)),c[t?"translateY":"y"]=me(s),this[this.placed?"animate":"attr"](c),this.placed=!0,this.alignAttr=c,this},getBBox:function(e){var t,n,r,a,o,i,s=this,l=s.renderer,u=s.rotation,c=s.element,d=s.styles,p=u*xe,f=s.textStr,h=c.style;if(f!==B&&(i=["",u||0,d&&d.fontSize,c.style.width].join(","),i=""===f||Qe.test(f)?"num:"+f.toString().length+i:f+i),i&&!e&&(t=l.cache[i]),!t){if(c.namespaceURI===De||l.forExport){try{o=this.fakeTS&&function(e){ht(c.querySelectorAll("."+Ge+"text-shadow"),function(t){t.style.display=e})},Ce&&h.textShadow?(a=h.textShadow,h.textShadow=""):o&&o(Je),t=c.getBBox?it({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight},a?h.textShadow=a:o&&o("")}catch(m){}(!t||t.width<0)&&(t={width:0,height:0})}else t=s.htmlGetBBox();l.isSVG&&(n=t.width,r=t.height,Pe&&d&&"11px"===d.fontSize&&"16.9"===r.toPrecision(3)&&(t.height=r=14),u&&(t.width=_e(r*ke(p))+_e(n*we(p)),t.height=_e(r*we(p))+_e(n*ke(p)))),l.cache[i]=t}return t},show:function(e){return e&&this.element.namespaceURI===De?this.element.removeAttribute("visibility"):this.attr({visibility:e?"inherit":Ye}),this},hide:function(){return this.attr({visibility:Ke})},fadeOut:function(e){var t=this;t.animate({opacity:0},{duration:e||150,complete:function(){t.attr({y:-9999})}})},add:function(e){var t,n=this.renderer,r=this.element;return e&&(this.parentGroup=e),this.parentInverted=e&&e.inverted,void 0!==this.textStr&&n.buildText(this),this.added=!0,(!e||e.handleZ||this.zIndex)&&(t=this.zIndexSetter()),t||(e?e.element:n.box).appendChild(r),this.onAdd&&this.onAdd(),this},safeRemoveChild:function(e){var t=e.parentNode;t&&t.removeChild(e)},destroy:function(){var e,t,n,r=this,a=r.element||{},o=r.shadows,i=r.renderer.isSVG&&"SPAN"===a.nodeName&&r.parentGroup;if(a.onclick=a.onmouseout=a.onmouseover=a.onmousemove=a.point=null,Et(r),r.clipPath&&(r.clipPath=r.clipPath.destroy()),r.stops){for(n=0;n=r;r++)a=d.cloneNode(0),o=2*i+1-2*r,c(a,{isShadow:"true",stroke:e.color||"black","stroke-opacity":s*r,"stroke-width":o,transform:"translate"+l,fill:Je}),n&&(c(a,"height",be(c(a,"height")-o,0)),a.cutHeight=o),t?t.element.appendChild(a):d.parentNode.insertBefore(a,d),u.push(a);this.shadows=u}return this},xGetter:function(e){return"circle"===this.element.nodeName&&(e={x:"cx",y:"cy"}[e]||e),this._defaultGetter(e)},_defaultGetter:function(e){var t=st(this[e],this.element?this.element.getAttribute(e):null,0);return/^[\-0-9\.]+$/.test(t)&&(t=parseFloat(t)),t},dSetter:function(e,t,n){e&&e.join&&(e=e.join(" ")),/(NaN| {2}|^$)/.test(e)&&(e="M 0 0"),n.setAttribute(t,e),this[t]=e},dashstyleSetter:function(e){var n;if(e=e&&e.toLowerCase()){for(e=e.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot","3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(","),n=e.length;n--;)e[n]=t(e[n])*this["stroke-width"];e=e.join(",").replace("NaN","none"),this.element.setAttribute("stroke-dasharray",e)}},alignSetter:function(e){this.element.setAttribute("text-anchor",{left:"start",center:"middle",right:"end"}[e])},opacitySetter:function(e,t,n){this[t]=e,n.setAttribute(t,e)},titleSetter:function(e){var t=this.element.getElementsByTagName("title")[0];t||(t=pe.createElementNS(De,"title"),this.element.appendChild(t)),t.appendChild(pe.createTextNode(String(st(e),"").replace(/<[^>]*>/g,"")))},textSetter:function(e){e!==this.textStr&&(delete this.bBox,this.textStr=e,this.added&&this.renderer.buildText(this))},fillSetter:function(e,t,n){"string"==typeof e?n.setAttribute(t,e):e&&this.colorGradient(e,t,n)},zIndexSetter:function(e,n){var r,a,o,i,s,l=this.renderer,d=this.parentGroup,p=d||l,f=p.element||l.box,h=this.element,m=this.added;if(u(e)&&(h.setAttribute(n,e),e=+e,this[n]===e&&(m=!1),this[n]=e),m){for(e=this.zIndex,e&&d&&(d.handleZ=!0),r=f.childNodes,s=0;se||!u(e)&&u(o))&&(f.insertBefore(h,a),i=!0);i||f.appendChild(h)}return i},_defaultSetter:function(e,t,n){n.setAttribute(t,e)}},M.prototype.yGetter=M.prototype.xGetter,M.prototype.translateXSetter=M.prototype.translateYSetter=M.prototype.rotationSetter=M.prototype.verticalAlignSetter=M.prototype.scaleXSetter=M.prototype.scaleYSetter=function(e,t){this[t]=e,this.doTransform=!0},M.prototype["stroke-widthSetter"]=M.prototype.strokeSetter=function(e,t,n){this[t]=e,this.stroke&&this["stroke-width"]?(this.strokeWidth=this["stroke-width"],M.prototype.fillSetter.call(this,this.stroke,"stroke",n),n.setAttribute("stroke-width",this["stroke-width"]),this.hasStroke=!0):"stroke-width"===t&&0===e&&this.hasStroke&&(n.removeAttribute("stroke"),this.hasStroke=!1)};var Ct=function(){this.init.apply(this,arguments)};Ct.prototype={Element:M,init:function(e,t,n,r,a){var o,i,s,l=this,u=location;o=l.createElement("svg").attr({version:"1.1"}).css(this.getStyle(r)),i=o.element,e.appendChild(i),-1===e.innerHTML.indexOf("xmlns")&&c(i,"xmlns",De),l.isSVG=!0,l.box=i,l.boxWrapper=o,l.alignedObjects=[],l.url=(Ce||je)&&pe.getElementsByTagName("base").length?u.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"",s=this.createElement("desc").add(),s.element.appendChild(pe.createTextNode("Created with "+Fe+" "+Ue)),l.defs=this.createElement("defs").add(),l.forExport=a,l.gradients={},l.cache={},l.setSize(t,n,!1);var d,f;Ce&&e.getBoundingClientRect&&(l.subPixelFix=d=function(){p(e,{left:0,top:0}),f=e.getBoundingClientRect(),p(e,{left:ye(f.left)-f.left+Xe,top:ye(f.top)-f.top+Xe})},d(),bt(fe,"resize",d))},getStyle:function(e){return this.style=it({fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif',fontSize:"12px"},e)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var e=this,t=e.defs;return e.box=null,e.boxWrapper=e.boxWrapper.destroy(),O(e.gradients||{}),e.gradients=null,t&&(e.defs=t.destroy()),e.subPixelFix&&vt(fe,"resize",e.subPixelFix),e.alignedObjects=null,null},createElement:function(e){var t=new this.Element;return t.init(this,e),t},draw:function(){},buildText:function(e){for(var n,r,a,o=e.element,i=this,s=i.forExport,l=st(e.textStr,"").toString(),u=-1!==l.indexOf("<"),d=o.childNodes,f=c(o,"x"),h=e.styles,m=e.textWidth,g=h&&h.lineHeight,y=h&&h.textShadow,b=h&&"ellipsis"===h.textOverflow,v=d.length,_=m&&!e.added&&this.box,w=function(e){return g?t(g):i.fontMetrics(/(px|em)$/.test(e&&e.style.fontSize)?e.style.fontSize:h&&h.fontSize||i.style.fontSize||12,e).h},k=function(e){return e.replace(/</g,"<").replace(/>/g,">")};v--;)o.removeChild(d[v]);return u||y||b||-1!==l.indexOf(" ")?(r=/<.*style="([^"]+)".*>/,a=/<.*href="(http[^"]+)".*>/,_&&_.appendChild(o),n=u?l.replace(/<(b|strong)>/g,'').replace(/<(i|em)>/g,'').replace(/
/g,"").split(//g):[l],""===n[n.length-1]&&n.pop(),ht(n,function(t,n){var l,u=0;t=t.replace(//g,"|||"),l=t.split("|||"),ht(l,function(t){if(""!==t||1===l.length){var d,g={},y=pe.createElementNS(De,"tspan");if(r.test(t)&&(d=t.match(r)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),c(y,"style",d)),a.test(t)&&!s&&(c(y,"onclick",'location.href="'+t.match(a)[1]+'"'),p(y,{cursor:"pointer"})),t=k(t.replace(/<(.|\n)*?>/g,"")||" ")," "!==t){if(y.appendChild(pe.createTextNode(t)),u?g.dx=0:n&&null!==f&&(g.x=f),c(y,g),o.appendChild(y),!u&&n&&(!Me&&s&&p(y,{display:"block"}),c(y,"dy",w(y))),m){for(var v,_,E,x,O=t.replace(/([^\^])-/g,"$1- ").split(" "),S=l.length>1||n||O.length>1&&"nowrap"!==h.whiteSpace,P=[],A=w(y),j=1,C=e.rotation,T=t,D=T.length;(S||b)&&(O.length||P.length);)e.rotation=0,x=e.getBBox(!0),E=x.width,!Me&&i.forExport&&(E=i.measureSpanWidth(y.firstChild.data,e.styles)),v=E>m,void 0===_&&(_=v),b&&_?(D/=2,""===T||!v&&.5>D?O=[]:(v&&(_=!0),T=t.substring(0,T.length+(v?-1:1)*ye(D)),O=[T+(m>3?"…":"")],y.removeChild(y.firstChild))):v&&1!==O.length?(y.removeChild(y.firstChild),P.unshift(O.pop())):(O=P,P=[],O.length&&(j++,y=pe.createElementNS(De,"tspan"),c(y,{dy:A,x:f}),d&&c(y,"style",d),o.appendChild(y)),E>m&&(m=E)),O.length&&y.appendChild(pe.createTextNode(O.join(" ").replace(/- /g,"-")));_&&e.attr("title",e.textStr),e.rotation=C}u++}}})}),_&&_.removeChild(o),y&&e.applyTextShadow&&e.applyTextShadow(y),void 0):void o.appendChild(pe.createTextNode(k(l)))},getContrast:function(e){return e=jt(e).rgba,e[0]+e[1]+e[2]>384?"#000000":"#FFFFFF"},button:function(t,n,r,a,o,i,s,l,u){var c,d,p,f,h,m,g=this.label(t,n,r,u,null,null,null,null,"button"),y=0,b={x1:0,y1:0,x2:0,y2:1};return o=e({"stroke-width":1,stroke:"#CCCCCC",fill:{linearGradient:b,stops:[[0,"#FEFEFE"],[1,"#F6F6F6"]]},r:2,padding:5,style:{color:"black"}},o),p=o.style,delete o.style,i=e(o,{stroke:"#68A",fill:{linearGradient:b,stops:[[0,"#FFF"],[1,"#ACF"]]}},i),f=i.style,delete i.style,s=e(o,{stroke:"#68A",fill:{linearGradient:b,stops:[[0,"#9BD"],[1,"#CDF"]]}},s),h=s.style,delete s.style,l=e(o,{style:{color:"#CCC"}},l),m=l.style,delete l.style,bt(g.element,Pe?"mouseover":"mouseenter",function(){3!==y&&g.attr(i).css(f)}),bt(g.element,Pe?"mouseout":"mouseleave",function(){3!==y&&(c=[o,i,s][y],d=[p,f,h][y],g.attr(c).css(d))}),g.setState=function(e){g.state=y=e,e?2===e?g.attr(s).css(h):3===e&&g.attr(l).css(m):g.attr(o).css(p)},g.on("click",function(){3!==y&&a.call(g)}).attr(o).css(it({cursor:"default"},p))},crispLine:function(e,t){return e[1]===e[4]&&(e[1]=e[4]=me(e[1])-t%2/2),e[2]===e[5]&&(e[2]=e[5]=me(e[2])+t%2/2),e},path:function(e){var t={fill:Je};return a(e)?t.d=e:r(e)&&it(t,e),this.createElement("path").attr(t)},circle:function(e,t,n){var a=r(e)?e:{x:e,y:t,r:n},o=this.createElement("circle");return o.xSetter=function(e){this.element.setAttribute("cx",e)},o.ySetter=function(e){this.element.setAttribute("cy",e)},o.attr(a)},arc:function(e,t,n,a,o,i){var s;return r(e)&&(t=e.y,n=e.r,a=e.innerR,o=e.start,i=e.end,e=e.x),s=this.symbol("arc",e||0,t||0,n||0,n||0,{innerR:a||0,start:o||0,end:i||0}),s.r=n,s},rect:function(e,t,n,a,o,i){o=r(e)?e.r:o;var s=this.createElement("rect"),l=r(e)?e:e===B?{}:{x:e,y:t,width:be(n,0),height:be(a,0)};return i!==B&&(l.strokeWidth=i,l=s.crisp(l)),o&&(l.r=o),s.rSetter=function(e){c(this.element,{rx:e,ry:e})},s.attr(l)},setSize:function(e,t,n){var r=this,a=r.alignedObjects,o=a.length;for(r.width=e,r.height=t,r.boxWrapper[st(n,!0)?"animate":"attr"]({width:e,height:t});o--;)a[o].align()},g:function(e){var t=this.createElement("g");return u(e)?t.attr({"class":Ge+e}):t},image:function(e,t,n,r,a){var o,i={preserveAspectRatio:Je};return arguments.length>1&&it(i,{x:t,y:n,width:r,height:a}),o=this.createElement("image").attr(i),o.element.setAttributeNS?o.element.setAttributeNS("http://www.w3.org/1999/xlink","href",e):o.element.setAttribute("hc-svg-href",e),o},symbol:function(e,t,n,r,a,o){var i,s,l,u,c,d=this.symbols[e],p=d&&d(me(t),me(n),r,a,o),h=/^url\((.*?)\)$/;return p?(i=this.path(p),it(i,{symbolName:e,x:t,y:n,width:r,height:a}),o&&it(i,o)):h.test(e)&&(c=function(e,t){e.element&&(e.attr({width:t[0],height:t[1]}),e.alignByTranslate||e.translate(me((r-t[0])/2),me((a-t[1])/2)))},l=e.match(h)[1],u=Ie[l]||o&&o.width&&o.height&&[o.width,o.height],i=this.image(l).attr({x:t,y:n}),i.isImg=!0,u?c(i,u):(i.attr({width:0,height:0}),s=f("img",{onload:function(){c(i,Ie[l]=[this.width,this.height])},src:l}))),i},symbols:{circle:function(e,t,n,r){var a=.166*n;return[$e,e+n/2,t,"C",e+n+a,t,e+n+a,t+r,e+n/2,t+r,"C",e-a,t+r,e-a,t,e+n/2,t,"Z"]},square:function(e,t,n,r){return[$e,e,t,Ze,e+n,t,e+n,t+r,e,t+r,"Z"]},triangle:function(e,t,n,r){return[$e,e+n/2,t,Ze,e+n,t+r,e,t+r,"Z"]; +},"triangle-down":function(e,t,n,r){return[$e,e,t,Ze,e+n,t,e+n/2,t+r,"Z"]},diamond:function(e,t,n,r){return[$e,e+n/2,t,Ze,e+n,t+r/2,e+n/2,t+r,e,t+r/2,"Z"]},arc:function(e,t,n,r,a){var o=a.start,i=a.r||n||r,s=a.end-.001,l=a.innerR,u=a.open,c=we(o),d=ke(o),p=we(s),f=ke(s),h=a.end-on&&d>t+u&&t+r-u>d?o.splice(13,3,"L",e+n,d-s,e+n+i,d,e+n,d+s,e+n,t+r-l):c&&0>c&&d>t+u&&t+r-u>d?o.splice(33,3,"L",e,d+s,e-i,d,e,d-s,e,t+l):d&&d>r&&c>e+u&&e+n-u>c?o.splice(23,3,"L",c+s,t+r,c,t+r+i,c-s,t+r,e+l,t+r):d&&0>d&&c>e+u&&e+n-u>c&&o.splice(3,3,"L",c-s,t,c,t-i,c+s,t,n-l,t),o}},clipRect:function(e,t,n,r){var a,o=Ge+Re++,i=this.createElement("clipPath").attr({id:o}).add(this.defs);return a=this.rect(e,t,n,r,0).add(i),a.id=o,a.clipPath=i,a.count=0,a},text:function(e,t,n,r){var a,o=this,i=ze||!Me&&o.forExport,s={};return r&&!o.forExport?o.html(e,t,n):(s.x=Math.round(t||0),n&&(s.y=Math.round(n)),(e||0===e)&&(s.text=e),a=o.createElement("text").attr(s),i&&a.css({position:We}),r||(a.xSetter=function(e,t,n){var r,a,o=n.getElementsByTagName("tspan"),i=n.getAttribute(t);for(a=0;ae?e+3:me(1.2*e),a=me(.8*r),{h:r,b:a,f:e}},rotCorr:function(e,t,n){var r=e;return t&&n&&(r=be(r*we(t*xe),4)),{x:-e/3*ke(t*xe),y:r}},label:function(t,n,r,a,o,i,s,l,c){function d(){var e,t,n=x.element.style;m=(void 0===g||void 0===y||E.styles.textAlign)&&u(x.textStr)&&x.getBBox(),E.width=(g||m.width||0)+2*S+P,E.height=(y||m.height||0)+2*S,_=S+k.fontMetrics(n&&n.fontSize,x).b,w&&(h||(e=me(-O*S)+A,t=(l?-_:0)+A,E.box=h=a?k.symbol(a,e,t,E.width,E.height,j):k.rect(e,t,E.width,E.height,0,j[at]),h.attr("fill",Je).add(E)),h.isImg||h.attr(it({width:me(E.width),height:me(E.height)},j)),j=null)}function p(){var e,t=E.styles,n=t&&t.textAlign,r=P+S*(1-O);e=l?0:_,u(g)&&m&&("center"===n||"right"===n)&&(r+={center:.5,right:1}[n]*(g-m.width)),(r!==x.x||e!==x.y)&&(x.attr("x",r),e!==B&&x.attr("y",e)),x.x=r,x.y=e}function f(e,t){h?h.attr(e,t):j[e]=t}var h,m,g,y,b,v,_,w,k=this,E=k.g(c),x=k.text("",0,0,s).attr({zIndex:1}),O=0,S=3,P=0,A=0,j={};E.onAdd=function(){x.add(E),E.attr({text:t||0===t?t:"",x:n,y:r}),h&&u(o)&&E.attr({anchorX:o,anchorY:i})},E.widthSetter=function(e){g=e},E.heightSetter=function(e){y=e},E.paddingSetter=function(e){u(e)&&e!==S&&(S=E.padding=e,p())},E.paddingLeftSetter=function(e){u(e)&&e!==P&&(P=e,p())},E.alignSetter=function(e){O={left:0,center:.5,right:1}[e]},E.textSetter=function(e){e!==B&&x.textSetter(e),d(),p()},E["stroke-widthSetter"]=function(e,t){e&&(w=!0),A=e%2/2,f(t,e)},E.strokeSetter=E.fillSetter=E.rSetter=function(e,t){"fill"===t&&e&&(w=!0),f(t,e)},E.anchorXSetter=function(e,t){o=e,f(t,me(e)-A-b)},E.anchorYSetter=function(e,t){i=e,f(t,e-v)},E.xSetter=function(e){E.x=e,O&&(e-=O*((g||m.width)+S)),b=me(e),E.attr("translateX",b)},E.ySetter=function(e){v=E.y=me(e),E.attr("translateY",v)};var C=E.css;return it(E,{css:function(t){if(t){var n={};t=e(t),ht(E.textProps,function(e){t[e]!==B&&(n[e]=t[e],delete t[e])}),x.css(n)}return C.call(E,t)},getBBox:function(){return{width:m.width+2*S,height:m.height+2*S,x:m.x-S,y:m.y-S}},shadow:function(e){return h&&h.shadow(e),E},destroy:function(){vt(E.element,"mouseenter"),vt(E.element,"mouseleave"),x&&(x=x.destroy()),h&&(h=h.destroy()),M.prototype.destroy.call(E),E=k=d=p=f=null}})}},L=Ct,it(M.prototype,{htmlCss:function(e){var t=this,n=t.element,r=e&&"SPAN"===n.tagName&&e.width;return r&&(delete e.width,t.textWidth=r,t.updateTransform()),e&&"ellipsis"===e.textOverflow&&(e.whiteSpace="nowrap",e.overflow="hidden"),t.styles=it(t.styles,e),p(t.element,e),t},htmlGetBBox:function(){var e=this,t=e.element;return"text"===t.nodeName&&(t.style.position=We),{x:t.offsetLeft,y:t.offsetTop,width:t.offsetWidth,height:t.offsetHeight}},htmlUpdateTransform:function(){if(!this.added)return void(this.alignOnAdd=!0);var e=this,n=e.renderer,r=e.element,a=e.translateX||0,o=e.translateY||0,i=e.x||0,s=e.y||0,l=e.textAlign||"left",c={left:0,center:.5,right:1}[l],d=e.shadows,f=e.styles;if(p(r,{marginLeft:a,marginTop:o}),d&&ht(d,function(e){p(e,{marginLeft:a+1,marginTop:o+1})}),e.inverted&&ht(r.childNodes,function(e){n.invertChild(e,r)}),"SPAN"===r.tagName){var h,m,g=e.rotation,y=t(e.textWidth),b=[g,l,r.innerHTML,e.textWidth].join(",");b!==e.cTT&&(m=n.fontMetrics(r.style.fontSize).b,u(g)&&e.setSpanRotation(g,c,m),h=st(e.elemWidth,r.offsetWidth),h>y&&/[ \-]/.test(r.textContent||r.innerText)&&(p(r,{width:y+Xe,display:"block",whiteSpace:f&&f.whiteSpace||"normal"}),h=y),e.getSpanCorrection(h,m,c,g,l)),p(r,{left:i+(e.xCorr||0)+Xe,top:s+(e.yCorr||0)+Xe}),je&&(m=r.offsetHeight),e.cTT=b}},setSpanRotation:function(e,t,n){var r={},a=Pe?"-ms-transform":je?"-webkit-transform":Ce?"MozTransform":Se?"-o-transform":"";r[a]=r.transform="rotate("+e+"deg)",r[a+(Ce?"Origin":"-origin")]=r.transformOrigin=100*t+"% "+n+"px",p(this.element,r)},getSpanCorrection:function(e,t,n){this.xCorr=-e*n,this.yCorr=-t}}),it(Ct.prototype,{html:function(e,t,n){var r=this.createElement("span"),a=r.element,o=r.renderer;return r.textSetter=function(e){e!==a.innerHTML&&delete this.bBox,a.innerHTML=this.textStr=e},r.xSetter=r.ySetter=r.alignSetter=r.rotationSetter=function(e,t){"align"===t&&(t="textAlign"),r[t]=e,r.htmlUpdateTransform()},r.attr({text:e,x:me(t),y:me(n)}).css({position:We,fontFamily:this.style.fontFamily,fontSize:this.style.fontSize}),a.style.whiteSpace="nowrap",r.css=r.htmlCss,o.isSVG&&(r.add=function(e){var t,n,i=o.box.parentNode,s=[];if(this.parentGroup=e,e){if(t=e.div,!t){for(n=e;n;)s.push(n),n=n.parentGroup;ht(s.reverse(),function(e){var n,r=c(e.element,"class");r&&(r={className:r}),t=e.div=e.div||f(He,r,{position:We,left:(e.translateX||0)+Xe,top:(e.translateY||0)+Xe},t||i),n=t.style,it(e,{translateXSetter:function(t,r){n.left=t+Xe,e[r]=t,e.doTransform=!0},translateYSetter:function(t,r){n.top=t+Xe,e[r]=t,e.doTransform=!0},visibilitySetter:function(e,t){n[t]=e}})})}}else t=i;return t.appendChild(a),r.added=!0,r.alignOnAdd&&r.htmlUpdateTransform(),r}),r}});var Tt,Dt;if(!Me&&!ze){Dt={init:function(e,t){var n=this,r=["<",t,' filled="f" stroked="f"'],a=["position: ",We,";"],o=t===He;("shape"===t||o)&&a.push("left:0;top:0;width:1px;height:1px;"),a.push("visibility: ",o?Ke:Ye),r.push(' style="',a.join(""),'"/>'),t&&(r=o||"span"===t||"img"===t?r.join(""):e.prepVML(r),n.element=f(r)),n.renderer=e},add:function(e){var t=this,n=t.renderer,r=t.element,a=n.box,o=e&&e.inverted,i=e?e.element||e:a;return o&&n.invertChild(r,i),i.appendChild(r),t.added=!0,t.alignOnAdd&&!t.deferUpdateTransform&&t.updateTransform(),t.onAdd&&t.onAdd(),t},updateTransform:M.prototype.htmlUpdateTransform,setSpanRotation:function(){var e=this.rotation,t=we(e*xe),n=ke(e*xe);p(this.element,{filter:e?["progid:DXImageTransform.Microsoft.Matrix(M11=",t,", M12=",-n,", M21=",n,", M22=",t,", sizingMethod='auto expand')"].join(""):Je})},getSpanCorrection:function(e,t,n,r,a){var o,i=r?we(r*xe):1,s=r?ke(r*xe):0,l=st(this.elemHeight,this.element.offsetHeight),u=a&&"left"!==a;this.xCorr=0>i&&-e,this.yCorr=0>s&&-l,o=0>i*s,this.xCorr+=s*t*(o?1-n:n),this.yCorr-=i*t*(r?o?n:1-n:1),u&&(this.xCorr-=e*n*(0>i?-1:1),r&&(this.yCorr-=l*n*(0>s?-1:1)),p(this.element,{textAlign:a}))},pathToVML:function(e){for(var t=e.length,n=[];t--;)o(e[t])?n[t]=me(10*e[t])-5:"Z"===e[t]?n[t]="x":(n[t]=e[t],!e.isArc||"wa"!==e[t]&&"at"!==e[t]||(n[t+5]===n[t+7]&&(n[t+7]+=e[t+7]>e[t+5]?1:-1),n[t+6]===n[t+8]&&(n[t+8]+=e[t+8]>e[t+6]?1:-1)));return n.join(" ")||"x"},clip:function(e){var t,n,r=this;return e?(t=e.members,l(t,r),t.push(r),r.destroyClip=function(){l(t,r)},n=e.getCSS(r)):(r.destroyClip&&r.destroyClip(),n={clip:Ae?"inherit":"rect(auto)"}),r.css(n)},css:M.prototype.htmlCss,safeRemoveChild:function(e){e.parentNode&&S(e)},destroy:function(){return this.destroyClip&&this.destroyClip(),M.prototype.destroy.apply(this)},on:function(e,t){return this.element["on"+e]=function(){var e=fe.event;e.target=e.srcElement,t(e)},this},cutOffPath:function(e,n){var r;return e=e.split(/[ ,]/),r=e.length,(9===r||11===r)&&(e[r-4]=e[r-2]=t(e[r-2])-10*n),e.join(" ")},shadow:function(e,n,r){var a,o,i,s,l,u,c,d=[],p=this.element,h=this.renderer,m=p.style,g=p.path;if(g&&"string"!=typeof g.value&&(g="x"),l=g,e){for(u=st(e.width,3),c=(e.opacity||.15)/u,a=1;3>=a;a++)s=2*u+1-2*a,r&&(l=this.cutOffPath(g.value,s+.5)),i=[''],o=f(h.prepVML(i),null,{left:t(m.left)+st(e.offsetX,1),top:t(m.top)+st(e.offsetY,1)}),r&&(o.cutOff=s+1),i=[''],f(h.prepVML(i),null,null,o),n?n.element.appendChild(o):p.parentNode.insertBefore(o,p),d.push(o);this.shadows=d}return this},updateShadows:Be,setAttr:function(e,t){Ae?this.element[e]=t:this.element.setAttribute(e,t)},classSetter:function(e){this.element.className=e},dashstyleSetter:function(e,t,n){var r=n.getElementsByTagName("stroke")[0]||f(this.renderer.prepVML([""]),null,null,n);r[t]=e||"solid",this[t]=e},dSetter:function(e,t,n){var r,a=this.shadows;if(e=e||[],this.d=e.join&&e.join(" "),n.path=e=this.pathToVML(e),a)for(r=a.length;r--;)a[r].path=a[r].cutOff?this.cutOffPath(e,a[r].cutOff):e;this.setAttr(t,e)},fillSetter:function(e,t,n){var r=n.nodeName;"SPAN"===r?n.style.color=e:"IMG"!==r&&(n.filled=e!==Je,this.setAttr("fillcolor",this.renderer.color(e,n,t,this)))},opacitySetter:Be,rotationSetter:function(e,t,n){var r=n.style;this[t]=r[t]=e,r.left=-me(ke(e*xe)+1)+Xe,r.top=me(we(e*xe))+Xe},strokeSetter:function(e,t,n){this.setAttr("strokecolor",this.renderer.color(e,n,t))},"stroke-widthSetter":function(e,t,n){n.stroked=!!e,this[t]=e,o(e)&&(e+=Xe),this.setAttr("strokeweight",e)},titleSetter:function(e,t){this.setAttr(t,e)},visibilitySetter:function(e,t,n){"inherit"===e&&(e=Ye),this.shadows&&ht(this.shadows,function(n){n.style[t]=e}),"DIV"===n.nodeName&&(e=e===Ke?"-999em":0,Ae||(n.style[t]=e?Ye:Ke),t="top"),n.style[t]=e},xSetter:function(e,t,n){this[t]=e,"x"===t?t="left":"y"===t&&(t="top"),this.updateClipping?(this[t]=e,this.updateClipping()):n.style[t]=e},zIndexSetter:function(e,t,n){n.style[t]=e}},de.VMLElement=Dt=h(M,Dt),Dt.prototype.ySetter=Dt.prototype.widthSetter=Dt.prototype.heightSetter=Dt.prototype.xSetter;var Mt={Element:Dt,isIE8:Oe.indexOf("MSIE 8.0")>-1,init:function(e,t,n,r){var a,o,i,s=this;if(s.alignedObjects=[],a=s.createElement(He).css(it(this.getStyle(r),{position:Ve})),o=a.element,e.appendChild(a.element),s.isVML=!0,s.box=o,s.boxWrapper=a,s.cache={},s.setSize(t,n,!1),!pe.namespaces.hcv){pe.namespaces.add("hcv","urn:schemas-microsoft-com:vml"),i="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } ";try{pe.createStyleSheet().cssText=i}catch(l){pe.styleSheets[0].cssText+=i}}},isHidden:function(){return!this.box.offsetWidth},clipRect:function(e,t,n,a){var o=this.createElement(),i=r(e);return it(o,{members:[],count:0,left:(i?e.x:e)+1,top:(i?e.y:t)+1,width:(i?e.width:n)-1,height:(i?e.height:a)-1,getCSS:function(e){var t=e.element,n=t.nodeName,r="shape"===n,a=e.inverted,o=this,i=o.top-(r?t.offsetTop:0),s=o.left,l=s+o.width,u=i+o.height,c={clip:"rect("+me(a?s:i)+"px,"+me(a?u:l)+"px,"+me(a?l:u)+"px,"+me(a?i:s)+"px)"};return!a&&Ae&&"DIV"===n&&it(c,{width:l+Xe,height:u+Xe}),c},updateClipping:function(){ht(o.members,function(e){e.element&&e.css(o.getCSS(e))})}})},color:function(e,t,n,r){var a,o,i,s=this,l=/^rgba/,u=Je;if(e&&e.linearGradient?i="gradient":e&&e.radialGradient&&(i="pattern"),i){var c,d,p,h,m,g,y,b,v,_,w,k,E=e.linearGradient||e.radialGradient,x="",O=e.stops,S=[],P=function(){o=[''],f(s.prepVML(o),null,null,t)};if(w=O[0],k=O[O.length-1],w[0]>0&&O.unshift([0,w[1]]),k[0]<1&&O.push([1,k[1]]),ht(O,function(e,t){l.test(e[1])?(a=jt(e[1]),c=a.get("rgb"),d=a.get("a")):(c=e[1],d=1),S.push(100*e[0]+"% "+c),t?(b=d,v=c):(y=d,_=c)}),"fill"===n)if("gradient"===i)p=E.x1||E[0]||0,h=E.y1||E[1]||0,m=E.x2||E[2]||0,g=E.y2||E[3]||0,x='angle="'+(90-180*he.atan((g-h)/(m-p))/Ee)+'"',P();else{var A,j=E.r,C=2*j,T=2*j,D=E.cx,M=E.cy,N=t.radialReference,z=function(){N&&(A=r.getBBox(),D+=(N[0]-A.x)/A.width-.5,M+=(N[1]-A.y)/A.height-.5,C*=N[2]/A.width,T*=N[2]/A.height),x='src="'+U.global.VMLRadialGradientURL+'" size="'+C+","+T+'" origin="0.5,0.5" position="'+D+","+M+'" color2="'+_+'" ',P()};r.added?z():r.onAdd=z,u=v}else u=c}else if(l.test(e)&&"IMG"!==t.tagName)a=jt(e),o=["<",n,' opacity="',a.get("a"),'"/>'],f(this.prepVML(o),null,null,t),u=a.get("rgb");else{var I=t.getElementsByTagName(n);I.length&&(I[0].opacity=1,I[0].type="solid"),u=e}return u},prepVML:function(e){var t="display:inline-block;behavior:url(#default#VML);",n=this.isIE8;return e=e.join(""),n?(e=e.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),e=-1===e.indexOf('style="')?e.replace("/>",' style="'+t+'" />'):e.replace('style="','style="'+t)):e=e.replace("<","1&&o.attr({x:t,y:n,width:r,height:a}),o},createElement:function(e){return"rect"===e?this.symbol(e):Ct.prototype.createElement.call(this,e)},invertChild:function(e,n){var r=this,a=n.style,o="IMG"===e.tagName&&e.style;p(e,{flip:"x",left:t(a.width)-(o?t(o.top):1),top:t(a.height)-(o?t(o.left):1),rotation:-90}),ht(e.childNodes,function(t){r.invertChild(t,e)})},symbols:{arc:function(e,t,n,r,a){var o,i=a.start,s=a.end,l=a.r||n||r,u=a.innerR,c=we(i),d=ke(i),p=we(s),f=ke(s);return s-i===0?["x"]:(o=["wa",e-l,t-l,e+l,t+l,e+l*c,t+l*d,e+l*p,t+l*f],a.open&&!u&&o.push("e",$e,e,t),o.push("at",e-u,t-u,e+u,t+u,e+u*p,t+u*f,e+u*c,t+u*d,"x","e"),o.isArc=!0,o)},circle:function(e,t,n,r,a){return a&&(n=r=2*a.r),a&&a.isCircle&&(e-=n/2,t-=r/2),["wa",e,t,e+n,t+r,e+n,t+r/2,e+n,t+r/2,"e"]},rect:function(e,t,n,r,a){return Ct.prototype.symbols[u(a)&&a.r?"callout":"square"].call(0,e,t,n,r,a)}}};de.VMLRenderer=Tt=function(){this.init.apply(this,arguments)},Tt.prototype=e(Ct.prototype,Mt),L=Tt}Ct.prototype.measureSpanWidth=function(e,t){var n,r=pe.createElement("span"),a=pe.createTextNode(e);return r.appendChild(a),p(r,t),this.box.appendChild(r),n=r.offsetWidth,S(r),n};var Nt,zt;ze&&(de.CanVGRenderer=Nt=function(){De="http://www.w3.org/1999/xhtml"},Nt.prototype.symbols={},zt=function(){function e(){var e,n=t.length;for(e=0;n>e;e++)t[e]();t=[]}var t=[];return{push:function(n,r){0===t.length&&pt(r,e),t.push(n)}}}(),L=Nt),N.prototype={addLabel:function(){var t,n,r=this,a=r.axis,o=a.options,i=a.chart,l=a.categories,c=a.names,d=r.pos,p=o.labels,f=a.tickPositions,h=d===f[0],m=d===f[f.length-1],g=l?st(l[d],c[d],d):d,y=r.label,b=f.info;a.isDatetimeAxis&&b&&(n=o.dateTimeLabelFormats[b.higherRanks[d]||b.unitName]),r.isFirst=h,r.isLast=m,t=a.labelFormatter.call({axis:a,chart:i,isFirst:h,isLast:m,dateTimeLabelFormat:n,value:a.isLog?A(s(g)):g}),u(y)?y&&y.attr({text:t}):(r.label=y=u(t)&&p.enabled?i.renderer.text(t,0,0,p.useHTML).css(e(p.style)).add(a.labelGroup):null,r.labelLength=y&&y.getBBox().width,r.rotation=0)},getLabelSize:function(){return this.label?this.label.getBBox()[this.axis.horiz?"height":"width"]:0},handleOverflow:function(e){var t,n,r,a=this.axis,o=e.x,i=a.chart.chartWidth,s=a.chart.spacing,l=st(a.labelLeft,ve(a.pos,s[3])),u=st(a.labelRight,be(a.pos+a.len,i-s[1])),c=this.label,d=this.rotation,p={left:0,center:.5,right:1}[a.labelAlign],f=c.getBBox().width,h=a.slotWidth,m=p,g=1,y={};d?0>d&&l>o-p*f?r=me(o/we(d*xe)-l):d>0&&o+p*f>u&&(r=me((i-o)/we(d*xe))):(t=o-p*f,n=o+(1-p)*f,l>t?h=e.x+h*(1-p)-l:n>u&&(h=u-e.x+h*p,g=-1),h=ve(a.slotWidth,h),hh||a.autoRotation&&c.styles.width)&&(r=h)),r&&(y.width=r,a.options.labels.style.textOverflow||(y.textOverflow="ellipsis"),c.css(y))},getPosition:function(e,t,n,r){var a=this.axis,o=a.chart,i=r&&o.oldChartHeight||o.chartHeight;return{x:e?a.translate(t+n,null,null,r)+a.transB:a.left+a.offset+(a.opposite?(r&&o.oldChartWidth||o.chartWidth)-a.right-a.left:0),y:e?i-a.bottom+a.offset-(a.opposite?a.height:0):i-a.translate(t+n,null,null,r)-a.transB}},getLabelPosition:function(e,t,n,r,a,o,i,s){var l,u=this.axis,c=u.transA,d=u.reversed,p=u.staggerLines,f=u.tickRotCorr||{x:0,y:0},h=st(a.y,f.y+(2===u.side?8:-(n.getBBox().height/2)));return e=e+a.x+f.x-(o&&r?o*c*(d?-1:1):0),t=t+h-(o&&!r?o*c*(d?1:-1):0),p&&(l=i/(s||1)%p,t+=l*(u.labelOffset/p)),{x:e,y:me(t)}},getMarkPath:function(e,t,n,r,a,o){return o.crispLine([$e,e,t,Ze,e+(a?0:-n),t+(a?n:0)],r)},render:function(e,t,n){var r,a,o,i=this,s=i.axis,l=s.options,u=s.chart,c=u.renderer,d=s.horiz,p=i.type,f=i.label,h=i.pos,m=l.labels,g=i.gridLine,y=p?p+"Grid":"grid",b=p?p+"Tick":"tick",v=l[y+"LineWidth"],_=l[y+"LineColor"],w=l[y+"LineDashStyle"],k=l[b+"Length"],E=l[b+"Width"]||0,x=l[b+"Color"],O=l[b+"Position"],S=i.mark,P=m.step,A=!0,j=s.tickmarkOffset,C=i.getPosition(d,h,j,t),T=C.x,D=C.y,M=d&&T===s.pos+s.len||!d&&D===s.pos?-1:1;n=st(n,1),this.isActive=!0,v&&(r=s.getPlotLinePath(h+j,v*M,t,!0),g===B&&(o={stroke:_,"stroke-width":v},w&&(o.dashstyle=w),p||(o.zIndex=1),t&&(o.opacity=0),i.gridLine=g=v?c.path(r).attr(o).add(s.gridGroup):null),!t&&g&&r&&g[i.isNew?"attr":"animate"]({d:r,opacity:n})),E&&k&&("inside"===O&&(k=-k),s.opposite&&(k=-k),a=i.getMarkPath(T,D,k,E*M,d,c),S?S.animate({d:a,opacity:n}):i.mark=c.path(a).attr({stroke:x,"stroke-width":E,opacity:n}).add(s.axisGroup)),f&&!isNaN(T)&&(f.xy=C=i.getLabelPosition(T,D,f,d,m,j,e,P),i.isFirst&&!i.isLast&&!st(l.showFirstLabel,1)||i.isLast&&!i.isFirst&&!st(l.showLastLabel,1)?A=!1:!d||s.isRadial||m.step||m.rotation||t||0===n||i.handleOverflow(C),P&&e%P&&(A=!1),A&&!isNaN(C.y)?(C.opacity=n,f[i.isNew?"attr":"animate"](C),i.isNew=!1):f.attr("y",-9999))},destroy:function(){O(this,this.axis)}},de.PlotLineOrBand=function(e,t){this.axis=e,t&&(this.options=t,this.id=t.id)},de.PlotLineOrBand.prototype={render:function(){var t,n,r,a,o,s,l=this,c=l.axis,d=c.horiz,p=l.options,f=p.label,h=l.label,m=p.width,g=p.to,y=p.from,b=u(y)&&u(g),v=p.value,_=p.dashStyle,w=l.svgElem,k=[],O=p.color,S=p.zIndex,P=p.events,A={},j=c.chart.renderer;if(c.isLog&&(y=i(y),g=i(g),v=i(v)),m)k=c.getPlotLinePath(v,m),A={stroke:O,"stroke-width":m},_&&(A.dashstyle=_);else{if(!b)return;k=c.getPlotBandPath(y,g,p),O&&(A.fill=O),p.borderWidth&&(A.stroke=p.borderColor,A["stroke-width"]=p.borderWidth)}if(u(S)&&(A.zIndex=S),w)k?w.animate({d:k},null,w.onGetPath):(w.hide(),w.onGetPath=function(){w.show()},h&&(l.label=h=h.destroy()));else if(k&&k.length&&(l.svgElem=w=j.path(k).attr(A).add(),P)){t=function(e){w.on(e,function(t){P[e].apply(l,[t])})};for(n in P)t(n)}return f&&u(f.text)&&k&&k.length&&c.width>0&&c.height>0?(f=e({align:d&&b&&"center",x:d?!b&&4:10,verticalAlign:!d&&b&&"middle",y:d?b?16:10:b?6:-4,rotation:d&&!b&&90},f),h||(A={align:f.textAlign||f.align,rotation:f.rotation},u(S)&&(A.zIndex=S),l.label=h=j.text(f.text,0,0,f.useHTML).attr(A).css(f.style).add()),r=[k[1],k[4],b?k[6]:k[1]],a=[k[2],k[5],b?k[7]:k[2]],o=E(r),s=E(a),h.align(f,!1,{x:o,y:s,width:x(r)-o,height:x(a)-s}),h.show()):h&&h.hide(),l},destroy:function(){l(this.axis.plotLinesAndBands,this),delete this.axis,O(this)}},G={getPlotBandPath:function(e,t){var n=this.getPlotLinePath(t,null,null,!0),r=this.getPlotLinePath(e,null,null,!0);return r&&n&&r.toString()!==n.toString()?r.push(n[4],n[5],n[1],n[2]):r=null,r},addPlotBand:function(e){return this.addPlotBandOrLine(e,"plotBands")},addPlotLine:function(e){return this.addPlotBandOrLine(e,"plotLines")},addPlotBandOrLine:function(e,t){var n=new de.PlotLineOrBand(this,e).render(),r=this.userOptions;return n&&(t&&(r[t]=r[t]||[],r[t].push(e)),this.plotLinesAndBands.push(n)),n},removePlotBandOrLine:function(e){for(var t=this.plotLinesAndBands,n=this.options,r=this.userOptions,a=t.length;a--;)t[a].id===e&&t[a].destroy();ht([n.plotLines||[],r.plotLines||[],n.plotBands||[],r.plotBands||[]],function(t){for(a=t.length;a--;)t[a].id===e&&l(t,t[a])})}};var It=de.Axis=function(){this.init.apply(this,arguments)};It.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"},endOnTick:!1,gridLineColor:"#D8D8D8",labels:{enabled:!0,style:{color:"#606060",cursor:"default",fontSize:"11px"},x:0,y:15},lineColor:"#C0D0E0",lineWidth:1,minPadding:.01,maxPadding:.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:10,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#707070"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8,y:3},lineWidth:0,maxPadding:.05,minPadding:.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Values"},stackLabels:{enabled:!1,formatter:function(){return de.numberFormat(this.total,-1)},style:e(xt.line.dataLabels.style,{color:"#000000"})}},defaultLeftAxisOptions:{labels:{x:-15,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{x:15,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{autoRotation:[-45],x:0,y:null},title:{rotation:0}},defaultTopAxisOptions:{labels:{autoRotation:[-45],x:0,y:-15},title:{rotation:0}},init:function(e,t){var n=t.isX,r=this;r.horiz=e.inverted?!n:n,r.isXAxis=n,r.coll=n?"xAxis":"yAxis",r.opposite=t.opposite,r.side=t.side||(r.horiz?r.opposite?0:2:r.opposite?1:3),r.setOptions(t);var a=this.options,o=a.type,l="datetime"===o;r.labelFormatter=a.labels.formatter||r.defaultLabelFormatter,r.userOptions=t,r.minPixelPadding=0,r.chart=e,r.reversed=a.reversed,r.zoomEnabled=a.zoomEnabled!==!1,r.categories=a.categories||"category"===o,r.names=r.names||[],r.isLog="logarithmic"===o,r.isDatetimeAxis=l,r.isLinked=u(a.linkedTo),r.ticks={},r.labelEdge=[],r.minorTicks={},r.plotLinesAndBands=[],r.alternateBands={},r.len=0,r.minRange=r.userMinRange=a.minRange||a.maxZoom,r.range=a.range,r.offset=a.offset||0,r.stacks={},r.oldStacks={},r.max=null,r.min=null,r.crosshair=st(a.crosshair,d(e.options.tooltip.crosshairs)[n?0:1],!1);var c,p=r.options.events;-1===ft(r,e.axes)&&(n&&!this.isColorAxis?e.axes.splice(e.xAxis.length,0,r):e.axes.push(r),e[r.coll].push(r)),r.series=r.series||[],e.inverted&&n&&r.reversed===B&&(r.reversed=!0),r.removePlotBand=r.removePlotBandOrLine,r.removePlotLine=r.removePlotBandOrLine;for(c in p)bt(r,c,p[c]);r.isLog&&(r.val2lin=i,r.lin2val=s)},setOptions:function(t){this.options=e(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],e(U[this.coll],t))},defaultLabelFormatter:function(){var e,t,n=this.axis,r=this.value,a=n.categories,o=this.dateTimeLabelFormat,i=U.lang.numericSymbols,s=i&&i.length,l=n.options.labels.format,u=n.isLog?r:n.tickInterval;if(l)t=v(l,this);else if(a)t=r;else if(o)t=H(o,r);else if(s&&u>=1e3)for(;s--&&t===B;)e=Math.pow(1e3,s+1),u>=e&&10*r%e===0&&null!==i[s]&&(t=de.numberFormat(r/e,-1)+i[s]);return t===B&&(t=_e(r)>=1e4?de.numberFormat(r,-1):de.numberFormat(r,-1,B,"")),t},getSeriesExtremes:function(){var e=this,t=e.chart;e.hasVisibleSeries=!1,e.dataMin=e.dataMax=e.ignoreMinPadding=e.ignoreMaxPadding=null,e.buildStacks&&e.buildStacks(),ht(e.series,function(n){if(n.visible||!t.options.chart.ignoreHiddenSeries){var r,a,o,i=n.options,s=i.threshold;e.hasVisibleSeries=!0,e.isLog&&0>=s&&(s=null),e.isXAxis?(r=n.xData,r.length&&(e.dataMin=ve(st(e.dataMin,r[0]),E(r)),e.dataMax=be(st(e.dataMax,r[0]),x(r)))):(n.getExtremes(),o=n.dataMax,a=n.dataMin,u(a)&&u(o)&&(e.dataMin=ve(st(e.dataMin,a),a),e.dataMax=be(st(e.dataMax,o),o)),u(s)&&(e.dataMin>=s?(e.dataMin=s,e.ignoreMinPadding=!0):e.dataMaxe||e>n)&&(r?e=ve(be(t,e),n):u=!0),e};return a=st(a,c.translate(e,null,null,n)),o=s=me(a+g),i=l=me(h-a-g),isNaN(a)?u=!0:c.horiz?(i=f,l=h-c.bottom,o=s=y(o,p,p+c.width)):(o=p,s=m-c.right,i=l=y(i,f,f+c.height)),u&&!r?null:d.renderer.crispLine([$e,o,i,Ze,s,l],t||1)},getLinearTickPositions:function(e,t,n){var r,a,i=A(ge(t/e)*e),s=A(ye(n/e)*e),l=[];if(t===n&&o(t))return[t];for(r=i;s>=r&&(l.push(r),r=A(r+e),r!==a);)a=r;return l},getMinorTickPositions:function(){var e,t,n,r=this,a=r.options,o=r.tickPositions,i=r.minorTickInterval,s=[],l=r.min,u=r.max,c=u-l;if(c&&c/it;t++)s=s.concat(r.getLogTickPositions(i,o[t-1],o[t],!0));else if(r.isDatetimeAxis&&"auto"===a.minorTickInterval)s=s.concat(r.getTimeTicks(r.normalizeTimeTickInterval(i),l,u,a.startOfWeek));else for(e=l+(o[0]-l)%i;u>=e;e+=i)s.push(e);return r.trimTicks(s),s},adjustForMinRange:function(){var e,t,n,r,a,o,i,s,l=this,c=l.options,d=l.min,p=l.max,f=l.dataMax-l.dataMin>=l.minRange;if(l.isXAxis&&l.minRange===B&&!l.isLog&&(u(c.min)||u(c.max)?l.minRange=null:(ht(l.series,function(e){for(a=e.xData,o=e.xIncrement?1:a.length-1,n=o;n>0;n--)r=a[n]-a[n-1],(t===B||t>r)&&(t=r)}),l.minRange=ve(5*t,l.dataMax-l.dataMin))),p-dp-d&&(i[0]=p-h,i[1]=st(c.min,p-h),d=x(i))}l.min=d,l.max=p},setAxisTranslation:function(e){var t,r,a=this,o=a.max-a.min,i=a.axisPointRange||0,s=0,l=0,c=a.linkedParent,d=!!a.categories,p=a.transA,f=a.isXAxis;(f||d||i)&&(c?(s=c.minPointOffset,l=c.pointRangePadding):ht(a.series,function(e){var r=d?1:f?e.pointRange:a.axisPointRange||0,c=e.options.pointPlacement,p=e.closestPointRange;r>o&&(r=0),i=be(i,r),a.single||(s=be(s,n(c)?0:r/2),l=be(l,"on"===c?0:r)),!e.noSharedTooltip&&u(p)&&(t=u(t)?ve(t,p):p)}),r=a.ordinalSlope&&t?a.ordinalSlope/t:1,a.minPointOffset=s*=r,a.pointRangePadding=l*=r,a.pointRange=ve(i,o),f&&(a.closestPointRange=t)),e&&(a.oldTransA=p),a.translationSlope=a.transA=p=a.len/(o+l||1),a.transB=a.horiz?a.left:a.bottom,a.minPixelPadding=p*s},setTickInterval:function(e){var t,n,r,a=this,s=a.chart,l=a.options,c=a.isLog,d=a.isDatetimeAxis,p=a.isXAxis,f=a.isLinked,h=l.maxPadding,m=l.minPadding,g=l.tickInterval,y=l.tickPixelInterval,b=a.categories;d||b||f||this.getTickAmount(),f?(a.linkedParent=s[a.coll][l.linkedTo],n=a.linkedParent.getExtremes(),a.min=st(n.min,n.dataMin),a.max=st(n.max,n.dataMax),l.type!==a.linkedParent.options.type&&P(11,1)):(a.min=st(a.userMin,l.min,a.dataMin),a.max=st(a.userMax,l.max,a.dataMax)),c&&(!e&&ve(a.min,st(a.dataMin,a.min))<=0&&P(10,1),a.min=A(i(a.min)),a.max=A(i(a.max))),a.range&&u(a.max)&&(a.userMin=a.min=be(a.min,a.max-a.range),a.userMax=a.max,a.range=null),a.beforePadding&&a.beforePadding(),a.adjustForMinRange(),b||a.axisPointRange||a.usePercentage||f||!u(a.min)||!u(a.max)||(t=a.max-a.min,t&&(u(l.min)||u(a.userMin)||!m||!(a.dataMin<0)&&a.ignoreMinPadding||(a.min-=t*m),u(l.max)||u(a.userMax)||!h||!(a.dataMax>0)&&a.ignoreMaxPadding||(a.max+=t*h))),o(l.floor)&&(a.min=be(a.min,l.floor)),o(l.ceiling)&&(a.max=ve(a.max,l.ceiling)),a.min===a.max||void 0===a.min||void 0===a.max?a.tickInterval=1:f&&!g&&y===a.linkedParent.options.tickPixelInterval?a.tickInterval=g=a.linkedParent.tickInterval:a.tickInterval=st(g,this.tickAmount?(a.max-a.min)/be(this.tickAmount-1,1):void 0,b?1:(a.max-a.min)*y/be(a.len,y)),p&&!e&&ht(a.series,function(e){e.processData(a.min!==a.oldMin||a.max!==a.oldMax)}),a.setAxisTranslation(!0),a.beforeSetTickPositions&&a.beforeSetTickPositions(),a.postProcessTickInterval&&(a.tickInterval=a.postProcessTickInterval(a.tickInterval)),a.pointRange&&(a.tickInterval=be(a.pointRange,a.tickInterval)),r=st(l.minTickInterval,a.isDatetimeAxis&&a.closestPointRange),!g&&a.tickInterval.5&&a.tickInterval<5&&a.max>1e3&&a.max<9999)),!!this.tickAmount)),!this.tickAmount&&this.len&&(a.tickInterval=a.unsquish()),this.setTickPositions()},setTickPositions:function(){var e,t,n=this.options,r=n.tickPositions,a=n.tickPositioner,o=n.startOnTick,i=n.endOnTick;this.tickmarkOffset=this.categories&&"between"===n.tickmarkPlacement&&1===this.tickInterval?.5:0,this.minorTickInterval="auto"===n.minorTickInterval&&this.tickInterval?this.tickInterval/5:n.minorTickInterval,this.tickPositions=e=r&&r.slice(),e||(e=this.isDatetimeAxis?this.getTimeTicks(this.normalizeTimeTickInterval(this.tickInterval,n.units),this.min,this.max,n.startOfWeek,this.ordinalPositions,this.closestPointRange,!0):this.isLog?this.getLogTickPositions(this.tickInterval,this.min,this.max):this.getLinearTickPositions(this.tickInterval,this.min,this.max),this.tickPositions=e,a&&(a=a.apply(this,[this.min,this.max]),a&&(this.tickPositions=e=a))),this.isLinked||(this.trimTicks(e,o,i),this.min===this.max&&u(this.min)&&!this.tickAmount&&(t=!0,this.min-=.5,this.max+=.5),this.single=t,r||a||this.adjustTickAmount())},trimTicks:function(e,t,n){var r=e[0],a=e[e.length-1],o=this.minPointOffset||0;t?this.min=r:this.min-o>r&&e.shift(),n?this.max=a:this.max+or&&(this.finalTickAmt=r,r=5),this.tickAmount=r},adjustTickAmount:function(){var e,t,n=this.tickInterval,r=this.tickPositions,a=this.tickAmount,o=this.finalTickAmt,i=r&&r.length;if(a>i){for(;r.lengtha&&(this.tickInterval*=2,this.setTickPositions());if(u(o)){for(e=t=r.length;e--;)(3===o&&e%2===1||2>=o&&e>0&&t-1>e)&&r.splice(e,1);this.finalTickAmt=B}},setScale:function(){var e,t,n,r,a=this,o=a.stacks;if(a.oldMin=a.min,a.oldMax=a.max,a.oldAxisLength=a.len,a.setAxisSize(),r=a.len!==a.oldAxisLength,ht(a.series,function(e){(e.isDirtyData||e.isDirty||e.xAxis.isDirty)&&(n=!0)}),r||n||a.isLinked||a.forceRedraw||a.userMin!==a.oldUserMin||a.userMax!==a.oldUserMax){if(!a.isXAxis)for(e in o)for(t in o[e])o[e][t].total=null, +o[e][t].cum=0;a.forceRedraw=!1,a.getSeriesExtremes(),a.setTickInterval(),a.oldUserMin=a.userMin,a.oldUserMax=a.userMax,a.isDirty||(a.isDirty=r||a.min!==a.oldMin||a.max!==a.oldMax)}else if(!a.isXAxis){a.oldStacks&&(o=a.stacks=a.oldStacks);for(e in o)for(t in o[e])o[e][t].cum=o[e][t].total}},setExtremes:function(e,t,n,r,a){var o=this,i=o.chart;n=st(n,!0),ht(o.series,function(e){delete e.kdTree}),a=it(a,{min:e,max:t}),_t(o,"setExtremes",a,function(){o.userMin=e,o.userMax=t,o.eventArgs=a,o.isDirtyExtremes=!0,n&&i.redraw(r)})},zoom:function(e,t){var n=this.dataMin,r=this.dataMax,a=this.options;return this.allowZoomOutside||(u(n)&&e<=ve(n,st(a.min,n))&&(e=B),u(r)&&t>=be(r,st(a.max,r))&&(t=B)),this.displayBtn=e!==B||t!==B,this.setExtremes(e,t,!1,B,{trigger:"zoom"}),!0},setAxisSize:function(){var e=this.chart,t=this.options,n=t.offsetLeft||0,r=t.offsetRight||0,a=this.horiz,o=st(t.width,e.plotWidth-n+r),i=st(t.height,e.plotHeight),s=st(t.top,e.plotTop),l=st(t.left,e.plotLeft+n),u=/%$/;u.test(i)&&(i=parseFloat(i)/100*e.plotHeight),u.test(s)&&(s=parseFloat(s)/100*e.plotHeight+e.plotTop),this.left=l,this.top=s,this.width=o,this.height=i,this.bottom=e.chartHeight-i-s,this.right=e.chartWidth-o-l,this.len=be(a?o:i,0),this.pos=a?l:s},getExtremes:function(){var e=this,t=e.isLog;return{min:t?A(s(e.min)):e.min,max:t?A(s(e.max)):e.max,dataMin:e.dataMin,dataMax:e.dataMax,userMin:e.userMin,userMax:e.userMax}},getThreshold:function(e){var t=this,n=t.isLog,r=n?s(t.min):t.min,a=n?s(t.max):t.max;return null===e?e=0>a?a:r:r>e?e=r:e>a&&(e=a),t.translate(e,0,1,0,1)},autoLabelAlign:function(e){var t,n=(st(e,0)-90*this.side+720)%360;return t=n>15&&165>n?"right":n>195&&345>n?"left":"center"},unsquish:function(){var e,t,n,r=this.chart,a=this.ticks,o=this.options.labels,i=this.horiz,s=this.tickInterval,l=s,c=this.len/(((this.categories?1:0)+this.max-this.min)/s),d=o.rotation,p=r.renderer.fontMetrics(o.style.fontSize,a[0]&&a[0].label),f=Number.MAX_VALUE,h=function(e){var t=e/(c||1);return t=t>1?ye(t):1,t*s};return i?(n=u(d)?[d]:c=-90&&90>=n)&&(t=h(_e(p.h/ke(xe*n))),r=t+_e(n/360),f>r&&(f=r,e=n,l=t))})):l=h(p.h),this.autoRotation=n,this.labelRotation=e,l},renderUnsquish:function(){var t,r,a,o,i=this.chart,s=i.renderer,l=this.tickPositions,u=this.ticks,c=this.options.labels,d=this.horiz,p=i.margin,f=this.categories?l.length:l.length-1,h=this.slotWidth=d&&!c.step&&!c.rotation&&(this.staggerLines||1)*i.plotWidth/f||!d&&(p[3]&&p[3]-i.spacing[3]||.33*i.chartWidth),m=be(1,me(h-2*(c.padding||5))),g={},y=s.fontMetrics(c.style.fontSize,u[0]&&u[0].label),b=c.style.textOverflow,v=0;if(n(c.rotation)||(g.rotation=c.rotation),this.autoRotation)ht(l,function(e){e=u[e],e&&e.labelLength>v&&(v=e.labelLength)}),v>m&&v>y.h?g.rotation=this.labelRotation:this.labelRotation=0;else if(h&&(t={width:m+Xe},!b))for(t.textOverflow="clip",a=l.length;!d&&a--;)o=l[a],r=u[o].label,r&&("ellipsis"===r.styles.textOverflow&&r.css({textOverflow:"clip"}),r.getBBox().height>this.len/l.length-(y.h-y.f)&&(r.specCss={textOverflow:"ellipsis"}));g.rotation&&(t={width:(v>.5*i.chartHeight?.33*i.chartHeight:i.chartHeight)+Xe},b||(t.textOverflow="ellipsis")),this.labelAlign=g.align=c.align||this.autoLabelAlign(this.labelRotation),ht(l,function(n){var r=u[n],a=r&&r.label;a&&(t&&a.css(e(t,a.specCss)),delete a.specCss,a.attr(g),r.rotation=g.rotation)}),this.tickRotCorr=s.rotCorr(y.b,this.labelRotation||0,2===this.side)},hasData:function(){return this.hasVisibleSeries||u(this.min)&&u(this.max)&&!!this.tickPositions},getOffset:function(){var e,t,n,r,a,o,i,s=this,l=s.chart,c=l.renderer,d=s.options,p=s.tickPositions,f=s.ticks,h=s.horiz,m=s.side,g=l.inverted?[1,0,3,2][m]:m,y=0,b=0,v=d.title,_=d.labels,w=0,k=l.axisOffset,E=l.clipOffset,x=[-1,1,1,-1][m];if(e=s.hasData(),s.showAxis=t=e||st(d.showEmpty,!0),s.staggerLines=s.horiz&&_.staggerLines,s.axisGroup||(s.gridGroup=c.g("grid").attr({zIndex:d.gridZIndex||1}).add(),s.axisGroup=c.g("axis").attr({zIndex:d.zIndex||2}).add(),s.labelGroup=c.g("axis-labels").attr({zIndex:_.zIndex||7}).addClass(Ge+s.coll.toLowerCase()+"-labels").add()),e||s.isLinked)ht(p,function(e){f[e]?f[e].addLabel():f[e]=new N(s,e)}),s.renderUnsquish(),ht(p,function(e){(0===m||2===m||{1:"left",3:"right"}[m]===s.labelAlign)&&(w=be(f[e].getLabelSize(),w))}),s.staggerLines&&(w*=s.staggerLines,s.labelOffset=w);else for(o in f)f[o].destroy(),delete f[o];v&&v.text&&v.enabled!==!1&&(s.axisTitle||(s.axisTitle=c.text(v.text,0,0,v.useHTML).attr({zIndex:7,rotation:v.rotation||0,align:v.textAlign||{low:"left",middle:"center",high:"right"}[v.align]}).addClass(Ge+this.coll.toLowerCase()+"-title").css(v.style).add(s.axisGroup),s.axisTitle.isNew=!0),t&&(y=s.axisTitle.getBBox()[h?"height":"width"],n=v.offset,b=u(n)?0:st(v.margin,h?5:10)),s.axisTitle[t?"show":"hide"]()),s.offset=x*st(d.offset,k[m]),s.tickRotCorr=s.tickRotCorr||{x:0,y:0},i=2===m?s.tickRotCorr.y:0,r=w+b+(w&&x*(h?st(_.y,s.tickRotCorr.y+8):_.x)-i),s.axisTitleMargin=st(n,r),k[m]=be(k[m],s.axisTitleMargin+y+x*s.offset,r),a=2*ge(d.lineWidth/2),d.offset&&(a=be(0,a-d.offset)),E[g]=be(E[g],a)},getLinePath:function(e){var t=this.chart,n=this.opposite,r=this.offset,a=this.horiz,o=this.left+(n?this.width:0)+r,i=t.chartHeight-this.bottom-(n?this.height:0)+r;return n&&(e*=-1),t.renderer.crispLine([$e,a?this.left:o,a?i:this.top,Ze,a?t.chartWidth-this.right:o,a?i:t.chartHeight-this.bottom],e)},getTitlePosition:function(){var e=this.horiz,n=this.left,r=this.top,a=this.len,o=this.options.title,i=e?n:r,s=this.opposite,l=this.offset,u=o.x||0,c=o.y||0,d=t(o.style.fontSize||12),p={low:i+(e?0:a),middle:i+a/2,high:i+(e?a:0)}[o.align],f=(e?r+this.height:n)+(e?1:-1)*(s?-1:1)*this.axisTitleMargin+(2===this.side?d:0);return{x:e?p+u:f+(s?this.width:0)+l+u,y:e?f+c-(s?this.height:0)+l:p+c}},render:function(){var e,t,n,r=this,a=r.chart,o=a.renderer,i=r.options,l=r.isLog,c=r.isLinked,d=r.tickPositions,p=r.axisTitle,f=r.ticks,h=r.minorTicks,m=r.alternateBands,g=i.stackLabels,y=i.alternateGridColor,b=r.tickmarkOffset,v=i.lineWidth,_=a.hasRendered,w=_&&u(r.oldMin)&&!isNaN(r.oldMin),k=r.showAxis;r.labelEdge.length=0,r.overlap=!1,ht([f,h,m],function(e){var t;for(t in e)e[t].isActive=!1}),(r.hasData()||c)&&(r.minorTickInterval&&!r.categories&&ht(r.getMinorTickPositions(),function(e){h[e]||(h[e]=new N(r,e,"minor")),w&&h[e].isNew&&h[e].render(null,!0),h[e].render(null,!1,1)}),d.length&&(ht(d,function(e,t){(!c||e>=r.min&&e<=r.max)&&(f[e]||(f[e]=new N(r,e)),w&&f[e].isNew&&f[e].render(t,!0,.1),f[e].render(t))}),b&&(0===r.min||r.single)&&(f[-1]||(f[-1]=new N(r,-1,null,!0)),f[-1].render(-1))),y&&ht(d,function(e,a){a%2===0&&e=K.second?0:p*ge(c.getMilliseconds()/p)),d>=K.second&&c[oe](d>=K.minute?0:p*ge(c.getSeconds()/p)),d>=K.minute&&c[ie](d>=K.hour?0:p*ge(c[Z]()/p)),d>=K.hour&&c[se](d>=K.day?0:p*ge(c[Q]()/p)),d>=K.day&&c[le](d>=K.month?1:p*ge(c[te]()/p)),d>=K.month&&(c[ue](d>=K.year?0:p*ge(c[ne]()/p)),o=c[re]()),d>=K.year&&(o-=o%p,c[ce](o)),d===K.week&&c[le](c[te]()-c[ee]()+st(r,1)),a=1,(J||$)&&(c=c.getTime(),c=new Y(c+y(c))),o=c[re]();for(var f=c.getTime(),h=c[ne](),m=c[te](),g=(K.day+(l?y(c):60*c.getTimezoneOffset()*1e3))%K.day;n>f;)i.push(f),d===K.year?f=X(o+a*p,0):d===K.month?f=X(o,h+a*p):l||d!==K.day&&d!==K.week?f+=d*p:f=X(o,h,m+a*p*(d===K.day?1:7)),a++;i.push(f),ht(mt(i,function(e){return d<=K.hour&&e%K.day===g}),function(e){s[e]="day"})}return i.info=it(e,{higherRanks:s,totalRange:d*p}),i},It.prototype.normalizeTimeTickInterval=function(e,t){var n,r,a=t||[["millisecond",[1,2,5,10,20,25,50,100,200,500]],["second",[1,2,5,10,15,30]],["minute",[1,2,5,10,15,30]],["hour",[1,2,3,4,6,8,12]],["day",[1,2]],["week",[1,2]],["month",[1,2,3,4,6]],["year",null]],o=a[a.length-1],i=K[o[0]],s=o[1];for(r=0;r=e)break}return i===K.year&&5*i>e&&(s=[1,2,5]),n=w(e/i,s,"year"===o[0]?be(_(e/i),1):1),{unitRange:i,count:n,unitName:o[0]}},It.prototype.getLogTickPositions=function(e,t,n,r){var a=this,o=a.options,l=a.len,u=[];if(r||(a._minorAutoInterval=null),e>=.5)e=me(e),u=a.getLinearTickPositions(e,t,n);else if(e>=.08){var c,d,p,f,h,m,g,y=ge(t);for(c=e>.3?[1,2,4]:e>.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9],d=y;n+1>d&&!g;d++)for(f=c.length,p=0;f>p&&!g;p++)h=i(s(d)*c[p]),h>t&&(!r||n>=m)&&m!==B&&u.push(m),m>n&&(g=!0),m=h}else{var b=s(t),v=s(n),k=o[r?"minorTickInterval":"tickInterval"],E="auto"===k?null:k,x=o.tickPixelInterval/(r?5:1),O=r?l/a.tickPositions.length:l;e=st(E,a._minorAutoInterval,(v-b)*x/(O||1)),e=w(e,null,_(e)),u=yt(a.getLinearTickPositions(e,b,v),i),r||(a._minorAutoInterval=e/5)}return r||(a.tickInterval=e),u};var Rt=de.Tooltip=function(){this.init.apply(this,arguments)};Rt.prototype={init:function(e,n){var r=n.borderWidth,a=n.style,o=t(a.padding);this.chart=e,this.options=n,this.crosshairs=[],this.now={x:0,y:0},this.isHidden=!0,this.label=e.renderer.label("",0,0,n.shape||"callout",null,null,n.useHTML,null,"tooltip").attr({padding:o,fill:n.backgroundColor,"stroke-width":r,r:n.borderRadius,zIndex:8}).css(a).css({padding:0}).add().attr({y:-9999}),ze||this.label.shadow(n.shadow),this.shared=n.shared},destroy:function(){this.label&&(this.label=this.label.destroy()),clearTimeout(this.hideTimer),clearTimeout(this.tooltipTimeout)},move:function(e,t,n,r){var a=this,o=a.now,i=a.options.animation!==!1&&!a.isHidden&&(_e(e-o.x)>1||_e(t-o.y)>1),s=a.followPointer||a.len>1;it(o,{x:i?(2*o.x+e)/3:e,y:i?(o.y+t)/2:t,anchorX:s?B:i?(2*o.anchorX+n)/3:n,anchorY:s?B:i?(o.anchorY+r)/2:r}),a.label.attr(o),i&&(clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){a&&a.move(e,t,n,r)},32))},hide:function(e){var t,n=this;clearTimeout(this.hideTimer),this.isHidden||(t=this.chart.hoverPoints,this.hideTimer=setTimeout(function(){n.label.fadeOut(),n.isHidden=!0},st(e,this.options.hideDelay,500)))},getAnchor:function(e,t){var n,r,a,o=this.chart,i=o.inverted,s=o.plotTop,l=o.plotLeft,u=0,c=0;return e=d(e),n=e[0].tooltipPos,this.followPointer&&t&&(t.chartX===B&&(t=o.pointer.normalize(t)),n=[t.chartX-o.plotLeft,t.chartY-s]),n||(ht(e,function(e){r=e.series.yAxis,a=e.series.xAxis,u+=e.plotX+(!i&&a?a.left-l:0),c+=(e.plotLow?(e.plotLow+e.plotHigh)/2:e.plotY)+(!i&&r?r.top-s:0)}),u/=e.length,c/=e.length,n=[i?o.plotWidth-c:u,this.shared&&!i&&e.length>1&&t?t.chartY-s:i?o.plotHeight-u:c]),yt(n,me)},getPosition:function(e,t,n){var r,a=this.chart,o=this.distance,i={},s=n.h||0,l=["y",a.chartHeight,t,n.plotY+a.plotTop],u=["x",a.chartWidth,e,n.plotX+a.plotLeft],c=st(n.ttBelow,a.inverted&&!n.negative||!a.inverted&&n.negative),d=function(e,t,n,r){var a=r-o>n,l=t>r+o+n,u=r-o-n,d=r+o;if(c&&l)i[e]=d;else if(!c&&a)i[e]=u;else if(a)i[e]=0>u-s?u:u-s;else{if(!l)return!1;i[e]=d+s+n>t?d:d+s}},p=function(e,t,n,r){return o>r||r>t-o?!1:void(n/2>r?i[e]=1:r>t-n/2?i[e]=t-n-2:i[e]=r-n/2)},f=function(e){var t=l;l=u,u=t,r=e},h=function(){d.apply(0,l)!==!1?p.apply(0,u)!==!1||r||(f(!0),h()):r?i.x=i.y=0:(f(!0),h())};return(a.inverted||this.len>1)&&f(),h(),i},defaultFormatter:function(e){var t,n=this.points||d(this);return t=[e.tooltipFooterHeaderFormatter(n[0])],t=t.concat(e.bodyFormatter(n)),t.push(e.tooltipFooterHeaderFormatter(n[0],!0)),t.join("")},refresh:function(e,t){var n,r,a,o,i,s,l=this,u=l.chart,c=l.label,p=l.options,f={},h=[],m=p.formatter||l.defaultFormatter,g=u.hoverPoints,y=l.shared;clearTimeout(this.hideTimer),l.followPointer=d(e)[0].series.tooltipOptions.followPointer,a=l.getAnchor(e,t),n=a[0],r=a[1],!y||e.series&&e.series.noSharedTooltip?f=e.getLabelConfig():(u.hoverPoints=e,g&&ht(g,function(e){e.setState()}),ht(e,function(e){e.setState(tt),h.push(e.getLabelConfig())}),f={x:e[0].category,y:e[0].y},f.points=h,this.len=h.length,e=e[0]),o=m.call(f,l),s=e.series,this.distance=st(s.tooltipOptions.distance,16),o===!1?this.hide():(l.isHidden&&(Et(c),c.attr("opacity",1).show()),c.attr({text:o}),i=p.borderColor||e.color||s.color||"#606060",c.attr({stroke:i}),l.updatePosition({plotX:n,plotY:r,negative:e.negative,ttBelow:e.ttBelow,h:a[2]||0}),this.isHidden=!1),_t(u,"tooltipRefresh",{text:o,x:n+u.plotLeft,y:r+u.plotTop,borderColor:i})},updatePosition:function(e){var t=this.chart,n=this.label,r=(this.options.positioner||this.getPosition).call(this,n.width,n.height,e);this.move(me(r.x),me(r.y||0),e.plotX+t.plotLeft,e.plotY+t.plotTop)},getXDateFormat:function(e,t,n){var r,a,o,i=t.dateTimeLabelFormats,s=n&&n.closestPointRange,l="01-01 00:00:00.000",u={millisecond:15,second:12,minute:9,hour:6,day:3},c="millisecond";if(s){o=H("%m-%d %H:%M:%S.%L",e.x);for(a in K){if(s===K.week&&+H("%w",e.x)===n.options.startOfWeek&&o.substr(6)===l.substr(6)){a="week";break}if(K[a]>s){a=c;break}if(u[a]&&o.substr(u[a])!==l.substr(u[a]))break;"week"!==a&&(c=a)}a&&(r=i[a])}else r=i.day;return r||i.year},tooltipFooterHeaderFormatter:function(e,t){var n=t?"footer":"header",r=e.series,a=r.tooltipOptions,i=a.xDateFormat,s=r.xAxis,l=s&&"datetime"===s.options.type&&o(e.key),u=a[n+"Format"];return l&&!i&&(i=this.getXDateFormat(e,a,s)),l&&i&&(u=u.replace("{point.key}","{point.key:"+i+"}")),v(u,{point:e,series:r})},bodyFormatter:function(e){return yt(e,function(e){var t=e.series.tooltipOptions;return(t.pointFormatter||e.point.tooltipFormatter).call(e.point,t.pointFormat)})}};var Bt;q=pe.documentElement.ontouchstart!==B;var Lt=de.Pointer=function(e,t){this.init(e,t)};if(Lt.prototype={init:function(e,t){var n,r,a=t.chart,o=a.events,i=ze?"":a.zoomType,s=e.inverted;this.options=t,this.chart=e,this.zoomX=n=/x/.test(i),this.zoomY=r=/y/.test(i),this.zoomHor=n&&!s||r&&s,this.zoomVert=r&&!s||n&&s,this.hasZoom=n||r,this.runChartClick=o&&!!o.click,this.pinchDown=[],this.lastValidTouch={},de.Tooltip&&t.tooltip.enabled&&(e.tooltip=new Rt(e,t.tooltip),this.followTouchMove=st(t.tooltip.followTouchMove,!0)),this.setDOMEvents()},normalize:function(e,t){var n,r,a;return e=e||window.event,e=wt(e),e.target||(e.target=e.srcElement),a=e.touches?e.touches.length?e.touches.item(0):e.changedTouches[0]:e,t||(this.chartPosition=t=gt(this.chart.container)),a.pageX===B?(n=be(e.x,e.clientX-t.left),r=e.y):(n=a.pageX-t.left,r=a.pageY-t.top),it(e,{chartX:me(n),chartY:me(r)})},getCoordinates:function(e){var t={xAxis:[],yAxis:[]};return ht(this.chart.axes,function(n){t[n.isXAxis?"xAxis":"yAxis"].push({axis:n,value:n.toValue(e[n.horiz?"chartX":"chartY"])})}),t},runPointActions:function(e){var t,n,r,a,o,i,s,l=this,u=l.chart,c=u.series,d=u.tooltip,p=d?d.shared:!1,f=u.hoverPoint,h=u.hoverSeries,m=u.chartWidth,g=[];if(!p&&!h)for(n=0;no?o=u:o>u+d&&(o=u+d),c>i?i=c:i>c+p&&(i=c+p),this.hasDragged=Math.sqrt(Math.pow(f-o,2)+Math.pow(h-i,2)),this.hasDragged>10&&(t=r.isInsidePlot(f-u,h-c),r.hasCartesianSeries&&(this.zoomX||this.zoomY)&&t&&!m&&(this.selectionMarker||(this.selectionMarker=r.renderer.rect(u,c,s?1:d,l?1:p,0).attr({fill:a.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add())),this.selectionMarker&&s&&(n=o-f,this.selectionMarker.attr({width:_e(n),x:(n>0?0:n)+f})),this.selectionMarker&&l&&(n=i-h,this.selectionMarker.attr({height:_e(n),y:(n>0?0:n)+h})),t&&!this.selectionMarker&&a.panning&&r.pan(e,a.panning))},drop:function(e){var t=this,n=this.chart,r=this.hasPinched;if(this.selectionMarker){var a,o={xAxis:[],yAxis:[],originalEvent:e.originalEvent||e},i=this.selectionMarker,s=i.attr?i.attr("x"):i.x,l=i.attr?i.attr("y"):i.y,c=i.attr?i.attr("width"):i.width,d=i.attr?i.attr("height"):i.height;(this.hasDragged||r)&&(ht(n.axes,function(n){if(n.zoomEnabled&&u(n.min)&&(r||t[{xAxis:"zoomX",yAxis:"zoomY"}[n.coll]])){var i=n.horiz,p="touchend"===e.type?n.minPixelPadding:0,f=n.toValue((i?s:l)+p),h=n.toValue((i?s+c:l+d)-p);o[n.coll].push({axis:n,min:ve(f,h),max:be(f,h)}),a=!0}}),a&&_t(n,"selection",o,function(e){n.zoom(it(e,r?{animation:!1}:null))})),this.selectionMarker=this.selectionMarker.destroy(),r&&this.scaleGroups()}n&&(p(n.container,{cursor:n._cursor}),n.cancelClick=this.hasDragged>10,n.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[])},onContainerMouseDown:function(e){e=this.normalize(e),e.preventDefault&&e.preventDefault(),this.dragStart(e)},onDocumentMouseUp:function(e){Le[Bt]&&Le[Bt].pointer.drop(e)},onDocumentMouseMove:function(e){var t=this.chart,n=this.chartPosition;e=this.normalize(e,n),!n||this.inClass(e.target,"highcharts-tracker")||t.isInsidePlot(e.chartX-t.plotLeft,e.chartY-t.plotTop)||this.reset()},onContainerMouseLeave:function(){var e=Le[Bt];e&&(e.pointer.reset(),e.pointer.chartPosition=null)},onContainerMouseMove:function(e){var t=this.chart;Bt=t.index,e=this.normalize(e),e.returnValue=!1,"mousedown"===t.mouseIsDown&&this.drag(e),!this.inClass(e.target,"highcharts-tracker")&&!t.isInsidePlot(e.chartX-t.plotLeft,e.chartY-t.plotTop)||t.openMenu||this.runPointActions(e)},inClass:function(e,t){for(var n;e;){if(n=c(e,"class")){if(-1!==n.indexOf(t))return!0;if(-1!==n.indexOf(Ge+"container"))return!1}e=e.parentNode}},onTrackerMouseOut:function(e){var t=this.chart.hoverSeries,n=e.relatedTarget||e.toElement,r=n&&n.point&&n.point.series;!t||t.options.stickyTracking||this.inClass(n,Ge+"tooltip")||r===t||t.onMouseOut()},onContainerClick:function(e){var t=this.chart,n=t.hoverPoint,r=t.plotLeft,a=t.plotTop;e=this.normalize(e),e.originalEvent=e,t.cancelClick||(n&&this.inClass(e.target,Ge+"tracker")?(_t(n.series,"click",it(e,{point:n})),t.hoverPoint&&n.firePointEvent("click",e)):(it(e,this.getCoordinates(e)),t.isInsidePlot(e.chartX-r,e.chartY-a)&&_t(t,"click",e)))},setDOMEvents:function(){var e=this,t=e.chart.container;t.onmousedown=function(t){e.onContainerMouseDown(t)},t.onmousemove=function(t){e.onContainerMouseMove(t)},t.onclick=function(t){e.onContainerClick(t)},bt(t,"mouseleave",e.onContainerMouseLeave),1===qe&&bt(pe,"mouseup",e.onDocumentMouseUp),q&&(t.ontouchstart=function(t){e.onContainerTouchStart(t)},t.ontouchmove=function(t){e.onContainerTouchMove(t)},1===qe&&bt(pe,"touchend",e.onDocumentTouchEnd))},destroy:function(){var e;vt(this.chart.container,"mouseleave",this.onContainerMouseLeave),qe||(vt(pe,"mouseup",this.onDocumentMouseUp),vt(pe,"touchend",this.onDocumentTouchEnd)),clearInterval(this.tooltipTimeout);for(e in this)this[e]=null}},it(de.Pointer.prototype,{pinchTranslate:function(e,t,n,r,a,o){(this.zoomHor||this.pinchHor)&&this.pinchTranslateDirection(!0,e,t,n,r,a,o),(this.zoomVert||this.pinchVert)&&this.pinchTranslateDirection(!1,e,t,n,r,a,o)},pinchTranslateDirection:function(e,t,n,r,a,o,i,s){var l,u,c,d,p,f,h=this.chart,m=e?"x":"y",g=e?"X":"Y",y="chart"+g,b=e?"width":"height",v=h["plot"+(e?"Left":"Top")],_=s||1,w=h.inverted,k=h.bounds[e?"h":"v"],E=1===t.length,x=t[0][y],O=n[0][y],S=!E&&t[1][y],P=!E&&n[1][y],A=function(){!E&&_e(x-S)>20&&(_=s||_e(O-P)/_e(x-S)),c=(v-O)/_+x,l=h["plot"+(e?"Width":"Height")]/_};A(),u=c,uk.max&&(u=k.max-l,d=!0),d?(O-=.8*(O-i[m][0]),E||(P-=.8*(P-i[m][1])),A()):i[m]=[O,P],w||(o[m]=c-v,o[b]=l),f=w?e?"scaleY":"scaleX":"scale"+g,p=w?1/_:_,a[b]=l,a[m]=u,r[f]=_,r["translate"+g]=p*v+(O-p*x)},pinch:function(e){var t=this,n=t.chart,r=t.pinchDown,a=e.touches,o=a.length,i=t.lastValidTouch,s=t.hasZoom,l=t.selectionMarker,u={},c=1===o&&(t.inClass(e.target,Ge+"tracker")&&n.runTrackerClick||t.runChartClick),d={};o>1&&(t.initiated=!0),s&&t.initiated&&!c&&e.preventDefault(),yt(a,function(e){return t.normalize(e)}),"touchstart"===e.type?(ht(a,function(e,t){r[t]={chartX:e.chartX,chartY:e.chartY}}),i.x=[r[0].chartX,r[1]&&r[1].chartX],i.y=[r[0].chartY,r[1]&&r[1].chartY],ht(n.axes,function(e){if(e.zoomEnabled){var t=n.bounds[e.horiz?"h":"v"],r=e.minPixelPadding,a=e.toPixels(st(e.options.min,e.dataMin)),o=e.toPixels(st(e.options.max,e.dataMax)),i=ve(a,o),s=be(a,o);t.min=ve(e.pos,i-r),t.max=be(e.pos+e.len,s+r)}}),t.res=!0):r.length&&(l||(t.selectionMarker=l=it({destroy:Be},n.plotBox)),t.pinchTranslate(r,a,u,l,d,i),t.hasPinched=s,t.scaleGroups(u,d),!s&&t.followTouchMove&&1===o?this.runPointActions(t.normalize(e)):t.res&&(t.res=!1,this.reset(!1,0)))},touch:function(e,t){var n=this.chart;Bt=n.index,1===e.touches.length?(e=this.normalize(e),n.isInsidePlot(e.chartX-n.plotLeft,e.chartY-n.plotTop)&&!n.openMenu?(t&&this.runPointActions(e),this.pinch(e)):t&&this.reset()):2===e.touches.length&&this.pinch(e)},onContainerTouchStart:function(e){this.touch(e,!0)},onContainerTouchMove:function(e){this.touch(e)},onDocumentTouchEnd:function(e){Le[Bt]&&Le[Bt].pointer.drop(e)}}),fe.PointerEvent||fe.MSPointerEvent){var qt={},Ft=!!fe.PointerEvent,Ut=function(){var e,t=[];t.item=function(e){return this[e]};for(e in qt)qt.hasOwnProperty(e)&&t.push({pageX:qt[e].pageX,pageY:qt[e].pageY,target:qt[e].target});return t},Ht=function(e,t,n,r){var a;e=e.originalEvent||e,"touch"!==e.pointerType&&e.pointerType!==e.MSPOINTER_TYPE_TOUCH||!Le[Bt]||(r(e),a=Le[Bt].pointer,a[t]({type:n,target:e.currentTarget,preventDefault:Be,touches:Ut()}))};it(Lt.prototype,{onContainerPointerDown:function(e){Ht(e,"onContainerTouchStart","touchstart",function(e){qt[e.pointerId]={pageX:e.pageX,pageY:e.pageY,target:e.currentTarget}})},onContainerPointerMove:function(e){Ht(e,"onContainerTouchMove","touchmove",function(e){qt[e.pointerId]={pageX:e.pageX,pageY:e.pageY},qt[e.pointerId].target||(qt[e.pointerId].target=e.currentTarget)})},onDocumentPointerUp:function(e){Ht(e,"onDocumentTouchEnd","touchend",function(e){delete qt[e.pointerId]})},batchMSEvents:function(e){e(this.chart.container,Ft?"pointerdown":"MSPointerDown",this.onContainerPointerDown),e(this.chart.container,Ft?"pointermove":"MSPointerMove",this.onContainerPointerMove),e(pe,Ft?"pointerup":"MSPointerUp",this.onDocumentPointerUp)}}),lt(Lt.prototype,"init",function(e,t,n){e.call(this,t,n),this.hasZoom&&p(t.container,{"-ms-touch-action":Je,"touch-action":Je})}),lt(Lt.prototype,"setDOMEvents",function(e){e.apply(this),(this.hasZoom||this.followTouchMove)&&this.batchMSEvents(bt)}),lt(Lt.prototype,"destroy",function(e){this.batchMSEvents(vt),e.call(this)})}var Wt=de.Legend=function(e,t){this.init(e,t)};Wt.prototype={init:function(t,n){var r,a=this,o=n.itemStyle,i=n.itemMarginTop||0;this.options=n,n.enabled&&(a.itemStyle=o,a.itemHiddenStyle=e(o,n.itemHiddenStyle),a.itemMarginTop=i,a.padding=r=st(n.padding,8),a.initialItemX=r,a.initialItemY=r-5,a.maxItemWidth=0,a.chart=t,a.itemHeight=0,a.symbolWidth=st(n.symbolWidth,16),a.pages=[],a.render(),bt(a.chart,"endResize",function(){a.positionCheckboxes()}))},colorizeItem:function(e,t){var n,r,a=this,o=a.options,i=e.legendItem,s=e.legendLine,l=e.legendSymbol,u=a.itemHiddenStyle.color,c=t?o.itemStyle.color:u,d=t?e.legendColor||e.color||"#CCC":u,p=e.options&&e.options.marker,f={fill:d};if(i&&i.css({fill:c,color:c}),s&&s.attr({stroke:d}),l){if(p&&l.isMarker){f.stroke=d,p=e.convertAttribs(p);for(n in p)r=p[n],r!==B&&(f[n]=r)}l.attr(f)}},positionItem:function(e){var t=this,n=t.options,r=n.symbolPadding,a=!n.rtl,o=e._legendItemPos,i=o[0],s=o[1],l=e.checkbox,u=e.legendGroup;u&&u.element&&u.translate(a?i:t.legendWidth-i-2*r-4,s),l&&(l.x=i,l.y=s)},destroyItem:function(e){var t=e.checkbox;ht(["legendItem","legendLine","legendSymbol","legendGroup"],function(t){e[t]&&(e[t]=e[t].destroy())}),t&&S(e.checkbox)},destroy:function(){var e=this,t=e.group,n=e.box;n&&(e.box=n.destroy()),t&&(e.group=t.destroy())},positionCheckboxes:function(e){var t,n=this.group.alignAttr,r=this.clipHeight||this.legendHeight;n&&(t=n.translateY,ht(this.allItems,function(a){var o,i=a.checkbox;i&&(o=t+i.y+(e||0)+3,p(i,{left:n.translateX+a.checkboxOffset+i.x-20+Xe,top:o+Xe,display:o>t-6&&t+r-6>o?"":Je}))}))},renderTitle:function(){var e,t=this.options,n=this.padding,r=t.title,a=0;r.text&&(this.title||(this.title=this.chart.renderer.label(r.text,n-3,n-4,null,null,null,null,null,"legend-title").attr({zIndex:1}).css(r.style).add(this.group)),e=this.title.getBBox(),a=e.height,this.offsetWidth=e.width,this.contentGroup.attr({translateY:a})),this.titleHeight=a},setText:function(e){var t=this.options;e.legendItem.attr({text:t.labelFormat?v(t.labelFormat,e):t.labelFormatter.call(e)})},renderItem:function(t){var n,r,a,o=this,i=o.chart,s=i.renderer,l=o.options,u="horizontal"===l.layout,c=o.symbolWidth,d=l.symbolPadding,p=o.itemStyle,f=o.itemHiddenStyle,h=o.padding,m=u?st(l.itemDistance,20):0,g=!l.rtl,y=l.width,b=l.itemMarginBottom||0,v=o.itemMarginTop,_=o.initialItemX,w=t.legendItem,k=t.series&&t.series.drawLegendSymbol?t.series:t,E=k.options,x=o.createCheckboxForItem&&E&&E.showCheckbox,O=l.useHTML;w||(t.legendGroup=s.g("legend-item").attr({zIndex:1}).add(o.scrollGroup),t.legendItem=w=s.text("",g?c+d:-d,o.baseline||0,O).css(e(t.visible?p:f)).attr({align:g?"left":"right",zIndex:2}).add(t.legendGroup),o.baseline||(o.fontMetrics=s.fontMetrics(p.fontSize,w),o.baseline=o.fontMetrics.f+3+v,w.attr("y",o.baseline)),k.drawLegendSymbol(o,t),o.setItemEvents&&o.setItemEvents(t,w,O,p,f),o.colorizeItem(t,t.visible),x&&o.createCheckboxForItem(t)),o.setText(t),r=w.getBBox(),a=t.checkboxOffset=l.itemWidth||t.legendItemWidth||c+d+r.width+m+(x?20:0),o.itemHeight=n=me(t.legendItemHeight||r.height),u&&o.itemX-_+a>(y||i.chartWidth-2*h-_-l.x)&&(o.itemX=_,o.itemY+=v+o.lastLineHeight+b,o.lastLineHeight=0),o.maxItemWidth=be(o.maxItemWidth,a),o.lastItemY=v+o.itemY+b,o.lastLineHeight=be(n,o.lastLineHeight),t._legendItemPos=[o.itemX,o.itemY],u?o.itemX+=a:(o.itemY+=v+n+b,o.lastLineHeight=n),o.offsetWidth=y||be((u?o.itemX-_-m:a)+h,o.offsetWidth)},getAllItems:function(){var e=[];return ht(this.chart.series,function(t){var n=t.options;st(n.showInLegend,u(n.linkedTo)?!1:B,!0)&&(e=e.concat(t.legendItems||("point"===n.legendType?t.data:t)))}),e},adjustMargins:function(e,t){var n=this.chart,r=this.options,a=r.align[0]+r.verticalAlign[0]+r.layout[0];this.display&&!r.floating&&ht([/(lth|ct|rth)/,/(rtv|rm|rbv)/,/(rbh|cb|lbh)/,/(lbv|lm|ltv)/],function(o,i){o.test(a)&&!u(e[i])&&(n[rt[i]]=be(n[rt[i]],n.legend[(i+1)%2?"legendHeight":"legendWidth"]+[1,-1,-1,1][i]*r[i%2?"x":"y"]+st(r.margin,12)+t[i]))})},render:function(){var e,t,n,r,a=this,o=a.chart,i=o.renderer,s=a.group,l=a.box,u=a.options,c=a.padding,d=u.borderWidth,p=u.backgroundColor;a.itemX=a.initialItemX,a.itemY=a.initialItemY,a.offsetWidth=0,a.lastItemY=0,s||(a.group=s=i.g("legend").attr({zIndex:7}).add(),a.contentGroup=i.g().attr({zIndex:1}).add(s),a.scrollGroup=i.g().add(a.contentGroup)),a.renderTitle(),e=a.getAllItems(),k(e,function(e,t){return(e.options&&e.options.legendIndex||0)-(t.options&&t.options.legendIndex||0)}),u.reversed&&e.reverse(),a.allItems=e,a.display=t=!!e.length,a.lastLineHeight=0,ht(e,function(e){a.renderItem(e)}),n=(u.width||a.offsetWidth)+c,r=a.lastItemY+a.lastLineHeight+a.titleHeight,r=a.handleOverflow(r),r+=c,(d||p)&&(l?n>0&&r>0&&(l[l.isNew?"attr":"animate"](l.crisp({width:n,height:r})),l.isNew=!1):(a.box=l=i.rect(0,0,n,r,u.borderRadius,d||0).attr({stroke:u.borderColor,"stroke-width":d||0,fill:p||Je}).add(s).shadow(u.shadow),l.isNew=!0),l[t?"show":"hide"]()),a.legendWidth=n,a.legendHeight=r,ht(e,function(e){a.positionItem(e)}),t&&s.align(it({width:n,height:r},u),!0,"spacingBox"),o.isResizing||this.positionCheckboxes()},handleOverflow:function(e){var t,n,r=this,a=this.chart,o=a.renderer,i=this.options,s=i.y,l="top"===i.verticalAlign,u=a.spacingBox.height+(l?-s:s)-this.padding,c=i.maxHeight,d=this.clipRect,p=i.navigation,f=st(p.animation,!0),h=p.arrowSize||12,m=this.nav,g=this.pages,y=this.padding,b=this.allItems,v=function(e){d.attr({height:e}),r.contentGroup.div&&(r.contentGroup.div.style.clip="rect("+y+"px,9999px,"+(y+e)+"px,0)"); +};return"horizontal"===i.layout&&(u/=2),c&&(u=ve(u,c)),g.length=0,e>u?(this.clipHeight=t=be(u-20-this.titleHeight-y,0),this.currentPage=st(this.currentPage,1),this.fullHeight=e,ht(b,function(e,r){var a=e._legendItemPos[1],o=me(e.legendItem.getBBox().height),i=g.length;(!i||a-g[i-1]>t&&(n||a)!==g[i-1])&&(g.push(n||a),i++),r===b.length-1&&a+o-g[i-1]>t&&g.push(a),a!==n&&(n=a)}),d||(d=r.clipRect=o.clipRect(0,y,9999,0),r.contentGroup.clip(d)),v(t),m||(this.nav=m=o.g().attr({zIndex:1}).add(this.group),this.up=o.symbol("triangle",0,0,h,h).on("click",function(){r.scroll(-1,f)}).add(m),this.pager=o.text("",15,10).css(p.style).add(m),this.down=o.symbol("triangle-down",0,0,h,h).on("click",function(){r.scroll(1,f)}).add(m)),r.scroll(0),e=u):m&&(v(a.chartHeight),m.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0),e},scroll:function(e,t){var n,r=this.pages,a=r.length,o=this.currentPage+e,i=this.clipHeight,s=this.options.navigation,l=s.activeColor,u=s.inactiveColor,c=this.pager,d=this.padding;o>a&&(o=a),o>0&&(t!==B&&j(t,this.chart),this.nav.attr({translateX:d,translateY:i+this.padding+7+this.titleHeight,visibility:Ye}),this.up.attr({fill:1===o?u:l}).css({cursor:1===o?"default":"pointer"}),c.attr({text:o+"/"+a}),this.down.attr({x:18+this.pager.getBBox().width,fill:o===a?u:l}).css({cursor:o===a?"default":"pointer"}),n=-r[o-1]+this.initialItemY,this.scrollGroup.animate({translateY:n}),this.currentPage=o,this.positionCheckboxes(n))}};var Vt=de.LegendSymbolMixin={drawRectangle:function(e,t){var n=e.options.symbolHeight||e.fontMetrics.f;t.legendSymbol=this.chart.renderer.rect(0,e.baseline-n+1,e.symbolWidth,n,e.options.symbolRadius||0).attr({zIndex:3}).add(t.legendGroup)},drawLineMarker:function(e){var t,n,r,a=this.options,o=a.marker,i=e.symbolWidth,s=this.chart.renderer,l=this.legendGroup,u=e.baseline-me(.3*e.fontMetrics.b);a.lineWidth&&(r={"stroke-width":a.lineWidth},a.dashStyle&&(r.dashstyle=a.dashStyle),this.legendLine=s.path([$e,0,u,Ze,i,u]).attr(r).add(l)),o&&o.enabled!==!1&&(t=o.radius,this.legendSymbol=n=s.symbol(this.symbol,i/2-t,u-t,2*t,2*t).add(l),n.isMarker=!0)}};(/Trident\/7\.0/.test(Oe)||Ce)&<(Wt.prototype,"positionItem",function(e,t){var n=this,r=function(){t._legendItemPos&&e.call(n,t)};r(),setTimeout(r)});var Kt=de.Chart=function(){this.init.apply(this,arguments)};Kt.prototype={callbacks:[],init:function(t,n){var r,a=t.series;t.series=null,r=e(U,t),r.series=t.series=a,this.userOptions=t;var o=r.chart;this.margin=this.splashArray("margin",o),this.spacing=this.splashArray("spacing",o);var i=o.events;this.bounds={h:{},v:{}},this.callback=n,this.isResizing=0,this.options=r,this.axes=[],this.series=[],this.hasCartesianSeries=o.showAxes;var s,l=this;if(l.index=Le.length,Le.push(l),qe++,o.reflow!==!1&&bt(l,"load",function(){l.initReflow()}),i)for(s in i)bt(l,s,i[s]);l.xAxis=[],l.yAxis=[],l.animation=ze?!1:st(o.animation,!0),l.pointCount=l.colorCounter=l.symbolCounter=0,l.firstRender()},initSeries:function(e){var t,n=this,r=n.options.chart,a=e.type||r.type||r.defaultSeriesType,o=ot[a];return o||P(17,!0),t=new o,t.init(this,e),t},isInsidePlot:function(e,t,n){var r=n?t:e,a=n?e:t;return r>=0&&r<=this.plotWidth&&a>=0&&a<=this.plotHeight},redraw:function(e){var t,n,r,a=this,o=a.axes,i=a.series,s=a.pointer,l=a.legend,u=a.isDirtyLegend,c=a.hasCartesianSeries,d=a.isDirtyBox,p=i.length,f=p,h=a.renderer,m=h.isHidden(),g=[];for(j(e,a),m&&a.cloneRenderTo(),a.layOutTitles();f--;)if(r=i[f],r.options.stacking&&(t=!0,r.isDirty)){n=!0;break}if(n)for(f=p;f--;)r=i[f],r.options.stacking&&(r.isDirty=!0);ht(i,function(e){e.isDirty&&"point"===e.options.legendType&&(e.updateTotals&&e.updateTotals(),u=!0)}),u&&l.options.enabled&&(l.render(),a.isDirtyLegend=!1),t&&a.getStacks(),c&&(a.isResizing||(a.maxTicks=null,ht(o,function(e){e.setScale()}))),a.getMargins(),c&&(ht(o,function(e){e.isDirty&&(d=!0)}),ht(o,function(e){e.isDirtyExtremes&&(e.isDirtyExtremes=!1,g.push(function(){_t(e,"afterSetExtremes",it(e.eventArgs,e.getExtremes())),delete e.eventArgs})),(d||t)&&e.redraw()})),d&&a.drawChartBox(),ht(i,function(e){e.isDirty&&e.visible&&(!e.isCartesian||e.xAxis)&&e.redraw()}),s&&s.reset(!0),h.draw(),_t(a,"redraw"),m&&a.cloneRenderTo(!0),ht(g,function(e){e.call()})},get:function(e){var t,n,r,a=this,o=a.axes,i=a.series;for(t=0;t19?e.containerHeight:400))},cloneRenderTo:function(e){var t=this.renderToClone,n=this.container;e?t&&(this.renderTo.appendChild(n),S(t),delete this.renderToClone):(n&&n.parentNode===this.renderTo&&this.renderTo.removeChild(n),this.renderToClone=t=this.renderTo.cloneNode(0),p(t,{position:We,top:"-9999px",display:"block"}),t.style.setProperty&&t.style.setProperty("display","block","important"),pe.body.appendChild(t),n&&t.appendChild(n))},getContainer:function(){var e,r,a,o,i,s,l=this,u=l.options.chart,d="data-highcharts-chart";l.renderTo=o=u.renderTo,s=Ge+Re++,n(o)&&(l.renderTo=o=pe.getElementById(o)),o||P(13,!0),i=t(c(o,d)),!isNaN(i)&&Le[i]&&Le[i].hasRendered&&Le[i].destroy(),c(o,d,l.index),o.innerHTML="",u.skipClone||o.offsetWidth||l.cloneRenderTo(),l.getChartSize(),r=l.chartWidth,a=l.chartHeight,l.container=e=f(He,{className:Ge+"container"+(u.className?" "+u.className:""),id:s},it({position:Ve,overflow:Ke,width:r+Xe,height:a+Xe,textAlign:"left",lineHeight:"normal",zIndex:0,"-webkit-tap-highlight-color":"rgba(0,0,0,0)"},u.style),l.renderToClone||o),l._cursor=e.style.cursor,l.renderer=u.forExport?new Ct(e,r,a,u.style,!0):new L(e,r,a,u.style),ze&&l.renderer.create(l,e,r,a),l.renderer.chartIndex=l.index},getMargins:function(e){var t=this,n=t.spacing,r=t.margin,a=t.titleOffset;t.resetMargins(),a&&!u(r[0])&&(t.plotTop=be(t.plotTop,a+t.options.title.margin+n[0])),t.legend.adjustMargins(r,n),t.extraBottomMargin&&(t.marginBottom+=t.extraBottomMargin),t.extraTopMargin&&(t.plotTop+=t.extraTopMargin),e||this.getAxisMargins()},getAxisMargins:function(){var e=this,t=e.axisOffset=[0,0,0,0],n=e.margin;e.hasCartesianSeries&&ht(e.axes,function(e){e.getOffset()}),ht(rt,function(r,a){u(n[a])||(e[r]+=t[a])}),e.setChartSize()},reflow:function(e){var t=this,n=t.options.chart,r=t.renderTo,a=n.width||dt(r,"width"),o=n.height||dt(r,"height"),i=e?e.target:fe,s=function(){t.container&&(t.setSize(a,o,!1),t.hasUserSize=null)};t.hasUserSize||t.isPrinting||!a||!o||i!==fe&&i!==pe||((a!==t.containerWidth||o!==t.containerHeight)&&(clearTimeout(t.reflowTimeout),e?t.reflowTimeout=setTimeout(s,100):s()),t.containerWidth=a,t.containerHeight=o)},initReflow:function(){var e=this,t=function(t){e.reflow(t)};bt(fe,"resize",t),bt(e,"destroy",function(){vt(fe,"resize",t)})},setSize:function(e,t,n){var r,a,o,i=this;i.isResizing+=1,o=function(){i&&_t(i,"endResize",null,function(){i.isResizing-=1})},j(n,i),i.oldChartHeight=i.chartHeight,i.oldChartWidth=i.chartWidth,u(e)&&(i.chartWidth=r=be(0,me(e)),i.hasUserSize=!!r),u(t)&&(i.chartHeight=a=be(0,me(t))),(W?kt:p)(i.container,{width:r+Xe,height:a+Xe},W),i.setChartSize(!0),i.renderer.setSize(r,a,n),i.maxTicks=null,ht(i.axes,function(e){e.isDirty=!0,e.setScale()}),ht(i.series,function(e){e.isDirty=!0}),i.isDirtyLegend=!0,i.isDirtyBox=!0,i.layOutTitles(),i.getMargins(),i.redraw(n),i.oldChartHeight=null,_t(i,"resize"),W===!1?o():setTimeout(o,W&&W.duration||500)},setChartSize:function(e){var t,n,r,a,o,i,s,l=this,u=l.inverted,c=l.renderer,d=l.chartWidth,p=l.chartHeight,f=l.options.chart,h=l.spacing,m=l.clipOffset;l.plotLeft=r=me(l.plotLeft),l.plotTop=a=me(l.plotTop),l.plotWidth=o=be(0,me(d-r-l.marginRight)),l.plotHeight=i=be(0,me(p-a-l.marginBottom)),l.plotSizeX=u?i:o,l.plotSizeY=u?o:i,l.plotBorderWidth=f.plotBorderWidth||0,l.spacingBox=c.spacingBox={x:h[3],y:h[0],width:d-h[3]-h[1],height:p-h[0]-h[2]},l.plotBox=c.plotBox={x:r,y:a,width:o,height:i},s=2*ge(l.plotBorderWidth/2),t=ye(be(s,m[3])/2),n=ye(be(s,m[0])/2),l.clipBox={x:t,y:n,width:ge(l.plotSizeX-be(s,m[1])/2-t),height:be(0,ge(l.plotSizeY-be(s,m[2])/2-n))},e||ht(l.axes,function(e){e.setAxisSize(),e.setAxisTranslation()})},resetMargins:function(){var e=this;ht(rt,function(t,n){e[t]=st(e.margin[n],e.spacing[n])}),e.axisOffset=[0,0,0,0],e.clipOffset=[0,0,0,0]},drawChartBox:function(){var e,t,n=this,r=n.options.chart,a=n.renderer,o=n.chartWidth,i=n.chartHeight,s=n.chartBackground,l=n.plotBackground,u=n.plotBorder,c=n.plotBGImage,d=r.borderWidth||0,p=r.backgroundColor,f=r.plotBackgroundColor,h=r.plotBackgroundImage,m=r.plotBorderWidth||0,g=n.plotLeft,y=n.plotTop,b=n.plotWidth,v=n.plotHeight,_=n.plotBox,w=n.clipRect,k=n.clipBox;e=d+(r.shadow?8:0),(d||p)&&(s?s.animate(s.crisp({width:o-e,height:i-e})):(t={fill:p||Je},d&&(t.stroke=r.borderColor,t["stroke-width"]=d),n.chartBackground=a.rect(e/2,e/2,o-e,i-e,r.borderRadius,d).attr(t).addClass(Ge+"background").add().shadow(r.shadow))),f&&(l?l.animate(_):n.plotBackground=a.rect(g,y,b,v,0).attr({fill:f}).add().shadow(r.plotShadow)),h&&(c?c.animate(_):n.plotBGImage=a.image(h,g,y,b,v).add()),w?w.animate({width:k.width,height:k.height}):n.clipRect=a.clipRect(k),m&&(u?u.animate(u.crisp({x:g,y:y,width:b,height:v,strokeWidth:-m})):n.plotBorder=a.rect(g,y,b,v,0,-m).attr({stroke:r.plotBorderColor,"stroke-width":m,fill:Je,zIndex:1}).add()),n.isDirtyBox=!1},propFromSeries:function(){var e,t,n,r=this,a=r.options.chart,o=r.options.series;ht(["inverted","angular","polar"],function(i){for(e=ot[a.type||a.defaultSeriesType],n=r[i]||a[i]||e&&e.prototype[i],t=o&&o.length;!n&&t--;)e=ot[o[t].type],e&&e.prototype[i]&&(n=!0);r[i]=n})},linkSeries:function(){var e=this,t=e.series;ht(t,function(e){e.linkedSeries.length=0}),ht(t,function(t){var r=t.options.linkedTo;n(r)&&(r=":previous"===r?e.series[t.index-1]:e.get(r),r&&(r.linkedSeries.push(t),t.linkedParent=r))})},renderSeries:function(){ht(this.series,function(e){e.translate(),e.render()})},renderLabels:function(){var e=this,n=e.options.labels;n.items&&ht(n.items,function(r){var a=it(n.style,r.style),o=t(a.left)+e.plotLeft,i=t(a.top)+e.plotTop+12;delete a.left,delete a.top,e.renderer.text(r.html,o,i).attr({zIndex:2}).css(a).add()})},render:function(){var e,t,n,r,a=this,o=a.axes,i=a.renderer,s=a.options;a.setTitle(),a.legend=new Wt(a,s.legend),a.getStacks(),a.getMargins(!0),a.setChartSize(),e=a.plotWidth,t=a.plotHeight=a.plotHeight-13,ht(o,function(e){e.setScale()}),a.getAxisMargins(),n=e/a.plotWidth>1.1,r=t/a.plotHeight>1.1,(n||r)&&(a.maxTicks=null,ht(o,function(e){(e.horiz&&n||!e.horiz&&r)&&e.setTickInterval(!0)}),a.getMargins()),a.drawChartBox(),a.hasCartesianSeries&&ht(o,function(e){e.render()}),a.seriesGroup||(a.seriesGroup=i.g("series-group").attr({zIndex:3}).add()),a.renderSeries(),a.renderLabels(),a.showCredits(s.credits),a.hasRendered=!0},showCredits:function(e){e.enabled&&!this.credits&&(this.credits=this.renderer.text(e.text,0,0).on("click",function(){e.href&&(location.href=e.href)}).attr({align:e.position.align,zIndex:8}).css(e.style).add().align(e.position))},destroy:function(){var e,t=this,n=t.axes,r=t.series,a=t.container,o=a&&a.parentNode;for(_t(t,"destroy"),Le[t.index]=B,qe--,t.renderTo.removeAttribute("data-highcharts-chart"),vt(t),e=n.length;e--;)n[e]=n[e].destroy();for(e=r.length;e--;)r[e]=r[e].destroy();ht(["title","subtitle","chartBackground","plotBackground","plotBGImage","plotBorder","seriesGroup","clipRect","credits","pointer","scroller","rangeSelector","legend","resetZoomButton","tooltip","renderer"],function(e){var n=t[e];n&&n.destroy&&(t[e]=n.destroy())}),a&&(a.innerHTML="",vt(a),o&&S(a));for(e in t)delete t[e]},isReadyToRender:function(){var e=this;return!Me&&fe==fe.top&&"complete"!==pe.readyState||ze&&!fe.canvg?(ze?zt.push(function(){e.firstRender()},e.options.global.canvasToolsURL):pe.attachEvent("onreadystatechange",function(){pe.detachEvent("onreadystatechange",e.firstRender),"complete"===pe.readyState&&e.firstRender()}),!1):!0},firstRender:function(){var e=this,t=e.options,n=e.callback;e.isReadyToRender()&&(e.getContainer(),_t(e,"init"),e.resetMargins(),e.setChartSize(),e.propFromSeries(),e.getAxes(),ht(t.series||[],function(t){e.initSeries(t)}),e.linkSeries(),_t(e,"beforeRender"),de.Pointer&&(e.pointer=new Lt(e,t)),e.render(),e.renderer.draw(),n&&n.apply(e,[e]),ht(e.callbacks,function(t){e.index!==B&&t.apply(e,[e])}),_t(e,"load"),e.cloneRenderTo(!0))},splashArray:function(e,t){var n=t[e],a=r(n)?n:[n,n,n,n];return[st(t[e+"Top"],a[0]),st(t[e+"Right"],a[1]),st(t[e+"Bottom"],a[2]),st(t[e+"Left"],a[3])]}};var Gt=de.CenteredSeriesMixin={getCenter:function(){var e,t,n,r=this.options,a=this.chart,o=2*(r.slicedOffset||0),i=a.plotWidth-2*o,s=a.plotHeight-2*o,l=r.center,u=[st(l[0],"50%"),st(l[1],"50%"),r.size||"100%",r.innerSize||0],c=ve(i,s);for(t=0;4>t;++t)n=u[t],e=2>t||2===t&&/%$/.test(n),u[t]=g(n,[i,s,c,u[2]][t])+(e?o:0);return u}},Yt=function(){};Yt.prototype={init:function(e,t,n){var r,a=this;return a.series=e,a.color=e.color,a.applyOptions(t,n),a.pointAttr={},e.options.colorByPoint&&(r=e.options.colors||e.chart.options.colors,a.color=a.color||r[e.colorCounter++],e.colorCounter===r.length&&(e.colorCounter=0)),e.chart.pointCount++,a},applyOptions:function(e,t){var n=this,r=n.series,a=r.options.pointValKey||r.pointValKey;return e=Yt.prototype.optionsToObject.call(this,e),it(n,e),n.options=n.options?it(n.options,e):e,a&&(n.y=n[a]),n.x===B&&r&&(n.x=t===B?r.autoIncrement():t),n},optionsToObject:function(e){var t,n={},r=this.series,o=r.options.keys,i=o||r.pointArrayMap||["y"],s=i.length,l=0,u=0;if("number"==typeof e||null===e)n[i[0]]=e;else if(a(e))for(!o&&e.length>s&&(t=typeof e[0],"string"===t?n.name=e[0]:"number"===t&&(n.x=e[0]),l++);s>u;)n[i[u++]]=e[l++];else"object"==typeof e&&(n=e,e.dataLabels&&(r._hasPointLabels=!0),e.marker&&(r._hasPointMarkers=!0));return n},destroy:function(){var e,t=this,n=t.series,r=n.chart,a=r.hoverPoints;r.pointCount--,a&&(t.setState(),l(a,t),a.length||(r.hoverPoints=null)),t===r.hoverPoint&&t.onMouseOut(),(t.graphic||t.dataLabel)&&(vt(t),t.destroyElements()),t.legendItem&&r.legend.destroyItem(t);for(e in t)t[e]=null},destroyElements:function(){for(var e,t=this,n=["graphic","dataLabel","dataLabelUpper","group","connector","shadowGroup"],r=6;r--;)e=n[r],t[e]&&(t[e]=t[e].destroy())},getLabelConfig:function(){var e=this;return{x:e.category,y:e.y,key:e.name||e.category,series:e.series,point:e,percentage:e.percentage,total:e.total||e.stackTotal}},tooltipFormatter:function(e){var t=this.series,n=t.tooltipOptions,r=st(n.valueDecimals,""),a=n.valuePrefix||"",o=n.valueSuffix||"";return ht(t.pointArrayMap||["y"],function(t){t="{point."+t,(a||o)&&(e=e.replace(t+"}",a+t+"}"+o)),e=e.replace(t+"}",t+":,."+r+"f}")}),v(e,{point:this,series:this.series})},firePointEvent:function(e,t,n){var r=this,a=this.series,o=a.options;(o.point.events[e]||r.options&&r.options.events&&r.options.events[e])&&this.importEvents(),"click"===e&&o.allowPointSelect&&(n=function(e){r.select&&r.select(null,e.ctrlKey||e.metaKey||e.shiftKey)}),_t(this,e,t,n)}};var Xt=de.Series=function(){};Xt.prototype={isCartesian:!0,type:"line",pointClass:Yt,sorted:!0,requireSorting:!0,pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",fill:"fillColor",r:"radius"},axisTypes:["xAxis","yAxis"],colorCounter:0,parallelArrays:["x","y"],init:function(e,t){var n,r,a=this,o=e.series,i=function(e,t){return st(e.options.index,e._i)-st(t.options.index,t._i)};a.chart=e,a.options=t=a.setOptions(t),a.linkedSeries=[],a.bindAxes(),it(a,{name:t.name,state:et,pointAttr:{},visible:t.visible!==!1,selected:t.selected===!0}),ze&&(t.animation=!1),r=t.events;for(n in r)bt(a,n,r[n]);(r&&r.click||t.point&&t.point.events&&t.point.events.click||t.allowPointSelect)&&(e.runTrackerClick=!0),a.getColor(),a.getSymbol(),ht(a.parallelArrays,function(e){a[e+"Data"]=[]}),a.setData(t.data,!1),a.isCartesian&&(e.hasCartesianSeries=!0),o.push(a),a._i=o.length-1,k(o,i),this.yAxis&&k(this.yAxis.series,i),ht(o,function(e,t){e.index=t,e.name=e.name||"Series "+(t+1)})},bindAxes:function(){var e,t=this,n=t.options,r=t.chart;ht(t.axisTypes||[],function(a){ht(r[a],function(r){e=r.options,(n[a]===e.index||n[a]!==B&&n[a]===e.id||n[a]===B&&0===e.index)&&(r.series.push(t),t[a]=r,r.isDirty=!0)}),t[a]||t.optionalAxis===a||P(18,!0)})},updateParallelArrays:function(e,t){var n=e.series,r=arguments,a="number"==typeof t?function(r){var a="y"===r&&n.toYData?n.toYData(e):e[r];n[r+"Data"][t]=a}:function(e){Array.prototype[t].apply(n[e+"Data"],Array.prototype.slice.call(r,2))};ht(n.parallelArrays,a)},autoIncrement:function(){var e,t,n=this.options,r=this.xIncrement,a=n.pointIntervalUnit;return r=st(r,n.pointStart,0),this.pointInterval=t=st(this.pointInterval,n.pointInterval,1),("month"===a||"year"===a)&&(e=new Y(r),e="month"===a?+e[ue](e[ne]()+t):+e[ce](e[re]()+t),t=e-r),this.xIncrement=r+t,r},getSegments:function(){var e,t=this,n=-1,r=[],a=t.points,o=a.length;if(o)if(t.options.connectNulls){for(e=o;e--;)null===a[e].y&&a.splice(e,1);a.length&&(r=[a])}else ht(a,function(e,t){null===e.y?(t>n+1&&r.push(a.slice(n+1,t)),n=t):t===o-1&&r.push(a.slice(n+1,t+1))});t.segments=r},setOptions:function(t){var n,r,a=this.chart,o=a.options,i=o.plotOptions,s=a.userOptions||{},l=s.plotOptions||{},c=i[this.type];return this.userOptions=t,n=e(c,i.series,t),this.tooltipOptions=e(U.tooltip,U.plotOptions[this.type].tooltip,s.tooltip,l.series&&l.series.tooltip,l[this.type]&&l[this.type].tooltip,t.tooltip),null===c.marker&&delete n.marker,this.zoneAxis=n.zoneAxis,r=this.zones=(n.zones||[]).slice(),!n.negativeColor&&!n.negativeFillColor||n.zones||r.push({value:n[this.zoneAxis+"Threshold"]||n.threshold||0,color:n.negativeColor,fillColor:n.negativeFillColor}),r.length&&u(r[r.length-1].value)&&r.push({color:this.color,fillColor:this.fillColor}),n},getCyclic:function(e,t,n){var r,a=this.userOptions,o="_"+e+"Index",i=e+"Counter";t||(u(a[o])?r=a[o]:(a[o]=r=this.chart[i]%n.length,this.chart[i]+=1),t=n[r]),this[e]=t},getColor:function(){this.options.colorByPoint||this.getCyclic("color",this.options.color||xt[this.type].color,this.chart.options.colors)},getSymbol:function(){var e=this.options.marker;this.getCyclic("symbol",e.symbol,this.chart.options.symbols),/^url/.test(this.symbol)&&(e.radius=0)},drawLegendSymbol:Vt.drawLineMarker,setData:function(e,t,r,i){var s,l,u,c=this,d=c.points,p=d&&d.length||0,f=c.options,h=c.chart,m=null,g=c.xAxis,y=g&&!!g.categories,b=f.turboThreshold,v=this.xData,_=this.yData,w=c.pointArrayMap,k=w&&w.length;if(e=e||[],s=e.length,t=st(t,!0),i!==!1&&s&&p===s&&!c.cropped&&!c.hasGroupedData&&c.visible)ht(e,function(e,t){d[t].update&&d[t].update(e,!1,null,!1)});else{if(c.xIncrement=null,c.pointRange=y?1:f.pointRange,c.colorCounter=0,ht(this.parallelArrays,function(e){c[e+"Data"].length=0}),b&&s>b){for(l=0;null===m&&s>l;)m=e[l],l++;if(o(m)){var E=st(f.pointStart,0),x=st(f.pointInterval,1);for(l=0;s>l;l++)v[l]=E,_[l]=e[l],E+=x;c.xIncrement=E}else if(a(m))if(k)for(l=0;s>l;l++)u=e[l],v[l]=u[0],_[l]=u.slice(1,k+1);else for(l=0;s>l;l++)u=e[l],v[l]=u[0],_[l]=u[1];else P(12)}else for(l=0;s>l;l++)e[l]!==B&&(u={series:c},c.pointClass.prototype.applyOptions.apply(u,[e[l]]),c.updateParallelArrays(u,l),y&&u.name&&(g.names[u.x]=u.name));for(n(_[0])&&P(14,!0),c.data=[],c.options.data=e,l=p;l--;)d[l]&&d[l].destroy&&d[l].destroy();g&&(g.minRange=g.userMinRange),c.isDirty=c.isDirtyData=h.isDirtyBox=!0,r=!1}t&&h.redraw(r)},processData:function(e){var t,n,r,a,o,i,s,l,u=this,c=u.xData,d=u.yData,p=c.length,f=0,h=u.xAxis,m=u.options,g=m.cropThreshold,y=u.isCartesian;if(y&&!u.isDirty&&!h.isDirty&&!u.yAxis.isDirty&&!e)return!1;for(h&&(i=h.getExtremes(),s=i.min,l=i.max),y&&u.sorted&&(!g||p>g||u.forceCrop)&&(c[p-1]l?(c=[],d=[]):(c[0]l)&&(t=this.cropData(u.xData,u.yData,s,l),c=t.xData,d=t.yData,f=t.start,n=!0)),o=c.length-1;o>=0;o--)r=c[o]-c[o-1],r>0&&(a===B||a>r)?a=r:0>r&&u.requireSorting&&P(15);u.cropped=n,u.cropStart=f,u.processedXData=c,u.processedYData=d,null===m.pointRange&&(u.pointRange=a||1),u.closestPointRange=a},cropData:function(e,t,n,r){var a,o=e.length,i=0,s=o,l=st(this.cropShoulder,1);for(a=0;o>a;a++)if(e[a]>=n){i=be(0,a-l);break}for(;o>a;a++)if(e[a]>r){s=a+l;break}return{xData:e.slice(i,s),yData:t.slice(i,s),start:i,end:s}},generatePoints:function(){var e,t,n,r,a=this,o=a.options,i=o.data,s=a.data,l=a.processedXData,u=a.processedYData,c=a.pointClass,p=l.length,f=a.cropStart||0,h=a.hasGroupedData,m=[];if(!s&&!h){var g=[];g.length=i.length,s=a.data=g}for(r=0;p>r;r++)t=f+r,h?m[r]=(new c).init(a,[l[r]].concat(d(u[r]))):(s[t]?n=s[t]:i[t]!==B&&(s[t]=n=(new c).init(a,i[t],l[r])),m[r]=n),m[r].index=t;if(s&&(p!==(e=s.length)||h))for(r=0;e>r;r++)r!==f||h||(r+=p),s[r]&&(s[r].destroyElements(),s[r].plotX=B);a.data=s,a.points=m},getExtremes:function(e){var t,n,r,a,o,i,s,l=this.xAxis,u=this.yAxis,c=this.processedXData,d=[],p=0,f=l.getExtremes(),h=f.min,m=f.max;for(e=e||this.stackedYData||this.processedYData,t=e.length,i=0;t>i;i++)if(a=c[i],o=e[i],n=null!==o&&o!==B&&(!u.isLog||o.length||o>0),r=this.getExtremesFromAll||this.options.getExtremesFromAll||this.cropped||(c[i+1]||a)>=h&&(c[i-1]||a)<=m,n&&r)if(s=o.length)for(;s--;)null!==o[s]&&(d[p++]=o[s]);else d[p++]=o;this.dataMin=E(d),this.dataMax=x(d)},translate:function(){this.processedXData||this.processData(),this.generatePoints();var e,t,n,r,a=this,i=a.options,s=i.stacking,l=a.xAxis,c=l.categories,d=a.yAxis,p=a.points,f=p.length,h=!!a.modifyValue,m=i.pointPlacement,g="between"===m||o(m),y=i.threshold,b=i.startFromThreshold?y:0,v=Number.MAX_VALUE;for(e=0;f>e;e++){var _,w,k=p[e],E=k.x,x=k.y,O=k.low,S=s&&d.stacks[(a.negStacks&&(b?0:y)>x?"-":"")+a.stackKey];d.isLog&&null!==x&&0>=x&&(k.y=x=null,P(10)),k.plotX=t=ve(be(-1e5,l.translate(E,0,0,0,1,m,"flags"===this.type)),1e5),s&&a.visible&&S&&S[E]&&(_=S[E],w=_.points[a.index+","+e],O=w[0],x=w[1],O===b&&(O=st(y,d.min)),d.isLog&&0>=O&&(O=null),k.total=k.stackTotal=_.total,k.percentage=_.total&&k.y/_.total*100,k.stackY=x,_.setOffset(a.pointXOffset||0,a.barW||0)),k.yBottom=u(O)?d.translate(O,0,1,0,1):null,h&&(x=a.modifyValue(x,k)),k.plotY=n="number"==typeof x&&x!==1/0?ve(be(-1e5,d.translate(x,0,1,0,1)),1e5):B,k.isInside=n!==B&&n>=0&&n<=d.len&&t>=0&&t<=l.len,k.clientX=g?l.translate(E,0,0,0,1):t,k.negative=k.y<(y||0),k.category=c&&c[k.x]!==B?c[k.x]:k.x,e&&(v=ve(v,_e(t-r))),r=t}a.closestPointRangePx=v,a.getSegments()},setClip:function(e){var t=this.chart,n=t.renderer,r=t.inverted,a=this.clipBox,o=a||t.clipBox,i=this.sharedClipKey||["_sharedClip",e&&e.duration,e&&e.easing,o.height].join(","),s=t[i],l=t[i+"m"];s||(e&&(o.width=0,t[i+"m"]=l=n.clipRect(-99,r?-t.plotLeft:-t.plotTop,99,r?t.chartWidth:t.chartHeight)),t[i]=s=n.clipRect(o)),e&&(s.count+=1),this.options.clip!==!1&&(this.group.clip(e||a?s:t.clipRect),this.markerGroup.clip(l),this.sharedClipKey=i),e||(s.count-=1,s.count<=0&&i&&t[i]&&(a||(t[i]=t[i].destroy()),t[i+"m"]&&(t[i+"m"]=t[i+"m"].destroy())))},animate:function(e){var t,n,a=this,o=a.chart,i=a.options.animation;i&&!r(i)&&(i=xt[a.type].animation),e?a.setClip(i):(n=this.sharedClipKey,t=o[n],t&&t.animate({width:o.plotSizeX},i),o[n+"m"]&&o[n+"m"].animate({width:o.plotSizeX+99},i),a.animate=null)},afterAnimate:function(){this.setClip(),_t(this,"afterAnimate")},drawPoints:function(){var e,t,n,r,a,o,i,s,l,u,c,d,p,f=this,h=f.points,m=f.chart,g=f.options,y=g.marker,b=f.pointAttr[""],v=f.markerGroup,_=f.xAxis,w=st(y.enabled,_.isRadial,f.closestPointRangePx>2*y.radius);if(y.enabled!==!1||f._hasPointMarkers)for(r=h.length;r--;)a=h[r],t=ge(a.plotX),n=a.plotY,l=a.graphic,u=a.marker||{},c=!!a.marker,d=w&&u.enabled===B||u.enabled,p=a.isInside,d&&n!==B&&!isNaN(n)&&null!==a.y?(e=a.pointAttr[a.selected?nt:et]||b,o=e.r,i=st(u.symbol,f.symbol),s=0===i.indexOf("url"),l?l[p?"show":"hide"](!0).animate(it({x:t-o,y:n-o},l.symbolName?{width:2*o,height:2*o}:{})):p&&(o>0||s)&&(a.graphic=l=m.renderer.symbol(i,t-o,n-o,2*o,2*o,c?u:y).attr(e).add(v))):l&&(a.graphic=l.destroy())},convertAttribs:function(e,t,n,r){var a,o,i=this.pointAttrToOptions,s={};e=e||{},t=t||{},n=n||{},r=r||{};for(a in i)o=i[a],s[a]=st(e[o],t[a],n[a],r[a]);return s},getAttribs:function(){var e,t,n,r,a,o,i=this,s=i.options,l=xt[i.type].marker?s.marker:s,c=l.states,d=c[tt],p=i.color,f=i.options.negativeColor,h={stroke:p,fill:p},m=i.points||[],g=[],y=i.pointAttrToOptions,b=i.hasPointSpecificOptions,v=l.lineColor,_=l.fillColor,w=s.turboThreshold,k=i.zones,E=i.zoneAxis||"y";if(s.marker?(d.radius=d.radius||l.radius+d.radiusPlus,d.lineWidth=d.lineWidth||l.lineWidth+d.lineWidthPlus):(d.color=d.color||jt(d.color||p).brighten(d.brightness).get(),d.negativeColor=d.negativeColor||jt(d.negativeColor||f).brighten(d.brightness).get()),g[et]=i.convertAttribs(l,h),ht([tt,nt],function(e){g[e]=i.convertAttribs(c[e],g[et])}),i.pointAttr=g,t=m.length,!w||w>t||b)for(;t--;){if(n=m[t],l=n.options&&n.options.marker||n.options,l&&l.enabled===!1&&(l.radius=0),k.length){for(var x=0,O=k[x];n[E]>=O.value;)O=k[++x];n.color=n.fillColor=O.color}if(b=s.colorByPoint||n.color,n.options)for(o in y)u(l[y[o]])&&(b=!0);b?(l=l||{},r=[],c=l.states||{},e=c[tt]=c[tt]||{},s.marker||(e.color=e.color||!n.options.color&&d[n.negative&&f?"negativeColor":"color"]||jt(n.color).brighten(e.brightness||d.brightness).get()),a={color:n.color},_||(a.fillColor=n.color),v||(a.lineColor=n.color),l.hasOwnProperty("color")&&!l.color&&delete l.color,r[et]=i.convertAttribs(it(a,l),g[et]),r[tt]=i.convertAttribs(c[tt],g[tt],r[et]),r[nt]=i.convertAttribs(c[nt],g[nt],r[et])):r=g,n.pointAttr=r}},destroy:function(){var e,t,n,r,a,o=this,i=o.chart,s=/AppleWebKit\/533/.test(Oe),u=o.data||[];for(_t(o,"destroy"),vt(o),ht(o.axisTypes||[],function(e){a=o[e],a&&(l(a.series,o),a.isDirty=a.forceRedraw=!0)}),o.legendItem&&o.chart.legend.destroyItem(o),t=u.length;t--;)n=u[t],n&&n.destroy&&n.destroy();o.points=null,clearTimeout(o.animationTimeout);for(r in o)o[r]instanceof M&&!o[r].survive&&(e=s&&"group"===r?"hide":"destroy",o[r][e]());i.hoverSeries===o&&(i.hoverSeries=null),l(i.series,o);for(r in o)delete o[r]},getSegmentPath:function(e){var t=this,n=[],r=t.options.step;return ht(e,function(a,o){var i,s=a.plotX,l=a.plotY;t.getPointSpline?n.push.apply(n,t.getPointSpline(e,a,o)):(n.push(o?Ze:$e),r&&o&&(i=e[o-1],"right"===r?n.push(i.plotX,l):"center"===r?n.push((i.plotX+s)/2,i.plotY,(i.plotX+s)/2,l):n.push(s,i.plotY)),n.push(a.plotX,a.plotY))}),n},getGraphPath:function(){var e,t=this,n=[],r=[];return ht(t.segments,function(a){e=t.getSegmentPath(a),a.length>1?n=n.concat(e):r.push(a[0])}),t.singlePoints=r,t.graphPath=n,n},drawGraph:function(){var e=this,t=this.options,n=[["graph",t.lineColor||this.color,t.dashStyle]],r=t.lineWidth,a="square"!==t.linecap,o=this.getGraphPath(),i=this.fillGraph&&this.color||Je,s=this.zones;ht(s,function(r,a){n.push(["zoneGraph"+a,r.color||e.color,r.dashStyle||t.dashStyle])}),ht(n,function(n,s){var l,u=n[0],c=e[u];c?(Et(c),c.animate({d:o})):(r||i)&&o.length&&(l={stroke:n[1],"stroke-width":r,fill:i,zIndex:1},n[2]?l.dashstyle=n[2]:a&&(l["stroke-linecap"]=l["stroke-linejoin"]="round"),e[u]=e.chart.renderer.path(o).attr(l).add(e.group).shadow(2>s&&t.shadow))})},applyZones:function(){var e,t,n,r,a,o,i,s=this,l=this.chart,u=l.renderer,c=this.zones,d=this.clips||[],p=this.graph,f=this.area,h=be(l.chartWidth,l.chartHeight),m=this.zoneAxis||"y",g=this[m+"Axis"],y=g.reversed,b=l.inverted,v=g.horiz,_=!1;c.length&&(p||f)&&(p&&p.hide(),f&&f.hide(),r=g.getExtremes(),ht(c,function(c,m){e=y?v?l.plotWidth:0:v?0:g.toPixels(r.min),e=ve(be(st(t,e),0),h),t=ve(be(me(g.toPixels(st(c.value,r.max),!0)),0),h),_&&(e=t=g.toPixels(r.max)),a=Math.abs(e-t),o=ve(e,t),i=be(e,t),g.isXAxis?(n={x:b?i:o,y:0,width:a,height:h},v||(n.x=l.plotHeight-n.x)):(n={x:0,y:b?i:o,width:h,height:a},v&&(n.y=l.plotWidth-n.y)),l.inverted&&u.isVML&&(n=g.isXAxis?{x:0,y:y?o:i,height:n.width,width:l.chartWidth}:{x:n.y-l.plotLeft-l.spacingBox.x,y:0,width:n.height,height:l.chartHeight}),d[m]?d[m].animate(n):(d[m]=u.clipRect(n),p&&s["zoneGraph"+m].clip(d[m]),f&&s["zoneArea"+m].clip(d[m])),_=c.value>r.max}),this.clips=d)},invertGroups:function(){function e(){var e={width:t.yAxis.len,height:t.xAxis.len};ht(["group","markerGroup"],function(n){t[n]&&t[n].attr(e).invert()})}var t=this,n=t.chart;t.xAxis&&(bt(n,"resize",e),bt(t,"destroy",function(){vt(n,"resize",e)}),e(),t.invertGroups=e)},plotGroup:function(e,t,n,r,a){var o=this[e],i=!o;return i&&(this[e]=o=this.chart.renderer.g(t).attr({visibility:n,zIndex:r||.1}).add(a)),o[i?"attr":"animate"](this.getPlotBox()),o},getPlotBox:function(){var e=this.chart,t=this.xAxis,n=this.yAxis;return e.inverted&&(t=n,n=this.xAxis),{translateX:t?t.left:e.plotLeft,translateY:n?n.top:e.plotTop,scaleX:1,scaleY:1}},render:function(){var e,t=this,n=t.chart,r=t.options,a=r.animation,o=a&&!!t.animate&&n.renderer.isSVG&&st(a.duration,500)||0,i=t.visible?Ye:Ke,s=r.zIndex,l=t.hasRendered,u=n.seriesGroup;e=t.plotGroup("group","series",i,s,u),t.markerGroup=t.plotGroup("markerGroup","markers",i,s,u),o&&t.animate(!0),t.getAttribs(),e.inverted=t.isCartesian?n.inverted:!1,t.drawGraph&&(t.drawGraph(),t.applyZones()),ht(t.points,function(e){e.redraw&&e.redraw()}),t.drawDataLabels&&t.drawDataLabels(),t.visible&&t.drawPoints(),t.drawTracker&&t.options.enableMouseTracking!==!1&&t.drawTracker(),n.inverted&&t.invertGroups(),r.clip===!1||t.sharedClipKey||l||e.clip(n.clipRect),o&&t.animate(),l||(o?t.animationTimeout=setTimeout(function(){t.afterAnimate()},o):t.afterAnimate()),t.isDirty=t.isDirtyData=!1,t.hasRendered=!0},redraw:function(){var e=this,t=e.chart,n=e.isDirtyData,r=e.isDirty,a=e.group,o=e.xAxis,i=e.yAxis;a&&(t.inverted&&a.attr({width:t.plotWidth,height:t.plotHeight}),a.animate({translateX:st(o&&o.left,t.plotLeft),translateY:st(i&&i.top,t.plotTop)})),e.translate(),e.render(),n&&_t(e,"updatedData"),(r||n)&&delete this.kdTree},kdDimensions:1,kdAxisArray:["clientX","plotY"],searchPoint:function(e,t){var n=this,r=n.xAxis,a=n.yAxis,o=n.chart.inverted;return this.searchKDTree({clientX:o?r.len-e.chartY+r.pos:e.chartX-r.pos,plotY:o?a.len-e.chartX+a.pos:e.chartY-a.pos},t)},buildKDTree:function(){function e(t,r,a){var o,i,s=t&&t.length;return s?(o=n.kdAxisArray[r%a],t.sort(function(e,t){return e[o]-t[o]; +}),i=Math.floor(s/2),{point:t[i],left:e(t.slice(0,i),r+1,a),right:e(t.slice(i+1),r+1,a)}):void 0}function t(){var t=mt(n.points,function(e){return null!==e.y});n.kdTree=e(t,r,r)}var n=this,r=n.kdDimensions;delete n.kdTree,n.options.kdSync?t():setTimeout(t)},searchKDTree:function(e,t){function n(e,t){var n=u(e[o])&&u(t[o])?Math.pow(e[o]-t[o],2):null,r=u(e[i])&&u(t[i])?Math.pow(e[i]-t[i],2):null,a=(n||0)+(r||0);t.dist=u(a)?Math.sqrt(a):Number.MAX_VALUE,t.distX=u(n)?Math.sqrt(n):Number.MAX_VALUE}function r(e,t,o,i){var l,u,c,d,p,f=t.point,h=a.kdAxisArray[o%i],m=f;return n(e,f),l=e[h]-f[h],u=0>l?"left":"right",c=0>l?"right":"left",t[u]&&(d=r(e,t[u],o+1,i),m=d[s]o;o++)i=u[o],s=c[o],a=l.index+","+o,e=_&&(m?0:h)>s,r=e?v:b,k[r]||(k[r]={}),k[r][i]||(E[r]&&E[r][i]?(k[r][i]=E[r][i],k[r][i].total=null):k[r][i]=new z(w,w.options.stackLabels,e,i,g)),t=k[r][i],t.points[a]=[st(t.cum,m)],"percent"===y?(n=e?b:v,_&&k[n]&&k[n][i]?(n=k[n][i],t.total=n.total=be(n.total,t.total)+_e(s)||0):t.total=A(t.total+(_e(s)||0))):t.total=A(t.total+(s||0)),t.cum=st(t.cum,m)+(s||0),t.points[a].push(t.cum),d[o]=t.cum;"percent"===y&&(w.usePercentage=!0),this.stackedYData=d,w.oldStacks={}}},Xt.prototype.setPercentStacks=function(){var e=this,t=e.stackKey,n=e.yAxis.stacks,r=e.processedXData;ht([t,"-"+t],function(t){for(var a,o,i,s,l=r.length;l--;)a=r[l],o=n[t]&&n[t][a],i=o&&o.points[e.index+","+l],i&&(s=o.total?100/o.total:0,i[0]=A(i[0]*s),i[1]=A(i[1]*s),e.stackedYData[l]=i[1])})},it(Kt.prototype,{addSeries:function(e,t,n){var r,a=this;return e&&(t=st(t,!0),_t(a,"addSeries",{options:e},function(){r=a.initSeries(e),a.isDirtyLegend=!0,a.linkSeries(),t&&a.redraw(n)})),r},addAxis:function(t,n,r,a){var o,i=n?"xAxis":"yAxis",s=this.options;o=new It(this,e(t,{index:this[i].length,isX:n})),s[i]=d(s[i]||{}),s[i].push(t),st(r,!0)&&this.redraw(a)},showLoading:function(e){var t=this,n=t.options,r=t.loadingDiv,a=n.loading,o=function(){r&&p(r,{left:t.plotLeft+Xe,top:t.plotTop+Xe,width:t.plotWidth+Xe,height:t.plotHeight+Xe})};r||(t.loadingDiv=r=f(He,{className:Ge+"loading"},it(a.style,{zIndex:10,display:Je}),t.container),t.loadingSpan=f("span",null,a.labelStyle,r),bt(t,"redraw",o)),t.loadingSpan.innerHTML=e||n.lang.loading,t.loadingShown||(p(r,{opacity:0,display:""}),kt(r,{opacity:a.style.opacity},{duration:a.showDuration||0}),t.loadingShown=!0),o()},hideLoading:function(){var e=this.options,t=this.loadingDiv;t&&kt(t,{opacity:0},{duration:e.loading.hideDuration||100,complete:function(){p(t,{display:Je})}}),this.loadingShown=!1}}),it(Yt.prototype,{update:function(e,t,n,o){function i(){l.applyOptions(e),null===l.y&&c&&(l.graphic=c.destroy()),r(e)&&!a(e)&&(l.redraw=function(){c&&(e&&e.marker&&e.marker.symbol?l.graphic=c.destroy():c.attr(l.pointAttr[l.state||""])[l.visible===!1?"hide":"show"]()),e&&e.dataLabels&&l.dataLabel&&(l.dataLabel=l.dataLabel.destroy()),l.redraw=null}),s=l.index,u.updateParallelArrays(l,s),f&&l.name&&(f[l.x]=l.name),p.data[s]=l.options,u.isDirty=u.isDirtyData=!0,!u.fixedBox&&u.hasCartesianSeries&&(d.isDirtyBox=!0),"point"===p.legendType&&(d.isDirtyLegend=!0),t&&d.redraw(n)}var s,l=this,u=l.series,c=l.graphic,d=u.chart,p=u.options,f=u.xAxis&&u.xAxis.names;t=st(t,!0),o===!1?i():l.firePointEvent("update",{options:e},i)},remove:function(e,t){this.series.removePoint(ft(this,this.series.data),e,t)}}),it(Xt.prototype,{addPoint:function(e,t,n,r){var a,o,i,s,l=this,u=l.options,c=l.data,d=l.graph,p=l.area,f=l.chart,h=l.xAxis&&l.xAxis.names,m=d&&d.shift||0,g=["graph","area"],y=u.data,b=l.xData;if(j(r,f),n){for(i=l.zones.length;i--;)g.push("zoneGraph"+i,"zoneArea"+i);ht(g,function(e){l[e]&&(l[e].shift=m+1)})}if(p&&(p.isArea=!0),t=st(t,!0),a={series:l},l.pointClass.prototype.applyOptions.apply(a,[e]),s=a.x,i=b.length,l.requireSorting&&ss;)i--;l.updateParallelArrays(a,"splice",i,0,0),l.updateParallelArrays(a,i),h&&a.name&&(h[s]=a.name),y.splice(i,0,e),o&&(l.data.splice(i,0,null),l.processData()),"point"===u.legendType&&l.generatePoints(),n&&(c[0]&&c[0].remove?c[0].remove(!1):(c.shift(),l.updateParallelArrays(a,"shift"),y.shift())),l.isDirty=!0,l.isDirtyData=!0,t&&(l.getAttribs(),f.redraw())},removePoint:function(e,t,n){var r=this,a=r.data,o=a[e],i=r.points,s=r.chart,l=function(){a.length===i.length&&i.splice(e,1),a.splice(e,1),r.options.data.splice(e,1),r.updateParallelArrays(o||{series:r},"splice",e,1),o&&o.destroy(),r.isDirty=!0,r.isDirtyData=!0,t&&s.redraw()};j(n,s),t=st(t,!0),o?o.firePointEvent("remove",null,l):l()},remove:function(e,t){var n=this,r=n.chart;e=st(e,!0),n.isRemoving||(n.isRemoving=!0,_t(n,"remove",null,function(){n.destroy(),r.isDirtyLegend=r.isDirtyBox=!0,r.linkSeries(),e&&r.redraw(t)})),n.isRemoving=!1},update:function(t,n){var r,a=this,o=this.chart,i=this.userOptions,s=this.type,l=ot[s].prototype,u=["group","markerGroup","dataLabelsGroup"];(t.type&&t.type!==s||void 0!==t.zIndex)&&(u.length=0),ht(u,function(e){u[e]=a[e],delete a[e]}),t=e(i,{animation:!1,index:this.index,pointStart:this.xData[0]},{data:this.options.data},t),this.remove(!1);for(r in l)this[r]=B;it(this,ot[t.type||s].prototype),ht(u,function(e){a[e]=u[e]}),this.init(o,t),o.linkSeries(),st(n,!0)&&o.redraw(!1)}}),it(It.prototype,{update:function(t,n){var r=this.chart;t=r.options[this.coll][this.options.index]=e(this.userOptions,t),this.destroy(!0),this._addedPlotLB=this.chart._labelPanes=B,this.init(r,it(t,{events:B})),r.isDirtyBox=!0,st(n,!0)&&r.redraw()},remove:function(e){for(var t=this.chart,n=this.coll,r=this.series,a=r.length;a--;)r[a]&&r[a].remove(!1);l(t.axes,this),l(t[n],this),t.options[n].splice(this.options.index,1),ht(t[n],function(e,t){e.options.index=t}),this.destroy(),t.isDirtyBox=!0,st(e,!0)&&t.redraw()},setTitle:function(e,t){this.update({title:e},t)},setCategories:function(e,t){this.update({categories:e},t)}});var Jt=h(Xt);ot.line=Jt,xt.area=e(Ot,{threshold:0});var $t=h(Xt,{type:"area",getSegments:function(){var e,t,n,r,a=this,o=[],i=[],s=[],l=this.xAxis,u=this.yAxis,c=u.stacks[this.stackKey],d={},p=this.points,f=this.options.connectNulls;if(this.options.stacking&&!this.cropped){for(n=0;n=0;t--)n=st(e[t].yBottom,s),tg&&a>d?(a=be(g,d),i=2*d-a):g>a&&d>a&&(a=ve(g,d),i=2*d-a),i>b&&i>d?(i=be(b,d),a=2*d-i):b>i&&d>i&&(i=ve(b,d),a=2*d-i),t.rightContX=o,t.rightContY=i}return n?(s=["C",p.rightContX||p.plotX,p.rightContY||p.plotY,r||c,a||d,c,d],p.rightContX=p.rightContY=null):s=[$e,c,d],s}});ot.spline=Zt,xt.areaspline=e(xt.area);var Qt=$t.prototype,en=h(Zt,{type:"areaspline",closedStacks:!0,getSegmentPath:Qt.getSegmentPath,closeSegment:Qt.closeSegment,drawGraph:Qt.drawGraph,drawLegendSymbol:Vt.drawRectangle});ot.areaspline=en,xt.column=e(Ot,{borderColor:"#FFFFFF",borderRadius:0,groupPadding:.2,marker:null,pointPadding:.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:.1,shadow:!1,halo:!1},select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}},dataLabels:{align:null,verticalAlign:null,y:null},startFromThreshold:!0,stickyTracking:!1,tooltip:{distance:6},threshold:0});var tn=h(Xt,{type:"column",pointAttrToOptions:{stroke:"borderColor",fill:"color",r:"borderRadius"},cropShoulder:0,directTouch:!0,trackerGroups:["group","dataLabelsGroup"],negStacks:!0,init:function(){Xt.prototype.init.apply(this,arguments);var e=this,t=e.chart;t.hasRendered&&ht(t.series,function(t){t.type===e.type&&(t.isDirty=!0)})},getColumnMetrics:function(){var e,t,n=this,r=n.options,a=n.xAxis,o=n.yAxis,i=a.reversed,s={},l=0;r.grouping===!1?l=1:ht(n.chart.series,function(r){var a=r.options,i=r.yAxis;r.type===n.type&&r.visible&&o.len===i.len&&o.pos===i.pos&&(a.stacking?(e=r.stackKey,s[e]===B&&(s[e]=l++),t=s[e]):a.grouping!==!1&&(t=l++),r.columnIndex=t)});var c=ve(_e(a.transA)*(a.ordinalSlope||r.pointRange||a.closestPointRange||a.tickInterval||1),a.len),d=c*r.groupPadding,p=c-2*d,f=p/l,h=r.pointWidth,m=u(h)?(f-h)/2:f*r.pointPadding,g=st(h,f-2*m),y=(i?l-(n.columnIndex||0):n.columnIndex)||0,b=m+(d+y*f-c/2)*(i?-1:1);return n.columnMetrics={width:g,offset:b}},translate:function(){var e=this,t=e.chart,n=e.options,r=e.borderWidth=st(n.borderWidth,e.closestPointRange*e.xAxis.transA<2?0:1),a=e.yAxis,o=n.threshold,i=e.translatedThreshold=a.getThreshold(o),s=st(n.minPointLength,5),l=e.getColumnMetrics(),u=l.width,c=e.barW=be(u,1+2*r),d=e.pointXOffset=l.offset,p=-(r%2?.5:0),f=r%2?.5:1;t.inverted&&(i-=.5,t.renderer.isVML&&(f+=1)),n.pointPadding&&(c=ye(c)),Xt.prototype.translate.apply(e),ht(e.points,function(n){var r,o,l,h,m=st(n.yBottom,i),g=999+_e(m),y=ve(be(-g,n.plotY),a.len+g),b=n.plotX+d,v=c,_=ve(y,m),w=be(y,m)-_;_e(w)s?m-s:i-(h?s:0))),n.barX=b,n.pointWidth=u,r=me(b+v)+p,b=me(b)+p,v=r-b,l=_e(_)<.5,o=ve(me(_+w)+f,9e4),_=me(_)+f,w=o-_,l&&(_-=1,w+=1),n.tooltipPos=t.inverted?[a.len+a.pos-t.plotLeft-y,e.xAxis.len-b-v/2,w]:[b+v/2,y+a.pos-t.plotTop,w],n.shapeType="rect",n.shapeArgs={x:b,y:_,width:v,height:w}})},getSymbol:Be,drawLegendSymbol:Vt.drawRectangle,drawGraph:Be,drawPoints:function(){var t,n,r=this,a=this.chart,o=r.options,i=a.renderer,s=o.animationLimit||250;ht(r.points,function(l){var c,d=l.plotY,p=l.graphic;d===B||isNaN(d)||null===l.y?p&&(l.graphic=p.destroy()):(t=l.shapeArgs,c=u(r.borderWidth)?{"stroke-width":r.borderWidth}:{},n=l.pointAttr[l.selected?nt:et]||r.pointAttr[et],p?(Et(p),p.attr(c)[a.pointCount {series.name}
',pointFormat:"x: {point.x}
y: {point.y}
"}});var rn=h(Xt,{type:"scatter",sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:["group","markerGroup","dataLabelsGroup"],takeOrdinalPosition:!1,kdDimensions:2,drawGraph:function(){this.options.lineWidth&&Xt.prototype.drawGraph.call(this)}});ot.scatter=rn,xt.pie=e(Ot,{borderColor:"#FFFFFF",borderWidth:1,center:[null,null],clip:!1,colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name},x:0},ignoreHiddenPoint:!0,legendType:"point",marker:null,size:null,showInLegend:!1,slicedOffset:10,states:{hover:{brightness:.1,shadow:!1}},stickyTracking:!1,tooltip:{followPointer:!0}});var an=h(Yt,{init:function(){Yt.prototype.init.apply(this,arguments);var e,t=this;return it(t,{visible:t.visible!==!1,name:st(t.name,"Slice")}),e=function(e){t.slice("select"===e.type)},bt(t,"select",e),bt(t,"unselect",e),t},setVisible:function(e,t){var n=this,r=n.series,a=r.chart,o=r.options.ignoreHiddenPoint;t=st(t,o),e!==n.visible&&(n.visible=n.options.visible=e=e===B?!n.visible:e,r.options.data[ft(n,r.data)]=n.options,ht(["graphic","dataLabel","connector","shadowGroup"],function(t){n[t]&&n[t][e?"show":"hide"](!0)}),n.legendItem&&a.legend.colorizeItem(n,e),e||"hover"!==n.state||n.setState(""),o&&(r.isDirty=!0),t&&a.redraw())},slice:function(e,t,n){var r,a=this,o=a.series,i=o.chart;j(n,i),t=st(t,!0),a.sliced=a.options.sliced=e=u(e)?e:!a.sliced,o.options.data[ft(a,o.data)]=a.options,r=e?a.slicedTranslation:{translateX:0,translateY:0},a.graphic.animate(r),a.shadowGroup&&a.shadowGroup.animate(r)},haloPath:function(e){var t=this.shapeArgs,n=this.series.chart;return this.sliced||!this.visible?[]:this.series.chart.renderer.symbols.arc(n.plotLeft+t.x,n.plotTop+t.y,t.r+e,t.r+e,{innerR:this.shapeArgs.r,start:t.start,end:t.end})}}),on={type:"pie",isCartesian:!1,pointClass:an,requireSorting:!1,directTouch:!0,noSharedTooltip:!0,trackerGroups:["group","dataLabelsGroup"],axisTypes:[],pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},getColor:Be,animate:function(e){var t=this,n=t.points,r=t.startAngleRad;e||(ht(n,function(e){var n=e.graphic,a=e.shapeArgs;n&&(n.attr({r:e.startR||t.center[3]/2,start:r,end:r}),n.animate({r:a.r,start:a.start,end:a.end},t.options.animation))}),t.animate=null)},setData:function(e,t,n,r){Xt.prototype.setData.call(this,e,!1,n,r),this.processData(),this.generatePoints(),st(t,!0)&&this.chart.redraw(n)},updateTotals:function(){var e,t,n=0,r=this.points,a=r.length,o=this.options.ignoreHiddenPoint;for(e=0;a>e;e++)t=r[e],n+=o&&!t.visible?0:t.y;for(this.total=n,e=0;a>e;e++)t=r[e],t.percentage=n>0&&(t.visible||!o)?t.y/n*100:0,t.total=n},generatePoints:function(){Xt.prototype.generatePoints.call(this),this.updateTotals()},translate:function(e){this.generatePoints();var t,n,r,a,o,i,s,l=this,u=0,c=1e3,d=l.options,p=d.slicedOffset,f=p+d.borderWidth,h=d.startAngle||0,m=l.startAngleRad=Ee/180*(h-90),g=l.endAngleRad=Ee/180*(st(d.endAngle,h+360)-90),y=g-m,b=l.points,v=d.dataLabels.distance,_=d.ignoreHiddenPoint,w=b.length;for(e||(l.center=e=l.getCenter()),l.getX=function(t,n){return r=he.asin(ve((t-e[1])/(e[2]/2+v),1)),e[0]+(n?-1:1)*(we(r)*(e[2]/2+v))},i=0;w>i;i++)s=b[i],t=m+u*y,(!_||s.visible)&&(u+=s.percentage/100),n=m+u*y,s.shapeType="arc",s.shapeArgs={x:e[0],y:e[1],r:e[2]/2,innerR:e[3]/2,start:me(t*c)/c,end:me(n*c)/c},r=(n+t)/2,r>1.5*Ee?r-=2*Ee:-Ee/2>r&&(r+=2*Ee),s.slicedTranslation={translateX:me(we(r)*p),translateY:me(ke(r)*p)},a=we(r)*e[2]/2,o=ke(r)*e[2]/2,s.tooltipPos=[e[0]+.7*a,e[1]+.7*o],s.half=-Ee/2>r||r>Ee/2?1:0,s.angle=r,f=ve(f,v/2),s.labelPos=[e[0]+a+we(r)*v,e[1]+o+ke(r)*v,e[0]+a+we(r)*f,e[1]+o+ke(r)*f,e[0]+a,e[1]+o,0>v?"center":s.half?"right":"left",r]},drawGraph:null,drawPoints:function(){var e,t,n,r,a,o=this,i=o.chart,s=i.renderer,l=o.options.shadow;l&&!o.shadowGroup&&(o.shadowGroup=s.g("shadow").add(o.group)),ht(o.points,function(i){t=i.graphic,r=i.shapeArgs,n=i.shadowGroup,l&&!n&&(n=i.shadowGroup=s.g("shadow").add(o.shadowGroup)),e=i.sliced?i.slicedTranslation:{translateX:0,translateY:0},n&&n.attr(e),t?t.animate(it(r,e)):(a={"stroke-linejoin":"round"},i.visible||(a.visibility="hidden"),i.graphic=t=s[i.shapeType](r).setRadialReference(o.center).attr(i.pointAttr[i.selected?nt:et]).attr(a).attr(e).add(o.group).shadow(l,n))})},searchPoint:Be,sortByAngle:function(e,t){e.sort(function(e,n){return void 0!==e.angle&&(n.angle-e.angle)*t})},drawLegendSymbol:Vt.drawRectangle,getCenter:Gt.getCenter,getSymbol:Be};on=h(Xt,on),ot.pie=on,Xt.prototype.drawDataLabels=function(){var t,n,r,a,o=this,i=o.options,s=i.cursor,l=i.dataLabels,c=o.points,d=o.hasRendered||0,p=o.chart.renderer;(l.enabled||o._hasPointLabels)&&(o.dlProcessOptions&&o.dlProcessOptions(l),a=o.plotGroup("dataLabelsGroup","data-labels",l.defer?Ke:Ye,l.zIndex||6),st(l.defer,!0)&&(a.attr({opacity:+d}),d||bt(o,"afterAnimate",function(){o.visible&&a.show(),a[i.animation?"animate":"attr"]({opacity:1},{duration:200})})),n=l,ht(c,function(c){var d,f,h,m,g,y,b=c.dataLabel,_=c.connector,w=!0,k={};if(t=c.dlOptions||c.options&&c.options.dataLabels,d=st(t&&t.enabled,n.enabled),b&&!d)c.dataLabel=b.destroy();else if(d){if(l=e(n,t),y=l.style,g=l.rotation,f=c.getLabelConfig(),r=l.format?v(l.format,f):l.formatter.call(f,l),y.color=st(l.color,y.color,o.color,"black"),b)u(r)?(b.attr({text:r}),w=!1):(c.dataLabel=b=b.destroy(),_&&(c.connector=_.destroy()));else if(u(r)){h={fill:l.backgroundColor,stroke:l.borderColor,"stroke-width":l.borderWidth,r:l.borderRadius||0,rotation:g,padding:l.padding,zIndex:1},"contrast"===y.color&&(k.color=l.inside||l.distance<0||i.stacking?p.getContrast(c.color||o.color):"#000000"),s&&(k.cursor=s);for(m in h)h[m]===B&&delete h[m];b=c.dataLabel=p[g?"text":"label"](r,0,-999,l.shape,null,null,l.useHTML).attr(h).css(it(y,k)).add(a).shadow(l.shadow)}b&&o.alignDataLabel(c,b,l,null,w)}}))},Xt.prototype.alignDataLabel=function(e,t,n,r,a){var o,i,s=this.chart,l=s.inverted,u=st(e.plotX,-999),c=st(e.plotY,-999),d=t.getBBox(),p=s.renderer.fontMetrics(n.style.fontSize).b,f=this.visible&&(e.series.forceDL||s.isInsidePlot(u,me(c),l)||r&&s.isInsidePlot(u,l?r.x+1:r.y+r.height-1,l));f&&(r=it({x:l?s.plotWidth-c:u,y:me(l?s.plotHeight-u:c),width:0,height:0},r),it(n,{width:d.width,height:d.height}),n.rotation?(o=s.renderer.rotCorr(p,n.rotation),t[a?"attr":"animate"]({x:r.x+n.x+r.width/2+o.x,y:r.y+n.y+r.height/2}).attr({align:n.align})):(t.align(n,null,r),i=t.alignAttr,"justify"===st(n.overflow,"justify")?this.justifyDataLabel(t,n,i,d,r,a):st(n.crop,!0)&&(f=s.isInsidePlot(i.x,i.y)&&s.isInsidePlot(i.x+d.width,i.y+d.height)),n.shape&&t.attr({anchorX:e.plotX,anchorY:e.plotY}))),f||(t.attr({y:-999}),t.placed=!1)},Xt.prototype.justifyDataLabel=function(e,t,n,r,a,o){var i,s,l=this.chart,u=t.align,c=t.verticalAlign,d=e.box?0:e.padding||0;i=n.x+d,0>i&&("right"===u?t.align="left":t.x=-i,s=!0),i=n.x+r.width-d,i>l.plotWidth&&("left"===u?t.align="right":t.x=l.plotWidth-i,s=!0),i=n.y+d,0>i&&("bottom"===c?t.verticalAlign="top":t.y=-i,s=!0),i=n.y+r.height-d,i>l.plotHeight&&("top"===c?t.verticalAlign="bottom":t.y=l.plotHeight-i,s=!0),s&&(e.placed=!o,e.align(t,null,a))},ot.pie&&(ot.pie.prototype.drawDataLabels=function(){var e,t,n,r,a,o,i,s,l,u,c,d,p,f=this,h=f.data,m=f.chart,g=f.options.dataLabels,y=st(g.connectorPadding,10),b=st(g.connectorWidth,1),v=m.plotWidth,_=m.plotHeight,w=st(g.softConnector,!0),k=g.distance,E=f.center,O=E[2]/2,S=E[1],P=k>0,A=[[],[]],j=[0,0,0,0],C=function(e,t){return t.y-e.y};if(f.visible&&(g.enabled||f._hasPointLabels)){for(Xt.prototype.drawDataLabels.apply(f),ht(h,function(e){e.dataLabel&&e.visible&&A[e.half].push(e)}),d=2;d--;){var T,D,M,N,z=[],I=[],R=A[d],B=R.length;if(B){for(f.sortByAngle(R,d-.5),p=i=0;!i&&R[p];)i=R[p]&&R[p].dataLabel&&(R[p].dataLabel.getBBox().height||21),p++;if(k>0){for(M=ve(S+O+k,m.plotHeight),D=be(0,S-O-k);M>=D;D+=i)z.push(D);if(T=z.length,B>T){for(c=[].concat(R),c.sort(C),p=B;p--;)c[p].rank=p;for(p=B;p--;)R[p].rank>=T&&R.splice(p,1);B=R.length}for(p=0;B>p;p++){e=R[p],o=e.labelPos;var L,q,F=9999;for(q=0;T>q;q++)L=_e(z[q]-o[1]),F>L&&(F=L,N=q);if(p>N&&null!==z[p])N=p;else if(B-p+N>T&&null!==z[p])for(N=T-B+p;null===z[N];)N++;else for(;null===z[N];)N++;I.push({i:N,y:z[N]}),z[N]=null}I.sort(C)}for(p=0;B>p;p++){var U,H;e=R[p],o=e.labelPos,r=e.dataLabel,u=e.visible===!1?Ke:"inherit",H=o[1],k>0?(U=I.pop(),N=U.i,l=U.y,(H>l&&null!==z[N+1]||l>H&&null!==z[N-1])&&(l=ve(be(0,H),m.plotHeight))):l=H,s=g.justify?E[0]+(d?-1:1)*(O+k):f.getX(l===S-O-k||l===S+O+k?H:l,d),r._attr={visibility:u,align:o[6]},r._pos={x:s+g.x+({left:y,right:-y}[o[6]]||0),y:l+g.y-10},r.connX=s,r.connY=l,null===this.options.size&&(a=r.width,y>s-a?j[3]=be(me(a-s+y),j[3]):s+a>v-y&&(j[1]=be(me(s+a-v+y),j[1])),0>l-i/2?j[0]=be(me(-l+i/2),j[0]):l+i/2>_&&(j[2]=be(me(l+i/2-_),j[2])))}}}(0===x(j)||this.verifyDataLabelOverflow(j))&&(this.placeDataLabels(),P&&b&&ht(this.points,function(e){t=e.connector,o=e.labelPos,r=e.dataLabel,r&&r._pos&&e.visible?(u=r._attr.visibility,s=r.connX,l=r.connY,n=w?[$e,s+("left"===o[6]?5:-5),l,"C",s,l,2*o[2]-o[4],2*o[3]-o[5],o[2],o[3],Ze,o[4],o[5]]:[$e,s+("left"===o[6]?5:-5),l,Ze,o[2],o[3],Ze,o[4],o[5]],t?(t.animate({d:n}),t.attr("visibility",u)):e.connector=t=f.chart.renderer.path(n).attr({"stroke-width":b,stroke:g.connectorColor||e.color||"#606060",visibility:u}).add(f.dataLabelsGroup)):t&&(e.connector=t.destroy())}))}},ot.pie.prototype.placeDataLabels=function(){ht(this.points,function(e){var t,n=e.dataLabel;n&&e.visible&&(t=n._pos,t?(n.attr(n._attr),n[n.moved?"animate":"attr"](t),n.moved=!0):n&&n.attr({y:-999}))})},ot.pie.prototype.alignDataLabel=Be,ot.pie.prototype.verifyDataLabelOverflow=function(e){var t,n=this.center,r=this.options,a=r.center,o=r.minSize||80,i=o;return null!==a[0]?i=be(n[2]-be(e[1],e[3]),o):(i=be(n[2]-e[1]-e[3],o),n[0]+=(e[3]-e[1])/2),null!==a[1]?i=be(ve(i,n[2]-be(e[0],e[2])),o):(i=be(ve(i,n[2]-e[0]-e[2]),o),n[1]+=(e[0]-e[2])/2),ist(this.translatedThreshold,s.yAxis.len)),c=st(r.inside,!!this.options.stacking);l&&(a=e(l),i&&(a={x:s.yAxis.len-a.y-a.height,y:s.xAxis.len-a.x-a.width,width:a.height,height:a.width}),c||(i?(a.x+=u?0:a.width,a.width=0):(a.y+=u?a.height:0,a.height=0))),r.align=st(r.align,!i||c?"center":u?"right":"left"),r.verticalAlign=st(r.verticalAlign,i||c?"middle":u?"top":"bottom"),Xt.prototype.alignDataLabel.call(this,t,n,r,a,o)}),function(e){var t=e.Chart,n=e.each,r=e.pick,a=HighchartsAdapter.addEvent;t.prototype.callbacks.push(function(e){function t(){var t=[];n(e.series,function(e){var a=e.options.dataLabels;(a.enabled||e._hasPointLabels)&&!a.allowOverlap&&e.visible&&n(e.points,function(e){e.dataLabel&&(e.dataLabel.labelrank=r(e.labelrank,e.shapeArgs&&e.shapeArgs.height),t.push(e.dataLabel))})}),e.hideOverlappingLabels(t)}t(),a(e,"redraw",t)}),t.prototype.hideOverlappingLabels=function(e){var t,n,r,a,o,i=e.length,s=function(e,t,n,r){return!(t.x>e.x+n.width||t.x+r.widthe.y+n.height||t.y+r.heightn;n++)t=e[n],t&&(t.oldOpacity=t.opacity,t.newOpacity=1);for(e.sort(function(e,t){return t.labelrank-e.labelrank}),n=0;i>n;n++)for(a=e[n],r=n+1;i>r;++r)o=e[r],a&&o&&a.placed&&o.placed&&0!==a.newOpacity&&0!==o.newOpacity&&s(a.alignAttr,o.alignAttr,a,o)&&((a.labelrankn;n++)t=e[n],t&&(t.oldOpacity!==t.newOpacity&&t.placed&&(t.alignAttr.opacity=t.newOpacity,t[t.isOld&&t.newOpacity?"animate":"attr"](t.alignAttr)),t.isOld=!0)}}(de);var sn=de.TrackerMixin={drawTrackerPoint:function(){var e=this,t=e.chart,n=t.pointer,r=e.options.cursor,a=r&&{cursor:r},o=function(e){for(var n,r=e.target;r&&!n;)n=r.point,r=r.parentNode;n!==B&&n!==t.hoverPoint&&n.onMouseOver(e)};ht(e.points,function(e){e.graphic&&(e.graphic.element.point=e),e.dataLabel&&(e.dataLabel.element.point=e)}),e._hasTracking||(ht(e.trackerGroups,function(t){e[t]&&(e[t].addClass(Ge+"tracker").on("mouseover",o).on("mouseout",function(e){n.onTrackerMouseOut(e)}).css(a),q&&e[t].on("touchstart",o))}),e._hasTracking=!0)},drawTrackerGraph:function(){var e,t,n=this,r=n.options,a=r.trackByArea,o=[].concat(a?n.areaPath:n.graphPath),i=o.length,s=n.chart,l=s.pointer,u=s.renderer,c=s.options.tooltip.snap,d=n.tracker,p=r.cursor,f=p&&{cursor:p},h=n.singlePoints,m=function(){s.hoverSeries!==n&&n.onMouseOver()},g="rgba(192,192,192,"+(Me?1e-4:.002)+")";if(i&&!a)for(t=i+1;t--;)o[t]===$e&&o.splice(t+1,0,o[t+1]-c,o[t+2],Ze),(t&&o[t]===$e||t===i)&&o.splice(t,0,Ze,o[t-2]+c,o[t-1]);for(t=0;ta;o.series.length&&(d||u>ve(l.dataMin,l.min))&&(!d||cm;m++){if(f=m&&o[m-1]>r,o[m]5*i||f){if(o[m]>b){for(l=e.call(this,t,o[h],o[m],a);l.length&&l[0]<=b;)l.shift();l.length&&(b=l[l.length-1]),y=y.concat(l)}h=m+1}if(f)break}if(d=l.info,s&&d.unitRange<=K.hour){for(m=y.length-1,h=1;m>h;h++)H("%d",y[h])!==H("%d",y[h-1])&&(g[y[h]]="day",c=!0);c&&(g[y[0]]="day"),d.higherRanks=g}if(y.info=d,s&&u(v)){for(var _,w,k,E,x,O=y.length,S=O,P=[],A=[];S--;)w=this.translate(y[S]),k&&(A[S]=k-w),P[S]=k=w;for(A.sort(),E=A[ge(A.length/2)],.6*v>E&&(E=null),S=y[O-1]>r?O-1:O,k=void 0;S--;)w=P[S],x=k-w,k&&.8*v>x&&(null===E||.8*E>x)?(g[y[S]]&&!g[y[S+1]]?(_=S+1,k=w):_=S,y.splice(_,1)):k=w}return y}),it(It.prototype,{beforeSetTickPositions:function(){var e,t,n,r,a,o,i=this,s=[],l=!1,u=i.getExtremes(),c=u.min,d=u.max,p=i.isXAxis&&!!i.options.breaks,f=i.options.ordinal;if(f||p){if(ht(i.series,function(t,n){if(t.visible!==!1&&(t.takeOrdinalPosition!==!1||p)&&(s=s.concat(t.processedXData),e=s.length,s.sort(function(e,t){return e-t}),e))for(n=e-1;n--;)s[n]===s[n+1]&&s.splice(n,1)}),e=s.length,e>2){for(t=s[1]-s[0],o=e-1;o--&&!l;)s[o+1]-s[o]!==t&&(l=!0);!i.options.keepOrdinalPadding&&(s[0]-c>t||d-s[s.length-1]>t)&&(l=!0)}l?(i.ordinalPositions=s,n=i.val2lin(be(c,s[0]),!0),r=be(i.val2lin(ve(d,s[s.length-1]),!0),1),i.ordinalSlope=a=(d-c)/(r-n),i.ordinalOffset=c-n*a):i.ordinalPositions=i.ordinalSlope=i.ordinalOffset=B}i.doPostTranslate=f&&l||p,i.groupIntervalFactor=null},val2lin:function(e,t){var n=this,r=n.ordinalPositions;if(r){var a,o,i,s=r.length;for(a=s;a--;)if(r[a]===e){i=a;break}for(a=s-1;a--;)if(e>r[a]||0===a){o=(e-r[a])/(r[a+1]-r[a]),i=a+o;break}return t?i:n.ordinalSlope*(i||0)+n.ordinalOffset}return e},lin2val:function(e,t){var n=this,r=n.ordinalPositions;if(r){var a,o,i,s=n.ordinalSlope,l=n.ordinalOffset,u=r.length-1;if(t)0>e?e=r[0]:e>u?e=r[u]:(u=ge(e),i=e-u);else for(;u--;)if(a=s*u+l,e>=a){o=s*(u+1)+l,i=(e-a)/(o-a);break}return i!==B&&r[u]!==B?r[u]+(i?i*(r[u+1]-r[u]):0):e}return e},getExtendedPositions:function(){var e,t,n=this,r=n.chart,a=n.series[0].currentDataGrouping,o=n.ordinalIndex,i=a?a.count+a.unitName:"raw",s=n.getExtremes();return o||(o=n.ordinalIndex={}),o[i]||(e={series:[],getExtremes:function(){return{min:s.dataMin,max:s.dataMax}},options:{ordinal:!0},val2lin:It.prototype.val2lin},ht(n.series,function(n){t={xAxis:e,xData:n.xData,chart:r,destroyGroupedData:Be},t.options={dataGrouping:a?{enabled:!0,forced:!0,approximation:"open",units:[[a.unitName,[a.count]]]}:{enabled:!1}},n.processData.apply(t),e.series.push(t)}),n.beforeSetTickPositions.apply(e),o[i]=e.ordinalPositions),o[i]},getGroupIntervalFactor:function(e,t,n){var r,a=0,o=n.processedXData,i=o.length,s=[],l=this.groupIntervalFactor;if(!l){for(;i-1>a;a++)s[a]=o[a+1]-o[a];s.sort(function(e,t){return e-t}),r=s[ge(i/2)],e=be(e,o[0]),t=ve(t,o[i-1]),this.groupIntervalFactor=l=i*r/(t-e)}return l},postProcessTickInterval:function(e){var t=this.ordinalSlope;return t?this.options.breaks?this.closestPointRange:e/(t/this.closestPointRange):e}}),lt(Kt.prototype,"pan",function(e,t){var n=this,r=n.xAxis[0],a=t.chartX,o=!1;if(r.options.ordinal&&r.series.length){var i,s,l,u,c=n.mouseDownX,d=r.getExtremes(),f=d.dataMax,h=d.min,m=d.max,g=n.hoverPoints,y=r.closestPointRange,b=r.translationSlope*(r.ordinalSlope||y),v=(c-a)/b,_={ordinalPositions:r.getExtendedPositions()},w=r.lin2val,k=r.val2lin;_.ordinalPositions?_e(v)>1&&(g&&ht(g,function(e){e.setState()}),0>v?(l=_,u=r.ordinalPositions?r:_):(l=r.ordinalPositions?r:_,u=_),s=u.ordinalPositions,f>s[s.length-1]&&s.push(f),n.fixedRange=m-h,i=r.toFixedRange(null,null,w.apply(l,[k.apply(l,[h,!0])+v,!0]),w.apply(u,[k.apply(u,[m,!0])+v,!0])),i.min>=ve(d.dataMin,h)&&i.max<=be(f,m)&&r.setExtremes(i.min,i.max,!0,!1,{trigger:"pan"}),n.mouseDownX=a,p(n.container,{cursor:"move"})):o=!0}else o=!0;o&&e.apply(this,Array.prototype.slice.call(arguments,1))}),lt(Xt.prototype,"getSegments",function(e){var t,n=this,r=n.options.gapSize,a=n.xAxis;e.apply(this,Array.prototype.slice.call(arguments,1)),r&&(t=n.segments,ht(t,function(e,n){for(var o=e.length-1;o--;){if(e[o].xa.max){t.length=0;break}e[o+1].x-e[o].x>a.closestPointRange*r&&t.splice(n+1,0,e.splice(o+1,e.length-o))}}))}),function(e){"use strict";function t(){return Array.prototype.slice.call(arguments,1)}var n=e.pick,r=e.wrap,a=e.extend,o=HighchartsAdapter.fireEvent,i=e.Axis,s=e.Series;a(i.prototype,{isInBreak:function(e,t){var n=e.repeat||1/0,r=e.from,a=e.to-e.from,o=t>=r?(t-r)%n:n-(r-t)%n;return e.inclusive?a>=o:a>o&&0!==o},isInAnyBreak:function(e,t){var r,a,o,i=this.options.breaks,s=i&&i.length;if(s){for(;s--;)this.isInBreak(i[s],e)&&(r=!0,a||(a=n(i[s].showPoints,this.isXAxis?!1:!0)));o=r&&t?r&&!a:r}return o}}),r(i.prototype,"setTickPositions",function(e){if(e.apply(this,Array.prototype.slice.call(arguments,1)),this.options.breaks){var t,n=this,r=this.tickPositions,a=this.tickPositions.info,o=[];if(a&&a.totalRange>=n.closestPointRange)return;for(t=0;t=e)break;if(r.isInBreak(t,e)){a-=e-t.from;break}}return a},this.lin2val=function(e){var t,n,a=e;for(n=0;n=a));n++)t.toh;)s-=n;for(;h>s;)s+=n;for(u=s;m>u;u+=n)d.push({value:u,move:"in"}),d.push({value:u+(a.to-a.from),move:"out",size:a.breakSize})}d.sort(function(e,t){return e.value===t.value?("in"===e.move?0:1)-("in"===t.move?0:1):e.value-t.value}),t=0,s=h;for(l in d)a=d[l],t+="in"===a.move?1:-1,1===t&&"in"===a.move&&(s=a.value),0===t&&(p.push({from:s,to:a.value,len:a.value-s-(a.size||0)}),f+=a.value-s-(a.size||0));r.breakArray=p,o(r,"afterBreaks"),r.transA*=(m-r.min)/(m-h-f),r.min=h,r.max=m}}}),r(s.prototype,"generatePoints",function(e){e.apply(this,t(arguments));var n,r,a=this,o=a.xAxis,i=a.yAxis,s=a.points,l=s.length,u=a.options.connectNulls;if(o&&i&&(o.options.breaks||i.options.breaks))for(;l--;)n=s[l],r=null===n.y&&u===!1,r||!o.isInAnyBreak(n.x,!0)&&!i.isInAnyBreak(n.y,!0)||(s.splice(l,1),this.data[l]&&this.data[l].destroyElements())}),r(e.seriesTypes.column.prototype,"drawPoints",function(e){e.apply(this);var t,n,r,a,i,s=this,l=s.points,u=s.yAxis,c=u.breakArray||[];for(r=0;rn.to?o(u,"pointBreak",{point:t,brk:n}):o(u,"pointInBreak",{point:t,brk:n})})}(de);var ln="dataGrouping",un=Xt.prototype,cn=Rt.prototype,dn=un.processData,pn=un.generatePoints,fn=un.destroy,hn=cn.tooltipFooterHeaderFormatter,mn="number",gn={approximation:"average",groupPixelWidth:2,dateTimeLabelFormats:{millisecond:["%A, %b %e, %H:%M:%S.%L","%A, %b %e, %H:%M:%S.%L","-%H:%M:%S.%L"],second:["%A, %b %e, %H:%M:%S","%A, %b %e, %H:%M:%S","-%H:%M:%S"],minute:["%A, %b %e, %H:%M","%A, %b %e, %H:%M","-%H:%M"],hour:["%A, %b %e, %H:%M","%A, %b %e, %H:%M","-%H:%M"],day:["%A, %b %e, %Y","%A, %b %e","-%A, %b %e, %Y"],week:["Week from %A, %b %e, %Y","%A, %b %e","-%A, %b %e, %Y"],month:["%B %Y","%B","-%B %Y"],year:["%Y","%Y","-%Y"]}},yn={line:{},spline:{},area:{},areaspline:{},column:{approximation:"sum",groupPixelWidth:10},arearange:{approximation:"range"},areasplinerange:{approximation:"range"},columnrange:{approximation:"range",groupPixelWidth:10},candlestick:{approximation:"ohlc",groupPixelWidth:10},ohlc:{approximation:"ohlc",groupPixelWidth:5}},bn=[["millisecond",[1,2,5,10,20,25,50,100,200,500]],["second",[1,2,5,10,15,30]],["minute",[1,2,5,10,15,30]],["hour",[1,2,3,4,6,8,12]],["day",[1]],["week",[1]],["month",[1,3,6]],["year",null]],vn={sum:function(e){var t,n=e.length;if(!n&&e.hasNulls)t=null;else if(n)for(t=0;n--;)t+=e[n];return t},average:function(e){var t=e.length,n=vn.sum(e);return typeof n===mn&&t&&(n/=t),n},open:function(e){return e.length?e[0]:e.hasNulls?null:B},high:function(e){return e.length?x(e):e.hasNulls?null:B},low:function(e){return e.length?E(e):e.hasNulls?null:B},close:function(e){return e.length?e[e.length-1]:e.hasNulls?null:B},ohlc:function(e,t,n,r){return e=vn.open(e),t=vn.high(t),n=vn.low(n),r=vn.close(r),typeof e===mn||typeof t===mn||typeof n===mn||typeof r===mn?[e,t,n,r]:void 0},range:function(e,t){return e=vn.low(e),t=vn.high(t),typeof e===mn||typeof t===mn?[e,t]:void 0}};un.groupData=function(e,t,n,r){var a,o,i,s,l=this,u=l.data,c=l.options.data,d=[],p=[],f=e.length,h=!!t,m=[[],[],[],[]],g="function"==typeof r?r:vn[r],y=l.pointArrayMap,b=y&&y.length;for(s=0;f>=s&&!(e[s]>=n[0]);s++);for(;f>=s;s++){for(;(n[1]!==B&&e[s]>=n[1]||s===f)&&(a=n.shift(),i=g.apply(0,m),i!==B&&(d.push(a),p.push(i)),m[0]=[],m[1]=[],m[2]=[],m[3]=[],s!==f););if(s===f)break;if(y){var v,_,w=l.cropStart+s,k=u&&u[w]||l.pointClass.prototype.applyOptions.apply({series:l},[c[w]]);for(v=0;b>v;v++)_=k[y[v]],typeof _===mn?m[v].push(_):null===_&&(m[v].hasNulls=!0)}else o=h?t[s]:null,typeof o===mn?m[0].push(o):null===o&&(m[0].hasNulls=!0)}return[d,p]},un.processData=function(){var e,t=this,n=t.chart,r=t.options,a=r[ln],o=t.allowDG!==!1&&a&&st(a.enabled,n.options._stock);if(t.forceCrop=o,t.groupPixelWidth=null,t.hasProcessed=!0,dn.apply(t,arguments)!==!1&&o){t.destroyGroupedData();var i,s=t.processedXData,l=t.processedYData,c=n.plotSizeX,d=t.xAxis,p=d.options.ordinal,f=t.groupPixelWidth=d.getGroupPixelWidth&&d.getGroupPixelWidth(),h=t.pointRange;if(f){e=!0,t.points=null;var m=d.getExtremes(),g=m.min,y=m.max,b=p&&d.getGroupIntervalFactor(g,y,t)||1,v=f*(y-g)/c*b,_=d.getTimeTicks(d.normalizeTimeTickInterval(v,a.units||bn),g,y,d.options.startOfWeek,s,t.closestPointRange),w=un.groupData.apply(t,[s,l,_,a.approximation]),k=w[0],E=w[1];if(a.smoothed){for(i=k.length-1,k[i]=y;i--&&i>0;)k[i]+=v/2;k[0]=g}t.currentDataGrouping=_.info,null===r.pointRange&&(t.pointRange=_.info.totalRange),t.closestPointRange=_.info.totalRange,u(k[0])&&k[0]this.chart.plotSizeX/o||t&&n.forced)&&(i=!0));return i?o:0},It.prototype.setDataGrouping=function(e,t){t=st(t,!0),e||(e={forced:!1,units:null}),this instanceof It?ht(this.series,function(t){t.update({dataGrouping:e},!1)}):ht(this.chart.options.series,function(t){t.dataGrouping=e})},xt.ohlc=e(xt.column,{lineWidth:1,tooltip:{pointFormat:' {series.name}
Open: {point.open}
High: {point.high}
Low: {point.low}
Close: {point.close}
'},states:{hover:{lineWidth:3}},threshold:null});var _n=h(ot.column,{type:"ohlc",pointArrayMap:["open","high","low","close"],toYData:function(e){return[e.open,e.high,e.low,e.close]},pointValKey:"high",pointAttrToOptions:{stroke:"color","stroke-width":"lineWidth"},upColorProp:"stroke",getAttribs:function(){ot.column.prototype.getAttribs.apply(this,arguments);var t=this,n=t.options,r=n.states,a=n.upColor||t.color,o=e(t.pointAttr),i=t.upColorProp;o[""][i]=a,o.hover[i]=r.hover.upColor||a,o.select[i]=r.select.upColor||a,ht(t.points,function(e){e.open"},threshold:null,y:-30}),ot.flags=h(ot.column,{type:"flags",sorted:!1,noSharedTooltip:!0,allowDG:!1,takeOrdinalPosition:!1,trackerGroups:["markerGroup"],forceCrop:!0,init:Xt.prototype.init,pointAttrToOptions:{fill:"fillColor",stroke:"color","stroke-width":"lineWidth",r:"radius"},translate:function(){ot.column.prototype.translate.apply(this);var e,t,n,r,a,o,i=this,s=i.options,l=i.chart,u=i.points,c=u.length-1,d=s.onSeries,p=d&&l.get(d),f=p&&p.options.step,h=p&&p.points,m=h&&h.length,g=i.xAxis,y=g.getExtremes();if(p&&p.visible&&m)for(o=p.currentDataGrouping,r=h[m-1].x+(o?o.totalRange:0),u.sort(function(e,t){return e.x-t.x});m--&&u[c]&&(e=u[c],n=h[m],!(n.x<=e.x&&n.plotY!==B&&(e.x<=r&&(e.plotY=n.plotY,n.xc))););ht(u,function(e,n){var r;e.plotY===B&&(e.x>=y.min&&e.x<=y.max?e.plotY=l.chartHeight-g.bottom-(g.opposite?g.height:0)+g.offset-l.plotTop:e.shapeArgs={}),t=u[n-1],t&&t.plotX===e.plotX&&(t.stackIndex===B&&(t.stackIndex=0),r=t.stackIndex+1),e.stackIndex=r})},drawPoints:function(){var t,n,r,a,o,i,s,l,u,c,d,p=this,f=p.pointAttr[""],h=p.points,m=p.chart,g=m.renderer,y=p.options,b=y.y;for(o=h.length;o--;)i=h[o],d=i.plotX>p.xAxis.len,n=i.plotX-st(i.lineWidth,y.lineWidth)%2,l=i.stackIndex,a=i.options.shape||y.shape,r=i.plotY,r!==B&&(r=i.plotY+b-(l!==B&&l*y.stackDistance)),u=l?B:i.plotX,c=l?B:i.plotY,s=i.graphic,r!==B&&n>=0&&!d?(t=i.pointAttr[i.selected?"select":""]||f,s?s.attr({x:n,y:r,r:t.r,anchorX:u,anchorY:c}):s=i.graphic=g.label(i.options.title||y.title||"A",n,r,a,u,c,y.useHTML).css(e(y.style,i.style)).attr(t).attr({align:"flag"===a?"left":"center",width:y.width,height:y.height}).add(p.markerGroup).shadow(y.shadow),i.tooltipPos=[n,r]):s&&(i.graphic=s.destroy())},drawTracker:function(){var e=this,t=e.points;sn.drawTrackerPoint.apply(this),ht(t,function(e){var n=e.graphic;n&&bt(n.element,"mouseover",function(){e.stackIndex>0&&!e.raised&&(e._y=n.y,n.attr({y:e._y-8}),e.raised=!0),ht(t,function(t){t!==e&&t.raised&&t.graphic&&(t.graphic.attr({y:t._y}),t.raised=!1)})})})},animate:Be,buildKDTree:Be,setClip:Be}),kn.flag=function(e,t,n,r,a){var o=a&&a.anchorX||e,i=a&&a.anchorY||t;return["M",o,i,"L",e,t+r,e,t,e+n,t,e+n,t+r,e,t+r,"Z"]},ht(["circle","square"],function(e){kn[e+"pin"]=function(t,n,r,a,o){var i,s,l=o&&o.anchorX,u=o&&o.anchorY;return"circle"===e&&a>r&&(t-=me((a-r)/2),r=a),i=kn[e](t,n,r,a),l&&u&&(s=n>u?n:n+a,i.push("M",l,s,"L",l,u)),i}}),L===de.VMLRenderer&&ht(["flag","circlepin","squarepin"],function(e){Tt.prototype.symbols[e]=kn[e]});var En,xn=[].concat(bn),On=function(e){var t=mt(arguments,function(e){return"number"==typeof e});return t.length?Math[e].apply(0,t):void 0};xn[4]=["day",[1,2,3,4]],xn[5]=["week",[1,2,3]],En=ot.areaspline===B?"line":"areaspline",it(U,{navigator:{handles:{backgroundColor:"#ebe7e8",borderColor:"#b2b1b6"},height:40,margin:25,maskFill:"rgba(128,179,236,0.3)",maskInside:!0,outlineColor:"#b2b1b6",outlineWidth:1,series:{type:En,color:"#4572A7",compare:null,fillOpacity:.05,dataGrouping:{approximation:"average",enabled:!0,groupPixelWidth:2,smoothed:!0,units:xn},dataLabels:{enabled:!1,zIndex:2},id:Ge+"navigator-series",lineColor:"#4572A7",lineWidth:1,marker:{enabled:!1},pointRange:0,shadow:!1,threshold:null},xAxis:{tickWidth:0,lineWidth:0,gridLineColor:"#EEE",gridLineWidth:1,tickPixelInterval:200,labels:{align:"left",style:{color:"#888"},x:3,y:-4},crosshair:!1},yAxis:{gridLineWidth:0,startOnTick:!1,endOnTick:!1,minPadding:.1,maxPadding:.1,labels:{enabled:!1},crosshair:!1,title:{text:null},tickWidth:0}},scrollbar:{height:Te?20:14,barBackgroundColor:"#bfc8d1",barBorderRadius:0,barBorderWidth:1,barBorderColor:"#bfc8d1",buttonArrowColor:"#666",buttonBackgroundColor:"#ebe7e8",buttonBorderColor:"#bbb",buttonBorderRadius:0,buttonBorderWidth:1,minWidth:6,rifleColor:"#666",trackBackgroundColor:"#eeeeee",trackBorderColor:"#eeeeee",trackBorderWidth:1,liveRedraw:Me&&!Te}}),I.prototype={drawHandle:function(e,t){var n,r=this,a=r.chart,o=a.renderer,i=r.elementsToDestroy,s=r.handles,l=r.navigatorOptions.handles,u={fill:l.backgroundColor,stroke:l.borderColor,"stroke-width":1};r.rendered||(s[t]=o.g("navigator-handle-"+["left","right"][t]).css({cursor:"ew-resize"}).attr({zIndex:4-t}).add(),n=o.rect(-4.5,0,9,16,0,1).attr(u).add(s[t]),i.push(n),n=o.path(["M",-1.5,4,"L",-1.5,12,"M",.5,4,"L",.5,12]).attr(u).add(s[t]),i.push(n)),s[t][a.isResizing?"animate":"attr"]({translateX:r.scrollerLeft+r.scrollbarHeight+parseInt(e,10),translateY:r.top+r.height/2-8})},drawScrollbarButton:function(e){var t,n=this,r=n.chart,a=r.renderer,o=n.elementsToDestroy,i=n.scrollbarButtons,s=n.scrollbarHeight,l=n.scrollbarOptions;n.rendered||(i[e]=a.g().add(n.scrollbarGroup),t=a.rect(-.5,-.5,s+1,s+1,l.buttonBorderRadius,l.buttonBorderWidth).attr({stroke:l.buttonBorderColor,"stroke-width":l.buttonBorderWidth,fill:l.buttonBackgroundColor}).add(i[e]),o.push(t),t=a.path(["M",s/2+(e?-1:1),s/2-3,"L",s/2+(e?-1:1),s/2+3,s/2+(e?2:-2),s/2]).attr({fill:l.buttonArrowColor}).add(i[e]),o.push(t)),e&&i[e].attr({translateX:n.scrollerWidth-s})},render:function(e,t,n,r){var a,o,i,s,l,c,d,p,f,h,m,g,y,b=this,v=b.chart,_=v.renderer,w=b.scrollbarGroup,k=b.navigatorGroup,E=b.scrollbar,x=b.xAxis,O=b.scrollbarTrack,S=b.scrollbarHeight,P=b.scrollbarEnabled,A=b.navigatorOptions,j=b.scrollbarOptions,C=j.minWidth,T=b.height,D=b.top,M=b.navigatorEnabled,N=A.outlineWidth,z=N/2,I=0,R=b.outlineHeight,B=j.barBorderRadius,L=j.barBorderWidth,q=D+z;u(e)&&!isNaN(e)&&(b.navigatorLeft=a=st(x.left,v.plotLeft+S),b.navigatorWidth=o=st(x.len,v.plotWidth-2*S),b.scrollerLeft=i=a-S,b.scrollerWidth=s=s=o+2*S,x.getExtremes&&(y=b.getUnionExtremes(!0),!y||y.dataMin===x.min&&y.dataMax===x.max||x.setExtremes(y.dataMin,y.dataMax,!0,!1)),n=st(n,x.translate(e)),r=st(r,x.translate(t)),(isNaN(n)||_e(n)===1/0)&&(n=0,r=s),x.translate(r,!0)-x.translate(n,!0)f&&(I=(C-f)/2,f=C,p-=I),b.scrollbarPad=I,E[g]({x:ge(p)+L%2/2,width:f}),m=S+l+d/2-.5,b.scrollbarRifles.attr({visibility:d>12?Ye:Ke})[g]({d:[$e,m-3,S/4,Ze,m-3,2*S/3,$e,m,S/4,Ze,m,2*S/3,$e,m+3,S/4,Ze,m+3,2*S/3]})),b.scrollbarPad=I,b.rendered=!0))},addEvents:function(){var e,t=this.chart.container,n=this.mouseDownHandler,r=this.mouseMoveHandler,a=this.mouseUpHandler;e=[[t,"mousedown",n],[t,"mousemove",r],[document,"mouseup",a]],q&&e.push([t,"touchstart",n],[t,"touchmove",r],[document,"touchend",a]),ht(e,function(e){bt.apply(null,e)}),this._events=e},removeEvents:function(){ht(this._events,function(e){vt.apply(null,e)}),this._events=B,this.navigatorEnabled&&this.baseSeries&&vt(this.baseSeries,"updatedData",this.updatedDataHandler)},init:function(){var t,n,r,a,o=this,i=o.chart,s=o.scrollbarHeight,l=o.navigatorOptions,u=o.height,c=o.top,d=o.baseSeries;o.mouseDownHandler=function(e){e=i.pointer.normalize(e);var n,a,s,l,c=o.zoomedMin,d=o.zoomedMax,p=o.top,f=o.scrollbarHeight,h=o.scrollerLeft,m=o.scrollerWidth,g=o.navigatorLeft,y=o.navigatorWidth,b=o.scrollbarPad,v=o.range,_=e.chartX,w=e.chartY,k=i.xAxis[0],E=Te?10:7;w>p&&p+u+f>w&&(l=!o.scrollbarEnabled||p+u>w,l&&he.abs(_-c-g)g+c-b&&g+d+b>_?(o.grabbedCenter=_,o.fixedWidth=v,r=_-c):_>h&&h+m>_&&(s=l?_-g-v/2:g>_?c-.2*v:_>h+m-f?c+.2*v:g+c>_?c-v:d,0>s?s=0:s+v>=y&&(s=y-v,n=o.getUnionExtremes().dataMax),s!==c&&(o.fixedWidth=v,a=t.toFixedRange(s,s+v,null,n),k.setExtremes(a.min,a.max,!0,!1,{trigger:"navigator"}))))},o.mouseMoveHandler=function(e){var t,n=o.scrollbarHeight,s=o.navigatorLeft,l=o.navigatorWidth,u=o.scrollerLeft,c=o.scrollerWidth,d=o.range;0!==e.pageX&&(e=i.pointer.normalize(e),t=e.chartX,s>t?t=s:t>u+c-n&&(t=u+c-n),o.grabbedLeft?(a=!0,o.render(0,0,t-s,o.otherHandlePos)):o.grabbedRight?(a=!0,o.render(0,0,o.otherHandlePos,t-s)):o.grabbedCenter&&(a=!0,r>t?t=r:t>l+r-d&&(t=l+r-d),o.render(0,0,t-r,t-r+d)),a&&o.scrollbarOptions.liveRedraw&&setTimeout(function(){o.mouseUpHandler(e)},0))},o.mouseUpHandler=function(e){var n,s,l;a&&(o.zoomedMin===o.otherHandlePos?s=o.fixedExtreme:o.zoomedMax===o.otherHandlePos&&(l=o.fixedExtreme),n=t.toFixedRange(o.zoomedMin,o.zoomedMax,s,l),i.xAxis[0].setExtremes(n.min,n.max,!0,!1,{trigger:"navigator",triggerOp:"navigator-drag",DOMEvent:e})),"mousemove"!==e.type&&(o.grabbedLeft=o.grabbedRight=o.grabbedCenter=o.fixedWidth=o.fixedExtreme=o.otherHandlePos=a=r=null)};var p=i.xAxis.length,f=i.yAxis.length;i.extraBottomMargin=o.outlineHeight+l.margin,o.navigatorEnabled?(o.xAxis=t=new It(i,e({breaks:d&&d.xAxis.options.breaks,ordinal:d&&d.xAxis.options.ordinal},l.xAxis,{id:"navigator-x-axis",isX:!0,type:"datetime",index:p,height:u,offset:0,offsetLeft:s,offsetRight:-s,keepOrdinalPadding:!0,startOnTick:!1,endOnTick:!1,minPadding:0,maxPadding:0,zoomEnabled:!1})),o.yAxis=n=new It(i,e(l.yAxis,{id:"navigator-y-axis",alignTicks:!1,height:u,offset:0,index:f,zoomEnabled:!1})),d||l.series.data?o.addBaseSeries():0===i.series.length&<(i,"redraw",function(e,t){i.series.length>0&&!o.series&&(o.setBaseSeries(),i.redraw=e),e.call(i,t)})):o.xAxis=t={translate:function(e,t){var n=i.xAxis[0],r=n.getExtremes(),a=i.plotWidth-2*s,o=On("min",n.options.min,r.dataMin),l=On("max",n.options.max,r.dataMax)-o;return t?e*l/a+o:a*(e-o)/l},toFixedRange:It.prototype.toFixedRange},lt(i,"getMargins",function(e){var r=this.legend,a=r.options;e.apply(this,[].slice.call(arguments,1)),o.top=c=o.navigatorOptions.top||this.chartHeight-o.height-o.scrollbarHeight-this.spacing[2]-("bottom"===a.verticalAlign&&a.enabled&&!a.floating?r.legendHeight+st(a.margin,10):0),t&&n&&(t.options.top=n.options.top=c,t.setAxisSize(),n.setAxisSize())}),o.addEvents()},getUnionExtremes:function(e){var t,n=this.chart.xAxis[0],r=this.xAxis,a=r.options,o=n.options;return e&&null===n.dataMin||(t={dataMin:st(a&&a.min,On("min",o.min,n.dataMin,r.dataMin)),dataMax:st(a&&a.max,On("max",o.max,n.dataMax,r.dataMax))}),t},setBaseSeries:function(e){var t=this.chart;e=e||t.options.navigator.baseSeries,this.series&&this.series.remove(),this.baseSeries=t.series[e]||"string"==typeof e&&t.get(e)||t.series[0],this.xAxis&&this.addBaseSeries()},addBaseSeries:function(){var t,n,r=this.baseSeries,a=r?r.options:{},o=a.data,i=this.navigatorOptions.series;n=i.data,this.hasNavigatorData=!!n,t=e(a,i,{enableMouseTracking:!1,group:"nav",padXAxis:!1,xAxis:"navigator-x-axis",yAxis:"navigator-y-axis",name:"Navigator",showInLegend:!1,isInternal:!0,visible:!0}),t.data=n||o,this.series=this.chart.initSeries(t),r&&this.navigatorOptions.adaptToUpdatedData!==!1&&(bt(r,"updatedData",this.updatedDataHandler),r.userOptions.events=it(r.userOptions.event,{updatedData:this.updatedDataHandler}))},updatedDataHandler:function(){var e,t,n,r,a,o=this.chart.scroller,i=o.baseSeries,s=i.xAxis,l=s.getExtremes(),u=l.min,c=l.max,d=l.dataMin,p=l.dataMax,f=c-u,h=o.series,m=h.xData,g=!!s.setExtremes;t=c>=m[m.length-1]-(this.closestPointRange||0),e=d>=u,o.hasNavigatorData||(h.options.pointStart=i.xData[0],h.setData(i.options.data,!1),a=!0),e&&(r=d,n=r+f),t&&(n=p,e||(r=be(n-f,h.xData[0]))),g&&(e||t)?isNaN(r)||s.setExtremes(r,n,!0,!1,{trigger:"updatedData"}):(a&&this.chart.redraw(!1),o.render(be(u,d),ve(c,p)))},destroy:function(){var e=this;e.removeEvents(),ht([e.xAxis,e.yAxis,e.leftShade,e.rightShade,e.outline,e.scrollbarTrack,e.scrollbarRifles,e.scrollbarGroup,e.scrollbar],function(e){e&&e.destroy&&e.destroy()}),e.xAxis=e.yAxis=e.leftShade=e.rightShade=e.outline=e.scrollbarTrack=e.scrollbarRifles=e.scrollbarGroup=e.scrollbar=null,ht([e.scrollbarButtons,e.handles,e.elementsToDestroy],function(e){O(e)})}},de.Scroller=I,lt(It.prototype,"zoom",function(e,t,n){var r,a,o=this.chart,i=o.options,s=i.chart.zoomType,l=i.navigator,c=i.rangeSelector;return this.isXAxis&&(l&&l.enabled||c&&c.enabled)&&("x"===s?o.resetZoomButton="blocked":"y"===s?a=!1:"xy"===s&&(r=this.previousZoom,u(t)?this.previousZoom=[this.min,this.max]:r&&(t=r[0],n=r[1],delete this.previousZoom))),a!==B?a:e.call(this,t,n)}),lt(Kt.prototype,"init",function(e,t,n){bt(this,"beforeRender",function(){var e=this.options;(e.navigator.enabled||e.scrollbar.enabled)&&(this.scroller=new I(this))}),e.call(this,t,n)}),lt(Xt.prototype,"addPoint",function(e,t,n,o,i){var s=this.options.turboThreshold;s&&this.xData.length>s&&r(t)&&!a(t)&&this.chart.scroller&&P(20,!0),e.call(this,t,n,o,i)}),it(U,{rangeSelector:{buttonTheme:{width:28,height:18,fill:"#f7f7f7",padding:2,r:0,"stroke-width":0,style:{color:"#444",cursor:"pointer",fontWeight:"normal"},zIndex:7,states:{hover:{fill:"#e7e7e7"},select:{fill:"#e7f0f9",style:{color:"black",fontWeight:"bold"}}}},inputPosition:{align:"right"},labelStyle:{color:"#666"}}}),U.lang=e(U.lang,{rangeSelectorZoom:"Zoom",rangeSelectorFrom:"From",rangeSelectorTo:"To"}),R.prototype={clickButton:function(e,t){var n,r,a,o,i,s,l,u,c=this,d=c.selected,p=c.chart,f=c.buttons,h=c.buttonOptions[e],m=p.xAxis[0],g=p.scroller&&p.scroller.getUnionExtremes()||m||{},y=g.dataMin,b=g.dataMax,v=m&&me(ve(m.max,st(b,m.max))),_=new Y(v),w=h.type,k=h.count,E=h._range,x=h.dataGrouping;if(null!==y&&null!==b&&e!==c.selected){if(x&&(this.forcedDataGrouping=!0,It.prototype.setDataGrouping.call(m||{chart:this.chart},x,!1)),"month"===w||"year"===w)s={month:"Month",year:"FullYear"}[w],_["set"+s](_["get"+s]()-k),n=_.getTime(),y=st(y,Number.MIN_VALUE),isNaN(n)||y>n?(n=y,v=ve(n+E,b)):E=v-n;else if(E)n=be(v-E,y),v=ve(n+E,b);else if("ytd"===w){if(!m)return void bt(p,"beforeRender",function(){ +c.clickButton(e)});b===B&&(y=Number.MAX_VALUE,b=Number.MIN_VALUE,ht(p.series,function(e){var t=e.xData;y=ve(t[0],y),b=be(t[t.length-1],b)}),t=!1),r=new Y(b),i=r.getFullYear(),n=o=be(y||0,Y.UTC(i,0,1)),r=r.getTime(),v=ve(b||r,r)}else"all"===w&&m&&(n=y,v=b);f[d]&&f[d].setState(0),f[e]&&f[e].setState(2),p.fixedRange=E,m?(m.setExtremes(n,v,st(t,1),0,{trigger:"rangeSelectorButton",rangeSelectorButton:h}),c.setSelected(e)):(a=p.options.xAxis[0],u=a.range,a.range=E,l=a.min,a.min=o,c.setSelected(e),bt(p,"load",function(){a.range=u,a.min=l}))}},setSelected:function(e){this.selected=this.options.selected=e},defaultButtons:[{type:"month",count:1,text:"1m"},{type:"month",count:3,text:"3m"},{type:"month",count:6,text:"6m"},{type:"ytd",text:"YTD"},{type:"year",count:1,text:"1y"},{type:"all",text:"All"}],init:function(e){var t=this,n=e.options.rangeSelector,r=n.buttons||[].concat(t.defaultButtons),a=n.selected,o=t.blurInputs=function(){var e=t.minInput,n=t.maxInput;e&&e.blur&&_t(e,"blur"),n&&n.blur&&_t(n,"blur")};t.chart=e,t.options=n,t.buttons=[],e.extraTopMargin=35,t.buttonOptions=r,bt(e.container,"mousedown",o),bt(e,"resize",o),ht(r,t.computeButtonRange),a!==B&&r[a]&&this.clickButton(a,!1),bt(e,"load",function(){bt(e.xAxis[0],"setExtremes",function(n){this.max-this.min!==e.fixedRange&&"rangeSelectorButton"!==n.trigger&&"updatedData"!==n.trigger&&t.forcedDataGrouping&&this.setDataGrouping(!1,!1)}),bt(e.xAxis[0],"afterSetExtremes",function(){t.updateButtonStates(!0)})})},updateButtonStates:function(e){var t=this,n=this.chart,r=n.xAxis[0],a=n.scroller&&n.scroller.getUnionExtremes()||r,o=a.dataMin,i=a.dataMax,s=t.selected,l=t.options.allButtonsEnabled,u=t.buttons;e&&n.fixedRange!==me(r.max-r.min)&&(u[s]&&u[s].setState(0),t.setSelected(null)),ht(t.buttonOptions,function(e,n){var a=e._range,c=a>i-o,d=a=i-o&&2!==u[n].state,f="ytd"===e.type&&H("%Y",o)===H("%Y",i);a===me(r.max-r.min)&&n!==s?(t.setSelected(n),u[n].setState(2)):!l&&(c||d||p||f)?u[n].setState(3):3===u[n].state&&u[n].setState(0)})},computeButtonRange:function(e){var t=e.type,n=e.count||1,r={millisecond:1,second:1e3,minute:6e4,hour:36e5,day:864e5,week:6048e5};r[t]?e._range=r[t]*n:("month"===t||"year"===t)&&(e._range=24*{month:30,year:365}[t]*36e5*n)},setInputValue:function(e,t){var n=this.chart.options.rangeSelector;u(t)&&(this[e+"Input"].HCTime=t),this[e+"Input"].value=H(n.inputEditDateFormat||"%Y-%m-%d",this[e+"Input"].HCTime),this[e+"DateBox"].attr({text:H(n.inputDateFormat||"%b %e, %Y",this[e+"Input"].HCTime)})},showInput:function(e){var t=this.inputGroup,n=this[e+"DateBox"];p(this[e+"Input"],{left:t.translateX+n.x+Xe,top:t.translateY+Xe,width:n.width-2+Xe,height:n.height-2+Xe,border:"2px solid silver"})},hideInput:function(e){document.activeElement===this[e+"Input"]&&(p(this[e+"Input"],{border:0,width:"1px",height:"1px"}),this.setInputValue(e))},drawInput:function(n){var r,a,o,i=this,s=i.chart,l=s.renderer.style,u=s.renderer,c=s.options.rangeSelector,d=U.lang,p=i.div,h="min"===n,m=this.inputGroup;this[n+"Label"]=a=u.label(d[h?"rangeSelectorFrom":"rangeSelectorTo"],this.inputGroup.offset).attr({padding:2}).css(e(l,c.labelStyle)).add(m),m.offset+=a.width+5,this[n+"DateBox"]=o=u.label("",m.offset).attr({padding:2,width:c.inputBoxWidth||90,height:c.inputBoxHeight||17,stroke:c.inputBoxBorderColor||"silver","stroke-width":1}).css(e({textAlign:"center",color:"#444"},l,c.inputStyle)).on("click",function(){i.showInput(n),i[n+"Input"].focus()}).add(m),m.offset+=o.width+(h?10:0),this[n+"Input"]=r=f("input",{name:n,className:Ge+"range-selector",type:"text"},it({position:We,border:0,width:"1px",height:"1px",padding:0,textAlign:"center",fontSize:l.fontSize,fontFamily:l.fontFamily,top:s.plotTop+Xe},c.inputStyle),p),r.onfocus=function(){i.showInput(n)},r.onblur=function(){i.hideInput(n)},r.onchange=function(){var e=r.value,n=(c.inputDateParser||Y.parse)(e),a=s.xAxis[0],o=a.dataMin,l=a.dataMax;isNaN(n)&&(n=e.split("-"),n=Y.UTC(t(n[0]),t(n[1])-1,t(n[2]))),isNaN(n)||(U.global.useUTC||(n+=60*(new Y).getTimezoneOffset()*1e3),h?n>i.maxInput.HCTime?n=B:o>n&&(n=o):nl&&(n=l),n!==B&&s.xAxis[0].setExtremes(h?n:a.min,h?a.max:n,B,B,{trigger:"rangeSelectorInput"}))}},getPosition:function(){var e=this.chart,t=e.options.rangeSelector,n=st((t.buttonPosition||{}).y,e.plotTop-e.axisOffset[0]-35);return{buttonTop:n,inputTop:n-10}},render:function(e,t){var n,r,a=this,o=a.chart,i=o.renderer,s=o.container,l=o.options,c=l.exporting&&l.navigation&&l.navigation.buttonOptions,d=l.rangeSelector,p=a.buttons,h=U.lang,m=a.div,g=a.inputGroup,y=d.buttonTheme,b=d.buttonPosition||{},v=d.inputEnabled,_=y&&y.states,w=o.plotLeft,k=this.getPosition(),E=a.group;a.rendered||(a.group=E=i.g("range-selector-buttons").add(),a.zoomText=i.text(h.rangeSelectorZoom,st(b.x,w),k.buttonTop+15).css(d.labelStyle).add(E),n=st(b.x,w)+a.zoomText.getBBox().width+5,ht(a.buttonOptions,function(e,t){p[t]=i.button(e.text,n,k.buttonTop,function(){a.clickButton(t),a.isActive=!0},y,_&&_.hover,_&&_.select,_&&_.disabled).css({textAlign:"center"}).add(E),n+=p[t].width+st(d.buttonSpacing,5),a.selected===t&&p[t].setState(2)}),a.updateButtonStates(),v!==!1&&(a.div=m=f("div",null,{position:"relative",height:0,zIndex:1}),s.parentNode.insertBefore(m,s),a.inputGroup=g=i.g("input-group").add(),g.offset=0,a.drawInput("min"),a.drawInput("max"))),v!==!1&&(g.align(it({y:k.inputTop,width:g.offset,x:c&&k.inputTop<(c.y||0)+c.height-o.spacing[0]?-40:0},d.inputPosition),!0,o.spacingBox),u(v)||(r=E.getBBox(),g[g.translateX.7&&1.3>s&&(r?o=i-a:i=o+a),{min:o,max:i}},lt(Kt.prototype,"init",function(e,t,n){bt(this,"init",function(){this.options.rangeSelector.enabled&&(this.rangeSelector=new R(this))}),e.call(this,t,n)}),de.RangeSelector=R,Kt.prototype.callbacks.push(function(e){function t(){i=e.xAxis[0].getExtremes(),s.render(i.min,i.max)}function n(){i=e.xAxis[0].getExtremes(),isNaN(i.min)||l.render(i.min,i.max)}function r(e){"navigator-drag"!==e.triggerOp&&s.render(e.min,e.max)}function a(e){l.render(e.min,e.max)}function o(){s&&vt(e.xAxis[0],"afterSetExtremes",r),l&&(vt(e,"resize",n),vt(e.xAxis[0],"afterSetExtremes",a))}var i,s=e.scroller,l=e.rangeSelector;s&&(bt(e.xAxis[0],"afterSetExtremes",r),lt(e,"drawChartBox",function(e){var n=this.isDirtyBox;e.call(this),n&&t()}),t()),l&&(bt(e.xAxis[0],"afterSetExtremes",a),bt(e,"resize",n),n()),bt(e,"destroy",o)}),de.StockChart=function(t,n){var r,a=t.series,o=st(t.navigator&&t.navigator.enabled,!0),i=o?{startOnTick:!1,endOnTick:!1}:null,s={marker:{enabled:!1,radius:2}},l={shadow:!1,borderWidth:0};return t.xAxis=yt(d(t.xAxis||{}),function(t){return e({minPadding:0,maxPadding:0,ordinal:!0,title:{text:null},labels:{overflow:"justify"},showLastLabel:!0},t,{type:"datetime",categories:null},i)}),t.yAxis=yt(d(t.yAxis||{}),function(t){return r=st(t.opposite,!0),e({labels:{y:-2},opposite:r,showLastLabel:!1,title:{text:null}},t)}),t.series=null,t=e({chart:{panning:!0,pinchType:"x"},navigator:{enabled:!0},scrollbar:{enabled:!0},rangeSelector:{enabled:!0},title:{text:null,style:{fontSize:"16px"}},tooltip:{shared:!0,crosshairs:!0},legend:{enabled:!1},plotOptions:{line:s,spline:s,area:s,areaspline:s,arearange:s,areasplinerange:s,column:l,columnrange:l,candlestick:l,ohlc:l}},t,{_stock:!0,chart:{inverted:!1}}),t.series=a,new Kt(t,n)},lt(Lt.prototype,"init",function(e,t,n){var r=n.chart.pinchType||"";e.call(this,t,n),this.pinchX=this.pinchHor=-1!==r.indexOf("x"),this.pinchY=this.pinchVert=-1!==r.indexOf("y"),this.hasZoom=this.hasZoom||this.pinchHor||this.pinchVert}),lt(It.prototype,"autoLabelAlign",function(e){var t,n=this.chart,r=this.options,a=n._labelPanes=n._labelPanes||{},o=this.options.labels;return this.chart.options._stock&&"yAxis"===this.coll&&(t=r.top+","+r.height,!a[t]&&o.enabled)?(15===o.x&&(o.x=0),void 0===o.align&&(o.align="right"),a[t]=1,"right"):e.call(this,[].slice.call(arguments,1))}),lt(It.prototype,"getPlotLinePath",function(e,t,n,r,a,o){var i,s,l,c,d,p,f=this,h=this.isLinked&&!this.series?this.linkedParent.series:this.series,m=f.chart,g=m.renderer,y=f.left,b=f.top,v=[],_=[];return"colorAxis"===f.coll?e.apply(this,[].slice.call(arguments,1)):(_=f.isXAxis?u(f.options.yAxis)?[m.yAxis[f.options.yAxis]]:yt(h,function(e){return e.yAxis}):u(f.options.xAxis)?[m.xAxis[f.options.xAxis]]:yt(h,function(e){return e.xAxis}),d=f.isXAxis?m.yAxis:m.xAxis,ht(d,function(e){if(u(e.options.id)?-1===e.options.id.indexOf("navigator"):!0){var t=e.isXAxis?"yAxis":"xAxis",n=u(e.options[t])?m[t][e.options[t]]:m[t][0];f===n&&_.push(e)}}),p=_.length?[]:[f.isXAxis?m.yAxis[0]:m.xAxis[0]],ht(_,function(e){-1===ft(e,p)&&p.push(e)}),o=st(o,f.translate(t,null,null,r)),isNaN(o)||(f.horiz?ht(p,function(e){var t;s=e.pos,c=s+e.len,i=l=me(o+f.transB),(y>i||i>y+f.width)&&(a?i=l=ve(be(y,i),y+f.width):t=!0),t||v.push("M",i,s,"L",l,c)}):ht(p,function(e){var t;i=e.pos,l=i+e.len,s=c=me(b+f.height-o),(b>s||s>b+f.height)&&(a?s=c=ve(be(b,s),f.top+f.height):t=!0),t||v.push("M",i,s,"L",l,c)})),v.length>0?g.crispPolyLine(v,n||1):null)}),It.prototype.getPlotBandPath=function(e,t){var n,r=this.getPlotLinePath(t,null,null,!0),a=this.getPlotLinePath(e,null,null,!0),o=[];if(a&&r&&a.toString()!==r.toString())for(n=0;na||a>h+this.height)return void this.hideCrosshair();g||l.formatter||(this.isDatetimeAxis&&(y="%b %d, %Y"),g="{value"+(y?":"+y:"")+"}"),m.attr({text:g?v(g,{value:n[c]}):l.formatter.call(this,n[c]),x:r,y:a,visibility:Ye}),o=m.getBBox(),d?("inside"===this.options.tickPosition&&!p||"inside"!==this.options.tickPosition&&p)&&(a=m.y-o.height):a=m.y-o.height/2,i=d?{left:f-o.x,right:f+this.width-o.x}:{left:"left"===this.labelAlign?f:0,right:"right"===this.labelAlign?f+this.width:s.chartWidth},m.translateX=i.right&&(r-=m.translateX+o.width-i.right),m.attr({x:r,y:a,visibility:Ye})}});var Sn=un.init,Pn=un.processData,An=Yt.prototype.tooltipFormatter;un.init=function(){Sn.apply(this,arguments),this.setCompare(this.options.compare)},un.setCompare=function(e){this.modifyValue="value"===e||"percent"===e?function(t,n){var r=this.compareValue;return t!==B&&(t="value"===e?t-r:t=100*(t/r)-100,n&&(n.change=t)),t}:null,this.chart.hasRendered&&(this.isDirty=!0)},un.processData=function(){var e,t,n,r=this,a=0;if(Pn.apply(this,arguments),r.xAxis&&r.processedYData)for(e=r.processedXData,t=r.processedYData,n=t.length;n>a;a++)if(typeof t[a]===mn&&e[a]>=r.xAxis.min){r.compareValue=t[a];break}},lt(un,"getExtremes",function(e){e.apply(this,[].slice.call(arguments,1)),this.modifyValue&&(this.dataMax=this.modifyValue(this.dataMax),this.dataMin=this.modifyValue(this.dataMin))}),It.prototype.setCompare=function(e,t){this.isXAxis||(ht(this.series,function(t){t.setCompare(e)}),st(t,!0)&&this.chart.redraw())},Yt.prototype.tooltipFormatter=function(e){var t=this;return e=e.replace("{point.change}",(t.change>0?"+":"")+de.numberFormat(t.change,st(t.series.tooltipOptions.changeDecimals,2))),An.apply(this,[e])},lt(Xt.prototype,"render",function(t){this.chart.options._stock&&(!this.clipBox&&this.animate?(this.clipBox=e(this.chart.clipBox),this.clipBox.width=this.xAxis.len,this.clipBox.height=this.yAxis.len):this.chart[this.sharedClipKey]&&(Et(this.chart[this.sharedClipKey]),this.chart[this.sharedClipKey].attr({width:this.xAxis.len,height:this.yAxis.len}))),t.call(this)}),it(de,{Color:jt,Point:Yt,Tick:N,Renderer:L,SVGElement:M,SVGRenderer:Ct,arrayMin:E,arrayMax:x,charts:Le,dateFormat:H,error:P,format:v,pathAnim:V,getOptions:D,hasBidiBug:Ne,isTouchDevice:Te,setOptions:T,addEvent:bt,removeEvent:vt,createElement:f,discardElement:S,css:p,each:ht,map:yt,merge:e,splat:d,extendClass:h,pInt:t,svg:Me,canvas:ze,vml:!Me&&!ze,product:Fe,version:Ue})}(),e.exports=Highcharts}])})},,,,function(e,t,n){var r=n(196),a=n(783),o=n(784),i=n(786),s=n(787),l=(n(788),r.createClass({displayName:"NotificationSystem",uid:3400,_getStyles:{overrideStyle:{},overrideWidth:null,setOverrideStyle:function(e){this.overrideStyle=e},wrapper:function(){if(!this.overrideStyle)return{};this.overrideStyle.Wrapper||{};return a({},s.Wrapper,this.overrideStyle)},container:function(e){if(!this.overrideStyle)return{};var t=this.overrideStyle.Containers||{};return this.overrideWidth=s.Containers.DefaultStyle.width,t.DefaultStyle&&t.DefaultStyle.width&&(this.overrideWidth=t.DefaultStyle.width),t[e]&&t[e].width&&(this.overrideWidth=t[e].width),a({},s.Containers.DefaultStyle,s.Containers[e],t.DefaultStyle,t[e])},notification:function(e){if(!this.overrideStyle)return{};var t=this.overrideStyle.NotificationItem||{};return a({},s.NotificationItem.DefaultStyle,s.NotificationItem[e],t.DefaultStyle,t[e])},title:function(e){if(!this.overrideStyle)return{};var t=this.overrideStyle.Title||{};return a({},s.Title.DefaultStyle,s.Title[e],t.DefaultStyle,t[e])},messageWrapper:function(e){if(!this.overrideStyle)return{};var t=this.overrideStyle.MessageWrapper||{};return a({},s.MessageWrapper.DefaultStyle,s.MessageWrapper[e],t.DefaultStyle,t[e])},dismiss:function(e){if(!this.overrideStyle)return{};var t=this.overrideStyle.Dismiss||{};return a({},s.Dismiss.DefaultStyle,s.Dismiss[e],t.DefaultStyle,t[e])},action:function(e){if(!this.overrideStyle)return{};var t=this.overrideStyle.Action||{};return a({},s.Action.DefaultStyle,s.Action[e],t.DefaultStyle,t[e])},actionWrapper:function(e){if(!this.overrideStyle)return{};var t=this.overrideStyle.ActionWrapper||{};return a({},s.ActionWrapper.DefaultStyle,s.ActionWrapper[e],t.DefaultStyle,t[e])}},_didNotificationRemoved:function(e){var t,n=this.state.notifications.filter(function(n){return n.uid===e&&(t=n),n.uid!==e});t&&t.onRemove&&t.onRemove(t),this.setState({notifications:n})},getInitialState:function(){return{notifications:[]}},getDefaultProps:function(){return{style:{},noAnimation:!1}},addNotification:function(e){var e=a({},i.notification,e),t=!1;try{if(!e.level)throw"notification level is required.";if(isNaN(e.autoDismiss))throw"'autoDismiss' must be a number.";if(-1===Object.keys(i.positions).indexOf(e.position))throw"'"+e.position+"' is not a valid position.";if(-1===Object.keys(i.levels).indexOf(e.level))throw"'"+e.level+"' is not a valid level.";if(!e.dismissible&&!e.action)throw"You need to set notification dismissible to true or set an action, otherwise user will not be able to dismiss the notification."}catch(n){t=!0,console.error("Error adding notification: "+n)}if(!t){var r=this.state.notifications;e.position=e.position.toLowerCase(),e.level=e.level.toLowerCase(),e.autoDismiss=parseInt(e.autoDismiss),e.uid=e.uid||this.uid,e.ref="notification-"+e.uid,this.uid+=1;for(var o=0;o-1&&this.props.notifications.reverse();var t=this.props.notifications.map(function(t){return r.createElement(a,{key:t.uid,notification:t,getStyles:e.props.getStyles,onRemove:e.props.onRemove,noAnimation:e.props.noAnimation,allowHTML:e.props.allowHTML})});return r.createElement("div",{className:"notifications-"+this.props.position,style:this._style},t)}}));e.exports=i},function(e,t,n){function r(){var e,t=document.createElement("fakeelement"),n={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(e in n)if(void 0!==t.style[e])return n[e]}var a=n(196),o=(n(783),n(786)),i=(n(787),n(788)),s=a.createClass({displayName:"NotificationItem",propTypes:{notification:a.PropTypes.object,onRemove:a.PropTypes.func,allowHTML:a.PropTypes.bool},getDefaultProps:function(){return{noAnimation:!1,onRemove:function(e){},allowHTML:!1}},getInitialState:function(){return{visible:!1,removed:!1}},componentWillMount:function(){var e=this.props.getStyles,t=this.props.notification.level;this._noAnimation=this.props.noAnimation,this._styles={notification:e.notification(t),title:e.title(t),dismiss:e.dismiss(t),messageWrapper:e.messageWrapper(t),actionWrapper:e.actionWrapper(t),action:e.action(t)},this.props.notification.dismissible||(this._styles.notification.cursor="default")},_styles:{},_notificationTimer:null,_height:0,_noAnimation:null,_getCssPropertyByPosition:function(){var e=this.props.notification.position,t={};switch(e){case o.positions.tl:case o.positions.bl:t={property:"left",value:-200};break;case o.positions.tr:case o.positions.br:t={property:"right",value:-200};break;case o.positions.tc:t={property:"top",value:-100};break;case o.positions.bc:t={property:"bottom",value:-100}}return t},_defaultAction:function(e){e.preventDefault();var t=this.props.notification;this._hideNotification(),t.action.callback()},_hideNotification:function(){this._notificationTimer&&this._notificationTimer.clear(),this.isMounted()&&this.setState({visible:!1,removed:!0}),this._noAnimation&&this._removeNotification()},_removeNotification:function(){this.props.onRemove(this.props.notification.uid)},_dismiss:function(){this.props.notification.dismissible&&this._hideNotification()},_showNotification:function(){var e=this;setTimeout(function(){e.setState({visible:!0})},50)},componentDidMount:function(){var e=this,t=r(),n=this.props.notification,o=a.findDOMNode(this);this._height=o.offsetHeight;var s=0;this._noAnimation||(t?o.addEventListener(t,function(){s>0||e.state.removed&&(s++,e._removeNotification())}):this._noAnimation=!0),n.autoDismiss&&(this._notificationTimer=new i.timer(function(){e._hideNotification()},1e3*n.autoDismiss),o.addEventListener("mouseenter",function(){e._notificationTimer.pause()}),o.addEventListener("mouseleave",function(){e._notificationTimer.resume()})),this._showNotification()},_allowHTML:function(e){return{__html:e}},render:function(){var e=this.props.notification,t="notification notification-"+e.level;if(t+=this.state.visible?" notification-visible":" notification-hidden",e.dismissible||(t+=" notification-not-dismissible"),this.props.getStyles.overrideStyle){var n=this._getCssPropertyByPosition();this.state.visible||this.state.removed||(this._styles.notification[n.property]=n.value),this.state.visible&&!this.state.removed&&(this._styles.notification.height=this._height,this._styles.notification[n.property]=0),this.state.removed&&(this._styles.notification.overlay="hidden",this._styles.notification.height=0,this._styles.notification.marginTop=0,this._styles.notification.paddingTop=0,this._styles.notification.paddingBottom=0),this._styles.notification.opacity=this.state.visible?this._styles.notification.isVisible.opacity:this._styles.notification.isHidden.opacity}var r=null,o=null,i=null,s=null;return e.title&&(i=a.createElement("h4",{className:"notification-title",style:this._styles.title},e.title)),e.message&&(s=this.props.allowHTML?a.createElement("div",{className:"notification-message",style:this._styles.messageWrapper,dangerouslySetInnerHTML:this._allowHTML(e.message)}):a.createElement("div",{className:"notification-message",style:this._styles.messageWrapper},e.message)),e.dismissible&&(r=a.createElement("span",{className:"notification-dismiss",style:this._styles.dismiss},"×")),e.action&&(o=a.createElement("div",{className:"notification-action-wrapper",style:this._styles.actionWrapper},a.createElement("button",{className:"notification-action-button",onClick:this._defaultAction,style:this._styles.action},e.action.label))),a.createElement("div",{className:t,onClick:this._dismiss,style:this._styles.notification},i,s,r,o)}});e.exports=s},function(e,t){var n={positions:{tl:"tl",tr:"tr",tc:"tc",bl:"bl",br:"br",bc:"bc"},levels:{success:"success",error:"error",warning:"warning",info:"info"},notification:{title:null,message:null,level:null,position:"tr",autoDismiss:5,dismissible:!0,action:null}};e.exports=n},function(e,t){var n=320,r={success:"#5ea400",error:"#ec3d3d",warning:"#ebad1a",info:"#369cc7"},a={Wrapper:{},Containers:{DefaultStyle:{fontFamily:"inherit",position:"fixed",width:n,padding:"0 10px 10px 10px",zIndex:9998,WebkitBoxSizing:"border-box",MozBoxSizing:"border-box",boxSizing:"border-box",height:"auto"},tl:{top:"0px",bottom:"auto",left:"0px",right:"auto"},tr:{top:"0px",bottom:"auto",left:"auto",right:"0px"},tc:{top:"0px",bottom:"auto",margin:"0 auto",left:"50%",marginLeft:-(n/2)},bl:{top:"auto",bottom:"0px",left:"0px",right:"auto"},br:{top:"auto",bottom:"0px",left:"auto",right:"0px"},bc:{top:"auto",bottom:"0px",margin:"0 auto",left:"50%",marginLeft:-(n/2)}},NotificationItem:{DefaultStyle:{position:"relative",width:"100%",cursor:"pointer",borderRadius:"2px",fontSize:"13px",border:"1px solid",borderTopWidth:"4px",margin:"10px 0 0",padding:"10px",display:"block",WebkitBoxSizing:"border-box",MozBoxSizing:"border-box",boxSizing:"border-box",WebkitBoxShadow:"0px 0px 5px 2px rgba(0,0,0,0.1)",MozBoxShadow:"0px 0px 5px 2px rgba(0,0,0,0.1)",boxShadow:"0px 0px 5px 2px rgba(0,0,0,0.1)",opacity:0,transition:"0.3s ease-in-out",isHidden:{opacity:0},isVisible:{opacity:.9}},success:{borderColor:"#d0ddbe",borderTopColor:r.success,backgroundColor:"#f0f5ea",color:"#4b583a"},error:{borderColor:"#edbfbf",borderTopColor:r.error,backgroundColor:"#f4e9e9",color:"#412f2f"},warning:{borderColor:"#ecd9ab",borderTopColor:r.warning,backgroundColor:"#f9f6f0",color:"#5a5343"},info:{borderColor:"#b2d0dd",borderTopColor:r.info,backgroundColor:"#e8f0f4",color:"#41555d"}},Title:{DefaultStyle:{fontSize:"14px",margin:"0 0 5px 0",padding:0,fontWeight:"bold"},success:{color:r.success},error:{color:r.error},warning:{color:r.warning},info:{color:r.info}},MessageWrapper:{DefaultStyle:{margin:0,padding:0}},Dismiss:{DefaultStyle:{fontFamily:"Arial",fontSize:"17px",position:"absolute",top:"4px",right:"5px",lineHeight:"15px",backgroundColor:"#dededf",color:"#ffffff",borderRadius:"50%",width:"14px",height:"14px",fontWeight:"bold",textAlign:"center"},success:{color:"#f0f5ea",backgroundColor:"#b0ca92"},error:{color:"#f4e9e9",backgroundColor:"#e4bebe"},warning:{color:"#f9f6f0",backgroundColor:"#e1cfac"},info:{color:"#e8f0f4",backgroundColor:"#a4becb"}},Action:{DefaultStyle:{background:"#ffffff",borderRadius:"2px",padding:"6px 20px",fontWeight:"bold",margin:"10px 0 0 0",border:0},success:{backgroundColor:r.success,color:"#ffffff"},error:{backgroundColor:r.error,color:"#ffffff"},warning:{backgroundColor:r.warning,color:"#ffffff"},info:{backgroundColor:r.info,color:"#ffffff"}},ActionWrapper:{DefaultStyle:{margin:0,padding:0}}};e.exports=a},function(e,t){var n={timer:function(e,t){var n,r,a=t;this.pause=function(){clearTimeout(n),a-=new Date-r},this.resume=function(){r=new Date,clearTimeout(n),n=setTimeout(e,a)},this.clear=function(){clearTimeout(n)},this.resume()}};e.exports=n},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;nr;r++)n[r]=arguments[r];n.forEach(function(t){return e[t]=e[t].bind(e)})}}]),i(t,[{key:"componentDidMount",value:function(){this._updatePosition(),this.bindListener()}},{key:"componentWillUnmount",value:function(){this.unbindListener()}},{key:"componentWillUpdate",value:function(){this.unbindListener()}},{key:"componentDidUpdate",value:function(){this._updatePosition(),this.bindListener()}},{key:"bindListener",value:function(){for(var e=document.querySelectorAll("[data-tip]"),t=0;t0)if("float"===this.state.effect)this.setState({show:!0,x:e.clientX,y:e.clientY});else if("solid"===this.state.effect){var t=e.target.getBoundingClientRect().top,n=e.target.getBoundingClientRect().left,r=u["default"].findDOMNode(this),a=r.clientWidth,o=r.clientHeight,i=e.target.clientWidth,s=e.target.clientHeight,l=this.state.place,c=void 0,d=void 0;"top"===l?(c=n-a/2+i/2,d=t-o-8):"bottom"===l?(c=n-a/2+i/2,d=t+s+8):"left"===l?(c=n-a-6,d=t+s/2-o/2):"right"===l&&(c=n+i+6,d=t+s/2-o/2),this.setState({show:!0,x:"NONE"===this.state.x?c:this.state.x,y:"NONE"===this.state.y?d:this.state.y})}}},{key:"hideTooltip",value:function(e){this.setState({show:!1,x:"NONE",y:"NONE"})}},{key:"render",value:function(){var e=d["default"]("reactTooltip",{show:this.state.show},{"place-top":"top"===this.state.place},{"place-bottom":"bottom"===this.state.place},{"place-left":"left"===this.state.place},{"place-right":"right"===this.state.place},{"type-dark":"dark"===this.state.type},{"type-success":"success"===this.state.type},{"type-warning":"warning"===this.state.type},{"type-error":"error"===this.state.type},{"type-info":"info"===this.state.type},{"type-light":"light"===this.state.type});return u["default"].createElement("span",{className:e,"data-id":"tooltip"},this.state.placeholder)}},{key:"trim",value:function(e){for(var t=e.split(""),n=0,r=0,a=0;a=0&&" "===e[a];a--)r++;return t.splice(0,n),t.splice(-r,r),t.join("")}}]),t}(u["default"].Component);p.displayName="ReactTooltip",p.propTypes={place:l.PropTypes.string,type:l.PropTypes.string,effect:l.PropTypes.string,positon:l.PropTypes.object},t["default"]=p,e.exports=t["default"]},function(e,t,n){/*! + Copyright (c) 2015 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames + */ +function r(){for(var e,t="",n=0;n | MIT +var a;a=r(),e.exports.LZMA=function(){return a},e.exports.compress=a.compress,e.exports.decompress=a.decompress},function(e,t,n){(function(e){function n(e,t){for(var n=0,r=e.length-1;r>=0;r--){var a=e[r];"."===a?e.splice(r,1):".."===a?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r=-1&&!a;o--){var i=o>=0?arguments[o]:e.cwd();if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(t=i+"/"+t,a="/"===i.charAt(0))}return t=n(r(t.split("/"),function(e){return!!e}),!a).join("/"),(a?"/":"")+t||"."},t.normalize=function(e){var a=t.isAbsolute(e),o="/"===i(e,-1);return e=n(r(e.split("/"),function(e){return!!e}),!a).join("/"),e||a||(e="."),e&&o&&(e+="/"),(a?"/":"")+e},t.isAbsolute=function(e){return"/"===e.charAt(0)},t.join=function(){var e=Array.prototype.slice.call(arguments,0);return t.normalize(r(e,function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e}).join("/"))},t.relative=function(e,n){function r(e){for(var t=0;t=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=t.resolve(e).substr(1),n=t.resolve(n).substr(1);for(var a=r(e.split("/")),o=r(n.split("/")),i=Math.min(a.length,o.length),s=i,l=0;i>l;l++)if(a[l]!==o[l]){s=l;break}for(var u=[],l=s;lt&&(t=e.length+t),e.substr(t,n)}}).call(t,n(175))},function(e,t,n){function r(e){return n(a(e))}function a(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./src/lzma_worker.js":838};r.keys=function(){return Object.keys(o)},r.resolve=a,e.exports=r,r.id=837},function(e,t,n){(function(e){var t=function(){"use strict";function n(e,t){postMessage({action:Rt,cbn:t,result:e})}function r(e){var t=[];return t[e-1]=void 0,t}function a(e,t){return s(e[0]+t[0],e[1]+t[1])}function o(e,t){return d(~~Math.max(Math.min(e[1]/Lt,2147483647),-2147483648)&~~Math.max(Math.min(t[1]/Lt,2147483647),-2147483648),c(e)&c(t))}function i(e,t){var n,r;return e[0]==t[0]&&e[1]==t[1]?0:(n=e[1]<0,r=t[1]<0,n&&!r?-1:!n&&r?1:g(e,t)[1]<0?-1:1)}function s(e,t){var n,r;for(t%=0x10000000000000000,e%=0x10000000000000000,n=t%Lt,r=Math.floor(e/Lt)*Lt,t=t-n+r,e=e-r+n;0>e;)e+=Lt,t-=Lt;for(;e>4294967295;)e-=Lt,t+=Lt;for(t%=0x10000000000000000;t>0x7fffffff00000000;)t-=0x10000000000000000;for(;-0x8000000000000000>t;)t+=0x10000000000000000;return[e,t]}function l(e,t){return e[0]==t[0]&&e[1]==t[1]}function u(e){return e>=0?[e,0]:[e+Lt,-Lt]}function c(e){return e[0]>=2147483648?~~Math.max(Math.min(e[0]-Lt,2147483647),-2147483648):~~Math.max(Math.min(e[0],2147483647),-2147483648)}function d(e,t){var n,r;return n=e*Lt,r=t,0>t&&(r+=Lt),[r,n]}function p(e){return 30>=e?1<=0x8000000000000000&&(r-=0x10000000000000000),[a,r]}function h(e,t){var n;return t&=63,n=p(t),s(Math.floor(e[0]/n),e[1]/n)}function m(e,t){var n;return t&=63,n=h(e,t),e[1]<0&&(n=a(n,f([2,0],63-t))),n}function g(e,t){return s(e[0]-t[0],e[1]-t[1])}function y(e,t){return e.buf=t,e.pos=0,e.count=t.length,e}function b(e){return e.pos>=e.count?-1:255&e.buf[e.pos++]}function v(e,t,n,r){return e.pos>=e.count?-1:(r=Math.min(r,e.count-e.pos),O(e.buf,e.pos,t,n,r),e.pos+=r,r)}function _(e){return e.buf=r(32),e.count=0,e}function w(e){var t=e.buf;return t.length=e.count,t}function k(e,t){e.buf[e.count++]=t<<24>>24}function E(e,t,n,r){O(t,n,e.buf,e.count,r),e.count+=r}function x(e,t,n,r,a){var o;for(o=t;n>o;++o)r[a++]=e.charCodeAt(o)}function O(e,t,n,r,a){for(var o=0;a>o;++o)n[r+o]=e[t+o]}function S(e,t){Le(t,1<s;s+=8)k(n,255&c(h(r,s)));e.chunker=(o._needReleaseMFStream=0,o._inStream=t,o._finished=0,Oe(o),o._rangeEncoder.Stream=n,Ne(o),Ae(o),Pe(o),o._lenEncoder._tableSize=o._numFastBytes+1-2,Ze(o._lenEncoder,1<a;++a){if(o=b(t),-1==o)throw new Error("truncated input");l[a]=o<<24>>24}if(r=se({}),!ue(r,l))throw new Error("corrupted input");for(a=0;64>a;a+=8){if(o=b(t),-1==o)throw new Error("truncated input");o=o.toString(16),1==o.length&&(o="0"+o),s=o+""+s}/^0+$|^f+$/i.test(s)?e.length_0=qt:(i=parseInt(s,16),i>4294967295?e.length_0=qt:e.length_0=u(i)),e.chunker=oe(r,t,n,e.length_0)}function C(e,t){return e.output=_({}),j(e,y({},t),e.output),e}function T(e,t,n,a){var o;e._keepSizeBefore=t,e._keepSizeAfter=n,o=t+n+a,(null==e._bufferBase||e._blockSize!=o)&&(e._bufferBase=null,e._blockSize=o,e._bufferBase=r(e._blockSize)),e._pointerToLastSafePosition=e._blockSize-n}function D(e,t){return e._bufferBase[e._bufferOffset+e._pos+t]}function M(e,t,n,r){var a,o;for(e._streamEndWasReached&&e._pos+t+r>e._streamPos&&(r=e._streamPos-(e._pos+t)),++n,o=e._bufferOffset+e._pos+t,a=0;r>a&&e._bufferBase[o+a]==e._bufferBase[o+a-n];++a);return a}function N(e){return e._streamPos-e._pos}function z(e){var t,n,r;for(r=e._bufferOffset+e._pos-e._keepSizeBefore,r>0&&--r,n=e._bufferOffset+e._streamPos-r,t=0;n>t;++t)e._bufferBase[t]=e._bufferBase[r+t];e._bufferOffset-=r}function I(e){var t;++e._pos,e._pos>e._posLimit&&(t=e._bufferOffset+e._pos,t>e._pointerToLastSafePosition&&z(e),R(e))}function R(e){var t,n,r;if(!e._streamEndWasReached)for(;;){if(r=-e._bufferOffset+e._blockSize-e._streamPos,!r)return;if(t=v(e._stream,e._bufferBase,e._bufferOffset+e._streamPos,r),-1==t)return e._posLimit=e._streamPos,n=e._bufferOffset+e._posLimit,n>e._pointerToLastSafePosition&&(e._posLimit=e._pointerToLastSafePosition-e._bufferOffset),void(e._streamEndWasReached=1);e._streamPos+=t,e._streamPos>=e._pos+e._keepSizeAfter&&(e._posLimit=e._streamPos-e._keepSizeAfter)}}function B(e,t){e._bufferOffset+=t,e._posLimit-=t,e._pos-=t,e._streamPos-=t}function L(e,t,n,a,o){var i,s,l;1073741567>t&&(e._cutValue=16+(a>>1),l=~~((t+n+a+o)/2)+256,T(e,t+n,a+o,l),e._matchMaxLen=a,i=t+1,e._cyclicBufferSize!=i&&(e._son=r(2*(e._cyclicBufferSize=i))),s=65536,e.HASH_ARRAY&&(s=t-1,s|=s>>1,s|=s>>2,s|=s>>4,s|=s>>8,s>>=1,s|=65535,s>16777216&&(s>>=1),e._hashMask=s,++s,s+=e.kFixHashSize),s!=e._hashSizeSum&&(e._hash=r(e._hashSizeSum=s)))}function q(e,t){var n,r,a,o,i,s,l,u,c,d,p,f,h,m,g,y,b,v,_,w,k;if(e._pos+e._matchMaxLen<=e._streamPos)m=e._matchMaxLen;else if(m=e._streamPos-e._pos,me._cyclicBufferSize?e._pos-e._cyclicBufferSize:0,r=e._bufferOffset+e._pos,y=1,u=0,c=0,e.HASH_ARRAY?(k=Wt[255&e._bufferBase[r]]^255&e._bufferBase[r+1],u=1023&k,k^=(255&e._bufferBase[r+2])<<8,c=65535&k,d=(k^Wt[255&e._bufferBase[r+3]]<<5)&e._hashMask):d=255&e._bufferBase[r]^(255&e._bufferBase[r+1])<<8,a=e._hash[e.kFixHashSize+d]||0,e.HASH_ARRAY&&(o=e._hash[u]||0,i=e._hash[1024+c]||0,e._hash[u]=e._pos,e._hash[1024+c]=e._pos,o>g&&e._bufferBase[e._bufferOffset+o]==e._bufferBase[r]&&(t[b++]=y=2,t[b++]=e._pos-o-1),i>g&&e._bufferBase[e._bufferOffset+i]==e._bufferBase[r]&&(i==o&&(b-=2),t[b++]=y=3,t[b++]=e._pos-i-1,o=i),0!=b&&o==a&&(b-=2,y=1)),e._hash[e.kFixHashSize+d]=e._pos,_=(e._cyclicBufferPos<<1)+1,w=e._cyclicBufferPos<<1,f=h=e.kNumHashDirectBytes,0!=e.kNumHashDirectBytes&&a>g&&e._bufferBase[e._bufferOffset+a+e.kNumHashDirectBytes]!=e._bufferBase[r+e.kNumHashDirectBytes]&&(t[b++]=y=e.kNumHashDirectBytes,t[b++]=e._pos-a-1),n=e._cutValue;;){if(g>=a||0==n--){e._son[_]=e._son[w]=0;break}if(l=e._pos-a,s=(l<=e._cyclicBufferPos?e._cyclicBufferPos-l:e._cyclicBufferPos-l+e._cyclicBufferSize)<<1,v=e._bufferOffset+a,p=h>f?f:h,e._bufferBase[v+p]==e._bufferBase[r+p]){for(;++p!=m&&e._bufferBase[v+p]==e._bufferBase[r+p];);if(p>y&&(t[b++]=y=p,t[b++]=l-1,p==m)){e._son[w]=e._son[s],e._son[_]=e._son[s+1];break}}(255&e._bufferBase[v+p])<(255&e._bufferBase[r+p])?(e._son[w]=a,w=s+1,a=e._son[w],h=p):(e._son[_]=a,_=s,a=e._son[_],f=p)}return U(e),b}function F(e){e._bufferOffset=0,e._pos=0,e._streamPos=0,e._streamEndWasReached=0,R(e),e._cyclicBufferPos=0,B(e,-1)}function U(e){var t;++e._cyclicBufferPos>=e._cyclicBufferSize&&(e._cyclicBufferPos=0),I(e),1073741823==e._pos&&(t=e._pos-e._cyclicBufferSize,H(e._son,2*e._cyclicBufferSize,t),H(e._hash,e._hashSizeSum,t),B(e,t))}function H(e,t,n){var r,a;for(r=0;t>r;++r)a=e[r]||0,n>=a?a=0:a-=n,e[r]=a}function W(e,t){e.HASH_ARRAY=t>2,e.HASH_ARRAY?(e.kNumHashDirectBytes=0,e.kMinMatchCheck=4,e.kFixHashSize=66560):(e.kNumHashDirectBytes=2,e.kMinMatchCheck=3,e.kFixHashSize=0)}function V(e,t){var n,r,a,o,i,s,l,u,c,d,p,f,h,m,g,y,b;do{if(e._pos+e._matchMaxLen<=e._streamPos)f=e._matchMaxLen;else if(f=e._streamPos-e._pos,fe._cyclicBufferSize?e._pos-e._cyclicBufferSize:0,r=e._bufferOffset+e._pos,e.HASH_ARRAY?(b=Wt[255&e._bufferBase[r]]^255&e._bufferBase[r+1],s=1023&b,e._hash[s]=e._pos,b^=(255&e._bufferBase[r+2])<<8,l=65535&b,e._hash[1024+l]=e._pos,u=(b^Wt[255&e._bufferBase[r+3]]<<5)&e._hashMask):u=255&e._bufferBase[r]^(255&e._bufferBase[r+1])<<8,a=e._hash[e.kFixHashSize+u],e._hash[e.kFixHashSize+u]=e._pos,g=(e._cyclicBufferPos<<1)+1,y=e._cyclicBufferPos<<1,d=p=e.kNumHashDirectBytes,n=e._cutValue;;){if(h>=a||0==n--){e._son[g]=e._son[y]=0;break}if(i=e._pos-a,o=(i<=e._cyclicBufferPos?e._cyclicBufferPos-i:e._cyclicBufferPos-i+e._cyclicBufferSize)<<1,m=e._bufferOffset+a,c=p>d?d:p,e._bufferBase[m+c]==e._bufferBase[r+c]){for(;++c!=f&&e._bufferBase[m+c]==e._bufferBase[r+c];);if(c==f){e._son[y]=e._son[o],e._son[g]=e._son[o+1];break}}(255&e._bufferBase[m+c])<(255&e._bufferBase[r+c])?(e._son[y]=a,y=o+1,a=e._son[y],p=c):(e._son[g]=a,g=o,a=e._son[g],d=c)}U(e)}while(0!=--t)}function K(e,t,n){var r=e._pos-t-1;for(0>r&&(r+=e._windowSize);0!=n;--n)r>=e._windowSize&&(r=0),e._buffer[e._pos++]=e._buffer[r++],e._pos>=e._windowSize&&Y(e)}function G(e,t){(null==e._buffer||e._windowSize!=t)&&(e._buffer=r(t)),e._windowSize=t,e._pos=0,e._streamPos=0}function Y(e){var t=e._pos-e._streamPos;t&&(E(e._stream,e._buffer,e._streamPos,t),e._pos>=e._windowSize&&(e._pos=0),e._streamPos=e._pos)}function X(e,t){var n=e._pos-t-1;return 0>n&&(n+=e._windowSize),e._buffer[n]}function J(e,t){e._buffer[e._pos++]=t,e._pos>=e._windowSize&&Y(e)}function $(e){Y(e),e._stream=null}function Z(e){return e-=2,4>e?e:3}function Q(e){return 4>e?0:10>e?e-3:e-6}function ee(e,t){return e.encoder=t,e.decoder=null,e.alive=1,e}function te(e,t){return e.decoder=t,e.encoder=null,e.alive=1,e}function ne(e){if(!e.alive)throw new Error("bad state");return e.encoder?ae(e):re(e),e.alive}function re(e){var t=ie(e.decoder);if(-1==t)throw new Error("corrupted input");e.inBytesProcessed=qt,e.outBytesProcessed=e.decoder.nowPos64,(t||i(e.decoder.outSize,Ut)>=0&&i(e.decoder.nowPos64,e.decoder.outSize)>=0)&&(Y(e.decoder.m_OutWindow),$(e.decoder.m_OutWindow),e.decoder.m_RangeDecoder.Stream=null,e.alive=0)}function ae(e){xe(e.encoder,e.encoder.processedInSize,e.encoder.processedOutSize,e.encoder.finished),e.inBytesProcessed=e.encoder.processedInSize[0],e.encoder.finished[0]&&(Be(e.encoder),e.alive=0)}function oe(e,t,n,r){return e.m_RangeDecoder.Stream=t,$(e.m_OutWindow),e.m_OutWindow._stream=n,le(e),e.state=0,e.rep0=0,e.rep1=0,e.rep2=0,e.rep3=0,e.outSize=r,e.nowPos64=Ut,e.prevByte=0,te({},e)}function ie(e){var t,n,r,o,s,l;if(l=c(e.nowPos64)&e.m_PosStateMask,vt(e.m_RangeDecoder,e.m_IsMatchDecoders,(e.state<<4)+l)){if(vt(e.m_RangeDecoder,e.m_IsRepDecoders,e.state))r=0,vt(e.m_RangeDecoder,e.m_IsRepG0Decoders,e.state)?(vt(e.m_RangeDecoder,e.m_IsRepG1Decoders,e.state)?(vt(e.m_RangeDecoder,e.m_IsRepG2Decoders,e.state)?(n=e.rep3,e.rep3=e.rep2):n=e.rep2,e.rep2=e.rep1):n=e.rep1,e.rep1=e.rep0,e.rep0=n):vt(e.m_RangeDecoder,e.m_IsRep0LongDecoders,(e.state<<4)+l)||(e.state=e.state<7?9:11,r=1),r||(r=fe(e.m_RepLenDecoder,e.m_RangeDecoder,l)+2,e.state=e.state<7?8:11);else if(e.rep3=e.rep2,e.rep2=e.rep1,e.rep1=e.rep0,r=2+fe(e.m_LenDecoder,e.m_RangeDecoder,l),e.state=e.state<7?7:10,s=ut(e.m_PosSlotDecoder[Z(r)],e.m_RangeDecoder),s>=4){if(o=(s>>1)-1,e.rep0=(2|1&s)<s)e.rep0+=dt(e.m_PosDecoders,e.rep0-s-1,e.m_RangeDecoder,o);else if(e.rep0+=_t(e.m_RangeDecoder,o-4)<<4,e.rep0+=ct(e.m_PosAlignDecoder,e.m_RangeDecoder),e.rep0<0)return-1==e.rep0?1:-1}else e.rep0=s;if(i(u(e.rep0),e.nowPos64)>=0||e.rep0>=e.m_DictionarySizeCheck)return-1;K(e.m_OutWindow,e.rep0,r),e.nowPos64=a(e.nowPos64,u(r)),e.prevByte=X(e.m_OutWindow,0)}else t=ye(e.m_LiteralDecoder,c(e.nowPos64),e.prevByte),e.state<7?e.prevByte=ve(t,e.m_RangeDecoder):e.prevByte=_e(t,e.m_RangeDecoder,X(e.m_OutWindow,e.rep0)),J(e.m_OutWindow,e.prevByte),e.state=Q(e.state),e.nowPos64=a(e.nowPos64,Ht);return 0}function se(e){e.m_OutWindow={},e.m_RangeDecoder={},e.m_IsMatchDecoders=r(192),e.m_IsRepDecoders=r(12),e.m_IsRepG0Decoders=r(12),e.m_IsRepG1Decoders=r(12),e.m_IsRepG2Decoders=r(12),e.m_IsRep0LongDecoders=r(192),e.m_PosSlotDecoder=r(4),e.m_PosDecoders=r(114),e.m_PosAlignDecoder=lt({},4),e.m_LenDecoder=he({}),e.m_RepLenDecoder=he({}),e.m_LiteralDecoder={};for(var t=0;4>t;++t)e.m_PosSlotDecoder[t]=lt({},6);return e}function le(e){e.m_OutWindow._streamPos=0,e.m_OutWindow._pos=0,kt(e.m_IsMatchDecoders),kt(e.m_IsRep0LongDecoders),kt(e.m_IsRepDecoders),kt(e.m_IsRepG0Decoders),kt(e.m_IsRepG1Decoders),kt(e.m_IsRepG2Decoders),kt(e.m_PosDecoders),be(e.m_LiteralDecoder);for(var t=0;4>t;++t)kt(e.m_PosSlotDecoder[t].Models);me(e.m_LenDecoder),me(e.m_RepLenDecoder),kt(e.m_PosAlignDecoder.Models),wt(e.m_RangeDecoder)}function ue(e,t){var n,r,a,o,i,s,l;if(t.length<5)return 0;for(l=255&t[0],a=l%9,s=~~(l/9),o=s%5,i=~~(s/5),n=0,r=0;4>r;++r)n+=(255&t[1+r])<<8*r;return n>99999999||!de(e,a,o,i)?0:ce(e,n)}function ce(e,t){return 0>t?0:(e.m_DictionarySize!=t&&(e.m_DictionarySize=t,e.m_DictionarySizeCheck=Math.max(e.m_DictionarySize,1),G(e.m_OutWindow,Math.max(e.m_DictionarySizeCheck,4096))),1)}function de(e,t,n,r){if(t>8||n>4||r>4)return 0;ge(e.m_LiteralDecoder,n,t);var a=1<a;++a)e.m_Coders[a]=we({})}function ye(e,t,n){return e.m_Coders[((t&e.m_PosMask)<>>8-e.m_NumPrevBits)]}function be(e){var t,n;for(n=1<t;++t)kt(e.m_Coders[t].m_Decoders)}function ve(e,t){var n=1;do n=n<<1|vt(t,e.m_Decoders,n);while(256>n);return n<<24>>24}function _e(e,t,n){var r,a,o=1;do if(a=n>>7&1,n<<=1,r=vt(t,e.m_Decoders,(1+a<<8)+o),o=o<<1|r,a!=r){for(;256>o;)o=o<<1|vt(t,e.m_Decoders,o);break}while(256>o);return o<<24>>24}function we(e){return e.m_Decoders=r(768),e}function ke(e,t){var n,r,a,o;e._optimumEndIndex=t,a=e._optimum[t].PosPrev,r=e._optimum[t].BackPrev;do e._optimum[t].Prev1IsChar&&(it(e._optimum[a]),e._optimum[a].PosPrev=a-1,e._optimum[t].Prev2&&(e._optimum[a-1].Prev1IsChar=0,e._optimum[a-1].PosPrev=e._optimum[t].PosPrev2,e._optimum[a-1].BackPrev=e._optimum[t].BackPrev2)),o=a,n=r,r=e._optimum[o].BackPrev,a=e._optimum[o].PosPrev,e._optimum[o].BackPrev=n,e._optimum[o].PosPrev=t,t=o;while(t>0);return e.backRes=e._optimum[0].BackPrev,e._optimumCurrentIndex=e._optimum[0].PosPrev,e._optimumCurrentIndex}function Ee(e){e._state=0,e._previousByte=0;for(var t=0;4>t;++t)e._repDistances[t]=0}function xe(e,t,n,r){var o,s,d,p,f,h,m,y,b,v,_,w,k,E,x;if(t[0]=Ut,n[0]=Ut,r[0]=1,e._inStream&&(e._matchFinder._stream=e._inStream,F(e._matchFinder),e._needReleaseMFStream=1,e._inStream=null),!e._finished){if(e._finished=1,E=e.nowPos64,l(e.nowPos64,Ut)){if(!N(e._matchFinder))return void je(e,c(e.nowPos64));Ie(e),k=c(e.nowPos64)&e._posStateMask,Et(e._rangeEncoder,e._isMatch,(e._state<<4)+k,0),e._state=Q(e._state),d=D(e._matchFinder,-e._additionalOffset),nt(et(e._literalEncoder,c(e.nowPos64),e._previousByte),e._rangeEncoder,d),e._previousByte=d,--e._additionalOffset,e.nowPos64=a(e.nowPos64,Ht)}if(!N(e._matchFinder))return void je(e,c(e.nowPos64));for(;;){if(m=Ce(e,c(e.nowPos64)),v=e.backRes,k=c(e.nowPos64)&e._posStateMask,s=(e._state<<4)+k,1==m&&-1==v)Et(e._rangeEncoder,e._isMatch,s,0),d=D(e._matchFinder,-e._additionalOffset),x=et(e._literalEncoder,c(e.nowPos64),e._previousByte),e._state<7?nt(x,e._rangeEncoder,d):(b=D(e._matchFinder,-e._repDistances[0]-1-e._additionalOffset),rt(x,e._rangeEncoder,b,d)),e._previousByte=d,e._state=Q(e._state);else{if(Et(e._rangeEncoder,e._isMatch,s,1),4>v){if(Et(e._rangeEncoder,e._isRep,e._state,1),v?(Et(e._rangeEncoder,e._isRepG0,e._state,1),1==v?Et(e._rangeEncoder,e._isRepG1,e._state,0):(Et(e._rangeEncoder,e._isRepG1,e._state,1),Et(e._rangeEncoder,e._isRepG2,e._state,v-2))):(Et(e._rangeEncoder,e._isRepG0,e._state,0),1==m?Et(e._rangeEncoder,e._isRep0Long,s,0):Et(e._rangeEncoder,e._isRep0Long,s,1)),1==m?e._state=e._state<7?9:11:(Xe(e._repMatchLenEncoder,e._rangeEncoder,m-2,k),e._state=e._state<7?8:11),p=e._repDistances[v],0!=v){for(h=v;h>=1;--h)e._repDistances[h]=e._repDistances[h-1];e._repDistances[0]=p}}else{for(Et(e._rangeEncoder,e._isRep,e._state,0),e._state=e._state<7?7:10,Xe(e._lenEncoder,e._rangeEncoder,m-2,k),v-=4,w=He(v),y=Z(m),ft(e._posSlotEncoder[y],e._rangeEncoder,w),w>=4&&(f=(w>>1)-1,o=(2|1&w)<w?yt(e._posEncoders,o-w-1,e._rangeEncoder,f,_):(xt(e._rangeEncoder,_>>4,f-4),mt(e._posAlignEncoder,e._rangeEncoder,15&_),++e._alignPriceCount)),p=v,h=3;h>=1;--h)e._repDistances[h]=e._repDistances[h-1];e._repDistances[0]=p,++e._matchPriceCount}e._previousByte=D(e._matchFinder,m-1-e._additionalOffset)}if(e._additionalOffset-=m,e.nowPos64=a(e.nowPos64,u(m)),!e._additionalOffset){if(e._matchPriceCount>=128&&Ae(e),e._alignPriceCount>=16&&Pe(e),t[0]=e.nowPos64,n[0]=St(e._rangeEncoder),!N(e._matchFinder))return void je(e,c(e.nowPos64));if(i(g(e.nowPos64,E),[4096,0])>=0)return e._finished=0,void(r[0]=0)}}}}function Oe(e){var t,n;e._matchFinder||(t={},n=4,e._matchFinderType||(n=2),W(t,n),e._matchFinder=t),Qe(e._literalEncoder,e._numLiteralPosStateBits,e._numLiteralContextBits),(e._dictionarySize!=e._dictionarySizePrev||e._numFastBytesPrev!=e._numFastBytes)&&(L(e._matchFinder,e._dictionarySize,4096,e._numFastBytes,274),e._dictionarySizePrev=e._dictionarySize,e._numFastBytesPrev=e._numFastBytes)}function Se(e){var t;for(e._repDistances=r(4),e._optimum=[],e._rangeEncoder={},e._isMatch=r(192),e._isRep=r(12),e._isRepG0=r(12),e._isRepG1=r(12),e._isRepG2=r(12),e._isRep0Long=r(192),e._posSlotEncoder=[],e._posEncoders=r(114),e._posAlignEncoder=pt({},4),e._lenEncoder=Je({}),e._repMatchLenEncoder=Je({}),e._literalEncoder={},e._matchDistances=[],e._posSlotPrices=[],e._distancesPrices=[],e._alignPrices=r(16),e.reps=r(4),e.repLens=r(4),e.processedInSize=[Ut],e.processedOutSize=[Ut],e.finished=[0],e.properties=r(5),e.tempPrices=r(128),e._longestMatchLength=0,e._matchFinderType=1,e._numDistancePairs=0,e._numFastBytesPrev=-1,e.backRes=0,t=0;4096>t;++t)e._optimum[t]={};for(t=0;4>t;++t)e._posSlotEncoder[t]=pt({},6);return e}function Pe(e){for(var t=0;16>t;++t)e._alignPrices[t]=gt(e._posAlignEncoder,t);e._alignPriceCount=0}function Ae(e){var t,n,r,a,o,i,s,l;for(a=4;128>a;++a)i=He(a),r=(i>>1)-1,t=(2|1&i)<o;++o){for(n=e._posSlotEncoder[o],s=o<<6,i=0;i>1)-1-4<<6;for(l=128*o,a=0;4>a;++a)e._distancesPrices[l+a]=e._posSlotPrices[s+a];for(;128>a;++a)e._distancesPrices[l+a]=e._posSlotPrices[s+He(a)]+e.tempPrices[a]}e._matchPriceCount=0}function je(e,t){Re(e),Ue(e,t&e._posStateMask),Ot(e._rangeEncoder)}function Ce(e,t){var n,r,a,o,i,s,l,u,c,d,p,f,h,m,g,y,b,v,_,w,k,E,x,O,S,P,A,j,C,T,z,I,R,B,L,q,F,U,H,W,V,K,G,Y,X,J,$,Z,ee,te;if(e._optimumEndIndex!=e._optimumCurrentIndex)return h=e._optimum[e._optimumCurrentIndex].PosPrev-e._optimumCurrentIndex,e.backRes=e._optimum[e._optimumCurrentIndex].BackPrev,e._optimumCurrentIndex=e._optimum[e._optimumCurrentIndex].PosPrev,h;if(e._optimumCurrentIndex=e._optimumEndIndex=0,e._longestMatchWasFound?(f=e._longestMatchLength,e._longestMatchWasFound=0):f=Ie(e),A=e._numDistancePairs,S=N(e._matchFinder)+1,2>S)return e.backRes=-1,1;for(S>273&&(S=273),W=0,c=0;4>c;++c)e.reps[c]=e._repDistances[c],e.repLens[c]=M(e._matchFinder,-1,e.reps[c],273),e.repLens[c]>e.repLens[W]&&(W=c);if(e.repLens[W]>=e._numFastBytes)return e.backRes=W,h=e.repLens[W],ze(e,h-1),h;if(f>=e._numFastBytes)return e.backRes=e._matchDistances[A-1]+4,ze(e,f-1),f;if(l=D(e._matchFinder,-1),b=D(e._matchFinder,-e._repDistances[0]-1-1),2>f&&l!=b&&e.repLens[W]<2)return e.backRes=-1,1;if(e._optimum[0].State=e._state,B=t&e._posStateMask,e._optimum[1].Price=Kt[e._isMatch[(e._state<<4)+B]>>>2]+ot(et(e._literalEncoder,t,e._previousByte),e._state>=7,b,l),it(e._optimum[1]),v=Kt[2048-e._isMatch[(e._state<<4)+B]>>>2],H=v+Kt[2048-e._isRep[e._state]>>>2],b==l&&(V=H+Me(e,e._state,B),V=e.repLens[W]?f:e.repLens[W],2>p)return e.backRes=e._optimum[1].BackPrev,1;e._optimum[1].PosPrev=0,e._optimum[0].Backs0=e.reps[0],e._optimum[0].Backs1=e.reps[1],e._optimum[0].Backs2=e.reps[2],e._optimum[0].Backs3=e.reps[3],d=p;do e._optimum[d--].Price=268435455;while(d>=2);for(c=0;4>c;++c)if(U=e.repLens[c],!(2>U)){q=H+De(e,c,e._state,B);do o=q+$e(e._repMatchLenEncoder,U-2,B),z=e._optimum[U],o=2)}if(O=v+Kt[e._isRep[e._state]>>>2],d=e.repLens[0]>=2?e.repLens[0]+1:2,f>=d){for(j=0;d>e._matchDistances[j];)j+=2;for(;u=e._matchDistances[j+1],o=O+Te(e,u,d,B),z=e._optimum[d],o=e._numFastBytes)return e._longestMatchLength=_,e._longestMatchWasFound=1,ke(e,n);if(++t,R=e._optimum[n].PosPrev,e._optimum[n].Prev1IsChar?(--R,e._optimum[n].Prev2?(G=e._optimum[e._optimum[n].PosPrev2].State,G=e._optimum[n].BackPrev2<4?7>G?8:11:7>G?7:10):G=e._optimum[R].State,G=Q(G)):G=e._optimum[R].State,R==n-1?G=e._optimum[n].BackPrev?Q(G):7>G?9:11:(e._optimum[n].Prev1IsChar&&e._optimum[n].Prev2?(R=e._optimum[n].PosPrev2,I=e._optimum[n].BackPrev2,G=7>G?8:11):(I=e._optimum[n].BackPrev,G=4>I?7>G?8:11:7>G?7:10),T=e._optimum[R],4>I?I?1==I?(e.reps[0]=T.Backs1,e.reps[1]=T.Backs0,e.reps[2]=T.Backs2,e.reps[3]=T.Backs3):2==I?(e.reps[0]=T.Backs2,e.reps[1]=T.Backs0,e.reps[2]=T.Backs1,e.reps[3]=T.Backs3):(e.reps[0]=T.Backs3,e.reps[1]=T.Backs0,e.reps[2]=T.Backs1,e.reps[3]=T.Backs2):(e.reps[0]=T.Backs0,e.reps[1]=T.Backs1,e.reps[2]=T.Backs2,e.reps[3]=T.Backs3):(e.reps[0]=I-4,e.reps[1]=T.Backs0,e.reps[2]=T.Backs1,e.reps[3]=T.Backs2)),e._optimum[n].State=G,e._optimum[n].Backs0=e.reps[0],e._optimum[n].Backs1=e.reps[1],e._optimum[n].Backs2=e.reps[2],e._optimum[n].Backs3=e.reps[3],s=e._optimum[n].Price,l=D(e._matchFinder,-1),b=D(e._matchFinder,-e.reps[0]-1-1),B=t&e._posStateMask,r=s+Kt[e._isMatch[(G<<4)+B]>>>2]+ot(et(e._literalEncoder,t,D(e._matchFinder,-2)),G>=7,b,l),E=e._optimum[n+1],w=0,r>>2],H=v+Kt[2048-e._isRep[G]>>>2],b!=l||E.PosPrev>>2]+Kt[e._isRep0Long[(G<<4)+B]>>>2]),V<=E.Price&&(E.Price=V,E.PosPrev=n,E.BackPrev=0,E.Prev1IsChar=0,w=1)),P=N(e._matchFinder)+1,P=P>4095-n?4095-n:P,S=P,!(2>S)){if(S>e._numFastBytes&&(S=e._numFastBytes),!w&&b!=l&&(X=Math.min(P-1,e._numFastBytes),g=M(e._matchFinder,0,e.reps[0],X),g>=2)){for(Y=Q(G),L=t+1&e._posStateMask,x=r+Kt[2048-e._isMatch[(Y<<4)+L]>>>2]+Kt[2048-e._isRep[Y]>>>2],C=n+1+g;C>p;)e._optimum[++p].Price=268435455;o=x+(J=$e(e._repMatchLenEncoder,g-2,L),J+De(e,0,Y,L)),z=e._optimum[C],oF;++F)if(m=M(e._matchFinder,-1,e.reps[F],S),!(2>m)){y=m;do{for(;n+m>p;)e._optimum[++p].Price=268435455;o=H+($=$e(e._repMatchLenEncoder,m-2,B),$+De(e,F,G,B)),z=e._optimum[n+m],o=2);if(m=y,F||(K=m+1),P>m&&(X=Math.min(P-1-m,e._numFastBytes),g=M(e._matchFinder,m,e.reps[F],X),g>=2)){for(Y=7>G?8:11,L=t+m&e._posStateMask,a=H+(Z=$e(e._repMatchLenEncoder,m-2,B),Z+De(e,F,G,B))+Kt[e._isMatch[(Y<<4)+L]>>>2]+ot(et(e._literalEncoder,t+m,D(e._matchFinder,m-1-1)),1,D(e._matchFinder,m-1-(e.reps[F]+1)),D(e._matchFinder,m-1)),Y=Q(Y),L=t+m+1&e._posStateMask,k=a+Kt[2048-e._isMatch[(Y<<4)+L]>>>2],x=k+Kt[2048-e._isRep[Y]>>>2],C=m+1+g;n+C>p;)e._optimum[++p].Price=268435455;o=x+(ee=$e(e._repMatchLenEncoder,g-2,L),ee+De(e,0,Y,L)),z=e._optimum[n+C],oS){for(_=S,A=0;_>e._matchDistances[A];A+=2);e._matchDistances[A]=_,A+=2}if(_>=K){for(O=v+Kt[e._isRep[G]>>>2];n+_>p;)e._optimum[++p].Price=268435455;for(j=0;K>e._matchDistances[j];)j+=2;for(m=K;;++m)if(i=e._matchDistances[j+1],o=O+Te(e,i,m,B),z=e._optimum[n+m],om&&(X=Math.min(P-1-m,e._numFastBytes),g=M(e._matchFinder,m,i,X),g>=2)){for(Y=7>G?7:10,L=t+m&e._posStateMask,a=o+Kt[e._isMatch[(Y<<4)+L]>>>2]+ot(et(e._literalEncoder,t+m,D(e._matchFinder,m-1-1)),1,D(e._matchFinder,m-(i+1)-1),D(e._matchFinder,m-1)),Y=Q(Y),L=t+m+1&e._posStateMask,k=a+Kt[2048-e._isMatch[(Y<<4)+L]>>>2],x=k+Kt[2048-e._isRep[Y]>>>2],C=m+1+g;n+C>p;)e._optimum[++p].Price=268435455;o=x+(te=$e(e._repMatchLenEncoder,g-2,L),te+De(e,0,Y,L)),z=e._optimum[n+C],ot?e._distancesPrices[128*o+t]:e._posSlotPrices[(o<<6)+We(t)]+e._alignPrices[15&t],a+$e(e._lenEncoder,n-2,r)}function De(e,t,n,r){var a;return t?(a=Kt[2048-e._isRepG0[n]>>>2],1==t?a+=Kt[e._isRepG1[n]>>>2]:(a+=Kt[2048-e._isRepG1[n]>>>2],a+=jt(e._isRepG2[n],t-2))):(a=Kt[e._isRepG0[n]>>>2],a+=Kt[2048-e._isRep0Long[(n<<4)+r]>>>2]),a}function Me(e,t,n){return Kt[e._isRepG0[t]>>>2]+Kt[e._isRep0Long[(t<<4)+n]>>>2]}function Ne(e){Ee(e),Pt(e._rangeEncoder),kt(e._isMatch),kt(e._isRep0Long),kt(e._isRep),kt(e._isRepG0),kt(e._isRepG1),kt(e._isRepG2),kt(e._posEncoders),tt(e._literalEncoder);for(var t=0;4>t;++t)kt(e._posSlotEncoder[t].Models);Ge(e._lenEncoder,1<0&&(V(e._matchFinder,t),e._additionalOffset+=t)}function Ie(e){var t=0;return e._numDistancePairs=q(e._matchFinder,e._matchDistances),e._numDistancePairs>0&&(t=e._matchDistances[e._numDistancePairs-2],t==e._numFastBytes&&(t+=M(e._matchFinder,t-1,e._matchDistances[e._numDistancePairs-1],273-t))),++e._additionalOffset,t}function Re(e){e._matchFinder&&e._needReleaseMFStream&&(e._matchFinder._stream=null,e._needReleaseMFStream=0)}function Be(e){Re(e),e._rangeEncoder.Stream=null}function Le(e,t){e._dictionarySize=t;for(var n=0;t>1<>24;for(var n=0;4>n;++n)e.properties[1+n]=e._dictionarySize>>8*n<<24>>24;E(t,e.properties,0,5)}function Ue(e,t){if(e._writeEndMark){Et(e._rangeEncoder,e._isMatch,(e._state<<4)+t,1),Et(e._rangeEncoder,e._isRep,e._state,0),e._state=e._state<7?7:10,Xe(e._lenEncoder,e._rangeEncoder,0,t);var n=Z(2);ft(e._posSlotEncoder[n],e._rangeEncoder,63),xt(e._rangeEncoder,67108863,26),mt(e._posAlignEncoder,e._rangeEncoder,15)}}function He(e){return 2048>e?Vt[e]:2097152>e?Vt[e>>10]+20:Vt[e>>20]+40}function We(e){return 131072>e?Vt[e>>6]+12:134217728>e?Vt[e>>16]+32:Vt[e>>26]+52}function Ve(e,t,n,r){8>n?(Et(t,e._choice,0,0),ft(e._lowCoder[r],t,n)):(n-=8,Et(t,e._choice,0,1),8>n?(Et(t,e._choice,1,0),ft(e._midCoder[r],t,n)):(Et(t,e._choice,1,1),ft(e._highCoder,t,n-8)))}function Ke(e){e._choice=r(2),e._lowCoder=r(16),e._midCoder=r(16),e._highCoder=pt({},8);for(var t=0;16>t;++t)e._lowCoder[t]=pt({},3),e._midCoder[t]=pt({},3);return e}function Ge(e,t){kt(e._choice);for(var n=0;t>n;++n)kt(e._lowCoder[n].Models),kt(e._midCoder[n].Models);kt(e._highCoder.Models)}function Ye(e,t,n,r,a){var o,i,s,l,u;for(o=Kt[e._choice[0]>>>2],i=Kt[2048-e._choice[0]>>>2],s=i+Kt[e._choice[1]>>>2],l=i+Kt[2048-e._choice[1]>>>2],u=0,u=0;8>u;++u){if(u>=n)return;r[a+u]=o+ht(e._lowCoder[t],u)}for(;16>u;++u){if(u>=n)return;r[a+u]=s+ht(e._midCoder[t],u-8)}for(;n>u;++u)r[a+u]=l+ht(e._highCoder,u-8-8)}function Xe(e,t,n,r){Ve(e,t,n,r),0==--e._counters[r]&&(Ye(e,r,e._tableSize,e._prices,272*r),e._counters[r]=e._tableSize)}function Je(e){return Ke(e),e._prices=[],e._counters=[],e}function $e(e,t,n){return e._prices[272*n+t]}function Ze(e,t){for(var n=0;t>n;++n)Ye(e,n,e._tableSize,e._prices,272*n),e._counters[n]=e._tableSize}function Qe(e,t,n){var a,o;if(null==e.m_Coders||e.m_NumPrevBits!=n||e.m_NumPosBits!=t)for(e.m_NumPosBits=t,e.m_PosMask=(1<a;++a)e.m_Coders[a]=at({})}function et(e,t,n){return e.m_Coders[((t&e.m_PosMask)<>>8-e.m_NumPrevBits)]}function tt(e){var t,n=1<t;++t)kt(e.m_Coders[t].m_Encoders)}function nt(e,t,n){var r,a,o=1;for(a=7;a>=0;--a)r=n>>a&1,Et(t,e.m_Encoders,o,r),o=o<<1|r}function rt(e,t,n,r){var a,o,i,s,l=1,u=1;for(o=7;o>=0;--o)a=r>>o&1,s=u,l&&(i=n>>o&1,s+=1+i<<8,l=i==a),Et(t,e.m_Encoders,s,a),u=u<<1|a}function at(e){return e.m_Encoders=r(768),e}function ot(e,t,n,r){var a,o,i=1,s=7,l=0;if(t)for(;s>=0;--s)if(o=n>>s&1,a=r>>s&1,l+=jt(e.m_Encoders[(1+o<<8)+i],a),i=i<<1|a,o!=a){--s;break}for(;s>=0;--s)a=r>>s&1,l+=jt(e.m_Encoders[i],a),i=i<<1|a;return l}function it(e){e.BackPrev=-1,e.Prev1IsChar=0}function st(e){e.BackPrev=0,e.Prev1IsChar=0}function lt(e,t){return e.NumBitLevels=t,e.Models=r(1<o;++o)a=vt(n,e,t+i),i<<=1,i+=a,s|=a<>>a&1,Et(t,e.Models,o,r),o=o<<1|r}function ht(e,t){var n,r,a=1,o=0;for(r=e.NumBitLevels;0!=r;)--r,n=t>>>r&1,o+=jt(e.Models[a],n),a=(a<<1)+n;return o}function mt(e,t,n){var r,a,o=1;for(a=0;a>=1}function gt(e,t){var n,r,a=1,o=0;for(r=e.NumBitLevels;0!=r;--r)n=1&t,t>>>=1,o+=jt(e.Models[a],n),a=a<<1|n;return o}function yt(e,t,n,r,a){var o,i,s=1;for(i=0;r>i;++i)o=1&a,Et(n,e,t+s,o),s=s<<1|o,a>>=1}function bt(e,t,n,r){var a,o,i=1,s=0;for(o=n;0!=o;--o)a=1&r,r>>>=1,s+=Kt[(2047&(e[t+i]-a^-a))>>>2],i=i<<1|a;return s}function vt(e,t,n){var r,a=t[n];return r=(e.Range>>>11)*a,(-2147483648^e.Code)<(-2147483648^r)?(e.Range=r,t[n]=a+(2048-a>>>5)<<16>>16,-16777216&e.Range||(e.Code=e.Code<<8|b(e.Stream),e.Range<<=8),0):(e.Range-=r,e.Code-=r,t[n]=a-(a>>>5)<<16>>16,-16777216&e.Range||(e.Code=e.Code<<8|b(e.Stream),e.Range<<=8),1)}function _t(e,t){var n,r,a=0;for(n=t;0!=n;--n)e.Range>>>=1,r=e.Code-e.Range>>>31,e.Code-=e.Range&r-1,a=a<<1|1-r,-16777216&e.Range||(e.Code=e.Code<<8|b(e.Stream),e.Range<<=8);return a}function wt(e){e.Code=0,e.Range=-1;for(var t=0;5>t;++t)e.Code=e.Code<<8|b(e.Stream)}function kt(e){for(var t=e.length-1;t>=0;--t)e[t]=1024}function Et(e,t,n,r){var i,s=t[n];i=(e.Range>>>11)*s,r?(e.Low=a(e.Low,o(u(i),[4294967295,0])),e.Range-=i,t[n]=s-(s>>>5)<<16>>16):(e.Range=i,t[n]=s+(2048-s>>>5)<<16>>16),-16777216&e.Range||(e.Range<<=8,At(e))}function xt(e,t,n){for(var r=n-1;r>=0;--r)e.Range>>>=1,1==(t>>>r&1)&&(e.Low=a(e.Low,u(e.Range))),-16777216&e.Range||(e.Range<<=8,At(e))}function Ot(e){for(var t=0;5>t;++t)At(e)}function St(e){return a(a(u(e._cacheSize),e._position),[4,0])}function Pt(e){e._position=Ut,e.Low=Ut,e.Range=-1,e._cacheSize=1,e._cache=0}function At(e){var t,n=c(m(e.Low,32));if(0!=n||i(e.Low,[4278190080,0])<0){e._position=a(e._position,u(e._cacheSize)),t=e._cache;do k(e.Stream,t+n),t=255;while(0!=--e._cacheSize);e._cache=c(e.Low)>>>24}++e._cacheSize,e.Low=f(o(e.Low,[16777215,0]),8)}function jt(e,t){return Kt[(2047&(e-t^-t))>>>2]}function Ct(e){var t,n,r,a,o="",i=e.length;for(t=0;i>t;++t)if(n=255&e[t],128&n)if(192==(224&n)){if(t+1>=e.length)return e;if(r=255&e[++t],128!=(192&r))return e;o+=String.fromCharCode((31&n)<<6&65535|63&r)}else{if(224!=(240&n))return e;if(t+2>=e.length)return e;if(r=255&e[++t],128!=(192&r))return e;if(a=255&e[++t],128!=(192&a))return e;o+=String.fromCharCode(65535&((15&n)<<12|(63&r)<<6|63&a))}else{if(!n)return e;o+=String.fromCharCode(65535&n)}return o}function Tt(e){var t,n,r,a=[],o=0,i=e.length;if("object"==typeof e)return e;for(x(e,0,i,a,0),r=0;i>r;++r)t=a[r],t>=1&&127>=t?++o:o+=!t||t>=128&&2047>=t?2:3;for(n=[],o=0,r=0;i>r;++r)t=a[r],t>=1&&127>=t?n[o++]=t<<24>>24:!t||t>=128&&2047>=t?(n[o++]=(192|t>>6&31)<<24>>24,n[o++]=(128|63&t)<<24>>24):(n[o++]=(224|t>>12&15)<<24>>24,n[o++]=(128|t>>6&63)<<24>>24,n[o++]=(128|63&t)<<24>>24);return n}function Dt(e){return e[1]+e[0]}function Mt(e,t,r,a){function o(){for(var e,t=(new Date).getTime();ne(l.c.chunker);)if(i=Dt(l.c.chunker.inBytesProcessed)/Dt(l.c.length_0),(new Date).getTime()-t>200)return a?a(i):"undefined"!=typeof s&&n(i,s),Bt(o,0),0;a?a(1):"undefined"!=typeof s&&n(1,s),e=w(l.c.output),r?r(e):"undefined"!=typeof s&&postMessage({action:zt,cbn:s,result:e})}var i,s,l={};"function"!=typeof r&&(s=r,r=a=0),l.c=A({},Tt(e),Gt(t)),a?a(0):"undefined"!=typeof s&&n(0,s),Bt(o,0)}function Nt(e,t,r){function a(){for(var e,c=0,d=(new Date).getTime();ne(u.d.chunker);)if(++c%1e3==0&&(new Date).getTime()-d>200)return s&&(o=Dt(u.d.chunker.decoder.nowPos64)/l,r?r(o):"undefined"!=typeof i&&n(o,i)),Bt(a,0),0;s&&(r?r(1):"undefined"!=typeof i&&n(1,i)),e=Ct(w(u.d.output)),t?t(e):"undefined"!=typeof i&&postMessage({action:It,cbn:i,result:e})}var o,i,s,l,u={};"function"!=typeof t&&(i=t,t=r=0),u.d=C({},e),l=Dt(u.d.length_0),s=l>-1,r?r(s?0:-1):"undefined"!=typeof i&&n(s?0:-1,i),Bt(a,0)}var zt=1,It=2,Rt=3,Bt="function"==typeof e?e:setTimeout,Lt=4294967296,qt=[4294967295,-Lt],Ft=[0,-0x8000000000000000],Ut=[0,0],Ht=[1,0],Wt=function(){var e,t,n,r=[];for(e=0;256>e;++e){for(n=e,t=0;8>t;++t)0!=(1&n)?n=n>>>1^-306674912:n>>>=1;r[e]=n}return r}(),Vt=function(){var e,t,n,r=2,a=[0,1];for(n=2;22>n;++n)for(t=1<<(n>>1)-1,e=0;t>e;++e,++r)a[r]=n<<24>>24;return a}(),Kt=function(){var e,t,n,r,a=[];for(t=8;t>=0;--t)for(r=1<<9-t-1,e=1<<9-t,n=r;e>n;++n)a[n]=(t<<6)+(e-n<<6>>>9-t-1);return a}(),Gt=function(){var e=[{s:16,f:64,m:0},{s:20,f:64,m:0},{s:19,f:64,m:1},{s:20,f:64,m:1},{s:21,f:128,m:1},{s:22,f:128,m:1},{s:23,f:128,m:1},{s:24,f:255,m:1},{s:25,f:255,m:1}];return function(t){return e[t-1]||e[6]}}();return"undefined"==typeof onmessage||"undefined"!=typeof window&&"undefined"!=typeof window.document||!function(){onmessage=function(e){e&&e.data&&(e.data.action==It?t.decompress(e.data.data,e.data.cbn):e.data.action==zt&&t.compress(e.data.data,e.data.mode,e.data.cbn))}}(),{compress:Mt,decompress:Nt}}();this.LZMA=this.LZMA_WORKER=t}).call(t,n(839).setImmediate)},function(e,t,n){(function(e,r){function a(e,t){this._id=e,this._clearFn=t}var o=n(175).nextTick,i=Function.prototype.apply,s=Array.prototype.slice,l={},u=0;t.setTimeout=function(){return new a(i.call(setTimeout,window,arguments),clearTimeout)},t.setInterval=function(){return new a(i.call(setInterval,window,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e.close()},a.prototype.unref=a.prototype.ref=function(){},a.prototype.close=function(){this._clearFn.call(window,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},t.setImmediate="function"==typeof e?e:function(e){var n=u++,r=arguments.length<2?!1:s.call(arguments,1);return l[n]=!0,o(function(){l[n]&&(r?e.apply(null,r):e.call(null),t.clearImmediate(n))}),n},t.clearImmediate="function"==typeof r?r:function(e){delete l[e]}}).call(t,n(839).setImmediate,n(839).clearImmediate)},,,function(e,t,n){(function(r){var a=n(843),o=a["default"];r.IntlPolyfill=o,n(846),r.Intl||(r.Intl=o,o.__applyLocaleSensitivePrototypes()),e.exports=t=o,t["default"]=o}).call(t,function(){return this}())},function(e,t,n){/** + * @license Copyright 2013 Andy Earnshaw, MIT License + * + * Implements the ECMAScript Internationalization API in ES5-compatible environments, + * following the ECMA-402 specification as closely as possible + * + * ECMA-402: http://ecma-international.org/ecma-402/1.0/ + * + * CLDR format locale data should be provided using IntlPolyfill.__addLocaleData(). + */ +"use strict";function r(e){return V.expBCP47Syntax.test(e)?V.expVariantDupes.test(e)?!1:V.expSingletonDupes.test(e)?!1:!0:!1}function a(e){var t,n;e=e.toLowerCase(),n=e.split("-");for(var r=1,a=n.length;a>r;r++)if(2===n[r].length)n[r]=n[r].toUpperCase();else if(4===n[r].length)n[r]=n[r].charAt(0).toUpperCase()+n[r].slice(1);else if(1===n[r].length&&"x"!==n[r])break;e=re.call(n,"-"),(t=e.match(V.expExtSequences))&&t.length>1&&(t.sort(),e=e.replace(RegExp("(?:"+V.expExtSequences.source+")+","i"),re.call(t,""))),J.call(fe.tags,e)&&(e=fe.tags[e]),n=e.split("-");for(var r=1,a=n.length;a>r;r++)J.call(fe.subtags,n[r])?n[r]=fe.subtags[n[r]]:J.call(fe.extLang,n[r])&&(n[r]=fe.extLang[n[r]][0],1===r&&fe.extLang[n[1]][1]===n[0]&&(n=ee.call(n,r++),a-=1));return re.call(n,"-")}function o(){return W}function i(e){var t=String(e),n=F(t);return de.test(n)===!1?!1:!0}function s(e){if(void 0===e)return new L;for(var t=new L,e="string"==typeof e?[e]:e,n=U(e),o=n.length,i=0;o>i;){var s=String(i),l=s in n;if(l){var u=n[s];if(null==u||"string"!=typeof u&&"object"!=typeof u)throw new TypeError("String or Object type expected");var c=String(u);if(!r(c))throw new RangeError("'"+c+"' is not a structurally valid language tag");c=a(c),-1===Z.call(t,c)&&ne.call(t,c)}i++}return t}function l(e,t){for(var n=t;;){if(Z.call(e,n)>-1)return n;var r=n.lastIndexOf("-");if(0>r)return;r>=2&&"-"===n.charAt(r-2)&&(r-=2),n=n.substring(0,r)}}function u(e,t){for(var n,r=0,a=t.length;a>r&&!n;){var i=t[r],s=String(i).replace(pe,""),n=l(e,s);r++}var u=new B;if(void 0!==n){if(u["[[locale]]"]=n,String(i)!==String(s)){var c=i.match(pe)[0],d=i.indexOf("-u-");u["[[extension]]"]=c,u["[[extensionIndex]]"]=d}}else u["[[locale]]"]=o();return u}function c(e,t){return u(e,t)}function d(e,t,n,r,a){if(0===e.length)throw new ReferenceError("No locale data has been provided for this object yet.");var o=n["[[localeMatcher]]"];if("lookup"===o)var i=u(e,t);else var i=c(e,t);var s=i["[[locale]]"];if(J.call(i,"[[extension]]"))var l=i["[[extension]]"],d=i["[[extensionIndex]]"],p=String.prototype.split,f=p.call(l,"-"),h=f.length;var m=new B;m["[[dataLocale]]"]=s;for(var g="-u",y=0,b=r.length;b>y;){var v=r[y],_=a[s],w=_[v],k=w[0],E="",x=Z;if(void 0!==f){var O=x.call(f,v);if(-1!==O)if(h>O+1&&f[O+1].length>2){var S=f[O+1],P=x.call(w,S);if(-1!==P)var k=S,E="-"+v+"-"+k}else{var P=x(w,"true");if(-1!==P)var k="true"}}if(J.call(n,"[["+v+"]]")){var A=n["[["+v+"]]"];-1!==x.call(w,A)&&A!==k&&(k=A,E="")}m["[["+v+"]]"]=k,g+=E,y++}if(g.length>2)var j=s.substring(0,d),C=s.substring(d),s=j+g+C;return m["[[locale]]"]=s,m}function p(e,t){for(var n=t.length,r=new L,a=0;n>a;){var o=t[a],i=String(o).replace(pe,""),s=l(e,i);void 0!==s&&ne.call(r,o),a++}var u=ee.call(r);return u}function f(e,t){return p(e,t)}function h(e,t,n){if(void 0!==n){var n=new B(U(n)),r=n.localeMatcher;if(void 0!==r&&(r=String(r),"lookup"!==r&&"best fit"!==r))throw new RangeError('matcher should be "lookup" or "best fit"')}if(void 0===r||"best fit"===r)var a=f(e,t);else var a=p(e,t);for(var o in a)J.call(a,o)&&$(a,o,{writable:!1,configurable:!1,value:a[o]});return $(a,"length",{writable:!1}),a}function m(e,t,n,r,a){var o=e[t];if(void 0!==o){if(o="boolean"===n?Boolean(o):"string"===n?String(o):o,void 0!==r&&-1===Z.call(r,o))throw new RangeError("'"+o+"' is not an allowed value for `"+t+"`");return o}return a}function g(e,t,n,r,a){var o=e[t];if(void 0!==o){if(o=Number(o),isNaN(o)||n>o||o>r)throw new RangeError("Value is not a number or outside accepted range");return Math.floor(o)}return a}function y(){var e=arguments[0],t=arguments[1];return this&&this!==G?b(U(this),e,t):new G.NumberFormat(e,t)}function b(e,t,n){var r=H(e),a=q();if(r["[[initializedIntlObject]]"]===!0)throw new TypeError("`this` object has already been initialized as an Intl object");$(e,"__getInternalProperties",{value:function(){return arguments[0]===se?r:void 0}}),r["[[initializedIntlObject]]"]=!0;var o=s(t);n=void 0===n?{}:U(n);var l=new B,u=m(n,"localeMatcher","string",new L("lookup","best fit"),"best fit");l["[[localeMatcher]]"]=u;var c=ie.NumberFormat["[[localeData]]"],p=d(ie.NumberFormat["[[availableLocales]]"],o,l,ie.NumberFormat["[[relevantExtensionKeys]]"],c);r["[[locale]]"]=p["[[locale]]"],r["[[numberingSystem]]"]=p["[[nu]]"],r["[[dataLocale]]"]=p["[[dataLocale]]"];var f=p["[[dataLocale]]"],h=m(n,"style","string",new L("decimal","percent","currency"),"decimal");r["[[style]]"]=h;var y=m(n,"currency","string");if(void 0!==y&&!i(y))throw new RangeError("'"+y+"' is not a valid currency code");if("currency"===h&&void 0===y)throw new TypeError("Currency code is required when style is currency");if("currency"===h){y=y.toUpperCase(),r["[[currency]]"]=y;var b=v(y)}var w=m(n,"currencyDisplay","string",new L("code","symbol","name"),"symbol");"currency"===h&&(r["[[currencyDisplay]]"]=w);var k=g(n,"minimumIntegerDigits",1,21,1);r["[[minimumIntegerDigits]]"]=k;var E="currency"===h?b:0,x=g(n,"minimumFractionDigits",0,20,E);r["[[minimumFractionDigits]]"]=x;var O="currency"===h?Math.max(x,b):"percent"===h?Math.max(x,0):Math.max(x,3),S=g(n,"maximumFractionDigits",x,20,O);r["[[maximumFractionDigits]]"]=S;var P=n.minimumSignificantDigits,A=n.maximumSignificantDigits;(void 0!==P||void 0!==A)&&(P=g(n,"minimumSignificantDigits",1,21,1),A=g(n,"maximumSignificantDigits",P,21,21),r["[[minimumSignificantDigits]]"]=P,r["[[maximumSignificantDigits]]"]=A);var j=m(n,"useGrouping","boolean",void 0,!0);r["[[useGrouping]]"]=j;var C=c[f],T=C.patterns,D=T[h];return r["[[positivePattern]]"]=D.positivePattern,r["[[negativePattern]]"]=D.negativePattern,r["[[boundFormat]]"]=void 0,r["[[initializedNumberFormat]]"]=!0,X&&(e.format=_.call(e)),a.exp.test(a.input),e}function v(e){return void 0!==he[e]?he[e]:2}function _(){var e=null!=this&&"object"==typeof this&&H(this);if(!e||!e["[[initializedNumberFormat]]"])throw new TypeError("`this` value for format() is not an initialized Intl.NumberFormat object.");if(void 0===e["[[boundFormat]]"]){var t=function(e){return w(this,Number(e))},n=oe.call(t,this);e["[[boundFormat]]"]=n}return e["[[boundFormat]]"]}function w(e,t){var n,r=q(),a=H(e),o=a["[[dataLocale]]"],i=a["[[numberingSystem]]"],s=ie.NumberFormat["[[localeData]]"][o],l=s.symbols[i]||s.symbols.latn,u=!1;if(isFinite(t)===!1)isNaN(t)?n=l.nan:(n=l.infinity,0>t&&(u=!0));else{if(0>t&&(u=!0,t=-t),"percent"===a["[[style]]"]&&(t*=100),n=J.call(a,"[[minimumSignificantDigits]]")&&J.call(a,"[[maximumSignificantDigits]]")?k(t,a["[[minimumSignificantDigits]]"],a["[[maximumSignificantDigits]]"]):E(t,a["[[minimumIntegerDigits]]"],a["[[minimumFractionDigits]]"],a["[[maximumFractionDigits]]"]),me[i]){var c=me[a["[[numberingSystem]]"]];n=String(n).replace(/\d/g,function(e){return c[e]})}else n=String(n);if(n=n.replace(/\./g,l.decimal),a["[[useGrouping]]"]===!0){var d=n.split(l.decimal),p=d[0],f=s.patterns.primaryGroupSize||3,h=s.patterns.secondaryGroupSize||f;if(p.length>f){var m=new L,g=p.length-f,y=g%h,b=p.slice(0,y);for(b.length&&ne.call(m,b);g>y;)ne.call(m,p.slice(y,y+h)),y+=h;ne.call(m,p.slice(g)),d[0]=re.call(m,l.group)}n=re.call(d,l.decimal)}}var v=a[u===!0?"[[negativePattern]]":"[[positivePattern]]"];if(v=v.replace("{number}",n),"currency"===a["[[style]]"]){var _,w=a["[[currency]]"],x=s.currencies[w];switch(a["[[currencyDisplay]]"]){case"symbol":_=x||w;break;default:case"code":case"name":_=w}v=v.replace("{currency}",_)}return r.exp.test(r.input),v}function k(e,t,n){var r=n;if(0===e)var a=re.call(Array(r+1),"0"),o=0;else var o=z(Math.abs(e)),i=Math.round(Math.exp(Math.abs(o-r+1)*Math.LN10)),a=String(Math.round(0>o-r+1?e*i:e/i));if(o>=r)return a+re.call(Array(o-r+1+1),"0");if(o===r-1)return a;if(o>=0?a=a.slice(0,o+1)+"."+a.slice(o+1):0>o&&(a="0."+re.call(Array(-(o+1)+1),"0")+a),a.indexOf(".")>=0&&n>t){for(var s=n-t;s>0&&"0"===a.charAt(a.length-1);)a=a.slice(0,-1),s--;"."===a.charAt(a.length-1)&&(a=a.slice(0,-1))}return a}function E(e,t,n,r){var a,o=Number.prototype.toFixed.call(e,r),i=o.split(".")[0].length,s=r-n,l=(a=o.indexOf("e"))>-1?o.slice(a+1):0;for(l&&(o=o.slice(0,a).replace(".",""),o+=re.call(Array(l-(o.length-1)+1),"0")+"."+re.call(Array(r+1),"0"),i=o.length);s>0&&"0"===o.slice(-1);)o=o.slice(0,-1),s--;if("."===o.slice(-1)&&(o=o.slice(0,-1)),t>i)var u=re.call(Array(t-i+1),"0");return(u?u:"")+o}function x(){var e=arguments[0],t=arguments[1];return this&&this!==G?O(U(this),e,t):new G.DateTimeFormat(e,t)}function O(e,t,n){var r=H(e),a=q();if(r["[[initializedIntlObject]]"]===!0)throw new TypeError("`this` object has already been initialized as an Intl object");$(e,"__getInternalProperties",{value:function(){return arguments[0]===se?r:void 0}}),r["[[initializedIntlObject]]"]=!0;var o=s(t),n=P(n,"any","date"),i=new B;_=m(n,"localeMatcher","string",new L("lookup","best fit"),"best fit"),i["[[localeMatcher]]"]=_;var l=ie.DateTimeFormat,u=l["[[localeData]]"],c=d(l["[[availableLocales]]"],o,i,l["[[relevantExtensionKeys]]"],u);r["[[locale]]"]=c["[[locale]]"],r["[[calendar]]"]=c["[[ca]]"],r["[[numberingSystem]]"]=c["[[nu]]"],r["[[dataLocale]]"]=c["[[dataLocale]]"];var p=c["[[dataLocale]]"],f=n.timeZone;if(void 0!==f&&(f=F(f),"UTC"!==f))throw new RangeError("timeZone is not supported.");r["[[timeZone]]"]=f,i=new B;for(var h in ge)if(J.call(ge,h)){var g=m(n,h,"string",ge[h]);i["[["+h+"]]"]=g}var y,b=u[p],v=S(b.formats),_=m(n,"formatMatcher","string",new L("basic","best fit"),"best fit");b.formats=v,y="basic"===_?A(i,v):C(i,v);for(var h in ge)if(J.call(ge,h)&&J.call(y,h)){var w=y[h];r["[["+h+"]]"]=w}var k,E=m(n,"hour12","boolean");if(r["[[hour]]"])if(E=void 0===E?b.hour12:E,r["[[hour12]]"]=E,E===!0){var x=b.hourNo0;r["[[hourNo0]]"]=x,k=y.pattern12}else k=y.pattern;else k=y.pattern;return r["[[pattern]]"]=k,r["[[boundFormat]]"]=void 0,r["[[initializedDateTimeFormat]]"]=!0,X&&(e.format=T.call(e)),a.exp.test(a.input),e}function S(e){return"[object Array]"===Object.prototype.toString.call(e)?e:K.createDateTimeFormats(e)}function P(e,t,n){if(void 0===e)e=null;else{var r=U(e);e=new B;for(var a in r)e[a]=r[a]}var o=Q,e=o(e),i=!0;return("date"===t||"any"===t)&&(void 0!==e.weekday||void 0!==e.year||void 0!==e.month||void 0!==e.day)&&(i=!1),("time"===t||"any"===t)&&(void 0!==e.hour||void 0!==e.minute||void 0!==e.second)&&(i=!1),!i||"date"!==n&&"all"!==n||(e.year=e.month=e.day="numeric"),!i||"time"!==n&&"all"!==n||(e.hour=e.minute=e.second="numeric"),e}function A(e,t){return j(e,t)}function j(e,t,n){for(var r,a=8,o=120,i=20,s=8,l=6,u=6,c=3,d=-(1/0),p=0,f=t.length;f>p;){var h=t[p],m=0;for(var g in ge)if(J.call(ge,g)){var y=e["[["+g+"]]"],b=J.call(h,g)?h[g]:void 0;if(void 0===y&&void 0!==b)m-=i;else if(void 0!==y&&void 0===b)m-=o;else{var v=["2-digit","numeric","narrow","short","long"],_=Z.call(v,y),w=Z.call(v,b),k=Math.max(Math.min(w-_,2),-2);!n||("numeric"!==y&&"2-digit"!==y||"numeric"===b||"2-digit"===b)&&("numeric"===y||"2-digit"===y||"2-digit"!==b&&"numeric"!==b)||(m-=a),2===k?m-=l:1===k?m-=c:-1===k?m-=u:-2===k&&(m-=s)}}m>d&&(d=m,r=h),p++}return r}function C(e,t){return j(e,t,!0)}function T(){var e=null!=this&&"object"==typeof this&&H(this);if(!e||!e["[[initializedDateTimeFormat]]"])throw new TypeError("`this` value for format() is not an initialized Intl.DateTimeFormat object.");if(void 0===e["[[boundFormat]]"]){var t=function(){var e=Number(0===arguments.length?Date.now():arguments[0]);return D(this,e)},n=oe.call(t,this);e["[[boundFormat]]"]=n}return e["[[boundFormat]]"]}function D(e,t){if(!isFinite(t))throw new RangeError("Invalid valid date passed to format");var n=e.__getInternalProperties(se),r=q(),a=n["[[locale]]"],o=new G.NumberFormat([a],{useGrouping:!1}),i=new G.NumberFormat([a],{minimumIntegerDigits:2,useGrouping:!1}),s=M(t,n["[[calendar]]"],n["[[timeZone]]"]),l=n["[[pattern]]"],u=n["[[dataLocale]]"],c=ie.DateTimeFormat["[[localeData]]"][u].calendars,d=n["[[calendar]]"];for(var p in ge)if(J.call(n,"[["+p+"]]")){var f,h,m=n["[["+p+"]]"],g=s["[["+p+"]]"];if("year"===p&&0>=g?g=1-g:"month"===p?g++:"hour"===p&&n["[[hour12]]"]===!0&&(g%=12,f=g!==s["[["+p+"]]"],0===g&&n["[[hourNo0]]"]===!0&&(g=12)),"numeric"===m)h=w(o,g);else if("2-digit"===m)h=w(i,g),h.length>2&&(h=h.slice(-2));else if(m in le)switch(p){case"month":h=R(c,d,"months",m,s["[["+p+"]]"]);break;case"weekday":try{h=R(c,d,"days",m,s["[["+p+"]]"])}catch(y){throw new Error("Could not find weekday data for locale "+a)}break;case"timeZoneName":h="";break;default:h=s["[["+p+"]]"]}l=l.replace("{"+p+"}",h)}return n["[[hour12]]"]===!0&&(h=R(c,d,"dayPeriods",f?"pm":"am"),l=l.replace("{ampm}",h)),r.exp.test(r.input),l}function M(e,t,n){var r=new Date(e),a="get"+(n||"");return new B({"[[weekday]]":r[a+"Day"](),"[[era]]":+(r[a+"FullYear"]()>=0),"[[year]]":r[a+"FullYear"](),"[[month]]":r[a+"Month"](),"[[day]]":r[a+"Date"](),"[[hour]]":r[a+"Hours"](),"[[minute]]":r[a+"Minutes"](),"[[second]]":r[a+"Seconds"](),"[[inDST]]":!1})}function N(e,t){if(!e.number)throw new Error("Object passed doesn't contain locale data for Intl.NumberFormat");var n,r=[t],a=t.split("-");for(a.length>2&&4===a[1].length&&ne.call(r,a[0]+"-"+a[2]);n=ae.call(r);)ne.call(ie.NumberFormat["[[availableLocales]]"],n),ie.NumberFormat["[[localeData]]"][n]=e.number,e.date&&(e.date.nu=e.number.nu,ne.call(ie.DateTimeFormat["[[availableLocales]]"],n),ie.DateTimeFormat["[[localeData]]"][n]=e.date);void 0===W&&(W=t),ue||(b(G.NumberFormat.prototype),ue=!0),e.date&&!ce&&(O(G.DateTimeFormat.prototype),ce=!0)}function z(e){if("function"==typeof Math.log10)return Math.floor(Math.log10(e));var t=Math.round(Math.log(e)*Math.LOG10E);return t-(Number("1e"+t)>e)}function I(e){if(!J.call(this,"[[availableLocales]]"))throw new TypeError("supportedLocalesOf() is not a constructor");var t=q(),n=arguments[1],r=this["[[availableLocales]]"],a=s(e);return t.exp.test(t.input),h(r,a,n)}function R(e,t,n,r,a){var o=e[t]&&e[t][n]?e[t][n]:e.gregory[n],i={narrow:["short","long"],"short":["long","narrow"],"long":["short","narrow"]},s=J.call(o,r)?o[r]:J.call(o,i[r][0])?o[i[r][0]]:o[i[r][1]];return null!=a?s[a]:s}function B(e){for(var t in e)(e instanceof B||J.call(e,t))&&$(this,t,{value:e[t],enumerable:!0,writable:!0,configurable:!0})}function L(){$(this,"length",{writable:!0,value:0}),arguments.length&&ne.apply(this,ee.call(arguments))}function q(){for(var e=/[.?*+^$[\]\\(){}|-]/g,t=RegExp.lastMatch||"",n=RegExp.multiline?"m":"",r={input:RegExp.input},a=new L,o=!1,i={},s=1;9>=s;s++)o=(i["$"+s]=RegExp["$"+s])||o;if(t=t.replace(e,"\\$&"),o)for(var s=1;9>=s;s++){var l=i["$"+s];l?(l=l.replace(e,"\\$&"),t=t.replace(l,"("+l+")")):t="()"+t,ne.call(a,t.slice(0,t.indexOf("(")+1)),t=t.slice(t.indexOf("(")+1)}return r.exp=new RegExp(re.call(a,"")+t,n),r}function F(e){for(var t=e.length;t--;){var n=e.charAt(t);n>="a"&&"z">=n&&(e=e.slice(0,t)+n.toUpperCase()+e.slice(t+1))}return e}function U(e){if(null==e)throw new TypeError("Cannot convert null or undefined to object");return Object(e)}function H(e){return J.call(e,"__getInternalProperties")?e.__getInternalProperties(se):Q(null)}var W,V=n(844),K=n(845),G={},Y=function(){var e={};try{return Object.defineProperty(e,"a",{}),"a"in e}catch(t){return!1}}(),X=!Y&&!Object.prototype.__defineGetter__,J=Object.prototype.hasOwnProperty,$=Y?Object.defineProperty:function(e,t,n){"get"in n&&e.__defineGetter__?e.__defineGetter__(t,n.get):(!J.call(e,t)||"value"in n)&&(e[t]=n.value)},Z=Array.prototype.indexOf||function(e){var t=this;if(!t.length)return-1;for(var n=arguments[1]||0,r=t.length;r>n;n++)if(t[n]===e)return n;return-1},Q=Object.create||function(e,t){function n(){}var r;n.prototype=e,r=new n;for(var a in t)J.call(t,a)&&$(r,a,t[a]);return r},ee=Array.prototype.slice,te=Array.prototype.concat,ne=Array.prototype.push,re=Array.prototype.join,ae=Array.prototype.shift,oe=(Array.prototype.unshift,Function.prototype.bind||function(e){var t=this,n=ee.call(arguments,1);return 1===t.length?function(r){return t.apply(e,te.call(n,ee.call(arguments)))}:function(){return t.apply(e,te.call(n,ee.call(arguments)))}}),ie=Q(null),se=Math.random(),le=Q(null,{narrow:{},"short":{},"long":{}}),ue=!1,ce=!1,de=/^[A-Z]{3}$/,pe=/-u(?:-[0-9a-z]{2,8})+/gi,fe={tags:{"art-lojban":"jbo","i-ami":"ami","i-bnn":"bnn","i-hak":"hak","i-klingon":"tlh","i-lux":"lb","i-navajo":"nv","i-pwn":"pwn","i-tao":"tao","i-tay":"tay","i-tsu":"tsu","no-bok":"nb","no-nyn":"nn","sgn-BE-FR":"sfb","sgn-BE-NL":"vgt","sgn-CH-DE":"sgg","zh-guoyu":"cmn","zh-hakka":"hak","zh-min-nan":"nan","zh-xiang":"hsn","sgn-BR":"bzs","sgn-CO":"csn","sgn-DE":"gsg","sgn-DK":"dsl","sgn-ES":"ssp","sgn-FR":"fsl","sgn-GB":"bfi","sgn-GR":"gss","sgn-IE":"isg","sgn-IT":"ise","sgn-JP":"jsl","sgn-MX":"mfs","sgn-NI":"ncs","sgn-NL":"dse","sgn-NO":"nsl","sgn-PT":"psr","sgn-SE":"swl","sgn-US":"ase","sgn-ZA":"sfs","zh-cmn":"cmn","zh-cmn-Hans":"cmn-Hans","zh-cmn-Hant":"cmn-Hant","zh-gan":"gan","zh-wuu":"wuu","zh-yue":"yue"},subtags:{BU:"MM",DD:"DE",FX:"FR",TP:"TL",YD:"YE",ZR:"CD",heploc:"alalc97","in":"id",iw:"he",ji:"yi",jw:"jv",mo:"ro",ayx:"nun",bjd:"drl",ccq:"rki",cjr:"mom",cka:"cmr",cmk:"xch",drh:"khk",drw:"prs",gav:"dev",hrr:"jal",ibi:"opa",kgh:"kml",lcq:"ppr",mst:"mry",myt:"mry",sca:"hle",tie:"ras",tkk:"twm",tlw:"weo",tnf:"prs",ybd:"rki",yma:"lrr"},extLang:{aao:["aao","ar"],abh:["abh","ar"],abv:["abv","ar"],acm:["acm","ar"],acq:["acq","ar"],acw:["acw","ar"],acx:["acx","ar"],acy:["acy","ar"],adf:["adf","ar"],ads:["ads","sgn"],aeb:["aeb","ar"],aec:["aec","ar"],aed:["aed","sgn"],aen:["aen","sgn"],afb:["afb","ar"],afg:["afg","sgn"],ajp:["ajp","ar"],apc:["apc","ar"],apd:["apd","ar"],arb:["arb","ar"],arq:["arq","ar"],ars:["ars","ar"],ary:["ary","ar"],arz:["arz","ar"],ase:["ase","sgn"],asf:["asf","sgn"],asp:["asp","sgn"],asq:["asq","sgn"],asw:["asw","sgn"],auz:["auz","ar"],avl:["avl","ar"],ayh:["ayh","ar"],ayl:["ayl","ar"],ayn:["ayn","ar"],ayp:["ayp","ar"],bbz:["bbz","ar"],bfi:["bfi","sgn"],bfk:["bfk","sgn"],bjn:["bjn","ms"],bog:["bog","sgn"],bqn:["bqn","sgn"],bqy:["bqy","sgn"],btj:["btj","ms"],bve:["bve","ms"],bvl:["bvl","sgn"],bvu:["bvu","ms"],bzs:["bzs","sgn"],cdo:["cdo","zh"],cds:["cds","sgn"],cjy:["cjy","zh"],cmn:["cmn","zh"],coa:["coa","ms"],cpx:["cpx","zh"],csc:["csc","sgn"],csd:["csd","sgn"],cse:["cse","sgn"],csf:["csf","sgn"],csg:["csg","sgn"],csl:["csl","sgn"],csn:["csn","sgn"],csq:["csq","sgn"],csr:["csr","sgn"],czh:["czh","zh"],czo:["czo","zh"],doq:["doq","sgn"],dse:["dse","sgn"],dsl:["dsl","sgn"],dup:["dup","ms"],ecs:["ecs","sgn"],esl:["esl","sgn"],esn:["esn","sgn"],eso:["eso","sgn"],eth:["eth","sgn"],fcs:["fcs","sgn"],fse:["fse","sgn"],fsl:["fsl","sgn"],fss:["fss","sgn"],gan:["gan","zh"],gds:["gds","sgn"],gom:["gom","kok"],gse:["gse","sgn"],gsg:["gsg","sgn"],gsm:["gsm","sgn"],gss:["gss","sgn"],gus:["gus","sgn"],hab:["hab","sgn"],haf:["haf","sgn"],hak:["hak","zh"],hds:["hds","sgn"],hji:["hji","ms"],hks:["hks","sgn"],hos:["hos","sgn"],hps:["hps","sgn"],hsh:["hsh","sgn"],hsl:["hsl","sgn"],hsn:["hsn","zh"],icl:["icl","sgn"],ils:["ils","sgn"],inl:["inl","sgn"],ins:["ins","sgn"],ise:["ise","sgn"],isg:["isg","sgn"],isr:["isr","sgn"],jak:["jak","ms"],jax:["jax","ms"],jcs:["jcs","sgn"],jhs:["jhs","sgn"],jls:["jls","sgn"],jos:["jos","sgn"],jsl:["jsl","sgn"],jus:["jus","sgn"],kgi:["kgi","sgn"],knn:["knn","kok"],kvb:["kvb","ms"],kvk:["kvk","sgn"],kvr:["kvr","ms"],kxd:["kxd","ms"],lbs:["lbs","sgn"],lce:["lce","ms"],lcf:["lcf","ms"],liw:["liw","ms"],lls:["lls","sgn"],lsg:["lsg","sgn"],lsl:["lsl","sgn"],lso:["lso","sgn"],lsp:["lsp","sgn"],lst:["lst","sgn"],lsy:["lsy","sgn"],ltg:["ltg","lv"],lvs:["lvs","lv"],lzh:["lzh","zh"],max:["max","ms"],mdl:["mdl","sgn"],meo:["meo","ms"],mfa:["mfa","ms"],mfb:["mfb","ms"],mfs:["mfs","sgn"],min:["min","ms"],mnp:["mnp","zh"],mqg:["mqg","ms"],mre:["mre","sgn"],msd:["msd","sgn"],msi:["msi","ms"],msr:["msr","sgn"],mui:["mui","ms"],mzc:["mzc","sgn"],mzg:["mzg","sgn"],mzy:["mzy","sgn"],nan:["nan","zh"],nbs:["nbs","sgn"],ncs:["ncs","sgn"],nsi:["nsi","sgn"],nsl:["nsl","sgn"],nsp:["nsp","sgn"],nsr:["nsr","sgn"],nzs:["nzs","sgn"],okl:["okl","sgn"],orn:["orn","ms"],ors:["ors","ms"],pel:["pel","ms"],pga:["pga","ar"],pks:["pks","sgn"],prl:["prl","sgn"],prz:["prz","sgn"],psc:["psc","sgn"],psd:["psd","sgn"],pse:["pse","ms"],psg:["psg","sgn"],psl:["psl","sgn"],pso:["pso","sgn"],psp:["psp","sgn"],psr:["psr","sgn"],pys:["pys","sgn"],rms:["rms","sgn"],rsi:["rsi","sgn"],rsl:["rsl","sgn"],sdl:["sdl","sgn"],sfb:["sfb","sgn"],sfs:["sfs","sgn"],sgg:["sgg","sgn"],sgx:["sgx","sgn"],shu:["shu","ar"],slf:["slf","sgn"],sls:["sls","sgn"],sqk:["sqk","sgn"],sqs:["sqs","sgn"],ssh:["ssh","ar"],ssp:["ssp","sgn"],ssr:["ssr","sgn"],svk:["svk","sgn"],swc:["swc","sw"],swh:["swh","sw"],swl:["swl","sgn"],syy:["syy","sgn"],tmw:["tmw","ms"],tse:["tse","sgn"],tsm:["tsm","sgn"],tsq:["tsq","sgn"],tss:["tss","sgn"],tsy:["tsy","sgn"],tza:["tza","sgn"],ugn:["ugn","sgn"],ugy:["ugy","sgn"],ukl:["ukl","sgn"],uks:["uks","sgn"],urk:["urk","ms"],uzn:["uzn","uz"],uzs:["uzs","uz"],vgt:["vgt","sgn"],vkk:["vkk","ms"],vkt:["vkt","ms"],vsi:["vsi","sgn"],vsl:["vsl","sgn"],vsv:["vsv","sgn"],wuu:["wuu","zh"],xki:["xki","sgn"],xml:["xml","sgn"],xmm:["xmm","ms"],xms:["xms","sgn"],yds:["yds","sgn"],ysl:["ysl","sgn"],yue:["yue","zh"],zib:["zib","sgn"],zlm:["zlm","ms"],zmi:["zmi","ms"],zsl:["zsl","sgn"],zsm:["zsm","ms"]}},he={BHD:3,BYR:0,XOF:0,BIF:0,XAF:0,CLF:4,CLP:0,KMF:0,DJF:0,XPF:0,GNF:0,ISK:0,IQD:3,JPY:0,JOD:3,KRW:0,KWD:3,LYD:3,OMR:3,PYG:0,RWF:0,TND:3,UGX:0,UYI:0,VUV:0,VND:0};$(G,"NumberFormat",{configurable:!0,writable:!0,value:y}),$(G.NumberFormat,"prototype",{writable:!1}),ie.NumberFormat={"[[availableLocales]]":[],"[[relevantExtensionKeys]]":["nu"],"[[localeData]]":{}},$(G.NumberFormat,"supportedLocalesOf",{configurable:!0,writable:!0,value:oe.call(I,ie.NumberFormat)}),$(G.NumberFormat.prototype,"format",{configurable:!0,get:_});var me={arab:["٠","١","٢","٣","٤","٥","٦","٧","٨","٩"],arabext:["۰","۱","۲","۳","۴","۵","۶","۷","۸","۹"],bali:["᭐","᭑","᭒","᭓","᭔","᭕","᭖","᭗","᭘","᭙"],beng:["০","১","২","৩","৪","৫","৬","৭","৮","৯"],deva:["०","१","२","३","४","५","६","७","८","९"],fullwide:["0","1","2","3","4","5","6","7","8","9"],gujr:["૦","૧","૨","૩","૪","૫","૬","૭","૮","૯"],guru:["੦","੧","੨","੩","੪","੫","੬","੭","੮","੯"],hanidec:["〇","一","二","三","四","五","六","七","八","九"],khmr:["០","១","២","៣","៤","៥","៦","៧","៨","៩"],knda:["೦","೧","೨","೩","೪","೫","೬","೭","೮","೯"],laoo:["໐","໑","໒","໓","໔","໕","໖","໗","໘","໙"],latn:["0","1","2","3","4","5","6","7","8","9"],limb:["᥆","᥇","᥈","᥉","᥊","᥋","᥌","᥍","᥎","᥏"],mlym:["൦","൧","൨","൩","൪","൫","൬","൭","൮","൯"],mong:["᠐","᠑","᠒","᠓","᠔","᠕","᠖","᠗","᠘","᠙"],mymr:["၀","၁","၂","၃","၄","၅","၆","၇","၈","၉"],orya:["୦","୧","୨","୩","୪","୫","୬","୭","୮","୯"],tamldec:["௦","௧","௨","௩","௪","௫","௬","௭","௮","௯"],telu:["౦","౧","౨","౩","౪","౫","౬","౭","౮","౯"],thai:["๐","๑","๒","๓","๔","๕","๖","๗","๘","๙"],tibt:["༠","༡","༢","༣","༤","༥","༦","༧","༨","༩"]};$(G.NumberFormat.prototype,"resolvedOptions",{configurable:!0,writable:!0,value:function(){var e,t=new B,n=["locale","numberingSystem","style","currency","currencyDisplay","minimumIntegerDigits","minimumFractionDigits","maximumFractionDigits","minimumSignificantDigits","maximumSignificantDigits","useGrouping"],r=null!=this&&"object"==typeof this&&H(this);if(!r||!r["[[initializedNumberFormat]]"])throw new TypeError("`this` value for resolvedOptions() is not an initialized Intl.NumberFormat object.");for(var a=0,o=n.length;o>a;a++)J.call(r,e="[["+n[a]+"]]")&&(t[n[a]]={value:r[e],writable:!0,configurable:!0,enumerable:!0});return Q({},t)}}),$(G,"DateTimeFormat",{configurable:!0,writable:!0,value:x}),$(x,"prototype",{writable:!1});var ge={weekday:["narrow","short","long"],era:["narrow","short","long"],year:["2-digit","numeric"],month:["2-digit","numeric","narrow","short","long"],day:["2-digit","numeric"],hour:["2-digit","numeric"],minute:["2-digit","numeric"],second:["2-digit","numeric"],timeZoneName:["short","long"]};ie.DateTimeFormat={"[[availableLocales]]":[],"[[relevantExtensionKeys]]":["ca","nu"],"[[localeData]]":{}},$(G.DateTimeFormat,"supportedLocalesOf",{configurable:!0,writable:!0,value:oe.call(I,ie.DateTimeFormat)}),$(G.DateTimeFormat.prototype,"format",{configurable:!0,get:T}),$(G.DateTimeFormat.prototype,"resolvedOptions",{writable:!0,configurable:!0,value:function(){var e,t=new B,n=["locale","calendar","numberingSystem","timeZone","hour12","weekday","era","year","month","day","hour","minute","second","timeZoneName"],r=null!=this&&"object"==typeof this&&H(this);if(!r||!r["[[initializedDateTimeFormat]]"])throw new TypeError("`this` value for resolvedOptions() is not an initialized Intl.DateTimeFormat object.");for(var a=0,o=n.length;o>a;a++)J.call(r,e="[["+n[a]+"]]")&&(t[n[a]]={value:r[e],writable:!0,configurable:!0,enumerable:!0});return Q({},t)}});var ye=G.__localeSensitiveProtos={Number:{},Date:{}};ye.Number.toLocaleString=function(){if("[object Number]"!==Object.prototype.toString.call(this))throw new TypeError("`this` value must be a number for Number.prototype.toLocaleString()");return w(new y(arguments[0],arguments[1]),this)},ye.Date.toLocaleString=function(){if("[object Date]"!==Object.prototype.toString.call(this))throw new TypeError("`this` value must be a Date instance for Date.prototype.toLocaleString()");var e=+this;if(isNaN(e))return"Invalid Date";var t=arguments[0],n=arguments[1],n=P(n,"any","all"),r=new x(t,n);return D(r,e)},ye.Date.toLocaleDateString=function(){if("[object Date]"!==Object.prototype.toString.call(this))throw new TypeError("`this` value must be a Date instance for Date.prototype.toLocaleDateString()");var e=+this;if(isNaN(e))return"Invalid Date";var t=arguments[0],n=arguments[1],n=P(n,"date","date"),r=new x(t,n);return D(r,e)},ye.Date.toLocaleTimeString=function(){if("[object Date]"!==Object.prototype.toString.call(this))throw new TypeError("`this` value must be a Date instance for Date.prototype.toLocaleTimeString()");var e=+this;if(isNaN(e))return"Invalid Date";var t=arguments[0],n=arguments[1],n=P(n,"time","time"),r=new x(t,n);return D(r,e)},$(G,"__applyLocaleSensitivePrototypes",{writable:!0,configurable:!0,value:function(){$(Number.prototype,"toLocaleString",{writable:!0,configurable:!0,value:ye.Number.toLocaleString}),$(Date.prototype,"toLocaleString",{writable:!0,configurable:!0,value:ye.Date.toLocaleString});for(var e in ye.Date)J.call(ye.Date,e)&&$(Date.prototype,e,{writable:!0,configurable:!0,value:ye.Date[e]})}}),$(G,"__addLocaleData",{value:function(e){if(!r(e.locale))throw new Error("Object passed doesn't identify itself with a valid language tag");N(e,e.locale)}}),B.prototype=Q(null),L.prototype=Q(null),t["default"]=G},function(e,t){"use strict";var n="[a-z]{3}(?:-[a-z]{3}){0,2}",r="(?:[a-z]{2,3}(?:-"+n+")?|[a-z]{4}|[a-z]{5,8})",a="[a-z]{4}",o="(?:[a-z]{2}|\\d{3})",i="(?:[a-z0-9]{5,8}|\\d[a-z0-9]{3})",s="[0-9a-wy-z]",l=s+"(?:-[a-z0-9]{2,8})+",u="x(?:-[a-z0-9]{1,8})+",c="(?:en-GB-oed|i-(?:ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|tao|tay|tsu)|sgn-(?:BE-FR|BE-NL|CH-DE))",d="(?:art-lojban|cel-gaulish|no-bok|no-nyn|zh-(?:guoyu|hakka|min|min-nan|xiang))",p="(?:"+c+"|"+d+")",f=r+"(?:-"+a+")?(?:-"+o+")?(?:-"+i+")*(?:-"+l+")*(?:-"+u+")?",h=RegExp("^(?:"+f+"|"+u+"|"+p+")$","i"),m=RegExp("^(?!x).*?-("+i+")-(?:\\w{4,8}-(?!x-))*\\1\\b","i"),g=RegExp("^(?!x).*?-("+s+")-(?:\\w+-(?!x-))*\\1\\b","i"),y=RegExp("-"+l,"ig");t.expBCP47Syntax=h,t.expVariantDupes=m,t.expSingletonDupes=g,t.expExtSequences=y},function(e,t){"use strict";function n(e){for(var t=0;t-1&&(t.hour12=!0,t.pattern12=t.pattern,t.pattern=t.pattern.replace("{ampm}","").replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),t}function o(e){function t(e,t){var n=new Array((e.match(/M/g)||[]).length+1),r=new Array((e.match(/E/g)||[]).length+1);return n.length>2&&(t=t.replace(/(M|L)+/,n.join("$1"))),r.length>2&&(t=t.replace(/([Eec])+/,r.join("$1"))),t}var o,i,s,l,u,c=e.availableFormats,d=e.timeFormats,p=e.dateFormats,f=e.medium,h=[],m=[],g=[];for(o in c)c.hasOwnProperty(o)&&(i=t(o,c[o]),s=a(i),s&&(h.push(s),n(s)?g.push(i):r(s)&&m.push(i)));for(l=0;l1?t-1:0),r=1;t>r;r++)n[r-1]=arguments[r];this.dispatch(n.length?[e].concat(n):e)}function s(){}Object.defineProperty(t,"__esModule",{value:!0}),t.getInternalMethods=n,t.warn=r,t.uid=a,t.formatAsConstant=o,t.dispatchIdentity=i;var l=Object.getOwnPropertyNames(s),u=Object.getOwnPropertyNames(s.prototype)},[865,584,856],function(e,t){"use strict";function n(){var e=[],t=function(t){var n=e.indexOf(t);n>=0&&e.splice(n,1)},n=function(n){e.push(n);var r=function(){return t(n)};return{dispose:r}},r=function(t){e.forEach(function(e){return e(t)})};return{subscribe:n,push:r,unsubscribe:t}}e.exports=n},[866,856,584],[867,584,854],function(e,t,n,r){"use strict";function a(e){var t={},n=i.apply(o,s.call(arguments,1));for(var r in e)-1===l(n,r)&&(t[r]=e[r]);return t}var o=Array.prototype,i=o.concat,s=o.slice,l=n(r);e.exports=a},function(e,t,n,r,a,o,i,s,l){"use strict";function u(e){return e&&e.__esModule?e:{"default":e}}function c(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function d(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1?r-1:0),o=1;r>o;o++)a[o-1]=arguments[o];return w.isFunction(n)?E.createStoreFromClass.apply(E,[this,n,t].concat(a)):E.createStoreFromObject(this,n,t)}},{key:"createStore",value:function(e,t){var n=t||e.displayName||e.name||"";E.createStoreConfig(this.config,e);var r=E.transformStore(this.storeTransforms,e);(this.stores[n]||!n)&&(this.stores[n]?O.warn("A store named "+n+" already exists, double check your store names or pass in your own custom identifier for each store"):O.warn("Store name was not specified"),n=O.uid(this.stores,n));for(var a=arguments.length,o=Array(a>2?a-2:0),i=2;a>i;i++)o[i-2]=arguments[i];var s=w.isFunction(r)?E.createStoreFromClass.apply(E,[this,r,n].concat(o)):E.createStoreFromObject(this,r,n);return this.stores[n]=s,v.saveInitialSnapshot(this,n),s}},{key:"generateActions",value:function(){for(var e={name:"global"},t=arguments.length,n=Array(t),r=0;t>r;r++)n[r]=arguments[r];return this.createActions(n.reduce(function(e,t){return e[t]=O.dispatchIdentity,e},e))}},{key:"createAction",value:function(e,t,n){return P["default"](this,"global",e,t,n)}},{key:"createActions",value:function(e){var t=arguments,n=this,r=void 0===arguments[1]?{}:arguments[1],a={},o=O.uid(this._actionsRegistry,e.displayName||e.name||"Unknown");if(w.isFunction(e)){var i,s,l;!function(){w.assign(a,O.getInternalMethods(e,!0));var n=function(e){function t(){f(this,t);for(var e=arguments.length,n=Array(e),r=0;e>r;r++)n[r]=arguments[r];m(Object.getPrototypeOf(t.prototype),"constructor",this).apply(this,n)}return p(t,e),g(t,[{key:"generateActions",value:function(){for(var e=arguments.length,t=Array(e),n=0;e>n;n++)t[n]=arguments[n];t.forEach(function(e){a[e]=O.dispatchIdentity})}}]),t}(e);for(i=t.length,s=Array(i>2?i-2:0),l=2;i>l;l++)s[l-2]=t[l];w.assign(a,new(h.apply(n,[null].concat(d(s)))))}()}else w.assign(a,e);return this.actions[o]=this.actions[o]||{},w.eachObject(function(e,t){if(w.isFunction(t)){r[e]=P["default"](n,o,e,t,r);var a=O.formatAsConstant(e);r[a]=r[e].id}},[a]),r}},{key:"takeSnapshot",value:function(){for(var e=arguments.length,t=Array(e),n=0;e>n;n++)t[n]=arguments[n];var r=v.snapshot(this,t);return w.assign(this._lastSnapshot,r),this.serialize(r)}},{key:"rollback",value:function(){v.setAppState(this,this.serialize(this._lastSnapshot),function(e){e.lifecycle("rollback"),e.emitChange()})}},{key:"recycle",value:function(){for(var e=arguments.length,t=Array(e),n=0;e>n;n++)t[n]=arguments[n];var r=t.length?v.filterSnapshots(this,this._initSnapshot,t):this._initSnapshot;v.setAppState(this,this.serialize(r),function(e){e.lifecycle("init"),e.emitChange()})}},{key:"flush",value:function(){var e=this.serialize(v.snapshot(this));return this.recycle(),e}},{key:"bootstrap",value:function(e){v.setAppState(this,e,function(e){e.lifecycle("bootstrap"),e.emitChange()})}},{key:"prepare",value:function(e,t){var n={};if(!e.displayName)throw new ReferenceError("Store provided does not have a name");return n[e.displayName]=t,this.serialize(n)}},{key:"addActions",value:function(e,t){for(var n=arguments.length,r=Array(n>2?n-2:0),a=2;n>a;a++)r[a-2]=arguments[a];this.actions[e]=Array.isArray(t)?this.generateActions.apply(this,t):this.createActions.apply(this,[t].concat(r))}},{key:"addStore",value:function(e,t){for(var n=arguments.length,r=Array(n>2?n-2:0),a=2;n>a;a++)r[a-2]=arguments[a];this.createStore.apply(this,[t,e].concat(r))}},{key:"getActions",value:function(e){return this.actions[e]}},{key:"getStore",value:function(e){return this.stores[e]}}],[{key:"debug",value:function(e,t){var n="alt.js.org";return"undefined"!=typeof window&&(window[n]=window[n]||[],window[n].push({name:e,alt:t})),t}}]),e}();t["default"]=A,e.exports=t["default"]},function(e,t,n,r){e.exports.Dispatcher=n(r)},function(e,t,n,r){"use strict";function a(){this.$Dispatcher_callbacks={},this.$Dispatcher_isPending={},this.$Dispatcher_isHandled={},this.$Dispatcher_isDispatching=!1,this.$Dispatcher_pendingPayload=null}var o=n(r),i=1,s="ID_";a.prototype.register=function(e){var t=s+i++;return this.$Dispatcher_callbacks[t]=e,t},a.prototype.unregister=function(e){o(this.$Dispatcher_callbacks[e],"Dispatcher.unregister(...): `%s` does not map to a registered callback.",e),delete this.$Dispatcher_callbacks[e]},a.prototype.waitFor=function(e){o(this.$Dispatcher_isDispatching,"Dispatcher.waitFor(...): Must be invoked while dispatching.");for(var t=0;tr;r++)n[r]=arguments[r];b(Object.getPrototypeOf(t.prototype),"constructor",this).apply(this,n)}return c(t,e),t}(t);p(o.prototype,e,n,{getInstance:function(){return r},setState:function(e){d(this,r,e)}});for(var i=arguments.length,s=Array(i>3?i-3:0),l=3;i>l;l++)s[l-3]=arguments[l];var f=new(y.apply(o,[null].concat(s)));return a.bindListeners&&f.bindListeners(a.bindListeners),a.datasource&&f.registerAsync(a.datasource),r=k.assign(new x["default"](e,f,"object"==typeof f.state?f.state:null,t),_.getInternalMethods(t),a.publicMethods,{displayName:n})}Object.defineProperty(t,"__esModule",{value:!0});var y=Function.prototype.bind,b=function(e,t,n){for(var r=!0;r;){var a=e,o=t,i=n;s=u=l=void 0,r=!1,null===a&&(a=Function.prototype);var s=Object.getOwnPropertyDescriptor(a,o);if(void 0!==s){if("value"in s)return s.value;var l=s.get;return void 0===l?void 0:l.call(i)}var u=Object.getPrototypeOf(a);if(null===u)return void 0;e=u,t=o,n=i,r=!0}};t.createStoreConfig=f,t.transformStore=h,t.createStoreFromObject=m,t.createStoreFromClass=g;var v=n(r),_=l(v),w=n(a),k=l(w),E=n(o),x=s(E),O=n(i),S=s(O)},function(e,t,n,r,a){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function i(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var l=function(){function e(e,t){for(var n=0;nn;n++)t[n]=arguments[n];if(!t.length)throw new ReferenceError("Dispatch tokens not provided");var r=t;1===t.length&&(r=Array.isArray(t[0])?t[0]:t);var a=r.map(function(e){return e.dispatchToken||e});this.dispatcher.waitFor(a)},exportAsync:function(e){this.registerAsync(e)},registerAsync:function(e){var t=this,n=0,r=c.isFunction(e)?e(this.alt):e,a=Object.keys(r).reduce(function(e,a){var o=r[a],i=c.isFunction(o)?o(t):o,s=["success","error","loading"];return s.forEach(function(e){if(i[e]&&!i[e].id)throw new Error(e+" handler must be an action function")}),e[a]=function(){for(var e=arguments.length,r=Array(e),a=0;e>a;a++)r[a]=arguments[a];var o=t.getInstance().getState(),s=i.local&&i.local.apply(i,[o].concat(r)),l=i.shouldFetch?i.shouldFetch.apply(i,[o].concat(r)):null==s,u=i.interceptResponse||function(e){return e},c=function(e,a){return function(o){var i=function(){if(n-=1,e(u(o,e,r)),a)throw o};return t.alt.trapAsync?function(){return i()}:i()}};return l?(n+=1,i.loading&&i.loading(u(null,i.loading,r)),i.remote.apply(i,[o].concat(r)).then(c(i.success),c(i.error,1))):void t.emitChange()},e},{});this.exportPublicMethods(a),this.exportPublicMethods({isLoading:function(){return n>0}})},exportPublicMethods:function(e){var t=this;c.eachObject(function(e,n){if(!c.isFunction(n))throw new TypeError("exportPublicMethods expects a function");t.publicMethods[e]=n},[e])},emitChange:function(){this.getInstance().emitChange()},on:function(e,t){"error"===e&&(this.handlesOwnErrors=!0);var n=this.lifecycleEvents[e]||l["default"]();return this.lifecycleEvents[e]=n,n.subscribe(t.bind(this))},bindAction:function(e,t){if(!e)throw new ReferenceError("Invalid action reference passed in");if(!c.isFunction(t))throw new TypeError("bindAction expects a function");if(t.length>1)throw new TypeError("Action handler in store "+this.displayName+" for "+((e.id||e).toString()+" was defined with ")+"two parameters. Only a single parameter is passed through the dispatcher, did you mean to pass in an Object instead?");var n=e.id?e.id:e;this.actionListeners[n]=t.bind(this),this.boundListeners.push(n)},bindActions:function(e){var t=this;c.eachObject(function(e,n){var r=/./,a=e.replace(r,function(e){return"on"+e[0].toUpperCase()}),o=null;if(t[e]&&t[a])throw new ReferenceError("You have multiple action handlers bound to an action: "+(e+" and "+a));t[e]?o=t[e]:t[a]&&(o=t[a]),o&&t.bindAction(n,o)},[e])},bindListeners:function(e){var t=this;c.eachObject(function(e,n){var r=t[e];if(!r)throw new ReferenceError(e+" defined but does not exist in "+t.displayName);Array.isArray(n)?n.forEach(function(e){t.bindAction(e,r)}):t.bindAction(n,r)},[e])}};t["default"]=d,e.exports=t["default"]},function(e,t,n,r,a){"use strict";function o(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t,n,r,a){var o=p.uid(e._actionsRegistry,t+"."+n);e._actionsRegistry[o]=1;var i={id:o,namespace:t,name:n},s=new f(e,o,r,a,i),l=function(t){return e.dispatch(o,t,i)},u=function(){s.dispatched=!1;var e=s._dispatch.apply(s,arguments);return s.dispatched||void 0===e||c.isPromise(e)||(c.isFunction(e)?e(l):l(e)),e};u.defer=function(){for(var e=arguments.length,t=Array(e),n=0;e>n;n++)t[n]=arguments[n];setTimeout(function(){s._dispatch.apply(null,t)})},u.id=o,u.data=i;var d=e.actions[t],h=p.uid(d,n);return d[h]=u,u}Object.defineProperty(t,"__esModule",{value:!0});var l=function(){function e(e,t){for(var n=0;n + + 1.app.js + app.css + app.js + favicon.ico + fonts + fonts/Roboto-Bold.eot + fonts/Roboto-Bold.svg + fonts/Roboto-Bold.ttf + fonts/Roboto-Bold.woff + fonts/Roboto-Light.eot + fonts/Roboto-Light.svg + fonts/Roboto-Light.ttf + fonts/Roboto-Light.woff + fonts/Roboto-Regular.eot + fonts/Roboto-Regular.svg + fonts/Roboto-Regular.ttf + fonts/Roboto-Regular.woff + fonts/RobotoCondensed-Regular.eot + fonts/RobotoCondensed-Regular.svg + fonts/RobotoCondensed-Regular.ttf + fonts/RobotoCondensed-Regular.woff + index.html + vendors.js + + diff --git a/programs/genesis_util/CMakeLists.txt b/programs/genesis_util/CMakeLists.txt new file mode 100644 index 00000000..1125a108 --- /dev/null +++ b/programs/genesis_util/CMakeLists.txt @@ -0,0 +1,29 @@ + +add_executable( genesis_update genesis_update.cpp ) +if( UNIX AND NOT APPLE ) + set(rt_library rt ) +endif() + +target_link_libraries( genesis_update + PRIVATE graphene_app graphene_chain graphene_egenesis_none fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) + +install( TARGETS + genesis_update + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) + +add_executable( get_dev_key get_dev_key.cpp ) + +target_link_libraries( get_dev_key + PRIVATE graphene_app graphene_chain graphene_egenesis_none graphene_utilities fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) + +install( TARGETS + get_dev_key + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/programs/genesis_util/genesis_update.cpp b/programs/genesis_util/genesis_update.cpp new file mode 100644 index 00000000..4923e72e --- /dev/null +++ b/programs/genesis_util/genesis_update.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2015, Cryptonomex, Inc. + * All rights reserved. + * + * This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and + * the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification, + * are permitted until September 8, 2015, provided that the following conditions are met: + * + * 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifndef WIN32 +#include +#endif + +using namespace graphene::app; +using namespace graphene::chain; +using namespace graphene::utilities; +using namespace std; +namespace bpo = boost::program_options; + +// hack: import create_example_genesis() even though it's a way, way +// specific internal detail +namespace graphene { namespace app { namespace detail { +genesis_state_type create_example_genesis(); +} } } // graphene::app::detail + +int main( int argc, char** argv ) +{ + try + { + bpo::options_description cli_options("Graphene empty blocks"); + cli_options.add_options() + ("help,h", "Print this help message and exit.") + ("genesis-json,g", bpo::value(), "File to read genesis state from") + ("out,o", bpo::value(), "File to output new genesis to") + ("dev-account-prefix", bpo::value()->default_value("devacct"), "Prefix for dev accounts") + ("dev-key-prefix", bpo::value()->default_value("devkey-"), "Prefix for dev key") + ("dev-account-count", bpo::value()->default_value(0), "Prefix for dev accounts") + ("dev-balance-count", bpo::value()->default_value(0), "Prefix for dev balances") + ("dev-balance-amount", bpo::value()->default_value(uint64_t(1000)*uint64_t(1000)*uint64_t(100000)), "Amount in each dev balance") + ; + + bpo::variables_map options; + try + { + boost::program_options::store( boost::program_options::parse_command_line(argc, argv, cli_options), options ); + } + catch (const boost::program_options::error& e) + { + std::cerr << "empty_blocks: error parsing command line: " << e.what() << "\n"; + return 1; + } + + if( options.count("help") ) + { + std::cout << cli_options << "\n"; + return 1; + } + + if( !options.count( "genesis-json" ) ) + { + std::cerr << "--genesis-json option is required\n"; + return 1; + } + + if( !options.count( "out" ) ) + { + std::cerr << "--out option is required\n"; + return 1; + } + + genesis_state_type genesis; + if( options.count("genesis-json") ) + { + fc::path genesis_json_filename = options["genesis-json"].as(); + std::cerr << "update_genesis: Reading genesis from file " << genesis_json_filename.preferred_string() << "\n"; + std::string genesis_json; + read_file_contents( genesis_json_filename, genesis_json ); + genesis = fc::json::from_string( genesis_json ).as< genesis_state_type >(); + } + else + { + std::cerr << "update_genesis: Using example genesis\n"; + genesis = graphene::app::detail::create_example_genesis(); + } + + std::string dev_key_prefix = options["dev-key-prefix"].as(); + + auto get_dev_key = [&]( std::string prefix, uint32_t i ) -> public_key_type + { + return fc::ecc::private_key::regenerate( fc::sha256::hash( dev_key_prefix + prefix + std::to_string(i) ) ).get_public_key(); + }; + + uint32_t dev_account_count = options["dev-account-count"].as(); + std::string dev_account_prefix = options["dev-account-prefix"].as(); + for(uint32_t i=0;i(); + uint64_t dev_balance_amount = options["dev-balance-amount"].as(); + for(uint32_t i=0;i name2index; + size_t num_accounts = genesis.initial_accounts.size(); + for( size_t i=0; i(); + fc::json::save_to_file( genesis, output_filename ); + } + catch ( const fc::exception& e ) + { + std::cout << e.to_detail_string() << "\n"; + return 1; + } + return 0; +} diff --git a/programs/genesis_util/get_dev_key.cpp b/programs/genesis_util/get_dev_key.cpp new file mode 100644 index 00000000..2a5b110e --- /dev/null +++ b/programs/genesis_util/get_dev_key.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015, Cryptonomex, Inc. + * All rights reserved. + * + * This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and + * the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification, + * are permitted until September 8, 2015, provided that the following conditions are met: + * + * 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +using namespace std; + +int main( int argc, char** argv ) +{ + try + { + std::string dev_key_prefix; + bool need_help; + if( argc < 2 ) + need_help = true; + else + { + dev_key_prefix = argv[1]; + if( (dev_key_prefix == "-h") + || (dev_key_prefix == "--help") + ) + need_help = true; + } + + if( need_help ) + { + std::cerr << "get-dev-key ...\n" + "\n" + "example:\n" + "\n" + "get-dev-key wxyz- owner-5 active-7 balance-9 wit-block-signing-3 wit-owner-5 wit-active-33\n" + "get-dev-key wxyz- wit-block-signing-0:101\n" + "\n"; + return 1; + } + + bool comma = false; + + auto show_key = [&]( const fc::ecc::private_key& priv_key ) + { + fc::mutable_variant_object mvo; + graphene::chain::public_key_type pub_key = priv_key.get_public_key(); + mvo( "private_key", graphene::utilities::key_to_wif( priv_key ) ) + ( "public_key", std::string( pub_key ) ) + ( "address", graphene::chain::address( pub_key ) ) + ; + if( comma ) + std::cout << ",\n"; + std::cout << fc::json::to_string( mvo ); + comma = true; + }; + + std::cout << "["; + + for( int i=2; i keys; + if( lep >= 0 ) + { + for( int k=lep; k #include #include +#include +#include #include using namespace graphene::chain; @@ -365,7 +367,7 @@ int main( int argc, char** argv ) operation op; std::cout << "ChainTypes.operations=\n"; - for( uint32_t i = 0; i < op.count(); ++i ) + for( int i = 0; i < op.count(); ++i ) { op.set_which(i); op.visit( detail_ns::serialize_type_visitor(i) ); diff --git a/programs/light_client/Account.cpp b/programs/light_client/Account.cpp new file mode 100644 index 00000000..60740b38 --- /dev/null +++ b/programs/light_client/Account.cpp @@ -0,0 +1,117 @@ +#include "Balance.hpp" +#include "ChainDataModel.hpp" +#include "Wallet.hpp" + +#include + +void Account::setAccountObject(const graphene::chain::account_object& obj) +{ + auto oldName = m_account.name; + auto oldMemoKey = memoKey(); + + m_account = obj; + if (oldName != m_account.name) + Q_EMIT nameChanged(); + if (oldMemoKey != memoKey()) + Q_EMIT memoKeyChanged(); + + if (!m_loaded) { + m_loaded = true; + Q_EMIT loaded(); + qDebug() << name() << "loaded."; + } +} + +QString Account::memoKey() const +{ + return toQString(m_account.options.memo_key); +} + +QQmlListProperty Account::balances() +{ + auto count = [](QQmlListProperty* list) { + return reinterpret_cast(list->data)->m_balances.size(); + }; + auto at = [](QQmlListProperty* list, int index) { + return reinterpret_cast(list->data)->m_balances[index]; + }; + + return QQmlListProperty(this, this, count, at); +} + +double Account::getActiveControl(Wallet* w, int depth)const +{ + if (depth >= GRAPHENE_MAX_SIG_CHECK_DEPTH) return 0; + if (m_account.active.num_auths() == 0) return 0; + if (m_account.active.weight_threshold == 0) return 0; + + uint64_t weight = 0; + for (auto& key : m_account.active.key_auths) + { + if (w->hasPrivateKey(toQString(key.first))) weight += key.second; + } + + ChainDataModel* model = qobject_cast(parent()); + for (auto& acnt : m_account.active.account_auths) + { + Account* account = model->getAccount(acnt.first.instance.value); + if (!account->m_loaded) { + QEventLoop el; + connect(account, &Account::loaded, &el, &QEventLoop::quit); + QTimer::singleShot(1000, &el, SLOT(quit())); + el.exec(); + if (!account->m_loaded) + // We don't have this account loaded yet... Oh well, move along + continue; + } + if (account->getActiveControl(w, depth + 1) >= 1.0) + weight += acnt.second; + } + + return double(weight) / double(m_account.active.weight_threshold); +} + +double Account::getOwnerControl(Wallet* w)const +{ + if (m_account.owner.num_auths() == 0) return 0; + if (m_account.owner.weight_threshold == 0) return 0; + uint64_t weight = 0; + for (auto& key : m_account.owner.key_auths) + { + if (w->hasPrivateKey(toQString(key.first))) weight += key.second; + } + + ChainDataModel* model = qobject_cast(parent()); + for (auto& acnt : m_account.owner.account_auths) + { + Account* account = model->getAccount(acnt.first.instance.value); + if (!account->m_loaded) + // We don't have this account loaded yet... Oh well, move along + continue; + if (account->getActiveControl(w) >= 1.0) + weight += acnt.second; + } + + return double(weight) / double(m_account.owner.weight_threshold); +} + +void Account::update(const graphene::chain::account_balance_object& balance) +{ + auto balanceItr = std::find_if(m_balances.begin(), m_balances.end(), + [&balance](Balance* b) { return b->type()->id() == balance.asset_type.instance.value; }); + + if (balanceItr != m_balances.end()) { + ilog("Updating ${a}'s balance: ${b}", ("a", name().toStdString())("b", balance)); + (*balanceItr)->update(balance); + Q_EMIT balancesChanged(); + } else { + ilog("Adding to ${a}'s new balance: ${b}", ("a", name().toStdString())("b", balance)); + Balance* newBalance = new Balance; + newBalance->setParent(this); + auto model = qobject_cast(parent()); + newBalance->setProperty("type", QVariant::fromValue(model->getAsset(balance.asset_type.instance.value))); + newBalance->setProperty("amount", QVariant::fromValue(balance.balance.value)); + m_balances.append(newBalance); + Q_EMIT balancesChanged(); + } +} diff --git a/programs/light_client/Account.hpp b/programs/light_client/Account.hpp new file mode 100644 index 00000000..4b58ce69 --- /dev/null +++ b/programs/light_client/Account.hpp @@ -0,0 +1,70 @@ +#pragma once +#pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#include "GrapheneObject.hpp" + +#include +#include + +namespace graphene { namespace chain { +class account_balance_object; +}} + +using graphene::chain::account_object; +using graphene::chain::account_balance_object; + +class Balance; +class Wallet; + +class Account : public GrapheneObject { + Q_OBJECT + + Q_PROPERTY(QString name READ name NOTIFY nameChanged) + Q_PROPERTY(QQmlListProperty balances READ balances NOTIFY balancesChanged) + Q_PROPERTY(QString memoKey READ memoKey NOTIFY memoKeyChanged) + Q_PROPERTY(bool isLoaded MEMBER m_loaded NOTIFY loaded) + + account_object m_account; + QList m_balances; + bool m_loaded = false; + +public: + Account(ObjectId id = -1, QString name = QString(), QObject* parent = nullptr) + : GrapheneObject(id, parent) + { + m_account.name = name.toStdString(); + } + void setAccountObject(const account_object& obj); + const account_object& accountObject()const { + return m_account; + } + + QString name()const { return QString::fromStdString(m_account.name); } + QString memoKey()const; + QQmlListProperty balances(); + + void setBalances(QList balances) { + if (balances != m_balances) { + m_balances = balances; + Q_EMIT balancesChanged(); + } + } + + void update(const account_balance_object& balance); + + /** + * Anything greater than 1.0 means full authority. + * Anything between (0 and 1.0) means partial authority + * 0 means no authority. + * + * @return the percent of direct control the wallet has over the account. + */ + Q_INVOKABLE double getOwnerControl(Wallet* w)const; + Q_INVOKABLE double getActiveControl(Wallet* w , int depth = 0)const; + +Q_SIGNALS: + void nameChanged(); + void balancesChanged(); + void memoKeyChanged(); + void loaded(); +}; diff --git a/programs/light_client/Asset.cpp b/programs/light_client/Asset.cpp new file mode 100644 index 00000000..d2401e41 --- /dev/null +++ b/programs/light_client/Asset.cpp @@ -0,0 +1,29 @@ +#include "Asset.hpp" + +#include + +#include + +QString Asset::formatAmount(qint64 amount) const +{ + graphene::chain::asset_object ao; + ao.precision = m_precision; + return QString::fromStdString(ao.amount_to_string(amount)); +} + +void Asset::update(const graphene::chain::asset_object& asset) +{ + if (asset.id.instance() != id()) + setProperty("id", QVariant::fromValue(asset.id.instance())); + if (asset.symbol != m_symbol.toStdString()) { + m_symbol = QString::fromStdString(asset.symbol); + Q_EMIT symbolChanged(); + } + if (asset.precision != m_precision) { + m_precision = asset.precision; + Q_EMIT precisionChanged(); + } + + if (asset.options.core_exchange_rate != coreExchangeRate) + coreExchangeRate = asset.options.core_exchange_rate; +} diff --git a/programs/light_client/Asset.hpp b/programs/light_client/Asset.hpp new file mode 100644 index 00000000..67ee720e --- /dev/null +++ b/programs/light_client/Asset.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "GrapheneObject.hpp" + +#include "graphene/chain/protocol/asset.hpp" + +class Asset : public GrapheneObject { + Q_OBJECT + + Q_PROPERTY(QString symbol MEMBER m_symbol READ symbol NOTIFY symbolChanged) + Q_PROPERTY(quint32 precision MEMBER m_precision NOTIFY precisionChanged) + + QString m_symbol; + quint32 m_precision; + + graphene::chain::price coreExchangeRate; + +public: + Asset(ObjectId id = -1, QString symbol = QString(), quint32 precision = 0, QObject* parent = nullptr) + : GrapheneObject(id, parent), m_symbol(symbol), m_precision(precision) + {} + + QString symbol() const { + return m_symbol; + } + + quint64 precisionPower() const { + quint64 power = 1; + for (int i = 0; i < m_precision; ++i) + power *= 10; + return power; + } + /// Given an amount like 123401, return "1234.01" + Q_INVOKABLE QString formatAmount(qint64 amount) const; + + void update(const graphene::chain::asset_object& asset); + +Q_SIGNALS: + void symbolChanged(); + void precisionChanged(); +}; diff --git a/programs/light_client/Balance.cpp b/programs/light_client/Balance.cpp new file mode 100644 index 00000000..d626b67f --- /dev/null +++ b/programs/light_client/Balance.cpp @@ -0,0 +1,16 @@ +#include "Balance.hpp" +#include "Asset.hpp" + +#include + +qreal Balance::amountReal() const { + return amount / qreal(m_type->precisionPower()); +} + +void Balance::update(const graphene::chain::account_balance_object& update) +{ + if (update.balance != amount) { + amount = update.balance.value; + emit amountChanged(); + } +} diff --git a/programs/light_client/Balance.hpp b/programs/light_client/Balance.hpp new file mode 100644 index 00000000..47e0727d --- /dev/null +++ b/programs/light_client/Balance.hpp @@ -0,0 +1,33 @@ +#pragma once +#pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#include "GrapheneObject.hpp" + +namespace graphene { namespace chain { +class account_balance_object; +}} + +class Asset; +class Balance : public GrapheneObject { + Q_OBJECT + + Q_PROPERTY(Asset* type MEMBER m_type READ type NOTIFY typeChanged) + Q_PROPERTY(qint64 amount MEMBER amount NOTIFY amountChanged) + + Asset* m_type; + qint64 amount; + +public: + // This ultimately needs to be replaced with a string equivalent + Q_INVOKABLE qreal amountReal() const; + + Asset* type()const { + return m_type; + } + + void update(const graphene::chain::account_balance_object& update); + +Q_SIGNALS: + void typeChanged(); + void amountChanged(); +}; diff --git a/programs/light_client/BoostMultiIndex.hpp b/programs/light_client/BoostMultiIndex.hpp new file mode 100644 index 00000000..b31d00e9 --- /dev/null +++ b/programs/light_client/BoostMultiIndex.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include +#include +#include + +using boost::multi_index_container; +using boost::multi_index::indexed_by; +using boost::multi_index::hashed_unique; +using boost::multi_index::tag; +using boost::multi_index::const_mem_fun; +using boost::multi_index::ordered_unique; diff --git a/programs/light_client/CMakeLists.txt b/programs/light_client/CMakeLists.txt index 54e8dfc9..eac86b39 100644 --- a/programs/light_client/CMakeLists.txt +++ b/programs/light_client/CMakeLists.txt @@ -13,11 +13,33 @@ find_package(Qt5Quick) file(GLOB QML qml/*) -qt5_add_resources(QML_QRC qml/qml.qrc) +# Skip building QRC in debug mode, since we access the QML files directly on disk in debug mode +if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + qt5_add_resources(QML_QRC qml/qml.qrc) +endif() + +add_executable(light_client + Wallet.cpp + ChainDataModel.cpp + Operations.cpp + GrapheneApplication.cpp + GrapheneObject.cpp + Asset.cpp + Account.cpp + Balance.cpp + Transaction.cpp + main.cpp ${QML_QRC} ${QML}) -add_executable(light_client ClientDataModel.cpp ClientDataModel.hpp main.cpp ${QML_QRC} ${QML}) if (CMAKE_VERSION VERSION_LESS 3.0) add_dependencies(light_client gen_qrc) endif() -target_link_libraries(light_client PRIVATE Qt5::Core Qt5::Widgets Qt5::Quick graphene_chain graphene_utilities fc graphene_app ) +target_link_libraries(light_client PRIVATE Qt5::Core Qt5::Widgets Qt5::Quick graphene_chain graphene_egenesis_brief graphene_utilities fc graphene_app ) + +install( TARGETS + light_client + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/programs/light_client/ChainDataModel.cpp b/programs/light_client/ChainDataModel.cpp new file mode 100644 index 00000000..56643533 --- /dev/null +++ b/programs/light_client/ChainDataModel.cpp @@ -0,0 +1,285 @@ +#include "ChainDataModel.hpp" +#include "Balance.hpp" +#include "Operations.hpp" +#include "Transaction.hpp" + +#include +#include + +#include + +#include + +using namespace graphene::app; + +template +QString idToString(T id) { + return QString("%1.%2.%3").arg(T::space_id).arg(T::type_id).arg(ObjectId(id.instance)); +} +QString idToString(graphene::db::object_id_type id) { + return QString("%1.%2.%3").arg(id.space(), id.type(), ObjectId(id.instance())); +} + +ChainDataModel::ChainDataModel(fc::thread& t, QObject* parent) + :QObject(parent),m_rpc_thread(&t){} + +void ChainDataModel::setDatabaseAPI(fc::api dbapi) { + m_db_api = dbapi; + m_rpc_thread->async([this] { + m_global_properties = m_db_api->get_global_properties(); + m_db_api->subscribe_to_objects([this](const variant& v) { + m_global_properties = v.as(); + }, {m_global_properties.id}); + + m_dynamic_global_properties = m_db_api->get_dynamic_global_properties(); + m_db_api->subscribe_to_objects([this](const variant& d) { + m_dynamic_global_properties = d.as(); + }, {m_dynamic_global_properties.id}); + + m_chain_properties = m_db_api->get_chain_properties(); + }); +} + +void ChainDataModel::setNetworkAPI(fc::api napi) +{ + m_net_api = napi; +} + +void ChainDataModel::broadcast(Transaction* transaction) +{ + try { + m_net_api->broadcast_transaction_with_callback([transaction](const fc::variant&) { + transaction->setStatus(Transaction::Complete); + }, transaction->internalTransaction()); + transaction->setStatus(Transaction::Pending); + } catch (const fc::exception& e) { + transaction->setStatus(Transaction::Failed); + Q_EMIT exceptionThrown(QString::fromStdString(e.to_string())); + } +} + +Asset* ChainDataModel::getAsset(ObjectId id) +{ + auto& by_id_idx = m_assets.get(); + auto itr = by_id_idx.find(id); + if (itr == by_id_idx.end()) + { + auto result = m_assets.insert(new Asset(id, QString::number(--m_account_query_num), 0, this)); + assert(result.second); + + // Run in RPC thread + m_rpc_thread->async([this,id,result]{ getAssetImpl(idToString(asset_id_type(id)), &*result.first); }); + return *result.first; + } + return *itr; +} + +Asset* ChainDataModel::getAsset(QString symbol) +{ + auto& by_symbol_idx = m_assets.get(); + auto itr = by_symbol_idx.find(symbol); + if (itr == by_symbol_idx.end()) + { + auto result = m_assets.insert(new Asset(--m_account_query_num, symbol, 0, this)); + assert(result.second); + + // Run in RPC thread + m_rpc_thread->async([this,symbol,result](){ getAssetImpl(symbol, &*result.first); }); + return *result.first; + } + return *itr; +} + +QDateTime ChainDataModel::chainTime() const { + return QDateTime::fromTime_t(m_dynamic_global_properties.time.sec_since_epoch()); +} + +void ChainDataModel::processUpdatedObject(const fc::variant& update) +{ + if (update.is_null()) + return; + if (&fc::thread::current() == m_rpc_thread) + { + ilog("Proxying object update to app thread."); + Q_EMIT queueExecute([this,update]{processUpdatedObject(update);}); + return; + } + + idump((update)); + try { + auto id = update.as()["id"].as(); + if (id.space() == protocol_ids) { + switch (id.type()) { + default: + wlog("Update procedure for ${update} is not yet implemented.", ("update", update)); + break; + } + } else if (id.space() == implementation_ids) { + switch (id.type()) { + case impl_account_balance_object_type: { + account_balance_object balance = update.as(); + auto owner = m_accounts.find(balance.owner.instance.value); + if (owner != m_accounts.end()) + (*owner)->update(balance); + else + elog("Got unexpected balance update:\n${u}\nfor an account I don't have.", + ("u", update)); + break; + } + + default: + wlog("Update procedure for ${update} is not yet implemented.", ("update", update)); + break; + } + } else + wlog("Update procedure for ${update} is not yet implemented.", ("update", update)); + } catch (const fc::exception& e) { + elog("Caught exception while updating object: ${e}", ("e", e.to_detail_string())); + } +} + +void ChainDataModel::getAssetImpl(QString assetIdentifier, Asset* const * assetInContainer) +{ + try { + ilog("Fetching asset ${asset}", ("asset", assetIdentifier.toStdString())); + auto result = m_db_api->lookup_asset_symbols({assetIdentifier.toStdString()}); + + // Run in main thread + Q_EMIT queueExecute([this,result,assetInContainer](){ + ilog("Processing result ${r}", ("r", result)); + auto itr = m_assets.iterator_to(*assetInContainer); + + if (result.size() == 0 || !result.front()) { + (*itr)->deleteLater(); + m_assets.erase(itr); + } else { + m_assets.modify(itr, + [=](Asset* a){ + a->setProperty("symbol", QString::fromStdString(result.front()->symbol)); + a->setProperty("id", ObjectId(result.front()->id.instance())); + a->setProperty("precision", result.front()->precision); + }); + } + }); + } + catch ( const fc::exception& e ) + { + Q_EMIT exceptionThrown(QString::fromStdString(e.to_string())); + } +} + +void ChainDataModel::getAccountImpl(QString accountIdentifier, Account* const * accountInContainer) +{ + try { + ilog("Fetching account ${acct}", ("acct", accountIdentifier.toStdString())); + auto result = m_db_api->get_full_accounts([this](const fc::variant& v) { + vector updates = v.as>(); + for (const variant& update : updates) { + if (update.is_object()) + processUpdatedObject(update); + else + elog("Handling object deletions is not yet implemented: ${update}", ("update", update)); + } + // TODO: replace true on the next line with a smarter decision as to whether we need status updates or not + }, {accountIdentifier.toStdString()}, true); + fc::optional accountPackage; + + if (result.count(accountIdentifier.toStdString())) { + accountPackage = result.at(accountIdentifier.toStdString()); + + // Fetch all necessary assets + QList assetsToFetch; + QList assetPlaceholders; + assetsToFetch.reserve(accountPackage->balances.size()); + // Get list of asset IDs the account has a balance in + std::transform(accountPackage->balances.begin(), accountPackage->balances.end(), std::back_inserter(assetsToFetch), + [](const account_balance_object& b) { return b.asset_type; }); + auto function = [this,&assetsToFetch,&assetPlaceholders] { + auto itr = assetsToFetch.begin(); + const auto& assets_by_id = m_assets.get(); + // Filter out assets I already have, create placeholders for the ones I don't. + while (itr != assetsToFetch.end()) { + if (assets_by_id.count(itr->instance)) + itr = assetsToFetch.erase(itr); + else { + assetPlaceholders.push_back(&*m_assets.insert(new Asset(itr->instance, QString(), 0, this)).first); + ++itr; + } + } + }; + QMetaObject::invokeMethod(parent(), "execute", Qt::BlockingQueuedConnection, + Q_ARG(const std::function&, function)); + assert(assetsToFetch.size() == assetPlaceholders.size()); + + // Blocking call to fetch and complete initialization for all the assets + for (int i = 0; i < assetsToFetch.size(); ++i) + getAssetImpl(idToString(assetsToFetch[i]), assetPlaceholders[i]); + } + + // Run in main thread + Q_EMIT queueExecute([this,accountPackage,accountInContainer](){ + ilog("Processing result ${r}", ("r", accountPackage)); + auto itr = m_accounts.iterator_to(*accountInContainer); + + if (!accountPackage.valid()) { + (*itr)->deleteLater(); + m_accounts.erase(itr); + } else { + m_accounts.modify(itr, [this,&accountPackage](Account* a){ + a->setProperty("id", ObjectId(accountPackage->account.id.instance())); + a->setAccountObject(accountPackage->account); + + // Set balances + QList balances; + std::transform(accountPackage->balances.begin(), accountPackage->balances.end(), std::back_inserter(balances), + [this](const account_balance_object& b) { + Balance* bal = new Balance; + bal->setParent(this); + bal->setProperty("amount", QVariant::fromValue(b.balance.value)); + bal->setProperty("type", QVariant::fromValue(getAsset(ObjectId(b.asset_type.instance)))); + return bal; + }); + a->setBalances(balances); + }); + } + }); + } + catch (const fc::exception& e) + { + Q_EMIT exceptionThrown(QString::fromStdString(e.to_string())); + } +} + +Account* ChainDataModel::getAccount(ObjectId id) +{ + auto& by_id_idx = m_accounts.get(); + auto itr = by_id_idx.find(id); + if( itr == by_id_idx.end() ) + { + auto tmp = new Account(id, tr("Account #%1").arg(--m_account_query_num), this); + auto result = m_accounts.insert(tmp); + assert(result.second); + + // Run in RPC thread + m_rpc_thread->async([this, id, result]{getAccountImpl(idToString(account_id_type(id)), &*result.first);}); + return *result.first; + } + return *itr; +} + +Account* ChainDataModel::getAccount(QString name) +{ + auto& by_name_idx = m_accounts.get(); + auto itr = by_name_idx.find(name); + if( itr == by_name_idx.end() ) + { + auto tmp = new Account(--m_account_query_num, name, this); + auto result = m_accounts.insert(tmp); + assert(result.second); + + // Run in RPC thread + m_rpc_thread->async([this, name, result]{getAccountImpl(name, &*result.first);}); + return *result.first; + } + return *itr; +} diff --git a/programs/light_client/ChainDataModel.hpp b/programs/light_client/ChainDataModel.hpp new file mode 100644 index 00000000..d213bec4 --- /dev/null +++ b/programs/light_client/ChainDataModel.hpp @@ -0,0 +1,88 @@ +#pragma once +#pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#include +#include + +#include "BoostMultiIndex.hpp" +#include "Asset.hpp" +#include "Account.hpp" + +#include +#include + +using graphene::chain::by_id; + +namespace fc { +class thread; +} + +struct by_symbol_name; +typedef multi_index_container< + Asset*, + indexed_by< + hashed_unique< tag, const_mem_fun >, + ordered_unique< tag, const_mem_fun > + > +> asset_multi_index_type; + +struct by_account_name; +typedef multi_index_container< + Account*, + indexed_by< + hashed_unique< tag, const_mem_fun >, + ordered_unique< tag, const_mem_fun > + > +> account_multi_index_type; + +class Transaction; +class ChainDataModel : public QObject { + Q_OBJECT + Q_PROPERTY(QDateTime chainTime READ chainTime NOTIFY blockReceived) + + void processUpdatedObject(const fc::variant& update); + + void getAssetImpl(QString assetIdentifier, Asset* const * assetInContainer); + void getAccountImpl(QString accountIdentifier, Account* const * accountInContainer); + +public: + Q_INVOKABLE Account* getAccount(ObjectId id); + Q_INVOKABLE Account* getAccount(QString name); + Q_INVOKABLE Asset* getAsset(ObjectId id); + Q_INVOKABLE Asset* getAsset(QString symbol); + + QDateTime chainTime() const; + + ChainDataModel(){} + ChainDataModel(fc::thread& t, QObject* parent = nullptr); + + void setDatabaseAPI(fc::api dbapi); + void setNetworkAPI(fc::api napi); + + const graphene::chain::global_property_object& global_properties() const { return m_global_properties; } + const graphene::chain::dynamic_global_property_object& dynamic_global_properties() const { return m_dynamic_global_properties; } + const graphene::chain::chain_property_object& chain_properties() const { return m_chain_properties; } + +public Q_SLOTS: + void broadcast(Transaction* transaction); + +Q_SIGNALS: + void queueExecute(const std::function&); + void exceptionThrown(QString message); + void blockReceived(); + +private: + fc::thread* m_rpc_thread = nullptr; + std::string m_api_url; + fc::api m_db_api; + fc::api m_net_api; + + graphene::chain::global_property_object m_global_properties; + graphene::chain::dynamic_global_property_object m_dynamic_global_properties; + graphene::chain::chain_property_object m_chain_properties; + + ObjectId m_account_query_num = -1; + account_multi_index_type m_accounts; + asset_multi_index_type m_assets; +}; + diff --git a/programs/light_client/ClientDataModel.cpp b/programs/light_client/ClientDataModel.cpp deleted file mode 100644 index 3c48fee4..00000000 --- a/programs/light_client/ClientDataModel.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "ClientDataModel.hpp" - -#include -#include - -#include - -using namespace graphene::app; - -ChainDataModel::ChainDataModel( fc::thread& t, QObject* parent ) -:QObject(parent),m_thread(&t){} - -Account* ChainDataModel::getAccount(ObjectId id) -{ - auto& by_id_idx = m_accounts.get<::by_id>(); - auto itr = by_id_idx.find(id); - if( itr == by_id_idx.end() ) - { - auto tmp = new Account; - tmp->id = id; --m_account_query_num; - tmp->name = QString::number( --m_account_query_num); - auto result = m_accounts.insert( tmp ); - assert( result.second ); - - /** execute in app thread */ - m_thread->async( [this,id](){ - try { - ilog( "look up names.." ); - auto result = m_db_api->get_accounts( {account_id_type(id)} ); - /** execute in main */ - Q_EMIT queueExecute( [this,result,id](){ - wlog( "process result" ); - auto& by_id_idx = this->m_accounts.get<::by_id>(); - auto itr = by_id_idx.find(id); - assert( itr != by_id_idx.end() ); - - if( result.size() == 0 || !result.front() ) - { - elog( "delete later" ); - (*itr)->deleteLater(); - by_id_idx.erase( itr ); - } - else - { - by_id_idx.modify( itr, - [=]( Account* a ){ - a->setProperty("name", QString::fromStdString(result.front()->name) ); - } - ); - } - }); - } - catch ( const fc::exception& e ) - { - Q_EMIT exceptionThrown( QString::fromStdString(e.to_string()) ); - } - }); - return *result.first; - } - return *itr; -} - -Account* ChainDataModel::getAccount(QString name) -{ - auto& by_name_idx = m_accounts.get(); - auto itr = by_name_idx.find(name); - if( itr == by_name_idx.end() ) - { - auto tmp = new Account; - tmp->id = --m_account_query_num; - tmp->name = name; - auto result = m_accounts.insert( tmp ); - assert( result.second ); - - /** execute in app thread */ - m_thread->async( [this,name](){ - try { - ilog( "look up names.." ); - auto result = m_db_api->lookup_account_names( {name.toStdString()} ); - /** execute in main */ - Q_EMIT queueExecute( [this,result,name](){ - wlog( "process result" ); - auto& by_name_idx = this->m_accounts.get(); - auto itr = by_name_idx.find(name); - assert( itr != by_name_idx.end() ); - - if( result.size() == 0 || !result.front() ) - { - elog( "delete later" ); - (*itr)->deleteLater(); - by_name_idx.erase( itr ); - } - else - { - by_name_idx.modify( itr, - [=]( Account* a ){ - a->setProperty("id", ObjectId(result.front()->id.instance())); - } - ); - } - }); - } - catch ( const fc::exception& e ) - { - Q_EMIT exceptionThrown( QString::fromStdString(e.to_string()) ); - } - }); - return *result.first; - } - return *itr; -} - -QQmlListProperty Account::balances() -{ - return QQmlListProperty(this, m_balances); -} - -GrapheneApplication::GrapheneApplication( QObject* parent ) -:QObject( parent ),m_thread("app") -{ - connect( this, &GrapheneApplication::queueExecute, - this, &GrapheneApplication::execute ); - - m_model = new ChainDataModel( m_thread, this ); - - connect( m_model, &ChainDataModel::queueExecute, - this, &GrapheneApplication::execute ); - - connect( m_model, &ChainDataModel::exceptionThrown, - this, &GrapheneApplication::exceptionThrown ); -} - -GrapheneApplication::~GrapheneApplication() -{ -} - -void GrapheneApplication::setIsConnected( bool v ) -{ - if( v != m_isConnected ) - { - m_isConnected = v; - Q_EMIT isConnectedChanged( m_isConnected ); - } -} - -void GrapheneApplication::start( QString apiurl, QString user, QString pass ) -{ - if( !m_thread.is_current() ) - { - m_done = m_thread.async( [=](){ return start( apiurl, user, pass ); } ); - return; - } - try { - m_client = std::make_shared(); - ilog( "connecting...${s}", ("s",apiurl.toStdString()) ); - auto con = m_client->connect( apiurl.toStdString() ); - auto apic = std::make_shared(*con); - auto remote_api = apic->get_remote_api< login_api >(1); - auto db_api = apic->get_remote_api< database_api >(0); - if( !remote_api->login( user.toStdString(), pass.toStdString() ) ) - { - elog( "login failed" ); - Q_EMIT loginFailed(); - return; - } - - ilog( "connecting..." ); - queueExecute( [=](){ - m_model->setDatabaseAPI( db_api ); - }); - - queueExecute( [=](){setIsConnected( true );} ); - } catch ( const fc::exception& e ) - { - Q_EMIT exceptionThrown( QString::fromStdString(e.to_string()) ); - } -} -Q_SLOT void GrapheneApplication::execute( const std::function& func )const -{ - func(); -} diff --git a/programs/light_client/ClientDataModel.hpp b/programs/light_client/ClientDataModel.hpp deleted file mode 100644 index d7533ba4..00000000 --- a/programs/light_client/ClientDataModel.hpp +++ /dev/null @@ -1,161 +0,0 @@ -#pragma once -#pragma GCC diagnostic ignored "-Wunknown-pragmas" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -using boost::multi_index_container; -using namespace boost::multi_index; - -using ObjectId = qint64; -Q_DECLARE_METATYPE(ObjectId) - -Q_DECLARE_METATYPE(std::function) - -class Crypto { - Q_GADGET - -public: - Q_INVOKABLE QString sha256(QByteArray data) { - return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex(); - } -}; -QML_DECLARE_TYPE(Crypto) - -class Asset : public QObject { - Q_OBJECT - - Q_PROPERTY(QString symbol MEMBER symbol) - Q_PROPERTY(ObjectId id MEMBER id) - Q_PROPERTY(quint8 precision MEMBER precision) - - QString symbol; - ObjectId id; - quint8 precision; -}; - -class Balance : public QObject { - Q_OBJECT - - Q_PROPERTY(Asset* type MEMBER type) - Q_PROPERTY(qint64 amount MEMBER amount) - Q_PROPERTY(ObjectId id MEMBER id) - - Asset* type; - qint64 amount; - ObjectId id; -}; - -class Account : public QObject { - Q_OBJECT - - Q_PROPERTY(QString name MEMBER name NOTIFY nameChanged) - Q_PROPERTY(ObjectId id MEMBER id NOTIFY idChanged) - Q_PROPERTY(QQmlListProperty balances READ balances) - - QList m_balances; - -public: - const QString& getName()const { return name; } - ObjectId getId()const { return id; } - - QQmlListProperty balances(); - - QString name; - ObjectId id; - -signals: - void nameChanged(); - void idChanged(); -}; - -struct by_id; -struct by_account_name; -/** - * @ingroup object_index - */ -using account_multi_index_type = multi_index_container< - Account*, - indexed_by< - hashed_unique< tag, const_mem_fun >, - ordered_unique< tag, const_mem_fun > - > ->; - -class ChainDataModel : public QObject { - Q_OBJECT - -public: - Q_INVOKABLE Account* getAccount(ObjectId id); - Q_INVOKABLE Account* getAccount(QString name); - - ChainDataModel(){} - ChainDataModel( fc::thread& t, QObject* parent = nullptr ); - - void setDatabaseAPI( fc::api dbapi ){ m_db_api = dbapi; } - -Q_SIGNALS: - void queueExecute( const std::function& ); - void exceptionThrown( QString message ); - -private: - fc::thread* m_thread = nullptr; - std::string m_api_url; - fc::api m_db_api; - - ObjectId m_account_query_num = -1; - account_multi_index_type m_accounts; -}; - -class GrapheneApplication : public QObject { - Q_OBJECT - - Q_PROPERTY(ChainDataModel* model READ model CONSTANT) - Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged) - - - fc::thread m_thread; - ChainDataModel* m_model = nullptr; - bool m_isConnected = false; - - std::shared_ptr m_client; - fc::future m_done; - - void setIsConnected( bool v ); - - Q_SLOT void execute( const std::function& )const; -public: - GrapheneApplication( QObject* parent = nullptr ); - ~GrapheneApplication(); - - ChainDataModel* model() const - { - return m_model; - } - - Q_INVOKABLE void start(QString apiUrl, - QString user, - QString pass ); - - bool isConnected() const - { - return m_isConnected; - } - -Q_SIGNALS: - void exceptionThrown( QString message ); - void loginFailed(); - void isConnectedChanged(bool isConnected); - void queueExecute( const std::function& ); -}; diff --git a/programs/light_client/GrapheneApplication.cpp b/programs/light_client/GrapheneApplication.cpp new file mode 100644 index 00000000..9365f968 --- /dev/null +++ b/programs/light_client/GrapheneApplication.cpp @@ -0,0 +1,118 @@ +#include "GrapheneApplication.hpp" +#include "ChainDataModel.hpp" +#include "Wallet.hpp" +#include "Operations.hpp" +#include "Transaction.hpp" + +#include + +#include + +#include + +using graphene::app::login_api; +using graphene::app::database_api; + +GrapheneApplication::GrapheneApplication(QObject* parent) +:QObject(parent),m_thread("app") +{ + connect(this, &GrapheneApplication::queueExecute, + this, &GrapheneApplication::execute); + + m_model = new ChainDataModel(m_thread, this); + m_operationBuilder = new OperationBuilder(*m_model, this); + m_wallet = new Wallet(this); + + connect(m_model, &ChainDataModel::queueExecute, + this, &GrapheneApplication::execute); + + connect(m_model, &ChainDataModel::exceptionThrown, + this, &GrapheneApplication::exceptionThrown); +} + +GrapheneApplication::~GrapheneApplication() +{ +} + +void GrapheneApplication::setIsConnected(bool v) +{ + if (v != m_isConnected) + { + m_isConnected = v; + Q_EMIT isConnectedChanged(m_isConnected); + } +} + +void GrapheneApplication::start(QString apiurl, QString user, QString pass) +{ + if (!m_thread.is_current()) + { + m_done = m_thread.async([=](){ return start(apiurl, user, pass); }); + return; + } + try { + m_client = std::make_shared(); + ilog("connecting...${s}", ("s",apiurl.toStdString())); + auto con = m_client->connect(apiurl.toStdString()); + m_connectionClosed = con->closed.connect([this]{queueExecute([this]{setIsConnected(false);});}); + auto apic = std::make_shared(*con); + auto remote_api = apic->get_remote_api(1); + auto db_api = apic->get_remote_api(0); + if (!remote_api->login(user.toStdString(), pass.toStdString())) + { + elog("login failed"); + Q_EMIT loginFailed(); + return; + } + auto net_api = remote_api->network_broadcast(); + + ilog("connecting..."); + queueExecute([=](){ + m_model->setDatabaseAPI(db_api); + m_model->setNetworkAPI(net_api); + }); + + queueExecute([=](){ setIsConnected(true); }); + } catch (const fc::exception& e) + { + Q_EMIT exceptionThrown(QString::fromStdString(e.to_string())); + } +} + +QString GrapheneApplication::defaultDataPath() +{ + return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); +} + +Transaction* GrapheneApplication::createTransaction() const +{ + return new Transaction; +} + +void GrapheneApplication::signTransaction(Transaction* transaction) const +{ + if (transaction == nullptr) return; + + auto getActiveAuth = [this](graphene::chain::account_id_type id) { + return &model()->getAccount(id.instance.value)->accountObject().active; + }; + auto getOwnerAuth = [this](graphene::chain::account_id_type id) { + return &model()->getAccount(id.instance.value)->accountObject().owner; + }; + + auto& chainId = model()->chain_properties().chain_id; + auto& trx = transaction->internalTransaction(); + trx.set_reference_block(model()->dynamic_global_properties().head_block_id); + flat_set pubKeys = wallet()->getAvailablePrivateKeys(); + auto requiredKeys = trx.get_required_signatures(chainId, pubKeys, getActiveAuth, getOwnerAuth); + trx.signatures = wallet()->signDigest(trx.digest(), requiredKeys); + idump((trx)); +} + + +Q_SLOT void GrapheneApplication::execute(const std::function& func)const +{ + func(); +} + + diff --git a/programs/light_client/GrapheneApplication.hpp b/programs/light_client/GrapheneApplication.hpp new file mode 100644 index 00000000..f45106ad --- /dev/null +++ b/programs/light_client/GrapheneApplication.hpp @@ -0,0 +1,79 @@ +#pragma once +#pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#include + +#include + +#include + + +namespace fc { namespace http { +class websocket_client; +}} + +class ChainDataModel; +class OperationBuilder; +class OperationBase; +class Transaction; +class Wallet; +class GrapheneApplication : public QObject { + Q_OBJECT + + Q_PROPERTY(ChainDataModel* model READ model CONSTANT) + Q_PROPERTY(OperationBuilder* operationBuilder READ operationBuilder CONSTANT) + Q_PROPERTY(Wallet* wallet READ wallet CONSTANT) + Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged) + + + fc::thread m_thread; + ChainDataModel* m_model = nullptr; + Wallet* m_wallet = nullptr; + OperationBuilder* m_operationBuilder = nullptr; + bool m_isConnected = false; + + boost::signals2::scoped_connection m_connectionClosed; + + std::shared_ptr m_client; + fc::future m_done; + + void setIsConnected(bool v); + +protected Q_SLOTS: + void execute(const std::function&)const; + +public: + GrapheneApplication(QObject* parent = nullptr); + ~GrapheneApplication(); + + Wallet* wallet()const { return m_wallet; } + + ChainDataModel* model() const { + return m_model; + } + OperationBuilder* operationBuilder() const { + return m_operationBuilder; + } + + Q_INVOKABLE void start(QString apiUrl, + QString user, + QString pass); + + bool isConnected() const + { + return m_isConnected; + } + + Q_INVOKABLE static QString defaultDataPath(); + + /// Convenience method to get a Transaction in QML. Caller takes ownership of the new Transaction. + Q_INVOKABLE Transaction* createTransaction() const; + Q_INVOKABLE void signTransaction(Transaction* transaction) const; + +Q_SIGNALS: + void exceptionThrown(QString message); + void loginFailed(); + void isConnectedChanged(bool isConnected); + void queueExecute(const std::function&); +}; + diff --git a/programs/light_client/GrapheneObject.cpp b/programs/light_client/GrapheneObject.cpp new file mode 100644 index 00000000..9ec55ba2 --- /dev/null +++ b/programs/light_client/GrapheneObject.cpp @@ -0,0 +1,3 @@ +#include "GrapheneObject.hpp" + +// This space intentionally left blank diff --git a/programs/light_client/GrapheneObject.hpp b/programs/light_client/GrapheneObject.hpp new file mode 100644 index 00000000..0c53c562 --- /dev/null +++ b/programs/light_client/GrapheneObject.hpp @@ -0,0 +1,31 @@ +#pragma once +#pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#include + +#include + +using ObjectId = qint64; +Q_DECLARE_METATYPE(ObjectId) + +Q_DECLARE_METATYPE(std::function) + +class GrapheneObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(ObjectId id MEMBER m_id READ id NOTIFY idChanged) + + ObjectId m_id; + +public: + GrapheneObject(ObjectId id = -1, QObject* parent = nullptr) + : QObject(parent), m_id(id) + {} + + ObjectId id() const { + return m_id; + } + +Q_SIGNALS: + void idChanged(); +}; diff --git a/programs/light_client/Operations.cpp b/programs/light_client/Operations.cpp new file mode 100644 index 00000000..19eae283 --- /dev/null +++ b/programs/light_client/Operations.cpp @@ -0,0 +1,100 @@ +#include "Operations.hpp" +#include "Wallet.hpp" + +#include + +#include + +TransferOperation* OperationBuilder::transfer(ObjectId sender, ObjectId receiver, qint64 amount, + ObjectId amountType, QString memo, ObjectId feeType) +{ + try { + TransferOperation* op = new TransferOperation; + op->setSender(sender); + op->setReceiver(receiver); + op->setAmount(amount); + op->setAmountType(amountType); + op->setMemo(memo); + op->setFeeType(feeType); + auto feeParameters = model.global_properties().parameters.current_fees->get(); + op->setFee(op->operation().calculate_fee(feeParameters).value); + return op; + } catch (const fc::exception& e) { + qDebug() << e.to_detail_string().c_str(); + return nullptr; + } +} + +QString TransferOperation::memo() const { + if (!m_op.memo) + return QString::null; + if (memoIsEncrypted()) + return tr("Encrypted Memo"); + QString memo = QString::fromStdString(m_op.memo->get_message({}, {})); + while (memo.endsWith(QChar('\0'))) + memo.chop(1); + return memo; +} + +bool TransferOperation::memoIsEncrypted() const +{ + if (!m_op.memo) + return false; + if (m_op.memo->message.empty()) + return false; + if (m_op.memo->from == public_key_type() && m_op.memo->to == public_key_type()) + return false; + return true; +} + +bool TransferOperation::canEncryptMemo(Wallet* wallet, ChainDataModel* model) const +{ + if (!m_op.memo) return false; + auto pub = model->getAccount(sender())->memoKey(); + if (!wallet->hasPrivateKey(pub)) return false; + return graphene::utilities::wif_to_key(wallet->getPrivateKey(pub).toStdString()).valid(); +} + +bool TransferOperation::canDecryptMemo(Wallet* wallet, ChainDataModel* model) const +{ + if (!m_op.memo) return false; + auto pub = model->getAccount(receiver())->memoKey(); + if (!wallet->hasPrivateKey(pub)) return false; + return graphene::utilities::wif_to_key(wallet->getPrivateKey(pub).toStdString()).valid(); +} + +QString TransferOperation::decryptedMemo(Wallet* wallet, ChainDataModel* model) const +{ + fc::ecc::private_key privateKey; + fc::ecc::public_key publicKey; + + if (canEncryptMemo(wallet, model)) { + privateKey = *graphene::utilities::wif_to_key(wallet->getPrivateKey(model->getAccount(sender())->memoKey()).toStdString()); + publicKey = m_op.memo->to; + } else if (canDecryptMemo(wallet, model)) { + privateKey = *graphene::utilities::wif_to_key(wallet->getPrivateKey(model->getAccount(receiver())->memoKey()).toStdString()); + publicKey = m_op.memo->from; + } else return QString::null; + + return QString::fromStdString(m_op.memo->get_message(privateKey, publicKey)); +} + +void TransferOperation::setMemo(QString memo) { + if (memo == this->memo()) + return; + if (!m_op.memo) + m_op.memo = graphene::chain::memo_data(); + while (memo.size() % 32) + memo.append('\0'); + m_op.memo->set_message({}, {}, memo.toStdString()); + Q_EMIT memoChanged(); +} + +void TransferOperation::encryptMemo(Wallet* wallet, ChainDataModel* model) +{ + if (!canEncryptMemo(wallet, model)) return; + auto privateKey = graphene::utilities::wif_to_key(wallet->getPrivateKey(model->getAccount(sender())->memoKey()).toStdString()); + if (!privateKey) return; + m_op.memo->set_message(*privateKey, public_key_type(model->getAccount(receiver())->memoKey().toStdString()), memo().toStdString()); + Q_EMIT memoChanged(); +} diff --git a/programs/light_client/Operations.hpp b/programs/light_client/Operations.hpp new file mode 100644 index 00000000..e56d5852 --- /dev/null +++ b/programs/light_client/Operations.hpp @@ -0,0 +1,143 @@ +#pragma once + +#include "ChainDataModel.hpp" + +#include + +#include +#include + +class OperationBase : public QObject { + Q_OBJECT + Q_PROPERTY(OperationType operationType READ operationType CONSTANT STORED false) + +public: + enum OperationType { + TransferOperationType = graphene::chain::operation::tag::value + }; + Q_ENUM(OperationType); + + OperationBase(QObject* parent = nullptr) + : QObject(parent) {} + virtual ~OperationBase() {} + + virtual OperationType operationType() const = 0; + virtual graphene::chain::operation genericOperation() const = 0; +}; +QML_DECLARE_INTERFACE(OperationBase) + +class TransferOperation : public OperationBase { + Q_OBJECT + Q_PROPERTY(qint64 fee READ fee WRITE setFee NOTIFY feeChanged) + Q_PROPERTY(ObjectId feeType READ feeType WRITE setFeeType NOTIFY feeTypeChanged) + Q_PROPERTY(ObjectId sender READ sender WRITE setSender NOTIFY senderChanged) + Q_PROPERTY(ObjectId receiver READ receiver WRITE setReceiver NOTIFY receiverChanged) + Q_PROPERTY(qint64 amount READ amount WRITE setAmount NOTIFY amountChanged) + Q_PROPERTY(ObjectId amountType READ amountType WRITE setAmountType NOTIFY amountTypeChanged) + Q_PROPERTY(QString memo READ memo WRITE setMemo NOTIFY memoChanged) + Q_PROPERTY(bool memoIsEncrypted READ memoIsEncrypted NOTIFY memoChanged) + + graphene::chain::transfer_operation m_op; + +public: + TransferOperation(){} + TransferOperation(const graphene::chain::transfer_operation& op) + : m_op(op) {} + + virtual OperationBase::OperationType operationType() const override { + return OperationBase::TransferOperationType; + } + virtual graphene::chain::operation genericOperation() const override { + return m_op; + } + + qint64 fee() const { return m_op.fee.amount.value; } + ObjectId feeType() const { return m_op.fee.asset_id.instance.value; } + ObjectId sender() const { return m_op.from.instance.value; } + ObjectId receiver() const { return m_op.to.instance.value; } + qint64 amount() const { return m_op.amount.amount.value; } + ObjectId amountType() const { return m_op.amount.asset_id.instance.value; } + /// This does not deal with encrypted memos. The memo stored here is unencrypted. The encryption step must be + /// performed by calling encryptMemo() + QString memo() const; + + bool memoIsEncrypted()const; + Q_INVOKABLE bool canEncryptMemo(Wallet* wallet, ChainDataModel* model) const; + Q_INVOKABLE bool canDecryptMemo(Wallet* wallet, ChainDataModel* model) const; + Q_INVOKABLE QString decryptedMemo(Wallet* wallet, ChainDataModel* model) const; + + const graphene::chain::transfer_operation& operation() const { return m_op; } + graphene::chain::transfer_operation& operation() { return m_op; } + +public Q_SLOTS: + void setFee(qint64 arg) { + if (arg == fee()) + return; + m_op.fee.amount = arg; + Q_EMIT feeChanged(); + } + void setFeeType(ObjectId arg) { + if (arg == feeType()) + return; + m_op.fee.asset_id = arg; + Q_EMIT feeTypeChanged(); + } + void setSender(ObjectId arg) { + if (arg == sender()) + return; + m_op.from = arg; + Q_EMIT senderChanged(); + } + void setReceiver(ObjectId arg) { + if (arg == receiver()) + return; + m_op.to = arg; + Q_EMIT receiverChanged(); + } + void setAmount(qint64 arg) { + if (arg == amount()) + return; + m_op.amount.amount = arg; + Q_EMIT amountChanged(); + } + void setAmountType(ObjectId arg) { + if (arg == amountType()) + return; + m_op.amount.asset_id = arg; + Q_EMIT amountTypeChanged(); + } + /// This does not deal with encrypted memos. The memo stored here is unencrypted. The encryption step must be + /// performed by calling encryptMemo() + void setMemo(QString memo); + void encryptMemo(Wallet* wallet, ChainDataModel* model); + +Q_SIGNALS: + void feeChanged(); + void feeTypeChanged(); + void senderChanged(); + void receiverChanged(); + void amountChanged(); + void amountTypeChanged(); + void memoChanged(); +}; +QML_DECLARE_TYPE(TransferOperation) + +/** + * @brief The OperationBuilder class creates operations which are inspectable by the GUI + * + * @note All operations returned by OperationBuilder are heap allocated on-demand and do not have parents. The caller + * must take ownership of these objects to prevent them from leaking. + */ +class OperationBuilder : public QObject { + Q_OBJECT + + ChainDataModel& model; + +public: + OperationBuilder(ChainDataModel& model, QObject* parent = nullptr) + : QObject(parent), model(model){} + + Q_INVOKABLE TransferOperation* transfer(ObjectId sender, ObjectId receiver, qint64 amount, + ObjectId amountType, QString memo, ObjectId feeType); + +}; diff --git a/programs/light_client/Transaction.cpp b/programs/light_client/Transaction.cpp new file mode 100644 index 00000000..a9a6f5f1 --- /dev/null +++ b/programs/light_client/Transaction.cpp @@ -0,0 +1,59 @@ +#include "Transaction.hpp" +#include "Operations.hpp" + +#include + +struct OperationConverter { + using result_type = OperationBase*; + + OperationBase* operator()(const graphene::chain::transfer_operation& op) const { + auto ret = new TransferOperation(op); + QObject::connect(ret, &QObject::destroyed, []{qDebug("Cleaned up operation");}); + return ret; + } + + template + OperationBase* operator()(const Op&) const { + elog("NYI: OperationConverter for ${type}", ("type", fc::get_typename::name())); + abort(); + } +}; + +QString Transaction::statusString() const +{ + return QMetaEnum::fromType().valueToKey(status()); +} + +QQmlListProperty Transaction::operations() +{ + auto append = [](QQmlListProperty* list, OperationBase* op) { + static_cast(list->data)->appendOperation(op); + }; + auto count = [](QQmlListProperty* list) { + return static_cast(list->data)->operationCount(); + }; + auto at = [](QQmlListProperty* list, int index) { + return static_cast(list->data)->operationAt(index); + }; + auto clear = [](QQmlListProperty* list) { + static_cast(list->data)->clearOperations(); + }; + + return QQmlListProperty(this, this, append, count, at, clear); +} + +OperationBase* Transaction::operationAt(int index) const { + return m_transaction.operations[index].visit(OperationConverter()); +} + +void Transaction::appendOperation(OperationBase* op) +{ + if (op == nullptr) + { + qWarning("Unable to append null operation to transaction"); + return; + } + op->setParent(this); + m_transaction.operations.push_back(op->genericOperation()); + Q_EMIT operationsChanged(); +} diff --git a/programs/light_client/Transaction.hpp b/programs/light_client/Transaction.hpp new file mode 100644 index 00000000..5720534d --- /dev/null +++ b/programs/light_client/Transaction.hpp @@ -0,0 +1,82 @@ +#pragma once +#pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#include + +#include +#include +#include +#include + +class OperationBase; +class Transaction : public QObject { + Q_OBJECT + +public: + enum Status { Unbroadcasted, Pending, Complete, Failed }; + Q_ENUM(Status); + + Status status() const { return m_status; } + QString statusString() const; + QQmlListProperty operations(); + + OperationBase* operationAt(int index) const; + int operationCount() const { + return m_transaction.operations.size(); + } + + graphene::chain::signed_transaction& internalTransaction() { + return m_transaction; + } + + QDateTime expiration() const + { + return QDateTime::fromTime_t(m_transaction.expiration.sec_since_epoch()); + } + +public Q_SLOTS: + void setStatus(Status status) + { + if (status == m_status) + return; + + m_status = status; + qDebug() << status; + emit statusChanged(status); + } + + /** + * @brief Append the operation to the transaction + * @param op The operation to append. This Transaction will take ownership of the operation. + */ + void appendOperation(OperationBase* op); + void clearOperations() { + m_transaction.operations.clear(); + Q_EMIT operationsChanged(); + } + + void setExpiration(QDateTime expiration) + { + fc::time_point_sec exp(expiration.toTime_t()); + if (exp == m_transaction.expiration) + return; + + m_transaction.expiration = exp; + emit expirationChanged(expiration); + } + +signals: + void statusChanged(Status status); + void operationsChanged(); + + void expirationChanged(QDateTime expiration); + +private: + Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged) + Q_PROPERTY(QString statusString READ statusString NOTIFY statusChanged STORED false) + Q_PROPERTY(QQmlListProperty operations READ operations NOTIFY operationsChanged) + Q_PROPERTY(QDateTime expiration READ expiration WRITE setExpiration NOTIFY expirationChanged) + + Status m_status = Unbroadcasted; + graphene::chain::signed_transaction m_transaction; +}; diff --git a/programs/light_client/Wallet.cpp b/programs/light_client/Wallet.cpp new file mode 100644 index 00000000..d3429909 --- /dev/null +++ b/programs/light_client/Wallet.cpp @@ -0,0 +1,460 @@ +#include "Transaction.hpp" +#include "Wallet.hpp" + +#include +#include + +#include +#include + +QString toQString(public_key_type k) { return QString::fromStdString(fc::variant(k).as_string()); } + +Wallet::Wallet(QObject* parent) +:QObject(parent) +{ +} + +Wallet::~Wallet() +{ + close(); +} + +bool Wallet::open(QString file_path) +{ + fc::path p(file_path.toStdString()); + if( !fc::exists(p) ) + { + ilog("Unable to open wallet file '${f}'; it does not exist", ("f",p)); + return false; + } + + _data = fc::json::from_file(p).as(); + + for( const auto& key : _data.encrypted_private_keys ) + { + if( key.second.label != string() ) + _label_to_key[QString::fromStdString(key.second.label)] = toQString(key.first); + if( key.second.encrypted_private_key.size() ) + _available_private_keys.insert(key.first); + } + _wallet_file_path = p; + + Q_EMIT isOpenChanged(true); + return true; +} + +bool Wallet::isOpen()const +{ + return _wallet_file_path != fc::path(); +} + +bool Wallet::close() +{ + if( !isOpen() ) return false; + save(); + _wallet_file_path = fc::path(); + Q_EMIT isOpenChanged(false); + return false; +} + +bool Wallet::save() +{ + if( !isOpen() ) return false; + /// TODO: backup existing wallet file first. + fc::json::save_to_file(_data, _wallet_file_path); + return false; +} + +bool Wallet::saveAs(QString file_path) +{ + if( !isOpen() ) return false; + fc::path p(file_path.toStdString()); + if( fc::exists(p) ) return false; + fc::json::save_to_file(_data, _wallet_file_path); + return true; +} + +bool Wallet::create(QString file_path, QString password, QString brain_key) +{ + if( isOpen() ) return false; + if( password == QString() ) return false; + + fc::path p(file_path.toStdString()); + if( fc::exists(p) ) + { + ilog("Unable to create wallet file '${f}' because a file with that name already exists.", ("f",p)); + return false; + } + + if( brain_key == QString() ) + { + auto key = fc::ecc::private_key::generate().get_secret(); + brain_key.fromStdString( fc::variant(key).as_string() ); + } + auto brainkey = brain_key.toStdString(); + auto pw_str = password.toStdString(); + + auto password_hash = fc::sha512::hash(pw_str.c_str(), pw_str.size()); + _decrypted_master_key = fc::sha512::hash(fc::ecc::private_key::generate().get_secret()); + _data.master_key_digest = fc::sha512::hash(_decrypted_master_key); + _data.encrypted_master_key = fc::aes_encrypt(password_hash, fc::raw::pack(_decrypted_master_key)); + + _data.brain_key_digest = fc::sha512::hash(brainkey.c_str(), brainkey.size()); + _data.encrypted_brain_key = fc::aes_encrypt(_decrypted_master_key, fc::raw::pack(brainkey)); + + QFileInfo(file_path).absoluteDir().mkpath("."); + fc::json::save_to_file(_data, p); + _wallet_file_path = p; + ilog("Created wallet file '${f}'", ("f", p)); + + return true; +} + +bool Wallet::loadBrainKey(QString brain_key) +{ + if( !isOpen() ) return false; + + if( brain_key == QString() ) return false; + auto brainkey = brain_key.toStdString(); + + if( _data.brain_key_digest != fc::sha512::hash(brainkey.c_str(), brainkey.size()) ) + return false; + + _brain_key = brain_key; + return true; +} + +bool Wallet::purgeBrainKey() +{ + if( !isOpen() ) return false; + _data.encrypted_brain_key.resize(0); + _brain_key = QString(); + return save(); +} + +bool Wallet::hasBrainKey()const +{ + if( !isOpen() ) return false; + return _brain_key != QString() || _data.encrypted_brain_key.size(); +} + +QString Wallet::getBrainKey() +{ + if( !isOpen() ) return QString(); + if( isLocked() ) return QString(); + + if( _brain_key != QString() ) + return _brain_key; + + auto dec_brain_key = fc::aes_decrypt(_decrypted_master_key, _data.encrypted_brain_key); + auto dec_brain_key_str = fc::raw::unpack(dec_brain_key); + _brain_key.fromStdString(dec_brain_key_str); + return _brain_key; +} + +bool Wallet::isLocked()const +{ + if( !isOpen() ) return true; + return _decrypted_master_key == fc::sha512(); +} +bool Wallet::unlock(QString password) +{ + try { + if( !isLocked() ) return true; + auto pw_str = password.toStdString(); + auto password_hash = fc::sha512::hash(pw_str.c_str(), pw_str.size()); + auto plain_txt = fc::aes_decrypt(password_hash, _data.encrypted_master_key); + _decrypted_master_key = fc::raw::unpack(plain_txt); + if( _data.master_key_digest != fc::sha512::hash(_decrypted_master_key) ) + _decrypted_master_key = fc::sha512(); + + Q_EMIT isLockedChanged(isLocked()); + return !isLocked(); + } catch (const fc::exception& e) { + elog(e.to_detail_string()); + return false; + } +} + +bool Wallet::lock() +{ + if( !isOpen() ) return false; + _brain_key = QString(); + _decrypted_master_key = fc::sha512(); + + Q_EMIT isLockedChanged(isLocked()); + return true; +} +bool Wallet::changePassword(QString new_password) +{ + if( !isOpen() ) return false; + if( isLocked() ) return false; + + auto pw_str = new_password.toStdString(); + auto password_hash = fc::sha512::hash(pw_str.c_str(), pw_str.size()); + _data.encrypted_master_key = fc::aes_encrypt(password_hash, fc::raw::pack(_decrypted_master_key)); + + save(); + + return true; +} +bool Wallet::hasPrivateKey(QString pubkey, bool include_with_brain_key) +{ + auto pub = fc::variant(pubkey.toStdString()).as(); + auto itr = _data.encrypted_private_keys.find(pub); + if( itr == _data.encrypted_private_keys.end() ) + return false; + if( itr->second.encrypted_private_key.size() ) + return true; + if( include_with_brain_key && itr->second.brain_sequence >= 0 ) + { + if( !itr->second.owner ) + return true; + return hasPrivateKey(toQString(*itr->second.owner), include_with_brain_key); + } + return false; +} + +QString Wallet::getPrivateKey(QString pubkey) +{ + if( !isOpen() ) return QString(); + if( isLocked() ) return QString(); + + auto pub = fc::variant(pubkey.toStdString()).as(); + auto itr = _data.encrypted_private_keys.find(pub); + if( itr == _data.encrypted_private_keys.end() ) + return QString(); + if( itr->second.encrypted_private_key.size() == 0 ) + return QString(); + auto plain = fc::aes_decrypt(_decrypted_master_key, itr->second.encrypted_private_key); + return QString::fromStdString(fc::raw::unpack(plain)); +} + +QString Wallet::getPublicKey(QString wif_private_key)const +{ + auto priv = graphene::utilities::wif_to_key(wif_private_key.toStdString()); + if( !priv ) return QString(); + + auto pub = public_key_type(priv->get_public_key()); + + return QString::fromStdString(fc::variant(pub).as_string()); +} + +QString Wallet::getActivePrivateKey(QString owner_pub_key, uint32_t seq) +{ + if( !isOpen() ) return QString(); + if( isLocked() ) return QString(); + + auto owner_wif_private_key = getPrivateKey(owner_pub_key); + if( owner_wif_private_key == QString() ) return QString(); + + auto seed = (owner_wif_private_key + " " + QString::number(seq)).toStdString(); + auto secret = fc::sha256::hash(fc::sha512::hash(seed.c_str(), seed.size())); + + auto wif = graphene::utilities::key_to_wif(secret); + auto priv_key = graphene::utilities::wif_to_key(wif); + if( !priv_key ) return QString(); + + public_key_type active_pub_key(priv_key->get_public_key()); + _data.encrypted_private_keys[active_pub_key].encrypted_private_key = fc::aes_encrypt(_decrypted_master_key, fc::raw::pack(wif)); + _data.encrypted_private_keys[active_pub_key].owner = fc::variant(owner_pub_key.toStdString()).as(); + _data.encrypted_private_keys[active_pub_key].brain_sequence = seq; + _available_private_keys.insert( active_pub_key ); + + return QString::fromStdString(wif); +} + +QString Wallet::getOwnerPrivateKey(uint32_t seq) +{ + if( !isOpen() ) return QString(); + if( isLocked() ) return QString(); + if( !hasBrainKey() ) return QString(); + + auto seed = (getBrainKey() + " " + QString::number(seq)).toStdString(); + + auto secret = fc::sha256::hash(fc::sha512::hash(seed.c_str(), seed.size())); + + auto wif = graphene::utilities::key_to_wif(secret); + auto priv_key = graphene::utilities::wif_to_key(wif); + if( !priv_key ) return QString(); + + public_key_type owner_pub_key(priv_key->get_public_key()); + _data.encrypted_private_keys[owner_pub_key].encrypted_private_key = fc::aes_encrypt(_decrypted_master_key, fc::raw::pack(wif)); + _data.encrypted_private_keys[owner_pub_key].brain_sequence = seq; + _available_private_keys.insert(owner_pub_key); + + return QString::fromStdString(wif); +} + +QString Wallet::getActivePublicKey(QString active_pub, uint32_t seq) +{ + return getPublicKey(getActivePrivateKey(active_pub, seq)); +} + +QString Wallet::getOwnerPublicKey(uint32_t seq) +{ + return getPublicKey(getOwnerPrivateKey(seq)); +} + + +QString Wallet::getKeyLabel(QString pubkey) +{ + if( !isOpen() ) return QString(); + public_key_type key = fc::variant( pubkey.toStdString() ).as(); + auto itr = _data.encrypted_private_keys.find(key); + if( itr == _data.encrypted_private_keys.end() ) + return QString(); + return QString::fromStdString(itr->second.label); +} +/** + * The same label may not be assigned to more than one key, this method will + * fail if a key with the same label already exists. + * + * @return true if the label was set + */ +bool Wallet::setKeyLabel(QString pubkey, QString label) +{ + if( label == QString() ) // clear the label + { + auto pub = fc::variant(pubkey.toStdString()).as(); + auto old_label = _data.encrypted_private_keys[pub].label; + _data.encrypted_private_keys[pub].label = string(); + if( old_label.size() ) + _label_to_key.erase(QString::fromStdString(old_label)); + + return true; + } + + auto itr = _label_to_key.find(label); + if( itr != _label_to_key.end() ) + return false; + + _label_to_key[label] = pubkey; + + auto pub = fc::variant(pubkey.toStdString()).as(); + _data.encrypted_private_keys[pub].label = label.toStdString(); + + return true; +} + + +QList> Wallet::getAllPublicKeys(bool only_if_private)const +{ + QList< QPair> result; + if( !isOpen() ) return result; + + for( const auto& item : _data.encrypted_private_keys ) + { + if( only_if_private && !item.second.encrypted_private_key.size() ) continue; + result.push_back(qMakePair(toQString(item.first), QString::fromStdString(item.second.label))); + } + + return result; +} + +QString Wallet::getPublicKey(QString label) +{ + if( !isOpen() ) return QString::null; + + auto itr = _label_to_key.find(label); + if( itr != _label_to_key.end() ) + return QString::null; + + return itr->second; +} + +/** imports a public key and assigns it a label */ +bool Wallet::importPublicKey(QString pubkey, QString label) +{ + return setKeyLabel(pubkey, label); +} + +/** + * @param wifkey a private key in (WIF) Wallet Import Format + * @pre !isLocked() + **/ +bool Wallet::importPrivateKey(QString wifkey, QString label) +{ + if( !isOpen() ) return false; + if( isLocked() ) return false; + + auto priv = graphene::utilities::wif_to_key(wifkey.toStdString()); + if (!priv) return false; + + auto p = priv->get_public_key(); + auto pub = toQString(p); + importPublicKey(pub, label); + + _data.encrypted_private_keys[p].encrypted_private_key = fc::aes_encrypt(_decrypted_master_key, fc::raw::pack(wifkey.toStdString())); + _available_private_keys.insert(p); + + return true; +} + +/** removes the key, its lablel and its private key */ +bool Wallet::removePublicKey(QString pubkey) +{ + if( !isOpen() ) return false; + auto pub = fc::variant( pubkey.toStdString() ).as(); + _available_private_keys.erase(pub); + + auto itr = _data.encrypted_private_keys.find(pub); + if( itr != _data.encrypted_private_keys.end() ) + { + _label_to_key.erase(QString::fromStdString(itr->second.label)); + _data.encrypted_private_keys.erase(itr); + return true; + } + return false; +} + +/** removes only the private key, keeping the public key and label + * + * @pre isOpen() && !isLocked() + **/ +bool Wallet::removePrivateKey(QString pubkey) +{ + if( !isOpen() ) return false; + if( isLocked() ) return false; + + auto pub = fc::variant(pubkey.toStdString()).as(); + _data.encrypted_private_keys[pub].encrypted_private_key.resize(0); + _available_private_keys.erase(pub); + + return true; +} + +/** + * @pre !isLocked() + */ +vector Wallet::signDigest(const digest_type& d, const set& keys)const +{ + vector result; + if( !isOpen() ) return result; + if( isLocked() ) return result; + + result.reserve( keys.size() ); + + for( const auto& key : keys ) + { + auto itr = _data.encrypted_private_keys.find(key); + if( itr == _data.encrypted_private_keys.end() ) + return vector(); + if( itr->second.encrypted_private_key.size() == 0 ) + return vector(); + + auto plain_wif = fc::aes_decrypt(_decrypted_master_key, itr->second.encrypted_private_key); + auto wif = fc::raw::unpack(plain_wif); + auto priv = graphene::utilities::wif_to_key(wif); + if( !priv ) return vector(); + + result.push_back(priv->sign_compact(d)); + } + + return result; +} + +const flat_set& Wallet::getAvailablePrivateKeys()const +{ + return _available_private_keys; +} diff --git a/programs/light_client/Wallet.hpp b/programs/light_client/Wallet.hpp new file mode 100644 index 00000000..a71b1b19 --- /dev/null +++ b/programs/light_client/Wallet.hpp @@ -0,0 +1,157 @@ +#pragma once +#pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#include + +#include +#include +#include +#include + +using std::string; +using std::vector; +using std::set; +using fc::flat_set; +using std::map; +using graphene::chain::public_key_type; +using graphene::chain::digest_type; +using graphene::chain::signature_type; +using fc::optional; + +class Transaction; + +QString toQString(public_key_type k); + +struct key_data +{ + string label; /** unique label assigned to this key */ + /** encrypted as a packed std::string containing a wif private key */ + vector encrypted_private_key; + int32_t brain_sequence = -1; + optional owner; /// if this key was derived from an owner key + sequence +}; + +struct wallet_file +{ + vector encrypted_brain_key; + fc::sha512 brain_key_digest; + vector encrypted_master_key; + fc::sha512 master_key_digest; + map encrypted_private_keys; +}; + + +/** + * @class Wallet + * @brief Securely maintains a set of labeled public and private keys + * + * @note this API is designed for use with QML which does not support exceptions so + * all errors are passed via return values. + */ +class Wallet : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool isOpen READ isOpen NOTIFY isOpenChanged) + Q_PROPERTY(bool isLocked READ isLocked NOTIFY isLockedChanged) + public: + Wallet( QObject* parent = nullptr ); + ~Wallet(); + + Q_INVOKABLE bool open(QString file_path); + Q_INVOKABLE bool close(); + bool isOpen()const; + Q_INVOKABLE bool save(); + Q_INVOKABLE bool saveAs(QString file_path); + Q_INVOKABLE bool create(QString file_path, QString password, QString brain_key = QString()); + + /** required to generate new owner keys */ + Q_INVOKABLE bool loadBrainKey(QString brain_key); + + /** removes brain key to secure owner keys */ + Q_INVOKABLE bool purgeBrainKey(); + Q_INVOKABLE bool hasBrainKey()const; + + /** @pre hasBrainKey() */ + Q_INVOKABLE QString getBrainKey(); + + bool isLocked()const; + Q_INVOKABLE bool unlock(QString password); + Q_INVOKABLE bool lock(); + Q_INVOKABLE bool changePassword(QString new_password); + + /** + * @pre !isLocked(); + * @post save() + * @return WIF private key + */ + Q_INVOKABLE QString getActivePrivateKey(QString owner_public_key, uint32_t sequence); + Q_INVOKABLE QString getActivePublicKey(QString owner_public_key, uint32_t sequence); + + /** + * @pre !isLocked(); + * @pre hasBrainKey(); + * @post save() + * @return WIF private key + */ + Q_INVOKABLE QString getOwnerPrivateKey(uint32_t sequence); + Q_INVOKABLE QString getOwnerPublicKey(uint32_t sequence); + Q_INVOKABLE QString getPublicKey(QString wif_private_key)const; + + Q_INVOKABLE QString getKeyLabel(QString pubkey); + Q_INVOKABLE bool setKeyLabel(QString pubkey, QString label); + Q_INVOKABLE QString getPublicKey(QString label); + Q_INVOKABLE QString getPrivateKey(QString pubkey); + Q_INVOKABLE bool hasPrivateKey(QString pubkey, bool include_with_brain_key = false); + + /** imports a public key and assigns it a label */ + Q_INVOKABLE bool importPublicKey(QString pubkey, QString label = QString()); + + /** + * @param wifkey a private key in (WIF) Wallet Import Format + * @pre !isLocked() + **/ + Q_INVOKABLE bool importPrivateKey(QString wifkey, QString label = QString()); + + /** removes the key, its lablel and its private key */ + Q_INVOKABLE bool removePublicKey(QString pubkey); + + /** removes only the private key, keeping the public key and label */ + Q_INVOKABLE bool removePrivateKey(QString pubkey); + + /** + * @param only_if_private filter any public keys for which the wallet lacks a private key + * @return a list of PUBLICKEY, LABEL for all known public keys + */ + Q_INVOKABLE QList> getAllPublicKeys(bool only_if_private)const; + + /** + * @pre !isLocked() + */ + vector signDigest(const digest_type& d, + const set& keys)const; + + const flat_set& getAvailablePrivateKeys()const; + + Q_SIGNALS: + void isLockedChanged(bool state); + void isOpenChanged(bool state); + + private: + fc::path _wallet_file_path; + wallet_file _data; + /** used to decrypt all of the encrypted private keys */ + fc::sha512 _decrypted_master_key; + flat_set _available_private_keys; + map _label_to_key; + QString _brain_key; +}; +QML_DECLARE_TYPE(Wallet) + +FC_REFLECT( key_data, (label)(encrypted_private_key)(brain_sequence)(owner) ) +FC_REFLECT( wallet_file, + (encrypted_brain_key) + (brain_key_digest) + (encrypted_master_key) + (master_key_digest) + (encrypted_private_keys) + ) diff --git a/programs/light_client/main.cpp b/programs/light_client/main.cpp index a2c12ac4..24af3467 100644 --- a/programs/light_client/main.cpp +++ b/programs/light_client/main.cpp @@ -2,11 +2,29 @@ #include #include -#include "ClientDataModel.hpp" +#include "GrapheneApplication.hpp" +#include "ChainDataModel.hpp" +#include "Transaction.hpp" +#include "Operations.hpp" +#include "Balance.hpp" +#include "Wallet.hpp" + +class Crypto { + Q_GADGET + +public: + Q_INVOKABLE QString sha256(QByteArray data) { + return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex(); + } +}; +QML_DECLARE_TYPE(Crypto) int main(int argc, char *argv[]) { - fc::thread::current().set_name( "main" ); +#ifndef NDEBUG + QQmlDebuggingEnabler enabler; +#endif + fc::thread::current().set_name("main"); QApplication app(argc, argv); app.setApplicationName("Graphene Client"); app.setOrganizationDomain("cryptonomex.org"); @@ -14,12 +32,23 @@ int main(int argc, char *argv[]) qRegisterMetaType>(); qRegisterMetaType(); + qRegisterMetaType>(); + qRegisterMetaType(); qmlRegisterType("Graphene.Client", 0, 1, "Asset"); qmlRegisterType("Graphene.Client", 0, 1, "Balance"); qmlRegisterType("Graphene.Client", 0, 1, "Account"); qmlRegisterType("Graphene.Client", 0, 1, "DataModel"); + qmlRegisterType("Graphene.Client", 0, 1, "Wallet"); qmlRegisterType("Graphene.Client", 0, 1, "GrapheneApplication"); + qmlRegisterType("Graphene.Client", 0, 1, "Transaction"); + + qmlRegisterUncreatableType("Graphene.Client", 0, 1, "OperationBase", + "OperationBase is an abstract base class; cannot be created"); + qmlRegisterType("Graphene.Client", 0, 1, "TransferOperation"); + + qmlRegisterUncreatableType("Graphene.Client", 0, 1, "OperationBuilder", + QStringLiteral("OperationBuilder cannot be created from QML")); QQmlApplicationEngine engine; QVariant crypto; @@ -29,7 +58,15 @@ int main(int argc, char *argv[]) engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); #else engine.load(QUrl(QStringLiteral("qml/main.qml"))); + QFileSystemWatcher watcher; + qDebug() << watcher.addPath("qml/"); + QObject::connect(&watcher, &QFileSystemWatcher::directoryChanged, &engine, [&](QString path) { + qDebug() << "Changed file" << path; + engine.clearComponentCache(); + }); #endif return app.exec(); } + +#include "main.moc" diff --git a/programs/light_client/qml/AccountPicker.qml b/programs/light_client/qml/AccountPicker.qml index b148f64f..91ed1dd0 100644 --- a/programs/light_client/qml/AccountPicker.qml +++ b/programs/light_client/qml/AccountPicker.qml @@ -7,47 +7,97 @@ import Graphene.Client 0.1 import "." +/// A component for choosing an Account from the chain RowLayout { - property Account account - + property GrapheneApplication app + /// The text to show in the name field when it is empty property alias placeholderText: accountNameField.placeholderText + /// Index into the balances Array of the balance to show beneath the name field + property int showBalance: -1 + /// The Account object the user has selected + property Account account + /// A real in the range [0,1] representing the amount of control the wallet has over this account + property real accountControlLevel: account && account.isLoaded? account.getActiveControl(app.wallet) : 0 + /// An Array of Balance objects held by account + property var balances: account? Object.keys(account.balances).map(function(key){return account.balances[key]}) + .filter(function(balance){return balance.amount > 0}) + : null + + /// Set the name field to have active focus function setFocus() { accountNameField.forceActiveFocus() } + signal balanceClicked(var balance) + Identicon { - name: accountNameField.text + name: account && account.name == accountNameField.text? accountNameField.text : "" width: Scaling.cm(2) height: Scaling.cm(2) + showOwnership: accountControlLevel > 0 + fullOwnership: accountControlLevel >= 1 } Column { Layout.fillWidth: true TextField { id: accountNameField - width: parent.width + onEditingFinished: accountDetails.update(text) + onTextChanged: if (account && account.name !== text) accountDetails.update("") } - Label { + Text { id: accountDetails + width: parent.width + height: text? implicitHeight : 0 + onLinkActivated: if (link === "balance") balanceClicked(balances[showBalance].amountReal()) + + Behavior on height { NumberAnimation{ easing.type: Easing.InOutQuad } } + function update(name) { if (!name) { text = "" + account = null return } account = app.model.getAccount(name) - if (account == null) + if (account == null) { text = qsTr("Error fetching account.") - else + } else { text = Qt.binding(function() { if (account == null) return qsTr("Account does not exist.") - return qsTr("Account ID: %1").arg(account.id < 0? qsTr("Loading...") - : account.id) + var text = qsTr("Account ID: %1").arg(!account.isLoaded? qsTr("Loading...") + : account.id) + if (showBalance >= 0) { + var bal = balances[showBalance] + text += "
" + qsTr("Balance:
%1 %2").arg(String(bal.amountReal())) + .arg(bal.type.symbol) + } + return text }) + } + } + + Behavior on text { + SequentialAnimation { + PropertyAnimation { + target: accountDetails + property: "opacity" + from: 1; to: 0 + duration: 100 + } + PropertyAction { target: accountDetails; property: "text" } + PropertyAnimation { + target: accountDetails + property: "opacity" + from: 0; to: 1 + duration: 100 + } + } } } } diff --git a/programs/light_client/qml/FormBase.qml b/programs/light_client/qml/FormBase.qml new file mode 100644 index 00000000..2a4936d2 --- /dev/null +++ b/programs/light_client/qml/FormBase.qml @@ -0,0 +1,37 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.2 + +import Graphene.Client 0.1 + +import "." + +/** + * Base for all forms + * + * This base contains all of the properties, slots, and signals which all forms are expected to expose. It also + * automatically lays its children out in a ColumnLayout + */ +Rectangle { + anchors.fill: parent + + /// Reference to the GrapheneApplication object + property GrapheneApplication app + /// Parent should trigger this signal to notify the form that it is about to be displayed + /// See specific form for the argument semantics + signal display(var arg) + /// Emitted when the form is canceled -- see specific form for the argument semantics + signal canceled(var arg) + /// Emitted when the form is completed -- see specific form for the argument semantics + signal completed(var arg) + + default property alias childItems: childLayout.data + + ColumnLayout { + id: childLayout + anchors.centerIn: parent + width: parent.width - Scaling.cm(2) + spacing: Scaling.mm(5) + } +} diff --git a/programs/light_client/qml/FormBox.qml b/programs/light_client/qml/FormBox.qml index 799069cf..137173aa 100644 --- a/programs/light_client/qml/FormBox.qml +++ b/programs/light_client/qml/FormBox.qml @@ -29,31 +29,45 @@ Rectangle { var form = formType.createObject(formContainer, params) formContainer.data = [form] - form.finished.connect(function(){state = "HIDDEN"}) + form.canceled.connect(function(){state = "HIDDEN"; internal.callbackArgs = []}) + form.completed.connect(function(){state = "HIDDEN"; internal.callbackArgs = arguments}) if (closedCallback instanceof Function) internal.callback = closedCallback + // Notify the form that it's about to go live + form.display({}) state = "SHOWN" } - MouseArea { - id: mouseTrap + FocusScope { + id: scope anchors.fill: parent - onClicked: { - mouse.accepted = true - greySheet.state = "HIDDEN" + + // Do not let focus leave this scope while form is open + onFocusChanged: if (enabled && !focus) forceActiveFocus() + + Keys.onEscapePressed: greySheet.state = "HIDDEN" + + MouseArea { + id: mouseTrap + anchors.fill: parent + onClicked: { + mouse.accepted = true + greySheet.state = "HIDDEN" + } + acceptedButtons: Qt.AllButtons + } + MouseArea { + // This mouse area blocks clicks inside the form from reaching the mouseTrap + anchors.fill: formContainer + acceptedButtons: Qt.AllButtons + onClicked: mouse.accepted = true + } + Item { + id: formContainer + anchors.centerIn: parent + width: parent.width / 2 + height: parent.height / 2 } - acceptedButtons: Qt.AllButtons - } - MouseArea { - anchors.fill: formContainer - acceptedButtons: Qt.AllButtons - onClicked: mouse.accepted = true - } - Item { - id: formContainer - anchors.centerIn: parent - width: parent.width / 2 - height: parent.height / 2 } states: [ @@ -73,12 +87,12 @@ Rectangle { StateChangeScript { name: "postHidden" script: { - console.log("Post") greySheet.closed() formContainer.data = [] if (internal.callback instanceof Function) - internal.callback() + internal.callback.apply(this, internal.callbackArgs) internal.callback = undefined + internal.callbackArgs = [] } } }, @@ -135,5 +149,6 @@ Rectangle { QtObject { id: internal property var callback + property var callbackArgs } } diff --git a/programs/light_client/qml/FormFlipper.qml b/programs/light_client/qml/FormFlipper.qml new file mode 100644 index 00000000..923ee6c5 --- /dev/null +++ b/programs/light_client/qml/FormFlipper.qml @@ -0,0 +1,52 @@ +import QtQuick 2.5 + +import Graphene.Client 0.1 + +Flipable { + id: flipable + anchors.fill: parent + + property Component frontComponent + property Component backComponent + + signal display(var arg) + signal canceled(var arg) + signal completed(var arg) + + property bool flipped: false + + Component.onCompleted: { + back = backComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return rotation.angle > 90})}) + front = frontComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return rotation.angle < 90})}) + front.canceled.connect(function() { canceled.apply(this, arguments) }) + front.completed.connect(function() { + back.display.apply(this, arguments) + flipped = true + }) + back.canceled.connect(function() { + front.display.apply(this, arguments) + flipped = false + }) + back.completed.connect(function() { completed.apply(this, arguments) }) + } + + transform: Rotation { + id: rotation + origin.x: flipable.width/2 + origin.y: flipable.height/2 + // set axis.y to 1 to rotate around y-axis + axis.x: 0; axis.y: 1; axis.z: 0 + // the default angle + angle: 0 + } + + states: State { + name: "back" + PropertyChanges { target: rotation; angle: 180 } + when: flipable.flipped + } + + transitions: Transition { + NumberAnimation { target: rotation; property: "angle"; duration: 500 } + } +} diff --git a/programs/light_client/qml/Identicon.qml b/programs/light_client/qml/Identicon.qml index fb674e55..d339c4f4 100644 --- a/programs/light_client/qml/Identicon.qml +++ b/programs/light_client/qml/Identicon.qml @@ -7,6 +7,9 @@ Canvas { contextType: "2d" property var name + property bool showOwnership: false + property bool fullOwnership: false + onNameChanged: requestPaint() onPaint: { @@ -14,6 +17,8 @@ Canvas { Jdenticon.draw(identicon, name) else { var context = identicon.context + if (!context) return + context.reset() var draw_circle = function(context, x, y, radius) { context.beginPath() @@ -36,4 +41,28 @@ Canvas { draw_circle(context, 2*radius, centerY, radius) } } + + Rectangle { + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + } + height: parent.height / 4 + color: fullOwnership? "green" : "blue" + opacity: .6 + visible: showOwnership + + Text { + anchors.centerIn: parent + color: "white" + font.pixelSize: parent.height * 2/3 + font.bold: true + text: fullOwnership? qsTr("FULL") : qsTr("PARTIAL") + } + TooltipArea { + text: fullOwnership? qsTr("You have full control of this account, and can use it to perform actions directly.") + : qsTr("You have partial control of this account, and can vote for it to take an action.") + } + } } diff --git a/programs/light_client/qml/TooltipArea.qml b/programs/light_client/qml/TooltipArea.qml new file mode 100644 index 00000000..5dda449e --- /dev/null +++ b/programs/light_client/qml/TooltipArea.qml @@ -0,0 +1,23 @@ +import QtQuick 2.4 +import QtQuick.Controls.Private 1.0 + +// TooltipArea.qml +// This file contains private Qt Quick modules that might change in future versions of Qt +// Tested on: Qt 5.4.1 + +MouseArea { + id: _root + property string text: "" + + anchors.fill: parent + hoverEnabled: _root.enabled + + onExited: Tooltip.hideText() + onCanceled: Tooltip.hideText() + + Timer { + interval: 1000 + running: _root.enabled && _root.containsMouse && _root.text.length + onTriggered: Tooltip.showText(_root, Qt.point(_root.mouseX, _root.mouseY), _root.text) + } +} diff --git a/programs/light_client/qml/TransactionConfirmationForm.qml b/programs/light_client/qml/TransactionConfirmationForm.qml new file mode 100644 index 00000000..c9e4694f --- /dev/null +++ b/programs/light_client/qml/TransactionConfirmationForm.qml @@ -0,0 +1,105 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.2 +import QtGraphicalEffects 1.0 + +import Graphene.Client 0.1 + +import "." + +/** + * This is the form for previewing and approving a transaction prior to broadcasting it + * + * The arguments property should be populated with an Array of operations. These operations will be used to create a + * Transaction, display it, and get confirmation to sign and broadcast it. This form will populate the transaction with + * the operations and expiration details, sign it, and pass the signed transaction through the completed signal. + */ +FormBase { + id: base + + readonly property alias trx: __trx + + Component.onCompleted: console.log("Made a transaction confirmation form") + Component.onDestruction: console.log("Destroyed a transaction confirmation form") + + onDisplay: { + trx.clearOperations() + for (var op in arg) + trx.appendOperation(arg[op]) + } + + Transaction { + id: __trx + } + + Rectangle { + id: background + Layout.preferredHeight: childrenRect.height + Scaling.mm(4) + Layout.preferredWidth: childrenRect.width + Scaling.mm(4) + layer.enabled: true + layer.effect: DropShadow { + radius: 8.0 + samples: 16 + horizontalOffset: Scaling.mm(.5) + verticalOffset: Scaling.mm(.5) + source: background + color: "#80000000" + transparentBorder: true + } + + // Debugging shim; disable before release + Loader { + id: delegateLoader + x: Scaling.mm(2) + y: Scaling.mm(2) + Layout.preferredWidth: Scaling.cm(10) + Component.onCompleted: setSource("TransactionDelegate.qml", {"trx": __trx, "app": base.app}) + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Reloading transaction") + delegateLoader.source = "" + delegateLoader.setSource("TransactionDelegate.qml", {"trx": __trx, "app": base.app}) + } + } + } + } + RowLayout { + Label { + text: qsTr("Transaction expires in") + } + ComboBox { + id: expirationSelector + model: [qsTr("five seconds"), qsTr("thirty seconds"), qsTr("a minute"), qsTr("an hour"), qsTr("a month"), qsTr("a year")] + + function getExpiration() { + switch(expirationSelector.currentIndex) { + case 0: return new Date(app.model.chainTime.getTime() + 1000*5) + case 1: return new Date(app.model.chainTime.getTime() + 1000*30) + case 2: return new Date(app.model.chainTime.getTime() + 1000*60) + case 3: return new Date(app.model.chainTime.getTime() + 1000*60*60) + case 4: return new Date(app.model.chainTime.getTime() + 1000*60*60*24*30) + case 5: return new Date(app.model.chainTime.getTime() + 1000*60*60*24*365) + } + } + } + } + UnlockingFinishButtons { + app: base.app + Layout.fillWidth: true + rightButtonText: qsTr("Commit") + onLeftButtonClicked: canceled({}) + onRightButtonClicked: { + if (app.wallet.isLocked) + app.wallet.unlock(passwordField.text) + else { + trx.setExpiration(expirationSelector.getExpiration()) + app.signTransaction(trx) + app.model.broadcast(trx) + completed(trx) + } + } + } +} diff --git a/programs/light_client/qml/TransactionDelegate.qml b/programs/light_client/qml/TransactionDelegate.qml new file mode 100644 index 00000000..26f6b5c4 --- /dev/null +++ b/programs/light_client/qml/TransactionDelegate.qml @@ -0,0 +1,42 @@ +import QtQuick 2.5 +import QtQuick.Layouts 1.2 + +import Graphene.Client 0.1 + +import "." + +ColumnLayout { + id: base + spacing: Scaling.mm(2) + + property Transaction trx + property GrapheneApplication app + + Text { + font.bold: true + font.pointSize: Scaling.cm(.4) + text: qsTr("Transaction Status: %1").arg(trx.statusString) + } + Repeater { + model: trx.operations + Loader { + function load() { + var source + switch (modelData.operationType) { + case OperationBase.TransferOperationType: source = "TransferOperationDelegate.qml" + } + setSource(source, {"op": modelData, "app": base.app, "width": base.width}) + } + Component.onCompleted: load() + // Debugging shim; disable before release + MouseArea { + anchors.fill: item + onClicked: { + console.log("Reloading " + parent.source) + parent.source = "" + parent.load() + } + } + } + } +} diff --git a/programs/light_client/qml/TransferForm.qml b/programs/light_client/qml/TransferForm.qml index 8ff7beac..f2850000 100644 --- a/programs/light_client/qml/TransferForm.qml +++ b/programs/light_client/qml/TransferForm.qml @@ -1,64 +1,130 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 -import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.2 import Graphene.Client 0.1 import "." -Rectangle { - anchors.fill: parent +/** + * This is the form for transferring some amount of asset from one account to another. + */ +FormBase { + id: base + /// The Account object for the sender property alias senderAccount: senderPicker.account + /// The Account object for the receiver property alias receiverAccount: recipientPicker.account - property GrapheneApplication app - signal finished + function operation() { + if (!finishLine.rightButtonEnabled) return app.operationBuilder.transfer(0,0,0,0, memoField.text, 0) + + return app.operationBuilder.transfer(senderPicker.account.id, recipientPicker.account.id, + amountField.value * amountField.precisionAdjustment, + amountField.maxBalance.type.id, memoField.text, 0) + } Component.onCompleted: console.log("Made a transfer form") Component.onDestruction: console.log("Destroyed a transfer form") - ColumnLayout { - anchors.centerIn: parent - width: parent.width - Scaling.cm(2) - spacing: Scaling.cm(1) + AccountPicker { + id: senderPicker + // The senderPicker is really the heart of the form. Everything else in the form adjusts based on the account + // selected here. The assetField below updates to contain all assets this account has a nonzero balance in. + // The amountField updates based on the asset selected in the assetField to have the appropriate precision and + // to have a maximum value equal to the account's balance in that asset. The transfer button enables only when + // both accounts are set, and a nonzero amount is selected to be transferred. - AccountPicker { - id: senderPicker - width: parent.width - Component.onCompleted: setFocus() - placeholderText: qsTr("Sender") + app: base.app + Layout.fillWidth: true + Layout.minimumWidth: Scaling.cm(5) + Component.onCompleted: setFocus() + placeholderText: qsTr("Sender") + showBalance: balances? balances.reduce(function(foundIndex, balance, index) { + if (foundIndex >= 0) return foundIndex + return balance.type.symbol === assetField.currentText? index : -1 + }, -1) : -1 + onBalanceClicked: amountField.value = balance + } + AccountPicker { + id: recipientPicker + app: base.app + Layout.fillWidth: true + Layout.minimumWidth: Scaling.cm(5) + placeholderText: qsTr("Recipient") + layoutDirection: Qt.RightToLeft + } + RowLayout { + Layout.fillWidth: true + TextField { + id: memoField + Layout.fillWidth: true + placeholderText: qsTr("Memo") } - AccountPicker { - id: recipientPicker - width: parent.width - placeholderText: qsTr("Recipient") - layoutDirection: Qt.RightToLeft + CheckBox { + id: encryptMemoField + text: qsTr("Encrypt Memo") + checked: true } - RowLayout { - width: parent.width - SpinBox { - Layout.preferredWidth: Scaling.cm(4) - Layout.minimumWidth: Scaling.cm(1.5) - enabled: senderPicker.account - minimumValue: 0 - maximumValue: Number.POSITIVE_INFINITY - } - ComboBox { - Layout.minimumWidth: Scaling.cm(3) - enabled: senderPicker.account - model: ["CORE", "USD", "GOLD"] - } - Item { Layout.fillWidth: true } - Button { - text: qsTr("Cancel") - onClicked: finished() - } - Button { - text: qsTr("Transfer") - enabled: senderPicker.account + } + RowLayout { + Layout.fillWidth: true + SpinBox { + id: amountField + Layout.preferredWidth: Scaling.cm(4) + Layout.minimumWidth: Scaling.cm(1.5) + enabled: maxBalance + minimumValue: 0 + maximumValue: maxBalance? maxBalance.amountReal() : 0 + decimals: maxBalance? maxBalance.type.precision : 0 + + Keys.onReturnPressed: if (finishLine.rightButtonEnabled) finishLine.clickRight() + + property Balance maxBalance: assetField.enabled && senderPicker.showBalance >= 0? + senderPicker.balances[senderPicker.showBalance] : null + property int precisionAdjustment: maxBalance? Math.pow(10, maxBalance.type.precision) : 1 + + // Workaround to preserve value in case form gets disabled then re-enabled + onEnabledChanged: if (!enabled) __valueBackup = value + onMaximumValueChanged: if (enabled && maximumValue > __valueBackup) value = __valueBackup + property real __valueBackup + } + ComboBox { + id: assetField + Layout.minimumWidth: Scaling.cm(1) + enabled: senderPicker.balances instanceof Array && senderPicker.balances.length > 0 + model: enabled? senderPicker.balances.filter(function(balance) { return balance.amount > 0 }) + .map(function(balance) { return balance.type.symbol }) + : ["Asset Type"] + } + Text { + font.pixelSize: assetField.height / 2.5 + text: { + if (!senderPicker.account || !amountField.maxBalance) + return "" + return qsTr("Fee:
") + amountField.maxBalance.type.formatAmount(operation().fee) + " CORE" } } } + UnlockingFinishButtons { + id: finishLine + app: base.app + rightButtonText: { + return !senderAccount || + !senderAccount.isLoaded || + senderPicker.accountControlLevel >= 1? qsTr("Transfer") : qsTr("Propose") + } + rightButtonEnabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value + requiresUnlocking: encryptMemoField.checked && memoField.text + Layout.fillWidth: true + + onLeftButtonClicked: canceled({}) + onRightButtonClicked: { + var op = operation() + if (encryptMemoField.checked) + op.encryptMemo(app.wallet, app.model) + completed([op]) + } + } } diff --git a/programs/light_client/qml/TransferOperationDelegate.qml b/programs/light_client/qml/TransferOperationDelegate.qml new file mode 100644 index 00000000..e0f62c29 --- /dev/null +++ b/programs/light_client/qml/TransferOperationDelegate.qml @@ -0,0 +1,59 @@ +import QtQuick 2.5 +import QtQuick.Layouts 1.2 + +import Graphene.Client 0.1 + +import "." + +ColumnLayout { + id: base + + property TransferOperation op + property GrapheneApplication app + + property Asset transferAsset: app.model.getAsset(op.amountType) + property Asset feeAsset: app.model.getAsset(op.feeType) + property Account sender: app.model.getAccount(op.sender) + property Account receiver: app.model.getAccount(op.receiver) + + RowLayout { + Layout.fillWidth: true + Identicon { + height: Scaling.cm(1) + width: Scaling.cm(1) + name: sender.name + } + Text { + Layout.alignment: Qt.AlignVCenter + text: "->
%1 %2".arg(transferAsset.formatAmount(op.amount)).arg(transferAsset.symbol) + horizontalAlignment: Text.Center + } + Identicon { + height: Scaling.cm(1) + width: Scaling.cm(1) + name: receiver.name + } + ColumnLayout { + Layout.fillWidth: true + Text { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + text: qsTr("Transfer from %1 to %2").arg(sender.name).arg(receiver.name) + } + Text { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + font.pointSize: 9 + text: qsTr("Fee: %1 %2").arg(feeAsset.formatAmount(op.fee)).arg(feeAsset.symbol) + } + } + } + + Text { + text: op.memo? qsTr("Memo: %1").arg(op.memoIsEncrypted && !app.wallet.isLocked? op.decryptedMemo(app.wallet, app.model) + : op.memo) + : qsTr("No memo") + color: op.memo? "black" : "grey" + font.italic: !op.memo + } +} diff --git a/programs/light_client/qml/UnlockingFinishButtons.qml b/programs/light_client/qml/UnlockingFinishButtons.qml new file mode 100644 index 00000000..0b6d0497 --- /dev/null +++ b/programs/light_client/qml/UnlockingFinishButtons.qml @@ -0,0 +1,54 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.2 + +import "." + +import Graphene.Client 0.1 + +RowLayout { + property string leftButtonText: qsTr("Cancel") + property string unlockButtonText: qsTr("Unlock") + property string rightButtonText: qsTr("Finish") + property bool leftButtonEnabled: true + property bool rightButtonEnabled: true + property bool requiresUnlocking: true + property GrapheneApplication app + + signal leftButtonClicked + signal rightButtonClicked + + function clickLeft() { leftButton.clicked() } + function clickRight() { rightButton.clicked() } + + Item { Layout.fillWidth: true } + Button { + id: leftButton + text: leftButtonText + onClicked: leftButtonClicked() + } + TextField { + id: passwordField + property bool shown: requiresUnlocking && app.wallet.isLocked + property real desiredWidth: shown? Scaling.cm(4) : 0 + Layout.preferredWidth: desiredWidth + echoMode: TextInput.Password + placeholderText: qsTr("Wallet password") + visible: desiredWidth > 0 + onAccepted: rightButton.clicked() + + Behavior on desiredWidth { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } } + } + Button { + id: rightButton + text: passwordField.shown? unlockButtonText : rightButtonText + enabled: rightButtonEnabled + onClicked: { + if (passwordField.visible) + return app.wallet.unlock(passwordField.text) + + rightButtonClicked() + } + Behavior on implicitWidth { NumberAnimation {} } + } +} diff --git a/programs/light_client/qml/main.qml b/programs/light_client/qml/main.qml index 9e6e1f96..0c25d019 100644 --- a/programs/light_client/qml/main.qml +++ b/programs/light_client/qml/main.qml @@ -14,10 +14,6 @@ ApplicationWindow { height: 480 title: qsTr("Hello World") - Component.onCompleted: { - app.start("ws://localhost:8090", "user", "pass") - } - menuBar: MenuBar { Menu { title: qsTr("File") @@ -32,13 +28,36 @@ ApplicationWindow { } } } + statusBar: StatusBar { + Label { + anchors.right: parent.right + text: qsTr("Network: %1 Wallet: %2").arg(app.isConnected? qsTr("Connected") : qsTr("Disconnected")) + .arg(app.wallet.isLocked? qsTr("Locked") : qsTr("Unlocked")) + } + } GrapheneApplication { id: app + Component.onCompleted: { + var walletFile = appSettings.walletPath + "/wallet.json" + if (!wallet.open(walletFile)) { + // TODO: onboarding experience + wallet.create(walletFile, "default password", "default brain key") + } + } + } + Timer { + running: !app.isConnected + interval: 5000 + repeat: true + onTriggered: app.start("ws://localhost:8090", "user", "pass") + triggeredOnStart: true } Settings { id: appSettings category: "appSettings" + + property string walletPath: app.defaultDataPath() } Connections { target: app @@ -47,12 +66,19 @@ ApplicationWindow { Column { anchors.centerIn: parent + enabled: app.isConnected + Button { text: "Transfer" - onClicked: formBox.showForm(Qt.createComponent("TransferForm.qml"), {}, - function() { - console.log("Closed form") - }) + onClicked: { + var front = Qt.createComponent("TransferForm.qml") + // TODO: make back into a preview and confirm dialog + var back = Qt.createComponent("TransactionConfirmationForm.qml") + formBox.showForm(Qt.createComponent("FormFlipper.qml"), {frontComponent: front, backComponent: back}, + function(arg) { + console.log("Closed form: " + JSON.stringify(arg)) + }) + } } TextField { id: nameField @@ -85,36 +111,83 @@ ApplicationWindow { } TextField { - id: idField - onAccepted: lookupIdButton.clicked() + id: accountIdField + onAccepted: lookupAccountIdButton.clicked() focus: true } Button { - id: lookupIdButton - text: "Lookup ID" + id: lookupAccountIdButton + text: "Lookup Account ID" onClicked: { - var acct = app.model.getAccount(parseInt(idField.text)) + var acct = app.model.getAccount(parseInt(accountIdField.text)) console.log(JSON.stringify(acct)) // @disable-check M126 if (acct == null) console.log("Got back null account") else if ( !(parseInt(acct.name) <= 0) ) - { - console.log("NAME ALREADY SET" ); console.log(JSON.stringify(acct)) - } - else - { + else { console.log("Waiting for result...") - acct.nameChanged.connect(function(loadedAcct) { - console.log( "NAME CHANGED" ); + acct.nameChanged.connect(function() { console.log(JSON.stringify(acct)) }) } } } - + TextField { + id: assetIdField + onAccepted: lookupassetIdButton.clicked() + focus: true + } + Button { + id: lookupassetIdButton + text: "Lookup Asset ID" + onClicked: { + var acct = app.model.getAsset(parseInt(assetIdField.text)) + console.log(JSON.stringify(acct)) + // @disable-check M126 + if (acct == null) + console.log("Got back null asset") + else if ( !(parseInt(acct.name) <= 0) ) + { + console.log(JSON.stringify(acct)) + } + else + { + console.log("Waiting for result...") + acct.nameChanged.connect(function() { + console.log(JSON.stringify(acct)) + }) + } + } + } + TextField { + id: passwordField + echoMode: TextInput.Password + } + Button { + text: app.wallet.isLocked? "Unlock wallet" : "Lock wallet" + onClicked: { + if (app.wallet.isLocked) + app.wallet.unlock(passwordField.text) + else + app.wallet.lock() + } + } + TextField { + id: keyField + placeholderText: "Private key" + } + TextField { + id: keyLabelField + placeholderText: "Key label" + } + Button { + text: "Import key" + enabled: !app.wallet.isLocked && keyField.text && keyLabelField.text + onClicked: app.wallet.importPrivateKey(keyField.text, keyLabelField.text) + } } FormBox { diff --git a/programs/light_client/qml/qml.qrc b/programs/light_client/qml/qml.qrc index ed16a610..55cdc35a 100644 --- a/programs/light_client/qml/qml.qrc +++ b/programs/light_client/qml/qml.qrc @@ -1,11 +1,18 @@ main.qml + FormBase.qml TransferForm.qml + TransactionDelegate.qml + TransferOperationDelegate.qml + TransactionConfirmationForm.qml FormBox.qml + FormFlipper.qml + UnlockingFinishButtons.qml Scaling.qml Identicon.qml AccountPicker.qml + TooltipArea.qml jdenticon/jdenticon-1.0.1.min.js diff --git a/programs/size_checker/CMakeLists.txt b/programs/size_checker/CMakeLists.txt index 8d9e752d..5e0a167c 100644 --- a/programs/size_checker/CMakeLists.txt +++ b/programs/size_checker/CMakeLists.txt @@ -4,4 +4,12 @@ if( UNIX AND NOT APPLE ) endif() target_link_libraries( size_checker - PRIVATE graphene_chain fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) + PRIVATE graphene_chain graphene_egenesis_none fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) + +install( TARGETS + size_checker + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/programs/size_checker/main.cpp b/programs/size_checker/main.cpp index 47c907e3..0d3fc7f1 100644 --- a/programs/size_checker/main.cpp +++ b/programs/size_checker/main.cpp @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -63,6 +64,20 @@ int main( int argc, char** argv ) { graphene::chain::operation op; + + vector witnesses; witnesses.resize(50); + for( uint32_t i = 0; i < 60*60*24*30; ++i ) + { + witnesses[ rand() % 50 ]++; + } + + std::sort( witnesses.begin(), witnesses.end() ); + idump((witnesses.back() - witnesses.front()) ); + idump((60*60*24*30/50)); + idump(("deviation: ")((60*60*24*30/50-witnesses.front())/(60*60*24*30/50.0))); + + idump( (witnesses) ); + for( int32_t i = 0; i < op.count(); ++i ) { op.set_which(i); @@ -84,6 +99,7 @@ int main( int argc, char** argv ) std::cout << "\n"; } std::cout << "]\n"; + std::cerr << "Size of block header: " << sizeof( block_header ) << " " << fc::raw::pack_size( block_header() ) << "\n"; } catch ( const fc::exception& e ){ edump((e.to_detail_string())); } idump((sizeof(signed_block))); diff --git a/programs/witness_node/CMakeLists.txt b/programs/witness_node/CMakeLists.txt index bf5f67d2..41bd784d 100644 --- a/programs/witness_node/CMakeLists.txt +++ b/programs/witness_node/CMakeLists.txt @@ -10,4 +10,12 @@ if( GPERFTOOLS_FOUND ) endif() target_link_libraries( witness_node - PRIVATE graphene_app graphene_account_history graphene_market_history graphene_witness graphene_chain fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) + PRIVATE graphene_app graphene_account_history graphene_market_history graphene_witness graphene_chain graphene_egenesis_full fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) + +install( TARGETS + witness_node + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/programs/witness_node/main.cpp b/programs/witness_node/main.cpp index 99387f31..97c7a4a9 100644 --- a/programs/witness_node/main.cpp +++ b/programs/witness_node/main.cpp @@ -21,24 +21,40 @@ #include #include +#include #include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include + #include #include -#ifndef WIN32 -#include +#ifdef WIN32 +# include +#else +# include #endif using namespace graphene; namespace bpo = boost::program_options; + +void write_default_logging_config_to_stream(std::ostream& out); +fc::optional load_logging_config_from_ini_file(const fc::path& config_ini_filename); int main(int argc, char** argv) { + app::application* node = new app::application(); try { - app::application node; bpo::options_description app_options("Graphene Witness Node"); bpo::options_description cfg_options("Graphene Witness Node"); app_options.add_options() @@ -48,14 +64,14 @@ int main(int argc, char** argv) { bpo::variables_map options; - auto witness_plug = node.register_plugin(); - auto history_plug = node.register_plugin(); - auto market_history_plug = node.register_plugin(); + auto witness_plug = node->register_plugin(); + auto history_plug = node->register_plugin(); + auto market_history_plug = node->register_plugin(); try { bpo::options_description cli, cfg; - node.set_program_options(cli, cfg); + node->set_program_options(cli, cfg); app_options.add(cli); cfg_options.add(cfg); bpo::store(bpo::parse_command_line(argc, argv, app_options), options); @@ -80,14 +96,31 @@ int main(int argc, char** argv) { data_dir = fc::current_path() / data_dir; } - if( fc::exists(data_dir / "config.ini") ) - bpo::store(bpo::parse_config_file((data_dir / "config.ini").preferred_string().c_str(), cfg_options), options); - else { - ilog("Writing new config file at ${path}", ("path", data_dir/"config.ini")); + fc::path config_ini_path = data_dir / "config.ini"; + if( fc::exists(config_ini_path) ) + { + // get the basic options + bpo::store(bpo::parse_config_file(config_ini_path.preferred_string().c_str(), cfg_options, true), options); + + // try to get logging options from the config file. + try + { + fc::optional logging_config = load_logging_config_from_ini_file(config_ini_path); + if (logging_config) + fc::configure_logging(*logging_config); + } + catch (const fc::exception&) + { + wlog("Error parsing logging config from config file ${config}, using default config", ("config", config_ini_path.preferred_string())); + } + } + else + { + ilog("Writing new config file at ${path}", ("path", config_ini_path)); if( !fc::exists(data_dir) ) fc::create_directories(data_dir); - std::ofstream out_cfg((data_dir / "config.ini").preferred_string()); + std::ofstream out_cfg(config_ini_path.preferred_string()); for( const boost::shared_ptr od : cfg_options.options() ) { if( !od->description().empty() ) @@ -109,30 +142,147 @@ int main(int argc, char** argv) { } out_cfg << "\n"; } + write_default_logging_config_to_stream(out_cfg); + out_cfg.close(); + // read the default logging config we just wrote out to the file and start using it + fc::optional logging_config = load_logging_config_from_ini_file(config_ini_path); + if (logging_config) + fc::configure_logging(*logging_config); } bpo::notify(options); - node.initialize(data_dir, options); - node.initialize_plugins( options ); + node->initialize(data_dir, options); + node->initialize_plugins( options ); - node.startup(); - node.startup_plugins(); + node->startup(); + node->startup_plugins(); fc::promise::ptr exit_promise = new fc::promise("UNIX Signal Handler"); -#if defined __APPLE__ || defined __unix__ fc::set_signal_handler([&exit_promise](int signal) { + elog( "Caught ^C attempting to exit cleanly" ); exit_promise->set_value(signal); }, SIGINT); -#endif - ilog("Started witness node on a chain with ${h} blocks.", ("h", node.chain_database()->head_block_num())); + ilog("Started witness node on a chain with ${h} blocks.", ("h", node->chain_database()->head_block_num())); + ilog("Chain ID is ${id}", ("id", node->chain_database()->get_chain_id()) ); int signal = exit_promise->wait(); ilog("Exiting from signal ${n}", ("n", signal)); - node.shutdown_plugins(); + node->shutdown_plugins(); + node->shutdown(); + delete node; return 0; } catch( const fc::exception& e ) { elog("Exiting with error:\n${e}", ("e", e.to_detail_string())); + node->shutdown(); + delete node; return 1; } } + +// logging config is too complicated to be parsed by boost::program_options, +// so we do it by hand +// +// Currently, you can only specify the filenames and logging levels, which +// are all most users would want to change. At a later time, options can +// be added to control rotation intervals, compression, and other seldom- +// used features +void write_default_logging_config_to_stream(std::ostream& out) +{ + out << "# declare an appender named \"stderr\" that writes messages to the console\n" + "[log.console_appender.stderr]\n" + "stream=std_error\n\n" + "# declare an appender named \"p2p\" that writes messages to p2p.log\n" + "[log.file_appender.p2p]\n" + "filename=logs/p2p/p2p.log\n" + "# filename can be absolute or relative to this config file\n\n" + "# route any messages logged to the default logger to the \"stderr\" logger we\n" + "# declared above, if they are info level are higher\n" + "[logger.default]\n" + "level=info\n" + "appenders=stderr\n\n" + "# route messages sent to the \"p2p\" logger to the p2p appender declared above\n" + "[logger.p2p]\n" + "level=debug\n" + "appenders=p2p\n\n"; +} + +fc::optional load_logging_config_from_ini_file(const fc::path& config_ini_filename) +{ + try + { + fc::logging_config logging_config; + bool found_logging_config = false; + + boost::property_tree::ptree config_ini_tree; + boost::property_tree::ini_parser::read_ini(config_ini_filename.preferred_string().c_str(), config_ini_tree); + for (const auto& section : config_ini_tree) + { + const std::string& section_name = section.first; + const boost::property_tree::ptree& section_tree = section.second; + + const std::string console_appender_section_prefix = "log.console_appender."; + const std::string file_appender_section_prefix = "log.file_appender."; + const std::string logger_section_prefix = "logger."; + + if (boost::starts_with(section_name, console_appender_section_prefix)) + { + std::string console_appender_name = section_name.substr(console_appender_section_prefix.length()); + std::string stream_name = section_tree.get("stream"); + + // construct a default console appender config here + // stdout/stderr will be taken from ini file, everything else hard-coded here + fc::console_appender::config console_appender_config; + console_appender_config.level_colors.emplace_back( + fc::console_appender::level_color(fc::log_level::debug, + fc::console_appender::color::green)); + console_appender_config.level_colors.emplace_back( + fc::console_appender::level_color(fc::log_level::warn, + fc::console_appender::color::brown)); + console_appender_config.level_colors.emplace_back( + fc::console_appender::level_color(fc::log_level::error, + fc::console_appender::color::cyan)); + console_appender_config.stream = fc::variant(stream_name).as(); + logging_config.appenders.push_back(fc::appender_config(console_appender_name, "console", fc::variant(console_appender_config))); + found_logging_config = true; + } + else if (boost::starts_with(section_name, file_appender_section_prefix)) + { + std::string file_appender_name = section_name.substr(file_appender_section_prefix.length()); + fc::path file_name = section_tree.get("filename"); + if (file_name.is_relative()) + file_name = fc::absolute(config_ini_filename).parent_path() / file_name; + + + // construct a default file appender config here + // filename will be taken from ini file, everything else hard-coded here + fc::file_appender::config file_appender_config; + file_appender_config.filename = file_name; + file_appender_config.flush = true; + file_appender_config.rotate = true; + file_appender_config.rotation_interval = fc::hours(1); + file_appender_config.rotation_limit = fc::days(1); + logging_config.appenders.push_back(fc::appender_config(file_appender_name, "file", fc::variant(file_appender_config))); + found_logging_config = true; + } + else if (boost::starts_with(section_name, logger_section_prefix)) + { + std::string logger_name = section_name.substr(logger_section_prefix.length()); + std::string level_string = section_tree.get("level"); + std::string appenders_string = section_tree.get("appenders"); + fc::logger_config logger_config(logger_name); + logger_config.level = fc::variant(level_string).as(); + boost::split(logger_config.appenders, appenders_string, + boost::is_any_of(" ,"), + boost::token_compress_on); + logging_config.loggers.push_back(logger_config); + found_logging_config = true; + } + } + if (found_logging_config) + return logging_config; + else + return fc::optional(); + } + FC_RETHROW_EXCEPTIONS(warn, "") +} diff --git a/testnet-shared-accounts.txt b/testnet-shared-accounts.txt index c3777468..99392365 100644 --- a/testnet-shared-accounts.txt +++ b/testnet-shared-accounts.txt @@ -1,3 +1,509 @@ + "initial_accounts": [{ + "name": "init0", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init1", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init2", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init3", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init4", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init5", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init6", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init7", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init8", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init9", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init10", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init11", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init12", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init13", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init14", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init15", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init16", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init17", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init18", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init19", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init20", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init21", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init22", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init23", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init24", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init25", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init26", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init27", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init28", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init29", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init30", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init31", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init32", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init33", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init34", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init35", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init36", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init37", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init38", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init39", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init40", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init41", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init42", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init43", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init44", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init45", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init46", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init47", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init48", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init49", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init50", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init51", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init52", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init53", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init54", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init55", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init56", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init57", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init58", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init59", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init60", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init61", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init62", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init63", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init64", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init65", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init66", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init67", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init68", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init69", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init70", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init71", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init72", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init73", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init74", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init75", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init76", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init77", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init78", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init79", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init80", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init81", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init82", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init83", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init84", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init85", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init86", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init87", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init88", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init89", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init90", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init91", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init92", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init93", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init94", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init95", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init96", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init97", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init98", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init99", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init100", + "owner_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ "name": "dummy0", "owner_key": "BTS6qkMe8pHmQ4zUetLV1bbVKoQJYTNb1fSUbkQzuzpscYhonWpgk", "active_key": "BTS6qkMe8pHmQ4zUetLV1bbVKoQJYTNb1fSUbkQzuzpscYhonWpgk", diff --git a/testnet-shared-committee-members.txt b/testnet-shared-committee-members.txt new file mode 100644 index 00000000..7d7ae11b --- /dev/null +++ b/testnet-shared-committee-members.txt @@ -0,0 +1,204 @@ + "initial_committee_candidates": [{ + "owner_name": "init0" + },{ + "owner_name": "init1" + },{ + "owner_name": "init2" + },{ + "owner_name": "init3" + },{ + "owner_name": "init4" + },{ + "owner_name": "init5" + },{ + "owner_name": "init6" + },{ + "owner_name": "init7" + },{ + "owner_name": "init8" + },{ + "owner_name": "init9" + },{ + "owner_name": "init10" + },{ + "owner_name": "init11" + },{ + "owner_name": "init12" + },{ + "owner_name": "init13" + },{ + "owner_name": "init14" + },{ + "owner_name": "init15" + },{ + "owner_name": "init16" + },{ + "owner_name": "init17" + },{ + "owner_name": "init18" + },{ + "owner_name": "init19" + },{ + "owner_name": "init20" + },{ + "owner_name": "init21" + },{ + "owner_name": "init22" + },{ + "owner_name": "init23" + },{ + "owner_name": "init24" + },{ + "owner_name": "init25" + },{ + "owner_name": "init26" + },{ + "owner_name": "init27" + },{ + "owner_name": "init28" + },{ + "owner_name": "init29" + },{ + "owner_name": "init30" + },{ + "owner_name": "init31" + },{ + "owner_name": "init32" + },{ + "owner_name": "init33" + },{ + "owner_name": "init34" + },{ + "owner_name": "init35" + },{ + "owner_name": "init36" + },{ + "owner_name": "init37" + },{ + "owner_name": "init38" + },{ + "owner_name": "init39" + },{ + "owner_name": "init40" + },{ + "owner_name": "init41" + },{ + "owner_name": "init42" + },{ + "owner_name": "init43" + },{ + "owner_name": "init44" + },{ + "owner_name": "init45" + },{ + "owner_name": "init46" + },{ + "owner_name": "init47" + },{ + "owner_name": "init48" + },{ + "owner_name": "init49" + },{ + "owner_name": "init50" + },{ + "owner_name": "init51" + },{ + "owner_name": "init52" + },{ + "owner_name": "init53" + },{ + "owner_name": "init54" + },{ + "owner_name": "init55" + },{ + "owner_name": "init56" + },{ + "owner_name": "init57" + },{ + "owner_name": "init58" + },{ + "owner_name": "init59" + },{ + "owner_name": "init60" + },{ + "owner_name": "init61" + },{ + "owner_name": "init62" + },{ + "owner_name": "init63" + },{ + "owner_name": "init64" + },{ + "owner_name": "init65" + },{ + "owner_name": "init66" + },{ + "owner_name": "init67" + },{ + "owner_name": "init68" + },{ + "owner_name": "init69" + },{ + "owner_name": "init70" + },{ + "owner_name": "init71" + },{ + "owner_name": "init72" + },{ + "owner_name": "init73" + },{ + "owner_name": "init74" + },{ + "owner_name": "init75" + },{ + "owner_name": "init76" + },{ + "owner_name": "init77" + },{ + "owner_name": "init78" + },{ + "owner_name": "init79" + },{ + "owner_name": "init80" + },{ + "owner_name": "init81" + },{ + "owner_name": "init82" + },{ + "owner_name": "init83" + },{ + "owner_name": "init84" + },{ + "owner_name": "init85" + },{ + "owner_name": "init86" + },{ + "owner_name": "init87" + },{ + "owner_name": "init88" + },{ + "owner_name": "init89" + },{ + "owner_name": "init90" + },{ + "owner_name": "init91" + },{ + "owner_name": "init92" + },{ + "owner_name": "init93" + },{ + "owner_name": "init94" + },{ + "owner_name": "init95" + },{ + "owner_name": "init96" + },{ + "owner_name": "init97" + },{ + "owner_name": "init98" + },{ + "owner_name": "init99" + },{ + "owner_name": "init100" + } + ], diff --git a/testnet-shared-vesting-balances.txt b/testnet-shared-vesting-balances.txt new file mode 100644 index 00000000..1dd00230 --- /dev/null +++ b/testnet-shared-vesting-balances.txt @@ -0,0 +1,71 @@ + "initial_vesting_balances": [{ + "owner": "BTSHYhQcrjVg5kBzCoeeD38eQdncCC5pBgee", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTSPgQZg5929ht1NBdEvsGKqoQ7buRu3nKf4", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTSC9zrLXSAPUQaVmQPk1S9dMqSzT7jPqYU7", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTS93aQPtbbkXwaSjtHaREsNVcCvbfHo93aZ", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTS6RM4UfsYFPDuhbmgkvDS9ip8Kvqundvyk", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTSNVkZXdqWWSzqHVxvfetMe347is6kEkC4K", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTS5GHzWZ64Luoajqsz6JGjTKVMgWYkGV9SQ", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTSDCVRFez92bW9doRLjnFCKLJnpM58mgmMb", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTS5CCdX3JYLBptYMuCjbsezqGYzN9vG9JCu", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ + "owner": "BTSEQ3yQdr3EMDL2eRqGiceMCpoanaW16Puw", + "asset_symbol": "BTS", + "amount": 50000000000, + "begin_timestamp": "2014-11-06T00:00:00", + "vesting_duration_seconds": 63072000, + "begin_balance": 50000000000 + },{ diff --git a/testnet-shared-witnesses.txt b/testnet-shared-witnesses.txt new file mode 100644 index 00000000..c09b1329 --- /dev/null +++ b/testnet-shared-witnesses.txt @@ -0,0 +1,304 @@ + "initial_witness_candidates": [{ + "owner_name": "init0", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init1", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init2", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init3", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init4", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init5", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init6", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init7", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init8", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init9", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init10", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init11", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init12", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init13", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init14", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init15", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init16", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init17", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init18", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init19", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init20", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init21", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init22", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init23", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init24", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init25", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init26", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init27", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init28", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init29", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init30", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init31", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init32", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init33", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init34", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init35", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init36", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init37", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init38", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init39", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init40", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init41", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init42", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init43", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init44", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init45", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init46", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init47", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init48", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init49", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init50", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init51", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init52", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init53", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init54", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init55", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init56", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init57", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init58", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init59", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init60", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init61", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init62", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init63", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init64", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init65", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init66", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init67", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init68", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init69", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init70", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init71", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init72", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init73", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init74", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init75", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init76", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init77", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init78", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init79", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init80", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init81", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init82", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init83", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init84", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init85", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init86", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init87", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init88", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init89", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init90", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init91", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init92", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init93", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init94", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init95", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init96", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init97", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init98", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init99", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init100", + "block_signing_key": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71bbf6ca..b03d58a8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,24 +8,25 @@ endif() file(GLOB UNIT_TESTS "tests/*.cpp") add_executable( chain_test ${UNIT_TESTS} ${COMMON_SOURCES} ) -target_link_libraries( chain_test graphene_chain graphene_app graphene_account_history fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( chain_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) if(MSVC) set_source_files_properties( tests/serialization_tests.cpp PROPERTIES COMPILE_FLAGS "/bigobj" ) endif(MSVC) file(GLOB PERFORMANCE_TESTS "performance/*.cpp") add_executable( performance_test ${PERFORMANCE_TESTS} ${COMMON_SOURCES} ) -target_link_libraries( performance_test graphene_chain graphene_app graphene_account_history fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( performance_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) file(GLOB BENCH_MARKS "benchmarks/*.cpp") add_executable( chain_bench ${BENCH_MARKS} ${COMMON_SOURCES} ) -target_link_libraries( chain_bench graphene_chain graphene_account_history graphene_time fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( chain_bench graphene_chain graphene_app graphene_account_history graphene_time graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) file(GLOB APP_SOURCES "app/*.cpp") add_executable( app_test ${APP_SOURCES} ) -target_link_libraries( app_test graphene_account_history graphene_app graphene_net graphene_chain graphene_time fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( app_test graphene_app graphene_account_history graphene_net graphene_chain graphene_time graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) file(GLOB INTENSE_SOURCES "intense/*.cpp") add_executable( intense_test ${INTENSE_SOURCES} ${COMMON_SOURCES} ) -target_link_libraries( intense_test graphene_chain graphene_app graphene_account_history fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( intense_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) +add_subdirectory( generate_empty_blocks ) diff --git a/tests/app/main.cpp b/tests/app/main.cpp index ffade287..b498ec01 100644 --- a/tests/app/main.cpp +++ b/tests/app/main.cpp @@ -18,6 +18,8 @@ #include #include +#include + #include #include @@ -25,6 +27,7 @@ #include #include +#include #include @@ -38,12 +41,13 @@ BOOST_AUTO_TEST_CASE( two_node_network ) using namespace graphene::chain; using namespace graphene::app; try { + BOOST_TEST_MESSAGE( "Creating temporary files" ); + fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); fc::temp_directory app2_dir( graphene::utilities::temp_directory_path() ); fc::temp_file genesis_json; - // TODO: Time should be read from the blockchain - fc::time_point_sec now( 1431700000 ); + BOOST_TEST_MESSAGE( "Creating and initializing app1" ); graphene::app::application app1; app1.register_plugin(); @@ -51,6 +55,8 @@ BOOST_AUTO_TEST_CASE( two_node_network ) cfg.emplace("p2p-endpoint", boost::program_options::variable_value(string("127.0.0.1:3939"), false)); app1.initialize(app_dir.path(), cfg); + BOOST_TEST_MESSAGE( "Creating and initializing app2" ); + graphene::app::application app2; app2.register_plugin(); auto cfg2 = cfg; @@ -59,42 +65,82 @@ BOOST_AUTO_TEST_CASE( two_node_network ) cfg2.emplace("seed-node", boost::program_options::variable_value(vector{"127.0.0.1:3939"}, false)); app2.initialize(app2_dir.path(), cfg2); - app1.startup(); + BOOST_TEST_MESSAGE( "Starting app1 and waiting 500 ms" ); + app1.startup(); + fc::usleep(fc::milliseconds(500)); + BOOST_TEST_MESSAGE( "Starting app2 and waiting 500 ms" ); app2.startup(); fc::usleep(fc::milliseconds(500)); BOOST_REQUIRE_EQUAL(app1.p2p_node()->get_connection_count(), 1); BOOST_CHECK_EQUAL(std::string(app1.p2p_node()->get_connected_peers().front().host.get_address()), "127.0.0.1"); - ilog("Connected!"); + BOOST_TEST_MESSAGE( "app1 and app2 successfully connected" ); - fc::ecc::private_key nathan_key = fc::ecc::private_key::generate(); - fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); - graphene::chain::signed_transaction trx; - trx.set_expiration(now + fc::seconds(30)); + std::shared_ptr db1 = app1.chain_database(); std::shared_ptr db2 = app2.chain_database(); - assert_operation op; - op.fee_paying_account = GRAPHENE_TEMP_ACCOUNT; - op.predicates.push_back( graphene::chain::asset_symbol_eq_lit_predicate{ asset_id_type(), "CORE" } ); + BOOST_CHECK_EQUAL( db1->get_balance( GRAPHENE_NULL_ACCOUNT, asset_id_type() ).amount.value, 0 ); + BOOST_CHECK_EQUAL( db2->get_balance( GRAPHENE_NULL_ACCOUNT, asset_id_type() ).amount.value, 0 ); - trx.operations.push_back( std::move( op ) ); + BOOST_TEST_MESSAGE( "Creating transfer tx" ); + graphene::chain::signed_transaction trx; + { + account_id_type nathan_id = db2->get_index_type().indices().get().find( "nathan" )->id; + fc::ecc::private_key nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); - trx.validate(); - processed_transaction ptrx = app1.chain_database()->push_transaction(trx); + balance_claim_operation claim_op; + balance_id_type bid = balance_id_type(); + claim_op.deposit_to_account = nathan_id; + claim_op.balance_to_claim = bid; + claim_op.balance_owner_key = nathan_key.get_public_key(); + claim_op.total_claimed = bid(*db1).balance; + trx.operations.push_back( claim_op ); + db1->current_fee_schedule().set_fee( trx.operations.back() ); + + transfer_operation xfer_op; + xfer_op.from = nathan_id; + xfer_op.to = GRAPHENE_NULL_ACCOUNT; + xfer_op.amount = asset( 1000000 ); + trx.operations.push_back( xfer_op ); + db1->current_fee_schedule().set_fee( trx.operations.back() ); + + trx.set_expiration( db1->get_slot_time( 10 ) ); + trx.sign( nathan_key, db1->get_chain_id() ); + trx.validate(); + } + + BOOST_TEST_MESSAGE( "Pushing tx locally on db1" ); + processed_transaction ptrx = db1->push_transaction(trx); + + BOOST_CHECK_EQUAL( db1->get_balance( GRAPHENE_NULL_ACCOUNT, asset_id_type() ).amount.value, 1000000 ); + BOOST_CHECK_EQUAL( db2->get_balance( GRAPHENE_NULL_ACCOUNT, asset_id_type() ).amount.value, 0 ); + + BOOST_TEST_MESSAGE( "Broadcasting tx" ); app1.p2p_node()->broadcast(graphene::net::trx_message(trx)); - fc::usleep(fc::milliseconds(250)); - ilog("Pushed transaction"); + fc::usleep(fc::milliseconds(500)); - now += GRAPHENE_DEFAULT_BLOCK_INTERVAL; - app2.p2p_node()->broadcast(graphene::net::block_message(db2->generate_block(now, - db2->get_scheduled_witness(1).first, - committee_key, - database::skip_nothing))); + BOOST_CHECK_EQUAL( db1->get_balance( GRAPHENE_NULL_ACCOUNT, asset_id_type() ).amount.value, 1000000 ); + BOOST_CHECK_EQUAL( db2->get_balance( GRAPHENE_NULL_ACCOUNT, asset_id_type() ).amount.value, 1000000 ); + + BOOST_TEST_MESSAGE( "Generating block on db2" ); + fc::ecc::private_key committee_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); + + auto block_1 = db2->generate_block( + db2->get_slot_time(1), + db2->get_scheduled_witness(1), + committee_key, + database::skip_nothing); + + BOOST_TEST_MESSAGE( "Broadcasting block" ); + app2.p2p_node()->broadcast(graphene::net::block_message( block_1 )); fc::usleep(fc::milliseconds(500)); + BOOST_TEST_MESSAGE( "Verifying nodes are still connected" ); BOOST_CHECK_EQUAL(app1.p2p_node()->get_connection_count(), 1); BOOST_CHECK_EQUAL(app1.chain_database()->head_block_num(), 1); + + BOOST_TEST_MESSAGE( "Checking GRAPHENE_NULL_ACCOUNT has balance" ); } catch( fc::exception& e ) { edump((e.to_detail_string())); throw; diff --git a/tests/benchmarks/genesis_allocation.cpp b/tests/benchmarks/genesis_allocation.cpp index 033a4350..5dedaedf 100644 --- a/tests/benchmarks/genesis_allocation.cpp +++ b/tests/benchmarks/genesis_allocation.cpp @@ -22,6 +22,7 @@ #include #include +#include #include @@ -85,7 +86,7 @@ BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench ) int blocks_out = 0; auto witness_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); auto aw = db.get_global_properties().active_witnesses; - auto b = db.generate_block( db.get_slot_time( 1 ), db.get_scheduled_witness( 1 ).first, witness_priv_key, ~0 ); + auto b = db.generate_block( db.get_slot_time( 1 ), db.get_scheduled_witness( 1 ), witness_priv_key, ~0 ); start_time = fc::time_point::now(); /* TODO: get this buliding again @@ -96,7 +97,7 @@ BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench ) db.push_transaction(trx, ~0); aw = db.get_global_properties().active_witnesses; - b = db.generate_block( db.get_slot_time( 1 ), db.get_scheduled_witness( 1 ).first, witness_priv_key, ~0 ); + b = db.generate_block( db.get_slot_time( 1 ), db.get_scheduled_witness( 1 ), witness_priv_key, ~0 ); } */ ilog("Pushed ${c} blocks (1 op each, no validation) in ${t} milliseconds.", diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index 69d557d8..b7325a7f 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -41,6 +41,8 @@ #include "database_fixture.hpp" +using namespace graphene::chain::test; + namespace graphene { namespace chain { using std::cout; @@ -92,7 +94,7 @@ database_fixture::database_fixture() generate_block(); - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); } catch ( const fc::exception& e ) { edump( (e.to_detail_string()) ); @@ -181,11 +183,7 @@ void database_fixture::verify_asset_supplies( const database& db ) total_balances[bad.options.short_backing_asset] += bad.settlement_fund; } } - for( const witness_object& witness_obj : db.get_index_type().indices() ) - { - total_balances[asset_id_type()] += witness_obj.accumulated_income; - } - for( const vesting_balance_object& vbo : db.get_index_type< simple_index >() ) + for( const vesting_balance_object& vbo : db.get_index_type< vesting_balance_index >().indices() ) total_balances[ vbo.balance.asset_id ] += vbo.balance.amount; total_balances[asset_id_type()] += db.get_dynamic_global_properties().witness_budget; @@ -196,7 +194,7 @@ void database_fixture::verify_asset_supplies( const database& db ) } BOOST_CHECK_EQUAL( core_in_orders.value , reported_core_in_orders.value ); - BOOST_CHECK_EQUAL( total_balances[asset_id_type()].value , core_asset_data.current_supply.value ); + BOOST_CHECK_EQUAL( total_balances[asset_id_type()].value , core_asset_data.current_supply.value - core_asset_data.confidential_supply.value); // wlog("*** End asset supply verification ***"); } @@ -296,10 +294,13 @@ signed_block database_fixture::generate_block(uint32_t skip, const fc::ecc::priv { open_database(); + skip |= database::skip_undo_history_check; // skip == ~0 will skip checks specified in database::validation_steps - return db.generate_block(db.get_slot_time(miss_blocks + 1), - db.get_scheduled_witness(miss_blocks + 1).first, + auto block = db.generate_block(db.get_slot_time(miss_blocks + 1), + db.get_scheduled_witness(miss_blocks + 1), key, skip); + db.clear_pending(); + return block; } void database_fixture::generate_blocks( uint32_t block_count ) @@ -334,6 +335,7 @@ account_create_operation database_fixture::make_account( create_account.owner = authority(123, key, 123); create_account.active = authority(321, key, 321); create_account.options.memo_key = key; + create_account.options.voting_account = GRAPHENE_PROXY_TO_SELF_ACCOUNT; auto& active_committee_members = db.get_global_properties().active_committee_members; if( active_committee_members.size() > 0 ) @@ -372,6 +374,7 @@ account_create_operation database_fixture::make_account( create_account.owner = authority(123, key, 123); create_account.active = authority(321, key, 321); create_account.options.memo_key = key; + create_account.options.voting_account = GRAPHENE_PROXY_TO_SELF_ACCOUNT; const vector& active_committee_members = db.get_global_properties().active_committee_members; if( active_committee_members.size() > 0 ) @@ -394,12 +397,18 @@ account_create_operation database_fixture::make_account( const asset_object& database_fixture::get_asset( const string& symbol )const { - return *db.get_index_type().indices().get().find(symbol); + const auto& idx = db.get_index_type().indices().get(); + const auto itr = idx.find(symbol); + assert( itr != idx.end() ); + return *itr; } const account_object& database_fixture::get_account( const string& name )const { - return *db.get_index_type().indices().get().find(name); + const auto& idx = db.get_index_type().indices().get(); + const auto itr = idx.find(name); + assert( itr != idx.end() ); + return *itr; } const asset_object& database_fixture::create_bitasset( @@ -493,13 +502,14 @@ const asset_object& database_fixture::create_user_issued_asset( const string& na void database_fixture::issue_uia( const account_object& recipient, asset amount ) { + BOOST_TEST_MESSAGE( "Issuing UIA" ); asset_issue_operation op; op.issuer = amount.asset_id(db).issuer; op.asset_to_issue = amount; op.issue_to_account = recipient.id; - trx.validate(); trx.operations.push_back(op); - return; + db.push_transaction( trx, ~0 ); + trx.operations.clear(); } const account_object& database_fixture::create_account( @@ -555,6 +565,7 @@ const account_object& database_fixture::create_account( account_create_op.owner = authority(1234, public_key_type(key.get_public_key()), 1234); account_create_op.active = authority(5678, public_key_type(key.get_public_key()), 5678); account_create_op.options.memo_key = key.get_public_key(); + account_create_op.options.voting_account = GRAPHENE_PROXY_TO_SELF_ACCOUNT; trx.operations.push_back( account_create_op ); trx.validate(); @@ -590,10 +601,6 @@ const witness_object& database_fixture::create_witness( const account_object& ow witness_create_operation op; op.witness_account = owner.id; op.block_signing_key = signing_private_key.get_public_key(); - secret_hash_type::encoder enc; - fc::raw::pack(enc, signing_private_key); - fc::raw::pack(enc, secret_hash_type()); - op.initial_secret = secret_hash_type::hash(enc.result()); trx.operations.push_back(op); trx.validate(); processed_transaction ptx = db.push_transaction(trx, ~0); @@ -601,7 +608,6 @@ const witness_object& database_fixture::create_witness( const account_object& ow return db.get(ptx.operation_results[0].get()); } FC_CAPTURE_AND_RETHROW() } - uint64_t database_fixture::fund( const account_object& account, const asset& amount /* = asset(500000) */ @@ -613,7 +619,12 @@ uint64_t database_fixture::fund( void database_fixture::sign(signed_transaction& trx, const fc::ecc::private_key& key) { - trx.sign( key ); + trx.sign( key, db.get_chain_id() ); +} + +digest_type database_fixture::digest( const transaction& tx ) +{ + return tx.digest(); } const limit_order_object*database_fixture::create_sell_order(account_id_type user, const asset& amount, const asset& recv) @@ -654,7 +665,6 @@ asset database_fixture::cancel_limit_order( const limit_order_object& order ) return processed.operation_results[0].get(); } - void database_fixture::transfer( account_id_type from, account_id_type to, @@ -673,7 +683,7 @@ void database_fixture::transfer( { try { - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); transfer_operation trans; trans.from = from.id; trans.to = to.id; @@ -693,7 +703,7 @@ void database_fixture::transfer( void database_fixture::update_feed_producers( const asset_object& mia, flat_set producers ) { try { - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); trx.operations.clear(); asset_update_feed_producers_operation op; op.asset_to_update = mia.id; @@ -708,10 +718,9 @@ void database_fixture::update_feed_producers( const asset_object& mia, flat_set< verify_asset_supplies(db); } FC_CAPTURE_AND_RETHROW( (mia)(producers) ) } - -void database_fixture::publish_feed( const asset_object& mia, const account_object& by, const price_feed& f ) +void database_fixture::publish_feed( const asset_object& mia, const account_object& by, const price_feed& f ) { - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); trx.operations.clear(); asset_publish_feed_operation op; @@ -729,7 +738,7 @@ void database_fixture::publish_feed( const asset_object& mia, const account_obj void database_fixture::force_global_settle( const asset_object& what, const price& p ) { try { - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); trx.operations.clear(); asset_global_settle_operation sop; sop.issuer = what.issuer; @@ -743,9 +752,9 @@ void database_fixture::force_global_settle( const asset_object& what, const pric verify_asset_supplies(db); } FC_CAPTURE_AND_RETHROW( (what)(p) ) } -void database_fixture::force_settle( const account_object& who, asset what ) +operation_result database_fixture::force_settle( const account_object& who, asset what ) { try { - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); trx.operations.clear(); asset_settle_operation sop; sop.account = who.id; @@ -753,14 +762,16 @@ void database_fixture::force_settle( const account_object& who, asset what ) trx.operations.push_back(sop); for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op); trx.validate(); - db.push_transaction(trx, ~0); + processed_transaction ptx = db.push_transaction(trx, ~0); + const operation_result& op_result = ptx.operation_results.front(); trx.operations.clear(); verify_asset_supplies(db); + return op_result; } FC_CAPTURE_AND_RETHROW( (who)(what) ) } -void database_fixture::borrow(const account_object& who, asset what, asset collateral) +const call_order_object* database_fixture::borrow(const account_object& who, asset what, asset collateral) { try { - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); trx.operations.clear(); call_order_update_operation update; update.funding_account = who.id; @@ -772,11 +783,19 @@ void database_fixture::borrow(const account_object& who, asset what, asset coll db.push_transaction(trx, ~0); trx.operations.clear(); verify_asset_supplies(db); + + auto& call_idx = db.get_index_type().indices().get(); + auto itr = call_idx.find( boost::make_tuple(who.id, what.asset_id) ); + const call_order_object* call_obj = nullptr; + + if( itr != call_idx.end() ) + call_obj = &*itr; + return call_obj; } FC_CAPTURE_AND_RETHROW( (who.name)(what)(collateral) ) } -void database_fixture::cover(const account_object& who, asset what, asset collateral) +void database_fixture::cover(const account_object& who, asset what, asset collateral) { try { - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); trx.operations.clear(); call_order_update_operation update; update.funding_account = who.id; @@ -810,7 +829,7 @@ void database_fixture::enable_fees() db.modify(global_property_id_type()(db), [](global_property_object& gpo) { gpo.parameters.current_fees = fee_schedule::get_default(); - } ); + }); } void database_fixture::upgrade_to_lifetime_member(account_id_type account) @@ -951,7 +970,6 @@ void database_fixture::print_joint_market( const string& syma, const string& sym } } - int64_t database_fixture::get_balance( account_id_type account, asset_id_type a )const { return db.get_balance(account, a).amount.value; @@ -964,6 +982,14 @@ int64_t database_fixture::get_balance( const account_object& account, const asse namespace test { +void set_expiration( const database& db, transaction& tx ) +{ + const chain_parameters& params = db.get_global_properties().parameters; + tx.set_reference_block(db.head_block_id()); + tx.set_expiration( db.head_block_time() + fc::seconds( params.block_interval * (params.maintenance_skip_slots + 1) * 3 ) ); + return; +} + bool _push_block( database& db, const signed_block& b, uint32_t skip_flags /* = 0 */ ) { return db.push_block( b, skip_flags); diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index 328a3be6..5b00ec8f 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -116,11 +117,12 @@ using namespace graphene::db; #define INVOKE(test) ((struct test*)this)->test_method(); trx.clear() #define PREP_ACTOR(name) \ - fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); + fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); \ + public_key_type name ## _public_key = name ## _private_key.get_public_key(); #define ACTOR(name) \ PREP_ACTOR(name) \ - const auto& name = create_account(BOOST_PP_STRINGIZE(name), name ## _private_key.get_public_key()); \ + const auto& name = create_account(BOOST_PP_STRINGIZE(name), name ## _public_key); \ account_id_type name ## _id = name.id; (void)name ## _id; #define GET_ACTOR(name) \ @@ -189,18 +191,18 @@ struct database_fixture { ); void force_global_settle(const asset_object& what, const price& p); - void force_settle(account_id_type who, asset what) - { force_settle(who(db), what); } - void force_settle(const account_object& who, asset what); + operation_result force_settle(account_id_type who, asset what) + { return force_settle(who(db), what); } + operation_result force_settle(const account_object& who, asset what); void update_feed_producers(asset_id_type mia, flat_set producers) { update_feed_producers(mia(db), producers); } void update_feed_producers(const asset_object& mia, flat_set producers); void publish_feed(asset_id_type mia, account_id_type by, const price_feed& f) { publish_feed(mia(db), by(db), f); } void publish_feed(const asset_object& mia, const account_object& by, const price_feed& f); - void borrow(account_id_type who, asset what, asset collateral) - { borrow(who(db), what, collateral); } - void borrow(const account_object& who, asset what, asset collateral); + const call_order_object* borrow(account_id_type who, asset what, asset collateral) + { return borrow(who(db), what, collateral); } + const call_order_object* borrow(const account_object& who, asset what, asset collateral); void cover(account_id_type who, asset what, asset collateral_freed) { cover(who(db), what, collateral_freed); } void cover(const account_object& who, asset what, asset collateral_freed); @@ -249,6 +251,7 @@ struct database_fixture { const witness_object& create_witness(const account_object& owner, const fc::ecc::private_key& signing_private_key = generate_private_key("null_key")); uint64_t fund( const account_object& account, const asset& amount = asset(500000) ); + digest_type digest( const transaction& tx ); void sign( signed_transaction& trx, const fc::ecc::private_key& key ); const limit_order_object* create_sell_order( account_id_type user, const asset& amount, const asset& recv ); const limit_order_object* create_sell_order( const account_object& user, const asset& amount, const asset& recv ); @@ -271,6 +274,9 @@ struct database_fixture { }; namespace test { +/// set a reasonable expiration time for the transaction +void set_expiration( const database& db, transaction& tx ); + bool _push_block( database& db, const signed_block& b, uint32_t skip_flags = 0 ); processed_transaction _push_transaction( database& db, const signed_transaction& tx, uint32_t skip_flags = 0 ); } diff --git a/tests/generate_empty_blocks/CMakeLists.txt b/tests/generate_empty_blocks/CMakeLists.txt new file mode 100644 index 00000000..af53ee91 --- /dev/null +++ b/tests/generate_empty_blocks/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable( generate_empty_blocks main.cpp ) +if( UNIX AND NOT APPLE ) + set(rt_library rt ) +endif() + +target_link_libraries( generate_empty_blocks + PRIVATE graphene_app graphene_chain graphene_egenesis_none fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) + +install( TARGETS + generate_empty_blocks + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/tests/generate_empty_blocks/main.cpp b/tests/generate_empty_blocks/main.cpp new file mode 100644 index 00000000..d022cb94 --- /dev/null +++ b/tests/generate_empty_blocks/main.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2015, Cryptonomex, Inc. + * All rights reserved. + * + * This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and + * the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification, + * are permitted until September 8, 2015, provided that the following conditions are met: + * + * 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#ifndef WIN32 +#include +#endif + +using namespace graphene::app; +using namespace graphene::chain; +using namespace graphene::utilities; +using namespace std; +namespace bpo = boost::program_options; + +// hack: import create_example_genesis() even though it's a way, way +// specific internal detail +namespace graphene { namespace app { namespace detail { +genesis_state_type create_example_genesis(); +} } } // graphene::app::detail + +int main( int argc, char** argv ) +{ + try + { + bpo::options_description cli_options("Graphene empty blocks"); + cli_options.add_options() + ("help,h", "Print this help message and exit.") + ("data-dir", bpo::value()->default_value("empty_blocks_data_dir"), "Directory containing generator database") + ("genesis-json,g", bpo::value(), "File to read genesis state from") + ("genesis-time,t", bpo::value()->default_value(0), "Timestamp for genesis state (0=use value from file/example)") + ("num-blocks,n", bpo::value()->default_value(1000000), "Number of blocks to generate") + ("miss-rate,r", bpo::value()->default_value(3), "Percentage of blocks to miss") + ("verbose,v", "Enter verbose mode") + ; + + bpo::variables_map options; + try + { + boost::program_options::store( boost::program_options::parse_command_line(argc, argv, cli_options), options ); + } + catch (const boost::program_options::error& e) + { + std::cerr << "empty_blocks: error parsing command line: " << e.what() << "\n"; + return 1; + } + + if( options.count("help") ) + { + std::cout << cli_options << "\n"; + return 0; + } + + fc::path data_dir; + if( options.count("data-dir") ) + { + data_dir = options["data-dir"].as(); + if( data_dir.is_relative() ) + data_dir = fc::current_path() / data_dir; + } + + genesis_state_type genesis; + if( options.count("genesis-json") ) + { + fc::path genesis_json_filename = options["genesis-json"].as(); + std::cerr << "embed_genesis: Reading genesis from file " << genesis_json_filename.preferred_string() << "\n"; + std::string genesis_json; + read_file_contents( genesis_json_filename, genesis_json ); + genesis = fc::json::from_string( genesis_json ).as< genesis_state_type >(); + } + else + genesis = graphene::app::detail::create_example_genesis(); + uint32_t timestamp = options["genesis-time"].as(); + if( timestamp != 0 ) + { + genesis.initial_timestamp = fc::time_point_sec( timestamp ); + std::cerr << "embed_genesis: Genesis timestamp is " << genesis.initial_timestamp.sec_since_epoch() << " (from CLI)\n"; + } + else + std::cerr << "embed_genesis: Genesis timestamp is " << genesis.initial_timestamp.sec_since_epoch() << " (from state)\n"; + bool verbose = (options.count("verbose") != 0); + + uint32_t num_blocks = options["num-blocks"].as(); + uint32_t miss_rate = options["miss-rate"].as(); + + fc::ecc::private_key init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); + fc::ecc::private_key nathan_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); + + database db; + fc::path db_path = data_dir / "db"; + db.open(db_path, [&]() { return genesis; } ); + + uint32_t slot = 1; + uint32_t missed = 0; + + for( uint32_t i = 1; i < num_blocks; ++i ) + { + signed_block b = db.generate_block(db.get_slot_time(slot), db.get_scheduled_witness(slot), nathan_priv_key, database::skip_nothing); + FC_ASSERT( db.head_block_id() == b.id() ); + fc::sha256 h = b.digest(); + uint64_t rand = h._hash[0]; + slot = 1; + while(true) + { + if( (rand % 100) < miss_rate ) + { + slot++; + rand = (rand/100) ^ h._hash[slot&3]; + missed++; + } + else + break; + } + + witness_id_type prev_witness = b.witness; + witness_id_type cur_witness = db.get_scheduled_witness(1); + if( verbose ) + { + wdump( (prev_witness)(cur_witness) ); + } + else if( (i%10000) == 0 ) + { + std::cerr << "\rblock #" << i << " missed " << missed; + } + if( slot == 1 ) // can possibly get consecutive production if block missed + { + FC_ASSERT( cur_witness != prev_witness ); + } + } + std::cerr << "\n"; + db.close(); + } + catch ( const fc::exception& e ) + { + std::cout << e.to_detail_string() << "\n"; + return 1; + } + return 0; +} diff --git a/tests/intense/api_stress.py b/tests/intense/api_stress.py new file mode 100755 index 00000000..3aa1f2d3 --- /dev/null +++ b/tests/intense/api_stress.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +import json +import os +import random +import signal +import struct +import sys +import time + +try: + import asyncio +except ImportError: + print("asyncio module not found (try pip install asyncio, or upgrade to Python 3.4 or later)") + sys.exit(1) + +try: + import websockets +except ImportError: + print("websockets module not found (try pip install websockets)") + sys.exit(1) + +@asyncio.coroutine +def mainloop(): + ws = yield from websockets.connect('ws://localhost:8090/') + entropy = struct.unpack(" #include #include -#include #include #include @@ -204,7 +203,7 @@ BOOST_FIXTURE_TEST_CASE( update_account_keys, database_fixture ) trx.operations.push_back( update_op ); for( int i=0; i> 1; - witness_scheduler_rng rng( - // - - - - + - - - - 1 - - - - + - - - - 2 - - - - + - - - - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - ); - witness_scheduler scheduler; - vector< witness_id_type > witness_ids; - - witness_ids.reserve( num_witnesses ); - for( size_t i=0; i cur_round; - vector< witness_id_type > full_schedule; - // if we make the maximum witness count testable, - // we'll need to enlarge this. - std::bitset< 0x40 > witness_seen; - size_t total_blocks = 1000000; - - cur_round.reserve( num_witnesses ); - full_schedule.reserve( total_blocks ); - - // we assert so the test doesn't continue, which would - // corrupt memory - assert( num_witnesses <= witness_seen.size() ); - - while( full_schedule.size() < total_blocks ) - { - scheduler.produce_schedule( rng ); - witness_id_type wid = scheduler.consume_schedule(); - full_schedule.push_back( wid ); - cur_round.push_back( wid ); - if( cur_round.size() == num_witnesses ) - { - // check that the current round contains exactly 1 copy - // of each witness - witness_seen.reset(); - for( const witness_id_type& w : cur_round ) - { - uint64_t inst = w.instance.value; - BOOST_CHECK( !witness_seen.test( inst ) ); - assert( !witness_seen.test( inst ) ); - witness_seen.set( inst ); - } - cur_round.clear(); - } - } - - for( size_t i=0,m=full_schedule.size(); i(PUSH_TX( db, trx ).operation_results.front().get()); BOOST_CHECK_EQUAL(proposal.required_active_approvals.size(), 1); @@ -352,16 +352,17 @@ BOOST_AUTO_TEST_CASE( proposed_single_account ) proposal_update_operation pup; pup.proposal = proposal.id; pup.fee_paying_account = nathan.id; + BOOST_TEST_MESSAGE( "Updating the proposal to have nathan's authority" ); pup.active_approvals_to_add.insert(nathan.id); trx.operations = {pup}; - trx.sign( committee_key ); + sign( trx, committee_key ); //committee may not add nathan's approval. GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); pup.active_approvals_to_add.clear(); pup.active_approvals_to_add.insert(account_id_type()); trx.operations = {pup}; - trx.sign( committee_key ); + sign( trx, committee_key ); //committee has no stake in the transaction. GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); @@ -370,8 +371,8 @@ BOOST_AUTO_TEST_CASE( proposed_single_account ) pup.active_approvals_to_add.insert(nathan.id); trx.operations = {pup}; - trx.sign( nathan_key3 ); - trx.sign( nathan_key2 ); + sign( trx, nathan_key3 ); + sign( trx, nathan_key2 ); BOOST_CHECK_EQUAL(get_balance(nathan, core), nathan_start_balance.amount.value); PUSH_TX( db, trx ); @@ -398,33 +399,33 @@ BOOST_AUTO_TEST_CASE( committee_authority ) p.parameters.committee_proposal_review_period = fc::days(1).to_seconds(); }); - BOOST_TEST_MESSAGE( "transfering 100000 CORE to nathan, signing with committee key" ); + BOOST_TEST_MESSAGE( "transfering 100000 CORE to nathan, signing with committee key should fail because this requires it to be part of a proposal" ); transfer_operation top; top.to = nathan.id; top.amount = asset(100000); trx.operations.push_back(top); sign(trx, committee_key); - GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); + GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), graphene::chain::invalid_committee_approval ); - auto sign = [&] { trx.signatures.clear(); trx.sign(nathan_key); }; + auto _sign = [&] { trx.signatures.clear(); sign( trx, nathan_key ); }; proposal_create_operation pop; pop.proposed_ops.push_back({trx.operations.front()}); pop.expiration_time = db.head_block_time() + global_params.committee_proposal_review_period*2; pop.fee_paying_account = nathan.id; trx.operations = {pop}; - sign(); + _sign(); // The review period isn't set yet. Make sure it throws. GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx ), proposal_create_review_period_required ); pop.review_period_seconds = global_params.committee_proposal_review_period / 2; trx.operations.back() = pop; - sign(); + _sign(); // The review period is too short. Make sure it throws. GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx ), proposal_create_review_period_insufficient ); pop.review_period_seconds = global_params.committee_proposal_review_period; trx.operations.back() = pop; - sign(); + _sign(); proposal_object prop = db.get(PUSH_TX( db, trx ).operation_results.front().get()); BOOST_REQUIRE(db.find_object(prop.id)); @@ -456,16 +457,17 @@ BOOST_AUTO_TEST_CASE( committee_authority ) uop.key_approvals_to_add.emplace(6); */ trx.operations.push_back(uop); - trx.sign(committee_key); + sign( trx, committee_key ); db.push_transaction(trx); BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 0); BOOST_CHECK(db.get(prop.id).is_authorized_to_execute(db)); + trx.signatures.clear(); generate_blocks(*prop.review_period_time); uop.key_approvals_to_add.clear(); uop.key_approvals_to_add.insert(committee_key.get_public_key()); // was 7 trx.operations.back() = uop; - trx.sign( committee_key); + sign( trx, committee_key ); // Should throw because the transaction is now in review. GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); @@ -486,10 +488,12 @@ BOOST_FIXTURE_TEST_CASE( fired_committee_members, database_fixture ) nathan = &get_account("nathan"); flat_set committee_members; + /* db.modify(db.get_global_properties(), [](global_property_object& p) { // Turn the review period WAY down, so it doesn't take long to produce blocks to that point in simulated time. p.parameters.committee_proposal_review_period = fc::days(1).to_seconds(); }); + */ for( int i = 0; i < 15; ++i ) { @@ -497,11 +501,14 @@ BOOST_FIXTURE_TEST_CASE( fired_committee_members, database_fixture ) upgrade_to_lifetime_member(account); committee_members.insert(create_committee_member(account).vote_id); } + BOOST_REQUIRE_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000); //A proposal is created to give nathan lots more money. proposal_create_operation pop = proposal_create_operation::committee_proposal(db.get_global_properties().parameters, db.head_block_time()); pop.fee_paying_account = GRAPHENE_TEMP_ACCOUNT; - pop.expiration_time = db.head_block_time() + *pop.review_period_seconds * 3; + pop.expiration_time = db.head_block_time() + *pop.review_period_seconds + fc::days(1).to_seconds(); + ilog( "Creating proposal to give nathan money that expires: ${e}", ("e", pop.expiration_time ) ); + ilog( "The proposal has a review period of: ${r} sec", ("r",*pop.review_period_seconds) ); transfer_operation top; top.to = nathan->id; @@ -512,37 +519,35 @@ BOOST_FIXTURE_TEST_CASE( fired_committee_members, database_fixture ) proposal_id_type pid = prop.id; BOOST_CHECK(!pid(db).is_authorized_to_execute(db)); + ilog( "commitee member approves proposal" ); //committee key approves of the proposal. proposal_update_operation uop; uop.fee_paying_account = GRAPHENE_TEMP_ACCOUNT; uop.proposal = pid; uop.key_approvals_to_add.emplace(init_account_pub_key); - /* TODO: what should this really be? - uop.key_approvals_to_add.emplace(2); - uop.key_approvals_to_add.emplace(3); - uop.key_approvals_to_add.emplace(4); - uop.key_approvals_to_add.emplace(5); - uop.key_approvals_to_add.emplace(6); - uop.key_approvals_to_add.emplace(7); - uop.key_approvals_to_add.emplace(8); - uop.key_approvals_to_add.emplace(9); - */ trx.operations.back() = uop; - trx.sign(committee_key); + sign( trx, committee_key ); PUSH_TX( db, trx ); BOOST_CHECK(pid(db).is_authorized_to_execute(db)); + ilog( "Generating blocks for 2 days" ); + generate_block(); + BOOST_REQUIRE_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000); + generate_block(); + BOOST_REQUIRE_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000); //Time passes... the proposal is now in its review period. - generate_blocks(*pid(db).review_period_time); + //generate_blocks(*pid(db).review_period_time); + generate_blocks(db.head_block_time() + fc::days(2) ); + ilog( "head block time: ${t}", ("t",db.head_block_time())); fc::time_point_sec maintenance_time = db.get_dynamic_global_properties().next_maintenance_time; BOOST_CHECK_LT(maintenance_time.sec_since_epoch(), pid(db).expiration_time.sec_since_epoch()); //Yay! The proposal to give nathan more money is authorized. - BOOST_CHECK(pid(db).is_authorized_to_execute(db)); + BOOST_REQUIRE(pid(db).is_authorized_to_execute(db)); nathan = &get_account("nathan"); // no money yet - BOOST_CHECK_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000); + BOOST_REQUIRE_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000); { //Oh noes! Nathan votes for a whole new slate of committee_members! @@ -551,10 +556,11 @@ BOOST_FIXTURE_TEST_CASE( fired_committee_members, database_fixture ) op.new_options = nathan->options; op.new_options->votes = committee_members; trx.operations.push_back(op); - trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION); + set_expiration( db, trx ); PUSH_TX( db, trx, ~0 ); trx.operations.clear(); } + idump((get_balance(*nathan, asset_id_type()(db)))); // still no money BOOST_CHECK_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000); @@ -599,7 +605,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_two_accounts, database_fixture ) pop.fee_paying_account = nathan.get_id(); pop.expiration_time = db.head_block_time() + fc::days(1); trx.operations.push_back(pop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -616,7 +622,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_two_accounts, database_fixture ) uop.active_approvals_to_add.insert(nathan.get_id()); uop.fee_paying_account = nathan.get_id(); trx.operations.push_back(uop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); @@ -625,9 +631,9 @@ BOOST_FIXTURE_TEST_CASE( proposal_two_accounts, database_fixture ) uop.active_approvals_to_add = {dan.get_id()}; trx.operations.push_back(uop); - trx.sign(nathan_key); + sign( trx, nathan_key ); GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx ), fc::exception); - trx.sign(dan_key); + sign( trx, dan_key ); PUSH_TX( db, trx ); BOOST_CHECK(db.find_object(pid) == nullptr); @@ -661,7 +667,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture ) pop.fee_paying_account = nathan.get_id(); pop.expiration_time = db.head_block_time() + fc::days(1); trx.operations.push_back(pop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -677,7 +683,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture ) uop.proposal = prop.id; uop.active_approvals_to_add.insert(nathan.get_id()); trx.operations.push_back(uop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); BOOST_CHECK(!prop.is_authorized_to_execute(db)); @@ -685,7 +691,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture ) std::swap(uop.active_approvals_to_add, uop.active_approvals_to_remove); trx.operations.push_back(uop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); BOOST_CHECK(!prop.is_authorized_to_execute(db)); @@ -698,7 +704,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture ) dop.fee_paying_account = nathan.get_id(); dop.proposal = pid; trx.operations.push_back(dop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); BOOST_CHECK(db.find_object(pid) == nullptr); BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 100000); @@ -737,7 +743,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture ) pop.fee_paying_account = nathan.get_id(); pop.expiration_time = db.head_block_time() + fc::days(1); trx.operations.push_back(pop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -753,7 +759,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture ) uop.proposal = prop.id; uop.owner_approvals_to_add.insert(nathan.get_id()); trx.operations.push_back(uop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); BOOST_CHECK(!prop.is_authorized_to_execute(db)); @@ -761,7 +767,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture ) std::swap(uop.owner_approvals_to_add, uop.owner_approvals_to_remove); trx.operations.push_back(uop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); BOOST_CHECK(!prop.is_authorized_to_execute(db)); @@ -775,7 +781,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture ) dop.proposal = pid; dop.using_owner_authority = true; trx.operations.push_back(dop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); BOOST_CHECK(db.find_object(pid) == nullptr); BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 100000); @@ -814,7 +820,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture ) pop.fee_paying_account = nathan.get_id(); pop.expiration_time = db.head_block_time() + fc::days(1); trx.operations.push_back(pop); - trx.sign(nathan_key); + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -831,8 +837,9 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture ) uop.proposal = prop.id; uop.key_approvals_to_add.insert(dan.active.key_auths.begin()->first); trx.operations.push_back(uop); - trx.sign(nathan_key); - trx.sign(dan_key); + set_expiration( db, trx ); + sign( trx, nathan_key ); + sign( trx, dan_key ); PUSH_TX( db, trx ); trx.clear(); BOOST_CHECK(!prop.is_authorized_to_execute(db)); @@ -840,19 +847,19 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture ) std::swap(uop.key_approvals_to_add, uop.key_approvals_to_remove); trx.operations.push_back(uop); - trx.sign(nathan_key); - trx.sign(dan_key); + trx.expiration += fc::seconds(1); // Survive trx dupe check + sign( trx, nathan_key ); + sign( trx, dan_key ); PUSH_TX( db, trx ); trx.clear(); BOOST_CHECK(!prop.is_authorized_to_execute(db)); BOOST_CHECK_EQUAL(prop.available_key_approvals.size(), 0); std::swap(uop.key_approvals_to_add, uop.key_approvals_to_remove); - // Survive trx dupe check - trx.set_expiration(db.head_block_id(), 5); trx.operations.push_back(uop); - trx.sign(nathan_key); - trx.sign(dan_key); + trx.expiration += fc::seconds(1); // Survive trx dupe check + sign( trx, nathan_key ); + sign( trx, dan_key ); PUSH_TX( db, trx ); trx.clear(); BOOST_CHECK(!prop.is_authorized_to_execute(db)); @@ -861,7 +868,8 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture ) uop.key_approvals_to_add.clear(); uop.owner_approvals_to_add.insert(nathan.get_id()); trx.operations.push_back(uop); - trx.sign(nathan_key); + trx.expiration += fc::seconds(1); // Survive trx dupe check + sign( trx, nathan_key ); PUSH_TX( db, trx ); trx.clear(); BOOST_CHECK(db.find_object(pid) == nullptr); @@ -899,7 +907,6 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture ) int keys_to_create = 2*GRAPHENE_DEFAULT_MAX_AUTHORITY_MEMBERSHIP; vector private_keys; - tx = transaction(); private_keys.reserve( keys_to_create ); for( int i=0; i key_ids; @@ -944,10 +951,11 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture ) anon_create_op.name = generate_anon_acct_name(); tx.operations.push_back( anon_create_op ); + set_expiration( db, tx ); if( num_keys > max_authority_membership ) { - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, tx, ~0 ), fc::exception); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, tx, ~0 ), account_create_max_auth_exceeded ); } else { @@ -999,7 +1007,7 @@ BOOST_FIXTURE_TEST_CASE( bogus_signature, database_fixture ) trx.operations.push_back( xfer_op ); BOOST_TEST_MESSAGE( "Transfer signed by alice" ); - trx.sign(alice_key ); + sign( trx, alice_key ); flat_set active_set, owner_set; vector others; @@ -1014,15 +1022,15 @@ BOOST_FIXTURE_TEST_CASE( bogus_signature, database_fixture ) // Re-sign, now OK (sig is replaced) BOOST_TEST_MESSAGE( "Resign with Alice's Signature" ); trx.signatures.clear(); - trx.sign( alice_key ); + sign( trx, alice_key ); PUSH_TX( db, trx, skip ); trx.signatures.clear(); trx.operations.pop_back(); - trx.sign( alice_key ); - trx.sign( charlie_key ); + sign( trx, alice_key ); + sign( trx, charlie_key ); // Signed by third-party Charlie (irrelevant key, not in authority) - GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, skip ), fc::exception ); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, skip ), tx_irrelevant_sig ); } FC_LOG_AND_RETHROW() } @@ -1050,7 +1058,7 @@ BOOST_FIXTURE_TEST_CASE( voting_account, database_fixture ) op.new_options->votes = flat_set{nathan_committee_member(db).vote_id}; op.new_options->num_committee = 1; trx.operations.push_back(op); - trx.sign(nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -1061,13 +1069,13 @@ BOOST_FIXTURE_TEST_CASE( voting_account, database_fixture ) op.new_options->votes.insert(vikram_committee_member(db).vote_id); op.new_options->num_committee = 11; trx.operations.push_back(op); - trx.sign(vikram_private_key); + sign( trx, vikram_private_key ); // Fails because num_committee is larger than the cardinality of committee members being voted for GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); op.new_options->num_committee = 3; trx.operations = {op}; trx.signatures.clear(); - trx.sign(vikram_private_key); + sign( trx, vikram_private_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -1081,4 +1089,222 @@ BOOST_FIXTURE_TEST_CASE( voting_account, database_fixture ) vikram_committee_member) != db.get_global_properties().active_committee_members.end()); } FC_LOG_AND_RETHROW() } +/* + * Simple corporate accounts: + * + * Well Corp. Alice 50, Bob 50 T=60 + * Xylo Company Alice 30, Cindy 50 T=40 + * Yaya Inc. Bob 10, Dan 10, Edy 10 T=20 + * Zyzz Co. Dan 50 T=40 + * + * Complex corporate accounts: + * + * Mega Corp. Well 30, Yes 30 T=40 + * Nova Ltd. Alice 10, Well 10 T=20 + * Odle Intl. Dan 10, Yes 10, Zyzz 10 T=20 + * Poxx LLC Well 10, Xylo 10, Yes 20, Zyzz 20 T=40 + */ + +BOOST_FIXTURE_TEST_CASE( get_required_signatures_test, database_fixture ) +{ + try + { + ACTORS( + (alice)(bob)(cindy)(dan)(edy) + (mega)(nova)(odle)(poxx) + (well)(xylo)(yaya)(zyzz) + ); + + auto set_auth = [&]( + account_id_type aid, + const authority& auth + ) + { + signed_transaction tx; + account_update_operation op; + op.account = aid; + op.active = auth; + op.owner = auth; + tx.operations.push_back( op ); + set_expiration( db, tx ); + PUSH_TX( db, tx, database::skip_transaction_signatures | database::skip_authority_check ); + } ; + + auto get_active = [&]( + account_id_type aid + ) -> const authority* + { + return &(aid(db).active); + } ; + + auto get_owner = [&]( + account_id_type aid + ) -> const authority* + { + return &(aid(db).owner); + } ; + + auto chk = [&]( + const signed_transaction& tx, + flat_set available_keys, + set ref_set + ) -> bool + { + //wdump( (tx)(available_keys) ); + set result_set = tx.get_required_signatures( db.get_chain_id(), available_keys, get_active, get_owner ); + //wdump( (result_set)(ref_set) ); + return result_set == ref_set; + } ; + + set_auth( well_id, authority( 60, alice_id, 50, bob_id, 50 ) ); + set_auth( xylo_id, authority( 40, alice_id, 30, cindy_id, 50 ) ); + set_auth( yaya_id, authority( 20, bob_id, 10, dan_id, 10, edy_id, 10 ) ); + set_auth( zyzz_id, authority( 40, dan_id, 50 ) ); + + set_auth( mega_id, authority( 40, well_id, 30, yaya_id, 30 ) ); + set_auth( nova_id, authority( 20, alice_id, 10, well_id, 10 ) ); + set_auth( odle_id, authority( 20, dan_id, 10, yaya_id, 10, zyzz_id, 10 ) ); + set_auth( poxx_id, authority( 40, well_id, 10, xylo_id, 10, yaya_id, 20, zyzz_id, 20 ) ); + + signed_transaction tx; + flat_set< public_key_type > all_keys + { alice_public_key, bob_public_key, cindy_public_key, dan_public_key, edy_public_key }; + + tx.operations.push_back( transfer_operation() ); + transfer_operation& op = tx.operations.back().get(); + op.to = edy_id; + op.amount = asset(1); + + op.from = alice_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key } ) ); + op.from = bob_id; + BOOST_CHECK( chk( tx, all_keys, { bob_public_key } ) ); + op.from = well_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, bob_public_key } ) ); + op.from = xylo_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, cindy_public_key } ) ); + op.from = yaya_id; + BOOST_CHECK( chk( tx, all_keys, { bob_public_key, dan_public_key } ) ); + op.from = zyzz_id; + BOOST_CHECK( chk( tx, all_keys, { dan_public_key } ) ); + + op.from = mega_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, bob_public_key, dan_public_key } ) ); + op.from = nova_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, bob_public_key } ) ); + op.from = odle_id; + BOOST_CHECK( chk( tx, all_keys, { bob_public_key, dan_public_key } ) ); + op.from = poxx_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, bob_public_key, cindy_public_key, dan_public_key } ) ); + + // TODO: Add sigs to tx, then check + // TODO: Check removing sigs + // TODO: Accounts with mix of keys and accounts in their authority + // TODO: Tx with multiple ops requiring different sigs + } + catch(fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } +} + +/* + * Pathological case + * + * Roco(T=2) + * 1/ \2 + * Styx(T=2) Thud(T=1) + * 1/ \1 |1 + * Alice Bob Alice + */ + +BOOST_FIXTURE_TEST_CASE( nonminimal_sig_test, database_fixture ) +{ + try + { + ACTORS( + (alice)(bob) + (roco) + (styx)(thud) + ); + + auto set_auth = [&]( + account_id_type aid, + const authority& auth + ) + { + signed_transaction tx; + account_update_operation op; + op.account = aid; + op.active = auth; + op.owner = auth; + tx.operations.push_back( op ); + set_expiration( db, tx ); + PUSH_TX( db, tx, database::skip_transaction_signatures | database::skip_authority_check ); + } ; + + auto get_active = [&]( + account_id_type aid + ) -> const authority* + { + return &(aid(db).active); + } ; + + auto get_owner = [&]( + account_id_type aid + ) -> const authority* + { + return &(aid(db).owner); + } ; + + auto chk = [&]( + const signed_transaction& tx, + flat_set available_keys, + set ref_set + ) -> bool + { + //wdump( (tx)(available_keys) ); + set result_set = tx.get_required_signatures( db.get_chain_id(), available_keys, get_active, get_owner ); + //wdump( (result_set)(ref_set) ); + return result_set == ref_set; + } ; + + auto chk_min = [&]( + const signed_transaction& tx, + flat_set available_keys, + set ref_set + ) -> bool + { + //wdump( (tx)(available_keys) ); + set result_set = tx.minimize_required_signatures( db.get_chain_id(), available_keys, get_active, get_owner ); + //wdump( (result_set)(ref_set) ); + return result_set == ref_set; + } ; + + set_auth( roco_id, authority( 2, styx_id, 1, thud_id, 2 ) ); + set_auth( styx_id, authority( 2, alice_id, 1, bob_id, 1 ) ); + set_auth( thud_id, authority( 1, alice_id, 1 ) ); + + signed_transaction tx; + transfer_operation op; + op.from = roco_id; + op.to = bob_id; + op.amount = asset(1); + tx.operations.push_back( op ); + + BOOST_CHECK( chk( tx, { alice_public_key, bob_public_key }, { alice_public_key, bob_public_key } ) ); + BOOST_CHECK( chk_min( tx, { alice_public_key, bob_public_key }, { alice_public_key } ) ); + + GRAPHENE_REQUIRE_THROW( tx.verify_authority( db.get_chain_id(), get_active, get_owner ), fc::exception ); + sign( tx, alice_private_key ); + tx.verify_authority( db.get_chain_id(), get_active, get_owner ); + } + catch(fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/basic_tests.cpp b/tests/tests/basic_tests.cpp index 376c53fe..e016571b 100644 --- a/tests/tests/basic_tests.cpp +++ b/tests/tests/basic_tests.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -166,7 +165,6 @@ BOOST_AUTO_TEST_CASE( price_test ) BOOST_CHECK(dummy == dummy2); } - BOOST_AUTO_TEST_CASE( memo_test ) { try { memo_data m; @@ -186,138 +184,217 @@ BOOST_AUTO_TEST_CASE( memo_test ) BOOST_CHECK_EQUAL(m.get_message(receiver, sender.get_public_key()), "Hello, world!"); } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE( witness_rng_test_bits ) -{ - try - { - const uint64_t COUNT = 131072; - const uint64_t HASH_SIZE = 32; - string ref_bits = ""; - ref_bits.reserve( COUNT * HASH_SIZE ); - static const char seed_data[] = "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55"; - - for( uint64_t i=0; i> 0x08) & 0xFF) ); - enc.put( char((i >> 0x10) & 0xFF) ); - enc.put( char((i >> 0x18) & 0xFF) ); - enc.put( char((i >> 0x20) & 0xFF) ); - enc.put( char((i >> 0x28) & 0xFF) ); - enc.put( char((i >> 0x30) & 0xFF) ); - enc.put( char((i >> 0x38) & 0xFF) ); - - fc::sha256 result = enc.result(); - auto result_data = result.data(); - std::copy( result_data, result_data+HASH_SIZE, std::back_inserter( ref_bits ) ); - } - - fc::sha256 seed = fc::sha256::hash( string("") ); - // seed = sha256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - BOOST_CHECK( memcmp( seed.data(), seed_data, HASH_SIZE ) == 0 ); - - hash_ctr_rng< fc::sha256, 32 > test_rng(seed.data(), 0); - // python2 -c 'import hashlib; import struct; h = lambda x : hashlib.sha256(x).digest(); i = lambda x : struct.pack(" uint64_t - { - uint64_t result = 0; - uint64_t i = ref_get_bits_offset; - uint64_t mask = 1; - while( count > 0 ) - { - if( ref_bits[ i >> 3 ] & (1 << (i & 7)) ) - result |= mask; - mask += mask; - i++; - count--; - } - ref_get_bits_offset = i; - return result; - }; - - // use PRNG to decide between 0-64 bits - std::minstd_rand rng; - rng.seed( 9999 ); - std::uniform_int_distribution< uint16_t > bit_dist( 0, 64 ); - for( int i=0; i<10000; i++ ) - { - uint8_t bit_count = bit_dist( rng ); - uint64_t ref_bits = ref_get_bits( bit_count ); - uint64_t test_bits = test_rng.get_bits( bit_count ); - //std::cout << i << ": get(" << int(bit_count) << ") -> " << test_bits << " (expect " << ref_bits << ")\n"; - if( bit_count < 64 ) - { - BOOST_CHECK( ref_bits < (uint64_t( 1 ) << bit_count ) ); - BOOST_CHECK( test_bits < (uint64_t( 1 ) << bit_count ) ); - } - BOOST_CHECK( ref_bits == test_bits ); - if( ref_bits != test_bits ) - break; - } - - std::uniform_int_distribution< uint64_t > whole_dist( - 0, std::numeric_limits::max() ); - for( int i=0; i<10000; i++ ) - { - uint8_t bit_count = bit_dist( rng ); - uint64_t bound = whole_dist( rng ) & ((uint64_t(1) << bit_count) - 1); - //std::cout << "bound:" << bound << "\n"; - uint64_t rnum = test_rng( bound ); - //std::cout << "rnum:" << rnum << "\n"; - if( bound > 1 ) - { - BOOST_CHECK( rnum < bound ); - } - else - { - BOOST_CHECK( rnum == 0 ); - } - } - - } FC_LOG_AND_RETHROW() -} - - BOOST_AUTO_TEST_CASE( exceptions ) { GRAPHENE_CHECK_THROW(FC_THROW_EXCEPTION(balance_claim_invalid_claim_amount, "Etc"), balance_claim_invalid_claim_amount); } +BOOST_AUTO_TEST_CASE( scaled_precision ) +{ + const int64_t _k = 1000; + const int64_t _m = _k*_k; + const int64_t _g = _m*_k; + const int64_t _t = _g*_k; + const int64_t _p = _t*_k; + const int64_t _e = _p*_k; + + BOOST_CHECK( asset::scaled_precision( 0) == share_type( 1 ) ); + BOOST_CHECK( asset::scaled_precision( 1) == share_type( 10 ) ); + BOOST_CHECK( asset::scaled_precision( 2) == share_type( 100 ) ); + BOOST_CHECK( asset::scaled_precision( 3) == share_type( 1*_k) ); + BOOST_CHECK( asset::scaled_precision( 4) == share_type( 10*_k) ); + BOOST_CHECK( asset::scaled_precision( 5) == share_type( 100*_k) ); + BOOST_CHECK( asset::scaled_precision( 6) == share_type( 1*_m) ); + BOOST_CHECK( asset::scaled_precision( 7) == share_type( 10*_m) ); + BOOST_CHECK( asset::scaled_precision( 8) == share_type( 100*_m) ); + BOOST_CHECK( asset::scaled_precision( 9) == share_type( 1*_g) ); + BOOST_CHECK( asset::scaled_precision(10) == share_type( 10*_g) ); + BOOST_CHECK( asset::scaled_precision(11) == share_type( 100*_g) ); + BOOST_CHECK( asset::scaled_precision(12) == share_type( 1*_t) ); + BOOST_CHECK( asset::scaled_precision(13) == share_type( 10*_t) ); + BOOST_CHECK( asset::scaled_precision(14) == share_type( 100*_t) ); + BOOST_CHECK( asset::scaled_precision(15) == share_type( 1*_p) ); + BOOST_CHECK( asset::scaled_precision(16) == share_type( 10*_p) ); + BOOST_CHECK( asset::scaled_precision(17) == share_type( 100*_p) ); + BOOST_CHECK( asset::scaled_precision(18) == share_type( 1*_e) ); + GRAPHENE_CHECK_THROW( asset::scaled_precision(19), fc::exception ); +} + +BOOST_AUTO_TEST_CASE( merkle_root ) +{ + signed_block block; + vector tx; + vector t; + const uint32_t num_tx = 10; + + for( uint32_t i=0; i checksum_type + { return checksum_type::hash( digest ); }; + + auto d = []( const digest_type& left, const digest_type& right ) -> digest_type + { return digest_type::hash( std::make_pair( left, right ) ); }; + + BOOST_CHECK( block.calculate_merkle_root() == checksum_type() ); + + block.transactions.push_back( tx[0] ); + BOOST_CHECK( block.calculate_merkle_root() == + c(t[0]) + ); + + digest_type dA, dB, dC, dD, dE, dI, dJ, dK, dM, dN, dO; + + /* + A=d(0,1) + / \ + 0 1 + */ + + dA = d(t[0], t[1]); + + block.transactions.push_back( tx[1] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dA) ); + + /* + I=d(A,B) + / \ + A=d(0,1) B=2 + / \ / + 0 1 2 + */ + + dB = t[2]; + dI = d(dA, dB); + + block.transactions.push_back( tx[2] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dI) ); + + /* + I=d(A,B) + / \ + A=d(0,1) B=d(2,3) + / \ / \ + 0 1 2 3 + */ + + dB = d(t[2], t[3]); + dI = d(dA, dB); + + block.transactions.push_back( tx[3] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dI) ); + + /* + __M=d(I,J)__ + / \ + I=d(A,B) J=C + / \ / + A=d(0,1) B=d(2,3) C=4 + / \ / \ / + 0 1 2 3 4 + */ + + dC = t[4]; + dJ = dC; + dM = d(dI, dJ); + + block.transactions.push_back( tx[4] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dM) ); + + /* + __M=d(I,J)__ + / \ + I=d(A,B) J=C + / \ / + A=d(0,1) B=d(2,3) C=d(4,5) + / \ / \ / \ + 0 1 2 3 4 5 + */ + + dC = d(t[4], t[5]); + dJ = dC; + dM = d(dI, dJ); + + block.transactions.push_back( tx[5] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dM) ); + + /* + __M=d(I,J)__ + / \ + I=d(A,B) J=d(C,D) + / \ / \ + A=d(0,1) B=d(2,3) C=d(4,5) D=6 + / \ / \ / \ / + 0 1 2 3 4 5 6 + */ + + dD = t[6]; + dJ = d(dC, dD); + dM = d(dI, dJ); + + block.transactions.push_back( tx[6] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dM) ); + + /* + __M=d(I,J)__ + / \ + I=d(A,B) J=d(C,D) + / \ / \ + A=d(0,1) B=d(2,3) C=d(4,5) D=d(6,7) + / \ / \ / \ / \ + 0 1 2 3 4 5 6 7 + */ + + dD = d(t[6], t[7]); + dJ = d(dC, dD); + dM = d(dI, dJ); + + block.transactions.push_back( tx[7] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dM) ); + + /* + _____________O=d(M,N)______________ + / \ + __M=d(I,J)__ N=K + / \ / + I=d(A,B) J=d(C,D) K=E + / \ / \ / + A=d(0,1) B=d(2,3) C=d(4,5) D=d(6,7) E=8 + / \ / \ / \ / \ / + 0 1 2 3 4 5 6 7 8 + */ + + dE = t[8]; + dK = dE; + dN = dK; + dO = d(dM, dN); + + block.transactions.push_back( tx[8] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dO) ); + + /* + _____________O=d(M,N)______________ + / \ + __M=d(I,J)__ N=K + / \ / + I=d(A,B) J=d(C,D) K=E + / \ / \ / + A=d(0,1) B=d(2,3) C=d(4,5) D=d(6,7) E=d(8,9) + / \ / \ / \ / \ / \ + 0 1 2 3 4 5 6 7 8 9 + */ + + dE = d(t[8], t[9]); + dK = dE; + dN = dK; + dO = d(dM, dN); + + block.transactions.push_back( tx[9] ); + BOOST_CHECK( block.calculate_merkle_root() == c(dO) ); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 0dca6448..366f3d57 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -19,12 +19,13 @@ #include #include +#include #include +#include #include #include #include -#include #include @@ -33,6 +34,7 @@ #include "../common/database_fixture.hpp" using namespace graphene::chain; +using namespace graphene::chain::test; genesis_state_type make_genesis() { genesis_state_type genesis_state; @@ -124,23 +126,25 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) fc::temp_directory data_dir( graphene::utilities::temp_directory_path() ); signed_block b; - now += GRAPHENE_DEFAULT_BLOCK_INTERVAL; // TODO: Don't generate this here auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); + signed_block b200; { database db; db.open(data_dir.path(), make_genesis ); - b = db.generate_block(now, db.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + b = db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); - for( uint32_t i = 1; i < 200; ++i ) + // n.b. we generate GRAPHENE_MIN_UNDO_HISTORY+1 extra blocks which will be discarded on save + for( uint32_t i = 1; i < 200+GRAPHENE_MIN_UNDO_HISTORY+1; ++i ) { BOOST_CHECK( db.head_block_id() == b.id() ); witness_id_type prev_witness = b.witness; - now += db.block_interval(); - witness_id_type cur_witness = db.get_scheduled_witness(1).first; - BOOST_CHECK( cur_witness != prev_witness ); - b = db.generate_block(now, cur_witness, init_account_priv_key, database::skip_nothing); + witness_id_type cur_witness = db.get_scheduled_witness(1); + //BOOST_CHECK( cur_witness != prev_witness ); + b = db.generate_block(db.get_slot_time(1), cur_witness, init_account_priv_key, database::skip_nothing); BOOST_CHECK( b.witness == cur_witness ); + if( i == 199 ) + b200 = b; } db.close(); } @@ -148,14 +152,14 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) database db; db.open(data_dir.path(), []{return genesis_state_type();}); BOOST_CHECK_EQUAL( db.head_block_num(), 200 ); + b = b200; for( uint32_t i = 0; i < 200; ++i ) { BOOST_CHECK( db.head_block_id() == b.id() ); witness_id_type prev_witness = b.witness; - now += db.block_interval(); - witness_id_type cur_witness = db.get_scheduled_witness(1).first; - BOOST_CHECK( cur_witness != prev_witness ); - b = db.generate_block(now, cur_witness, init_account_priv_key, database::skip_nothing); + witness_id_type cur_witness = db.get_scheduled_witness(1); + //BOOST_CHECK( cur_witness != prev_witness ); + b = db.generate_block(db.get_slot_time(1), cur_witness, init_account_priv_key, database::skip_nothing); } BOOST_CHECK_EQUAL( db.head_block_num(), 400 ); } @@ -173,27 +177,37 @@ BOOST_AUTO_TEST_CASE( undo_block ) database db; db.open(data_dir.path(), make_genesis); fc::time_point_sec now( GRAPHENE_TESTING_GENESIS_TIMESTAMP ); + std::vector< time_point_sec > time_stack; auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); for( uint32_t i = 0; i < 5; ++i ) { - now += db.block_interval(); - auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, init_account_priv_key, database::skip_nothing ); + now = db.get_slot_time(1); + time_stack.push_back( now ); + auto b = db.generate_block( now, db.get_scheduled_witness( 1 ), init_account_priv_key, database::skip_nothing ); } BOOST_CHECK( db.head_block_num() == 5 ); + BOOST_CHECK( db.head_block_time() == now ); db.pop_block(); - now -= db.block_interval(); + time_stack.pop_back(); + now = time_stack.back(); BOOST_CHECK( db.head_block_num() == 4 ); + BOOST_CHECK( db.head_block_time() == now ); db.pop_block(); - now -= db.block_interval(); + time_stack.pop_back(); + now = time_stack.back(); BOOST_CHECK( db.head_block_num() == 3 ); + BOOST_CHECK( db.head_block_time() == now ); db.pop_block(); - now -= db.block_interval(); + time_stack.pop_back(); + now = time_stack.back(); BOOST_CHECK( db.head_block_num() == 2 ); + BOOST_CHECK( db.head_block_time() == now ); for( uint32_t i = 0; i < 5; ++i ) { - now += db.block_interval(); - auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, init_account_priv_key, database::skip_nothing ); + now = db.get_slot_time(1); + time_stack.push_back( now ); + auto b = db.generate_block( now, db.get_scheduled_witness( 1 ), init_account_priv_key, database::skip_nothing ); } BOOST_CHECK( db.head_block_num() == 7 ); } @@ -208,32 +222,31 @@ BOOST_AUTO_TEST_CASE( fork_blocks ) try { fc::temp_directory data_dir1( graphene::utilities::temp_directory_path() ); fc::temp_directory data_dir2( graphene::utilities::temp_directory_path() ); - fc::time_point_sec now( GRAPHENE_TESTING_GENESIS_TIMESTAMP ); database db1; db1.open(data_dir1.path(), make_genesis); database db2; db2.open(data_dir2.path(), make_genesis); + BOOST_CHECK( db1.get_chain_id() == db2.get_chain_id() ); auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); for( uint32_t i = 0; i < 10; ++i ) { - now += db1.block_interval(); - auto b = db1.generate_block(now, db1.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + auto b = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); try { PUSH_BLOCK( db2, b ); } FC_CAPTURE_AND_RETHROW( ("db2") ); } for( uint32_t i = 10; i < 13; ++i ) { - now += db1.block_interval(); - auto b = db1.generate_block(now, db1.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + auto b = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); } string db1_tip = db1.head_block_id().str(); + uint32_t next_slot = 3; for( uint32_t i = 13; i < 16; ++i ) { - now += db2.block_interval(); - auto b = db2.generate_block(now, db2.get_scheduled_witness(db2.get_slot_at_time(now)).first, init_account_priv_key, database::skip_nothing); + auto b = db2.generate_block(db2.get_slot_time(next_slot), db2.get_scheduled_witness(next_slot), init_account_priv_key, database::skip_nothing); + next_slot = 1; // notify both databases of the new block. // only db2 should switch to the new fork, db1 should not PUSH_BLOCK( db1, b ); @@ -247,12 +260,11 @@ BOOST_AUTO_TEST_CASE( fork_blocks ) BOOST_CHECK_EQUAL(db1.head_block_num(), 13); BOOST_CHECK_EQUAL(db2.head_block_num(), 13); { - now += db2.block_interval(); - auto b = db2.generate_block(now, db2.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + auto b = db2.generate_block(db2.get_slot_time(1), db2.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); good_block = b; b.transactions.emplace_back(signed_transaction()); b.transactions.back().operations.emplace_back(transfer_operation()); - b.sign(init_account_priv_key); + b.sign( init_account_priv_key ); BOOST_CHECK_EQUAL(b.block_num(), 14); GRAPHENE_CHECK_THROW(PUSH_BLOCK( db1, b ), fc::exception); } @@ -269,10 +281,91 @@ BOOST_AUTO_TEST_CASE( fork_blocks ) } } + +/** + * These test has been disabled, out of order blocks should result in the node getting disconnected. + * +BOOST_AUTO_TEST_CASE( fork_db_tests ) +{ + try { + fork_database fdb; + signed_block prev; + signed_block skipped_block; + for( uint32_t i = 0; i < 2000; ++i ) + { + signed_block b; + b.previous = prev.id(); + if( b.block_num() == 1800 ) + skipped_block = b; + else + fdb.push_block( b ); + prev = b; + } + auto head = fdb.head(); + FC_ASSERT( head && head->data.block_num() == 1799 ); + + fdb.push_block(skipped_block); + head = fdb.head(); + FC_ASSERT( head && head->data.block_num() == 2001, "", ("head",head->data.block_num()) ); + } FC_LOG_AND_RETHROW() +} +BOOST_AUTO_TEST_CASE( out_of_order_blocks ) +{ + try { + fc::temp_directory data_dir1( graphene::utilities::temp_directory_path() ); + fc::temp_directory data_dir2( graphene::utilities::temp_directory_path() ); + + database db1; + db1.open(data_dir1.path(), make_genesis); + database db2; + db2.open(data_dir2.path(), make_genesis); + BOOST_CHECK( db1.get_chain_id() == db2.get_chain_id() ); + + auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); + auto b1 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b2 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b3 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b4 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b5 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b6 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b7 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b8 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b9 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b10 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b11 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + auto b12 = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + BOOST_CHECK_EQUAL(db1.head_block_num(), 12); + BOOST_CHECK_EQUAL(db2.head_block_num(), 0); + PUSH_BLOCK( db2, b1 ); + BOOST_CHECK_EQUAL(db2.head_block_num(), 1); + PUSH_BLOCK( db2, b3 ); + BOOST_CHECK_EQUAL(db2.head_block_num(), 1); + PUSH_BLOCK( db2, b2 ); + BOOST_CHECK_EQUAL(db2.head_block_num(), 3); + PUSH_BLOCK( db2, b5 ); + PUSH_BLOCK( db2, b6 ); + PUSH_BLOCK( db2, b7 ); + BOOST_CHECK_EQUAL(db2.head_block_num(), 3); + PUSH_BLOCK( db2, b4 ); + BOOST_CHECK_EQUAL(db2.head_block_num(), 7); + PUSH_BLOCK( db2, b8 ); + BOOST_CHECK_EQUAL(db2.head_block_num(), 8); + PUSH_BLOCK( db2, b11 ); + PUSH_BLOCK( db2, b10 ); + PUSH_BLOCK( db2, b12 ); + BOOST_CHECK_EQUAL(db2.head_block_num(), 8); + PUSH_BLOCK( db2, b9 ); + BOOST_CHECK_EQUAL(db2.head_block_num(), 12); + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + */ + BOOST_AUTO_TEST_CASE( undo_pending ) { try { - fc::time_point_sec now(GRAPHENE_TESTING_GENESIS_TIMESTAMP); fc::temp_directory data_dir( graphene::utilities::temp_directory_path() ); { database db; @@ -287,32 +380,32 @@ BOOST_AUTO_TEST_CASE( undo_pending ) t.amount = asset( 10000000 ); { signed_transaction trx; - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); + trx.operations.push_back(t); PUSH_TX( db, trx, ~0 ); - now += db.block_interval(); - auto b = db.generate_block(now, db.get_scheduled_witness(1).first, init_account_priv_key, ~0); + auto b = db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1), init_account_priv_key, ~0); } signed_transaction trx; - trx.set_expiration( now + db.get_global_properties().parameters.maximum_time_until_expiration ); + set_expiration( db, trx ); account_id_type nathan_id = account_idx.get_next_id(); account_create_operation cop; cop.registrar = GRAPHENE_TEMP_ACCOUNT; cop.name = "nathan"; cop.owner = authority(1, init_account_pub_key, 1); + cop.active = cop.owner; trx.operations.push_back(cop); - //trx.sign( init_account_priv_key ); + //sign( trx, init_account_priv_key ); PUSH_TX( db, trx ); - now += db.block_interval(); - auto b = db.generate_block(now, db.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + auto b = db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); BOOST_CHECK(nathan_id(db).name == "nathan"); trx.clear(); - trx.set_expiration(db.head_block_time() + db.get_global_properties().parameters.maximum_time_until_expiration-1); + set_expiration( db, trx ); t.fee = asset(1); t.from = account_id_type(1); t.to = nathan_id; @@ -320,7 +413,7 @@ BOOST_AUTO_TEST_CASE( undo_pending ) trx.operations.push_back(t); db.push_transaction(trx, ~0); trx.clear(); - trx.set_expiration(db.head_block_time() + db.get_global_properties().parameters.maximum_time_until_expiration-2); + set_expiration( db, trx ); trx.operations.push_back(t); db.push_transaction(trx, ~0); @@ -343,44 +436,46 @@ BOOST_AUTO_TEST_CASE( switch_forks_undo_create ) db2; db1.open(dir1.path(), make_genesis); db2.open(dir2.path(), make_genesis); + BOOST_CHECK( db1.get_chain_id() == db2.get_chain_id() ); - fc::time_point_sec now( GRAPHENE_TESTING_GENESIS_TIMESTAMP ); auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); public_key_type init_account_pub_key = init_account_priv_key.get_public_key(); const graphene::db::index& account_idx = db1.get_index(protocol_ids, account_object_type); signed_transaction trx; - trx.set_expiration(now + db1.get_global_properties().parameters.maximum_time_until_expiration); + set_expiration( db1, trx ); account_id_type nathan_id = account_idx.get_next_id(); account_create_operation cop; cop.registrar = GRAPHENE_TEMP_ACCOUNT; cop.name = "nathan"; cop.owner = authority(1, init_account_pub_key, 1); + cop.active = cop.owner; trx.operations.push_back(cop); PUSH_TX( db1, trx ); + // generate blocks + // db1 : A + // db2 : B C D + auto aw = db1.get_global_properties().active_witnesses; - now += db1.block_interval(); - auto b = db1.generate_block(now, db1.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + auto b = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); BOOST_CHECK(nathan_id(db1).name == "nathan"); - now = fc::time_point_sec( GRAPHENE_TESTING_GENESIS_TIMESTAMP ); - now += db2.block_interval(); - b = db2.generate_block(now, db2.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + b = db2.generate_block(db2.get_slot_time(1), db2.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); db1.push_block(b); aw = db2.get_global_properties().active_witnesses; - now += db2.block_interval(); - b = db2.generate_block(now, db2.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + b = db2.generate_block(db2.get_slot_time(1), db2.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); db1.push_block(b); - - GRAPHENE_CHECK_THROW(nathan_id(db1), fc::exception); + GRAPHENE_REQUIRE_THROW(nathan_id(db2), fc::exception); + nathan_id(db1); /// it should be included in the pending state + db1.clear_pending(); // clear it so that we can verify it was properly removed from pending state. + GRAPHENE_REQUIRE_THROW(nathan_id(db1), fc::exception); PUSH_TX( db2, trx ); aw = db2.get_global_properties().active_witnesses; - now += db2.block_interval(); - b = db2.generate_block(now, db2.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + b = db2.generate_block(db2.get_slot_time(1), db2.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); db1.push_block(b); BOOST_CHECK(nathan_id(db1).name == "nathan"); @@ -394,13 +489,13 @@ BOOST_AUTO_TEST_CASE( switch_forks_undo_create ) BOOST_AUTO_TEST_CASE( duplicate_transactions ) { try { - fc::time_point_sec now( GRAPHENE_TESTING_GENESIS_TIMESTAMP ); fc::temp_directory dir1( graphene::utilities::temp_directory_path() ), dir2( graphene::utilities::temp_directory_path() ); database db1, db2; db1.open(dir1.path(), make_genesis); db2.open(dir2.path(), make_genesis); + BOOST_CHECK( db1.get_chain_id() == db2.get_chain_id() ); auto skip_sigs = database::skip_transaction_signatures | database::skip_authority_check; @@ -409,28 +504,28 @@ BOOST_AUTO_TEST_CASE( duplicate_transactions ) const graphene::db::index& account_idx = db1.get_index(protocol_ids, account_object_type); signed_transaction trx; - trx.set_expiration(db1.head_block_time() + fc::minutes(1)); + set_expiration( db1, trx ); account_id_type nathan_id = account_idx.get_next_id(); account_create_operation cop; cop.name = "nathan"; cop.owner = authority(1, init_account_pub_key, 1); + cop.active = cop.owner; trx.operations.push_back(cop); - trx.sign( init_account_priv_key ); + trx.sign( init_account_priv_key, db1.get_chain_id() ); PUSH_TX( db1, trx, skip_sigs ); trx = decltype(trx)(); - trx.set_expiration(db1.head_block_time() + fc::minutes(1)); + set_expiration( db1, trx ); transfer_operation t; t.to = nathan_id; t.amount = asset(500); trx.operations.push_back(t); - trx.sign( init_account_priv_key ); + trx.sign( init_account_priv_key, db1.get_chain_id() ); PUSH_TX( db1, trx, skip_sigs ); GRAPHENE_CHECK_THROW(PUSH_TX( db1, trx, skip_sigs ), fc::exception); - now += db1.block_interval(); - auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, init_account_priv_key, skip_sigs ); + auto b = db1.generate_block( db1.get_slot_time(1), db1.get_scheduled_witness( 1 ), init_account_priv_key, skip_sigs ); PUSH_BLOCK( db2, b, skip_sigs ); GRAPHENE_CHECK_THROW(PUSH_TX( db1, trx, skip_sigs ), fc::exception); @@ -446,13 +541,9 @@ BOOST_AUTO_TEST_CASE( duplicate_transactions ) BOOST_AUTO_TEST_CASE( tapos ) { try { - fc::time_point_sec now( GRAPHENE_TESTING_GENESIS_TIMESTAMP ); - fc::temp_directory dir1( graphene::utilities::temp_directory_path() ), - dir2( graphene::utilities::temp_directory_path() ); - database db1, - db2; + fc::temp_directory dir1( graphene::utilities::temp_directory_path() ); + database db1; db1.open(dir1.path(), make_genesis); - db2.open(dir2.path(), make_genesis); const account_object& init1 = *db1.get_index_type().indices().get().find("init1"); @@ -460,35 +551,35 @@ BOOST_AUTO_TEST_CASE( tapos ) public_key_type init_account_pub_key = init_account_priv_key.get_public_key(); const graphene::db::index& account_idx = db1.get_index(protocol_ids, account_object_type); - now += db1.block_interval(); - auto b = db1.generate_block(now, db1.get_scheduled_witness( 1 ).first, init_account_priv_key, database::skip_nothing); + auto b = db1.generate_block( db1.get_slot_time(1), db1.get_scheduled_witness( 1 ), init_account_priv_key, database::skip_nothing); signed_transaction trx; //This transaction must be in the next block after its reference, or it is invalid. - trx.set_expiration(db1.head_block_id(), 1); + trx.set_expiration( db1.head_block_time() ); //db1.get_slot_time(1) ); + trx.set_reference_block( db1.head_block_id() ); account_id_type nathan_id = account_idx.get_next_id(); account_create_operation cop; cop.registrar = init1.id; cop.name = "nathan"; cop.owner = authority(1, init_account_pub_key, 1); + cop.active = cop.owner; trx.operations.push_back(cop); - trx.sign(init_account_priv_key); + trx.sign( init_account_priv_key, db1.get_chain_id() ); db1.push_transaction(trx); - now += db1.block_interval(); - b = db1.generate_block(now, db1.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + b = db1.generate_block(db1.get_slot_time(1), db1.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); trx.clear(); transfer_operation t; t.to = nathan_id; t.amount = asset(50); trx.operations.push_back(t); - trx.sign(init_account_priv_key); + trx.sign( init_account_priv_key, db1.get_chain_id() ); //relative_expiration is 1, but ref block is 2 blocks old, so this should fail. GRAPHENE_REQUIRE_THROW(PUSH_TX( db1, trx, database::skip_transaction_signatures | database::skip_authority_check ), fc::exception); - trx.set_expiration(db1.head_block_id(), 2); + set_expiration( db1, trx ); trx.signatures.clear(); - trx.sign(init_account_priv_key); + trx.sign( init_account_priv_key, db1.get_chain_id() ); db1.push_transaction(trx, database::skip_transaction_signatures | database::skip_authority_check); } catch (fc::exception& e) { edump((e.to_detail_string())); @@ -496,6 +587,71 @@ BOOST_AUTO_TEST_CASE( tapos ) } } +BOOST_FIXTURE_TEST_CASE( optional_tapos, database_fixture ) +{ + try + { + ACTORS( (alice)(bob) ); + + generate_block(); + + BOOST_TEST_MESSAGE( "Create transaction" ); + + transfer( account_id_type(), alice_id, asset( 1000000 ) ); + transfer_operation op; + op.from = alice_id; + op.to = bob_id; + op.amount = asset( 1000 ); + signed_transaction tx; + tx.operations.push_back( op ); + set_expiration( db, tx ); + + BOOST_TEST_MESSAGE( "ref_block_num=0, ref_block_prefix=0" ); + + tx.ref_block_num = 0; + tx.ref_block_prefix = 0; + tx.signatures.clear(); + sign( tx, alice_private_key ); + PUSH_TX( db, tx ); + + BOOST_TEST_MESSAGE( "proper ref_block_num, ref_block_prefix" ); + + set_expiration( db, tx ); + tx.signatures.clear(); + sign( tx, alice_private_key ); + PUSH_TX( db, tx ); + + BOOST_TEST_MESSAGE( "ref_block_num=0, ref_block_prefix=12345678" ); + + tx.ref_block_num = 0; + tx.ref_block_prefix = 0x12345678; + tx.signatures.clear(); + sign( tx, alice_private_key ); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, tx ), fc::exception ); + + BOOST_TEST_MESSAGE( "ref_block_num=1, ref_block_prefix=12345678" ); + + tx.ref_block_num = 1; + tx.ref_block_prefix = 0x12345678; + tx.signatures.clear(); + sign( tx, alice_private_key ); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, tx ), fc::exception ); + + BOOST_TEST_MESSAGE( "ref_block_num=9999, ref_block_prefix=12345678" ); + + tx.ref_block_num = 9999; + tx.ref_block_prefix = 0x12345678; + tx.signatures.clear(); + sign( tx, alice_private_key ); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, tx ), fc::exception ); + } + catch (fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } +} + BOOST_FIXTURE_TEST_CASE( maintenance_interval, database_fixture ) { try { @@ -524,7 +680,6 @@ BOOST_FIXTURE_TEST_CASE( maintenance_interval, database_fixture ) initial_properties.parameters.maximum_transaction_size); BOOST_CHECK_EQUAL(db.get_dynamic_global_properties().next_maintenance_time.sec_since_epoch(), db.head_block_time().sec_since_epoch() + db.get_global_properties().parameters.block_interval); - // shuffling is now handled by the witness_schedule_object. BOOST_CHECK(db.get_global_properties().active_witnesses == initial_properties.active_witnesses); BOOST_CHECK(db.get_global_properties().active_committee_members == initial_properties.active_committee_members); @@ -597,7 +752,7 @@ BOOST_FIXTURE_TEST_CASE( double_sign_check, database_fixture ) ACTOR(bob); asset amount(1000); - trx.set_expiration(db.head_block_time() + fc::minutes(1)); + set_expiration( db, trx ); transfer_operation t; t.from = alice.id; t.to = bob.id; @@ -613,26 +768,26 @@ BOOST_FIXTURE_TEST_CASE( double_sign_check, database_fixture ) t.to = alice.id; t.amount = amount; trx.operations.push_back(t); - for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op); + for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op); trx.validate(); BOOST_TEST_MESSAGE( "Verify that not-signing causes an exception" ); GRAPHENE_REQUIRE_THROW( db.push_transaction(trx, 0), fc::exception ); BOOST_TEST_MESSAGE( "Verify that double-signing causes an exception" ); - trx.sign(bob_private_key); - trx.sign(bob_private_key); - GRAPHENE_REQUIRE_THROW( db.push_transaction(trx, 0), fc::exception ); + sign( trx, bob_private_key ); + sign( trx, bob_private_key ); + GRAPHENE_REQUIRE_THROW( db.push_transaction(trx, 0), tx_duplicate_sig ); BOOST_TEST_MESSAGE( "Verify that signing with an extra, unused key fails" ); trx.signatures.pop_back(); - trx.sign(generate_private_key("bogus")); - GRAPHENE_REQUIRE_THROW( db.push_transaction(trx, 0), fc::exception ); + sign( trx, generate_private_key("bogus" )); + GRAPHENE_REQUIRE_THROW( db.push_transaction(trx, 0), tx_irrelevant_sig ); BOOST_TEST_MESSAGE( "Verify that signing once with the proper key passes" ); trx.signatures.pop_back(); db.push_transaction(trx, 0); - trx.sign(bob_private_key); + sign( trx, bob_private_key ); } FC_LOG_AND_RETHROW() } @@ -664,15 +819,15 @@ BOOST_FIXTURE_TEST_CASE( change_block_interval, database_fixture ) get_account("init4").get_id(), get_account("init5").get_id(), get_account("init6").get_id(), get_account("init7").get_id()}; trx.operations.push_back(uop); - trx.sign(init_account_priv_key); + sign( trx, init_account_priv_key ); /* - trx.sign(get_account("init1").active.get_keys().front(),init_account_priv_key); - trx.sign(get_account("init2").active.get_keys().front(),init_account_priv_key); - trx.sign(get_account("init3").active.get_keys().front(),init_account_priv_key); - trx.sign(get_account("init4").active.get_keys().front(),init_account_priv_key); - trx.sign(get_account("init5").active.get_keys().front(),init_account_priv_key); - trx.sign(get_account("init6").active.get_keys().front(),init_account_priv_key); - trx.sign(get_account("init7").active.get_keys().front(),init_account_priv_key); + sign( trx, get_account("init1" ).active.get_keys().front(),init_account_priv_key); + sign( trx, get_account("init2" ).active.get_keys().front(),init_account_priv_key); + sign( trx, get_account("init3" ).active.get_keys().front(),init_account_priv_key); + sign( trx, get_account("init4" ).active.get_keys().front(),init_account_priv_key); + sign( trx, get_account("init5" ).active.get_keys().front(),init_account_priv_key); + sign( trx, get_account("init6" ).active.get_keys().front(),init_account_priv_key); + sign( trx, get_account("init7" ).active.get_keys().front(),init_account_priv_key); */ db.push_transaction(trx); BOOST_CHECK(proposal_id_type()(db).is_authorized_to_execute(db)); @@ -693,6 +848,7 @@ BOOST_FIXTURE_TEST_CASE( change_block_interval, database_fixture ) BOOST_TEST_MESSAGE( "Generating blocks until next maintenance interval" ); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); + generate_block(); // get the maintenance skip slots out of the way BOOST_TEST_MESSAGE( "Verify that the new block interval is 1 second" ); BOOST_CHECK_EQUAL(db.get_global_properties().parameters.block_interval, 1); @@ -703,138 +859,6 @@ BOOST_FIXTURE_TEST_CASE( change_block_interval, database_fixture ) BOOST_CHECK_EQUAL(db.head_block_time().sec_since_epoch() - past_time, 2); } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_force_settlement, 1 ) -BOOST_FIXTURE_TEST_CASE( unimp_force_settlement, database_fixture ) -{ - BOOST_FAIL( "TODO" ); - /* - try { - auto private_key = init_account_priv_key; - auto private_key = generate_private_key("committee"); ->>>>>>> short_refactor - account_id_type nathan_id = create_account("nathan").get_id(); - account_id_type shorter1_id = create_account("shorter1").get_id(); - account_id_type shorter2_id = create_account("shorter2").get_id(); - account_id_type shorter3_id = create_account("shorter3").get_id(); - transfer(account_id_type()(db), nathan_id(db), asset(100000000)); - transfer(account_id_type()(db), shorter1_id(db), asset(100000000)); - transfer(account_id_type()(db), shorter2_id(db), asset(100000000)); - transfer(account_id_type()(db), shorter3_id(db), asset(100000000)); - asset_id_type bit_usd = create_bitasset("BITUSD", GRAPHENE_TEMP_ACCOUNT, 0).get_id(); - { - asset_update_bitasset_operation op; - op.asset_to_update = bit_usd; - op.issuer = bit_usd(db).issuer; - op.new_options = bit_usd(db).bitasset_data(db).options; - op.new_options.maximum_force_settlement_volume = 9000; - trx.clear(); - trx.operations.push_back(op); - PUSH_TX( db, trx, ~0 ); - trx.clear(); - } - generate_block(); - - create_short(shorter1_id(db), asset(1000, bit_usd), asset(1000)); - create_sell_order(nathan_id(db), asset(1000), asset(1000, bit_usd)); - create_short(shorter2_id(db), asset(2000, bit_usd), asset(1999)); - create_sell_order(nathan_id(db), asset(1999), asset(2000, bit_usd)); - create_short(shorter3_id(db), asset(3000, bit_usd), asset(2990)); - create_sell_order(nathan_id(db), asset(2990), asset(3000, bit_usd)); - BOOST_CHECK_EQUAL(get_balance(nathan_id, bit_usd), 6000); - - transfer(nathan_id(db), account_id_type()(db), db.get_balance(nathan_id, asset_id_type())); - - { - asset_update_bitasset_operation uop; - uop.issuer = bit_usd(db).issuer; - uop.asset_to_update = bit_usd; - uop.new_options = bit_usd(db).bitasset_data(db).options; - uop.new_options.force_settlement_delay_sec = 100; - uop.new_options.force_settlement_offset_percent = 100; - trx.operations.push_back(uop); - } { - asset_update_feed_producers_operation uop; - uop.asset_to_update = bit_usd; - uop.issuer = bit_usd(db).issuer; - uop.new_feed_producers = {nathan_id}; - trx.operations.push_back(uop); - } { - asset_publish_feed_operation pop; - pop.asset_id = bit_usd; - pop.publisher = nathan_id; - price_feed feed; - feed.settlement_price = price(asset(1),asset(1, bit_usd)); - feed.call_limit = price::min(0, bit_usd); - feed.short_limit = price::min(bit_usd, 0); - pop.feed = feed; - trx.operations.push_back(pop); - } - trx.sign(key_id_type(),private_key); - PUSH_TX( db, trx ); - trx.clear(); - - asset_settle_operation sop; - sop.account = nathan_id; - sop.amount = asset(50, bit_usd); - trx.operations.push_back(sop); - REQUIRE_THROW_WITH_VALUE(sop, amount, asset(999999, bit_usd)); - trx.operations.back() = sop; - trx.sign(key_id_type(),private_key); - - //Partially settle a call - force_settlement_id_type settle_id = PUSH_TX( db, trx ).operation_results.front().get(); - trx.clear(); - call_order_id_type call_id = db.get_index_type().indices().get().begin()->id; - BOOST_CHECK_EQUAL(settle_id(db).balance.amount.value, 50); - BOOST_CHECK_EQUAL(call_id(db).debt.value, 3000); - BOOST_CHECK(settle_id(db).owner == nathan_id); - - generate_blocks(settle_id(db).settlement_date); - BOOST_CHECK(db.find(settle_id) == nullptr); - BOOST_CHECK_EQUAL(get_balance(nathan_id, asset_id_type()), 49); - BOOST_CHECK_EQUAL(call_id(db).debt.value, 2950); - - //Exactly settle a call - call_id = db.get_index_type().indices().get().begin()->id; - sop.amount.amount = 2000; - trx.operations.push_back(sop); - trx.sign(key_id_type(),private_key); - //Trx has expired by now. Make sure it throws. - GRAPHENE_CHECK_THROW(settle_id = PUSH_TX( db, trx ).operation_results.front().get(), fc::exception); - trx.set_expiration(db.head_block_time() + fc::minutes(1)); - trx.sign(key_id_type(),private_key); - settle_id = PUSH_TX( db, trx ).operation_results.front().get(); - trx.clear(); - - generate_blocks(settle_id(db).settlement_date); - BOOST_CHECK(db.find(settle_id) == nullptr); - BOOST_CHECK_EQUAL(get_balance(nathan_id, asset_id_type()), 2029); - BOOST_CHECK(db.find(call_id) == nullptr); - trx.set_expiration(db.head_block_time() + fc::minutes(1)); - - //Attempt to settle all existing asset - sop.amount = db.get_balance(nathan_id, bit_usd); - trx.operations.push_back(sop); - trx.sign(key_id_type(),private_key); - settle_id = PUSH_TX( db, trx ).operation_results.front().get(); - trx.clear(); - - generate_blocks(settle_id(db).settlement_date); - //We've hit the max force settlement. Can't settle more now. - BOOST_CHECK(db.find(settle_id)); - BOOST_CHECK_EQUAL(get_balance(nathan_id, asset_id_type()), 5344); - BOOST_CHECK(!db.get_index_type().indices().empty()); - - generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - //Now it's been another maintenance interval, so we should have some more settlement. - //I can't force settle all existing asset, but with a 90% limit, I get pretty close. - BOOST_CHECK(db.find(settle_id)); - BOOST_CHECK_EQUAL(get_balance(nathan_id, asset_id_type()), 5878); - BOOST_CHECK(!db.get_index_type().indices().empty()); -} FC_LOG_AND_RETHROW() -*/ -} - BOOST_FIXTURE_TEST_CASE( pop_block_twice, database_fixture ) { try @@ -881,32 +905,6 @@ BOOST_FIXTURE_TEST_CASE( pop_block_twice, database_fixture ) } } -BOOST_FIXTURE_TEST_CASE( witness_scheduler_missed_blocks, database_fixture ) -{ try { - db.get_near_witness_schedule(); - generate_block(); - auto near_schedule = db.get_near_witness_schedule(); - - std::for_each(near_schedule.begin(), near_schedule.end(), [&](witness_id_type id) { - generate_block(0); - BOOST_CHECK(db.get_dynamic_global_properties().current_witness == id); - }); - - near_schedule = db.get_near_witness_schedule(); - generate_block(0, init_account_priv_key, 2); - BOOST_CHECK(db.get_dynamic_global_properties().current_witness == near_schedule[2]); - - near_schedule.erase(near_schedule.begin(), near_schedule.begin() + 3); - auto new_schedule = db.get_near_witness_schedule(); - new_schedule.erase(new_schedule.end() - 3, new_schedule.end()); - BOOST_CHECK(new_schedule == near_schedule); - - std::for_each(near_schedule.begin(), near_schedule.end(), [&](witness_id_type id) { - generate_block(0); - BOOST_CHECK(db.get_dynamic_global_properties().current_witness == id); - }); -} FC_LOG_AND_RETHROW() } - BOOST_FIXTURE_TEST_CASE( rsf_missed_blocks, database_fixture ) { try @@ -915,7 +913,7 @@ BOOST_FIXTURE_TEST_CASE( rsf_missed_blocks, database_fixture ) auto rsf = [&]() -> string { - fc::uint128 rsf = db.get( witness_schedule_id_type() ).recent_slots_filled; + fc::uint128 rsf = db.get_dynamic_global_properties().recent_slots_filled; string result = ""; result.reserve(128); for( int i=0; i<128; i++ ) @@ -1031,4 +1029,227 @@ BOOST_FIXTURE_TEST_CASE( rsf_missed_blocks, database_fixture ) FC_LOG_AND_RETHROW() } +/** Disabled until it can be reimplemented +BOOST_FIXTURE_TEST_CASE( transaction_invalidated_in_cache, database_fixture ) +{ + try + { + ACTORS( (alice)(bob) ); + + auto generate_block = [&]( database& d ) -> signed_block + { + return d.generate_block(d.get_slot_time(1), d.get_scheduled_witness(1), init_account_priv_key, database::skip_nothing); + }; + + wdump( (db.fetch_block_by_number(1)) ); + wdump( (db.fetch_block_by_id( db.head_block_id() ) ) ); + + signed_block b1 = generate_block(db); + wdump( (db.fetch_block_by_number(1)) ); + wdump( (db.fetch_block_by_id( db.head_block_id() ) ) ); + + fc::temp_directory data_dir2( graphene::utilities::temp_directory_path() ); + + database db2; + db2.open(data_dir2.path(), make_genesis); + BOOST_CHECK( db.get_chain_id() == db2.get_chain_id() ); + + while( db2.head_block_num() < db.head_block_num() ) + { + wdump( (db.head_block_num()) (db2.head_block_num()) ); + optional< signed_block > b = db.fetch_block_by_number( db2.head_block_num()+1 ); + db2.push_block(*b, database::skip_witness_signature); + } + wlog("caught up db2 to db"); + BOOST_CHECK( db2.get( alice_id ).name == "alice" ); + BOOST_CHECK( db2.get( bob_id ).name == "bob" ); + + db2.push_block(generate_block(db)); + transfer( account_id_type(), alice_id, asset( 1000 ) ); + transfer( account_id_type(), bob_id, asset( 1000 ) ); + db2.push_block(generate_block(db)); + + BOOST_CHECK_EQUAL(db.get_balance(alice_id, asset_id_type()).amount.value, 1000); + BOOST_CHECK_EQUAL(db.get_balance( bob_id, asset_id_type()).amount.value, 1000); + BOOST_CHECK_EQUAL(db2.get_balance(alice_id, asset_id_type()).amount.value, 1000); + BOOST_CHECK_EQUAL(db2.get_balance( bob_id, asset_id_type()).amount.value, 1000); + + auto generate_and_send = [&]( int n ) + { + for( int i=0; i signed_transaction + { + signed_transaction tx; + transfer_operation xfer_op; + xfer_op.from = from; + xfer_op.to = to; + xfer_op.amount = asset( amount, asset_id_type() ); + xfer_op.fee = asset( 0, asset_id_type() ); + tx.operations.push_back( xfer_op ); + tx.set_expiration( db.head_block_time() + blocks_to_expire * db.get_global_properties().parameters.block_interval ); + if( from == alice_id ) + sign( tx, alice_private_key ); + else + sign( tx, bob_private_key ); + return tx; + }; + + signed_transaction tx = generate_xfer_tx( alice_id, bob_id, 1000, 2 ); + tx.set_expiration( db.head_block_time() + 2 * db.get_global_properties().parameters.block_interval ); + tx.signatures.clear(); + sign( tx, alice_private_key ); + // put the tx in db tx cache + PUSH_TX( db, tx ); + + BOOST_CHECK_EQUAL(db.get_balance(alice_id, asset_id_type()).amount.value, 0); + BOOST_CHECK_EQUAL(db.get_balance( bob_id, asset_id_type()).amount.value, 2000); + + // generate some blocks with db2, make tx expire in db's cache + generate_and_send(3); + + BOOST_CHECK_EQUAL(db.get_balance(alice_id, asset_id_type()).amount.value, 1000); + BOOST_CHECK_EQUAL(db.get_balance( bob_id, asset_id_type()).amount.value, 1000); + + // generate a block with db and ensure we don't somehow apply it + PUSH_BLOCK(db2, generate_block(db)); + BOOST_CHECK_EQUAL(db.get_balance(alice_id, asset_id_type()).amount.value, 1000); + BOOST_CHECK_EQUAL(db.get_balance( bob_id, asset_id_type()).amount.value, 1000); + + // now the tricky part... + // (A) Bob sends 1000 to Alice + // (B) Alice sends 2000 to Bob + // (C) Alice sends 500 to Bob + // + // We push AB, then receive a block containing C. + // we need to apply the block, then invalidate B in the cache. + // AB results in Alice having 0, Bob having 2000. + // C results in Alice having 500, Bob having 1500. + // + // This needs to occur while switching to a fork. + // + + signed_transaction tx_a = generate_xfer_tx( bob_id, alice_id, 1000, 3 ); + signed_transaction tx_b = generate_xfer_tx( alice_id, bob_id, 2000, 10 ); + signed_transaction tx_c = generate_xfer_tx( alice_id, bob_id, 500, 10 ); + + generate_block( db ); + + PUSH_TX( db, tx_a ); + BOOST_CHECK_EQUAL(db.get_balance(alice_id, asset_id_type()).amount.value, 2000); + BOOST_CHECK_EQUAL(db.get_balance( bob_id, asset_id_type()).amount.value, 0); + + PUSH_TX( db, tx_b ); + PUSH_TX( db2, tx_c ); + + BOOST_CHECK_EQUAL(db.get_balance(alice_id, asset_id_type()).amount.value, 0); + BOOST_CHECK_EQUAL(db.get_balance( bob_id, asset_id_type()).amount.value, 2000); + + BOOST_CHECK_EQUAL(db2.get_balance(alice_id, asset_id_type()).amount.value, 500); + BOOST_CHECK_EQUAL(db2.get_balance( bob_id, asset_id_type()).amount.value, 1500); + + // generate enough blocks on db2 to cause db to switch forks + generate_and_send(2); + + // db should invalidate B, but still be applying A, so the states don't agree + + BOOST_CHECK_EQUAL(db.get_balance(alice_id, asset_id_type()).amount.value, 1500); + BOOST_CHECK_EQUAL(db.get_balance( bob_id, asset_id_type()).amount.value, 500); + + BOOST_CHECK_EQUAL(db2.get_balance(alice_id, asset_id_type()).amount.value, 500); + BOOST_CHECK_EQUAL(db2.get_balance( bob_id, asset_id_type()).amount.value, 1500); + + // This will cause A to expire in db + generate_and_send(1); + + BOOST_CHECK_EQUAL(db.get_balance(alice_id, asset_id_type()).amount.value, 500); + BOOST_CHECK_EQUAL(db.get_balance( bob_id, asset_id_type()).amount.value, 1500); + + BOOST_CHECK_EQUAL(db2.get_balance(alice_id, asset_id_type()).amount.value, 500); + BOOST_CHECK_EQUAL(db2.get_balance( bob_id, asset_id_type()).amount.value, 1500); + + // Make sure we can generate and accept a plain old empty block on top of all this! + generate_and_send(1); + } + catch (fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } +} +*/ + +BOOST_AUTO_TEST_CASE( genesis_reserve_ids ) +{ + try + { + fc::time_point_sec now( GRAPHENE_TESTING_GENESIS_TIMESTAMP ); + fc::temp_directory data_dir( graphene::utilities::temp_directory_path() ); + + uint32_t num_special_accounts = 100; + uint32_t num_special_assets = 30; + + database db; + db.open( data_dir.path(), [&]() -> genesis_state_type + { + genesis_state_type genesis_state = make_genesis(); + genesis_state_type::initial_asset_type usd; + + usd.symbol = "USD"; + usd.issuer_name = "init0"; + usd.description = "federally floated"; + usd.precision = 4; + usd.max_supply = GRAPHENE_MAX_SHARE_SUPPLY; + usd.accumulated_fees = 0; + usd.is_bitasset = true; + + genesis_state.immutable_parameters.num_special_accounts = num_special_accounts; + genesis_state.immutable_parameters.num_special_assets = num_special_assets; + genesis_state.initial_assets.push_back( usd ); + + return genesis_state; + } ); + + const auto& acct_idx = db.get_index_type().indices().get(); + auto acct_itr = acct_idx.find("init0"); + BOOST_REQUIRE( acct_itr != acct_idx.end() ); + BOOST_CHECK( acct_itr->id == account_id_type( num_special_accounts ) ); + + const auto& asset_idx = db.get_index_type().indices().get(); + auto asset_itr = asset_idx.find("USD"); + BOOST_REQUIRE( asset_itr != asset_idx.end() ); + BOOST_CHECK( asset_itr->id == asset_id_type( num_special_assets ) ); + } + catch (fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_FIXTURE_TEST_CASE( miss_many_blocks, database_fixture ) +{ + try + { + generate_block(); + generate_block(); + generate_block(); + // miss 10 maintenance intervals + generate_blocks( db.get_dynamic_global_properties().next_maintenance_time + db.get_global_properties().parameters.maintenance_interval * 10, true ); + generate_block(); + generate_block(); + generate_block(); + } + catch (fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/confidential_tests.cpp b/tests/tests/confidential_tests.cpp new file mode 100644 index 00000000..729b25c3 --- /dev/null +++ b/tests/tests/confidential_tests.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015, Cryptonomex, Inc. + * All rights reserved. + * + * This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and + * the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification, + * are permitted until September 8, 2015, provided that the following conditions are met: + * + * 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include "../common/database_fixture.hpp" + +using namespace graphene::chain; + +BOOST_FIXTURE_TEST_SUITE( confidential_tests, database_fixture ) +BOOST_AUTO_TEST_CASE( confidential_test ) +{ try { + ACTORS( (dan)(nathan) ) + const asset_object& core = asset_id_type()(db); + + transfer(account_id_type()(db), dan, core.amount(1000000)); + + transfer_to_blind_operation to_blind; + to_blind.amount = core.amount(1000); + to_blind.from = dan.id; + + auto owner1_key = fc::ecc::private_key::generate(); + auto owner1_pub = owner1_key.get_public_key(); + auto owner2_key = fc::ecc::private_key::generate(); + auto owner2_pub = owner2_key.get_public_key(); + + blind_output out1, out2; + out1.owner = authority( 1, public_key_type(owner1_pub), 1 ); + out2.owner = authority( 1, public_key_type(owner2_pub), 1 ); + + + auto InB1 = fc::sha256::hash("InB1"); + auto InB2 = fc::sha256::hash("InB2"); + auto OutB = fc::sha256::hash("InB2"); + auto nonce1 = fc::sha256::hash("nonce"); + auto nonce2 = fc::sha256::hash("nonce2"); + + out1.commitment = fc::ecc::blind(InB1,250); + out1.range_proof = fc::ecc::range_proof_sign( 0, out1.commitment, InB1, nonce1, 0, 0, 250 ); + + out2.commitment = fc::ecc::blind(InB2,750); + out2.range_proof = fc::ecc::range_proof_sign( 0, out2.commitment, InB1, nonce2, 0, 0, 750 ); + + to_blind.blinding_factor = fc::ecc::blind_sum( {InB1,InB2}, 2 ); + to_blind.outputs = {out2,out1}; + + trx.operations = {to_blind}; + sign( trx, dan_private_key ); + db.push_transaction(trx); + trx.signatures.clear(); + + BOOST_TEST_MESSAGE( "Transfering from blind to blind with change address" ); + auto Out3B = fc::sha256::hash("Out3B"); + auto Out4B = fc::ecc::blind_sum( {InB2,Out3B}, 1 ); // add InB2 - Out3b + blind_output out3, out4; + out3.commitment = fc::ecc::blind(Out3B,300); + out3.range_proof = fc::ecc::range_proof_sign( 0, out3.commitment, InB1, nonce1, 0, 0, 300 ); + out4.commitment = fc::ecc::blind(Out4B,750-300-10); + out4.range_proof = fc::ecc::range_proof_sign( 0, out3.commitment, InB1, nonce1, 0, 0, 750-300-10 ); + + + blind_transfer_operation blind_tr; + blind_tr.fee = core.amount(10); + blind_tr.inputs.push_back( {out2.commitment, out2.owner} ); + blind_tr.outputs = {out3,out4}; + blind_tr.validate(); + trx.operations = {blind_tr}; + sign( trx, owner2_key ); + db.push_transaction(trx); + + BOOST_TEST_MESSAGE( "Attempting to double spend the same commitments" ); + blind_tr.fee = core.amount(11); + + Out4B = fc::ecc::blind_sum( {InB2,Out3B}, 1 ); // add InB2 - Out3b + out4.commitment = fc::ecc::blind(Out4B,750-300-11); + auto out4_amount = 750-300-10; + out4.range_proof = fc::ecc::range_proof_sign( 0, out3.commitment, InB1, nonce1, 0, 0, 750-300-11 ); + blind_tr.outputs = {out4,out3}; + trx.operations = {blind_tr}; + BOOST_REQUIRE_THROW( db.push_transaction(trx, ~0), graphene::chain::blind_transfer_unknown_commitment ); + + + BOOST_TEST_MESSAGE( "Transfering from blind to nathan public" ); + out4.commitment = fc::ecc::blind(Out4B,750-300-10); + + transfer_from_blind_operation from_blind; + from_blind.fee = core.amount(10); + from_blind.to = nathan.id; + from_blind.amount = core.amount( out4_amount - 10 ); + from_blind.blinding_factor = Out4B; + from_blind.inputs.push_back( {out4.commitment, out4.owner} ); + trx.operations = {from_blind}; + trx.signatures.clear(); + db.push_transaction(trx); + + BOOST_REQUIRE_EQUAL( get_balance( nathan, core ), 750-300-10-10 ); + +} FC_LOG_AND_RETHROW() } + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/fee_tests.cpp b/tests/tests/fee_tests.cpp index f3ebf58c..777dfa2e 100644 --- a/tests/tests/fee_tests.cpp +++ b/tests/tests/fee_tests.cpp @@ -16,6 +16,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include @@ -23,50 +25,167 @@ #include "../common/database_fixture.hpp" using namespace graphene::chain; +using namespace graphene::chain::test; BOOST_FIXTURE_TEST_SUITE( fee_tests, database_fixture ) +BOOST_AUTO_TEST_CASE( nonzero_fee_test ) +{ + try + { + ACTORS((alice)(bob)); + + const share_type prec = asset::scaled_precision( asset_id_type()(db).precision ); + + // Return number of core shares (times precision) + auto _core = [&]( int64_t x ) -> asset + { return asset( x*prec ); }; + + transfer( committee_account, alice_id, _core(1000000) ); + + // make sure the database requires our fee to be nonzero + enable_fees(); + + signed_transaction tx; + transfer_operation xfer_op; + xfer_op.from = alice_id; + xfer_op.to = bob_id; + xfer_op.amount = _core(1000); + xfer_op.fee = _core(0); + tx.operations.push_back( xfer_op ); + set_expiration( db, tx ); + sign( tx, alice_private_key ); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, tx ), insufficient_fee ); + } + catch( const fc::exception& e ) + { + edump((e.to_detail_string())); + throw; + } +} + + +/////////////////////////////////////////////////////////////// +// cashback_test infrastructure // +/////////////////////////////////////////////////////////////// + +#define CHECK_BALANCE( actor_name, amount ) \ + BOOST_CHECK_EQUAL( get_balance( actor_name ## _id, asset_id_type() ), amount ) + +#define CHECK_VESTED_CASHBACK( actor_name, amount ) \ + BOOST_CHECK_EQUAL( actor_name ## _id(db).statistics(db).pending_vested_fees.value, amount ) + +#define CHECK_UNVESTED_CASHBACK( actor_name, amount ) \ + BOOST_CHECK_EQUAL( actor_name ## _id(db).statistics(db).pending_fees.value, amount ) + +#define GET_CASHBACK_BALANCE( account ) \ + ( (account.cashback_vb.valid()) \ + ? account.cashback_balance(db).balance.amount.value \ + : 0 ) + +#define CHECK_CASHBACK_VBO( actor_name, _amount ) \ + BOOST_CHECK_EQUAL( GET_CASHBACK_BALANCE( actor_name ## _id(db) ), _amount ) + +#define P100 GRAPHENE_100_PERCENT +#define P1 GRAPHENE_1_PERCENT + +uint64_t pct( uint64_t percentage, uint64_t val ) +{ + fc::uint128_t x = percentage; + x *= val; + x /= GRAPHENE_100_PERCENT; + return x.to_uint64(); +} + +uint64_t pct( uint64_t percentage0, uint64_t percentage1, uint64_t val ) +{ + return pct( percentage1, pct( percentage0, val ) ); +} + +uint64_t pct( uint64_t percentage0, uint64_t percentage1, uint64_t percentage2, uint64_t val ) +{ + return pct( percentage2, pct( percentage1, pct( percentage0, val ) ) ); +} + +struct actor_audit +{ + int64_t b0 = 0; // starting balance parameter + int64_t bal = 0; // balance should be this + int64_t ubal = 0; // unvested balance (in VBO) should be this + int64_t ucb = 0; // unvested cashback in account_statistics should be this + int64_t vcb = 0; // vested cashback in account_statistics should be this + int64_t ref_pct = 0; // referrer percentage should be this +}; BOOST_AUTO_TEST_CASE( cashback_test ) { try { - wlog(""); /* Account Structure used in this test * * * * /-----------------\ /-------------------\ * - * | life (Lifetime) | | reggie (Lifetime) | * + * | life (Lifetime) | | rog (Lifetime) | * * \-----------------/ \-------------------/ * - * | Refers & | Refers | Registers | Registers * - * v Registers v v | * + * | Ref&Reg | Refers | Registers | Registers * + * | | 75 | 25 | * + * v v v | * * /----------------\ /----------------\ | * * | ann (Annual) | | dumy (basic) | | * * \----------------/ \----------------/ |-------------. * - * | Refers L--------------------------------. | | * - * v Refers v v | * + * 80 | Refers L--------------------------------. | | * + * v Refers 80 v v 20 | * * /----------------\ /----------------\ | * * | scud (basic) |<------------------------| stud (basic) | | * - * \----------------/ Registers | (Upgrades to | | * + * \----------------/ 20 Registers | (Upgrades to | | 5 * * | Lifetime) | v * * \----------------/ /--------------\ * * L------->| pleb (Basic) | * - * Refers \--------------/ * + * 95 Refers \--------------/ * * * + * Fee distribution chains (80-20 referral/net split, 50-30 referrer/LTM split) * + * life : 80% -> life, 20% -> net * + * rog: 80% -> rog, 20% -> net * + * ann (before upg): 80% -> life, 20% -> net * + * ann (after upg): 80% * 5/8 -> ann, 80% * 3/8 -> life, 20% -> net * + * stud (before upg): 80% * 5/8 -> ann, 80% * 3/8 -> life, 20% * 80% -> rog, * + * 20% -> net * + * stud (after upg): 80% -> stud, 20% -> net * + * dumy : 75% * 80% -> life, 25% * 80% -> rog, 20% -> net * + * scud : 80% * 5/8 -> ann, 80% * 3/8 -> life, 20% * 80% -> stud, 20% -> net * + * pleb : 95% * 80% -> stud, 5% * 80% -> rog, 20% -> net * */ + + BOOST_TEST_MESSAGE("Creating actors"); + ACTOR(life); - ACTOR(reggie); + ACTOR(rog); PREP_ACTOR(ann); PREP_ACTOR(scud); PREP_ACTOR(dumy); PREP_ACTOR(stud); PREP_ACTOR(pleb); - transfer(account_id_type(), life_id, asset(500000*CORE)); - transfer(account_id_type(), reggie_id, asset(500000*CORE)); + + account_id_type ann_id, scud_id, dumy_id, stud_id, pleb_id; + actor_audit alife, arog, aann, ascud, adumy, astud, apleb; + + alife.b0 = 100000000; + arog.b0 = 100000000; + aann.b0 = 1000000; + astud.b0 = 1000000; + astud.ref_pct = 80 * GRAPHENE_1_PERCENT; + ascud.ref_pct = 80 * GRAPHENE_1_PERCENT; + adumy.ref_pct = 75 * GRAPHENE_1_PERCENT; + apleb.ref_pct = 95 * GRAPHENE_1_PERCENT; + + transfer(account_id_type(), life_id, asset(alife.b0)); + alife.bal += alife.b0; + transfer(account_id_type(), rog_id, asset(arog.b0)); + arog.bal += arog.b0; upgrade_to_lifetime_member(life_id); - upgrade_to_lifetime_member(reggie_id); - enable_fees(); + upgrade_to_lifetime_member(rog_id); + + BOOST_TEST_MESSAGE("Enable fees"); const auto& fees = db.get_global_properties().parameters.current_fees; #define CustomRegisterActor(actor_name, registrar_name, referrer_name, referrer_rate) \ - account_id_type actor_name ## _id; \ { \ account_create_operation op; \ op.registrar = registrar_name ## _id; \ @@ -76,61 +195,264 @@ BOOST_AUTO_TEST_CASE( cashback_test ) op.options.memo_key = actor_name ## _private_key.get_public_key(); \ op.active = authority(1, public_key_type(actor_name ## _private_key.get_public_key()), 1); \ op.owner = op.active; \ - op.fee = fees->calculate_fee(op); \ - idump((op.fee)); \ + op.fee = fees->calculate_fee(op); \ trx.operations = {op}; \ - trx.sign( registrar_name ## _private_key); \ + sign( trx, registrar_name ## _private_key ); \ actor_name ## _id = PUSH_TX( db, trx ).operation_results.front().get(); \ trx.clear(); \ } +#define CustomAuditActor(actor_name) \ + if( actor_name ## _id != account_id_type() ) \ + { \ + CHECK_BALANCE( actor_name, a ## actor_name.bal ); \ + CHECK_VESTED_CASHBACK( actor_name, a ## actor_name.vcb ); \ + CHECK_UNVESTED_CASHBACK( actor_name, a ## actor_name.ucb ); \ + CHECK_CASHBACK_VBO( actor_name, a ## actor_name.ubal ); \ + } - CustomRegisterActor(ann, life, life, 75); +#define CustomAudit() \ + { \ + CustomAuditActor( life ); \ + CustomAuditActor( rog ); \ + CustomAuditActor( ann ); \ + CustomAuditActor( stud ); \ + CustomAuditActor( dumy ); \ + CustomAuditActor( scud ); \ + CustomAuditActor( pleb ); \ + } - transfer(life_id, ann_id, asset(3000*CORE)); - upgrade_to_annual_member(ann_id); + int64_t reg_fee = fees->get< account_create_operation >().premium_fee; + int64_t xfer_fee = fees->get< transfer_operation >().fee; + int64_t upg_an_fee = fees->get< account_upgrade_operation >().membership_annual_fee; + int64_t upg_lt_fee = fees->get< account_upgrade_operation >().membership_lifetime_fee; + // all percentages here are cut from whole pie! + uint64_t network_pct = 20 * P1; + uint64_t lt_pct = 375 * P100 / 1000; - CustomRegisterActor(dumy, reggie, life, 75); - CustomRegisterActor(stud, reggie, ann, 80); + BOOST_TEST_MESSAGE("Register and upgrade Ann"); + { + CustomRegisterActor(ann, life, life, 75); + alife.vcb += reg_fee; alife.bal += -reg_fee; + CustomAudit(); + + transfer(life_id, ann_id, asset(aann.b0)); + alife.vcb += xfer_fee; alife.bal += -xfer_fee -aann.b0; aann.bal += aann.b0; + CustomAudit(); + + upgrade_to_annual_member(ann_id); + aann.ucb += upg_an_fee; aann.bal += -upg_an_fee; + + // audit distribution of fees from Ann + alife.ubal += pct( P100-network_pct, aann.ucb ); + alife.bal += pct( P100-network_pct, aann.vcb ); + aann.ucb = 0; aann.vcb = 0; + CustomAudit(); + } + + BOOST_TEST_MESSAGE("Register dumy and stud"); + CustomRegisterActor(dumy, rog, life, 75); + arog.vcb += reg_fee; arog.bal += -reg_fee; + CustomAudit(); + + CustomRegisterActor(stud, rog, ann, 80); + arog.vcb += reg_fee; arog.bal += -reg_fee; + CustomAudit(); + + BOOST_TEST_MESSAGE("Upgrade stud to lifetime member"); + + transfer(life_id, stud_id, asset(astud.b0)); + alife.vcb += xfer_fee; alife.bal += -astud.b0 -xfer_fee; astud.bal += astud.b0; + CustomAudit(); - transfer(life_id, stud_id, asset(20000*CORE)); upgrade_to_lifetime_member(stud_id); + astud.ucb += upg_lt_fee; astud.bal -= upg_lt_fee; + +/* +network_cut: 20000 +referrer_cut: 40000 -> ann +registrar_cut: 10000 -> rog +lifetime_cut: 30000 -> life + +NET : net +LTM : net' ltm +REF : net' ltm' ref +REG : net' ltm' ref' +*/ + + // audit distribution of fees from stud + alife.ubal += pct( P100-network_pct, lt_pct, astud.ucb ); + aann.ubal += pct( P100-network_pct, P100-lt_pct, astud.ref_pct, astud.ucb ); + arog.ubal += pct( P100-network_pct, P100-lt_pct, P100-astud.ref_pct, astud.ucb ); + astud.ucb = 0; + CustomAudit(); + + BOOST_TEST_MESSAGE("Register pleb and scud"); + + CustomRegisterActor(pleb, rog, stud, 95); + arog.vcb += reg_fee; arog.bal += -reg_fee; + CustomAudit(); - CustomRegisterActor(pleb, reggie, stud, 95); CustomRegisterActor(scud, stud, ann, 80); + astud.vcb += reg_fee; astud.bal += -reg_fee; + CustomAudit(); + + generate_block(); + + BOOST_TEST_MESSAGE("Wait for maintenance interval"); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - enable_fees(); + // audit distribution of fees from life + alife.ubal += pct( P100-network_pct, alife.ucb +alife.vcb ); + alife.ucb = 0; alife.vcb = 0; - BOOST_CHECK_EQUAL(life_id(db).cashback_balance(db).balance.amount.value, 78000); - BOOST_CHECK_EQUAL(reggie_id(db).cashback_balance(db).balance.amount.value, 34000); - BOOST_CHECK_EQUAL(ann_id(db).cashback_balance(db).balance.amount.value, 40000); - BOOST_CHECK_EQUAL(stud_id(db).cashback_balance(db).balance.amount.value, 8000); + // audit distribution of fees from rog + arog.ubal += pct( P100-network_pct, arog.ucb + arog.vcb ); + arog.ucb = 0; arog.vcb = 0; - transfer(stud_id, scud_id, asset(5*CORE)); - transfer(scud_id, pleb_id, asset(4*CORE)); - transfer(pleb_id, dumy_id, asset(3*CORE)); - transfer(dumy_id, reggie_id, asset(2*CORE)); + // audit distribution of fees from ann + alife.ubal += pct( P100-network_pct, lt_pct, aann.ucb+aann.vcb ); + aann.ubal += pct( P100-network_pct, P100-lt_pct, aann.ref_pct, aann.ucb+aann.vcb ); + alife.ubal += pct( P100-network_pct, P100-lt_pct, P100-aann.ref_pct, aann.ucb+aann.vcb ); + aann.ucb = 0; aann.vcb = 0; + + // audit distribution of fees from stud + astud.ubal += pct( P100-network_pct, astud.ucb+astud.vcb ); + astud.ucb = 0; astud.vcb = 0; + + // audit distribution of fees from dumy + alife.ubal += pct( P100-network_pct, lt_pct, adumy.ucb+adumy.vcb ); + alife.ubal += pct( P100-network_pct, P100-lt_pct, adumy.ref_pct, adumy.ucb+adumy.vcb ); + arog.ubal += pct( P100-network_pct, P100-lt_pct, P100-adumy.ref_pct, adumy.ucb+adumy.vcb ); + adumy.ucb = 0; adumy.vcb = 0; + + // audit distribution of fees from scud + alife.ubal += pct( P100-network_pct, lt_pct, ascud.ucb+ascud.vcb ); + aann.ubal += pct( P100-network_pct, P100-lt_pct, ascud.ref_pct, ascud.ucb+ascud.vcb ); + astud.ubal += pct( P100-network_pct, P100-lt_pct, P100-ascud.ref_pct, ascud.ucb+ascud.vcb ); + ascud.ucb = 0; ascud.vcb = 0; + + // audit distribution of fees from pleb + astud.ubal += pct( P100-network_pct, lt_pct, apleb.ucb+apleb.vcb ); + astud.ubal += pct( P100-network_pct, P100-lt_pct, apleb.ref_pct, apleb.ucb+apleb.vcb ); + arog.ubal += pct( P100-network_pct, P100-lt_pct, P100-apleb.ref_pct, apleb.ucb+apleb.vcb ); + apleb.ucb = 0; apleb.vcb = 0; + + CustomAudit(); + + BOOST_TEST_MESSAGE("Doing some transfers"); + + transfer(stud_id, scud_id, asset(500000)); + astud.bal += -500000-xfer_fee; astud.vcb += xfer_fee; ascud.bal += 500000; + CustomAudit(); + + transfer(scud_id, pleb_id, asset(400000)); + ascud.bal += -400000-xfer_fee; ascud.vcb += xfer_fee; apleb.bal += 400000; + CustomAudit(); + + transfer(pleb_id, dumy_id, asset(300000)); + apleb.bal += -300000-xfer_fee; apleb.vcb += xfer_fee; adumy.bal += 300000; + CustomAudit(); + + transfer(dumy_id, rog_id, asset(200000)); + adumy.bal += -200000-xfer_fee; adumy.vcb += xfer_fee; arog.bal += 200000; + CustomAudit(); + + BOOST_TEST_MESSAGE("Waiting for maintenance time"); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - BOOST_CHECK_EQUAL(life_id(db).cashback_balance(db).balance.amount.value, 87750); - BOOST_CHECK_EQUAL(reggie_id(db).cashback_balance(db).balance.amount.value, 35500); - BOOST_CHECK_EQUAL(ann_id(db).cashback_balance(db).balance.amount.value, 44000); - BOOST_CHECK_EQUAL(stud_id(db).cashback_balance(db).balance.amount.value, 24750); + // audit distribution of fees from life + alife.ubal += pct( P100-network_pct, alife.ucb +alife.vcb ); + alife.ucb = 0; alife.vcb = 0; + + // audit distribution of fees from rog + arog.ubal += pct( P100-network_pct, arog.ucb + arog.vcb ); + arog.ucb = 0; arog.vcb = 0; + + // audit distribution of fees from ann + alife.ubal += pct( P100-network_pct, lt_pct, aann.ucb+aann.vcb ); + aann.ubal += pct( P100-network_pct, P100-lt_pct, aann.ref_pct, aann.ucb+aann.vcb ); + alife.ubal += pct( P100-network_pct, P100-lt_pct, P100-aann.ref_pct, aann.ucb+aann.vcb ); + aann.ucb = 0; aann.vcb = 0; + + // audit distribution of fees from stud + astud.ubal += pct( P100-network_pct, astud.ucb+astud.vcb ); + astud.ucb = 0; astud.vcb = 0; + + // audit distribution of fees from dumy + alife.ubal += pct( P100-network_pct, lt_pct, adumy.ucb+adumy.vcb ); + alife.ubal += pct( P100-network_pct, P100-lt_pct, adumy.ref_pct, adumy.ucb+adumy.vcb ); + arog.ubal += pct( P100-network_pct, P100-lt_pct, P100-adumy.ref_pct, adumy.ucb+adumy.vcb ); + adumy.ucb = 0; adumy.vcb = 0; + + // audit distribution of fees from scud + alife.ubal += pct( P100-network_pct, lt_pct, ascud.ucb+ascud.vcb ); + aann.ubal += pct( P100-network_pct, P100-lt_pct, ascud.ref_pct, ascud.ucb+ascud.vcb ); + astud.ubal += pct( P100-network_pct, P100-lt_pct, P100-ascud.ref_pct, ascud.ucb+ascud.vcb ); + ascud.ucb = 0; ascud.vcb = 0; + + // audit distribution of fees from pleb + astud.ubal += pct( P100-network_pct, lt_pct, apleb.ucb+apleb.vcb ); + astud.ubal += pct( P100-network_pct, P100-lt_pct, apleb.ref_pct, apleb.ucb+apleb.vcb ); + arog.ubal += pct( P100-network_pct, P100-lt_pct, P100-apleb.ref_pct, apleb.ucb+apleb.vcb ); + apleb.ucb = 0; apleb.vcb = 0; + + CustomAudit(); + + BOOST_TEST_MESSAGE("Waiting for annual membership to expire"); generate_blocks(ann_id(db).membership_expiration_date); generate_block(); - enable_fees(); + + BOOST_TEST_MESSAGE("Transferring from scud to pleb"); //ann's membership has expired, so scud's fee should go up to life instead. transfer(scud_id, pleb_id, asset(10)); + ascud.bal += -10-xfer_fee; ascud.vcb += xfer_fee; apleb.bal += 10; + CustomAudit(); + + BOOST_TEST_MESSAGE("Waiting for maint interval"); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - BOOST_CHECK_EQUAL(life_id(db).cashback_balance(db).balance.amount.value, 94750); - BOOST_CHECK_EQUAL(reggie_id(db).cashback_balance(db).balance.amount.value, 35500); - BOOST_CHECK_EQUAL(ann_id(db).cashback_balance(db).balance.amount.value, 44000); - BOOST_CHECK_EQUAL(stud_id(db).cashback_balance(db).balance.amount.value, 25750); + // audit distribution of fees from scud + alife.ubal += pct( P100-network_pct, lt_pct, ascud.ucb+ascud.vcb ); + alife.ubal += pct( P100-network_pct, P100-lt_pct, ascud.ref_pct, ascud.ucb+ascud.vcb ); + astud.ubal += pct( P100-network_pct, P100-lt_pct, P100-ascud.ref_pct, ascud.ucb+ascud.vcb ); + ascud.ucb = 0; ascud.vcb = 0; + + CustomAudit(); + +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_CASE( account_create_fee_scaling ) +{ try { + auto accounts_per_scale = db.get_global_properties().parameters.accounts_per_fee_scale; + db.modify(global_property_id_type()(db), [](global_property_object& gpo) + { + gpo.parameters.current_fees = fee_schedule::get_default(); + gpo.parameters.current_fees->get().basic_fee = 1; + }); + + for( int i = db.get_dynamic_global_properties().accounts_registered_this_interval; i < accounts_per_scale; ++i ) + { + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 1); + create_account("shill" + fc::to_string(i)); + } + for( int i = 0; i < accounts_per_scale; ++i ) + { + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 16); + create_account("moreshills" + fc::to_string(i)); + } + for( int i = 0; i < accounts_per_scale; ++i ) + { + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 256); + create_account("moarshills" + fc::to_string(i)); + } + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 4096); + + generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 1); } FC_LOG_AND_RETHROW() } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index acf2ff26..00eca382 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -18,9 +18,11 @@ #include +#include +#include + #include #include -#include #include #include #include @@ -32,6 +34,7 @@ #include "../common/database_fixture.hpp" using namespace graphene::chain; +using namespace graphene::chain::test; BOOST_FIXTURE_TEST_SUITE( operation_tests, database_fixture ) @@ -329,7 +332,7 @@ BOOST_AUTO_TEST_CASE( create_account_test ) op.owner = auth_bak; trx.operations.back() = op; - trx.sign( init_account_priv_key); + sign( trx, init_account_priv_key ); trx.validate(); PUSH_TX( db, trx, ~0 ); @@ -342,7 +345,7 @@ BOOST_AUTO_TEST_CASE( create_account_test ) BOOST_CHECK(nathan_account.owner.key_auths.at(committee_key) == 123); BOOST_REQUIRE(nathan_account.active.num_auths() == 1); BOOST_CHECK(nathan_account.active.key_auths.at(committee_key) == 321); - BOOST_CHECK(nathan_account.options.voting_account == account_id_type()); + BOOST_CHECK(nathan_account.options.voting_account == GRAPHENE_PROXY_TO_SELF_ACCOUNT); BOOST_CHECK(nathan_account.options.memo_key == committee_key); const account_statistics_object& statistics = nathan_account.statistics(db); @@ -439,6 +442,7 @@ BOOST_AUTO_TEST_CASE( transfer_core_asset ) for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op); fee = trx.operations.front().get().fee; + set_expiration( db, trx ); trx.validate(); PUSH_TX( db, trx, ~0 ); @@ -611,11 +615,15 @@ BOOST_AUTO_TEST_CASE( update_uia ) trx.operations.push_back(op); //Cannot change issuer to same as before + BOOST_TEST_MESSAGE( "Make sure changing issuer to same as before is forbidden" ); REQUIRE_THROW_WITH_VALUE(op, new_issuer, test.issuer); + //Cannot convert to an MIA + BOOST_TEST_MESSAGE( "Make sure we can't convert UIA to MIA" ); REQUIRE_THROW_WITH_VALUE(op, new_options.issuer_permissions, ASSET_ISSUER_PERMISSION_MASK); REQUIRE_THROW_WITH_VALUE(op, new_options.core_exchange_rate, price(asset(5), asset(5))); + BOOST_TEST_MESSAGE( "Test updating core_exchange_rate" ); op.new_options.core_exchange_rate = price(asset(3), test.amount(5)); trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); @@ -624,21 +632,37 @@ BOOST_AUTO_TEST_CASE( update_uia ) op.new_issuer = nathan.id; trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); + + BOOST_TEST_MESSAGE( "Test setting flags" ); op.issuer = nathan.id; op.new_issuer.reset(); op.new_options.flags = transfer_restricted | white_list; trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); - REQUIRE_THROW_WITH_VALUE(op, new_options.issuer_permissions, test.options.issuer_permissions & ~white_list); + + BOOST_TEST_MESSAGE( "Disable white_list permission" ); op.new_options.issuer_permissions = test.options.issuer_permissions & ~white_list; - op.new_options.flags = 0; trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); + + BOOST_TEST_MESSAGE( "Can't toggle white_list" ); + REQUIRE_THROW_WITH_VALUE(op, new_options.flags, test.options.flags & ~white_list); + + BOOST_TEST_MESSAGE( "Can toggle transfer_restricted" ); + for( int i=0; i<2; i++ ) + { + op.new_options.flags = test.options.flags ^ transfer_restricted; + trx.operations.back() = op; + PUSH_TX( db, trx, ~0 ); + } + + BOOST_TEST_MESSAGE( "Make sure white_list can't be re-enabled" ); op.new_options.issuer_permissions = test.options.issuer_permissions; op.new_options.flags = test.options.flags; BOOST_CHECK(!(test.options.issuer_permissions & white_list)); REQUIRE_THROW_WITH_VALUE(op, new_options.issuer_permissions, UIA_ASSET_ISSUER_PERMISSION_MASK); - REQUIRE_THROW_WITH_VALUE(op, new_options.flags, white_list); + + BOOST_TEST_MESSAGE( "We can change issuer to account_id_type(), but can't do it again" ); op.new_issuer = account_id_type(); trx.operations.back() = op; PUSH_TX( db, trx, ~0 ); @@ -897,9 +921,10 @@ BOOST_AUTO_TEST_CASE( uia_fees ) const asset_dynamic_data_object& asset_dynamic = test_asset.dynamic_asset_data_id(db); const account_object& nathan_account = get_account("nathan"); const account_object& committee_account = account_id_type()(db); + const share_type prec = asset::scaled_precision( asset_id_type()(db).precision ); - fund_fee_pool(committee_account, test_asset, 1000*CORE); - BOOST_CHECK(asset_dynamic.fee_pool == 1000*CORE); + fund_fee_pool(committee_account, test_asset, 1000*prec); + BOOST_CHECK(asset_dynamic.fee_pool == 1000*prec); transfer_operation op; op.fee = test_asset.amount(0); @@ -919,7 +944,7 @@ BOOST_AUTO_TEST_CASE( uia_fees ) (old_balance - fee - test_asset.amount(100)).amount.value); BOOST_CHECK_EQUAL(get_balance(committee_account, test_asset), 100); BOOST_CHECK(asset_dynamic.accumulated_fees == fee.amount); - BOOST_CHECK(asset_dynamic.fee_pool == 1000*CORE - core_fee.amount); + BOOST_CHECK(asset_dynamic.fee_pool == 1000*prec - core_fee.amount); //Do it again, for good measure. PUSH_TX( db, trx, ~0 ); @@ -927,7 +952,7 @@ BOOST_AUTO_TEST_CASE( uia_fees ) (old_balance - fee - fee - test_asset.amount(200)).amount.value); BOOST_CHECK_EQUAL(get_balance(committee_account, test_asset), 200); BOOST_CHECK(asset_dynamic.accumulated_fees == fee.amount + fee.amount); - BOOST_CHECK(asset_dynamic.fee_pool == 1000*CORE - core_fee.amount - core_fee.amount); + BOOST_CHECK(asset_dynamic.fee_pool == 1000*prec - core_fee.amount - core_fee.amount); op = std::move(trx.operations.back().get()); trx.operations.clear(); @@ -945,7 +970,7 @@ BOOST_AUTO_TEST_CASE( uia_fees ) (old_balance - fee - fee - fee - test_asset.amount(200)).amount.value); BOOST_CHECK_EQUAL(get_balance(committee_account, test_asset), 200); BOOST_CHECK(asset_dynamic.accumulated_fees == fee.amount.value * 3); - BOOST_CHECK(asset_dynamic.fee_pool == 1000*CORE - core_fee.amount.value * 3); + BOOST_CHECK(asset_dynamic.fee_pool == 1000*prec - core_fee.amount.value * 3); } catch (fc::exception& e) { edump((e.to_detail_string())); throw; @@ -1100,27 +1125,39 @@ BOOST_AUTO_TEST_CASE( fill_order ) //o.calculate_fee(db.current_fee_schedule()); } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test ) +BOOST_AUTO_TEST_CASE( witness_pay_test ) { try { + + const share_type prec = asset::scaled_precision( asset_id_type()(db).precision ); + // there is an immediate maintenance interval in the first block // which will initialize last_budget_time generate_block(); // Make an account and upgrade it to prime, so that witnesses get some pay create_account("nathan", init_account_pub_key); - transfer(account_id_type()(db), get_account("nathan"), asset(20000*CORE)); - transfer(account_id_type()(db), get_account("init3"), asset(20*CORE)); + transfer(account_id_type()(db), get_account("nathan"), asset(20000*prec)); + transfer(account_id_type()(db), get_account("init3"), asset(20*prec)); generate_block(); + auto last_witness_vbo_balance = [&]() -> share_type + { + const witness_object& wit = db.fetch_block_by_number(db.head_block_num())->witness(db); + if( !wit.pay_vb.valid() ) + return 0; + return (*wit.pay_vb)(db).balance.amount; + }; + + const auto block_interval = db.get_global_properties().parameters.block_interval; const asset_object* core = &asset_id_type()(db); const account_object* nathan = &get_account("nathan"); - enable_fees();//105000000); + enable_fees(); BOOST_CHECK_GT(db.current_fee_schedule().get().membership_lifetime_fee, 0); // Based on the size of the reserve fund later in the test, the witness budget will be set to this value const uint64_t ref_budget = ((uint64_t( db.current_fee_schedule().get().membership_lifetime_fee ) * GRAPHENE_CORE_ASSET_CYCLE_RATE * 30 - * db.get_global_properties().parameters.block_interval + * block_interval ) + ((uint64_t(1) << GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS)-1) ) >> GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS ; @@ -1143,21 +1180,20 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test ) account_upgrade_operation uop; uop.account_to_upgrade = nathan->get_id(); uop.upgrade_to_lifetime_member = true; - trx.set_expiration(db.head_block_id()); + set_expiration( db, trx ); trx.operations.push_back(uop); for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op); trx.validate(); - trx.sign(init_account_priv_key); - db.push_transaction(trx); + sign( trx, init_account_priv_key ); + PUSH_TX( db, trx ); + auto pay_fee_time = db.head_block_time().sec_since_epoch(); trx.clear(); - BOOST_CHECK_EQUAL(get_balance(*nathan, *core), 20000*CORE - account_upgrade_operation::fee_parameters_type().membership_lifetime_fee );; + BOOST_CHECK( get_balance(*nathan, *core) == 20000*prec - account_upgrade_operation::fee_parameters_type().membership_lifetime_fee );; generate_block(); nathan = &get_account("nathan"); core = &asset_id_type()(db); - const witness_object* witness = &db.fetch_block_by_number(db.head_block_num())->witness(db); - - BOOST_CHECK_EQUAL(witness->accumulated_income.value, 0); + BOOST_CHECK_EQUAL( last_witness_vbo_balance().value, 0 ); auto schedule_maint = [&]() { @@ -1170,135 +1206,204 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test ) BOOST_TEST_MESSAGE( "Generating some blocks" ); // generate some blocks - while( db.head_block_num() < 30 ) + while( db.head_block_time().sec_since_epoch() - pay_fee_time < 24 * block_interval ) { generate_block(); - witness = &db.fetch_block_by_number(db.head_block_num())->witness(db); - BOOST_CHECK_EQUAL( witness->accumulated_income.value, 0 ); + BOOST_CHECK_EQUAL( last_witness_vbo_balance().value, 0 ); } - BOOST_CHECK_EQUAL( db.head_block_num(), 30 ); - // maintenance will be in block 31. time of block 31 - time of block 1 = 30 * 5 seconds. + BOOST_CHECK_EQUAL( db.head_block_time().sec_since_epoch() - pay_fee_time, 24 * block_interval ); schedule_maint(); // The 80% lifetime referral fee went to the committee account, which burned it. Check that it's here. - BOOST_CHECK_EQUAL( core->reserved(db).value, 8000*CORE ); + BOOST_CHECK( core->reserved(db).value == 8000*prec ); generate_block(); BOOST_CHECK_EQUAL( core->reserved(db).value, 999999406 ); BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget ); - witness = &db.fetch_block_by_number(db.head_block_num())->witness(db); // first witness paid from old budget (so no pay) - BOOST_CHECK_EQUAL( witness->accumulated_income.value, 0 ); + BOOST_CHECK_EQUAL( last_witness_vbo_balance().value, 0 ); // second witness finally gets paid! generate_block(); - witness = &db.fetch_block_by_number(db.head_block_num())->witness(db); - const witness_object* paid_witness = witness; - BOOST_CHECK_EQUAL( witness->accumulated_income.value, witness_ppb ); + BOOST_CHECK_EQUAL( last_witness_vbo_balance().value, witness_ppb ); BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget - witness_ppb ); generate_block(); - witness = &db.fetch_block_by_number(db.head_block_num())->witness(db); - BOOST_CHECK_EQUAL( witness->accumulated_income.value, witness_ppb ); + BOOST_CHECK_EQUAL( last_witness_vbo_balance().value, witness_ppb ); BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget - 2 * witness_ppb ); generate_block(); - witness = &db.fetch_block_by_number(db.head_block_num())->witness(db); - BOOST_CHECK_LT( witness->accumulated_income.value, witness_ppb ); - BOOST_CHECK_EQUAL( witness->accumulated_income.value, ref_budget - 2 * witness_ppb ); + BOOST_CHECK_LT( last_witness_vbo_balance().value, witness_ppb ); + BOOST_CHECK_EQUAL( last_witness_vbo_balance().value, ref_budget - 2 * witness_ppb ); BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, 0 ); generate_block(); - witness = &db.fetch_block_by_number(db.head_block_num())->witness(db); - BOOST_CHECK_EQUAL( witness->accumulated_income.value, 0 ); + BOOST_CHECK_EQUAL( last_witness_vbo_balance().value, 0 ); BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, 0 ); - - trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION); - // Withdraw the witness's pay - enable_fees();//1); - witness = paid_witness; - witness_withdraw_pay_operation wop; - wop.from_witness = witness->id; - wop.to_account = witness->witness_account; - wop.amount = witness->accumulated_income; - trx.operations.push_back(wop); - REQUIRE_THROW_WITH_VALUE(wop, amount, witness->accumulated_income.value * 2); - trx.operations.back() = wop; - for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op); - trx.validate(); - db.push_transaction(trx, database::skip_authority_check); - trx.clear(); - - BOOST_CHECK_EQUAL(get_balance(witness->witness_account(db), *core), witness_ppb ); BOOST_CHECK_EQUAL(core->reserved(db).value, 999999406 ); - BOOST_CHECK_EQUAL(witness->accumulated_income.value, 0); + } FC_LOG_AND_RETHROW() } /** - * Asset Burn Test should make sure that all assets except bitassets - * can be burned and all supplies add up. + * Reserve asset test should make sure that all assets except bitassets + * can be burned, and all supplies add up. */ -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_burn_asset_test, 1 ) -BOOST_AUTO_TEST_CASE( unimp_burn_asset_test ) +BOOST_AUTO_TEST_CASE( reserve_asset_test ) { - BOOST_FAIL( "not implemented" ); + try + { + ACTORS((alice)(bob)(sam)(judge)); + const auto& basset = create_bitasset("BITUSD"); + const auto& uasset = create_user_issued_asset("TEST"); + const auto& passet = create_prediction_market("PMARK", judge_id); + const auto& casset = asset_id_type()(db); + + auto reserve_asset = [&]( account_id_type payer, asset amount_to_reserve ) + { + asset_reserve_operation op; + op.payer = payer; + op.amount_to_reserve = amount_to_reserve; + transaction tx; + tx.operations.push_back( op ); + set_expiration( db, tx ); + db.push_transaction( tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures ); + } ; + + auto _issue_uia = [&]( const account_object& recipient, asset amount ) + { + asset_issue_operation op; + op.issuer = amount.asset_id(db).issuer; + op.asset_to_issue = amount; + op.issue_to_account = recipient.id; + transaction tx; + tx.operations.push_back( op ); + set_expiration( db, tx ); + db.push_transaction( tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures ); + } ; + + int64_t init_balance = 10000; + int64_t reserve_amount = 3000; + share_type initial_reserve; + + BOOST_TEST_MESSAGE( "Test reserve operation on core asset" ); + transfer( committee_account, alice_id, casset.amount( init_balance ) ); + + initial_reserve = casset.reserved( db ); + reserve_asset( alice_id, casset.amount( reserve_amount ) ); + BOOST_CHECK_EQUAL( get_balance( alice, casset ), init_balance - reserve_amount ); + BOOST_CHECK_EQUAL( (casset.reserved( db ) - initial_reserve).value, reserve_amount ); + verify_asset_supplies(db); + + BOOST_TEST_MESSAGE( "Test reserve operation on market issued asset" ); + transfer( committee_account, alice_id, casset.amount( init_balance*100 ) ); + update_feed_producers( basset, {sam.id} ); + price_feed current_feed; + current_feed.settlement_price = basset.amount( 2 ) / casset.amount(100); + publish_feed( basset, sam, current_feed ); + borrow( alice_id, basset.amount( init_balance ), casset.amount( 100*init_balance ) ); + BOOST_CHECK_EQUAL( get_balance( alice, basset ), init_balance ); + + GRAPHENE_REQUIRE_THROW( reserve_asset( alice_id, basset.amount( reserve_amount ) ), asset_reserve_invalid_on_mia ); + + BOOST_TEST_MESSAGE( "Test reserve operation on prediction market asset" ); + transfer( committee_account, alice_id, casset.amount( init_balance ) ); + borrow( alice_id, passet.amount( init_balance ), casset.amount( init_balance ) ); + GRAPHENE_REQUIRE_THROW( reserve_asset( alice_id, passet.amount( reserve_amount ) ), asset_reserve_invalid_on_mia ); + + BOOST_TEST_MESSAGE( "Test reserve operation on user issued asset" ); + _issue_uia( alice, uasset.amount( init_balance ) ); + BOOST_CHECK_EQUAL( get_balance( alice, uasset ), init_balance ); + verify_asset_supplies(db); + + BOOST_TEST_MESSAGE( "Reserving asset" ); + initial_reserve = uasset.reserved( db ); + reserve_asset( alice_id, uasset.amount( reserve_amount ) ); + BOOST_CHECK_EQUAL( get_balance( alice, uasset ), init_balance - reserve_amount ); + BOOST_CHECK_EQUAL( (uasset.reserved( db ) - initial_reserve).value, reserve_amount ); + verify_asset_supplies(db); + } + catch (fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } } /** * This test demonstrates how using the call_order_update_operation to - * increase the maintenance collateral ratio above the current market - * price, perhaps setting it to infinity. + * trigger a margin call is legal if there is a matching order. */ -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_cover_with_collateral_test, 1 ) -BOOST_AUTO_TEST_CASE( unimp_cover_with_collateral_test ) +BOOST_AUTO_TEST_CASE( cover_with_collateral_test ) { - BOOST_FAIL( "not implemented" ); -} + try + { + ACTORS((alice)(bob)(sam)); + const auto& bitusd = create_bitasset("BITUSD"); + const auto& core = asset_id_type()(db); -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_bulk_discount_test, 1 ) -BOOST_AUTO_TEST_CASE( unimp_bulk_discount_test ) -{ - // commented out to silence compiler warnings - //const account_object& shorter1 = create_account( "alice" ); - //const account_object& shorter2 = create_account( "bob" ); - BOOST_FAIL( "not implemented" ); -} -/** - * Assume the referrer gets 99% of transaction fee - */ -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_transfer_cashback_test, 1 ) -BOOST_AUTO_TEST_CASE( unimp_transfer_cashback_test ) -{ - try { - BOOST_FAIL( "Rewrite this test with VBO based cashback" ); -#if 0 - generate_blocks(1); + BOOST_TEST_MESSAGE( "Setting price feed to $0.02 / 100" ); + transfer(committee_account, alice_id, asset(10000000)); + update_feed_producers( bitusd, {sam.id} ); - const account_object& sam = create_account( "sam" ); - transfer(account_id_type()(db), sam, asset(30000)); - upgrade_to_lifetime_member(sam); + price_feed current_feed; + current_feed.settlement_price = bitusd.amount( 2 ) / core.amount(100); + publish_feed( bitusd, sam, current_feed ); - ilog( "Creating alice" ); - const account_object& alice = create_account( "alice", sam, sam, 0 ); - ilog( "Creating bob" ); - const account_object& bob = create_account( "bob", sam, sam, 0 ); + BOOST_REQUIRE( bitusd.bitasset_data(db).current_feed.settlement_price == current_feed.settlement_price ); - transfer(account_id_type()(db), alice, asset(300000)); + BOOST_TEST_MESSAGE( "Alice borrows some BitUSD at 2x collateral and gives it to Bob" ); + const call_order_object* call_order = borrow( alice, bitusd.amount(100), asset(10000) ); + BOOST_REQUIRE( call_order != nullptr ); - enable_fees(); + // wdump( (*call_order) ); - transfer(alice, bob, asset(100000)); + transfer( alice_id, bob_id, bitusd.amount(100) ); - BOOST_REQUIRE_EQUAL( alice.statistics(db).lifetime_fees_paid.value, GRAPHENE_BLOCKCHAIN_PRECISION ); + auto update_call_order = [&]( account_id_type acct, asset delta_collateral, asset delta_debt ) + { + call_order_update_operation op; + op.funding_account = acct; + op.delta_collateral = delta_collateral; + op.delta_debt = delta_debt; + transaction tx; + tx.operations.push_back( op ); + set_expiration( db, tx ); + db.push_transaction( tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures ); + } ; - const asset_dynamic_data_object& core_asset_data = db.get_core_asset().dynamic_asset_data_id(db); - // 1% of fee goes to witnesses - BOOST_CHECK_EQUAL(core_asset_data.accumulated_fees.value, - GRAPHENE_BLOCKCHAIN_PRECISION/100/*witness*/ + GRAPHENE_BLOCKCHAIN_PRECISION/5 /*burn*/); - // 99% of fee goes to referrer / registrar sam - BOOST_CHECK_EQUAL( sam.statistics(db).cashback_rewards.value, - GRAPHENE_BLOCKCHAIN_PRECISION - GRAPHENE_BLOCKCHAIN_PRECISION/100/*witness*/ - GRAPHENE_BLOCKCHAIN_PRECISION/5/*burn*/); + // margin call requirement: 1.75x + BOOST_TEST_MESSAGE( "Alice decreases her collateral to maint level plus one satoshi" ); + asset delta_collateral = asset(int64_t( current_feed.maintenance_collateral_ratio ) * 5000 / GRAPHENE_COLLATERAL_RATIO_DENOM - 10000 + 1 ); + update_call_order( alice_id, delta_collateral, bitusd.amount(0) ); + // wdump( (*call_order) ); -#endif - } catch( const fc::exception& e ) + BOOST_TEST_MESSAGE( "Alice cannot decrease her collateral by one satoshi, there is no buyer" ); + GRAPHENE_REQUIRE_THROW( update_call_order( alice_id, asset(-1), bitusd.amount(0) ), call_order_update_unfilled_margin_call ); + // wdump( (*call_order) ); + + BOOST_TEST_MESSAGE( "Bob offers to sell most of the BitUSD at the feed" ); + const limit_order_object* order = create_sell_order( bob_id, bitusd.amount(99), asset(4950) ); + BOOST_REQUIRE( order != nullptr ); + limit_order_id_type order1_id = order->id; + BOOST_CHECK_EQUAL( order->for_sale.value, 99 ); + // wdump( (*call_order) ); + + BOOST_TEST_MESSAGE( "Alice still cannot decrease her collateral to maint level" ); + GRAPHENE_REQUIRE_THROW( update_call_order( alice_id, asset(-1), bitusd.amount(0) ), call_order_update_unfilled_margin_call ); + // wdump( (*call_order) ); + + BOOST_TEST_MESSAGE( "Bob offers to sell the last of his BitUSD in another order" ); + order = create_sell_order( bob_id, bitusd.amount(1), asset(50) ); + BOOST_REQUIRE( order != nullptr ); + limit_order_id_type order2_id = order->id; + BOOST_CHECK_EQUAL( order->for_sale.value, 1 ); + // wdump( (*call_order) ); + + BOOST_TEST_MESSAGE( "Alice decreases her collateral to maint level and Bob's orders fill" ); + update_call_order( alice_id, asset(-1), bitusd.amount(0) ); + + BOOST_CHECK( db.find( order1_id ) == nullptr ); + BOOST_CHECK( db.find( order2_id ) == nullptr ); + } + catch (fc::exception& e) { edump((e.to_detail_string())); throw; @@ -1409,6 +1514,7 @@ BOOST_AUTO_TEST_CASE( vesting_balance_withdraw_test ) create_op.amount = amount; create_op.policy = cdd_vesting_policy_initializer(vesting_seconds); tx.operations.push_back( create_op ); + set_expiration( db, tx ); processed_transaction ptx = PUSH_TX( db, tx, ~0 ); const vesting_balance_object& vbo = vesting_balance_id_type( diff --git a/tests/tests/operation_tests2.cpp b/tests/tests/operation_tests2.cpp index be752ec2..aebe492f 100644 --- a/tests/tests/operation_tests2.cpp +++ b/tests/tests/operation_tests2.cpp @@ -38,6 +38,7 @@ #include "../common/database_fixture.hpp" using namespace graphene::chain; +using namespace graphene::chain::test; BOOST_FIXTURE_TEST_SUITE( operation_tests, database_fixture ) @@ -50,7 +51,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_create ) transfer(account_id_type(), nathan_id, asset(1000)); generate_block(); - trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION / 2); + set_expiration( db, trx ); { withdraw_permission_create_operation op; @@ -71,7 +72,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_create ) REQUIRE_THROW_WITH_VALUE(op, withdrawal_period_sec, 1); trx.operations.back() = op; } - trx.sign(nathan_private_key); + sign( trx, nathan_private_key ); db.push_transaction( trx ); trx.clear(); } FC_LOG_AND_RETHROW() } @@ -85,7 +86,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test ) account_id_type nathan_id = get_account("nathan").id; account_id_type dan_id = get_account("dan").id; withdraw_permission_id_type permit; - trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION/2); + set_expiration( db, trx ); fc::time_point_sec first_start_time; { @@ -107,6 +108,8 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test ) op.withdraw_from_account = nathan_id; op.withdraw_to_account = dan_id; op.amount_to_withdraw = asset(1); + set_expiration( db, trx ); + trx.operations.push_back(op); //Throws because we haven't entered the first withdrawal period yet. GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx ), fc::exception); @@ -120,9 +123,10 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test ) REQUIRE_THROW_WITH_VALUE(op, withdraw_to_account, account_id_type()); REQUIRE_THROW_WITH_VALUE(op, amount_to_withdraw, asset(10)); REQUIRE_THROW_WITH_VALUE(op, amount_to_withdraw, asset(6)); + set_expiration( db, trx ); trx.clear(); trx.operations.push_back(op); - trx.sign(dan_private_key); + sign( trx, dan_private_key ); PUSH_TX( db, trx ); // would be legal on its own, but doesn't work because trx already withdrew @@ -133,8 +137,8 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test ) // withdraw 1 trx.operations = {op}; // make it different from previous trx so it's non-duplicate - trx.ref_block_prefix++; - trx.sign(dan_private_key); + trx.expiration += fc::seconds(1); + sign( trx, dan_private_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -164,13 +168,15 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test ) op.withdraw_to_account = dan_id; op.amount_to_withdraw = asset(5); trx.operations.push_back(op); - trx.sign(dan_private_key); + set_expiration( db, trx ); + sign( trx, dan_private_key ); //Throws because nathan doesn't have the money GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); op.amount_to_withdraw = asset(1); trx.clear(); trx.operations = {op}; - trx.sign(dan_private_key); + set_expiration( db, trx ); + sign( trx, dan_private_key ); PUSH_TX( db, trx ); } @@ -199,7 +205,8 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test ) op.withdraw_to_account = dan_id; op.amount_to_withdraw = asset(5); trx.operations.push_back(op); - trx.sign(dan_private_key); + set_expiration( db, trx ); + sign( trx, dan_private_key ); //Throws because the permission has expired GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); } @@ -214,7 +221,6 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_nominal_case ) account_id_type nathan_id = get_account("nathan").id; account_id_type dan_id = get_account("dan").id; withdraw_permission_id_type permit; - trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION/2); while(true) { @@ -226,10 +232,8 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_nominal_case ) op.withdraw_to_account = dan_id; op.amount_to_withdraw = asset(5); trx.operations.push_back(op); - // ref_block_prefix is timestamp, so treat it as a rollable nonce - // so tx's have different txid's - trx.ref_block_prefix++; - trx.sign(dan_private_key); + set_expiration( db, trx ); + sign( trx, dan_private_key ); PUSH_TX( db, trx ); // tx's involving withdraw_permissions can't delete it even // if no further withdrawals are possible @@ -255,7 +259,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_update ) account_id_type nathan_id = get_account("nathan").id; account_id_type dan_id = get_account("dan").id; withdraw_permission_id_type permit; - trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION/2); + set_expiration( db, trx ); { withdraw_permission_update_operation op; @@ -275,7 +279,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_update ) REQUIRE_THROW_WITH_VALUE(op, authorized_account, account_id_type(0)); REQUIRE_THROW_WITH_VALUE(op, period_start_time, db.head_block_time() - 50); trx.operations.back() = op; - trx.sign(nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); } @@ -297,9 +301,9 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_delete ) withdraw_permission_delete_operation op; op.authorized_account = get_account("dan").id; op.withdraw_from_account = get_account("nathan").id; - trx.set_expiration(db.head_block_id()); + set_expiration( db, trx ); trx.operations.push_back(op); - trx.sign(generate_private_key("nathan")); + sign( trx, generate_private_key("nathan" )); PUSH_TX( db, trx ); } FC_LOG_AND_RETHROW() } @@ -326,7 +330,7 @@ BOOST_AUTO_TEST_CASE( mia_feeds ) op.issuer = nathan_id; op.new_feed_producers = {dan_id, ben_id, vikram_id}; trx.operations.push_back(op); - trx.sign(nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); generate_block(database::skip_nothing); } @@ -389,7 +393,7 @@ BOOST_AUTO_TEST_CASE( feed_limit_test ) op.asset_to_update = bit_usd.get_id(); op.issuer = bit_usd.issuer; trx.operations = {op}; - trx.sign(nathan_private_key); + sign( trx, nathan_private_key ); db.push_transaction(trx); BOOST_TEST_MESSAGE("Checking current_feed is null"); @@ -399,7 +403,7 @@ BOOST_AUTO_TEST_CASE( feed_limit_test ) op.new_options.minimum_feeds = 3; trx.clear(); trx.operations = {op}; - trx.sign(nathan_private_key); + sign( trx, nathan_private_key ); db.push_transaction(trx); BOOST_TEST_MESSAGE("Checking current_feed is not null"); @@ -415,7 +419,7 @@ BOOST_AUTO_TEST_CASE( witness_create ) // Give nathan some voting stake transfer(committee_account, nathan_id, asset(10000000)); generate_block(); - trx.set_expiration(db.head_block_id()); + set_expiration( db, trx ); { account_update_operation op; @@ -427,7 +431,7 @@ BOOST_AUTO_TEST_CASE( witness_create ) op.new_options->num_committee = std::count_if(op.new_options->votes.begin(), op.new_options->votes.end(), [](vote_id_type id) { return id.type() == vote_id_type::committee; }); trx.operations.push_back(op); - trx.sign(nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -439,34 +443,20 @@ BOOST_AUTO_TEST_CASE( witness_create ) auto itr = std::find(witnesses.begin(), witnesses.end(), nathan_witness_id); BOOST_CHECK(itr != witnesses.end()); - generate_blocks(witnesses.size()); + // generate blocks until we are at the beginning of a round + while( ((db.get_dynamic_global_properties().current_aslot + 1) % witnesses.size()) != 0 ) + generate_block(); - // make sure we're scheduled to produce - vector near_witnesses = db.get_near_witness_schedule(); - BOOST_CHECK( std::find( near_witnesses.begin(), near_witnesses.end(), nathan_witness_id ) - != near_witnesses.end() ); - - struct generator_helper { - database_fixture& f; - witness_id_type nathan_id; - fc::ecc::private_key nathan_key; - bool nathan_generated_block; - - void operator()(witness_id_type id) { - if( id == nathan_id ) - { - nathan_generated_block = true; - f.generate_block(0, nathan_key); - } else - f.generate_block(0); - BOOST_CHECK_EQUAL(f.db.get_dynamic_global_properties().current_witness.instance.value, id.instance.value); - f.db.get_near_witness_schedule(); - } - }; - - generator_helper h = std::for_each(near_witnesses.begin(), near_witnesses.end(), - generator_helper{*this, nathan_witness_id, nathan_private_key, false}); - BOOST_CHECK(h.nathan_generated_block); + int produced = 0; + // Make sure we get scheduled exactly once in witnesses.size() blocks + // TODO: intense_test that repeats this loop many times + for( size_t i=0; i().balance; op.amount = asset(500); op.owner = nathan_id; - trx.set_expiration(db.head_block_id()); + set_expiration( db, trx ); trx.operations.push_back(op); - trx.sign( nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); trx.signatures.clear(); REQUIRE_THROW_WITH_VALUE(op, amount, asset(1)); @@ -657,14 +647,14 @@ BOOST_AUTO_TEST_CASE( worker_pay_test ) op.vesting_balance = worker_id_type()(db).worker.get().balance; op.amount = asset(500); op.owner = nathan_id; - trx.set_expiration(db.head_block_id()); + set_expiration( db, trx ); trx.operations.push_back(op); REQUIRE_THROW_WITH_VALUE(op, amount, asset(500)); generate_blocks(db.head_block_time() + fc::hours(12)); - trx.set_expiration(db.head_block_id()); + set_expiration( db, trx ); REQUIRE_THROW_WITH_VALUE(op, amount, asset(501)); trx.operations.back() = op; - trx.sign( nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); trx.signatures.clear(); trx.clear(); @@ -680,7 +670,7 @@ BOOST_AUTO_TEST_CASE( refund_worker_test ) upgrade_to_lifetime_member(nathan_id); generate_block(); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - trx.set_expiration(db.head_block_id()); + set_expiration( db, trx ); { worker_create_operation op; @@ -697,7 +687,7 @@ BOOST_AUTO_TEST_CASE( refund_worker_test ) REQUIRE_THROW_WITH_VALUE(op, work_begin_date, db.head_block_time() - 10); REQUIRE_THROW_WITH_VALUE(op, work_end_date, op.work_begin_date); trx.operations.back() = op; - trx.sign( nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -753,7 +743,7 @@ BOOST_AUTO_TEST_CASE( burn_worker_test ) upgrade_to_lifetime_member(nathan_id); generate_block(); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - trx.set_expiration(db.head_block_id()); + set_expiration( db, trx ); { worker_create_operation op; @@ -770,7 +760,7 @@ BOOST_AUTO_TEST_CASE( burn_worker_test ) REQUIRE_THROW_WITH_VALUE(op, work_begin_date, db.head_block_time() - 10); REQUIRE_THROW_WITH_VALUE(op, work_end_date, op.work_begin_date); trx.operations.back() = op; - trx.sign( nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); trx.clear(); } @@ -820,128 +810,191 @@ BOOST_AUTO_TEST_CASE( burn_worker_test ) BOOST_CHECK_EQUAL( get_balance(GRAPHENE_NULL_ACCOUNT, asset_id_type()), 2000 ); }FC_LOG_AND_RETHROW()} -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_force_settlement_unavailable, 1 ) -BOOST_AUTO_TEST_CASE( unimp_force_settlement_unavailable ) +BOOST_AUTO_TEST_CASE( force_settle_test ) { - BOOST_FAIL( "TODO - Reimplement this" ); - /* - try { - auto private_key = init_account_priv_key; - auto private_key = generate_private_key("committee"); ->>>>>>> short_refactor - account_id_type nathan_id = create_account("nathan").get_id(); - account_id_type shorter1_id = create_account("shorter1").get_id(); - account_id_type shorter2_id = create_account("shorter2").get_id(); - account_id_type shorter3_id = create_account("shorter3").get_id(); - transfer(account_id_type()(db), nathan_id(db), asset(100000000)); - transfer(account_id_type()(db), shorter1_id(db), asset(100000000)); - transfer(account_id_type()(db), shorter2_id(db), asset(100000000)); - transfer(account_id_type()(db), shorter3_id(db), asset(100000000)); - asset_id_type bit_usd = create_bitasset("BITUSD", GRAPHENE_TEMP_ACCOUNT, 0, disable_force_settle).get_id(); - FC_ASSERT( bit_usd(db).is_market_issued() ); + try { - asset_update_bitasset_operation op; - op.asset_to_update = bit_usd; - op.issuer = bit_usd(db).issuer; - op.new_options = bit_usd(db).bitasset_data(db).options; - op.new_options.maximum_force_settlement_volume = 9000; - trx.clear(); - trx.operations.push_back(op); - PUSH_TX( db, trx, ~0 ); - trx.clear(); + ACTORS( (nathan)(shorter1)(shorter2)(shorter3)(shorter4)(shorter5) ); + + int64_t initial_balance = 100000000; + + transfer(account_id_type()(db), shorter1_id(db), asset(initial_balance)); + transfer(account_id_type()(db), shorter2_id(db), asset(initial_balance)); + transfer(account_id_type()(db), shorter3_id(db), asset(initial_balance)); + transfer(account_id_type()(db), shorter4_id(db), asset(initial_balance)); + transfer(account_id_type()(db), shorter5_id(db), asset(initial_balance)); + + asset_id_type bitusd_id = create_bitasset( + "BITUSD", + nathan_id, + 100, + disable_force_settle + ).id; + + asset_id_type core_id = asset_id_type(); + + auto update_bitasset_options = [&]( asset_id_type asset_id, + std::function< void(bitasset_options&) > update_function ) + { + const asset_object& _asset = asset_id(db); + asset_update_bitasset_operation op; + op.asset_to_update = asset_id; + op.issuer = _asset.issuer; + op.new_options = (*_asset.bitasset_data_id)(db).options; + update_function( op.new_options ); + signed_transaction tx; + tx.operations.push_back( op ); + set_expiration( db, tx ); + PUSH_TX( db, tx, ~0 ); + } ; + + auto update_asset_options = [&]( asset_id_type asset_id, + std::function< void(asset_options&) > update_function ) + { + const asset_object& _asset = asset_id(db); + asset_update_operation op; + op.asset_to_update = asset_id; + op.issuer = _asset.issuer; + op.new_options = _asset.options; + update_function( op.new_options ); + signed_transaction tx; + tx.operations.push_back( op ); + set_expiration( db, tx ); + PUSH_TX( db, tx, ~0 ); + } ; + + BOOST_TEST_MESSAGE( "Update maximum_force_settlement_volume = 9000" ); + + BOOST_CHECK( bitusd_id(db).is_market_issued() ); + update_bitasset_options( bitusd_id, [&]( bitasset_options& new_options ) + { new_options.maximum_force_settlement_volume = 9000; } ); + + BOOST_TEST_MESSAGE( "Publish price feed" ); + + update_feed_producers( bitusd_id, { nathan_id } ); + { + price_feed feed; + feed.settlement_price = price( asset( 1, bitusd_id ), asset( 1, core_id ) ); + publish_feed( bitusd_id, nathan_id, feed ); + } + + BOOST_TEST_MESSAGE( "First short batch" ); + + call_order_id_type call1_id = borrow( shorter1_id, asset(1000, bitusd_id), asset(2*1000, core_id) )->id; // 2.0000 + call_order_id_type call2_id = borrow( shorter2_id, asset(2000, bitusd_id), asset(2*1999, core_id) )->id; // 1.9990 + call_order_id_type call3_id = borrow( shorter3_id, asset(3000, bitusd_id), asset(2*2890, core_id) )->id; // 1.9267 + call_order_id_type call4_id = borrow( shorter4_id, asset(4000, bitusd_id), asset(2*3950, core_id) )->id; // 1.9750 + call_order_id_type call5_id = borrow( shorter5_id, asset(5000, bitusd_id), asset(2*4900, core_id) )->id; // 1.9600 + + transfer( shorter1_id, nathan_id, asset(1000, bitusd_id) ); + transfer( shorter2_id, nathan_id, asset(2000, bitusd_id) ); + transfer( shorter3_id, nathan_id, asset(3000, bitusd_id) ); + transfer( shorter4_id, nathan_id, asset(4000, bitusd_id) ); + transfer( shorter5_id, nathan_id, asset(5000, bitusd_id) ); + + BOOST_CHECK_EQUAL( get_balance(nathan_id, bitusd_id), 15000); + BOOST_CHECK_EQUAL( get_balance(nathan_id, core_id), 0); + BOOST_CHECK_EQUAL( get_balance(shorter1_id, core_id), initial_balance-2000 ); + BOOST_CHECK_EQUAL( get_balance(shorter2_id, core_id), initial_balance-3998 ); + BOOST_CHECK_EQUAL( get_balance(shorter3_id, core_id), initial_balance-5780 ); + BOOST_CHECK_EQUAL( get_balance(shorter4_id, core_id), initial_balance-7900 ); + BOOST_CHECK_EQUAL( get_balance(shorter5_id, core_id), initial_balance-9800 ); + + BOOST_TEST_MESSAGE( "Update force_settlement_delay_sec = 100, force_settlement_offset_percent = 1%" ); + + update_bitasset_options( bitusd_id, [&]( bitasset_options& new_options ) + { new_options.force_settlement_delay_sec = 100; + new_options.force_settlement_offset_percent = GRAPHENE_1_PERCENT; } ); + + // Force settlement is disabled; check that it fails + GRAPHENE_REQUIRE_THROW( force_settle( nathan_id, asset( 50, bitusd_id ) ), fc::exception ); + + update_asset_options( bitusd_id, [&]( asset_options& new_options ) + { new_options.flags &= ~disable_force_settle; } ); + + // Can't settle more BitUSD than you own + GRAPHENE_REQUIRE_THROW( force_settle( nathan_id, asset( 999999, bitusd_id ) ), fc::exception ); + + // settle3 should be least collateralized order according to index + BOOST_CHECK( db.get_index_type().indices().get().begin()->id == call3_id ); + BOOST_CHECK_EQUAL( call3_id(db).debt.value, 3000 ); + + BOOST_TEST_MESSAGE( "Verify partial settlement of call" ); + // Partially settle a call + force_settlement_id_type settle_id = force_settle( nathan_id, asset( 50, bitusd_id ) ).get< object_id_type >(); + + // Call does not take effect immediately + BOOST_CHECK_EQUAL( get_balance(nathan_id, bitusd_id), 14950); + BOOST_CHECK_EQUAL( settle_id(db).balance.amount.value, 50); + BOOST_CHECK_EQUAL( call3_id(db).debt.value, 3000 ); + BOOST_CHECK_EQUAL( call3_id(db).collateral.value, 5780 ); + BOOST_CHECK( settle_id(db).owner == nathan_id ); + + // Wait for settlement to take effect + generate_blocks(settle_id(db).settlement_date); + BOOST_CHECK(db.find(settle_id) == nullptr); + BOOST_CHECK_EQUAL( get_balance(nathan_id, bitusd_id), 14950); + BOOST_CHECK_EQUAL( get_balance(nathan_id, core_id), 49 ); // 1% force_settlement_offset_percent (rounded unfavorably) + BOOST_CHECK_EQUAL( call3_id(db).debt.value, 2950 ); + BOOST_CHECK_EQUAL( call3_id(db).collateral.value, 5731 ); // 5731 == 5780-49 + + BOOST_CHECK( db.get_index_type().indices().get().begin()->id == call3_id ); + + BOOST_TEST_MESSAGE( "Verify pending settlement is cancelled when asset's force_settle is disabled" ); + // Ensure pending settlement is cancelled when force settle is disabled + settle_id = force_settle( nathan_id, asset( 50, bitusd_id ) ).get< object_id_type >(); + + BOOST_CHECK( !db.get_index_type().indices().empty() ); + update_asset_options( bitusd_id, [&]( asset_options& new_options ) + { new_options.flags |= disable_force_settle; } ); + BOOST_CHECK( db.get_index_type().indices().empty() ); + update_asset_options( bitusd_id, [&]( asset_options& new_options ) + { new_options.flags &= ~disable_force_settle; } ); + + BOOST_TEST_MESSAGE( "Perform iterative settlement" ); + settle_id = force_settle( nathan_id, asset( 12500, bitusd_id ) ).get< object_id_type >(); + + // c3 2950 : 5731 1.9427 fully settled + // c5 5000 : 9800 1.9600 fully settled + // c4 4000 : 7900 1.9750 fully settled + // c2 2000 : 3998 1.9990 550 settled + // c1 1000 : 2000 2.0000 + + generate_blocks( settle_id(db).settlement_date ); + + int64_t call1_payout = 0; + int64_t call2_payout = 550*99/100; + int64_t call3_payout = 49 + 2950*99/100; + int64_t call4_payout = 4000*99/100; + int64_t call5_payout = 5000*99/100; + + BOOST_CHECK_EQUAL( get_balance(shorter1_id, core_id), initial_balance-2*1000 ); // full collat still tied up + BOOST_CHECK_EQUAL( get_balance(shorter2_id, core_id), initial_balance-2*1999 ); // full collat still tied up + BOOST_CHECK_EQUAL( get_balance(shorter3_id, core_id), initial_balance-call3_payout ); // initial balance minus transfer to Nathan (as BitUSD) + BOOST_CHECK_EQUAL( get_balance(shorter4_id, core_id), initial_balance-call4_payout ); // initial balance minus transfer to Nathan (as BitUSD) + BOOST_CHECK_EQUAL( get_balance(shorter5_id, core_id), initial_balance-call5_payout ); // initial balance minus transfer to Nathan (as BitUSD) + + BOOST_CHECK_EQUAL( get_balance(nathan_id, core_id), + call1_payout + call2_payout + call3_payout + call4_payout + call5_payout ); + + BOOST_CHECK( db.find(call3_id) == nullptr ); + BOOST_CHECK( db.find(call4_id) == nullptr ); + BOOST_CHECK( db.find(call5_id) == nullptr ); + + BOOST_REQUIRE( db.find(call1_id) != nullptr ); + BOOST_REQUIRE( db.find(call2_id) != nullptr ); + + BOOST_CHECK_EQUAL( call1_id(db).debt.value, 1000 ); + BOOST_CHECK_EQUAL( call1_id(db).collateral.value, 2000 ); + + BOOST_CHECK_EQUAL( call2_id(db).debt.value, 2000-550 ); + BOOST_CHECK_EQUAL( call2_id(db).collateral.value, 3998-call2_payout ); } - generate_block(); - - create_short(shorter1_id(db), asset(1000, bit_usd), asset(1000)); - create_sell_order(nathan_id(db), asset(1000), asset(1000, bit_usd)); - create_short(shorter2_id(db), asset(2000, bit_usd), asset(1999)); - create_sell_order(nathan_id(db), asset(1999), asset(2000, bit_usd)); - create_short(shorter3_id(db), asset(3000, bit_usd), asset(2990)); - create_sell_order(nathan_id(db), asset(2990), asset(3000, bit_usd)); - BOOST_CHECK_EQUAL(get_balance(nathan_id, bit_usd), 6000); - - transfer(nathan_id(db), account_id_type()(db), db.get_balance(nathan_id, asset_id_type())); - + catch(fc::exception& e) { - asset_update_bitasset_operation uop; - uop.issuer = bit_usd(db).issuer; - uop.asset_to_update = bit_usd; - uop.new_options = bit_usd(db).bitasset_data(db).options; - uop.new_options.force_settlement_delay_sec = 100; - uop.new_options.force_settlement_offset_percent = 100; - trx.operations.push_back(uop); - } { - asset_update_feed_producers_operation uop; - uop.asset_to_update = bit_usd; - uop.issuer = bit_usd(db).issuer; - uop.new_feed_producers = {nathan_id}; - trx.operations.push_back(uop); - } { - asset_publish_feed_operation pop; - pop.asset_id = bit_usd; - pop.publisher = nathan_id; - price_feed feed; - feed.settlement_price = price(asset(1),asset(1, bit_usd)); - feed.call_limit = price::min(0, bit_usd); - pop.feed = feed; - trx.operations.push_back(pop); + edump((e.to_detail_string())); + throw; } - trx.sign(key_id_type(),private_key); - PUSH_TX( db, trx ); - trx.clear(); - - asset_settle_operation sop; - sop.account = nathan_id; - sop.amount = asset(50, bit_usd); - trx.operations = {sop}; - //Force settlement is disabled; check that it fails - GRAPHENE_CHECK_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); - { - //Enable force settlement - asset_update_operation op; - op.issuer = bit_usd(db).issuer; - op.asset_to_update = bit_usd; - op.new_options = bit_usd(db).options; - op.new_options.flags &= ~disable_force_settle; - trx.operations = {op}; - trx.sign(key_id_type(), private_key); - PUSH_TX( db, trx ); - trx.operations = {sop}; - } - REQUIRE_THROW_WITH_VALUE(sop, amount, asset(999999, bit_usd)); - trx.operations.back() = sop; - trx.sign(key_id_type(),private_key); - - //Partially settle a call - force_settlement_id_type settle_id = PUSH_TX( db, trx ).operation_results.front().get(); - trx.clear(); - call_order_id_type call_id = db.get_index_type().indices().get().begin()->id; - BOOST_CHECK_EQUAL(settle_id(db).balance.amount.value, 50); - BOOST_CHECK_EQUAL(call_id(db).debt.value, 3000); - BOOST_CHECK(settle_id(db).owner == nathan_id); - - generate_blocks(settle_id(db).settlement_date); - BOOST_CHECK(db.find(settle_id) == nullptr); - BOOST_CHECK_EQUAL(get_balance(nathan_id, asset_id_type()), 49); - BOOST_CHECK_EQUAL(call_id(db).debt.value, 2950); - - { - //Disable force settlement - asset_update_operation op; - op.issuer = bit_usd(db).issuer; - op.asset_to_update = bit_usd; - op.new_options = bit_usd(db).options; - op.new_options.flags |= disable_force_settle; - trx.operations.push_back(op); - trx.set_expiration(db.head_block_id()); - trx.sign(key_id_type(), private_key); - PUSH_TX( db, trx ); - //Check that force settlements were all canceled - BOOST_CHECK(db.get_index_type().indices().empty()); - BOOST_CHECK_EQUAL(get_balance(nathan_id, bit_usd), bit_usd(db).dynamic_data(db).current_supply.value); - } - } FC_LOG_AND_RETHROW() - */ } BOOST_AUTO_TEST_CASE( assert_op_test ) @@ -958,13 +1011,14 @@ BOOST_AUTO_TEST_CASE( assert_op_test ) op.fee_paying_account = nathan_id; op.predicates.emplace_back(account_name_eq_lit_predicate{ nathan_id, "nathan" }); trx.operations.push_back(op); - trx.sign(nathan_private_key); + sign( trx, nathan_private_key ); PUSH_TX( db, trx ); // nathan checks that his public key is not equal to the given value (fail) - op.predicates.back() = account_name_eq_lit_predicate{ nathan_id, "dan" }; - trx.operations.back() = op; - trx.sign(nathan_private_key); + trx.clear(); + op.predicates.emplace_back(account_name_eq_lit_predicate{ nathan_id, "dan" }); + trx.operations.push_back(op); + sign( trx, nathan_private_key ); GRAPHENE_CHECK_THROW( PUSH_TX( db, trx ), fc::exception ); } FC_LOG_AND_RETHROW() } @@ -973,6 +1027,7 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) { try { // Intentionally overriding the fixture's db; I need to control genesis on this one. database db; + const uint32_t skip_flags = database::skip_undo_history_check; fc::temp_directory td( graphene::utilities::temp_directory_path() ); genesis_state.initial_balances.push_back({generate_private_key("n").get_public_key(), GRAPHENE_SYMBOL, 1}); genesis_state.initial_balances.push_back({generate_private_key("x").get_public_key(), GRAPHENE_SYMBOL, 1}); @@ -999,6 +1054,9 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) genesis_state.initial_accounts.emplace_back("n", n_key.get_public_key()); + auto _sign = [&]( signed_transaction& tx, const private_key_type& key ) + { tx.sign( key, db.get_chain_id() ); }; + db.open(td.path(), [this]{return genesis_state;}); const balance_object& balance = balance_id_type()(db); BOOST_CHECK_EQUAL(balance.balance.amount.value, 1); @@ -1010,14 +1068,14 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) op.balance_to_claim = balance_id_type(1); op.balance_owner_key = x_key.get_public_key(); trx.operations = {op}; - trx.sign(n_key); + _sign( trx, n_key ); // Fail because I'm claiming from an address which hasn't signed - GRAPHENE_CHECK_THROW(db.push_transaction(trx), fc::exception); + GRAPHENE_CHECK_THROW(db.push_transaction(trx), tx_missing_other_auth); trx.clear(); op.balance_to_claim = balance_id_type(); op.balance_owner_key = n_key.get_public_key(); trx.operations = {op}; - trx.sign(n_key); + _sign( trx, n_key ); db.push_transaction(trx); // Not using fixture's get_balance() here because it uses fixture's db, not my override @@ -1026,8 +1084,8 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) BOOST_CHECK(db.find_object(balance_id_type(1)) != nullptr); auto slot = db.get_slot_at_time(starting_time); - db.generate_block(starting_time, db.get_scheduled_witness(slot).first, init_account_priv_key, database::skip_nothing); - trx.set_expiration(db.head_block_id()); + db.generate_block(starting_time, db.get_scheduled_witness(slot), init_account_priv_key, skip_flags); + set_expiration( db, trx ); const balance_object& vesting_balance_1 = balance_id_type(2)(db); const balance_object& vesting_balance_2 = balance_id_type(3)(db); @@ -1043,8 +1101,8 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) op.balance_owner_key = v1_key.get_public_key(); trx.clear(); trx.operations = {op}; - trx.sign(n_key); - trx.sign(v1_key); + _sign( trx, n_key ); + _sign( trx, v1_key ); // Attempting to claim 1 from a balance with 0 available GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claim_invalid_claim_amount); @@ -1053,8 +1111,8 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) op.balance_owner_key = v2_key.get_public_key(); trx.operations = {op}; trx.signatures.clear(); - trx.sign(n_key); - trx.sign(v2_key); + _sign( trx, n_key ); + _sign( trx, v2_key ); // Attempting to claim 151 from a balance with 150 available GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claim_invalid_claim_amount); @@ -1063,8 +1121,8 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) op.balance_owner_key = v2_key.get_public_key(); trx.operations = {op}; trx.signatures.clear(); - trx.sign(n_key); - trx.sign(v2_key); + _sign( trx, n_key ); + _sign( trx, v2_key ); db.push_transaction(trx); BOOST_CHECK_EQUAL(db.get_balance(op.deposit_to_account, asset_id_type()).amount.value, 101); BOOST_CHECK_EQUAL(vesting_balance_2.balance.amount.value, 300); @@ -1072,23 +1130,23 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) op.total_claimed.amount = 10; trx.operations = {op}; trx.signatures.clear(); - trx.sign(n_key); - trx.sign(v2_key); + _sign( trx, n_key ); + _sign( trx, v2_key ); // Attempting to claim twice within a day GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claim_claimed_too_often); - db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1), init_account_priv_key, skip_flags); slot = db.get_slot_at_time(vesting_balance_1.vesting_policy->begin_timestamp + 60); - db.generate_block(db.get_slot_time(slot), db.get_scheduled_witness(slot).first, init_account_priv_key, database::skip_nothing); - trx.set_expiration(db.head_block_id()); + db.generate_block(db.get_slot_time(slot), db.get_scheduled_witness(slot), init_account_priv_key, skip_flags); + set_expiration( db, trx ); op.balance_to_claim = vesting_balance_1.id; op.total_claimed.amount = 500; op.balance_owner_key = v1_key.get_public_key(); trx.operations = {op}; trx.signatures.clear(); - trx.sign(n_key); - trx.sign(v1_key); + _sign( trx, n_key ); + _sign( trx, v1_key ); db.push_transaction(trx); BOOST_CHECK(db.find_object(op.balance_to_claim) == nullptr); BOOST_CHECK_EQUAL(db.get_balance(op.deposit_to_account, asset_id_type()).amount.value, 601); @@ -1098,26 +1156,52 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) op.total_claimed.amount = 10; trx.operations = {op}; trx.signatures.clear(); - trx.sign(n_key); - trx.sign(v2_key); + _sign( trx, n_key ); + _sign( trx, v2_key ); // Attempting to claim twice within a day GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claim_claimed_too_often); - db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1).first, init_account_priv_key, database::skip_nothing); + db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1), init_account_priv_key, skip_flags); slot = db.get_slot_at_time(db.head_block_time() + fc::days(1)); - db.generate_block(db.get_slot_time(slot), db.get_scheduled_witness(slot).first, init_account_priv_key, database::skip_nothing); - trx.set_expiration(db.head_block_id()); + db.generate_block(db.get_slot_time(slot), db.get_scheduled_witness(slot), init_account_priv_key, skip_flags); + set_expiration( db, trx ); op.total_claimed = vesting_balance_2.balance; trx.operations = {op}; trx.signatures.clear(); - trx.sign(n_key); - trx.sign(v2_key); + _sign( trx, n_key ); + _sign( trx, v2_key ); db.push_transaction(trx); BOOST_CHECK(db.find_object(op.balance_to_claim) == nullptr); BOOST_CHECK_EQUAL(db.get_balance(op.deposit_to_account, asset_id_type()).amount.value, 901); } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE(transfer_with_memo) { + try { + ACTOR(alice); + ACTOR(bob); + transfer(account_id_type(), alice_id, asset(1000)); + BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 1000); + + transfer_operation op; + op.from = alice_id; + op.to = bob_id; + op.amount = asset(500); + op.memo = memo_data(); + op.memo->set_message(alice_private_key, bob_public_key, "Dear Bob,\n\nMoney!\n\nLove, Alice"); + trx.operations = {op}; + trx.sign(alice_private_key, db.get_chain_id()); + db.push_transaction(trx); + + BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 500); + BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 500); + + auto memo = db.get_recent_transaction(trx.id()).operations.front().get().memo; + BOOST_CHECK(memo); + BOOST_CHECK_EQUAL(memo->get_message(bob_private_key, alice_public_key), "Dear Bob,\n\nMoney!\n\nLove, Alice"); + } FC_LOG_AND_RETHROW() +} + // TODO: Write linear VBO tests BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/serialization_tests.cpp b/tests/tests/serialization_tests.cpp index 8094639a..5067f20b 100644 --- a/tests/tests/serialization_tests.cpp +++ b/tests/tests/serialization_tests.cpp @@ -34,10 +34,15 @@ BOOST_AUTO_TEST_CASE( serialization_raw_test ) { try { make_account(); + transfer_operation op; + op.from = account_id_type(1); + op.to = account_id_type(2); + op.amount = asset(100); + trx.operations.push_back( op ); auto packed = fc::raw::pack( trx ); signed_transaction unpacked = fc::raw::unpack(packed); unpacked.validate(); - BOOST_CHECK( trx.digest() == unpacked.digest() ); + BOOST_CHECK( digest(trx) == digest(unpacked) ); } catch (fc::exception& e) { edump((e.to_detail_string())); throw; @@ -47,10 +52,15 @@ BOOST_AUTO_TEST_CASE( serialization_json_test ) { try { make_account(); + transfer_operation op; + op.from = account_id_type(1); + op.to = account_id_type(2); + op.amount = asset(100); + trx.operations.push_back( op ); fc::variant packed(trx); signed_transaction unpacked = packed.as(); unpacked.validate(); - BOOST_CHECK( trx.digest() == unpacked.digest() ); + BOOST_CHECK( digest(trx) == digest(unpacked) ); } catch (fc::exception& e) { edump((e.to_detail_string())); throw; @@ -69,6 +79,4 @@ BOOST_AUTO_TEST_CASE( json_tests ) } } - - BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/uia_tests.cpp b/tests/tests/uia_tests.cpp index 35bf3d98..435810ea 100644 --- a/tests/tests/uia_tests.cpp +++ b/tests/tests/uia_tests.cpp @@ -29,6 +29,7 @@ #include "../common/database_fixture.hpp" using namespace graphene::chain; +using namespace graphene::chain::test; BOOST_FIXTURE_TEST_SUITE( uia_tests, database_fixture ) @@ -72,13 +73,11 @@ BOOST_AUTO_TEST_CASE( override_transfer_test ) { try { ACTORS( (dan)(eric)(sam) ); const asset_object& advanced = create_user_issued_asset( "ADVANCED", sam, override_authority ); + BOOST_TEST_MESSAGE( "Issuing 1000 ADVANCED to dan" ); issue_uia( dan, advanced.amount( 1000 ) ); - trx.validate(); - db.push_transaction(trx, ~0); - trx.operations.clear(); + BOOST_TEST_MESSAGE( "Checking dan's balance" ); BOOST_REQUIRE_EQUAL( get_balance( dan, advanced ), 1000 ); - trx.operations.clear(); override_transfer_operation otrans; otrans.issuer = advanced.issuer; otrans.from = dan.id; @@ -89,11 +88,11 @@ BOOST_AUTO_TEST_CASE( override_transfer_test ) BOOST_TEST_MESSAGE( "Require throwing without signature" ); GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, 0 ), tx_missing_active_auth ); BOOST_TEST_MESSAGE( "Require throwing with dan's signature" ); - trx.sign( dan_private_key ); + sign( trx, dan_private_key ); GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, 0 ), tx_missing_active_auth ); BOOST_TEST_MESSAGE( "Pass with issuer's signature" ); trx.signatures.clear(); - trx.sign( sam_private_key ); + sign( trx, sam_private_key ); PUSH_TX( db, trx, 0 ); BOOST_REQUIRE_EQUAL( get_balance( dan, advanced ), 900 ); @@ -105,9 +104,6 @@ BOOST_AUTO_TEST_CASE( override_transfer_test2 ) ACTORS( (dan)(eric)(sam) ); const asset_object& advanced = create_user_issued_asset( "ADVANCED", sam, 0 ); issue_uia( dan, advanced.amount( 1000 ) ); - trx.validate(); - db.push_transaction(trx, ~0); - trx.operations.clear(); BOOST_REQUIRE_EQUAL( get_balance( dan, advanced ), 1000 ); trx.operations.clear(); @@ -121,11 +117,11 @@ BOOST_AUTO_TEST_CASE( override_transfer_test2 ) BOOST_TEST_MESSAGE( "Require throwing without signature" ); GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, 0 ), fc::exception); BOOST_TEST_MESSAGE( "Require throwing with dan's signature" ); - trx.sign( dan_private_key ); + sign( trx, dan_private_key ); GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, 0 ), fc::exception); BOOST_TEST_MESSAGE( "Fail because overide_authority flag is not set" ); trx.signatures.clear(); - trx.sign( sam_private_key ); + sign( trx, sam_private_key ); GRAPHENE_REQUIRE_THROW( PUSH_TX( db, trx, 0 ), fc::exception ); BOOST_REQUIRE_EQUAL( get_balance( dan, advanced ), 1000 ); @@ -286,23 +282,76 @@ BOOST_AUTO_TEST_CASE( transfer_whitelist_uia ) } } - /** * verify that issuers can halt transfers */ -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_halt_transfers_flag_test, 1 ) -BOOST_AUTO_TEST_CASE( unimp_halt_transfers_flag_test ) +BOOST_AUTO_TEST_CASE( transfer_restricted_test ) { - BOOST_FAIL( "not implemented" ); + try + { + ACTORS( (sam)(alice)(bob) ); + + BOOST_TEST_MESSAGE( "Issuing 1000 UIA to Alice" ); + + auto _issue_uia = [&]( const account_object& recipient, asset amount ) + { + asset_issue_operation op; + op.issuer = amount.asset_id(db).issuer; + op.asset_to_issue = amount; + op.issue_to_account = recipient.id; + transaction tx; + tx.operations.push_back( op ); + set_expiration( db, tx ); + PUSH_TX( db, tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures ); + } ; + + const asset_object& uia = create_user_issued_asset( "TXRX", sam, transfer_restricted ); + _issue_uia( alice, uia.amount( 1000 ) ); + + auto _restrict_xfer = [&]( bool xfer_flag ) + { + asset_update_operation op; + op.issuer = sam_id; + op.asset_to_update = uia.id; + op.new_options = uia.options; + if( xfer_flag ) + op.new_options.flags |= transfer_restricted; + else + op.new_options.flags &= ~transfer_restricted; + transaction tx; + tx.operations.push_back( op ); + set_expiration( db, tx ); + PUSH_TX( db, tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures ); + } ; + + BOOST_TEST_MESSAGE( "Enable transfer_restricted, send fails" ); + + transfer_operation xfer_op; + xfer_op.from = alice_id; + xfer_op.to = bob_id; + xfer_op.amount = uia.amount(100); + signed_transaction xfer_tx; + xfer_tx.operations.push_back( xfer_op ); + set_expiration( db, xfer_tx ); + sign( xfer_tx, alice_private_key ); + + _restrict_xfer( true ); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, xfer_tx ), transfer_restricted_transfer_asset ); + + BOOST_TEST_MESSAGE( "Disable transfer_restricted, send succeeds" ); + + _restrict_xfer( false ); + PUSH_TX( db, xfer_tx ); + + xfer_op.amount = uia.amount(101); + + } + catch(fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } } -/** - * verify that issuers can retract funds - */ -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_fund_retraction_test, 1 ) -BOOST_AUTO_TEST_CASE( unimp_fund_retraction_test ) -{ - BOOST_FAIL( "not implemented" ); -} BOOST_AUTO_TEST_SUITE_END()