[
  {
    "path": "LICENSE",
    "content": "The MIT License\n\nCopyright (c) 2014 Andrej Karpathy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n"
  },
  {
    "path": "Readme.md",
    "content": "\n# ConvNetJS\n\nConvNetJS is a Javascript implementation of Neural networks, together with nice browser-based demos. It currently supports:\n\n- Common **Neural Network modules** (fully connected layers, non-linearities)\n- Classification (SVM/Softmax) and Regression (L2) **cost functions**\n- Ability to specify and train **Convolutional Networks** that process images\n- An experimental **Reinforcement Learning** module, based on Deep Q Learning\n\nFor much more information, see the main page at [convnetjs.com](http://convnetjs.com)\n\n**Note**: I am not actively maintaining ConvNetJS anymore because I simply don't have time. I think the npm repo might not work at this point.\n\n## Online Demos\n- [Convolutional Neural Network on MNIST digits](http://cs.stanford.edu/~karpathy/convnetjs/demo/mnist.html)\n- [Convolutional Neural Network on CIFAR-10](http://cs.stanford.edu/~karpathy/convnetjs/demo/cifar10.html)\n- [Toy 2D data](http://cs.stanford.edu/~karpathy/convnetjs/demo/classify2d.html)\n- [Toy 1D regression](http://cs.stanford.edu/~karpathy/convnetjs/demo/regression.html)\n- [Training an Autoencoder on MNIST digits](http://cs.stanford.edu/~karpathy/convnetjs/demo/autoencoder.html)\n- [Deep Q Learning Reinforcement Learning demo](http://cs.stanford.edu/people/karpathy/convnetjs/demo/rldemo.html)\n- [Image Regression (\"Painting\")](http://cs.stanford.edu/~karpathy/convnetjs/demo/image_regression.html)\n- [Comparison of SGD/Adagrad/Adadelta on MNIST](http://cs.stanford.edu/people/karpathy/convnetjs/demo/trainers.html)\n\n## Example Code\n\nHere's a minimum example of defining a **2-layer neural network** and training\nit on a single data point:\n\n```javascript\n// species a 2-layer neural network with one hidden layer of 20 neurons\nvar layer_defs = [];\n// input layer declares size of input. here: 2-D data\n// ConvNetJS works on 3-Dimensional volumes (sx, sy, depth), but if you're not dealing with images\n// then the first two dimensions (sx, sy) will always be kept at size 1\nlayer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:2});\n// declare 20 neurons, followed by ReLU (rectified linear unit non-linearity)\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'}); \n// declare the linear classifier on top of the previous hidden layer\nlayer_defs.push({type:'softmax', num_classes:10});\n\nvar net = new convnetjs.Net();\nnet.makeLayers(layer_defs);\n\n// forward a random data point through the network\nvar x = new convnetjs.Vol([0.3, -0.5]);\nvar prob = net.forward(x); \n\n// prob is a Vol. Vols have a field .w that stores the raw data, and .dw that stores gradients\nconsole.log('probability that x is class 0: ' + prob.w[0]); // prints 0.50101\n\nvar trainer = new convnetjs.SGDTrainer(net, {learning_rate:0.01, l2_decay:0.001});\ntrainer.train(x, 0); // train the network, specifying that x is class zero\n\nvar prob2 = net.forward(x);\nconsole.log('probability that x is class 0: ' + prob2.w[0]);\n// now prints 0.50374, slightly higher than previous 0.50101: the networks\n// weights have been adjusted by the Trainer to give a higher probability to\n// the class we trained the network with (zero)\n```\n\nand here is a small **Convolutional Neural Network** if you wish to predict on images:\n\n```javascript\nvar layer_defs = [];\nlayer_defs.push({type:'input', out_sx:32, out_sy:32, out_depth:3}); // declare size of input\n// output Vol is of size 32x32x3 here\nlayer_defs.push({type:'conv', sx:5, filters:16, stride:1, pad:2, activation:'relu'});\n// the layer will perform convolution with 16 kernels, each of size 5x5.\n// the input will be padded with 2 pixels on all sides to make the output Vol of the same size\n// output Vol will thus be 32x32x16 at this point\nlayer_defs.push({type:'pool', sx:2, stride:2});\n// output Vol is of size 16x16x16 here\nlayer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});\n// output Vol is of size 16x16x20 here\nlayer_defs.push({type:'pool', sx:2, stride:2});\n// output Vol is of size 8x8x20 here\nlayer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});\n// output Vol is of size 8x8x20 here\nlayer_defs.push({type:'pool', sx:2, stride:2});\n// output Vol is of size 4x4x20 here\nlayer_defs.push({type:'softmax', num_classes:10});\n// output Vol is of size 1x1x10 here\n\nnet = new convnetjs.Net();\nnet.makeLayers(layer_defs);\n\n// helpful utility for converting images into Vols is included\nvar x = convnetjs.img_to_vol(document.getElementById('some_image'))\nvar output_probabilities_vol = net.forward(x)\n```\n\n## Getting Started\nA [Getting Started](http://cs.stanford.edu/people/karpathy/convnetjs/started.html) tutorial is available on main page.\n\nThe full [Documentation](http://cs.stanford.edu/people/karpathy/convnetjs/docs.html) can also be found there.\n\nSee the **releases** page for this project to get the minified, compiled library, and a direct link to is also available below for convenience (but please host your own copy)\n\n- [convnet.js](http://cs.stanford.edu/people/karpathy/convnetjs/build/convnet.js)\n- [convnet-min.js](http://cs.stanford.edu/people/karpathy/convnetjs/build/convnet-min.js)\n\n## Compiling the library from src/ to build/\nIf you would like to add features to the library, you will have to change the code in `src/` and then compile the library into the `build/` directory. The compilation script simply concatenates files in `src/` and then minifies the result.\n\nThe compilation is done using an ant task: it compiles `build/convnet.js` by concatenating the source files in `src/` and then minifies the result into `build/convnet-min.js`. Make sure you have **ant** installed (on Ubuntu you can simply *sudo apt-get install* it), then cd into `compile/` directory and run:\n\n    $ ant -lib yuicompressor-2.4.8.jar -f build.xml\n\nThe output files will be in `build/`\n## Use in Node\nThe library is also available on *node.js*:\n\n1. Install it: `$ npm install convnetjs`\n2. Use it: `var convnetjs = require(\"convnetjs\");`\n\n## License\nMIT\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"convnetjs\",\n  \"version\": \"0.0.0\",\n  \"authors\": [\n    \"Andrej Karpathy <andrej.karpathy@gmail.com>\"\n  ],\n  \"description\": \"Deep Learning in Javascript. Train Convolutional Neural Networks (or ordinary ones) in your browser.\",\n  \"main\": \"build/convnet.js\",\n  \"moduleType\": [\n    \"amd\",\n    \"es6\",\n    \"globals\",\n    \"node\",\n    \"yui\"\n  ],\n  \"keywords\": [\n    \"machine\",\n    \"learning\",\n    \"AI\",\n    \"convnet\"\n  ],\n  \"license\": \"MIT\",\n  \"homepage\": \"http://cs.stanford.edu/people/karpathy/convnetjs/\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ]\n}\n"
  },
  {
    "path": "build/deepqlearn.js",
    "content": "var deepqlearn = deepqlearn || { REVISION: 'ALPHA' };\r\n\r\n(function(global) {\r\n  \"use strict\";\r\n  \r\n  // An agent is in state0 and does action0\r\n  // environment then assigns reward0 and provides new state, state1\r\n  // Experience nodes store all this information, which is used in the\r\n  // Q-learning update step\r\n  var Experience = function(state0, action0, reward0, state1) {\r\n    this.state0 = state0;\r\n    this.action0 = action0;\r\n    this.reward0 = reward0;\r\n    this.state1 = state1;\r\n  }\r\n\r\n  // A Brain object does all the magic.\r\n  // over time it receives some inputs and some rewards\r\n  // and its job is to set the outputs to maximize the expected reward\r\n  var Brain = function(num_states, num_actions, opt) {\r\n    var opt = opt || {};\r\n    // in number of time steps, of temporal memory\r\n    // the ACTUAL input to the net will be (x,a) temporal_window times, and followed by current x\r\n    // so to have no information from previous time step going into value function, set to 0.\r\n    this.temporal_window = typeof opt.temporal_window !== 'undefined' ? opt.temporal_window : 1; \r\n    // size of experience replay memory\r\n    this.experience_size = typeof opt.experience_size !== 'undefined' ? opt.experience_size : 30000;\r\n    // number of examples in experience replay memory before we begin learning\r\n    this.start_learn_threshold = typeof opt.start_learn_threshold !== 'undefined'? opt.start_learn_threshold : Math.floor(Math.min(this.experience_size*0.1, 1000)); \r\n    // gamma is a crucial parameter that controls how much plan-ahead the agent does. In [0,1]\r\n    this.gamma = typeof opt.gamma !== 'undefined' ? opt.gamma : 0.8;\r\n    \r\n    // number of steps we will learn for\r\n    this.learning_steps_total = typeof opt.learning_steps_total !== 'undefined' ? opt.learning_steps_total : 100000;\r\n    // how many steps of the above to perform only random actions (in the beginning)?\r\n    this.learning_steps_burnin = typeof opt.learning_steps_burnin !== 'undefined' ? opt.learning_steps_burnin : 3000;\r\n    // what epsilon value do we bottom out on? 0.0 => purely deterministic policy at end\r\n    this.epsilon_min = typeof opt.epsilon_min !== 'undefined' ? opt.epsilon_min : 0.05;\r\n    // what epsilon to use at test time? (i.e. when learning is disabled)\r\n    this.epsilon_test_time = typeof opt.epsilon_test_time !== 'undefined' ? opt.epsilon_test_time : 0.01;\r\n    \r\n    // advanced feature. Sometimes a random action should be biased towards some values\r\n    // for example in flappy bird, we may want to choose to not flap more often\r\n    if(typeof opt.random_action_distribution !== 'undefined') {\r\n      // this better sum to 1 by the way, and be of length this.num_actions\r\n      this.random_action_distribution = opt.random_action_distribution;\r\n      if(this.random_action_distribution.length !== num_actions) {\r\n        console.log('TROUBLE. random_action_distribution should be same length as num_actions.');\r\n      }\r\n      var a = this.random_action_distribution;\r\n      var s = 0.0; for(var k=0;k<a.length;k++) { s+= a[k]; }\r\n      if(Math.abs(s-1.0)>0.0001) { console.log('TROUBLE. random_action_distribution should sum to 1!'); }\r\n    } else {\r\n      this.random_action_distribution = [];\r\n    }\r\n    \r\n    // states that go into neural net to predict optimal action look as\r\n    // x0,a0,x1,a1,x2,a2,...xt\r\n    // this variable controls the size of that temporal window. Actions are\r\n    // encoded as 1-of-k hot vectors\r\n    this.net_inputs = num_states * this.temporal_window + num_actions * this.temporal_window + num_states;\r\n    this.num_states = num_states;\r\n    this.num_actions = num_actions;\r\n    this.window_size = Math.max(this.temporal_window, 2); // must be at least 2, but if we want more context even more\r\n    this.state_window = new Array(this.window_size);\r\n    this.action_window = new Array(this.window_size);\r\n    this.reward_window = new Array(this.window_size);\r\n    this.net_window = new Array(this.window_size);\r\n    \r\n    // create [state -> value of all possible actions] modeling net for the value function\r\n    var layer_defs = [];\r\n    if(typeof opt.layer_defs !== 'undefined') {\r\n      // this is an advanced usage feature, because size of the input to the network, and number of\r\n      // actions must check out. This is not very pretty Object Oriented programming but I can't see\r\n      // a way out of it :(\r\n      layer_defs = opt.layer_defs;\r\n      if(layer_defs.length < 2) { console.log('TROUBLE! must have at least 2 layers'); }\r\n      if(layer_defs[0].type !== 'input') { console.log('TROUBLE! first layer must be input layer!'); }\r\n      if(layer_defs[layer_defs.length-1].type !== 'regression') { console.log('TROUBLE! last layer must be input regression!'); }\r\n      if(layer_defs[0].out_depth * layer_defs[0].out_sx * layer_defs[0].out_sy !== this.net_inputs) {\r\n        console.log('TROUBLE! Number of inputs must be num_states * temporal_window + num_actions * temporal_window + num_states!');\r\n      }\r\n      if(layer_defs[layer_defs.length-1].num_neurons !== this.num_actions) {\r\n        console.log('TROUBLE! Number of regression neurons should be num_actions!');\r\n      }\r\n    } else {\r\n      // create a very simple neural net by default\r\n      layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:this.net_inputs});\r\n      if(typeof opt.hidden_layer_sizes !== 'undefined') {\r\n        // allow user to specify this via the option, for convenience\r\n        var hl = opt.hidden_layer_sizes;\r\n        for(var k=0;k<hl.length;k++) {\r\n          layer_defs.push({type:'fc', num_neurons:hl[k], activation:'relu'}); // relu by default\r\n        }\r\n      }\r\n      layer_defs.push({type:'regression', num_neurons:num_actions}); // value function output\r\n    }\r\n    this.value_net = new convnetjs.Net();\r\n    this.value_net.makeLayers(layer_defs);\r\n    \r\n    // and finally we need a Temporal Difference Learning trainer!\r\n    var tdtrainer_options = {learning_rate:0.01, momentum:0.0, batch_size:64, l2_decay:0.01};\r\n    if(typeof opt.tdtrainer_options !== 'undefined') {\r\n      tdtrainer_options = opt.tdtrainer_options; // allow user to overwrite this\r\n    }\r\n    this.tdtrainer = new convnetjs.SGDTrainer(this.value_net, tdtrainer_options);\r\n    \r\n    // experience replay\r\n    this.experience = [];\r\n    \r\n    // various housekeeping variables\r\n    this.age = 0; // incremented every backward()\r\n    this.forward_passes = 0; // incremented every forward()\r\n    this.epsilon = 1.0; // controls exploration exploitation tradeoff. Should be annealed over time\r\n    this.latest_reward = 0;\r\n    this.last_input_array = [];\r\n    this.average_reward_window = new cnnutil.Window(1000, 10);\r\n    this.average_loss_window = new cnnutil.Window(1000, 10);\r\n    this.learning = true;\r\n  }\r\n  Brain.prototype = {\r\n    random_action: function() {\r\n      // a bit of a helper function. It returns a random action\r\n      // we are abstracting this away because in future we may want to \r\n      // do more sophisticated things. For example some actions could be more\r\n      // or less likely at \"rest\"/default state.\r\n      if(this.random_action_distribution.length === 0) {\r\n        return convnetjs.randi(0, this.num_actions);\r\n      } else {\r\n        // okay, lets do some fancier sampling:\r\n        var p = convnetjs.randf(0, 1.0);\r\n        var cumprob = 0.0;\r\n        for(var k=0;k<this.num_actions;k++) {\r\n          cumprob += this.random_action_distribution[k];\r\n          if(p < cumprob) { return k; }\r\n        }\r\n      }\r\n    },\r\n    policy: function(s) {\r\n      // compute the value of doing any action in this state\r\n      // and return the argmax action and its value\r\n      var svol = new convnetjs.Vol(1, 1, this.net_inputs);\r\n      svol.w = s;\r\n      var action_values = this.value_net.forward(svol);\r\n      var maxk = 0; \r\n      var maxval = action_values.w[0];\r\n      for(var k=1;k<this.num_actions;k++) {\r\n        if(action_values.w[k] > maxval) { maxk = k; maxval = action_values.w[k]; }\r\n      }\r\n      return {action:maxk, value:maxval};\r\n    },\r\n    getNetInput: function(xt) {\r\n      // return s = (x,a,x,a,x,a,xt) state vector. \r\n      // It's a concatenation of last window_size (x,a) pairs and current state x\r\n      var w = [];\r\n      w = w.concat(xt); // start with current state\r\n      // and now go backwards and append states and actions from history temporal_window times\r\n      var n = this.window_size; \r\n      for(var k=0;k<this.temporal_window;k++) {\r\n        // state\r\n        w = w.concat(this.state_window[n-1-k]);\r\n        // action, encoded as 1-of-k indicator vector. We scale it up a bit because\r\n        // we dont want weight regularization to undervalue this information, as it only exists once\r\n        var action1ofk = new Array(this.num_actions);\r\n        for(var q=0;q<this.num_actions;q++) action1ofk[q] = 0.0;\r\n        action1ofk[this.action_window[n-1-k]] = 1.0*this.num_states;\r\n        w = w.concat(action1ofk);\r\n      }\r\n      return w;\r\n    },\r\n    forward: function(input_array) {\r\n      // compute forward (behavior) pass given the input neuron signals from body\r\n      this.forward_passes += 1;\r\n      this.last_input_array = input_array; // back this up\r\n      \r\n      // create network input\r\n      var action;\r\n      if(this.forward_passes > this.temporal_window) {\r\n        // we have enough to actually do something reasonable\r\n        var net_input = this.getNetInput(input_array);\r\n        if(this.learning) {\r\n          // compute epsilon for the epsilon-greedy policy\r\n          this.epsilon = Math.min(1.0, Math.max(this.epsilon_min, 1.0-(this.age - this.learning_steps_burnin)/(this.learning_steps_total - this.learning_steps_burnin))); \r\n        } else {\r\n          this.epsilon = this.epsilon_test_time; // use test-time value\r\n        }\r\n        var rf = convnetjs.randf(0,1);\r\n        if(rf < this.epsilon) {\r\n          // choose a random action with epsilon probability\r\n          action = this.random_action();\r\n        } else {\r\n          // otherwise use our policy to make decision\r\n          var maxact = this.policy(net_input);\r\n          action = maxact.action;\r\n       }\r\n      } else {\r\n        // pathological case that happens first few iterations \r\n        // before we accumulate window_size inputs\r\n        var net_input = [];\r\n        action = this.random_action();\r\n      }\r\n      \r\n      // remember the state and action we took for backward pass\r\n      this.net_window.shift();\r\n      this.net_window.push(net_input);\r\n      this.state_window.shift(); \r\n      this.state_window.push(input_array);\r\n      this.action_window.shift(); \r\n      this.action_window.push(action);\r\n      \r\n      return action;\r\n    },\r\n    backward: function(reward) {\r\n      this.latest_reward = reward;\r\n      this.average_reward_window.add(reward);\r\n      this.reward_window.shift();\r\n      this.reward_window.push(reward);\r\n      \r\n      if(!this.learning) { return; } \r\n      \r\n      // various book-keeping\r\n      this.age += 1;\r\n      \r\n      // it is time t+1 and we have to store (s_t, a_t, r_t, s_{t+1}) as new experience\r\n      // (given that an appropriate number of state measurements already exist, of course)\r\n      if(this.forward_passes > this.temporal_window + 1) {\r\n        var e = new Experience();\r\n        var n = this.window_size;\r\n        e.state0 = this.net_window[n-2];\r\n        e.action0 = this.action_window[n-2];\r\n        e.reward0 = this.reward_window[n-2];\r\n        e.state1 = this.net_window[n-1];\r\n        if(this.experience.length < this.experience_size) {\r\n          this.experience.push(e);\r\n        } else {\r\n          // replace. finite memory!\r\n          var ri = convnetjs.randi(0, this.experience_size);\r\n          this.experience[ri] = e;\r\n        }\r\n      }\r\n      \r\n      // learn based on experience, once we have some samples to go on\r\n      // this is where the magic happens...\r\n      if(this.experience.length > this.start_learn_threshold) {\r\n        var avcost = 0.0;\r\n        for(var k=0;k < this.tdtrainer.batch_size;k++) {\r\n          var re = convnetjs.randi(0, this.experience.length);\r\n          var e = this.experience[re];\r\n          var x = new convnetjs.Vol(1, 1, this.net_inputs);\r\n          x.w = e.state0;\r\n          var maxact = this.policy(e.state1);\r\n          var r = e.reward0 + this.gamma * maxact.value;\r\n          var ystruct = {dim: e.action0, val: r};\r\n          var loss = this.tdtrainer.train(x, ystruct);\r\n          avcost += loss.loss;\r\n        }\r\n        avcost = avcost/this.tdtrainer.batch_size;\r\n        this.average_loss_window.add(avcost);\r\n      }\r\n    },\r\n    visSelf: function(elt) {\r\n      elt.innerHTML = ''; // erase elt first\r\n      \r\n      // elt is a DOM element that this function fills with brain-related information\r\n      var brainvis = document.createElement('div');\r\n      \r\n      // basic information\r\n      var desc = document.createElement('div');\r\n      var t = '';\r\n      t += 'experience replay size: ' + this.experience.length + '<br>';\r\n      t += 'exploration epsilon: ' + this.epsilon + '<br>';\r\n      t += 'age: ' + this.age + '<br>';\r\n      t += 'average Q-learning loss: ' + this.average_loss_window.get_average() + '<br />';\r\n      t += 'smooth-ish reward: ' + this.average_reward_window.get_average() + '<br />';\r\n      desc.innerHTML = t;\r\n      brainvis.appendChild(desc);\r\n      \r\n      elt.appendChild(brainvis);\r\n    }\r\n  }\r\n  \r\n  global.Brain = Brain;\r\n})(deepqlearn);\r\n\r\n(function(lib) {\r\n  \"use strict\";\r\n  if (typeof module === \"undefined\" || typeof module.exports === \"undefined\") {\r\n    window.deepqlearn = lib; // in ordinary browser attach library to window\r\n  } else {\r\n    module.exports = lib; // in nodejs\r\n  }\r\n})(deepqlearn);\r\n"
  },
  {
    "path": "build/util.js",
    "content": "\n// contains various utility functions \nvar cnnutil = (function(exports){\n\n  // a window stores _size_ number of values\n  // and returns averages. Useful for keeping running\n  // track of validation or training accuracy during SGD\n  var Window = function(size, minsize) {\n    this.v = [];\n    this.size = typeof(size)==='undefined' ? 100 : size;\n    this.minsize = typeof(minsize)==='undefined' ? 20 : minsize;\n    this.sum = 0;\n  }\n  Window.prototype = {\n    add: function(x) {\n      this.v.push(x);\n      this.sum += x;\n      if(this.v.length>this.size) {\n        var xold = this.v.shift();\n        this.sum -= xold;\n      }\n    },\n    get_average: function() {\n      if(this.v.length < this.minsize) return -1;\n      else return this.sum/this.v.length;\n    },\n    reset: function(x) {\n      this.v = [];\n      this.sum = 0;\n    }\n  }\n\n  // returns min, max and indeces of an array\n  var maxmin = function(w) {\n    if(w.length === 0) { return {}; } // ... ;s\n\n    var maxv = w[0];\n    var minv = w[0];\n    var maxi = 0;\n    var mini = 0;\n    for(var i=1;i<w.length;i++) {\n      if(w[i] > maxv) { maxv = w[i]; maxi = i; } \n      if(w[i] < minv) { minv = w[i]; mini = i; } \n    }\n    return {maxi: maxi, maxv: maxv, mini: mini, minv: minv, dv:maxv-minv};\n  }\n\n  // returns string representation of float\n  // but truncated to length of d digits\n  var f2t = function(x, d) {\n    if(typeof(d)==='undefined') { var d = 5; }\n    var dd = 1.0 * Math.pow(10, d);\n    return '' + Math.floor(x*dd)/dd;\n  }\n\n  exports = exports || {};\n  exports.Window = Window;\n  exports.maxmin = maxmin;\n  exports.f2t = f2t;\n  return exports;\n\n})(typeof module != 'undefined' && module.exports);  // add exports to module.exports if in node.js\n\n\n"
  },
  {
    "path": "build/vis.js",
    "content": "\n// contains various utility functions \nvar cnnvis = (function(exports){\n\n  // can be used to graph loss, or accuract over time\n  var Graph = function(options) {\n    var options = options || {};\n    this.step_horizon = options.step_horizon || 1000;\n    \n    this.pts = [];\n    \n    this.maxy = -9999;\n    this.miny = 9999;\n  }\n\n  Graph.prototype = {\n    // canv is the canvas we wish to update with this new datapoint\n    add: function(step, y) {\n      var time = new Date().getTime(); // in ms\n      if(y>this.maxy*0.99) this.maxy = y*1.05;\n      if(y<this.miny*1.01) this.miny = y*0.95;\n\n      this.pts.push({step: step, time: time, y: y});\n      if(step > this.step_horizon) this.step_horizon *= 2;\n    },\n    // elt is a canvas we wish to draw into\n    drawSelf: function(canv) {\n      \n      var pad = 25;\n      var H = canv.height;\n      var W = canv.width;\n      var ctx = canv.getContext('2d');\n\n      ctx.clearRect(0, 0, W, H);\n      ctx.font=\"10px Georgia\";\n\n      var f2t = function(x) {\n        var dd = 1.0 * Math.pow(10, 2);\n        return '' + Math.floor(x*dd)/dd;\n      }\n\n      // draw guidelines and values\n      ctx.strokeStyle = \"#999\";\n      ctx.beginPath();\n      var ng = 10;\n      for(var i=0;i<=ng;i++) {\n        var xpos = i/ng*(W-2*pad)+pad;\n        ctx.moveTo(xpos, pad);\n        ctx.lineTo(xpos, H-pad);\n        ctx.fillText(f2t(i/ng*this.step_horizon/1000)+'k',xpos,H-pad+14);\n      }\n      for(var i=0;i<=ng;i++) {\n        var ypos = i/ng*(H-2*pad)+pad;\n        ctx.moveTo(pad, ypos);\n        ctx.lineTo(W-pad, ypos);\n        ctx.fillText(f2t((ng-i)/ng*(this.maxy-this.miny) + this.miny), 0, ypos);\n      }\n      ctx.stroke();\n\n      var N = this.pts.length;\n      if(N<2) return;\n\n      // draw the actual curve\n      var t = function(x, y, s) {\n        var tx = x / s.step_horizon * (W-pad*2) + pad;\n        var ty = H - ((y-s.miny) / (s.maxy-s.miny) * (H-pad*2) + pad);\n        return {tx:tx, ty:ty}\n      }\n\n      ctx.strokeStyle = \"red\";\n      ctx.beginPath()\n      for(var i=0;i<N;i++) {\n        // draw line from i-1 to i\n        var p = this.pts[i];\n        var pt = t(p.step, p.y, this);\n        if(i===0) ctx.moveTo(pt.tx, pt.ty);\n        else ctx.lineTo(pt.tx, pt.ty);\n      }\n      ctx.stroke();\n    }\n  }\n\n  // same as graph but draws multiple lines. For now I'm lazy and duplicating\n  // the code, but in future I will merge these two more nicely.\n  var MultiGraph = function(legend, options) {\n    var options = options || {};\n    this.step_horizon = options.step_horizon || 1000;\n\n    if(typeof options.maxy !== 'undefined') this.maxy_forced = options.maxy;\n    if(typeof options.miny !== 'undefined') this.miny_forced = options.miny;\n\n    this.pts = [];\n    \n    this.maxy = -9999;\n    this.miny = 9999;\n    this.numlines = 0;\n\n    this.numlines = legend.length;\n    this.legend = legend;\n    this.styles = [\"red\", \"blue\", \"green\", \"black\", \"magenta\", \"cyan\", \"purple\", \"aqua\", \"olive\", \"lime\", \"navy\"];\n    // 17 basic colors: aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, orange, purple, red, silver, teal, white, and yellow\n  }\n\n  MultiGraph.prototype = {\n    // canv is the canvas we wish to update with this new datapoint\n    add: function(step, yl) {\n      var time = new Date().getTime(); // in ms\n      var n = yl.length;\n      for(var k=0;k<n;k++) {\n        var y = yl[k];\n        if(y>this.maxy*0.99) this.maxy = y*1.05;\n        if(y<this.miny*1.01) this.miny = y*0.95;\n      }\n\n      if(typeof this.maxy_forced !== 'undefined') this.maxy = this.maxy_forced;\n      if(typeof this.miny_forced !== 'undefined') this.miny = this.miny_forced;\n\n      this.pts.push({step: step, time: time, yl: yl});\n      if(step > this.step_horizon) this.step_horizon *= 2;\n    },\n    // elt is a canvas we wish to draw into\n    drawSelf: function(canv) {\n      \n      var pad = 25;\n      var H = canv.height;\n      var W = canv.width;\n      var ctx = canv.getContext('2d');\n\n      ctx.clearRect(0, 0, W, H);\n      ctx.font=\"10px Georgia\";\n\n      var f2t = function(x) {\n        var dd = 1.0 * Math.pow(10, 2);\n        return '' + Math.floor(x*dd)/dd;\n      }\n\n      // draw guidelines and values\n      ctx.strokeStyle = \"#999\";\n      ctx.beginPath();\n      var ng = 10;\n      for(var i=0;i<=ng;i++) {\n        var xpos = i/ng*(W-2*pad)+pad;\n        ctx.moveTo(xpos, pad);\n        ctx.lineTo(xpos, H-pad);\n        ctx.fillText(f2t(i/ng*this.step_horizon/1000)+'k',xpos,H-pad+14);\n      }\n      for(var i=0;i<=ng;i++) {\n        var ypos = i/ng*(H-2*pad)+pad;\n        ctx.moveTo(pad, ypos);\n        ctx.lineTo(W-pad, ypos);\n        ctx.fillText(f2t((ng-i)/ng*(this.maxy-this.miny) + this.miny), 0, ypos);\n      }\n      ctx.stroke();\n\n      var N = this.pts.length;\n      if(N<2) return;\n\n      // draw legend\n      for(var k=0;k<this.numlines;k++) {\n        ctx.fillStyle = this.styles[k % this.styles.length];\n        ctx.fillText(this.legend[k], W-pad-100, pad+20+k*16);\n      }\n      ctx.fillStyle = \"black\";\n\n      // draw the actual curve\n      var t = function(x, y, s) {\n        var tx = x / s.step_horizon * (W-pad*2) + pad;\n        var ty = H - ((y-s.miny) / (s.maxy-s.miny) * (H-pad*2) + pad);\n        return {tx:tx, ty:ty}\n      }\n      for(var k=0;k<this.numlines;k++) {\n\n        ctx.strokeStyle = this.styles[k % this.styles.length];\n        ctx.beginPath()\n        for(var i=0;i<N;i++) {\n          // draw line from i-1 to i\n          var p = this.pts[i];\n          var pt = t(p.step, p.yl[k], this);\n          if(i===0) ctx.moveTo(pt.tx, pt.ty);\n          else ctx.lineTo(pt.tx, pt.ty);\n        }\n        ctx.stroke();\n      }\n\n    }\n  }\n\n  exports = exports || {};\n  exports.Graph = Graph;\n  exports.MultiGraph = MultiGraph;\n  return exports;\n\n})(typeof module != 'undefined' && module.exports);  // add exports to module.exports if in node.js\n\n\n"
  },
  {
    "path": "compile/build.xml",
    "content": "<project name=\"Build\" default=\"compress\">\n  <target name=\"concatenate\">\n    <concat destfile=\"../build/convnet.js\" encoding=\"UTF-8\" outputencoding=\"UTF-8\" fixlastline=\"true\">\n      <filelist id=\"filelist\" dir=\"../src\">\n        <file name=\"convnet_init.js\"/>\n        <file name=\"convnet_util.js\" />\n        <file name=\"convnet_vol.js\" />\n        <file name=\"convnet_vol_util.js\" />\n        <file name=\"convnet_layers_dotproducts.js\" />\n        <file name=\"convnet_layers_pool.js\" />\n        <file name=\"convnet_layers_input.js\" />\n        <file name=\"convnet_layers_loss.js\" />\n        <file name=\"convnet_layers_nonlinearities.js\" />\n        <file name=\"convnet_layers_dropout.js\" />\n        <file name=\"convnet_layers_normalization.js\" />\n        <file name=\"convnet_net.js\" />\n        <file name=\"convnet_trainers.js\" />\n        <file name=\"convnet_magicnet.js\" />\n        <file name=\"convnet_export.js\" />\n      </filelist>\n    </concat>\n  </target>\n  <target name=\"compress\" depends=\"concatenate\" description=\"Minify convnet.js to convnet-min.js\">\n    <apply executable=\"java\" parallel=\"false\">\n      <filelist dir=\"../build\" files=\"convnet.js\" />\n      <arg line=\"-jar\" />\n      <arg path=\"yuicompressor-2.4.8.jar\" />\n      <srcfile />\n      <arg line=\"-o\" />\n      <mapper type=\"glob\" from=\"*.js\" to=\"../build/*-min.js\" />\n      <targetfile />\n    </apply>\n  </target>\n</project>\n"
  },
  {
    "path": "demo/autoencoder.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>ConvNetJS MNIST demo</title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"author\" content=\"\">\n  <link rel=\"stylesheet\" href=\"css/style.css\">\n</head>\n\n<script src=\"js/jquery-1.8.3.min.js\"></script>\n<script src=\"../build/vis.js\"></script>\n<script src=\"../build/util.js\"></script>\n<script src=\"../build/convnet.js\"></script>\n\n\n<script src=\"mnist/mnist_labels.js\"></script>\n<script src=\"js/autoencoder.js\"></script>\n\n<body>\n  <div id=\"wrap\">\n  <h2 style=\"text-align: center;\"><a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">ConvNetJS</a> Denoising Autoencoder demo</h2>\n  <h1>Description</h1>\n  <p>\n    All the other demos are examples of Supervised Learning, so in this demo I wanted to show an example of Unsupervised Learning. We are going to train an autoencoder on MNIST digits.\n  </p>\n  <p>\n    An autoencoder is a regression task where the network is asked to predict its input (in other words, model the identity function). Sounds simple enough, except the network has a tight bottleneck of a few neurons in the middle (in the default example only two!), forcing it to create effective representations that compress the input into a low-dimensional code that can be used by the decoder to reproduce the original input.\n  </p>\n  <p>Report questions/bugs/suggestions to <a href=\"https://twitter.com/karpathy\">@karpathy</a>.\n  </p>\n  <h1>Training Stats</h1>\n  <div class=\"divsec\" style=\"270px;\">\n    <div class=\"secpart\">\n      Current image: <img id=\"input_image\" src=\"\"></img><input id=\"buttontp\" type=\"submit\" value=\"pause\" onclick=\"toggle_pause();\"/>\n      <div id=\"trainstats\"></div>\n\n      <div id=\"controls\">\n        Learning rate: <input name=\"lri\" type=\"text\" maxlength=\"20\" id=\"lr_input\"/>\n        <input id=\"buttonlr\" type=\"submit\" value=\"change\" onclick=\"change_lr();\"/>\n        <br />\n      </div>\n\n      <input id=\"buttondj\" type=\"submit\" value=\"save network snapshot as JSON\" onclick=\"dump_json();\"/><br />\n      <input id=\"buttonlfj\" type=\"submit\" value=\"init network from JSON snapshot\" onclick=\"load_from_json();\"/><br />\n      <textarea id=\"dumpjson\"></textarea>\n    </div>\n    <div class=\"secpart\">\n      \n      <div>\n        Loss:<br />\n        <canvas id=\"lossgraph\">\n        </canvas>\n        <br />\n        <input id=\"buttoncg\" type=\"submit\" value=\"clear graph\" onclick=\"clear_graph();\"/>\n      </div>\n\n    </div>\n    <div>\n      <textarea id=\"newnet\" style=\"width:100%; height:100px;\"></textarea><br />\n      <input id=\"buttonnn\" type=\"submit\" value=\"reload\" onclick=\"change_net();\" style=\"width:200px; height: 40px;\"/>\n    </div>\n\n    <div style=\"margin-top: 1px solid #000; margin-top:20px;\">\n      <div id=\"layer_ixes\"></div>\n      <input id=\"buttoncycle\" type=\"submit\" value=\"cycle through visualized neurons at selected layer (if more than 2)\" onclick=\"cycle();\" style=\"height: 40px;\"/>\n      <div id=\"cyclestatus\"></div>\n      <div style=\"text-align:center;\"><canvas id=\"embedding\" width=\"500\" height=\"500\"></canvas></div>\n    </div>\n\n    <div style=\"clear:both;\"></div>\n  </div>\n\n  <div class=\"divsec\">\n  <h1>Network Visualization</h1>\n    <div id=\"visnet\"></div>\n  </div>\n\n  </div>  \n</body>\n</html>\n\n\n\n"
  },
  {
    "path": "demo/automatic.html",
    "content": "<!doctype html>\r\n<html lang=\"en\">\r\n <head>\r\n  <meta charset=\"utf-8\">\r\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\r\n  <title>ConvNetJS Automatic</title>\r\n  <meta name=\"description\" content=\"\">\r\n  <meta name=\"author\" content=\"\">\r\n  <link href='http://fonts.googleapis.com/css?family=Lato:300,400,900' rel='stylesheet' type='text/css'>\r\n\r\n  <script src=\"../build/convnet.js\"></script>\r\n  <script src=\"../build/util.js\"></script>\r\n  <script src=\"../build/vis.js\"></script>\r\n  <script src=\"js/jquery-1.8.3.min.js\"></script>\r\n  <script src=\"js/jquery.csv-0.71.min.js\"></script>\r\n  \r\n  <!-- JS syntax highlighting -->\r\n  <script type=\"text/javascript\" src=\"../syntaxhighlighter_3.0.83/scripts/shCore.js\"></script>\r\n  <script type=\"text/javascript\" src=\"../syntaxhighlighter_3.0.83/scripts/shBrushJScript.js\"></script>\r\n  <link type=\"text/css\" rel=\"stylesheet\" href=\"../syntaxhighlighter_3.0.83/styles/shCoreDefault.css\"/>\r\n  <script type=\"text/javascript\">SyntaxHighlighter.all();</script>\r\n\r\n  <link rel=\"stylesheet\" href=\"css/automatic.css\">\r\n  \r\n  <script src=\"js/automatic.js\"></script>\r\n </head>\r\n <body onload=\"start();\">\r\n  <div id=\"wrap\">\r\n    <h2>ConvNetJS Automatic Prediction Demo</h2>\r\n    <h1>Introduction</h1>\r\n    <p>\r\n    This demo illustrates the usage of ConvNetJS' <b>MagicNet</b> class, which performs fully automatic prediction given your arbitrary data. Internally, the MagicNet tries out many different types of networks, performs cross-validations of network hyper-parameters across folds of your data, and creates a final classifier by model averaging the best architectures. The API for MagicNet looks as follows:\r\n    </p>\r\n\r\n<pre class=\"brush: js; toolbar: false;\">\r\nvar opts = {}; // options struct\r\nopts.train_ratio = 0.7;\r\nopts.num_folds = 10; // number of folds to eval per candidate\r\nopts.num_candidates = 10; // number of candidates to eval in parallel\r\nopts.num_epochs = 50; // epochs to make through data per fold\r\n// below, train_data is a list of input Vols and train_labels is a \r\n// list of integer correct labels (in 0...K).\r\nvar magicNet = new convnetjs.MagicNet(train_data, train_labels, opts);\r\nmagicNet.onFinishBatch(finishedBatch); // example of setting callback for events\r\n\r\n// start training magicNet. Every step() call all candidates train on one example\r\nsetInterval(function(){ magicNet.step() }, 0);\r\n\r\n// once at least one batch of candidates is evaluated on all folds we can do prediction!\r\nfunction finishedBatch() {\r\n  // prediction example. xout is Vol of scores\r\n  // there is also predict_soft(), which returns the full score volume for all labels\r\n  var predicted_label = magicNet.predict(some_test_vol);\r\n}\r\n</pre>\r\n\r\n    <h1>Your data</h1>\r\n    <p>\r\n      Currently made input data assumptions:\r\n    </p>\r\n    <ul>\r\n      <li>Provide data as CSV (comma-separated) values. Leave out any header rows.</li>\r\n      <li>Every row is a data point.</li>\r\n      <li>No missing values.</li>\r\n      <li>Last column is the class (only classification is currently supported).</li>\r\n    </ul>\r\n    <p>\r\n      The text area is pre-filled with a Car Quality Evaluation dataset to show you example input, but there are a few buttons that load some example datasets (more details on these: <a href=\"https://archive.ics.uci.edu/ml/datasets/Iris\">Iris data</a>, <a href=\"https://archive.ics.uci.edu/ml/datasets/Car+Evaluation\">Car Eval data</a>, <a href=\"https://archive.ics.uci.edu/ml/datasets/Yeast\">Yeast Data</a>). A nice place to find more datasets are <a href=\"https://archive.ics.uci.edu/ml/datasets.html?format=mat&task=cla&att=&area=&numAtt=&numIns=&type=&sort=dateDown&view=table\">UCI Repository</a> or <a href=\"http://mldata.org/repository/data/by_views/\">mldata.org</a>.\r\n    </p>\r\n\r\n    <div style=\"text-align: center;\">\r\n      <button class=\"clouds-flat-button\" onclick=\"loadDB('data/iris.data.txt')\" style=\"height: 40px; width: 260px; margin-bottom: 5px;\">Fill Iris data</button>\r\n      <button class=\"clouds-flat-button\" onclick=\"loadDB('data/car.data.txt')\" style=\"height: 40px; width: 260px; margin-bottom: 5px;\">Fill Car Evaluation data</button>\r\n      <button class=\"clouds-flat-button\" onclick=\"loadDB('data/yeast.data.txt')\" style=\"height: 40px; width: 260px; margin-bottom: 5px;\">Fill Yeast data</button>\r\n    </div>\r\n\r\n    <textarea id=\"data-ta\" style=\"width:100%; height:200px;\">\r\n    </textarea>\r\n\r\n    <button class=\"clouds-flat-button\" onclick=\"importTrainData()\" style=\"width: 200px; height: 40px; margin-top: 5px;\">Import Data</button>\r\n    (and send <input type=\"text\" id=\"testsplit\" maxlength=\"3\" value=\"20\" style=\"width:40px;\">% of imported data randomly into Test Set below)\r\n\r\n    <div id='prepromsg'></div>\r\n    <div id='datamsg'></div>\r\n    \r\n    <h1>Cross-Validation</h1>\r\n    \r\n    <div>\r\n    <input type=\"text\" id=\"labelix\" maxlength=\"4\" value=\"-1\" style=\"width:40px;\">\r\n    Index of column to classify as target. (e.g. 0 = first column, -1 = last column)\r\n    </div>\r\n\r\n    <div>\r\n    <input type=\"text\" id=\"trainp\" name=\"train_split\" maxlength=\"3\" value=\"70\" style=\"width:20px;\">\r\n    Percent of data to use for training (rest will be validation)\r\n    </div>\r\n\r\n    <div>\r\n    <input type=\"text\" id=\"foldsnum\" name=\"folds_number\" maxlength=\"3\" value=\"3\" style=\"width:40px;\"> Number of data folds to evaluate per candidate\r\n    </div>\r\n\r\n    <div>\r\n    <input type=\"text\" id=\"candsnum\" name=\"candidates_number\" maxlength=\"4\" value=\"50\" style=\"width:40px;\"> Number of candidates in a batch, to evaluate in parallel\r\n    </div>\r\n\r\n    <div>\r\n    <input type=\"text\" id=\"epochsnum\" name=\"epochs_number\" maxlength=\"4\" value=\"40\" style=\"width:40px;\"> Number of epochs to make over each fold\r\n    </div>\r\n\r\n    <div>\r\n    Number of Neurons in each layer: Min <input type=\"text\" id=\"nnmin\" maxlength=\"4\" value=\"5\" style=\"width:40px;\"> Max <input type=\"text\" id=\"nnmax\" maxlength=\"4\" value=\"30\" style=\"width:40px;\"> \r\n    </div>\r\n\r\n    <!--\r\n    <div class=\"sopts\">\r\n    Batch size sampling:<br>\r\n    Min: <input type=\"text\" id=\"bsmin\" maxlength=\"4\" value=\"10\" style=\"width:40px;\"> \r\n    Max: <input type=\"text\" id=\"bsmax\" maxlength=\"4\" value=\"300\" style=\"width:40px;\"> \r\n    </div>\r\n\r\n    <div class=\"sopts\">\r\n    L2 weight decay (values will be raised to power of 10):<br>\r\n    Min: <input type=\"text\" id=\"l2min\" maxlength=\"4\" value=\"-4\" style=\"width:40px;\"> \r\n    Max: <input type=\"text\" id=\"l2max\" maxlength=\"4\" value=\"2\" style=\"width:40px;\"> \r\n    </div>\r\n\r\n    <div class=\"sopts\">\r\n    Learning rate for SGD/Adagrad (values will be raised to power of 10):<br>\r\n    Min: <input type=\"text\" id=\"lrmin\" maxlength=\"4\" value=\"-4\" style=\"width:40px;\"> \r\n    Max: <input type=\"text\" id=\"lrmax\" maxlength=\"4\" value=\"0\" style=\"width:40px;\"> \r\n    </div>\r\n\r\n    <div class=\"sopts\">\r\n    Momentum for SGD (must be between 0 and 1):<br>\r\n    Min: <input type=\"text\" id=\"mommin\" maxlength=\"4\" value=\"0.9\" style=\"width:40px;\"> \r\n    Max: <input type=\"text\" id=\"mommax\" maxlength=\"4\" value=\"0.9\" style=\"width:40px;\"> \r\n    </div>\r\n    -->\r\n    \r\n    <button class=\"clouds-flat-button\" onclick=\"startCV()\" style=\"width: 200px; height: 40px; margin-top: 5px;\">Start/Restart</button>\r\n    <hr>\r\n\r\n    <p>Below: graph of the <b>validation accuracy</b> for current batch of candidate models as a function of the number of training points they have seen during training. Good networks will rise up as high as possible and stay there. The best performer is printed in detail below the graph. The graph is less wiggly if there is more data.</p>\r\n    <div id=\"foldreport\"></div>\r\n    <div id=\"candsreport\"></div>\r\n\r\n    <canvas id=\"valgraph\" width=\"800\" height=\"400\"></canvas>\r\n    <div id=\"bestmodel\"></div>\r\n    <div id=\"bestmodeloverall\"></div>\r\n    \r\n    <h1>Evaluate on Test Set</h1>\r\n    <p>\r\n      Paste a test set in box below to evaluate the final test accuracy, which is based on a model-averaged ensemble of the best discovered network from the training data above. The CSV pasted below should be in the same format as the one used for training data above. The text field is pre-filled with the training data.\r\n    </p>\r\n    \r\n    <div>\r\n    <input type=\"text\" id=\"ensemblenum\" maxlength=\"3\" value=\"10\" style=\"width:20px;\"> Number of best models to average in the ensemble network\r\n    </div>\r\n\r\n    <textarea id=\"data-te\" style=\"width:100%; height:200px;\">\r\n    </textarea>\r\n    <button class=\"clouds-flat-button\" onclick=\"testEval()\" style=\"width: 200px; height: 40px; margin-top: 5px;\">Evaluate Test Accuracy</button>\r\n    <div id='datamsgtest'></div>\r\n    <br>\r\n    <div id=\"testresult\"></div>\r\n\r\n    <h1>Export Best Network</h1>\r\n    <button class=\"clouds-flat-button\" onclick=\"exportMagicNet()\" style=\"width: 200px; height: 40px; margin-top: 5px;\">Export</button><br><br>\r\n    <textarea id=\"taexport\" style=\"width:100%; height:200px;\">\r\n    </textarea>\r\n\r\n    Above you can export a trained MagicNet in JSON format. The exported MagicNet is simply a thin wrapper around a list of the best networks that were discovered during cross-validation and it can be loaded and used again as follows:\r\n<pre class=\"brush: js; toolbar: false;\">\r\nvar magicNet = new convnetjs.MagicNet();\r\nmagicNet.fromJSON(json);\r\nmagicNet.predict(some_vol); // ready to use!\r\n</pre>\r\n    \r\n    <br><br><br><br><br><br><br><br>\r\n    \r\n  </div>\r\n </body>\r\n</html>\r\n"
  },
  {
    "path": "demo/cifar10.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>ConvNetJS CIFAR-10 demo</title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"author\" content=\"\">\n  <link rel=\"stylesheet\" href=\"css/style.css\">\n\n<script src=\"js/jquery-1.8.3.min.js\"></script>\n<script src=\"../build/vis.js\"></script>\n<script src=\"../build/util.js\"></script>\n<script src=\"../build/convnet.js\"></script>\n\n<script src=\"js/image-helpers.js\"></script>\n<script src=\"js/pica.js\"></script>\n\n<script src=\"cifar10/cifar10_labels.js\"></script>\n<script type=\"text/javascript\">\n  // ------------------------\n  // BEGIN CIFAR-10 SPECIFIC STUFF\n  // ------------------------\n  var classes_txt = ['airplane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'];\n  var dataset_name = \"cifar10\";\n  var num_batches = 51; // 20 training batches, 1 test\n  var test_batch = 50;\n  var num_samples_per_batch = 1000;\n  var image_dimension = 32;\n  var image_channels = 3;\n  var use_validation_data = true;\n  var random_flip = true;\n  var random_position = true;\n\n  var layer_defs, net, trainer;\n  var t = \"layer_defs = [];\\n\\\n  layer_defs.push({type:'input', out_sx:32, out_sy:32, out_depth:3});\\n\\\n  layer_defs.push({type:'conv', sx:5, filters:16, stride:1, pad:2, activation:'relu'});\\n\\\n  layer_defs.push({type:'pool', sx:2, stride:2});\\n\\\n  layer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});\\n\\\n  layer_defs.push({type:'pool', sx:2, stride:2});\\n\\\n  layer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});\\n\\\n  layer_defs.push({type:'pool', sx:2, stride:2});\\n\\\n  layer_defs.push({type:'softmax', num_classes:10});\\n\\\n  \\n\\\n  net = new convnetjs.Net();\\n\\\n  net.makeLayers(layer_defs);\\n\\\n  \\n\\\n  trainer = new convnetjs.SGDTrainer(net, {method:'adadelta', batch_size:4, l2_decay:0.0001});\\n\\\n  \";\n  // ------------------------\n  // END CIFAR-10 SPECIFIC STUFF\n  // ------------------------\n</script>\n<script src=\"js/images-demo.js\"></script>\n\n</head>\n<body>\n  <div id=\"wrap\">\n  <h2 style=\"text-align: center;\"><a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">ConvNetJS</a> CIFAR-10 demo</h2>\n  <h1>Description</h1>\n  <p>\n    This demo trains a Convolutional Neural Network on the <a href=\"http://www.cs.toronto.edu/~kriz/cifar.html\">CIFAR-10 dataset</a> in your browser, with nothing but Javascript. The state of the art on this dataset is about 90% accuracy and human performance is at about 94% (not perfect as the dataset can be a bit ambiguous). I used <a href=\"cifar10_parse.zip\">this python script</a> to parse the <a href=\"http://www.cs.toronto.edu/~kriz/cifar.html\">original files</a> (python version) into batches of images that can be easily loaded into page DOM with img tags.\n  </p>\n  <p>This dataset is more difficult and it takes longer to train a network. Data augmentation includes random flipping and random image shifts by up to 2px horizontally and verically.</p>\n  <p>\n    By default, in this demo we're using Adadelta which is one of per-parameter adaptive step size methods, so we don't have to worry about changing learning rates or momentum over time. However, I still included the text fields for changing these if you'd like to play around with SGD+Momentum trainer.\n  </p>\n  <p>Report questions/bugs/suggestions to <a href=\"https://twitter.com/karpathy\">@karpathy</a>.</p>\n  <h1>Training Stats</h1>\n  <div class=\"divsec\" style=\"270px;\">\n    <div class=\"secpart\">\n      <input id=\"buttontp\" type=\"submit\" value=\"pause\" onclick=\"toggle_pause();\"/>\n      <div id=\"trainstats\"></div>\n\n      <div id=\"controls\">\n        Learning rate: <input name=\"lri\" type=\"text\" maxlength=\"20\" id=\"lr_input\"/>\n        <input id=\"buttonlr\" type=\"submit\" value=\"change\" onclick=\"change_lr();\"/>\n        <br />\n\n        Momentum: <input name=\"momi\" type=\"text\" maxlength=\"20\" id=\"momentum_input\"/>\n        <input id=\"buttonmom\" type=\"submit\" value=\"change\" onclick=\"change_momentum();\"/>\n        <br />\n\n        Batch size: <input name=\"bsi\" type=\"text\" maxlength=\"20\" id=\"batch_size_input\"/>\n        <input id=\"buttonbs\" type=\"submit\" value=\"change\" onclick=\"change_batch_size();\"/>\n        <br />\n\n        Weight decay: <input name=\"wdi\" type=\"text\" maxlength=\"20\" id=\"decay_input\"/>\n        <input id=\"buttonwd\" type=\"submit\" value=\"change\" onclick=\"change_decay();\"/>\n      </div>\n\n      <input id=\"buttondj\" type=\"submit\" value=\"save network snapshot as JSON\" onclick=\"dump_json();\"/><br />\n      <input id=\"buttonlfj\" type=\"submit\" value=\"init network from JSON snapshot\" onclick=\"load_from_json();\"/><br />\n      <textarea id=\"dumpjson\"></textarea>\n      <br>\n\n      <input id=\"buttonpre\" type=\"submit\" value=\"load a pretrained network (achieves ~80% accuracy)\" onclick=\"load_pretrained();\" style=\"height: 30px; width: 400px;\"/><br />\n    </div>\n    <div class=\"secpart\">\n      <div>\n        Loss:<br />\n        <canvas id=\"lossgraph\">\n        </canvas>\n        <br />\n        <input id=\"buttoncg\" type=\"submit\" value=\"clear graph\" onclick=\"clear_graph();\"/>\n      </div>\n    </div>\n    <div class=\"secpart\"> \n      <div id=\"upload_box\">\n        Test an image from your computer:\n        <div id=\"img_div\">\n            <img id=\"preview_img\"/>\n        </div>\n        <input name=\"image\" type=\"file\" accept=\"image/*\" onchange=\"loadFile(event)\">\n\n        <input type=\"submit\" value=\"Test Image\" onclick=\"testImage(document.getElementById('preview_img'))\">\n      </div>\n    </div>\n    <div style=\"clear:both;\"></div>\n  </div>\n\n  <h1>Instantiate a Network and Trainer</h1>\n  <div>\n    <textarea id=\"newnet\" style=\"width:100%; height:200px;\"></textarea><br />\n    <input id=\"buttonnn\" type=\"submit\" value=\"change network\" onclick=\"change_net();\" style=\"width:200px;height:30px;\"/>\n  </div>\n\n  <div class=\"divsec\">\n  <h1>Network Visualization</h1>\n    <div id=\"visnet\"></div>\n  </div>\n  \n  <div class=\"divsec\">\n  <h1>Example predictions on Test set</h1>\n    <div id=\"testset_acc\"></div>\n    <div id=\"testset_vis\"></div>\n  </div>\n\n  </div>  \n</body>\n</html>\n\n\n\n"
  },
  {
    "path": "demo/classify2d.html",
    "content": "<html>\n<head>\n<title>ConvNetJS demo: Classify toy 2D data</title>\n<link href='http://fonts.googleapis.com/css?family=Cabin' rel='stylesheet' type='text/css'>\n\n<script src=\"js/jquery-1.8.3.min.js\"></script>\n<script src=\"js/npgmain.js\"></script>\n<script src=\"../build/convnet.js\"></script>\n<script src=\"../build/util.js\"></script>\n<script src=\"js/classify2d.js\"></script>\n\n<style type=\"text/css\">\nbody {\n  font-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;\n  color: #333;\n  padding: 20px;\n}\ncanvas { \n    border: 1px solid #555;\n}\n#wrap {\n  width: 900px;\n  margin-right: auto;\n  margin-left: auto;\n  margin-bottom: 200px;\n}\n.pane {\n  width: 420px;\n  display: inline-block;\n  vertical-align: top;\n}\ninput[type=\"submit\"]\n{\n  margin: 3px;\n}\n\n</style>\n\n</head>\n\n<body>\n\n<div id=\"wrap\">\n<h1><a href=\"http://cs.stanford.edu/people/karpathy/convnetjs\">ConvnetJS</a> demo: toy 2d classification with 2-layer neural network</h1>\n\n<p>The simulation below shows a toy binary problem with a few data points of class 0 (red) and 1 (green). The network is set up as:</p>\n\n<textarea id=\"layerdef\" style=\"width:100%; height:200px;\">\n</textarea>\n<br>\n<input id=\"buttontp\" type=\"submit\" value=\"change network\" onclick=\"reload();\" style=\"width: 300px; height: 50px;\"/>\n\n<p>Feel free to change this, the text area above gets eval()'d when you hit the button and the network gets reloaded. Every 10th of a second, all points are fed to the network multiple times through the trainer class to train the network. The resulting predictions of the network are then \"painted\" under the data points to show you the generalization.</p>\n\n<p>On the right we visualize the transformed representation of all grid points in the original space and the data, for a given layer and only for 2 neurons at a time. The number in the bracket shows the total number of neurons at that level of representation. If the number is more than 2, you will only see the two visualized but you can cycle through all of them with the cycle button.</p>\n\n<div class=\"panes\">\n<div class=\"pane\">\n<canvas id=\"NPGcanvas\" width=\"400\" height=\"400\">Browser not supported for Canvas. Get a real browser.</canvas>\n<input id=\"buttondata1\" type=\"submit\" value=\"simple data\" onclick=\"original_data();\" style=\"width: 100px; height: 30px;\"/>\n<input id=\"buttondata2\" type=\"submit\" value=\"circle data\" onclick=\"circle_data();\" style=\"width: 100px; height: 30px;\"/>\n<input id=\"buttondata3\" type=\"submit\" value=\"spiral data\" onclick=\"spiral_data();\" style=\"width: 100px; height: 30px;\"/><br>\n<input id=\"buttondata4\" type=\"submit\" value=\"random data\" onclick=\"random_data();\" style=\"width: 100px; height: 30px;\"/><br>\n<p>\nControls:<br>\n<b>CLICK</b>: Add red data point<br>\n<b>SHIFT+CLICK</b>: Add green data point<br>\n<b>CTRL+CLICK</b>: Remove closest data point<br>\n</p>\n</div>\n\n<div class=\"pane\">\n  <canvas id=\"viscanvas\" width=\"400\" height=\"400\">Browser not supported for Canvas. Get a real browser.</canvas>\n  <div id=\"cyclestatus\"></div>\n<div id=\"layer_ixes\"></div>\n<input id=\"buttoncycle\" type=\"submit\" value=\"cycle through visualized neurons at selected layer (if more than 2)\" onclick=\"cycle();\" style=\"height: 40px;\"/>\n</div>\n\n</div>\n\n<p>Go <a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">back to ConvNetJS</a></p>\n\n</div>\n\n</body>\n</html>\n"
  },
  {
    "path": "demo/css/automatic.css",
    "content": "#wrap {\n  width:800px;\n  margin-left: auto;\n  margin-right: auto;\n}\nh2 {\n  text-align: center;\n  font-size: 34px;\n  font-weight: 300;\n  margin-bottom: 50px;\n}\nh1 {\n  font-size: 26px;\n  font-weight: 400;\n  border-bottom: 1px #999 solid;\n}\n#datamsg{\n  background-color: white;\n  margin-top: 2px;\n  padding: 10px;\n}\n#prepromsg{\n  margin-top: 10px;\n  padding: 10px;\n}\n.msg{\n  padding: 2px;\n}\nbody {\n  font-family: 'Lato', sans-serif;\n  color: #333;\n  font-size: 20px;\n  font-weight: 300;\n}\ninput[type=text] {\n  border: 1px solid #999;\n  padding: 3px;\n  font-size: 18px;\n  color: #333;\n}\n.clouds-flat-button {\n  position: relative;\n  vertical-align: top;\n  width: 100%;\n  height: 80px;\n  padding: 0;\n  color:#454545;\n  text-align: center;\n  font-size: 16px;\n  background: #ecf0f1;\n  border: 0;\n  border-bottom: 2px solid #dadedf;\n  cursor: pointer;\n  -webkit-box-shadow: inset 0 -2px #dadedf;\n  box-shadow: inset 0 -2px #dadedf;\n}\n.clouds-flat-button:active {\n  top: 1px;\n  outline: none;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n#bestmodel {\n  font-size: 16px;\n  background-color: #FAFAFA;\n  padding: 10px;\n}\n#bestmodeloverall {\n  font-size: 16px;\n  background-color: #FAFAFA;\n  padding: 10px;\n  margin-top: 10px;\n}\n.syntaxhighlighter {\n  font-size: 14px !important;\n  overflow-y: hidden !important; \n}\n.sopts {\n  box-shadow: 0px 0px 2px 0px #555;\n  margin-bottom: 5px;\n  padding: 10px;\n}"
  },
  {
    "path": "demo/css/style.css",
    "content": ".layer {\n  border: 1px solid #999;\n  margin-bottom: 5px;\n  text-align: left;\n  padding: 10px;\n}\n.layer_act {\n  width: 500px;\n  float: right;\n}\n.ltconv {\n  background-color: #FDD;\n}\n.ltrelu {\n  background-color: #FDF;\n}\n.ltpool {\n  background-color: #DDF;\n}\n.ltsoftmax {\n  background-color: #FFD;\n}\n.ltfc {\n  background-color: #DFF;\n}\n.ltlrn {\n  background-color: #DFD; \n}\n.ltdropout {\n  background-color: #AAA;  \n}\n.ltitle {\n  color: #333;\n  font-size: 18px;\n}\n.actmap {\n  margin: 1px;\n}\n#trainstats {\n  text-align: left;\n}\n.clear {\n  clear: both;\n}\n#wrap {\n  width: 800px;\n  margin-left: auto;\n  margin-right: auto;\n}\nh1 {\n  font-size: 16px;\n  color: #333;\n  background-color: #DDD;\n  border-bottom: 1px #999 solid;\n  text-align: center;\n}\nh2 {\n  text-align: center;\n}\n.secpart {\n  width: 400px;\n  float: left;\n}\n#lossgraph {\n  /*border: 1px solid #F0F;*/\n  width: 100%;\n}\n.testdiv canvas {\n  float: left;\n  width: 64px;\n}\n.testdiv {\n  background-color: rgba(255,255,255,0.65);\n  height: auto;\n  width: auto;\n  display: inline-block;\n  font-size: 12px;\n  box-shadow: 0px 0px 2px 2px #EEE;\n  margin: 5px;\n  padding: 5px;\n  color: black;\n}\n.probsdiv {\n  float: left;\n  width: 100px;\n  margin-left: 1px;\n}\n.pp {\n  margin: 1px;\n  padding: 1px;\n}\n#testset_acc {\n  /* margin-bottom: 200px; */\n}\n#testset_vis {\n  margin-bottom: 200px;\n}\nbody {\n  font-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;\n  /* color: #333; */\n  /* padding: 20px; */\n}"
  },
  {
    "path": "demo/image_regression.html",
    "content": "<html>\n<head>\n<title>ConvNetJS demo: Image Painting</title>\n<link href='http://fonts.googleapis.com/css?family=Cabin' rel='stylesheet' type='text/css'>\n<link rel=\"stylesheet\" href=\"css/style.css\">\n\n<link rel=\"stylesheet\" href=\"css/jquery-ui.min.css\">\n<script src=\"js/jquery-1.8.3.min.js\"></script>\n<script src=\"js/jquery-ui.min.js\"></script>\n\n<script src=\"../build/convnet.js\"></script>\n<script src=\"js/image_regression.js\"></script>\n\n<style type=\"text/css\">\ncanvas { \n    border: 1px solid #555;\n    margin-top: 10px;\n}\n#wrap {\n  width: 800px;\n  margin-right: auto;\n  margin-left: auto;\n  margin-bottom: 200px;\n}\n#gallery img {\n  width: 195;\n  height: 195px;\n  display: inline-block;\n}\n</style>\n\n</head>\n\n<body>\n\n<div id=\"wrap\">\n<h1><a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">ConvnetJS</a> demo: Image \"Painting\"</h1>\n\n<p>This demo that treats the pixels of an image as a learning problem: it takes the (x,y) position on a grid and learns to predict the color at that point using regression to (r,g,b). It's a bit like compression, since the image information is encoded in the weights of the network, but almost certainly not of practical kind :)</p>\n<p>\n  Note that the entire ConvNetJS definition is shown in textbox below and it gets eval()'d to create the network, so feel free to fiddle with the parameters and hit \"reload\". I found that, empirically and interestingly, deeper networks tend to work much better on this task given a fixed parameter budget.\n</p>\n\n<p>Report questions/bugs/suggestions to <a href=\"https://twitter.com/karpathy\">@karpathy</a>.</p>\n\n<textarea id=\"layerdef\" style=\"width:100%; height:250px;\"></textarea>\n<br /><br  />\n<input id=\"buttontp\" type=\"submit\" value=\"reload network\" onclick=\"reload();\" style=\"width: 200px; height: 30px;\"/>\n\n<div style=\"float: right;\">\nChoose your own image: \n<input id=\"f\" type=\"file\" />\n</div>\n\n<br>\n\n<div style=\"background-color: #EEE; padding: 10px; margin-top: 10px;\">\n<div style=\"float: left; margin-left: 200px;\">\n  Original Image<br>\n  <canvas id=\"canv_original\"></canvas>\n</div>\n<div style=\"float: left; margin-left: 10px;\">\n  Neural Network output<br>\n  <canvas id=\"canv_net\"></canvas>\n</div>\n\n<div style=\"clear:both;\"></div>\n</div>\n\n<br>\n<div id=\"report\"></div>\n<br>\n\n<div id=\"lr\">Learning rate:</div>\n<div id=\"slider\"></div>\n<div>The learning rate should probably be decreased over time (slide left) to let the network better overfit the training data. It's nice to not have to worry about overfitting.</div>\n\n<br><br>\n<div>\n  You can upload your own image above (click Choose File), or you can click on any of the images below to load them.\n</div>\n<div id=\"gallery\">\n  <img src=\"imgs/cat.jpg\" class=\"ci\" />\n  <img src=\"imgs/esher.png\"  class=\"ci\" />\n  <img src=\"imgs/pencils.png\" class=\"ci\" />\n  <img src=\"imgs/usa.png\"  class=\"ci\" />\n  <img src=\"imgs/fractal.jpg\"  class=\"ci\" />\n  <img src=\"imgs/dora.jpg\" class=\"ci\" />\n  <img src=\"imgs/rubiks.jpg\" class=\"ci\" />\n  <img src=\"imgs/earth.jpg\" class=\"ci\" />\n  <img src=\"imgs/fox.png\" class=\"ci\" />\n  <img src=\"imgs/twitter.png\" class=\"ci\" />\n  <img src=\"imgs/reddit.jpg\" class=\"ci\" />\n  <img src=\"imgs/chip.jpg\" class=\"ci\" />\n  <img src=\"imgs/jitendra.jpg\" class=\"ci\" />\n  <img src=\"imgs/tesla.jpg\" class=\"ci\" />\n  <img src=\"imgs/rainforest.jpg\" class=\"ci\" />\n  <img src=\"imgs/chess.png\" class=\"ci\" />\n  <img src=\"imgs/gradient.png\" class=\"ci\" />\n  <img src=\"imgs/battery.jpg\" class=\"ci\" />\n  <img src=\"imgs/starry.jpg\" class=\"ci\" />\n</div>\n\n<br><br>\n<p>Go <a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">back to ConvNetJS</a></p>\n\n</div>\n\n</body>\n</html>\n\n"
  },
  {
    "path": "demo/js/autoencoder.js",
    "content": "// globals\nvar layer_defs, net, trainer;\nvar t = \"\\\nlayer_defs = [];\\n\\\nlayer_defs.push({type:'input', out_sx:28, out_sy:28, out_depth:1});\\n\\\nlayer_defs.push({type:'fc', num_neurons:50, activation:'tanh'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:50, activation:'tanh'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:2});\\n\\\nlayer_defs.push({type:'fc', num_neurons:50, activation:'tanh'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:50, activation:'tanh'});\\n\\\nlayer_defs.push({type:'regression', num_neurons:28*28});\\n\\\n\\n\\\nnet = new convnetjs.Net();\\n\\\nnet.makeLayers(layer_defs);\\n\\\n\\n\\\ntrainer = new convnetjs.SGDTrainer(net, {learning_rate:1, method:'adadelta', batch_size:50, l2_decay:0.001, l1_decay:0.001});\\n\\\n\";\n\n// ------------------------\n// BEGIN MNIST SPECIFIC STUFF\n// ------------------------\nvar sample_training_instance = function() {\n\n  // find an unloaded batch\n  var bi = Math.floor(Math.random()*loaded_train_batches.length);\n  var b = loaded_train_batches[bi];\n  var k = Math.floor(Math.random()*3000); // sample within the batch\n  var n = b*3000+k;\n\n  // load more batches over time\n  if(step_num%5000===0 && step_num>0) {\n    for(var i=0;i<num_batches;i++) {\n      if(!loaded[i]) {\n        // load it\n        load_data_batch(i);\n        break; // okay for now\n      }\n    }\n  }\n\n  // fetch the appropriate row of the training image and reshape into a Vol\n  var p = img_data[b].data;\n  var x = new convnetjs.Vol(28,28,1,0.0);\n  var W = 28*28;\n  for(var i=0;i<W;i++) {\n    var ix = ((W * k) + i) * 4;\n    x.w[i] = p[ix]/255.0;\n  }\n\n  return {x:x, label:labels[n]};\n}\n\nvar num_batches = 21; // 20 training batches, 1 test\nvar data_img_elts = new Array(num_batches);\nvar img_data = new Array(num_batches);\nvar loaded = new Array(num_batches);\nvar loaded_train_batches = [];\n\n// int main\n$(window).load(function() {\n\n  $(\"#newnet\").val(t);\n  change_net();\n\n  for(var k=0;k<loaded.length;k++) { loaded[k] = false; }\n\n  load_data_batch(0); // async load train set batch 0 (6 total train batches)\n  load_data_batch(20); // async load test set (batch 6)\n  start_fun();\n});\n\nvar start_fun = function() {\n  if(loaded[0] && loaded[20]) { \n    console.log('starting!'); \n    setInterval(load_and_step, 0); // lets go!\n  }\n  else { setTimeout(start_fun, 200); } // keep checking\n}\n\nvar load_data_batch = function(batch_num) {\n  // Load the dataset with JS in background\n  data_img_elts[batch_num] = new Image();\n  var data_img_elt = data_img_elts[batch_num];\n  data_img_elt.onload = function() { \n    var data_canvas = document.createElement('canvas');\n    data_canvas.width = data_img_elt.width;\n    data_canvas.height = data_img_elt.height;\n    var data_ctx = data_canvas.getContext(\"2d\");\n    data_ctx.drawImage(data_img_elt, 0, 0); // copy it over... bit wasteful :(\n    img_data[batch_num] = data_ctx.getImageData(0, 0, data_canvas.width, data_canvas.height);\n    loaded[batch_num] = true;\n    if(batch_num < 20) { loaded_train_batches.push(batch_num); }\n    console.log('finished loading data batch ' + batch_num);\n  };\n  data_img_elt.src = \"mnist/mnist_batch_\" + batch_num + \".png\";\n}\n\n// ------------------------\n// END MNIST SPECIFIC STUFF\n// ------------------------\n\nvar maxmin = cnnutil.maxmin;\nvar f2t = cnnutil.f2t;\n\nvar render_act = function(A) {\n  var w = A.w;\n  var mm = maxmin(w);\n  var s = 1;\n\n  var canv = document.createElement('canvas');\n  canv.className = 'rendera';\n  var W = A.sx * s;\n  var H = A.sy * s;\n  canv.width = W;\n  canv.height = H;\n  var ctx = canv.getContext('2d');\n  var g = ctx.createImageData(W, H);\n  var d = 0;\n  for(var x=0;x<A.sx;x++) {\n    for(var y=0;y<A.sy;y++) {\n      var dval = Math.floor((A.get(x,y,d)-mm.minv)/mm.dv*255);  \n      for(var dx=0;dx<s;dx++) {\n        for(var dy=0;dy<s;dy++) {\n          var pp = ((W * (y*s+dy)) + (dx + x*s)) * 4;\n          for(var i=0;i<3;i++) { g.data[pp + i] = dval; } // rgb\n          g.data[pp+3] = 255; // alpha channel\n        }\n      }\n    }\n  }\n  ctx.putImageData(g, 0, 0);\n  return canv;\n}\n\n// elt is the element to add all the canvas activation drawings into\n// A is the Vol() to use\n// scale is a multiplier to make the visualizations larger. Make higher for larger pictures\n// if grads is true then gradients are used instead\nvar draw_activations = function(elt, A, scale, grads) {\n\n  var s = scale || 2; // scale\n  var draw_grads = false;\n  if(typeof(grads) !== 'undefined') draw_grads = grads;\n\n  // get max and min activation to scale the maps automatically\n  var w = draw_grads ? A.dw : A.w;\n  var mm = maxmin(w);\n\n  // create the canvas elements, draw and add to DOM\n  for(var d=0;d<A.depth;d++) {\n\n    var canv = document.createElement('canvas');\n    canv.className = 'actmap';\n    var W = A.sx * s;\n    var H = A.sy * s;\n    canv.width = W;\n    canv.height = H;\n    var ctx = canv.getContext('2d');\n    var g = ctx.createImageData(W, H);\n\n    for(var x=0;x<A.sx;x++) {\n      for(var y=0;y<A.sy;y++) {\n        if(draw_grads) {\n          var dval = Math.floor((A.get_grad(x,y,d)-mm.minv)/mm.dv*255);\n        } else {\n          var dval = Math.floor((A.get(x,y,d)-mm.minv)/mm.dv*255);  \n        }\n        for(var dx=0;dx<s;dx++) {\n          for(var dy=0;dy<s;dy++) {\n            var pp = ((W * (y*s+dy)) + (dx + x*s)) * 4;\n            for(var i=0;i<3;i++) { g.data[pp + i] = dval; } // rgb\n            g.data[pp+3] = 255; // alpha channel\n          }\n        }\n      }\n    }\n    ctx.putImageData(g, 0, 0);\n    elt.appendChild(canv);\n  }  \n}\n\nvar visualize_activations = function(net, elt) {\n\n  // clear the element\n  elt.innerHTML = \"\";\n\n  // show activations in each layer\n  var N = net.layers.length;\n  for(var i=0;i<N;i++) {\n    var L = net.layers[i];\n\n    var layer_div = document.createElement('div');\n\n    // visualize activations\n    var activations_div = document.createElement('div');\n    activations_div.appendChild(document.createTextNode('Activations:'));\n    activations_div.appendChild(document.createElement('br'));\n    activations_div.className = 'layer_act';\n    var scale = 2;\n    if(L.layer_type==='fc') scale = 10; // for softmax\n    if(L.layer_type==='regression') {\n      var Vvis = L.out_act.clone();\n      Vvis.sx = 28; \n      Vvis.sy = 28;\n      Vvis.depth = 1;\n      draw_activations(activations_div, Vvis, scale);\n    } else {\n      draw_activations(activations_div, L.out_act, scale);\n\n      if(i===0) {\n        // also append the regression layer right nex tto input\n        // so that it's easy to compare\n        activations_div.appendChild(document.createElement('br'));\n        activations_div.appendChild(document.createTextNode('Predicted reconstruction:'));\n        activations_div.appendChild(document.createElement('br'));\n        var Vvis = net.layers[net.layers.length-1].out_act.clone();\n        Vvis.sx = 28; \n        Vvis.sy = 28;\n        Vvis.depth = 1;\n        draw_activations(activations_div, Vvis, scale);\n      }\n    }\n\n    if(L.layer_type === 'fc' && i===1) {\n      var filters_div = document.createElement('div');\n      filters_div.appendChild(document.createTextNode('Weights:'));\n      filters_div.appendChild(document.createElement('br'));\n      for(var j=0;j<L.filters.length;j++) {\n        var Lshow = L.filters[j].clone();\n        Lshow.sx = 28; \n        Lshow.sy = 28; \n        Lshow.depth = 1;\n        draw_activations(filters_div, Lshow, 2);\n      }\n      activations_div.appendChild(filters_div);\n    }\n\n    // visualize filters if they are of reasonable size\n    if(L.layer_type === 'conv') {\n      var filters_div = document.createElement('div');\n      if(L.filters[0].sx>3) {\n        // actual weights\n        filters_div.appendChild(document.createTextNode('Weights:'));\n        filters_div.appendChild(document.createElement('br'));\n        for(var j=0;j<L.filters.length;j++) {\n          draw_activations(filters_div, L.filters[j], 2);\n        }\n        // gradients\n        filters_div.appendChild(document.createElement('br'));\n        filters_div.appendChild(document.createTextNode('Gradients:'));\n        filters_div.appendChild(document.createElement('br'));\n        for(var j=0;j<L.filters.length;j++) {\n          draw_activations(filters_div, L.filters[j], 2, true);\n        }\n      } else {\n        filters_div.appendChild(document.createTextNode('Weights hidden, too small'));\n      }\n      activations_div.appendChild(filters_div);\n    }\n    layer_div.appendChild(activations_div);\n\n    // print some stats on left of the layer\n    layer_div.className = 'layer ' + 'lt' + L.layer_type;\n    var title_div = document.createElement('div');\n    title_div.className = 'ltitle'\n    var t = L.layer_type + ' (' + L.out_sx + 'x' + L.out_sy + 'x' + L.out_depth + ')';\n    title_div.appendChild(document.createTextNode(t));\n    layer_div.appendChild(title_div);\n\n    if(L.layer_type==='conv') {\n      var t = 'filter size ' + L.filters[0].sx + 'x' + L.filters[0].sy + 'x' + L.filters[0].depth + ', stride ' + L.stride;\n      layer_div.appendChild(document.createTextNode(t));\n      layer_div.appendChild(document.createElement('br'));\n    }\n    if(L.layer_type==='pool') {\n      var t = 'pooling size ' + L.sx + 'x' + L.sy + ', stride ' + L.stride;\n      layer_div.appendChild(document.createTextNode(t));\n      layer_div.appendChild(document.createElement('br'));\n    }\n\n    // find min, max activations and display them\n    var mma = maxmin(L.out_act.w);\n    var t = 'max activation: ' + f2t(mma.maxv) + ', min: ' + f2t(mma.minv);\n    layer_div.appendChild(document.createTextNode(t));\n    layer_div.appendChild(document.createElement('br'));\n\n    // number of parameters\n    if(L.layer_type==='conv') {\n      var tot_params = L.sx*L.sy*L.in_depth*L.filters.length + L.filters.length;\n      var t = 'parameters: ' + L.filters.length + 'x' + L.sx + 'x' + L.sy + 'x' + L.in_depth + '+' + L.filters.length + ' = ' + tot_params;\n      layer_div.appendChild(document.createTextNode(t));\n      layer_div.appendChild(document.createElement('br'));\n    }\n    if(L.layer_type==='fc') {\n      var tot_params = L.num_inputs*L.filters.length + L.filters.length;\n      var t = 'parameters: ' + L.filters.length + 'x' + L.num_inputs + '+' + L.filters.length + ' = ' + tot_params;\n      layer_div.appendChild(document.createTextNode(t));\n      layer_div.appendChild(document.createElement('br'));\n    }\n\n    // css madness needed here...\n    var clear = document.createElement('div');\n    clear.className = 'clear';\n    layer_div.appendChild(clear);\n\n    elt.appendChild(layer_div);\n  }\n}\n\n// loads a training image and trains on it with the network\nvar paused = false;\nvar embed_samples = [];\nvar embed_imgs = [];\nvar load_and_step = function() {\n  if(paused) return; \n\n  if(embed_samples.length === 0) { // happens once\n    for(var k=0;k<200;k++) {\n      var s = sample_training_instance();\n      embed_samples.push(s);\n      // render x and save it too\n      var I = render_act(s.x);\n      embed_imgs.push(I);\n    }\n  }\n  var sample = sample_training_instance();\n  step(sample); // process this image\n}\n\nvar lix = 5;\nvar d0 = 0;\nvar d1 = 1;\nfunction cycle() {\n  var selected_layer = net.layers[lix];\n  d0 += 1;\n  d1 += 1;\n  if(d1 >= selected_layer.out_depth) d1 = 0; // and wrap\n  if(d0 >= selected_layer.out_depth) d0 = 0; // and wrap\n  $(\"#cyclestatus\").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer #' + lix + ' (' + net.layers[lix].layer_type + ')');\n}\nfunction updateLix(newlix) {\n  $(\"#button\"+lix).css('background-color', ''); // erase highlight\n  lix = newlix;\n  d0 = 0;\n  d1 = 1; // reset these\n  $(\"#button\"+lix).css('background-color', '#FFA');\n\n  $(\"#cyclestatus\").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer with index ' + lix + ' (' + net.layers[lix].layer_type + ')');\n}\n\n\nvar lossGraph = new cnnvis.Graph();\nvar xLossWindow = new cnnutil.Window(100);\nvar w2LossWindow = new cnnutil.Window(100);\nvar w1LossWindow = new cnnutil.Window(100);\nvar step_num = 0;\nvar colors = [\"red\", \"blue\", \"green\", \"orange\", \"magenta\", \"cyan\", \"purple\", \"silver\", \"olive\", \"lime\", \"yellow\"];\nvar step = function(sample) {\n\n  // train on it with network\n  var stats = trainer.train(sample.x, sample.x.w);\n\n  // keep track of stats such as the average training error and loss  \n  xLossWindow.add(stats.cost_loss);\n  w1LossWindow.add(stats.l1_decay_loss);\n  w2LossWindow.add(stats.l2_decay_loss);\n\n  // visualize training status\n  var train_elt = document.getElementById(\"trainstats\");\n  train_elt.innerHTML = '';\n  var t = 'Forward time per example: ' + stats.fwd_time + 'ms';\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'Backprop time per example: ' + stats.bwd_time + 'ms';\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'Regression loss: ' + f2t(xLossWindow.get_average());\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'L2 Weight decay loss: ' + f2t(w2LossWindow.get_average());\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'L1 Weight decay loss: ' + f2t(w1LossWindow.get_average());\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'Examples seen: ' + step_num;\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n\n  // visualize activations\n  if(step_num % 100 === 0) {\n    var vis_elt = document.getElementById(\"visnet\");\n    visualize_activations(net, vis_elt);\n  }\n\n  // visualize embedding\n  if(step_num % 100 === 0) {\n\n    var embcanvas = document.getElementById('embedding');\n    var ctx = embcanvas.getContext(\"2d\");\n    var EW = embcanvas.width;\n    var EH = embcanvas.height;\n\n    // propagate a few training examples through the network and grab codes\n    var xcodes = [];\n    var ycodes = [];\n    var ns = embed_samples.length; // number of samples\n    for(var k=0;k<ns;k++) {\n      var sample = embed_samples[k];\n      net.forward(sample.x);\n      var xcode = net.layers[lix].out_act.w[d0];\n      var ycode = net.layers[lix].out_act.w[d1];\n      xcodes.push(xcode);\n      ycodes.push(ycode);\n    }\n    var mmx = cnnutil.maxmin(xcodes);\n    var mmy = cnnutil.maxmin(ycodes);\n\n    // draw every example into the canvas\n    ctx.clearRect(0,0,EW,EH);\n    for(var k=0;k<ns;k++) {\n      var xpos = (EW-28*2)*(xcodes[k]-mmx.minv)/mmx.dv+28;\n      var ypos = (EH-28*2)*(ycodes[k]-mmy.minv)/mmy.dv+28;\n      // draw border according to class\n      ctx.fillStyle = colors[embed_samples[k].label];\n      ctx.fillRect(xpos-2,ypos-2,32,32);\n\n      ctx.drawImage(embed_imgs[k], xpos, ypos );\n    }\n\n  }\n\n  // log progress to graph, (full loss)\n  if(step_num % 200 === 0) {\n    var xa = xLossWindow.get_average();\n    var xw1 = w1LossWindow.get_average();\n    var xw2 = w2LossWindow.get_average();\n    if(xa >= 0 && xw1 >= 0 && xw2 >= 0) { // if they are -1 it means not enough data was accumulated yet for estimates\n      lossGraph.add(step_num, xa + xw1 + xw2);\n      lossGraph.drawSelf(document.getElementById(\"lossgraph\"));\n    }\n  }\n\n  step_num++;\n}\n\n// user settings \nvar change_lr = function() {\n  trainer.learning_rate = parseFloat(document.getElementById(\"lr_input\").value);\n  update_net_param_display();\n}\nvar update_net_param_display = function() {\n  document.getElementById('lr_input').value = trainer.learning_rate;\n}\nvar toggle_pause = function() {\n  paused = !paused;\n  var btn = document.getElementById('buttontp');\n  if(paused) { btn.value = 'resume' }\n  else { btn.value = 'pause'; }\n}\nvar dump_json = function() {\n  document.getElementById(\"dumpjson\").value = JSON.stringify(net.toJSON());\n}\nvar clear_graph = function() {\n  lossGraph = new cnnvis.Graph(); // reinit graph too \n}\nvar reset_all = function() {\n  update_net_param_display();\n\n  // reinit windows that keep track of val/train accuracies\n  lossGraph = new cnnvis.Graph(); // reinit graph too\n  step_num = 0;\n\n  // enter buttons for layers\n  var t = '';\n  for(var i=1;i<net.layers.length-1;i++) { // ignore input and regression layers (first and last)\n    var butid = \"button\" + i;\n    t += \"<input id=\\\"\"+butid+\"\\\" value=\\\"\" + net.layers[i].layer_type + \"(\" + net.layers[i].out_depth + \")\" +\"\\\" type=\\\"submit\\\" onclick=\\\"updateLix(\"+i+\")\\\" style=\\\"width:80px; height: 30px; margin:5px;\\\";>\";\n  }\n  $(\"#layer_ixes\").html(t);\n  $(\"#button\"+lix).css('background-color', '#FFA');\n  $(\"#cyclestatus\").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer with index ' + lix + ' (' + net.layers[lix].layer_type + ')');\n\n}\nvar load_from_json = function() {\n  var jsonString = document.getElementById(\"dumpjson\").value;\n  var json = JSON.parse(jsonString);\n  net = new convnetjs.Net();\n  net.fromJSON(json);\n  reset_all();\n}\nvar change_net = function() {\n  eval($(\"#newnet\").val());\n  reset_all();\n}\n"
  },
  {
    "path": "demo/js/automatic.js",
    "content": " \n    // utility functions\n    Array.prototype.contains = function(v) {\n    for(var i = 0; i < this.length; i++) {\n      if(this[i] === v) return true;\n    }\n    return false;\n    };\n    Array.prototype.unique = function() {\n      var arr = [];\n      for(var i = 0; i < this.length; i++) {\n        if(!arr.contains(this[i])) {\n          arr.push(this[i]);\n        }\n      }\n      return arr; \n    }\n    \n    function FAIL(outdivid, msg) {\n      $(outdivid).prepend(\"<div class=\\\"msg\\\" style=\\\"background-color:#FCC;\\\">\"+msg+\"</div>\")\n    }\n    function SUCC(outdivid, msg) {\n      $(outdivid).prepend(\"<div class=\\\"msg\\\" style=\\\"background-color:#CFC;\\\">\"+msg+\"</div>\")\n    }\n\n    // looks at a column i of data and guesses what's in it\n    // returns results of analysis: is column numeric? How many unique entries and what are they?\n    function guessColumn(data, c) {\n      var numeric = true;\n      var vs = [];\n      for(var i=0,n=data.length;i<n;i++) {\n        var v = data[i][c];\n        vs.push(v);\n        if(isNaN(v)) numeric = false;\n      }\n      var u = vs.unique();\n      if(!numeric) {\n        // if we have a non-numeric we will map it through uniques to an index\n        return {numeric:numeric, num:u.length, uniques:u};\n      } else {\n        return {numeric:numeric, num:u.length};\n      }\n    }\n    \n    // returns arr (csv parse)\n    // and colstats, which contains statistics about the columns of the input\n    // parsing results will be appended to a div with id outdivid\n    function importData(arr, outdivid) {\n      $(outdivid).empty(); // flush messages\n\n      // find number of datapoints\n      N = arr.length;\n      var t = [];\n      SUCC(outdivid, \"found \" + N + \" data points\");\n      if(N === 0) { FAIL(outdivid, 'no data points found?'); return; }\n      \n      // find dimensionality and enforce consistency\n      D = arr[0].length;\n      for(var i=0;i<N;i++) {\n        var d = arr[i].length;\n        if(d !== D) { FAIL(outdivid, 'data dimension not constant: line ' + i + ' has ' + d + ' entries.'); return; }\n      }\n      SUCC(outdivid, \"data dimensionality is \" + (D-1));\n      \n      // go through columns of data and figure out what they are\n      var colstats = [];\n      for(var i=0;i<D;i++) {\n        var res = guessColumn(arr, i);\n        colstats.push(res);\n        if(D > 20 && i>3 && i < D-3) {\n          if(i==4) {\n            SUCC(outdivid, \"...\"); // suppress output for too many columns\n          }\n        } else {\n          SUCC(outdivid, \"column \" + i + \" looks \" + (res.numeric ? \"numeric\" : \"NOT numeric\") + \" and has \" + res.num + \" unique elements\");\n        }\n      }\n\n      return {arr: arr, colstats: colstats};\n   }\n    \n  // process input mess into vols and labels\n  function makeDataset(arr, colstats) {\n\n    var labelix = parseInt($(\"#labelix\").val());\n    if(labelix < 0) labelix = D + labelix; // -1 should turn to D-1\n\n    var data = [];\n    var labels = [];\n    for(var i=0;i<N;i++) {\n      var arri = arr[i];\n      \n      // create the input datapoint Vol()\n      var p = arri.slice(0, D-1);\n      var xarr = [];\n      for(var j=0;j<D;j++) {\n        if(j===labelix) continue; // skip!\n\n        if(colstats[j].numeric) {\n          xarr.push(parseFloat(arri[j]));\n        } else {\n          var u = colstats[j].uniques;\n          var ix = u.indexOf(arri[j]); // turn into 1ofk encoding\n          for(var q=0;q<u.length;q++) {\n            if(q === ix) { xarr.push(1.0); }\n            else { xarr.push(0.0); }\n          }\n        }\n      }\n      var x = new convnetjs.Vol(xarr);\n      \n      // process the label (last column)\n      if(colstats[labelix].numeric) {\n        var L = parseFloat(arri[labelix]); // regression\n      } else {\n        var L = colstats[labelix].uniques.indexOf(arri[labelix]); // classification\n        if(L==-1) {\n          console.log('whoa label not found! CRITICAL ERROR, very fishy.');\n        }\n      }\n      data.push(x);\n      labels.push(L);\n    }\n    \n    var dataset = {};\n    dataset.data = data;\n    dataset.labels = labels;\n    return dataset;\n  }\n\n  // optionally provide a magic net\n  function testEval(optional_net) {\n    if (typeof optional_net !== 'undefined') {\n      var net = optional_net;\n    } else {\n      var net = magicNet;\n    }\n\n    // set options for magic net\n    net.ensemble_size = parseInt($(\"#ensemblenum\").val())\n\n    // read in the data in the text field\n    var test_dataset = importTestData();\n    // use magic net to predict\n    var n = test_dataset.data.length;\n    var acc = 0.0;\n    for(var i=0;i<n;i++) {\n      var yhat = net.predict(test_dataset.data[i]);\n      if(yhat === -1) {\n        $(\"#testresult\").html(\"The MagicNet is not yet ready! It must process at least one batch of candidates across all folds first. Wait a bit.\");\n        $(\"#testresult\").css('background-color', '#FCC');\n        return;\n      }\n      var l = test_dataset.labels[i];\n      acc += (yhat === l ? 1 : 0); // 0-1 loss\n      console.log('test example ' + i + ': predicting ' + yhat + ', ground truth is ' + l);\n    }\n    acc /= n;\n\n    // report accuracy\n    $(\"#testresult\").html(\"Test set accuracy: \" + acc);\n    $(\"#testresult\").css('background-color', '#CFC');\n  }\n\n  function reinitGraph() {\n    var legend = [];\n    for(var i=0;i<magicNet.candidates.length;i++) {\n      legend.push('model ' + i);\n    }\n    valGraph = new cnnvis.MultiGraph(legend, {miny: 0, maxy: 1});\n  }\n\n  var folds_evaluated = 0;\n  function finishedFold() {\n    folds_evaluated++;\n    $(\"#foldreport\").html(\"So far evaluated a total of \" + folds_evaluated + \"/\" + magicNet.num_folds + \" folds in current batch\");\n    reinitGraph();\n  }\n  var batches_evaluated = 0;\n  function finishedBatch() {\n    batches_evaluated++;\n    $(\"#candsreport\").html(\"So far evaluated a total of \" + batches_evaluated + \" batches of candidates\");\n  }\n\n  var magicNet = null;\n  function startCV() { // takes in train_dataset global\n    var opts = {}\n    opts.train_ratio = parseInt($(\"#trainp\").val())/100.0;\n    opts.num_folds = parseInt($(\"#foldsnum\").val());\n    opts.num_candidates = parseInt($(\"#candsnum\").val());\n    opts.num_epochs = parseInt($(\"#epochsnum\").val());\n    opts.neurons_min = parseInt($(\"#nnmin\").val());\n    opts.neurons_max = parseInt($(\"#nnmin\").val());\n    magicNet = new convnetjs.MagicNet(train_dataset.data, train_dataset.labels, opts);\n    magicNet.onFinishFold(finishedFold);\n    magicNet.onFinishBatch(finishedBatch);\n\n    folds_evaluated = 0;\n    batches_evaluated = 0;\n    $(\"#candsreport\").html(\"So far evaluated a total of \" + batches_evaluated + \" batches of candidates\");\n    $(\"#foldreport\").html(\"So far evaluated a total of \" + folds_evaluated + \"/\" + magicNet.num_folds + \" folds in current batch\");\n    reinitGraph();\n\n    var legend = [];\n    for(var i=0;i<magicNet.candidates.length;i++) {\n      legend.push('model ' + i);\n    }\n    valGraph = new cnnvis.MultiGraph(legend, {miny: 0, maxy: 1});\n    setInterval(step, 0);\n  }\n      \n    var fold;\n    var cands = [];\n    var dostep = false;\n    var valGraph;\n    var iter = 0;\n    function step() {\n      iter++;\n      \n      magicNet.step();\n      if(iter % 300 == 0) {\n\n        var vals = magicNet.evalValErrors();\n        valGraph.add(magicNet.iter, vals);\n        valGraph.drawSelf(document.getElementById(\"valgraph\"));\n    \n        // print out the best models so far\n        var cands = magicNet.candidates; // naughty: get pointer to internal data\n        var scores = [];\n        for(var k=0;k<cands.length;k++) {\n          var c = cands[k];\n          var s = c.acc.length === 0 ? 0 : c.accv / c.acc.length;\n          scores.push(s);\n        }\n        var mm = convnetjs.maxmin(scores);\n        var cm = cands[mm.maxi];\n        var t = '';\n        if(c.acc.length > 0) {\n          t += 'Results based on ' + c.acc.length + ' folds:';\n          t += 'best model in current batch (validation accuracy ' + mm.maxv + '):<br>';\n          t += '<b>Net layer definitions:</b><br>';\n          t += JSON.stringify(cm.layer_defs);\n          t += '<br><b>Trainer definition:</b><br>';\n          t += JSON.stringify(cm.trainer_def);\n          t += '<br>';\n        }\n        $('#bestmodel').html(t);\n\n        // also print out the best model so far\n        var t = '';\n        if(magicNet.evaluated_candidates.length > 0) {\n          var cm = magicNet.evaluated_candidates[0];\n          t += 'validation accuracy of best model so far, overall: ' + cm.accv / cm.acc.length + '<br>';\n          t += '<b>Net layer definitions:</b><br>';\n          t += JSON.stringify(cm.layer_defs);\n          t += '<br><b>Trainer definition:</b><br>';\n          t += JSON.stringify(cm.trainer_def);\n          t += '<br>';\n        }\n        $('#bestmodeloverall').html(t);\n      }\n    }\n    \n    // TODO: MOVE TO CONVNETJS UTILS\n    var randperm = function(n) {\n      var i = n,\n          j = 0,\n          temp;\n      var array = [];\n      for(var q=0;q<n;q++)array[q]=q;\n      while (i--) {\n          j = Math.floor(Math.random() * (i+1));\n          temp = array[i];\n          array[i] = array[j];\n          array[j] = temp;\n      }\n      return array;\n    }\n\n    var train_dataset, train_import_data; // globals\n    function importTrainData() {\n      var csv_txt = $('#data-ta').val();\n      var arr = $.csv.toArrays(csv_txt);\n      var arr_train = arr;\n      var arr_test = [];\n\n      var test_ratio = Math.floor($(\"#testsplit\").val());\n      if(test_ratio !== 0) {\n        // send some lines to test set\n        var test_lines_num = Math.floor(arr.length * test_ratio / 100.0);\n        var rp = randperm(arr.length);\n        arr_train = [];\n        for(var i=0;i<arr.length;i++) {\n          if(i<test_lines_num) {\n            arr_test.push(arr[rp[i]]);\n          } else {\n            arr_train.push(arr[rp[i]]);\n          }\n        }\n        // enter test lines to test box\n        var t = \"\";\n        for(var i=0;i<arr_test.length;i++) {\n          t+= arr_test[i].join(\",\")+\"\\n\";\n        }\n        $(\"#data-te\").val(t);\n        $(\"#datamsgtest\").empty();\n      }\n\n      $(\"#prepromsg\").empty(); // flush\n      SUCC(\"#prepromsg\", \"Sent \" + arr_test.length + \" data to test, keeping \" + arr_train.length + \" for train.\");\n      train_import_data = importData(arr_train,'#datamsg');\n      train_dataset = makeDataset(train_import_data.arr, train_import_data.colstats);\n      return train_dataset;\n    }\n\n    function importTestData() {\n      var csv_txt = $('#data-te').val();\n      var arr = $.csv.toArrays(csv_txt);\n      var import_data = importData(arr,'#datamsgtest');\n      // note important that we use colstats of train data!\n      test_dataset = makeDataset(import_data.arr, train_import_data.colstats);\n      return test_dataset;\n    }\n\n    function loadDB(url) {\n      // load a dataset from a url with ajax\n      $.ajax({\n        url: url,\n        dataType: \"text\",\n        success: function(txt) {\n          $(\"#data-ta\").val(txt);\n        }\n      });\n    }\n\n    function start() {\n      loadDB('data/car.data.txt');\n    }\n\n    function exportMagicNet() {\n      $(\"#taexport\").val(JSON.stringify(magicNet.toJSON()));\n\n      /*\n      // for debugging\n      var j = JSON.parse($(\"#taexport\").val());\n      var m = new convnetjs.MagicNet();\n      m.fromJSON(j);\n      testEval(m);\n      */\n    }\n\n    function changeNNRange() {\n      magicNet.neurons_min = parseInt($(\"#nnmin\").val());\n      magicNet.neurons_max = parseInt($(\"#nnmax\").val());\n    }\n"
  },
  {
    "path": "demo/js/classify2d.js",
    "content": "\nvar data, labels, N;\nvar ss = 50.0; // scale for drawing\n\n// create neural net\nvar layer_defs, net, trainer;\nvar t = \"\\n\\\nlayer_defs = [];\\n\\\nlayer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:2});\\n\\\nlayer_defs.push({type:'fc', num_neurons:6, activation: 'tanh'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:2, activation: 'tanh'});\\n\\\nlayer_defs.push({type:'softmax', num_classes:2});\\n\\\n\\n\\\nnet = new convnetjs.Net();\\n\\\nnet.makeLayers(layer_defs);\\n\\\n\\n\\\ntrainer = new convnetjs.SGDTrainer(net, {learning_rate:0.01, momentum:0.1, batch_size:10, l2_decay:0.001});\\n\\\n\";\n\nfunction reload() {\n  eval($(\"#layerdef\").val());\n\n  // enter buttons for layers\n  var t = '';\n  for(var i=1;i<net.layers.length-1;i++) { // ignore input and regression layers (first and last)\n    var butid = \"button\" + i;\n    t += \"<input id=\\\"\"+butid+\"\\\" value=\\\"\" + net.layers[i].layer_type + \"(\" + net.layers[i].out_depth + \")\" +\"\\\" type=\\\"submit\\\" onclick=\\\"updateLix(\"+i+\")\\\" style=\\\"width:80px; height: 30px; margin:5px;\\\";>\";\n  }\n  $(\"#layer_ixes\").html(t);\n  $(\"#button\"+lix).css('background-color', '#FFA');\n  $(\"#cyclestatus\").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer with index ' + lix + ' (' + net.layers[lix].layer_type + ')');\n}\nfunction updateLix(newlix) {\n  $(\"#button\"+lix).css('background-color', ''); // erase highlight\n  lix = newlix;\n  d0 = 0;\n  d1 = 1; // reset these\n  $(\"#button\"+lix).css('background-color', '#FFA');\n\n  $(\"#cyclestatus\").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer with index ' + lix + ' (' + net.layers[lix].layer_type + ')');\n}\n \n\nfunction myinit() { }\n\nfunction random_data(){\n  data = [];\n  labels = [];\n  for(var k=0;k<40;k++) {\n    data.push([convnetjs.randf(-3,3), convnetjs.randf(-3,3)]); labels.push(convnetjs.randf(0,1) > 0.5 ? 1 : 0);\n  }\n  N = labels.length;\n}\n\nfunction original_data(){\n  \n  data = [];\n  labels = [];\n  data.push([-0.4326  ,  1.1909 ]); labels.push(1);\n  data.push([3.0, 4.0]); labels.push(1);\n  data.push([0.1253 , -0.0376   ]); labels.push(1);\n  data.push([0.2877 ,   0.3273  ]); labels.push(1);\n  data.push([-1.1465 ,   0.1746 ]); labels.push(1);\n  data.push([1.8133 ,   1.0139  ]); labels.push(0);\n  data.push([2.7258 ,   1.0668  ]); labels.push(0);\n  data.push([1.4117 ,   0.5593  ]); labels.push(0);\n  data.push([4.1832 ,   0.3044  ]); labels.push(0);\n  data.push([1.8636 ,   0.1677  ]); labels.push(0);\n  data.push([0.5 ,   3.2  ]); labels.push(1);\n  data.push([0.8 ,   3.2  ]); labels.push(1);\n  data.push([1.0 ,   -2.2  ]); labels.push(1);\n  N = labels.length;\n}\n\nfunction circle_data() {\n  data = [];\n  labels = [];\n  for(var i=0;i<50;i++) {\n    var r = convnetjs.randf(0.0, 2.0);\n    var t = convnetjs.randf(0.0, 2*Math.PI);\n    data.push([r*Math.sin(t), r*Math.cos(t)]);\n    labels.push(1);\n  }\n  for(var i=0;i<50;i++) {\n    var r = convnetjs.randf(3.0, 5.0);\n    //var t = convnetjs.randf(0.0, 2*Math.PI);\n    var t = 2*Math.PI*i/50.0\n    data.push([r*Math.sin(t), r*Math.cos(t)]);\n    labels.push(0);\n  }\n  N = data.length;\n}\n\nfunction spiral_data() {\n  data = [];\n  labels = [];\n  var n = 100;\n  for(var i=0;i<n;i++) {\n    var r = i/n*5 + convnetjs.randf(-0.1, 0.1);\n    var t = 1.25*i/n*2*Math.PI + convnetjs.randf(-0.1, 0.1);\n    data.push([r*Math.sin(t), r*Math.cos(t)]);\n    labels.push(1);\n  }\n  for(var i=0;i<n;i++) {\n    var r = i/n*5 + convnetjs.randf(-0.1, 0.1);\n    var t = 1.25*i/n*2*Math.PI + Math.PI + convnetjs.randf(-0.1, 0.1);\n    data.push([r*Math.sin(t), r*Math.cos(t)]);\n    labels.push(0);\n  }\n  N = data.length;\n}\n \nfunction update(){\n  // forward prop the data\n\n  var start = new Date().getTime();\n\n  var x = new convnetjs.Vol(1,1,2);\n  //x.w = data[ix];\n  var avloss = 0.0;\n  for(var iters=0;iters<20;iters++) {\n    for(var ix=0;ix<N;ix++) {\n      x.w = data[ix];\n      var stats = trainer.train(x, labels[ix]);\n      avloss += stats.loss;\n    }\n  }\n  avloss /= N*iters;\n\n  var end = new Date().getTime();\n  var time = end - start;\n      \n  //console.log('loss = ' + avloss + ', 100 cycles through data in ' + time + 'ms');\n}\n\nfunction cycle() {\n  var selected_layer = net.layers[lix];\n  d0 += 1;\n  d1 += 1;\n  if(d1 >= selected_layer.out_depth) d1 = 0; // and wrap\n  if(d0 >= selected_layer.out_depth) d0 = 0; // and wrap\n  $(\"#cyclestatus\").html('drawing neurons ' + d0 + ' and ' + d1 + ' of layer #' + lix + ' (' + net.layers[lix].layer_type + ')');\n}\n\nvar lix = 4; // layer id to track first 2 neurons of\nvar d0 = 0; // first dimension to show visualized\nvar d1 = 1; // second dimension to show visualized\nfunction draw(){\n    \n    ctx.clearRect(0,0,WIDTH,HEIGHT);\n    \n    var netx = new convnetjs.Vol(1,1,2);\n    // draw decisions in the grid\n    var density= 5.0;\n    var gridstep = 2;\n    var gridx = [];\n    var gridy = [];\n    var gridl = []; \n    for(var x=0.0, cx=0; x<=WIDTH; x+= density, cx++) {\n      for(var y=0.0, cy=0; y<=HEIGHT; y+= density, cy++) {\n        //var dec= svm.marginOne([(x-WIDTH/2)/ss, (y-HEIGHT/2)/ss]);\n        netx.w[0] = (x-WIDTH/2)/ss;\n        netx.w[1] = (y-HEIGHT/2)/ss;\n        var a = net.forward(netx, false);\n        \n        if(a.w[0] > a.w[1]) ctx.fillStyle = 'rgb(250, 150, 150)';\n        else ctx.fillStyle = 'rgb(150, 250, 150)';\n\n        //ctx.fillStyle = 'rgb(150,' + Math.floor(a.w[0]*105)+150 + ',150)';\n        //ctx.fillStyle = 'rgb(' + Math.floor(a.w[0]*255) + ',' + Math.floor(a.w[1]*255) + ', 0)';\n        ctx.fillRect(x-density/2-1, y-density/2-1, density+2, density+2);\n\n        if(cx%gridstep === 0 && cy%gridstep===0) {\n          // record the transformation information\n          var xt = net.layers[lix].out_act.w[d0]; // in screen coords\n          var yt = net.layers[lix].out_act.w[d1]; // in screen coords\n          gridx.push(xt);\n          gridy.push(yt);\n          gridl.push(a.w[0] > a.w[1]); // remember final label as well\n        }\n      }\n    }\n\n    // draw axes\n    ctx.beginPath();\n    ctx.strokeStyle = 'rgb(50,50,50)';\n    ctx.lineWidth = 1;\n    ctx.moveTo(0, HEIGHT/2);\n    ctx.lineTo(WIDTH, HEIGHT/2);\n    ctx.moveTo(WIDTH/2, 0);\n    ctx.lineTo(WIDTH/2, HEIGHT);\n    ctx.stroke();\n\n    // draw representation transformation axes for two neurons at some layer\n    var mmx = cnnutil.maxmin(gridx);\n    var mmy = cnnutil.maxmin(gridy);\n    visctx.clearRect(0,0,visWIDTH,visHEIGHT);\n    visctx.strokeStyle = 'rgb(0, 0, 0)';\n    var n = Math.floor(Math.sqrt(gridx.length)); // size of grid. Should be fine?\n    var ng = gridx.length;\n    var c = 0; // counter\n    visctx.beginPath() \n    for(var x=0;x<n;x++) {\n      for(var y=0;y<n;y++) {\n\n        // down\n        var ix1 = x*n+y;\n        var ix2 = x*n+y+1;\n        if(ix1 >= 0 && ix2 >= 0 && ix1 < ng && ix2 < ng && y<n-1) { // check oob\n          var xraw = gridx[ix1];\n          xraw1 = visWIDTH*(gridx[ix1] - mmx.minv)/mmx.dv;\n          yraw1 = visHEIGHT*(gridy[ix1] - mmy.minv)/mmy.dv;\n          xraw2 = visWIDTH*(gridx[ix2] - mmx.minv)/mmx.dv;\n          yraw2 = visHEIGHT*(gridy[ix2] - mmy.minv)/mmy.dv;\n          visctx.moveTo(xraw1, yraw1);\n          visctx.lineTo(xraw2, yraw2);\n        }\n\n        // and draw its color\n        if(gridl[ix1]) visctx.fillStyle = 'rgb(250, 150, 150)';\n        else visctx.fillStyle = 'rgb(150, 250, 150)';\n        var sz = density * gridstep;\n        visctx.fillRect(xraw1-sz/2-1, yraw1-sz/2-1, sz+2, sz+2);\n\n        // right\n        var ix1 = (x+1)*n+y;\n        var ix2 = x*n+y;\n        if(ix1 >= 0 && ix2 >= 0 && ix1 < ng && ix2 < ng && x <n-1) { // check oob\n          var xraw = gridx[ix1];\n          xraw1 = visWIDTH*(gridx[ix1] - mmx.minv)/mmx.dv;\n          yraw1 = visHEIGHT*(gridy[ix1] - mmy.minv)/mmy.dv;\n          xraw2 = visWIDTH*(gridx[ix2] - mmx.minv)/mmx.dv;\n          yraw2 = visHEIGHT*(gridy[ix2] - mmy.minv)/mmy.dv;\n          visctx.moveTo(xraw1, yraw1);\n          visctx.lineTo(xraw2, yraw2);\n        }\n \n      }\n    }\n    visctx.stroke();\n\n    // draw datapoints.\n    ctx.strokeStyle = 'rgb(0,0,0)';\n    ctx.lineWidth = 1;\n    for(var i=0;i<N;i++) {\n      \n      if(labels[i]==1) ctx.fillStyle = 'rgb(100,200,100)';\n      else ctx.fillStyle = 'rgb(200,100,100)';\n      \n      drawCircle(data[i][0]*ss+WIDTH/2, data[i][1]*ss+HEIGHT/2, 5.0);\n\n      // also draw transformed data points while we're at it\n      netx.w[0] = data[i][0];\n      netx.w[1] = data[i][1]\n      var a = net.forward(netx, false);\n      var xt = visWIDTH * (net.layers[lix].out_act.w[d0] - mmx.minv) / mmx.dv; // in screen coords\n      var yt = visHEIGHT * (net.layers[lix].out_act.w[d1] - mmy.minv) / mmy.dv; // in screen coords\n      if(labels[i]==1) visctx.fillStyle = 'rgb(100,200,100)';\n      else visctx.fillStyle = 'rgb(200,100,100)';\n      visctx.beginPath();\n      visctx.arc(xt, yt, 5.0, 0, Math.PI*2, true); \n      visctx.closePath();\n      visctx.stroke();\n      visctx.fill();\n    }\n}\n\nfunction mouseClick(x, y, shiftPressed, ctrlPressed){\n  \n  // x and y transformed to data space coordinates\n  var xt = (x-WIDTH/2)/ss;\n  var yt = (y-HEIGHT/2)/ss;\n\n  if(ctrlPressed) {\n    // remove closest data point\n    var mink = -1;\n    var mind = 99999;\n    for(var k=0, n=data.length;k<n;k++) {\n      var dx = data[k][0] - xt;\n      var dy = data[k][1] - yt;\n      var d = dx*dx+dy*dy;\n      if(d < mind || k==0) {\n        mind = d;\n        mink = k;\n      }\n    }\n    if(mink>=0) {\n      console.log('splicing ' + mink);\n      data.splice(mink, 1);\n      labels.splice(mink, 1);\n      N -= 1;\n    }\n\n  } else {\n    // add datapoint at location of click\n    data.push([xt, yt]);\n    labels.push(shiftPressed ? 1 : 0);\n    N += 1;\n  }\n\n}\n\nfunction keyDown(key){\n}\n\nfunction keyUp(key) {\n}\n\n$(function() {\n    // note, globals\n    viscanvas = document.getElementById('viscanvas');\n    visctx = viscanvas.getContext('2d');\n    visWIDTH = viscanvas.width;\n    visHEIGHT = viscanvas.height;\n\n    circle_data();\n    $(\"#layerdef\").val(t);\n    reload();\n    NPGinit(20);\n\n});"
  },
  {
    "path": "demo/js/image-helpers.js",
    "content": "\nvar loadFile = function(event) {\nvar reader = new FileReader();\nreader.onload = function(){\n  var preview = document.getElementById('preview_img');\n  preview.src = centerCrop(reader.result);\n  preview.src = resize(preview.src);\n};\nreader.readAsDataURL(event.target.files[0]);\n};\n\nfunction centerCrop(src){\n    var image = new Image();\n    image.src = src;\n\n    var max_width = Math.min(image.width, image.height);\n    var max_height = Math.min(image.width, image.height);\n\n    var canvas = document.createElement('canvas');\n    var ctx = canvas.getContext(\"2d\");\n\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\n    canvas.width = max_width;\n    canvas.height = max_height;\n    ctx.drawImage(image, (max_width - image.width)/2, (max_height - image.height)/2, image.width, image.height);\n    return canvas.toDataURL(\"image/png\");\n}\n\nfunction resize(src){\n    var image = new Image();\n    image.src = src;\n\n    var canvas = document.createElement('canvas');\n    canvas.width = image.width;\n    canvas.height = image.height;\n    var ctx = canvas.getContext(\"2d\");\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\n    ctx.drawImage(image, 0, 0, image.width, image.height);\n\n    var dst = document.createElement('canvas');\n    dst.width = image_dimension;\n    dst.height = image_dimension;\n\n    window.pica.WW = false;\n    window.pica.resizeCanvas(canvas, dst, {\n    quality: 2,\n    unsharpAmount: 500,\n    unsharpThreshold: 100,\n    transferable: false\n  }, function (err) {  });\n    window.pica.WW = true;\n    return dst.toDataURL(\"image/png\");\n}\n  \n"
  },
  {
    "path": "demo/js/image_regression.js",
    "content": "\nvar data, labels;\nvar layer_defs, net, trainer;\n\n// create neural net\nvar t = \"layer_defs = [];\\n\\\nlayer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:2}); // 2 inputs: x, y \\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'regression', num_neurons:3}); // 3 outputs: r,g,b \\n\\\n\\n\\\nnet = new convnetjs.Net();\\n\\\nnet.makeLayers(layer_defs);\\n\\\n\\n\\\ntrainer = new convnetjs.SGDTrainer(net, {learning_rate:0.01, momentum:0.9, batch_size:5, l2_decay:0.0});\\n\\\n\";\n\nvar batches_per_iteration = 100;\nvar mod_skip_draw = 100;\nvar smooth_loss = -1;\n\nfunction update(){\n  // forward prop the data\n  var W = nn_canvas.width;\n  var H = nn_canvas.height;\n\n  var p = oridata.data;\n\n  var v = new convnetjs.Vol(1,1,2);\n  var loss = 0;\n  var lossi = 0;\n  var N = batches_per_iteration;\n  for(var iters=0;iters<trainer.batch_size;iters++) {\n    for(var i=0;i<N;i++) {\n      // sample a coordinate\n      var x = convnetjs.randi(0, W);\n      var y = convnetjs.randi(0, H);\n      var ix = ((W*y)+x)*4;\n      var r = [p[ix]/255.0, p[ix+1]/255.0, p[ix+2]/255.0]; // r g b\n      v.w[0] = (x-W/2)/W;\n      v.w[1] = (y-H/2)/H;\n      var stats = trainer.train(v, r);\n      loss += stats.loss;\n      lossi += 1;\n    }\n  }\n  loss /= lossi;\n\n  if(counter === 0) smooth_loss = loss;\n  else smooth_loss = 0.99*smooth_loss + 0.01*loss;\n\n  var t = '';\n  t += 'loss: ' + smooth_loss;\n  t += '<br>'\n  t += 'iteration: ' + counter;\n  $(\"#report\").html(t);\n}\n\nfunction draw() {\n  if(counter % mod_skip_draw !== 0) return;\n\n  // iterate over all pixels in the target array, evaluate them\n  // and draw\n  var W = nn_canvas.width;\n  var H = nn_canvas.height;\n\n  var g = nn_ctx.getImageData(0, 0, W, H);\n  var v = new convnetjs.Vol(1, 1, 2);\n  for(var x=0;x<W;x++) {\n    v.w[0] = (x-W/2)/W;\n    for(var y=0;y<H;y++) {\n      v.w[1] = (y-H/2)/H;\n\n      var ix = ((W*y)+x)*4;\n      var r = net.forward(v);\n      g.data[ix+0] = Math.floor(255*r.w[0]);\n      g.data[ix+1] = Math.floor(255*r.w[1]);\n      g.data[ix+2] = Math.floor(255*r.w[2]);\n      g.data[ix+3] = 255; // alpha...\n    }\n  }\n  nn_ctx.putImageData(g, 0, 0);\n}\n\nfunction tick() {\n  update();\n  draw();\n  counter += 1;\n}\n\nfunction reload() {\n  counter = 0;\n  eval($(\"#layerdef\").val());\n  //$(\"#slider\").slider(\"value\", Math.log(trainer.learning_rate) / Math.LN10);\n  //$(\"#lr\").html('Learning rate: ' + trainer.learning_rate);\n}\nfunction refreshSwatch() {\n  var lr = $(\"#slider\").slider(\"value\");\n  trainer.learning_rate = Math.pow(10, lr);\n  $(\"#lr\").html('Learning rate: ' + trainer.learning_rate);\n}\n\nvar ori_canvas, nn_canvas, ori_ctx, nn_ctx, oridata;\nvar sz = 200; // size of our drawing area\nvar counter = 0;\n$(function() {\n    // dynamically load lena image into original image canvas\n    var image = new Image();\n    //image.src = \"lena.png\";\n    image.onload = function() {\n\n      ori_canvas = document.getElementById('canv_original');\n      nn_canvas = document.getElementById('canv_net');\n      ori_canvas.width = sz;\n      ori_canvas.height = sz;\n      nn_canvas.width = sz;\n      nn_canvas.height = sz;\n\n      ori_ctx = ori_canvas.getContext(\"2d\");\n      nn_ctx = nn_canvas.getContext(\"2d\");\n      ori_ctx.drawImage(image, 0, 0, sz, sz);\n      oridata = ori_ctx.getImageData(0, 0, sz, sz); // grab the data pointer. Our dataset.\n\n      // start the regression!\n      setInterval(tick, 1);\n    }\n    image.src = \"imgs/cat.jpg\";\n\n    // init put text into textarea\n    $(\"#layerdef\").val(t);\n\n    // load the net\n    reload();\n\n    // set up slider for learning rate\n    $(\"#slider\").slider({\n      orientation: \"horizontal\",\n      min: -4,\n      max: -1,\n      step: 0.05,\n      value: Math.log(trainer.learning_rate) / Math.LN10,\n      slide: refreshSwatch,\n      change: refreshSwatch\n    });\n    $(\"#lr\").html('Learning rate: ' + trainer.learning_rate);\n\n    $(\"#f\").on('change', function(ev) {\n      var f = ev.target.files[0];\n      var fr = new FileReader();\n      fr.onload = function(ev2) {\n        var image = new Image();\n        image.onload = function(){\n          ori_ctx.drawImage(image, 0, 0, sz, sz);\n          oridata = ori_ctx.getImageData(0, 0, sz, sz);\n          reload();\n        }\n        image.src = ev2.target.result;\n      };\n      fr.readAsDataURL(f);\n    });\n\n    $('.ci').click(function(){\n      var src = $(this).attr('src');\n      ori_ctx.drawImage(this, 0, 0, sz, sz);\n      oridata = ori_ctx.getImageData(0, 0, sz, sz);\n      reload();\n    });\n});\n"
  },
  {
    "path": "demo/js/images-demo.js",
    "content": "var sample_training_instance = function() {\n  // find an unloaded batch\n  var bi = Math.floor(Math.random()*loaded_train_batches.length);\n  var b = loaded_train_batches[bi];\n  var k = Math.floor(Math.random()*num_samples_per_batch); // sample within the batch\n  var n = b*num_samples_per_batch+k;\n\n  // load more batches over time\n  if(step_num%(2 * num_samples_per_batch)===0 && step_num>0) {\n    for(var i=0;i<num_batches;i++) {\n      if(!loaded[i]) {\n        // load it\n        load_data_batch(i);\n        break; // okay for now\n      }\n    }\n  }\n\n  // fetch the appropriate row of the training image and reshape into a Vol\n  var p = img_data[b].data;\n  var x = new convnetjs.Vol(image_dimension,image_dimension,image_channels,0.0);\n  var W = image_dimension*image_dimension;\n  var j=0;\n  for(var dc=0;dc<image_channels;dc++) {\n    var i=0;\n    for(var xc=0;xc<image_dimension;xc++) {\n      for(var yc=0;yc<image_dimension;yc++) {\n        var ix = ((W * k) + i) * 4 + dc;\n        x.set(yc,xc,dc,p[ix]/255.0-0.5);\n        i++;\n      }\n    }\n  }\n\n  if(random_position){\n    var dx = Math.floor(Math.random()*5-2);\n    var dy = Math.floor(Math.random()*5-2);\n    x = convnetjs.augment(x, image_dimension, dx, dy, false); //maybe change position\n  }\n\n  if(random_flip){\n    x = convnetjs.augment(x, image_dimension, 0, 0, Math.random()<0.5); //maybe flip horizontally\n  }\n\n  var isval = use_validation_data && n%10===0 ? true : false;\n  return {x:x, label:labels[n], isval:isval};\n}\n\n// sample a random testing instance\nvar sample_test_instance = function() {\n\n  var b = test_batch;\n  var k = Math.floor(Math.random()*num_samples_per_batch);\n  var n = b*num_samples_per_batch+k;\n\n  var p = img_data[b].data;\n  var x = new convnetjs.Vol(image_dimension,image_dimension,image_channels,0.0);\n  var W = image_dimension*image_dimension;\n  var j=0;\n  for(var dc=0;dc<image_channels;dc++) {\n    var i=0;\n    for(var xc=0;xc<image_dimension;xc++) {\n      for(var yc=0;yc<image_dimension;yc++) {\n        var ix = ((W * k) + i) * 4 + dc;\n        x.set(yc,xc,dc,p[ix]/255.0-0.5);\n        i++;\n      }\n    }\n  }\n\n  // distort position and maybe flip\n  var xs = [];\n  \n  if (random_flip || random_position){\n    for(var k=0;k<6;k++) {\n      var test_variation = x;\n      if(random_position){\n        var dx = Math.floor(Math.random()*5-2);\n        var dy = Math.floor(Math.random()*5-2);\n        test_variation = convnetjs.augment(test_variation, image_dimension, dx, dy, false);\n      }\n      \n      if(random_flip){\n        test_variation = convnetjs.augment(test_variation, image_dimension, 0, 0, Math.random()<0.5); \n      }\n\n      xs.push(test_variation);\n    }\n  }else{\n    xs.push(x, image_dimension, 0, 0, false); // push an un-augmented copy\n  }\n  \n  // return multiple augmentations, and we will average the network over them\n  // to increase performance\n  return {x:xs, label:labels[n]};\n}\n\n\nvar data_img_elts = new Array(num_batches);\nvar img_data = new Array(num_batches);\nvar loaded = new Array(num_batches);\nvar loaded_train_batches = [];\n\n// int main\n$(window).load(function() {\n\n  $(\"#newnet\").val(t);\n  eval($(\"#newnet\").val());\n\n  update_net_param_display();\n\n  for(var k=0;k<loaded.length;k++) { loaded[k] = false; }\n\n  load_data_batch(0); // async load train set batch 0\n  load_data_batch(test_batch); // async load test set\n  start_fun();\n});\n\nvar start_fun = function() {\n  if(loaded[0] && loaded[test_batch]) { \n    console.log('starting!'); \n    setInterval(load_and_step, 0); // lets go!\n  }\n  else { setTimeout(start_fun, 200); } // keep checking\n}\n\nvar load_data_batch = function(batch_num) {\n  // Load the dataset with JS in background\n  data_img_elts[batch_num] = new Image();\n  var data_img_elt = data_img_elts[batch_num];\n  data_img_elt.onload = function() { \n    var data_canvas = document.createElement('canvas');\n    data_canvas.width = data_img_elt.width;\n    data_canvas.height = data_img_elt.height;\n    var data_ctx = data_canvas.getContext(\"2d\");\n    data_ctx.drawImage(data_img_elt, 0, 0); // copy it over... bit wasteful :(\n    img_data[batch_num] = data_ctx.getImageData(0, 0, data_canvas.width, data_canvas.height);\n    loaded[batch_num] = true;\n    if(batch_num < test_batch) { loaded_train_batches.push(batch_num); }\n    console.log('finished loading data batch ' + batch_num);\n  };\n  data_img_elt.src = dataset_name + \"/\" + dataset_name + \"_batch_\" + batch_num + \".png\";\n}\n\nvar maxmin = cnnutil.maxmin;\nvar f2t = cnnutil.f2t;\n\n// elt is the element to add all the canvas activation drawings into\n// A is the Vol() to use\n// scale is a multiplier to make the visualizations larger. Make higher for larger pictures\n// if grads is true then gradients are used instead\nvar draw_activations = function(elt, A, scale, grads) {\n\n  var s = scale || 2; // scale\n  var draw_grads = false;\n  if(typeof(grads) !== 'undefined') draw_grads = grads;\n\n  // get max and min activation to scale the maps automatically\n  var w = draw_grads ? A.dw : A.w;\n  var mm = maxmin(w);\n\n  // create the canvas elements, draw and add to DOM\n  for(var d=0;d<A.depth;d++) {\n\n    var canv = document.createElement('canvas');\n    canv.className = 'actmap';\n    var W = A.sx * s;\n    var H = A.sy * s;\n    canv.width = W;\n    canv.height = H;\n    var ctx = canv.getContext('2d');\n    var g = ctx.createImageData(W, H);\n\n    for(var x=0;x<A.sx;x++) {\n      for(var y=0;y<A.sy;y++) {\n        if(draw_grads) {\n          var dval = Math.floor((A.get_grad(x,y,d)-mm.minv)/mm.dv*255);\n        } else {\n          var dval = Math.floor((A.get(x,y,d)-mm.minv)/mm.dv*255);  \n        }\n        for(var dx=0;dx<s;dx++) {\n          for(var dy=0;dy<s;dy++) {\n            var pp = ((W * (y*s+dy)) + (dx + x*s)) * 4;\n            for(var i=0;i<3;i++) { g.data[pp + i] = dval; } // rgb\n            g.data[pp+3] = 255; // alpha channel\n          }\n        }\n      }\n    }\n    ctx.putImageData(g, 0, 0);\n    elt.appendChild(canv);\n  }  \n}\n\nvar draw_activations_COLOR = function(elt, A, scale, grads) {\n\n  var s = scale || 2; // scale\n  var draw_grads = false;\n  if(typeof(grads) !== 'undefined') draw_grads = grads;\n\n  // get max and min activation to scale the maps automatically\n  var w = draw_grads ? A.dw : A.w;\n  var mm = maxmin(w);\n\n  var canv = document.createElement('canvas');\n  canv.className = 'actmap';\n  var W = A.sx * s;\n  var H = A.sy * s;\n  canv.width = W;\n  canv.height = H;\n  var ctx = canv.getContext('2d');\n  var g = ctx.createImageData(W, H);\n  for(var d=0;d<3;d++) {\n    for(var x=0;x<A.sx;x++) {\n      for(var y=0;y<A.sy;y++) {\n        if(draw_grads) {\n          var dval = Math.floor((A.get_grad(x,y,d)-mm.minv)/mm.dv*255);\n        } else {\n          var dval = Math.floor((A.get(x,y,d)-mm.minv)/mm.dv*255);  \n        }\n        for(var dx=0;dx<s;dx++) {\n          for(var dy=0;dy<s;dy++) {\n            var pp = ((W * (y*s+dy)) + (dx + x*s)) * 4;\n            g.data[pp + d] = dval;\n            if(d===0) g.data[pp+3] = 255; // alpha channel\n          }\n        }\n      }\n    }\n  }\n  ctx.putImageData(g, 0, 0);\n  elt.appendChild(canv);\n}\n\nvar visualize_activations = function(net, elt) {\n\n  // clear the element\n  elt.innerHTML = \"\";\n\n  // show activations in each layer\n  var N = net.layers.length;\n  for(var i=0;i<N;i++) {\n    var L = net.layers[i];\n\n    var layer_div = document.createElement('div');\n\n    // visualize activations\n    var activations_div = document.createElement('div');\n    activations_div.appendChild(document.createTextNode('Activations:'));\n    activations_div.appendChild(document.createElement('br'));\n    activations_div.className = 'layer_act';\n    var scale = 2;\n    if(L.layer_type==='softmax' || L.layer_type==='fc') scale = 10; // for softmax\n    \n    // HACK to draw in color in input layer\n    if(i===0) {\n      draw_activations_COLOR(activations_div, L.out_act, scale);\n      draw_activations_COLOR(activations_div, L.out_act, scale, true);\n\n      /*\n      // visualize positive and negative components of the gradient separately\n      var dd = L.out_act.clone();\n      var ni = L.out_act.w.length;\n      for(var q=0;q<ni;q++) { var dwq = L.out_act.dw[q]; dd.w[q] = dwq > 0 ? dwq : 0.0; }\n      draw_activations_COLOR(activations_div, dd, scale);\n      for(var q=0;q<ni;q++) { var dwq = L.out_act.dw[q]; dd.w[q] = dwq < 0 ? -dwq : 0.0; }\n      draw_activations_COLOR(activations_div, dd, scale);\n      */\n\n      /*\n      // visualize what the network would like the image to look like more\n      var dd = L.out_act.clone();\n      var ni = L.out_act.w.length;\n      for(var q=0;q<ni;q++) { var dwq = L.out_act.dw[q]; dd.w[q] -= 20*dwq; }\n      draw_activations_COLOR(activations_div, dd, scale);\n      */\n\n      /*\n      // visualize gradient magnitude\n      var dd = L.out_act.clone();\n      var ni = L.out_act.w.length;\n      for(var q=0;q<ni;q++) { var dwq = L.out_act.dw[q]; dd.w[q] = dwq*dwq; }\n      draw_activations_COLOR(activations_div, dd, scale);\n      */\n\n    } else {\n      draw_activations(activations_div, L.out_act, scale);\n    } \n\n    // visualize data gradients\n    if(L.layer_type !== 'softmax' && L.layer_type !== 'input' ) {\n      var grad_div = document.createElement('div');\n      grad_div.appendChild(document.createTextNode('Activation Gradients:'));\n      grad_div.appendChild(document.createElement('br'));\n      grad_div.className = 'layer_grad';\n      var scale = 2;\n      if(L.layer_type==='softmax' || L.layer_type==='fc') scale = 10; // for softmax\n      draw_activations(grad_div, L.out_act, scale, true);\n      activations_div.appendChild(grad_div);\n    }\n\n    // visualize filters if they are of reasonable size\n    if(L.layer_type === 'conv') {\n      var filters_div = document.createElement('div');\n      if(L.filters[0].sx>3) {\n        // actual weights\n        filters_div.appendChild(document.createTextNode('Weights:'));\n        filters_div.appendChild(document.createElement('br'));\n        for(var j=0;j<L.filters.length;j++) {\n          // HACK to draw in color for first layer conv filters\n          if(i===1) {\n            draw_activations_COLOR(filters_div, L.filters[j], 2);\n          } else {\n            filters_div.appendChild(document.createTextNode('('));\n            draw_activations(filters_div, L.filters[j], 2);\n            filters_div.appendChild(document.createTextNode(')'));\n          }\n        }\n        // gradients\n        filters_div.appendChild(document.createElement('br'));\n        filters_div.appendChild(document.createTextNode('Weight Gradients:'));\n        filters_div.appendChild(document.createElement('br'));\n        for(var j=0;j<L.filters.length;j++) {\n          if(i===1) { draw_activations_COLOR(filters_div, L.filters[j], 2, true); }\n          else {\n            filters_div.appendChild(document.createTextNode('('));\n            draw_activations(filters_div, L.filters[j], 2, true);\n            filters_div.appendChild(document.createTextNode(')'));\n          }\n        }\n      } else {\n        filters_div.appendChild(document.createTextNode('Weights hidden, too small'));\n      }\n      activations_div.appendChild(filters_div);\n    }\n    layer_div.appendChild(activations_div);\n\n    // print some stats on left of the layer\n    layer_div.className = 'layer ' + 'lt' + L.layer_type;\n    var title_div = document.createElement('div');\n    title_div.className = 'ltitle'\n    var t = L.layer_type + ' (' + L.out_sx + 'x' + L.out_sy + 'x' + L.out_depth + ')';\n    title_div.appendChild(document.createTextNode(t));\n    layer_div.appendChild(title_div);\n\n    if(L.layer_type==='conv') {\n      var t = 'filter size ' + L.filters[0].sx + 'x' + L.filters[0].sy + 'x' + L.filters[0].depth + ', stride ' + L.stride;\n      layer_div.appendChild(document.createTextNode(t));\n      layer_div.appendChild(document.createElement('br'));\n    }\n    if(L.layer_type==='pool') {\n      var t = 'pooling size ' + L.sx + 'x' + L.sy + ', stride ' + L.stride;\n      layer_div.appendChild(document.createTextNode(t));\n      layer_div.appendChild(document.createElement('br'));\n    }\n\n    // find min, max activations and display them\n    var mma = maxmin(L.out_act.w);\n    var t = 'max activation: ' + f2t(mma.maxv) + ', min: ' + f2t(mma.minv);\n    layer_div.appendChild(document.createTextNode(t));\n    layer_div.appendChild(document.createElement('br'));\n\n    var mma = maxmin(L.out_act.dw);\n    var t = 'max gradient: ' + f2t(mma.maxv) + ', min: ' + f2t(mma.minv);\n    layer_div.appendChild(document.createTextNode(t));\n    layer_div.appendChild(document.createElement('br'));\n\n    // number of parameters\n    if(L.layer_type==='conv' || L.layer_type==='local') {\n      var tot_params = L.sx*L.sy*L.in_depth*L.filters.length + L.filters.length;\n      var t = 'parameters: ' + L.filters.length + 'x' + L.sx + 'x' + L.sy + 'x' + L.in_depth + '+' + L.filters.length + ' = ' + tot_params;\n      layer_div.appendChild(document.createTextNode(t));\n      layer_div.appendChild(document.createElement('br'));\n    }\n    if(L.layer_type==='fc') {\n      var tot_params = L.num_inputs*L.filters.length + L.filters.length;\n      var t = 'parameters: ' + L.filters.length + 'x' + L.num_inputs + '+' + L.filters.length + ' = ' + tot_params;\n      layer_div.appendChild(document.createTextNode(t));\n      layer_div.appendChild(document.createElement('br'));\n    }\n\n    // css madness needed here...\n    var clear = document.createElement('div');\n    clear.className = 'clear';\n    layer_div.appendChild(clear);\n\n    elt.appendChild(layer_div);\n  }\n}\n\n// loads a training image and trains on it with the network\nvar paused = false;\nvar load_and_step = function() {\n  if(paused) return; \n\n  var sample = sample_training_instance();\n  step(sample); // process this image\n  \n  //setTimeout(load_and_step, 0); // schedule the next iteration\n}\n\n// evaluate current network on test set\nvar test_predict = function() {\n  var num_classes = net.layers[net.layers.length-1].out_depth;\n\n  document.getElementById('testset_acc').innerHTML = '';\n  var num_total = 0;\n  var num_correct = 0;\n\n  // grab a random test image\n  for(num=0;num<4;num++) {\n    var sample = sample_test_instance();\n    var y = sample.label;  // ground truth label\n\n    // forward prop it through the network\n    var aavg = new convnetjs.Vol(1,1,num_classes,0.0);\n    // ensures we always have a list, regardless if above returns single item or list\n    var xs = [].concat(sample.x);\n    var n = xs.length;\n    for(var i=0;i<n;i++) {\n      var a = net.forward(xs[i]);\n      aavg.addFrom(a);\n    }\n    var preds = [];\n    for(var k=0;k<aavg.w.length;k++) { preds.push({k:k,p:aavg.w[k]}); }\n    preds.sort(function(a,b){return a.p<b.p ? 1:-1;});\n    \n    var correct = preds[0].k===y;\n    if(correct) num_correct++;\n    num_total++;\n\n    var div = document.createElement('div');\n    div.className = 'testdiv';\n\n    // draw the image into a canvas\n    draw_activations_COLOR(div, xs[0], 2); // draw Vol into canv\n\n    // add predictions\n    var probsdiv = document.createElement('div');\n    \n    var t = '';\n    for(var k=0;k<3;k++) {\n      var col = preds[k].k===y ? 'rgb(85,187,85)' : 'rgb(187,85,85)';\n      t += '<div class=\\\"pp\\\" style=\\\"width:' + Math.floor(preds[k].p/n*100) + 'px; background-color:' + col + ';\\\">' + classes_txt[preds[k].k] + '</div>'\n    }\n    probsdiv.innerHTML = t;\n    probsdiv.className = 'probsdiv';\n    div.appendChild(probsdiv);\n\n    // add it into DOM\n    $(div).prependTo($(\"#testset_vis\")).hide().fadeIn('slow').slideDown('slow');\n    if($(\".probsdiv\").length>200) {\n      $(\"#testset_vis > .probsdiv\").last().remove(); // pop to keep upper bound of shown items\n    }\n  }\n  testAccWindow.add(num_correct/num_total);\n  $(\"#testset_acc\").text('test accuracy based on last 200 test images: ' + testAccWindow.get_average());  \n}\nvar testImage = function(img) {\n  var x = convnetjs.img_to_vol(img);\n  var out_p = net.forward(x);\n\n\n  var vis_elt = document.getElementById(\"visnet\");\n  visualize_activations(net, vis_elt);\n\n  var preds =[]\n  for(var k=0;k<out_p.w.length;k++) { preds.push({k:k,p:out_p.w[k]}); }\n  preds.sort(function(a,b){return a.p<b.p ? 1:-1;});\n\n  // add predictions\n  var div = document.createElement('div');\n  div.className = 'testdiv';\n\n  // draw the image into a canvas\n  draw_activations_COLOR(div, x, 2);\n\n  var probsdiv = document.createElement('div');\n\n\n  var t = '';\n  for(var k=0;k<3;k++) {\n    var col = k===0 ? 'rgb(85,187,85)' : 'rgb(187,85,85)';\n    t += '<div class=\\\"pp\\\" style=\\\"width:' + Math.floor(preds[k].p/1*100) + 'px; background-color:' + col + ';\\\">' + classes_txt[preds[k].k] + '</div>'\n  }\n  \n  probsdiv.innerHTML = t;\n  probsdiv.className = 'probsdiv';\n  div.appendChild(probsdiv);\n\n  // add it into DOM\n  $(div).prependTo($(\"#testset_vis\")).hide().fadeIn('slow').slideDown('slow');\n  if($(\".probsdiv\").length>200) {\n    $(\"#testset_vis > .probsdiv\").last().remove(); // pop to keep upper bound of shown items\n  }\n}\n\nvar lossGraph = new cnnvis.Graph();\nvar xLossWindow = new cnnutil.Window(100);\nvar wLossWindow = new cnnutil.Window(100);\nvar trainAccWindow = new cnnutil.Window(100);\nvar valAccWindow = new cnnutil.Window(100);\nvar testAccWindow = new cnnutil.Window(50, 1);\nvar step_num = 0;\nvar step = function(sample) {\n\n  var x = sample.x;\n  var y = sample.label;\n\n  if(sample.isval) {\n    // use x to build our estimate of validation error\n    net.forward(x);\n    var yhat = net.getPrediction();\n    var val_acc = yhat === y ? 1.0 : 0.0;\n    valAccWindow.add(val_acc);\n    return; // get out\n  }\n\n  // train on it with network\n  var stats = trainer.train(x, y);\n  var lossx = stats.cost_loss;\n  var lossw = stats.l2_decay_loss;\n\n  // keep track of stats such as the average training error and loss\n  var yhat = net.getPrediction();\n  var train_acc = yhat === y ? 1.0 : 0.0;\n  xLossWindow.add(lossx);\n  wLossWindow.add(lossw);\n  trainAccWindow.add(train_acc);\n\n  // visualize training status\n  var train_elt = document.getElementById(\"trainstats\");\n  train_elt.innerHTML = '';\n  var t = 'Forward time per example: ' + stats.fwd_time + 'ms';\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'Backprop time per example: ' + stats.bwd_time + 'ms';\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'Classification loss: ' + f2t(xLossWindow.get_average());\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'L2 Weight decay loss: ' + f2t(wLossWindow.get_average());\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'Training accuracy: ' + f2t(trainAccWindow.get_average());\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'Validation accuracy: ' + f2t(valAccWindow.get_average());\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n  var t = 'Examples seen: ' + step_num;\n  train_elt.appendChild(document.createTextNode(t));\n  train_elt.appendChild(document.createElement('br'));\n\n  // visualize activations\n  if(step_num % 100 === 0) {\n    var vis_elt = document.getElementById(\"visnet\");\n    visualize_activations(net, vis_elt);\n  }\n\n  // log progress to graph, (full loss)\n  if(step_num % 200 === 0) {\n    var xa = xLossWindow.get_average();\n    var xw = wLossWindow.get_average();\n    if(xa >= 0 && xw >= 0) { // if they are -1 it means not enough data was accumulated yet for estimates\n      lossGraph.add(step_num, xa + xw);\n      lossGraph.drawSelf(document.getElementById(\"lossgraph\"));\n    }\n  }\n\n  // run prediction on test set\n  if((step_num % 100 === 0 && step_num > 0) || step_num===100) {\n    test_predict();\n  }\n  step_num++;\n}\n\n// user settings \nvar change_lr = function() {\n  trainer.learning_rate = parseFloat(document.getElementById(\"lr_input\").value);\n  update_net_param_display();\n}\nvar change_momentum = function() {\n  trainer.momentum = parseFloat(document.getElementById(\"momentum_input\").value);\n  update_net_param_display();\n}\nvar change_batch_size = function() {\n  trainer.batch_size = parseFloat(document.getElementById(\"batch_size_input\").value);\n  update_net_param_display();\n}\nvar change_decay = function() {\n  trainer.l2_decay = parseFloat(document.getElementById(\"decay_input\").value);\n  update_net_param_display();\n}\nvar update_net_param_display = function() {\n  document.getElementById('lr_input').value = trainer.learning_rate;\n  document.getElementById('momentum_input').value = trainer.momentum;\n  document.getElementById('batch_size_input').value = trainer.batch_size;\n  document.getElementById('decay_input').value = trainer.l2_decay;\n}\nvar toggle_pause = function() {\n  paused = !paused;\n  var btn = document.getElementById('buttontp');\n  if(paused) { btn.value = 'resume' }\n  else { btn.value = 'pause'; }\n}\nvar dump_json = function() {\n  document.getElementById(\"dumpjson\").value = JSON.stringify(this.net.toJSON());\n}\nvar clear_graph = function() {\n  lossGraph = new cnnvis.Graph(); // reinit graph too \n}\nvar reset_all = function() {\n  // reinit trainer\n  trainer = new convnetjs.SGDTrainer(net, {learning_rate:trainer.learning_rate, momentum:trainer.momentum, batch_size:trainer.batch_size, l2_decay:trainer.l2_decay});\n  update_net_param_display();\n\n  // reinit windows that keep track of val/train accuracies\n  xLossWindow.reset();\n  wLossWindow.reset();\n  trainAccWindow.reset();\n  valAccWindow.reset();\n  testAccWindow.reset();\n  lossGraph = new cnnvis.Graph(); // reinit graph too\n  step_num = 0;\n}\nvar load_from_json = function() {\n  var jsonString = document.getElementById(\"dumpjson\").value;\n  var json = JSON.parse(jsonString);\n  net = new convnetjs.Net();\n  net.fromJSON(json);\n  reset_all();\n}\n\nvar load_pretrained = function() {\n  $.getJSON(dataset_name + \"_snapshot.json\", function(json){\n    net = new convnetjs.Net();\n    net.fromJSON(json);\n    trainer.learning_rate = 0.0001;\n    trainer.momentum = 0.9;\n    trainer.batch_size = 2;\n    trainer.l2_decay = 0.00001;\n    reset_all();\n  });\n}\n\nvar change_net = function() {\n  eval($(\"#newnet\").val());\n  reset_all();\n}\n"
  },
  {
    "path": "demo/js/npgmain.js",
    "content": "//Simple game engine\n//Author: Andrej Karpathy\n//License: BSD\n//This function does all the boring canvas stuff. To use it, just create functions:\n//update()          gets called every frame\n//draw()            gets called every frame\n//myinit()          gets called once in beginning\n//mouseClick(x, y)  gets called on mouse click\n//keyUp(keycode)    gets called when key is released\n//keyDown(keycode)  gets called when key is pushed\n\nvar canvas;\nvar ctx;\nvar WIDTH;\nvar HEIGHT; \nvar FPS;\n\nfunction drawBubble(x, y, w, h, radius)\n{\n  var r = x + w;\n  var b = y + h;\n  ctx.beginPath();\n  ctx.strokeStyle=\"black\";\n  ctx.lineWidth=\"2\";\n  ctx.moveTo(x+radius, y);\n  ctx.lineTo(x+radius/2, y-10);\n  ctx.lineTo(x+radius * 2, y);\n  ctx.lineTo(r-radius, y);\n  ctx.quadraticCurveTo(r, y, r, y+radius);\n  ctx.lineTo(r, y+h-radius);\n  ctx.quadraticCurveTo(r, b, r-radius, b);\n  ctx.lineTo(x+radius, b);\n  ctx.quadraticCurveTo(x, b, x, b-radius);\n  ctx.lineTo(x, y+radius);\n  ctx.quadraticCurveTo(x, y, x+radius, y);\n  ctx.stroke();\n}\n\nfunction drawRect(x, y, w, h){\n  ctx.beginPath();\n  ctx.rect(x,y,w,h);\n  ctx.closePath();\n  ctx.fill();\n  ctx.stroke();\n}\n\nfunction drawCircle(x, y, r){\n  ctx.beginPath();\n  ctx.arc(x, y, r, 0, Math.PI*2, true); \n  ctx.closePath();\n  ctx.stroke();\n  ctx.fill();\n}\n\n//uniform distribution integer\nfunction randi(s, e) {\n  return Math.floor(Math.random()*(e-s) + s);\n}\n\n//uniform distribution\nfunction randf(s, e) {\n  return Math.random()*(e-s) + s;\n}\n\n//normal distribution random number\nfunction randn(mean, variance) {\n  var V1, V2, S;\n  do {\n    var U1 = Math.random();\n    var U2 = Math.random();\n    V1 = 2 * U1 - 1;\n    V2 = 2 * U2 - 1;\n    S = V1 * V1 + V2 * V2;\n  } while (S > 1);\n  X = Math.sqrt(-2 * Math.log(S) / S) * V1;\n  X = mean + Math.sqrt(variance) * X;\n  return X;\n}\n\nfunction eventClick(e) {\n    \n  //get position of cursor relative to top left of canvas\n  var x;\n  var y;\n  if (e.pageX || e.pageY) { \n    x = e.pageX;\n    y = e.pageY;\n  } else { \n    x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; \n    y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; \n  } \n  x -= canvas.offsetLeft;\n  y -= canvas.offsetTop;\n  \n  //call user-defined callback\n  mouseClick(x, y, e.shiftKey, e.ctrlKey);\n}\n\n//event codes can be found here:\n//http://www.aspdotnetfaq.com/Faq/What-is-the-list-of-KeyCodes-for-JavaScript-KeyDown-KeyPress-and-KeyUp-events.aspx\nfunction eventKeyUp(e) {\n  var keycode = ('which' in e) ? e.which : e.keyCode;\n  keyUp(keycode);\n}\n\nfunction eventKeyDown(e) {\n  var keycode = ('which' in e) ? e.which : e.keyCode;\n  keyDown(keycode);\n}\n\nfunction NPGinit(FPS){\n  //takes frames per secont to run at\n  \n  canvas = document.getElementById('NPGcanvas');\n  ctx = canvas.getContext('2d');\n  WIDTH = canvas.width;\n  HEIGHT = canvas.height;\n  canvas.addEventListener('click', eventClick, false);\n  \n  //canvas element cannot get focus by default. Requires to either set \n  //tabindex to 1 so that it's focusable, or we need to attach listeners\n  //to the document. Here we do the latter\n  document.addEventListener('keyup', eventKeyUp, true);\n  document.addEventListener('keydown', eventKeyDown, true);\n  \n  setInterval(NPGtick, 1000/FPS);\n  \n  myinit();\n}\n\nfunction NPGtick() {\n    update();\n    draw();\n}\n"
  },
  {
    "path": "demo/js/pica.js",
    "content": "/* pica 1.0.7 nodeca/pica */!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.pica=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({\"./\":[function(require,module,exports){\n'use strict';\n\n/*global window:true*/\n/*eslint space-infix-ops:0*/\n\n// Feature detect\nvar WORKER = (typeof window !== 'undefined') && ('Worker' in window);\nif (WORKER) {\n  // IE don't allow to create webworkers from string. We should check it.\n  // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11\n  try {\n    var wkr = require('webworkify')(function () {});\n    wkr.terminate();\n  } catch (__) {\n    WORKER = false;\n  }\n}\n\nvar resize       = require('./lib/resize');\nvar resizeWorker = require('./lib/resize_worker');\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Helpers\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\nfunction isFunction(obj) { return _class(obj) === '[object Function]'; }\n\n\n////////////////////////////////////////////////////////////////////////////////\n// API methods\n\n\n// RGBA buffer async resize\n//\nfunction resizeBuffer(options, callback) {\n  var wr;\n\n  var _opts = {\n    src:      options.src,\n    dest:     null,\n    width:    options.width|0,\n    height:   options.height|0,\n    toWidth:  options.toWidth|0,\n    toHeight: options.toHeight|0,\n    quality:  options.quality,\n    alpha:    options.alpha,\n    unsharpAmount:    options.unsharpAmount,\n    unsharpThreshold: options.unsharpThreshold\n  };\n\n  if (WORKER && exports.WW) {\n    wr = require('webworkify')(resizeWorker);\n\n    wr.onmessage = function(ev) {\n      var i, l,\n          dest = options.dest,\n          output = ev.data.output;\n\n      // If we got output buffer by reference, we should copy data,\n      // because WW returns independent instance\n      if (dest) {\n        // IE ImageData can return old-style CanvasPixelArray\n        // without .set() method. Copy manually for such case.\n        if (dest.set) {\n          dest.set(output);\n        } else {\n          for (i = 0, l = output.length; i < l; i++) {\n            dest[i] = output[i];\n          }\n        }\n      }\n      callback(ev.data.err, output);\n      wr.terminate();\n    };\n\n    if (options.transferable) {\n      wr.postMessage(_opts, [ options.src.buffer ]);\n    } else {\n      wr.postMessage(_opts);\n    }\n    // Expose worker when available, to allow early termination.\n    return wr;\n  }\n\n  // Fallback to sync call, if WebWorkers not available\n  _opts.dest = options.dest;\n  resize(_opts, callback);\n  return undefined;\n}\n\n\n// Canvas async resize\n//\nfunction resizeCanvas(from, to, options, callback) {\n  var w = from.width,\n      h = from.height,\n      w2 = to.width,\n      h2 = to.height;\n\n  if (isFunction(options)) {\n    callback = options;\n    options = {};\n  }\n\n  if (!isNaN(options)) {\n    options = { quality: options, alpha: false };\n  }\n\n  var ctxTo = to.getContext('2d');\n  var imageDataTo = ctxTo.getImageData(0, 0, w2, h2);\n\n  var _opts = {\n    src:      from.getContext('2d').getImageData(0, 0, w, h).data,\n    dest:     imageDataTo.data,\n    width:    from.width,\n    height:   from.height,\n    toWidth:  to.width,\n    toHeight: to.height,\n    quality:  options.quality,\n    alpha:    options.alpha,\n    unsharpAmount:    options.unsharpAmount,\n    unsharpThreshold: options.unsharpThreshold,\n    transferable: true\n  };\n\n  return resizeBuffer(_opts, function (err/*, output*/) {\n    if (err) {\n      callback(err);\n      return;\n    }\n\n    ctxTo.putImageData(imageDataTo, 0, 0);\n    callback();\n  });\n}\n\n\nexports.resizeBuffer = resizeBuffer;\nexports.resizeCanvas = resizeCanvas;\nexports.WW = WORKER;\n\n},{\"./lib/resize\":4,\"./lib/resize_worker\":5,\"webworkify\":6}],1:[function(require,module,exports){\n// Blur filter\n//\n\n'use strict';\n\n\nvar _blurKernel = new Uint8Array([\n  1, 2, 1,\n  2, 4, 2,\n  1, 2, 1\n]);\n\nvar _bkWidth = Math.floor(Math.sqrt(_blurKernel.length));\nvar _bkHalf = Math.floor(_bkWidth / 2);\nvar _bkWsum = 0;\nfor (var wc=0; wc < _blurKernel.length; wc++) { _bkWsum += _blurKernel[wc]; }\n\n\nfunction blurPoint(gs, x, y, srcW, srcH) {\n  var bx, by, sx, sy, w, wsum, br;\n  var bPtr = 0;\n  var blurKernel = _blurKernel;\n  var bkHalf = _bkHalf;\n\n  wsum = 0; // weight sum to normalize result\n  br   = 0;\n\n  if (x >= bkHalf && y >= bkHalf && x + bkHalf < srcW && y + bkHalf < srcH) {\n    for (by = 0; by < 3; by++) {\n      for (bx = 0; bx < 3; bx++) {\n        sx = x + bx - bkHalf;\n        sy = y + by - bkHalf;\n\n        br += gs[sx + sy * srcW] * blurKernel[bPtr++];\n      }\n    }\n    return (br - (br % _bkWsum)) / _bkWsum;\n  }\n\n  for (by = 0; by < 3; by++) {\n    for (bx = 0; bx < 3; bx++) {\n      sx = x + bx - bkHalf;\n      sy = y + by - bkHalf;\n\n      if (sx >= 0 && sx < srcW && sy >= 0 && sy < srcH) {\n        w = blurKernel[bPtr];\n        wsum += w;\n        br += gs[sx + sy * srcW] * w;\n      }\n      bPtr++;\n    }\n  }\n  return ((br - (br % wsum)) / wsum)|0;\n}\n\nfunction blur(src, srcW, srcH/*, radius*/) {\n  var x, y,\n      output = new Uint16Array(src.length);\n\n  for (x = 0; x < srcW; x++) {\n    for (y = 0; y < srcH; y++) {\n      output[y * srcW + x] = blurPoint(src, x, y, srcW, srcH);\n    }\n  }\n\n  return output;\n}\n\nmodule.exports = blur;\n\n},{}],2:[function(require,module,exports){\n// High speed resize with tuneable speed/quality ratio\n\n'use strict';\n\n\nvar unsharp = require('./unsharp');\n\n\n// Precision of fixed FP values\nvar FIXED_FRAC_BITS = 14;\nvar FIXED_FRAC_VAL  = 1 << FIXED_FRAC_BITS;\n\n\n//\n// Presets for quality 0..3. Filter functions + window size\n//\nvar FILTER_INFO = [\n  { // Nearest neibor (Box)\n    win: 0.5,\n    filter: function (x) {\n      return (x >= -0.5 && x < 0.5) ? 1.0 : 0.0;\n    }\n  },\n  { // Hamming\n    win: 1.0,\n    filter: function (x) {\n      if (x <= -1.0 || x >= 1.0) { return 0.0; }\n      if (x > -1.19209290E-07 && x < 1.19209290E-07) { return 1.0; }\n      var xpi = x * Math.PI;\n      return ((Math.sin(xpi) / xpi) *  (0.54 + 0.46 * Math.cos(xpi / 1.0)));\n    }\n  },\n  { // Lanczos, win = 2\n    win: 2.0,\n    filter: function (x) {\n      if (x <= -2.0 || x >= 2.0) { return 0.0; }\n      if (x > -1.19209290E-07 && x < 1.19209290E-07) { return 1.0; }\n      var xpi = x * Math.PI;\n      return (Math.sin(xpi) / xpi) * Math.sin(xpi / 2.0) / (xpi / 2.0);\n    }\n  },\n  { // Lanczos, win = 3\n    win: 3.0,\n    filter: function (x) {\n      if (x <= -3.0 || x >= 3.0) { return 0.0; }\n      if (x > -1.19209290E-07 && x < 1.19209290E-07) { return 1.0; }\n      var xpi = x * Math.PI;\n      return (Math.sin(xpi) / xpi) * Math.sin(xpi / 3.0) / (xpi / 3.0);\n    }\n  }\n];\n\nfunction clampTo8(i) { return i < 0 ? 0 : (i > 255 ? 255 : i); }\n\nfunction toFixedPoint(num) { return Math.floor(num * FIXED_FRAC_VAL); }\n\n\n// Calculate convolution filters for each destination point,\n// and pack data to Int16Array:\n//\n// [ shift, length, data..., shift2, length2, data..., ... ]\n//\n// - shift - offset in src image\n// - length - filter length (in src points)\n// - data - filter values sequence\n//\nfunction createFilters(quality, srcSize, destSize) {\n\n  var filterFunction = FILTER_INFO[quality].filter;\n\n  var scale         = destSize / srcSize;\n  var scaleInverted = 1.0 / scale;\n  var scaleClamped  = Math.min(1.0, scale); // For upscale\n\n  // Filter window (averaging interval), scaled to src image\n  var srcWindow = FILTER_INFO[quality].win / scaleClamped;\n\n  var destPixel, srcPixel, srcFirst, srcLast, filterElementSize,\n      floatFilter, fxpFilter, total, fixedTotal, pxl, idx, floatVal, fixedVal;\n  var leftNotEmpty, rightNotEmpty, filterShift, filterSize;\n\n  var maxFilterElementSize = Math.floor((srcWindow + 1) * 2 );\n  var packedFilter    = new Int16Array((maxFilterElementSize + 2) * destSize);\n  var packedFilterPtr = 0;\n\n  // For each destination pixel calculate source range and built filter values\n  for (destPixel = 0; destPixel < destSize; destPixel++) {\n\n    // Scaling should be done relative to central pixel point\n    srcPixel = (destPixel + 0.5) * scaleInverted;\n\n    srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));\n    srcLast  = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));\n\n    filterElementSize = srcLast - srcFirst + 1;\n    floatFilter = new Float32Array(filterElementSize);\n    fxpFilter = new Int16Array(filterElementSize);\n\n    total = 0.0;\n\n    // Fill filter values for calculated range\n    for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n      floatVal = filterFunction(((pxl + 0.5) - srcPixel) * scaleClamped);\n      total += floatVal;\n      floatFilter[idx] = floatVal;\n    }\n\n    // Normalize filter, convert to fixed point and accumulate conversion error\n    fixedTotal = 0;\n\n    for (idx = 0; idx < floatFilter.length; idx++) {\n      fixedVal = toFixedPoint(floatFilter[idx] / total);\n      fixedTotal += fixedVal;\n      fxpFilter[idx] = fixedVal;\n    }\n\n    // Compensate normalization error, to minimize brightness drift\n    fxpFilter[destSize >> 1] += toFixedPoint(1.0) - fixedTotal;\n\n    //\n    // Now pack filter to useable form\n    //\n    // 1. Trim heading and tailing zero values, and compensate shitf/length\n    // 2. Put all to single array in this format:\n    //\n    //    [ pos shift, data length, value1, value2, value3, ... ]\n    //\n\n    leftNotEmpty = 0;\n    while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n      leftNotEmpty++;\n    }\n\n    if (leftNotEmpty < fxpFilter.length) {\n      rightNotEmpty = fxpFilter.length - 1;\n      while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n        rightNotEmpty--;\n      }\n\n      filterShift = srcFirst + leftNotEmpty;\n      filterSize = rightNotEmpty - leftNotEmpty + 1;\n\n      packedFilter[packedFilterPtr++] = filterShift; // shift\n      packedFilter[packedFilterPtr++] = filterSize; // size\n\n      packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);\n      packedFilterPtr += filterSize;\n    } else {\n      // zero data, write header only\n      packedFilter[packedFilterPtr++] = 0; // shift\n      packedFilter[packedFilterPtr++] = 0; // size\n    }\n  }\n  return packedFilter;\n}\n\n// Convolve image in horizontal directions and transpose output. In theory,\n// transpose allow:\n//\n// - use the same convolver for both passes (this fails due different\n//   types of input array and temporary buffer)\n// - making vertical pass by horisonltal lines inprove CPU cache use.\n//\n// But in real life this doesn't work :)\n//\nfunction convolveHorizontally(src, dest, srcW, srcH, destW, filters) {\n\n  var r, g, b, a;\n  var filterPtr, filterShift, filterSize;\n  var srcPtr, srcY, destX, filterVal;\n  var srcOffset = 0, destOffset = 0;\n\n  // For each row\n  for (srcY = 0; srcY < srcH; srcY++) {\n    filterPtr  = 0;\n\n    // Apply precomputed filters to each destination row point\n    for (destX = 0; destX < destW; destX++) {\n      // Get the filter that determines the current output pixel.\n      filterShift = filters[filterPtr++];\n      filterSize  = filters[filterPtr++];\n\n      srcPtr = (srcOffset + (filterShift * 4))|0;\n\n      r = g = b = a = 0;\n\n      // Apply the filter to the row to get the destination pixel r, g, b, a\n      for (; filterSize > 0; filterSize--) {\n        filterVal = filters[filterPtr++];\n\n        // Use reverse order to workaround deopts in old v8 (node v.10)\n        // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n        a = (a + filterVal * src[srcPtr + 3])|0;\n        b = (b + filterVal * src[srcPtr + 2])|0;\n        g = (g + filterVal * src[srcPtr + 1])|0;\n        r = (r + filterVal * src[srcPtr])|0;\n        srcPtr = (srcPtr + 4)|0;\n      }\n\n      // Bring this value back in range. All of the filter scaling factors\n      // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n      dest[destOffset + 3] = clampTo8(a >> 14/*FIXED_FRAC_BITS*/);\n      dest[destOffset + 2] = clampTo8(b >> 14/*FIXED_FRAC_BITS*/);\n      dest[destOffset + 1] = clampTo8(g >> 14/*FIXED_FRAC_BITS*/);\n      dest[destOffset]     = clampTo8(r >> 14/*FIXED_FRAC_BITS*/);\n      destOffset = (destOffset + srcH * 4)|0;\n    }\n\n    destOffset = ((srcY + 1) * 4)|0;\n    srcOffset  = ((srcY + 1) * srcW * 4)|0;\n  }\n}\n\n// Technically, convolvers are the same. But input array and temporary\n// buffer can be of different type (especially, in old browsers). So,\n// keep code in separate functions to avoid deoptimizations & speed loss.\n\nfunction convolveVertically(src, dest, srcW, srcH, destW, filters) {\n\n  var r, g, b, a;\n  var filterPtr, filterShift, filterSize;\n  var srcPtr, srcY, destX, filterVal;\n  var srcOffset = 0, destOffset = 0;\n\n  // For each row\n  for (srcY = 0; srcY < srcH; srcY++) {\n    filterPtr  = 0;\n\n    // Apply precomputed filters to each destination row point\n    for (destX = 0; destX < destW; destX++) {\n      // Get the filter that determines the current output pixel.\n      filterShift = filters[filterPtr++];\n      filterSize  = filters[filterPtr++];\n\n      srcPtr = (srcOffset + (filterShift * 4))|0;\n\n      r = g = b = a = 0;\n\n      // Apply the filter to the row to get the destination pixel r, g, b, a\n      for (; filterSize > 0; filterSize--) {\n        filterVal = filters[filterPtr++];\n\n        // Use reverse order to workaround deopts in old v8 (node v.10)\n        // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n        a = (a + filterVal * src[srcPtr + 3])|0;\n        b = (b + filterVal * src[srcPtr + 2])|0;\n        g = (g + filterVal * src[srcPtr + 1])|0;\n        r = (r + filterVal * src[srcPtr])|0;\n        srcPtr = (srcPtr + 4)|0;\n      }\n\n      // Bring this value back in range. All of the filter scaling factors\n      // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n      dest[destOffset + 3] = clampTo8(a >> 14/*FIXED_FRAC_BITS*/);\n      dest[destOffset + 2] = clampTo8(b >> 14/*FIXED_FRAC_BITS*/);\n      dest[destOffset + 1] = clampTo8(g >> 14/*FIXED_FRAC_BITS*/);\n      dest[destOffset]     = clampTo8(r >> 14/*FIXED_FRAC_BITS*/);\n      destOffset = (destOffset + srcH * 4)|0;\n    }\n\n    destOffset = ((srcY + 1) * 4)|0;\n    srcOffset  = ((srcY + 1) * srcW * 4)|0;\n  }\n}\n\n\nfunction resetAlpha(dst, width, height) {\n  var ptr = 3, len = (width * height * 4)|0;\n  while (ptr < len) { dst[ptr] = 0xFF; ptr = (ptr + 4)|0; }\n}\n\n\nfunction resize(options) {\n  var src   = options.src;\n  var srcW  = options.width;\n  var srcH  = options.height;\n  var destW = options.toWidth;\n  var destH = options.toHeight;\n  var dest  = options.dest || new Uint8Array(destW * destH * 4);\n  var quality = options.quality === undefined ? 3 : options.quality;\n  var alpha = options.alpha || false;\n  var unsharpAmount = options.unsharpAmount === undefined ? 0 : (options.unsharpAmount|0);\n  var unsharpThreshold = options.unsharpThreshold === undefined ? 0 : (options.unsharpThreshold|0);\n\n  if (srcW < 1 || srcH < 1 || destW < 1 || destH < 1) { return []; }\n\n  var filtersX = createFilters(quality, srcW, destW),\n      filtersY = createFilters(quality, srcH, destH);\n\n  var tmp  = new Uint8Array(destW * srcH * 4);\n\n  // To use single function we need src & tmp of the same type.\n  // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep\n  // vertical and horizontal passes separately to avoid deoptimization.\n\n  convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);\n  convolveVertically(tmp, dest, srcH, destW, destH, filtersY);\n\n  // That's faster than doing checks in convolver.\n  // !!! Note, canvas data is not premultipled. We don't need other\n  // alpha corrections.\n\n  if (!alpha) {\n    resetAlpha(dest, destW, destH);\n  }\n\n  if (unsharpAmount) {\n    unsharp(dest, destW, destH, unsharpAmount, 1.0, unsharpThreshold);\n  }\n\n  return dest;\n}\n\n\nmodule.exports = resize;\n\n},{\"./unsharp\":3}],3:[function(require,module,exports){\n// Unsharp mask filter\n//\n// http://stackoverflow.com/a/23322820/1031804\n// USM(O) = O + (2 * (Amount / 100) * (O - GB))\n// GB - gaussial blur.\n//\n// brightness = 0.299*R + 0.587*G + 0.114*B\n// http://stackoverflow.com/a/596243/1031804\n//\n// To simplify math, normalize brighness mutipliers to 2^16:\n//\n// brightness = (19595*R + 38470*G + 7471*B) / 65536\n\n'use strict';\n\n\nvar blur = require('./blur');\n\n\nfunction clampTo8(i) { return i < 0 ? 0 : (i > 255 ? 255 : i); }\n\n// Convert image to greyscale, 16bits FP result (8.8)\n//\nfunction greyscale(src, srcW, srcH) {\n  var size = srcW * srcH;\n  var result = new Uint16Array(size); // We don't use sign, but that helps to JIT\n  var i, srcPtr;\n\n  for (i = 0, srcPtr = 0; i < size; i++) {\n    result[i] = (src[srcPtr + 2] * 7471       // blue\n               + src[srcPtr + 1] * 38470      // green\n               + src[srcPtr] * 19595) >>> 8;  // red\n    srcPtr = (srcPtr + 4)|0;\n  }\n\n  return result;\n}\n\n\n// Apply unsharp mask to src\n//\n// NOTE: radius is ignored to simplify gaussian blur calculation\n// on practice we need radius 0.3..2.0. Use 1.0 now.\n//\nfunction unsharp(src, srcW, srcH, amount, radius, threshold) {\n  var x, y, c, diff = 0, corr, srcPtr;\n\n  // Normalized delta multiplier. Expect that:\n  var AMOUNT_NORM = Math.floor(amount * 256 / 50);\n\n  // Convert to grayscale:\n  //\n  // - prevent color drift\n  // - speedup blur calc\n  //\n  var gs = greyscale(src, srcW, srcH);\n  var blured = blur(gs, srcW, srcH, 1);\n  var fpThreshold = threshold << 8;\n  var gsPtr = 0;\n\n  for (y = 0; y < srcH; y++) {\n    for (x = 0; x < srcW; x++) {\n\n      // calculate brightness blur, difference & update source buffer\n\n      diff = gs[gsPtr] - blured[gsPtr];\n\n      // Update source image if thresold exceeded\n      if (Math.abs(diff) > fpThreshold) {\n        // Calculate correction multiplier\n        corr = 65536 + ((diff * AMOUNT_NORM) >> 8);\n        srcPtr = gsPtr * 4;\n\n        c = src[srcPtr];\n        src[srcPtr++] = clampTo8((c * corr) >> 16);\n        c = src[srcPtr];\n        src[srcPtr++] = clampTo8((c * corr) >> 16);\n        c = src[srcPtr];\n        src[srcPtr] = clampTo8((c * corr) >> 16);\n      }\n\n      gsPtr++;\n\n    } // end row\n  } // end column\n}\n\n\nmodule.exports = unsharp;\n\n},{\"./blur\":1}],4:[function(require,module,exports){\n// Proxy to simplify split between webworker/plain calls\n'use strict';\n\nvar resize = require('./pure/resize');\n\nmodule.exports = function (options, callback) {\n  var output = resize(options);\n\n  callback(null, output);\n};\n\n},{\"./pure/resize\":2}],5:[function(require,module,exports){\n// Web Worker wrapper for image resize function\n\n'use strict';\n\nmodule.exports = function(self) {\n  var resize = require('./resize');\n\n  self.onmessage = function (ev) {\n    resize(ev.data, function(err, output) {\n      if (err) {\n        self.postMessage({ err: err });\n        return;\n      }\n\n      self.postMessage({ output: output }, [ output.buffer ]);\n    });\n  };\n};\n\n},{\"./resize\":4}],6:[function(require,module,exports){\nvar bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn) {\n    var keys = [];\n    var wkey;\n    var cacheKeys = Object.keys(cache);\n    \n    for (var i = 0, l = cacheKeys.length; i < l; i++) {\n        var key = cacheKeys[i];\n        if (cache[key].exports === fn) {\n            wkey = key;\n            break;\n        }\n    }\n    \n    if (!wkey) {\n        wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n        var wcache = {};\n        for (var i = 0, l = cacheKeys.length; i < l; i++) {\n            var key = cacheKeys[i];\n            wcache[key] = key;\n        }\n        sources[wkey] = [\n            Function(['require','module','exports'], '(' + fn + ')(self)'),\n            wcache\n        ];\n    }\n    var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n    \n    var scache = {}; scache[wkey] = wkey;\n    sources[skey] = [\n        Function(['require'],'require(' + stringify(wkey) + ')(self)'),\n        scache\n    ];\n    \n    var src = '(' + bundleFn + ')({'\n        + Object.keys(sources).map(function (key) {\n            return stringify(key) + ':['\n                + sources[key][0]\n                + ',' + stringify(sources[key][1]) + ']'\n            ;\n        }).join(',')\n        + '},{},[' + stringify(skey) + '])'\n    ;\n    return new Worker(window.URL.createObjectURL(\n        new Blob([src], { type: 'text/javascript' })\n    ));\n};\n\n},{}]},{},[])(\"./\")\n});"
  },
  {
    "path": "demo/js/regression.js",
    "content": "\nvar N, data, labels;\nvar ss = 30.0; // scale for drawing\n\nvar layer_defs, net, trainer;\n\n// create neural net\nvar t = \"layer_defs = [];\\n\\\nlayer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:1});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'sigmoid'});\\n\\\nlayer_defs.push({type:'regression', num_neurons:1});\\n\\\n\\n\\\nnet = new convnetjs.Net();\\n\\\nnet.makeLayers(layer_defs);\\n\\\n\\n\\\ntrainer = new convnetjs.SGDTrainer(net, {learning_rate:0.01, momentum:0.0, batch_size:1, l2_decay:0.001});\\n\\\n\";\n\nvar lix=2; // layer id of layer we'd like to draw outputs of\nfunction reload() {\n  eval($(\"#layerdef\").val());\n\n  // refresh buttons\n  var t = '';\n  for(var i=1;i<net.layers.length-1;i++) { // ignore input and regression layers (first and last)\n    var butid = \"button\" + i;\n    t += \"<input id=\\\"\"+butid+\"\\\" value=\\\"\" + net.layers[i].layer_type +\"\\\" type=\\\"submit\\\" onclick=\\\"updateLix(\"+i+\")\\\" style=\\\"width:80px; height: 30px; margin:5px;\\\";>\";\n  }\n  $(\"#layer_ixes\").html(t);\n  $(\"#button\"+lix).css('background-color', '#FFA');\n}\nfunction updateLix(newlix) {\n  $(\"#button\"+lix).css('background-color', ''); // erase highlight\n  lix = newlix;\n  $(\"#button\"+lix).css('background-color', '#FFA');\n}\n \nfunction regen_data() {\n  N = parseInt($(\"#num_data\").val());\n  data = [];\n  labels = [];\n  for(var i=0;i<N;i++) {\n    var x = Math.random()*10-5;\n    var y = x*Math.sin(x);\n    data.push([x]);\n    labels.push([y]);\n  }\n}\n\nfunction myinit(){\n  regen_data();\n  $(\"#layerdef\").val(t);\n  reload();\n}\n \nfunction update(){\n  // forward prop the data\n  \n  var netx = new convnetjs.Vol(1,1,1);\n  avloss = 0.0;\n\n  for(var iters=0;iters<50;iters++) {\n    for(var ix=0;ix<N;ix++) {\n      netx.w = data[ix];\n      var stats = trainer.train(netx, labels[ix]);\n      avloss += stats.loss;\n    }\n  }\n  avloss /= N*iters;\n\n}\n\nfunction draw(){\n    \n    ctx.clearRect(0,0,WIDTH,HEIGHT);\n    ctx.fillStyle = \"black\";\n\n    var netx = new convnetjs.Vol(1,1,1);\n\n    // draw decisions in the grid\n    var density= 5.0;\n    var draw_neuron_outputs = $(\"#layer_outs\").is(':checked');\n    \n    // draw final decision\n    var neurons = [];\n    ctx.beginPath();\n    for(var x=0.0; x<=WIDTH; x+= density) {\n\n      netx.w[0] = (x-WIDTH/2)/ss;\n      var a = net.forward(netx);\n      var y = a.w[0];\n\n      if(draw_neuron_outputs) {\n        neurons.push(net.layers[lix].out_act.w); // back these up\n      }\n\n      if(x===0) ctx.moveTo(x, -y*ss+HEIGHT/2);\n      else ctx.lineTo(x, -y*ss+HEIGHT/2);\n    }\n    ctx.stroke();\n\n    // draw individual neurons on first layer\n    if(draw_neuron_outputs) {\n      var NL = neurons.length;\n      ctx.strokeStyle = 'rgb(250,50,50)';\n      for(var k=0;k<NL;k++) {\n        ctx.beginPath();\n        var n = 0;\n        for(var x=0.0; x<=WIDTH; x+= density) {\n          if(x===0) ctx.moveTo(x, -neurons[n][k]*ss+HEIGHT/2);\n          else ctx.lineTo(x, -neurons[n][k]*ss+HEIGHT/2);\n          n++;\n        }\n        ctx.stroke();\n      }\n    }\n  \n    // draw axes\n    ctx.beginPath();\n    ctx.strokeStyle = 'rgb(50,50,50)';\n    ctx.lineWidth = 1;\n    ctx.moveTo(0, HEIGHT/2);\n    ctx.lineTo(WIDTH, HEIGHT/2);\n    ctx.moveTo(WIDTH/2, 0);\n    ctx.lineTo(WIDTH/2, HEIGHT);\n    ctx.stroke();\n\n    // draw datapoints. Draw support vectors larger\n    ctx.strokeStyle = 'rgb(0,0,0)';\n    ctx.lineWidth = 1;\n    for(var i=0;i<N;i++) {\n      drawCircle(data[i]*ss+WIDTH/2, -labels[i]*ss+HEIGHT/2, 5.0);\n    }\n\n    ctx.fillStyle = \"blue\";\n    ctx.font = \"bold 16px Arial\";\n    ctx.fillText(\"average loss: \" + avloss, 20, 20);\n}\n\nfunction mouseClick(x, y, shiftPressed){\n  \n  // add datapoint at location of click\n  data.push([(x-WIDTH/2)/ss]);\n  labels.push([-(y-HEIGHT/2)/ss]);\n  N += 1;\n\n}\n\nfunction keyDown(key){\n}\n\nfunction keyUp(key) {\n\n}\n\n$(function() {\n    \n});"
  },
  {
    "path": "demo/js/rldemo.js",
    "content": "  var canvas, ctx;\n    \n    // A 2D vector utility\n    var Vec = function(x, y) {\n      this.x = x;\n      this.y = y;\n    }\n    Vec.prototype = {\n      \n      // utilities\n      dist_from: function(v) { return Math.sqrt(Math.pow(this.x-v.x,2) + Math.pow(this.y-v.y,2)); },\n      length: function() { return Math.sqrt(Math.pow(this.x,2) + Math.pow(this.y,2)); },\n      \n      // new vector returning operations\n      add: function(v) { return new Vec(this.x + v.x, this.y + v.y); },\n      sub: function(v) { return new Vec(this.x - v.x, this.y - v.y); },\n      rotate: function(a) {  // CLOCKWISE\n        return new Vec(this.x * Math.cos(a) + this.y * Math.sin(a),\n                       -this.x * Math.sin(a) + this.y * Math.cos(a));\n      },\n      \n      // in place operations\n      scale: function(s) { this.x *= s; this.y *= s; },\n      normalize: function() { var d = this.length(); this.scale(1.0/d); }\n    }\n    \n    // line intersection helper function: does line segment (p1,p2) intersect segment (p3,p4) ?\n    var line_intersect = function(p1,p2,p3,p4) {\n      var denom = (p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y);\n      if(denom===0.0) { return false; } // parallel lines\n      var ua = ((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/denom;\n      var ub = ((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/denom;\n      if(ua>0.0&&ua<1.0&&ub>0.0&&ub<1.0) {\n        var up = new Vec(p1.x+ua*(p2.x-p1.x), p1.y+ua*(p2.y-p1.y));\n        return {ua:ua, ub:ub, up:up}; // up is intersection point\n      }\n      return false;\n    }\n    \n    var line_point_intersect = function(p1,p2,p0,rad) {\n      var v = new Vec(p2.y-p1.y,-(p2.x-p1.x)); // perpendicular vector\n      var d = Math.abs((p2.x-p1.x)*(p1.y-p0.y)-(p1.x-p0.x)*(p2.y-p1.y));\n      d = d / v.length();\n      if(d > rad) { return false; }\n      \n      v.normalize();\n      v.scale(d);\n      var up = p0.add(v);\n      if(Math.abs(p2.x-p1.x)>Math.abs(p2.y-p1.y)) {\n        var ua = (up.x - p1.x) / (p2.x - p1.x);\n      } else {\n        var ua = (up.y - p1.y) / (p2.y - p1.y);\n      }\n      if(ua>0.0&&ua<1.0) {\n        return {ua:ua, up:up};\n      }\n      return false;\n    }\n    \n    // Wall is made up of two points\n    var Wall = function(p1, p2) {\n      this.p1 = p1;\n      this.p2 = p2;\n    }\n    \n    // World object contains many agents and walls and food and stuff\n    var util_add_box = function(lst, x, y, w, h) {\n      lst.push(new Wall(new Vec(x,y), new Vec(x+w,y)));\n      lst.push(new Wall(new Vec(x+w,y), new Vec(x+w,y+h)));\n      lst.push(new Wall(new Vec(x+w,y+h), new Vec(x,y+h)));\n      lst.push(new Wall(new Vec(x,y+h), new Vec(x,y)));\n    }\n    \n    // item is circle thing on the floor that agent can interact with (see or eat, etc)\n    var Item = function(x, y, type) {\n      this.p = new Vec(x, y); // position\n      this.type = type;\n      this.rad = 10; // default radius\n      this.age = 0;\n      this.cleanup_ = false;\n    }\n    \n    var World = function() {\n      this.agents = [];\n      this.W = canvas.width;\n      this.H = canvas.height;\n      \n      this.clock = 0;\n      \n      // set up walls in the world\n      this.walls = []; \n      var pad = 10;\n      util_add_box(this.walls, pad, pad, this.W-pad*2, this.H-pad*2);\n      util_add_box(this.walls, 100, 100, 200, 300); // inner walls\n      this.walls.pop();\n      util_add_box(this.walls, 400, 100, 200, 300);\n      this.walls.pop();\n      \n      // set up food and poison\n      this.items = []\n      for(var k=0;k<30;k++) {\n        var x = convnetjs.randf(20, this.W-20);\n        var y = convnetjs.randf(20, this.H-20);\n        var t = convnetjs.randi(1, 3); // food or poison (1 and 2)\n        var it = new Item(x, y, t);\n        this.items.push(it);\n      }\n    }\n    \n    World.prototype = {      \n      // helper function to get closest colliding walls/items\n      stuff_collide_: function(p1, p2, check_walls, check_items) {\n        var minres = false;\n        \n        // collide with walls\n        if(check_walls) {\n          for(var i=0,n=this.walls.length;i<n;i++) {\n            var wall = this.walls[i];\n            var res = line_intersect(p1, p2, wall.p1, wall.p2);\n            if(res) {\n              res.type = 0; // 0 is wall\n              if(!minres) { minres=res; }\n              else {\n                // check if its closer\n                if(res.ua < minres.ua) {\n                  // if yes replace it\n                  minres = res;\n                }\n              }\n            }\n          }\n        }\n        \n        // collide with items\n        if(check_items) {\n          for(var i=0,n=this.items.length;i<n;i++) {\n            var it = this.items[i];\n            var res = line_point_intersect(p1, p2, it.p, it.rad);\n            if(res) {\n              res.type = it.type; // store type of item\n              if(!minres) { minres=res; }\n              else { if(res.ua < minres.ua) { minres = res; }\n              }\n            }\n          }\n        }\n        \n        return minres;\n      },\n      tick: function() {\n        // tick the environment\n        this.clock++;\n        \n        // fix input to all agents based on environment\n        // process eyes\n        this.collpoints = [];\n        for(var i=0,n=this.agents.length;i<n;i++) {\n          var a = this.agents[i];\n          for(var ei=0,ne=a.eyes.length;ei<ne;ei++) {\n            var e = a.eyes[ei];\n            // we have a line from p to p->eyep\n            var eyep = new Vec(a.p.x + e.max_range * Math.sin(a.angle + e.angle),\n                               a.p.y + e.max_range * Math.cos(a.angle + e.angle));\n            var res = this.stuff_collide_(a.p, eyep, true, true);\n            if(res) {\n              // eye collided with wall\n              e.sensed_proximity = res.up.dist_from(a.p);\n              e.sensed_type = res.type;\n            } else {\n              e.sensed_proximity = e.max_range;\n              e.sensed_type = -1;\n            }\n          }\n        }\n        \n        // let the agents behave in the world based on their input\n        for(var i=0,n=this.agents.length;i<n;i++) {\n          this.agents[i].forward();\n        }\n        \n        // apply outputs of agents on evironment\n        for(var i=0,n=this.agents.length;i<n;i++) {\n          var a = this.agents[i];\n          a.op = a.p; // back up old position\n          a.oangle = a.angle; // and angle\n          \n          // steer the agent according to outputs of wheel velocities\n          var v = new Vec(0, a.rad / 2.0);\n          v = v.rotate(a.angle + Math.PI/2);\n          var w1p = a.p.add(v); // positions of wheel 1 and 2\n          var w2p = a.p.sub(v);\n          var vv = a.p.sub(w2p);\n          vv = vv.rotate(-a.rot1);\n          var vv2 = a.p.sub(w1p);\n          vv2 = vv2.rotate(a.rot2);\n          var np = w2p.add(vv);\n          np.scale(0.5);\n          var np2 = w1p.add(vv2);\n          np2.scale(0.5);\n          a.p = np.add(np2);\n          \n          a.angle -= a.rot1;\n          if(a.angle<0)a.angle+=2*Math.PI;\n          a.angle += a.rot2;\n          if(a.angle>2*Math.PI)a.angle-=2*Math.PI;\n          \n          // agent is trying to move from p to op. Check walls\n          var res = this.stuff_collide_(a.op, a.p, true, false);\n          if(res) {\n            // wall collision! reset position\n            a.p = a.op;\n          }\n          \n          // handle boundary conditions\n          if(a.p.x<0)a.p.x=0;\n          if(a.p.x>this.W)a.p.x=this.W;\n          if(a.p.y<0)a.p.y=0;\n          if(a.p.y>this.H)a.p.y=this.H;\n        }\n        \n        // tick all items\n        var update_items = false;\n        for(var i=0,n=this.items.length;i<n;i++) {\n          var it = this.items[i];\n          it.age += 1;\n          \n          // see if some agent gets lunch\n          for(var j=0,m=this.agents.length;j<m;j++) {\n            var a = this.agents[j];\n            var d = a.p.dist_from(it.p);\n            if(d < it.rad + a.rad) {\n              \n              // wait lets just make sure that this isn't through a wall\n              var rescheck = this.stuff_collide_(a.p, it.p, true, false);\n              if(!rescheck) { \n                // ding! nom nom nom\n                if(it.type === 1) a.digestion_signal += 5.0; // mmm delicious apple\n                if(it.type === 2) a.digestion_signal += -6.0; // ewww poison\n                it.cleanup_ = true;\n                update_items = true;\n                break; // break out of loop, item was consumed\n              }\n            }\n          }\n          \n          if(it.age > 5000 && this.clock % 100 === 0 && convnetjs.randf(0,1)<0.1) {\n            it.cleanup_ = true; // replace this one, has been around too long\n            update_items = true;\n          }\n        }\n        if(update_items) {\n          var nt = [];\n          for(var i=0,n=this.items.length;i<n;i++) {\n            var it = this.items[i];\n            if(!it.cleanup_) nt.push(it);\n          }\n          this.items = nt; // swap\n        }\n        if(this.items.length < 30 && this.clock % 10 === 0 && convnetjs.randf(0,1)<0.25) {\n          var newitx = convnetjs.randf(20, this.W-20);\n          var newity = convnetjs.randf(20, this.H-20);\n          var newitt = convnetjs.randi(1, 3); // food or poison (1 and 2)\n          var newit = new Item(newitx, newity, newitt);\n          this.items.push(newit);\n        }\n        \n        // agents are given the opportunity to learn based on feedback of their action on environment\n        for(var i=0,n=this.agents.length;i<n;i++) {\n          this.agents[i].backward();\n        }\n      }\n    }\n    \n    // Eye sensor has a maximum range and senses walls\n    var Eye = function(angle) {\n      this.angle = angle; // angle relative to agent its on\n      this.max_range = 85;\n      this.sensed_proximity = 85; // what the eye is seeing. will be set in world.tick()\n      this.sensed_type = -1; // what does the eye see?\n    }\n    \n    // A single agent\n    var Agent = function() {\n    \n      // positional information\n      this.p = new Vec(50, 50);\n      this.op = this.p; // old position\n      this.angle = 0; // direction facing\n      \n      this.actions = [];\n      this.actions.push([1,1]);\n      this.actions.push([0.8,1]);\n      this.actions.push([1,0.8]);\n      this.actions.push([0.5,0]);\n      this.actions.push([0,0.5]);\n      \n      // properties\n      this.rad = 10;\n      this.eyes = [];\n      for(var k=0;k<9;k++) { this.eyes.push(new Eye((k-3)*0.25)); }\n      \n      // braaain\n      //this.brain = new deepqlearn.Brain(this.eyes.length * 3, this.actions.length);\n      var spec = document.getElementById('qspec').value;\n      eval(spec);\n      this.brain = brain;\n      \n      this.reward_bonus = 0.0;\n      this.digestion_signal = 0.0;\n      \n      // outputs on world\n      this.rot1 = 0.0; // rotation speed of 1st wheel\n      this.rot2 = 0.0; // rotation speed of 2nd wheel\n      \n      this.prevactionix = -1;\n    }\n    Agent.prototype = {\n      forward: function() {\n        // in forward pass the agent simply behaves in the environment\n        // create input to brain\n        var num_eyes = this.eyes.length;\n        var input_array = new Array(num_eyes * 3);\n        for(var i=0;i<num_eyes;i++) {\n          var e = this.eyes[i];\n          input_array[i*3] = 1.0;\n          input_array[i*3+1] = 1.0;\n          input_array[i*3+2] = 1.0;\n          if(e.sensed_type !== -1) {\n            // sensed_type is 0 for wall, 1 for food and 2 for poison.\n            // lets do a 1-of-k encoding into the input array\n            input_array[i*3 + e.sensed_type] = e.sensed_proximity/e.max_range; // normalize to [0,1]\n          }\n        }\n        \n        // get action from brain\n        var actionix = this.brain.forward(input_array);\n        var action = this.actions[actionix];\n        this.actionix = actionix; //back this up\n        \n        // demultiplex into behavior variables\n        this.rot1 = action[0]*1;\n        this.rot2 = action[1]*1;\n        \n        //this.rot1 = 0;\n        //this.rot2 = 0;\n      },\n      backward: function() {\n        // in backward pass agent learns.\n        // compute reward \n        var proximity_reward = 0.0;\n        var num_eyes = this.eyes.length;\n        for(var i=0;i<num_eyes;i++) {\n          var e = this.eyes[i];\n          // agents dont like to see walls, especially up close\n          proximity_reward += e.sensed_type === 0 ? e.sensed_proximity/e.max_range : 1.0;\n        }\n        proximity_reward = proximity_reward/num_eyes;\n        proximity_reward = Math.min(1.0, proximity_reward * 2);\n        \n        // agents like to go straight forward\n        var forward_reward = 0.0;\n        if(this.actionix === 0 && proximity_reward > 0.75) forward_reward = 0.1 * proximity_reward;\n        \n        // agents like to eat good things\n        var digestion_reward = this.digestion_signal;\n        this.digestion_signal = 0.0;\n        \n        var reward = proximity_reward + forward_reward + digestion_reward;\n        \n        // pass to brain for learning\n        this.brain.backward(reward);\n      }\n    }\n    \n    function draw_net() {\n      if(simspeed <=1) {\n        // we will always draw at these speeds\n      } else {\n        if(w.clock % 50 !== 0) return;  // do this sparingly\n      }\n      \n      var canvas = document.getElementById(\"net_canvas\");\n      var ctx = canvas.getContext(\"2d\");\n      var W = canvas.width;\n      var H = canvas.height;\n      ctx.clearRect(0, 0, canvas.width, canvas.height);\n      var L = w.agents[0].brain.value_net.layers;\n      var dx = (W - 50)/L.length;\n      var x = 10;\n      var y = 40;\n      ctx.font=\"12px Verdana\";\n      ctx.fillStyle = \"rgb(0,0,0)\";\n      ctx.fillText(\"Value Function Approximating Neural Network:\", 10, 14);\n      for(var k=0;k<L.length;k++) {\n        if(typeof(L[k].out_act)==='undefined') continue; // maybe not yet ready\n        var kw = L[k].out_act.w;\n        var n = kw.length;\n        var dy = (H-50)/n;\n        ctx.fillStyle = \"rgb(0,0,0)\";\n        ctx.fillText(L[k].layer_type + \"(\" + n + \")\", x, 35);\n        for(var q=0;q<n;q++) {\n          var v = Math.floor(kw[q]*100);\n          if(v >= 0) ctx.fillStyle = \"rgb(0,0,\" + v + \")\";\n          if(v < 0) ctx.fillStyle = \"rgb(\" + (-v) + \",0,0)\";\n          ctx.fillRect(x,y,10,10);\n          y += 12;\n          if(y>H-25) { y = 40; x += 12};\n        }\n        x += 50;\n        y = 40;\n      }\n    }\n    \n    var reward_graph = new cnnvis.Graph();\n    function draw_stats() {\n      var canvas = document.getElementById(\"vis_canvas\");\n      var ctx = canvas.getContext(\"2d\");\n      var W = canvas.width;\n      var H = canvas.height;\n      ctx.clearRect(0, 0, canvas.width, canvas.height);\n      var a = w.agents[0];\n      var b = a.brain;\n      var netin = b.last_input_array;\n      ctx.strokeStyle = \"rgb(0,0,0)\";\n      //ctx.font=\"12px Verdana\";\n      //ctx.fillText(\"Current state:\",10,10);\n      ctx.lineWidth = 10;\n      ctx.beginPath();\n      for(var k=0,n=netin.length;k<n;k++) {\n        ctx.moveTo(10+k*12, 120);\n        ctx.lineTo(10+k*12, 120 - netin[k] * 100);\n      }\n      ctx.stroke();\n      \n      if(w.clock % 200 === 0) {\n        reward_graph.add(w.clock/200, b.average_reward_window.get_average());\n        var gcanvas = document.getElementById(\"graph_canvas\");\n        reward_graph.drawSelf(gcanvas);\n      }\n    }\n    \n    // Draw everything\n    function draw() {  \n      ctx.clearRect(0, 0, canvas.width, canvas.height);\n      ctx.lineWidth = 1;\n      var agents = w.agents;\n      \n      // draw walls in environment\n      ctx.strokeStyle = \"rgb(0,0,0)\";\n      ctx.beginPath();\n      for(var i=0,n=w.walls.length;i<n;i++) {\n        var q = w.walls[i];\n        ctx.moveTo(q.p1.x, q.p1.y);\n        ctx.lineTo(q.p2.x, q.p2.y);\n      }\n      ctx.stroke();\n  \n      // draw agents\n      // color agent based on reward it is experiencing at the moment\n      var r = Math.floor(agents[0].brain.latest_reward * 200);\n      if(r>255)r=255;if(r<0)r=0;\n      ctx.fillStyle = \"rgb(\" + r + \", 150, 150)\";\n      ctx.strokeStyle = \"rgb(0,0,0)\";\n      for(var i=0,n=agents.length;i<n;i++) {\n        var a = agents[i];\n        \n        // draw agents body\n        ctx.beginPath();\n        ctx.arc(a.op.x, a.op.y, a.rad, 0, Math.PI*2, true); \n        ctx.fill();\n        ctx.stroke();\n        \n        // draw agents sight\n        for(var ei=0,ne=a.eyes.length;ei<ne;ei++) {\n          var e = a.eyes[ei];\n          var sr = e.sensed_proximity;\n          if(e.sensed_type === -1 || e.sensed_type === 0) { \n            ctx.strokeStyle = \"rgb(0,0,0)\"; // wall or nothing\n          }\n          if(e.sensed_type === 1) { ctx.strokeStyle = \"rgb(255,150,150)\"; } // apples\n          if(e.sensed_type === 2) { ctx.strokeStyle = \"rgb(150,255,150)\"; } // poison\n          ctx.beginPath();\n          ctx.moveTo(a.op.x, a.op.y);\n          ctx.lineTo(a.op.x + sr * Math.sin(a.oangle + e.angle),\n                     a.op.y + sr * Math.cos(a.oangle + e.angle));\n          ctx.stroke();\n        }\n      }\n      \n      // draw items\n      ctx.strokeStyle = \"rgb(0,0,0)\";\n      for(var i=0,n=w.items.length;i<n;i++) {\n        var it = w.items[i];\n        if(it.type === 1) ctx.fillStyle = \"rgb(255, 150, 150)\";\n        if(it.type === 2) ctx.fillStyle = \"rgb(150, 255, 150)\";\n        ctx.beginPath();\n        ctx.arc(it.p.x, it.p.y, it.rad, 0, Math.PI*2, true); \n        ctx.fill();\n        ctx.stroke();\n      }\n      \n      w.agents[0].brain.visSelf(document.getElementById('brain_info_div'));\n    }\n    \n    // Tick the world\n    function tick() {\n      w.tick();\n      if(!skipdraw || w.clock % 50 === 0) {\n        draw();\n        draw_stats();\n        draw_net();\n      }\n    }\n    \n    var simspeed = 2;\n    function goveryfast() {\n      window.clearInterval(current_interval_id);\n      current_interval_id = setInterval(tick, 0);\n      skipdraw = true;\n      simspeed = 3;\n    }\n    function gofast() {\n      window.clearInterval(current_interval_id);\n      current_interval_id = setInterval(tick, 0);\n      skipdraw = false;\n      simspeed = 2;\n    }\n    function gonormal() {\n      window.clearInterval(current_interval_id);\n      current_interval_id = setInterval(tick, 30);\n      skipdraw = false;\n      simspeed = 1;\n    }\n    function goslow() {\n      window.clearInterval(current_interval_id);\n      current_interval_id = setInterval(tick, 200);\n      skipdraw = false;\n      simspeed = 0;\n    }\n    \n    function savenet() {\n      var j = w.agents[0].brain.value_net.toJSON();\n      var t = JSON.stringify(j);\n      document.getElementById('tt').value = t;\n    }\n    \n    function loadnet() {\n      var t = document.getElementById('tt').value;\n      var j = JSON.parse(t);\n      w.agents[0].brain.value_net.fromJSON(j);\n      stoplearn(); // also stop learning\n      gonormal();\n    }\n    \n    function startlearn() {\n      w.agents[0].brain.learning = true;\n    }\n    function stoplearn() {\n      w.agents[0].brain.learning = false;\n    }\n    \n    function reload() {\n      w.agents = [new Agent()]; // this should simply work. I think... ;\\\n      reward_graph = new cnnvis.Graph(); // reinit\n    }\n    \n    var w; // global world object\n    var current_interval_id;\n    var skipdraw = false;\n    function start() {\n      canvas = document.getElementById(\"canvas\");\n      ctx = canvas.getContext(\"2d\");\n      \n      w = new World();\n      w.agents = [new Agent()];\n      \n      gofast();\n    }"
  },
  {
    "path": "demo/js/trainers.js",
    "content": "\nvar t = \"\\n\\\n// lets use an example fully-connected 2-layer ReLU net\\n\\\nvar layer_defs = [];\\n\\\nlayer_defs.push({type:'input', out_sx:24, out_sy:24, out_depth:1});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'fc', num_neurons:20, activation:'relu'});\\n\\\nlayer_defs.push({type:'softmax', num_classes:10});\\n\\\n\\n\\\n// below fill out the trainer specs you wish to evaluate, and give them names for legend\\n\\\nvar LR = 0.01; // learning rate\\n\\\nvar BS = 8; // batch size\\n\\\nvar L2 = 0.001; // L2 weight decay\\n\\\nnets = [];\\n\\\ntrainer_defs = [];\\n\\\ntrainer_defs.push({learning_rate:LR, method: 'sgd', momentum: 0.0, batch_size:BS, l2_decay:L2});\\n\\\ntrainer_defs.push({learning_rate:LR, method: 'sgd', momentum: 0.9, batch_size:BS, l2_decay:L2});\\n\\\ntrainer_defs.push({learning_rate:LR, method: 'adam', eps: 1e-8, beta1: 0.9, beta2: 0.99, batch_size:BS, l2_decay:L2});\\n\\\ntrainer_defs.push({learning_rate:LR, method: 'adagrad', eps: 1e-6, batch_size:BS, l2_decay:L2});\\n\\\ntrainer_defs.push({learning_rate:LR, method: 'windowgrad', eps: 1e-6, ro: 0.95, batch_size:BS, l2_decay:L2});\\n\\\ntrainer_defs.push({learning_rate:1.0, method: 'adadelta', eps: 1e-6, ro:0.95, batch_size:BS, l2_decay:L2});\\n\\\ntrainer_defs.push({learning_rate:LR, method: 'nesterov', momentum: 0.9, batch_size:BS, l2_decay:L2});\\n\\\n\\n\\\n// names for all trainers above\\n\\\nlegend = ['sgd', 'sgd+momentum', 'adam', 'adagrad', 'windowgrad', 'adadelta', 'nesterov'];\\n\\\n\"\n\n// ------------------------\n// BEGIN MNIST SPECIFIC STUFF\n// ------------------------\nclasses_txt = ['0','1','2','3','4','5','6','7','8','9'];\n\nvar use_validation_data = false;\nvar sample_training_instance = function() {\n\n  // find an unloaded batch\n  var bi = Math.floor(Math.random()*loaded_train_batches.length);\n  var b = loaded_train_batches[bi];\n  var k = Math.floor(Math.random()*3000); // sample within the batch\n  var n = b*3000+k;\n\n  // load more batches over time\n  if(step_num%5000===0 && step_num>0) {\n    for(var i=0;i<num_batches;i++) {\n      if(!loaded[i]) {\n        // load it\n        load_data_batch(i);\n        break; // okay for now\n      }\n    }\n  }\n\n  // fetch the appropriate row of the training image and reshape into a Vol\n  var p = img_data[b].data;\n  var x = new convnetjs.Vol(28,28,1,0.0);\n  var W = 28*28;\n  for(var i=0;i<W;i++) {\n    var ix = ((W * k) + i) * 4;\n    x.w[i] = p[ix]/255.0;\n  }\n  x = convnetjs.augment(x, 24);\n\n  var isval = use_validation_data && n%10===0 ? true : false;\n  return {x:x, label:labels[n], isval:isval};\n}\n\nvar sample_test_instance = function() {\n  var b = 20;\n  var k = Math.floor(Math.random()*3000);\n  var n = b*3000+k;\n\n  var p = img_data[b].data;\n  var x = new convnetjs.Vol(28,28,1,0.0);\n  var W = 28*28;\n  for(var i=0;i<W;i++) {\n    var ix = ((W * k) + i) * 4;\n    x.w[i] = p[ix]/255.0;\n  }\n  x = convnetjs.augment(x, 24);\n  return {x:x, label:labels[n]};\n}\n\nvar num_batches = 21; // 20 training batches, 1 test\nvar data_img_elts = new Array(num_batches);\nvar img_data = new Array(num_batches);\nvar loaded = new Array(num_batches);\nvar loaded_train_batches = [];\nvar step_num = 0;\n\n// int main\nvar lossWindows = [];\nvar trainAccWindows = [];\nvar testAccWindows = [];\nvar lossGraph, trainGraph, testGraph;\n$(window).load(function() {\n\n  $(\"#layerdef\").val(t);\n\n  for(var k=0;k<loaded.length;k++) { loaded[k] = false; }\n  load_data_batch(0); // async load train set batch 0 (6 total train batches)\n  load_data_batch(20); // async load test set (batch 6)\n  start_fun();\n\n  reload();\n});\n\nvar reload = function() {\n  \n  eval($(\"#layerdef\").val()); // fills in trainer_spects[] array, and layer_defs\n\n  var N = trainer_defs.length;\n  nets = [];\n  trainers = [];\n  for(var i=0;i<N;i++) {\n    var net = new convnetjs.Net();\n    net.makeLayers(layer_defs);\n    var trainer = new convnetjs.Trainer(net, trainer_defs[i]);\n    nets.push(net); \n    trainers.push(trainer);\n  }\n\n  step_num = 0;\n\n  lossWindows = [];\n  trainAccWindows = [];\n  testAccWindows = [];\n  for(var i=0;i<N;i++) {\n    lossWindows.push(new cnnutil.Window(800));\n    trainAccWindows.push(new cnnutil.Window(800));\n    testAccWindows.push(new cnnutil.Window(800));\n  }\n  lossGraph = new cnnvis.MultiGraph(legend);\n  trainGraph = new cnnvis.MultiGraph(legend);\n  testGraph = new cnnvis.MultiGraph(legend);\n}\n\nvar start_fun = function() {\n  if(loaded[0] && loaded[20]) { \n    console.log('starting!'); \n    setInterval(load_and_step, 0); // lets go!\n  }\n  else { setTimeout(start_fun, 200); } // keep checking\n}\n\nvar load_data_batch = function(batch_num) {\n  // Load the dataset with JS in background\n  data_img_elts[batch_num] = new Image();\n  var data_img_elt = data_img_elts[batch_num];\n  data_img_elt.onload = function() { \n    var data_canvas = document.createElement('canvas');\n    data_canvas.width = data_img_elt.width;\n    data_canvas.height = data_img_elt.height;\n    var data_ctx = data_canvas.getContext(\"2d\");\n    data_ctx.drawImage(data_img_elt, 0, 0); // copy it over... bit wasteful :(\n    img_data[batch_num] = data_ctx.getImageData(0, 0, data_canvas.width, data_canvas.height);\n    loaded[batch_num] = true;\n    if(batch_num < 20) { loaded_train_batches.push(batch_num); }\n    console.log('finished loading data batch ' + batch_num);\n  };\n  data_img_elt.src = \"mnist/mnist_batch_\" + batch_num + \".png\";\n}\n\n// ------------------------\n// END MNIST SPECIFIC STUFF\n// ------------------------\n\n// main iterator function\nvar load_and_step = function() {\n  step_num++;\n  var sample = sample_training_instance();\n  var test_sample = sample_test_instance();\n\n  // train on all networks\n  var N = nets.length;\n  var losses = [];\n  var trainacc = [];\n  testacc = [];\n  for(var i=0;i<N;i++) {\n\n    // train on training example\n    var stats = trainers[i].train(sample.x, sample.label);\n    var yhat = nets[i].getPrediction();\n    trainAccWindows[i].add(yhat === sample.label ? 1.0 : 0.0);\n    lossWindows[i].add(stats.loss);\n\n    // evaluate a test example\n    nets[i].forward(test_sample.x);\n    var yhat_test = nets[i].getPrediction();\n    testAccWindows[i].add(yhat_test === test_sample.label ? 1.0 : 0.0);\n\n    // every 100 iterations also draw\n    if(step_num % 100 === 0) {\n      losses.push(lossWindows[i].get_average());\n      trainacc.push(trainAccWindows[i].get_average());\n      testacc.push(testAccWindows[i].get_average());\n    }\n  }\n  if(step_num % 100 === 0) {\n    lossGraph.add(step_num, losses);\n    lossGraph.drawSelf(document.getElementById(\"lossgraph\"));\n\n    trainGraph.add(step_num, trainacc);\n    trainGraph.drawSelf(document.getElementById(\"trainaccgraph\"));\n\n    testGraph.add(step_num, testacc);\n    testGraph.drawSelf(document.getElementById(\"testaccgraph\"));\n  }\n}\n"
  },
  {
    "path": "demo/mnist.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>ConvNetJS MNIST demo</title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"author\" content=\"\">\n  <link rel=\"stylesheet\" href=\"css/style.css\">\n\n<script src=\"js/jquery-1.8.3.min.js\"></script>\n<script src=\"../build/vis.js\"></script>\n<script src=\"../build/util.js\"></script>\n<script src=\"../build/convnet.js\"></script>\n\n<script src=\"js/image-helpers.js\"></script>\n<script src=\"js/pica.js\"></script>\n\n<script src=\"mnist/mnist_labels.js\"></script>\n<script type=\"text/javascript\">\n  // ------------------------\n  // BEGIN MNIST SPECIFIC STUFF\n  // ------------------------\n  classes_txt = ['0','1','2','3','4','5','6','7','8','9'];\n  var dataset_name = \"mnist\";\n  var num_batches = 21; // 20 training batches, 1 test\n  var test_batch = 20;\n  var num_samples_per_batch = 3000;\n  var image_dimension = 28;\n  var image_channels = 1;\n  var use_validation_data = true;\n  var random_flip = false;\n  var random_position = false;\n\n  var layer_defs, net, trainer;\n  var t = \"layer_defs = [];\\n\\\n  layer_defs.push({type:'input', out_sx:24, out_sy:24, out_depth:1});\\n\\\n  layer_defs.push({type:'conv', sx:5, filters:8, stride:1, pad:2, activation:'relu'});\\n\\\n  layer_defs.push({type:'pool', sx:2, stride:2});\\n\\\n  layer_defs.push({type:'conv', sx:5, filters:16, stride:1, pad:2, activation:'relu'});\\n\\\n  layer_defs.push({type:'pool', sx:3, stride:3});\\n\\\n  layer_defs.push({type:'softmax', num_classes:10});\\n\\\n  \\n\\\n  net = new convnetjs.Net();\\n\\\n  net.makeLayers(layer_defs);\\n\\\n  \\n\\\n  trainer = new convnetjs.SGDTrainer(net, {method:'adadelta', batch_size:20, l2_decay:0.001});\\n\\\n  \";\n  // ------------------------\n  // END MNIST SPECIFIC STUFF\n  // ------------------------\n</script>\n<script src=\"js/images-demo.js\"></script>\n\n</head>\n<body>\n  <div id=\"wrap\">\n  <h2 style=\"text-align: center;\"><a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">ConvNetJS</a> MNIST demo</h2>\n  <h1>Description</h1>\n  <p>\n    This demo trains a Convolutional Neural Network on the <a href=\"http://yann.lecun.com/exdb/mnist/\">MNIST digits dataset</a> in your browser, with nothing but Javascript. The dataset is fairly easy and one should expect to get somewhere around 99% accuracy within few minutes. I used <a href=\"mnist_parse.zip\">this python script</a> to parse the <a href=\"http://deeplearning.net/tutorial/gettingstarted.html\">original files</a> into batches of images that can be easily loaded into page DOM with img tags.\n  </p>\n  <p>\n    This network takes a 28x28 MNIST image and crops a random 24x24 window before training on it (this technique is called data augmentation and improves generalization). Similarly to do prediction, 4 random crops are sampled and the probabilities across all crops are averaged to produce final predictions. The network runs at about 5ms for both forward and backward pass on my reasonably decent Ubuntu+Chrome machine.\n  </p>\n  <p>\n    By default, in this demo we're using Adadelta which is one of per-parameter adaptive step size methods, so we don't have to worry about changing learning rates or momentum over time. However, I still included the text fields for changing these if you'd like to play around with SGD+Momentum trainer.\n  </p>\n  <p>Report questions/bugs/suggestions to <a href=\"https://twitter.com/karpathy\">@karpathy</a>.</p>\n  <h1>Training Stats</h1>\n  <div class=\"divsec\" style=\"270px;\">\n    <div class=\"secpart\">\n      <input id=\"buttontp\" type=\"submit\" value=\"pause\" onclick=\"toggle_pause();\" style=\"width: 100px; height:30px; background-color: #FCC;\"/>\n      <div id=\"trainstats\"></div>\n\n      <div id=\"controls\">\n        Learning rate: <input name=\"lri\" type=\"text\" maxlength=\"20\" id=\"lr_input\"/>\n        <input id=\"buttonlr\" type=\"submit\" value=\"change\" onclick=\"change_lr();\"/>\n        <br />\n\n        Momentum: <input name=\"momi\" type=\"text\" maxlength=\"20\" id=\"momentum_input\"/>\n        <input id=\"buttonmom\" type=\"submit\" value=\"change\" onclick=\"change_momentum();\"/>\n        <br />\n\n        Batch size: <input name=\"bsi\" type=\"text\" maxlength=\"20\" id=\"batch_size_input\"/>\n        <input id=\"buttonbs\" type=\"submit\" value=\"change\" onclick=\"change_batch_size();\"/>\n        <br />\n\n        Weight decay: <input name=\"wdi\" type=\"text\" maxlength=\"20\" id=\"decay_input\"/>\n        <input id=\"buttonwd\" type=\"submit\" value=\"change\" onclick=\"change_decay();\"/>\n      </div>\n\n      <input id=\"buttondj\" type=\"submit\" value=\"save network snapshot as JSON\" onclick=\"dump_json();\"/><br />\n      <input id=\"buttonlfj\" type=\"submit\" value=\"init network from JSON snapshot\" onclick=\"load_from_json();\"/><br />\n      <textarea id=\"dumpjson\"></textarea>\n    </div>\n    <div class=\"secpart\">\n      <div>\n        Loss:<br />\n        <canvas id=\"lossgraph\">\n        </canvas>\n        <br />\n        <input id=\"buttoncg\" type=\"submit\" value=\"clear graph\" onclick=\"clear_graph();\"/>\n      </div>\n    </div>\n    <div class=\"secpart\"> \n      <div id=\"upload_box\">\n        Test an image from your computer:\n        <div id=\"img_div\">\n            <img id=\"preview_img\"/>\n        </div>\n        <input name=\"image\" type=\"file\" accept=\"image/*\" onchange=\"loadFile(event)\">\n\n        <input type=\"submit\" value=\"Test Image\" onclick=\"testImage(document.getElementById('preview_img'))\">\n      </div>\n    </div>\n    <div style=\"clear:both;\"></div>\n  </div>\n\n  <h1>Instantiate a Network and Trainer</h1>\n  <div>\n    <textarea id=\"newnet\" style=\"width:100%; height:200px;\"></textarea><br />\n    <input id=\"buttonnn\" type=\"submit\" value=\"change network\" onclick=\"change_net();\" style=\"width:200px;height:30px;\"/>\n  </div>\n\n  <div class=\"divsec\">\n  <h1>Network Visualization</h1>\n    <div id=\"visnet\"></div>\n  </div>\n  \n  <div class=\"divsec\">\n  <h1>Example predictions on Test set</h1>\n    <div id=\"testset_acc\"></div>\n\t<div id=\"testset_vis\"></div>\n  </div>\n\n  </div>  \n</body>\n</html>\n\n\n\n"
  },
  {
    "path": "demo/regression.html",
    "content": "<html>\n<head>\n<title>ConvNetJS demo: Classify toy 2D data</title>\n<link href='http://fonts.googleapis.com/css?family=Cabin' rel='stylesheet' type='text/css'>\n<link rel=\"stylesheet\" href=\"css/style.css\">\n\n<script>\n      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n      ga('create', 'UA-3698471-21', 'stanford.edu');\n      ga('send', 'pageview');\n\n</script>\n\n<script src=\"js/jquery-1.8.3.min.js\"></script>\n<script src=\"js/npgmain.js\"></script>\n<script src=\"../build/convnet.js\"></script>\n<script src=\"js/regression.js\"></script>\n\n<style type=\"text/css\">\ncanvas { \n    border: 1px solid #555;\n    margin-top: 10px;\n}\n#wrap {\n  width: 800px;\n  margin-right: auto;\n  margin-left: auto;\n  margin-bottom: 200px;\n}\n</style>\n\n</head>\n\n<body onLoad=\"NPGinit(10);\">\n\n<div id=\"wrap\">\n<h1><a href=\"http://cs.stanford.edu/people/karpathy/convnetjs\">ConvnetJS</a> demo: toy 1d regression</h1>\n\n<p>The simulation below is a 1-dimensional regression where a neural network is trained to regress to y coordinates for every given point x through an L2 loss. That is, the minimized cost function computes the squared difference between the predicted y-coordinate and the \"correct\" y coordinate. Every 10th of a second, all points are fed to the network multiple times through the trainer class to train the network.</p>\n\n<p>The simulation below will eval() whatever you have in the text area and reload. Feel free to explore and use ConvNetJS to instantiate your own network!</p>\n\n<p>Report questions/bugs/suggestions to <a href=\"https://twitter.com/karpathy\">@karpathy</a>.</p>\n\n<textarea id=\"layerdef\" style=\"width:100%; height:250px;\">\n</textarea>\n<br /><br  />\n<input id=\"buttontp\" type=\"submit\" value=\"change network\" onclick=\"reload();\" style=\"width: 300px; height: 50px;\"/>\n\n<div style=\"float: right;\">\nNumber of points to generate:  <input type=\"text\" name=\"num_points\" id=\"num_data\" value=\"20\">\n<input type=\"submit\" value=\"regenerate data\" style=\"height:50px;\" onclick=\"regen_data();\" />\n</div>\n\n<br />\n<p style=\"color: red\">Add data points by clicking!</p>\n<br />\n<input type=\"checkbox\" name=\"draw_layer_outputs\" id=\"layer_outs\">\nAlso draw outputs of a layer (click layer button below) in red.\n<br /><div id=\"layer_ixes\"></div>\n\n<canvas id=\"NPGcanvas\" width=\"800\" height=\"500\">Browser not supported for Canvas. Get a real browser.</canvas>\n\n<p>Go <a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">back to ConvNetJS</a></p>\n\n</div>\n\n</body>\n</html>\n\n"
  },
  {
    "path": "demo/rldemo.html",
    "content": "<!doctype html>\r\n<html lang=\"en\">\r\n <head>\r\n  <meta charset=\"utf-8\">\r\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\r\n  <title>ConvNetJS Deep Q Learning Reinforcement Learning with Neural Network demo</title>\r\n  <meta name=\"description\" content=\"\">\r\n  <meta name=\"author\" content=\"\">\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n\r\n  <script src=\"../build/convnet.js\"></script>\r\n  <script src=\"../build/util.js\"></script>\r\n  <script src=\"../build/vis.js\"></script>\r\n  <script src=\"../build/deepqlearn.js\"></script>\r\n  <link rel=\"stylesheet\" href=\"css/style.css\">\r\n  \r\n  <script src=\"js/rldemo.js\"></script>\r\n  <style type=\"text/css\">\r\n      canvas { border: 1px solid white; }\r\n    </style>\r\n\r\n </head>\r\n <body onload=\"start();\">\r\n   <div id=\"wrap\">\r\n   <h2><a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">ConvNetJS</a> Deep Q Learning Demo</h2>\r\n   <h1>Description</h1>\r\n   <p>\r\n   This demo follows the description of the Deep Q Learning algorithm described in \r\n   <a href=\"http://arxiv.org/pdf/1312.5602v1.pdf\">Playing Atari with Deep Reinforcement Learning</a>, \r\n   a paper from NIPS 2013 Deep Learning Workshop from DeepMind. The paper is a nice demo of a fairly\r\n   standard (model-free) Reinforcement Learning algorithm (Q Learning) learning to play Atari games.\r\n   </p>\r\n   <p>\r\n   In this demo, instead of Atari games, we'll start out with something more simple: \r\n   a 2D agent that has 9 eyes pointing in different angles ahead and every eye senses 3 values\r\n   along its direction (up to a certain maximum visibility distance): distance to a wall, distance to \r\n   a green thing, or distance to a red thing. The agent navigates by using one of 5 actions that turn \r\n   it different angles. The red things are apples and the agent gets reward for eating them. The green\r\n   things are poison and the agent gets negative reward for eating them. The training takes a few tens\r\n   of minutes with current parameter settings.\r\n   </p>\r\n   <p>\r\n   Over time, the agent learns to avoid states that lead to states with low rewards, and picks actions\r\n   that lead to better states instead.\r\n   </p>\r\n   <h1>Q-Learner full specification and options</h1>\r\n   <p>\r\n   The textfield below gets eval()'d to produce the Q-learner for this demo. This allows you to fiddle with \r\n   various parameters and settings and also shows how you can use the API for your own purposes. \r\n   All of these settings are optional but are listed to give an idea of possibilities.\r\n   Feel free to change things around and hit reload! Documentation for all\r\n   options is the paper linked to above, and there are also \r\n   comments for every option in the source code javascript file.\r\n   </p>\r\n   <textarea id=\"qspec\" style=\"width:100%; height:200px;\">\r\nvar num_inputs = 27; // 9 eyes, each sees 3 numbers (wall, green, red thing proximity)\r\nvar num_actions = 5; // 5 possible angles agent can turn\r\nvar temporal_window = 1; // amount of temporal memory. 0 = agent lives in-the-moment :)\r\nvar network_size = num_inputs*temporal_window + num_actions*temporal_window + num_inputs;\r\n\r\n// the value function network computes a value of taking any of the possible actions\r\n// given an input state. Here we specify one explicitly the hard way\r\n// but user could also equivalently instead use opt.hidden_layer_sizes = [20,20]\r\n// to just insert simple relu hidden layers.\r\nvar layer_defs = [];\r\nlayer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:network_size});\r\nlayer_defs.push({type:'fc', num_neurons: 50, activation:'relu'});\r\nlayer_defs.push({type:'fc', num_neurons: 50, activation:'relu'});\r\nlayer_defs.push({type:'regression', num_neurons:num_actions});\r\n\r\n// options for the Temporal Difference learner that trains the above net\r\n// by backpropping the temporal difference learning rule.\r\nvar tdtrainer_options = {learning_rate:0.001, momentum:0.0, batch_size:64, l2_decay:0.01};\r\n\r\nvar opt = {};\r\nopt.temporal_window = temporal_window;\r\nopt.experience_size = 30000;\r\nopt.start_learn_threshold = 1000;\r\nopt.gamma = 0.7;\r\nopt.learning_steps_total = 200000;\r\nopt.learning_steps_burnin = 3000;\r\nopt.epsilon_min = 0.05;\r\nopt.epsilon_test_time = 0.05;\r\nopt.layer_defs = layer_defs;\r\nopt.tdtrainer_options = tdtrainer_options;\r\n\r\nvar brain = new deepqlearn.Brain(num_inputs, num_actions, opt); // woohoo\r\n   </textarea>\r\n   <button onclick=\"reload()\" style=\"width: 200px; height: 30px; margin-top: 5px;\">Reload</button>\r\n   \r\n   <h1>Q-Learner API</h1>\r\n   <p>It's very simple to use deeqlearn.Brain: Initialize your network:</p>\r\n   <pre>\r\n   var brain = new deepqlearn.Brain(num_inputs, num_actions);\r\n   </pre>\r\n   <p>And to train it proceed in loops as follows:</p>\r\n   <pre>\r\n   var action = brain.forward(array_with_num_inputs_numbers);\r\n   // action is a number in [0, num_actions) telling index of the action the agent chooses\r\n   // here, apply the action on environment and observe some reward. Finally, communicate it:\r\n   brain.backward(reward); // <-- learning magic happens here\r\n   </pre>\r\n   <p>That's it! Let the agent learn over time (it will take opt.learning_steps_total), and it\r\n   will only get better and better at accumulating reward as it learns. Note that the agent will still take\r\n   random actions with probability opt.epsilon_min even once it's fully trained. \r\n   To completely disable this randomness, or change it, you can disable the learning and set epsilon_test_time to 0:</p>\r\n   <pre>\r\n   brain.epsilon_test_time = 0.0; // don't make any random choices, ever\r\n   brain.learning = false;\r\n   var action = brain.forward(array_with_num_inputs_numbers); // get optimal action from learned policy\r\n   </pre>\r\n   \r\n   <h1>State Visualizations</h1>\r\n   \r\n   <div><b>Left</b>: Current input state (quite a useless thing to look at). <b>Right</b>: Average reward over time (this should go up as agent becomes better on average at collecting rewards)</div>\r\n   <canvas id=\"vis_canvas\" width=\"350\" height=\"150\"></canvas>\r\n   <canvas id=\"graph_canvas\" width=\"350\" height=\"150\"></canvas><br />\r\n   <canvas id=\"net_canvas\" width=\"700\" height=\"200\"></canvas><br />\r\n\r\n   <div style=\"font-size:13px;\">\r\n   (Takes ~10 minutes to train with current settings. If you're impatient, scroll down and load an example pre-trained network from pre-filled JSON)\r\n   </div>\r\n   <canvas id=\"canvas\" width=\"700\" height=\"500\"></canvas>\r\n   <div id=\"brain_info_div\"></div>\r\n   \r\n   <h1>Controls</h1>\r\n   <button onclick=\"goveryfast()\">Go very fast</button>\r\n   <button onclick=\"gofast()\">Go fast</button>\r\n   <button onclick=\"gonormal()\">Go normal speed</button>\r\n   <button onclick=\"goslow()\">Go slow</button><br />\r\n   <button onclick=\"startlearn()\">Start Learning</button>\r\n   <button onclick=\"stoplearn()\">Stop Learning</button>\r\n   \r\n   <h1>I/O</h1>\r\n   <p>\r\n   You can save and load a network from JSON here. Note that the textfield is prefilled with a\r\n   pretrained network that works reasonable well, if you're impatient to let yours train enough.\r\n   Just hit the load button!\r\n   </p>\r\n   <button onclick=\"savenet()\">Save network to JSON</button>\r\n   <button onclick=\"loadnet()\">Load network from JSON</button>\r\n   <textarea id=\"tt\" style=\"width:100%; height:200px;\">\r\n   {\"layers\":[{\"out_depth\":59,\"out_sx\":1,\"out_sy\":1,\"layer_type\":\"input\"},{\"out_depth\":50,\"out_sx\":1,\"out_sy\":1,\"layer_type\":\"fc\",\"num_inputs\":59,\"l1_decay_mul\":0,\"l2_decay_mul\":1,\"filters\":[{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.07568619865259014,\"1\":0.20893832699294146,\"2\":0.08277820923132798,\"3\":0.003463575624515028,\"4\":0.20494383431677626,\"5\":-0.08698498619856396,\"6\":-0.1572669314417734,\"7\":0.014768879500503164,\"8\":-0.08970136761457331,\"9\":-0.2492827251111491,\"10\":0.03741095313171217,\"11\":-0.2279739920142714,\"12\":-0.19136373291667877,\"13\":-0.012090654697954215,\"14\":0.10449381329061105,\"15\":0.11879427121158571,\"16\":0.03334130331388528,\"17\":0.0692309172412154,\"18\":-0.07881972151988506,\"19\":-0.06870906875278555,\"20\":-0.060249793773842625,\"21\":-0.22954925237921542,\"22\":-0.1967280316362117,\"23\":0.015455332305158817,\"24\":0.0006527109337938079,\"25\":-0.1748671379933951,\"26\":0.1056868278832309,\"27\":-0.016920768467689293,\"28\":-0.0793675374981745,\"29\":-0.07896773696842947,\"30\":-0.0858766249585122,\"31\":0.08871601327002077,\"32\":-0.154385335721499,\"33\":-0.15941521733329764,\"34\":0.13935233451342358,\"35\":0.0909690822364802,\"36\":-0.038567604752220694,\"37\":-0.08293138521325195,\"38\":0.12312513410927378,\"39\":-0.07498762474644094,\"40\":-0.16263339285857692,\"41\":-0.05900177180169054,\"42\":0.007074006539861552,\"43\":0.272213980600211,\"44\":-0.14771413309216286,\"45\":-0.25499007024896514,\"46\":-0.14682128308833736,\"47\":0.09358139878136032,\"48\":0.1763443149335001,\"49\":-0.14541759245264008,\"50\":-0.2060051858964503,\"51\":-0.08920170170316712,\"52\":-0.23314268564372914,\"53\":0.21888292181145477,\"54\":0.04972551124436227,\"55\":0.1336800863475002,\"56\":-0.1225507205585294,\"57\":-0.04501829366312003,\"58\":0.20331902606599386}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.028503741612961174,\"1\":0.08909761543239324,\"2\":-0.13317614327964097,\"3\":-0.05058915480406845,\"4\":0.1457307389537489,\"5\":0.060415023679052424,\"6\":0.14195581431254928,\"7\":-0.04482357732782931,\"8\":0.2909985848981078,\"9\":-0.013698798628110246,\"10\":0.03225874913103504,\"11\":-0.060642513718580114,\"12\":0.04843180405717124,\"13\":0.23457590954605634,\"14\":-0.12967513147956025,\"15\":0.05580208026031705,\"16\":0.2534232871116277,\"17\":-0.029774602048734347,\"18\":-0.11504048891124324,\"19\":0.2569255445823429,\"20\":-0.0006732687123468358,\"21\":0.21783628503393462,\"22\":-0.04280126548319759,\"23\":0.10559718904664156,\"24\":0.09721965526888939,\"25\":0.09093106185871204,\"26\":-0.088353512353856,\"27\":0.14579230064072665,\"28\":-0.018820849120558446,\"29\":0.13910481021198265,\"30\":0.05415983170433983,\"31\":-0.15140721010519498,\"32\":0.07075944891232136,\"33\":0.10101111302189461,\"34\":0.19234627887346023,\"35\":0.15019533296278867,\"36\":0.06578957961412281,\"37\":0.03809709662557473,\"38\":-0.07131980820670589,\"39\":-0.12771548826313697,\"40\":0.2518292102213821,\"41\":-0.17695507608057312,\"42\":0.017703061938704558,\"43\":0.06367768359478883,\"44\":-0.01952892434832844,\"45\":-0.033522521245899634,\"46\":0.15257170617436192,\"47\":-0.019373051018795714,\"48\":0.23126163127239582,\"49\":0.11413994935777193,\"50\":-0.06047058247532035,\"51\":0.05126947026779747,\"52\":0.1853117161573042,\"53\":0.007277778037151278,\"54\":0.03287662696789752,\"55\":-0.05714520809295533,\"56\":-0.023455101040810642,\"57\":-0.022842877769284464,\"58\":0.18884484738055748}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.08086162928309681,\"1\":0.07889255866790876,\"2\":-0.2480773034747618,\"3\":-0.08317461474304912,\"4\":-0.031352766041292154,\"5\":0.009358972421699429,\"6\":-0.03712783246665528,\"7\":-0.012609550093555636,\"8\":0.08969348933843663,\"9\":-0.13767122053665423,\"10\":0.04383267597825894,\"11\":0.01489494403169067,\"12\":-0.027323213453522153,\"13\":-0.19424152612006385,\"14\":0.006379136478309673,\"15\":-0.1095470997286232,\"16\":-0.18177268401137128,\"17\":-0.034765793600815074,\"18\":-0.1521219443045043,\"19\":-0.18984978560495747,\"20\":-0.07840160507164504,\"21\":0.020048968629593465,\"22\":0.029915018647682028,\"23\":0.028812872317726154,\"24\":-0.0761499278061531,\"25\":0.173156686132017,\"26\":-0.05676613616824758,\"27\":-0.05752001711757769,\"28\":0.046426472030747595,\"29\":-0.0003901032077098355,\"30\":0.24393247239365332,\"31\":0.2797951852490883,\"32\":0.11921777649997811,\"33\":-0.14654316528167297,\"34\":0.19215169809111793,\"35\":-0.1844051242172835,\"36\":0.006986398654407016,\"37\":-0.01615401501502596,\"38\":-0.05701037563662642,\"39\":-0.01368710008958653,\"40\":0.03392354650963498,\"41\":-0.027431062580606982,\"42\":0.04664097977955143,\"43\":-0.13730219273556388,\"44\":0.11726966286388503,\"45\":0.10049730997030336,\"46\":-0.08551584911997363,\"47\":0.023821348145208875,\"48\":-0.09250073929196023,\"49\":0.18951927158956608,\"50\":0.005567419989588734,\"51\":0.20066118687025358,\"52\":-0.25261483767473564,\"53\":-0.059115301522740867,\"54\":-0.020374534082823054,\"55\":-0.09905584812677456,\"56\":-0.06190720437052105,\"57\":0.15051818652671786,\"58\":-0.1701807934647233}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.21792796167975018,\"1\":-0.06144622045403336,\"2\":-0.17436514201519396,\"3\":-0.11315939273221401,\"4\":0.047320317288489525,\"5\":0.10276311134743098,\"6\":0.05157272415835688,\"7\":-0.2723788242652161,\"8\":-0.11651677947214875,\"9\":0.001272075452328442,\"10\":-0.049847161226051546,\"11\":0.061798622904317396,\"12\":-0.02230053709725508,\"13\":0.09781275381053982,\"14\":-0.04337009957241692,\"15\":0.26341106607325454,\"16\":0.1493737674709007,\"17\":0.0882157743943263,\"18\":0.14553959988043347,\"19\":0.015182520382829332,\"20\":-0.07032215329505208,\"21\":-0.07721546683504153,\"22\":-0.2003317003001039,\"23\":-0.37417621773969906,\"24\":0.0002598819018964462,\"25\":-0.20960246997460583,\"26\":-0.20254750592906148,\"27\":0.3214421189533645,\"28\":-0.03086441457225746,\"29\":0.22585426700422917,\"30\":-0.13148585111400746,\"31\":-0.08247854177002978,\"32\":-0.16404130757422516,\"33\":0.20974373104071153,\"34\":0.07652297205100404,\"35\":0.20112431595083455,\"36\":0.2148473454177445,\"37\":-0.16159448737642415,\"38\":0.10272173537979544,\"39\":-0.24751321551205105,\"40\":0.17295703345172284,\"41\":-0.045661351469138176,\"42\":-0.1511479598389083,\"43\":0.1889959631329223,\"44\":-0.14510653847846267,\"45\":0.014549120475373083,\"46\":-0.1891269805573303,\"47\":0.16070608015355062,\"48\":-0.19278547196193546,\"49\":0.18080316202667054,\"50\":0.001758319106748629,\"51\":-0.21087365860840396,\"52\":-0.17936433098677448,\"53\":-0.038797609942731244,\"54\":-0.03343496718705578,\"55\":-0.060305678599548884,\"56\":0.0064655062605580875,\"57\":-0.02726071472301753,\"58\":0.1064083548933379}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.043184949913496536,\"1\":-0.39339556492667943,\"2\":0.14229845619317702,\"3\":-0.05435868153969304,\"4\":0.006229191352121519,\"5\":0.07020916317994665,\"6\":0.033572999174373404,\"7\":-0.16674314934687975,\"8\":0.18495484641583582,\"9\":0.16283001058422342,\"10\":-0.12781783790611634,\"11\":0.04250125005319777,\"12\":-0.07589250822310245,\"13\":-0.11114720035753167,\"14\":0.0286791716772955,\"15\":0.06935416698520286,\"16\":-0.07613505870616132,\"17\":0.11063511604430665,\"18\":-0.05110045810146945,\"19\":-0.17086949272523325,\"20\":0.047693025556446826,\"21\":0.06741782059315171,\"22\":-0.09296610136913934,\"23\":0.0484725934698921,\"24\":0.03680044894825596,\"25\":-0.1070824108417384,\"26\":0.21715815747044886,\"27\":-0.02890750743926502,\"28\":0.034646384796661246,\"29\":0.18227061821679333,\"30\":-0.05264836831052613,\"31\":-0.07888837308720863,\"32\":-0.1581089572300349,\"33\":-0.10207098802484822,\"34\":0.09274859749507537,\"35\":-0.11646661300050228,\"36\":0.20412310784557547,\"37\":-0.011309178986363924,\"38\":0.08612331064492901,\"39\":-0.009352450559624382,\"40\":0.03170374900378987,\"41\":-0.14972056112212836,\"42\":-0.1473913176263749,\"43\":-0.12116077407269943,\"44\":0.18124732600338872,\"45\":-0.11871467499508744,\"46\":-0.12512066670474897,\"47\":0.16071041153010115,\"48\":0.037044158963635575,\"49\":0.06026937660515527,\"50\":-0.19618851311619367,\"51\":0.058122742562347576,\"52\":0.029298906017452102,\"53\":-0.18307223971909187,\"54\":0.011200258380899806,\"55\":-0.2243642790197571,\"56\":-0.22999290733159772,\"57\":0.05457559109275763,\"58\":-0.08120002237439485}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.09273510979239763,\"1\":0.09711434872410996,\"2\":0.05331746319510409,\"3\":-0.07330269078993319,\"4\":0.17412787861473827,\"5\":-0.16335150668296727,\"6\":-0.055123963144974926,\"7\":0.09163651226710834,\"8\":-0.10711777299431939,\"9\":0.16639955863583838,\"10\":-0.14590153499126854,\"11\":-0.22977732911931514,\"12\":-0.11059063332447187,\"13\":-0.04714787909590923,\"14\":-0.08793643869478769,\"15\":-0.00006461062614998591,\"16\":0.11778650243356045,\"17\":-0.06716937250994721,\"18\":-0.13211895956795253,\"19\":0.08094008833511182,\"20\":-0.008848224621503272,\"21\":-0.193725454296876,\"22\":-0.26548042909773667,\"23\":-0.05085421524640532,\"24\":0.004951060421276049,\"25\":-0.09574473203354782,\"26\":0.07026642070516825,\"27\":-0.07134182756896705,\"28\":0.1371021438814226,\"29\":-0.09055535463718906,\"30\":-0.1389491882716881,\"31\":0.10213860312868114,\"32\":-0.2070072540287602,\"33\":0.0929704552655362,\"34\":0.21683575385845064,\"35\":0.10874574795088213,\"36\":-0.07274413104576095,\"37\":-0.17982978050298842,\"38\":0.17389995832592514,\"39\":0.31608159337510744,\"40\":-0.002820254867532113,\"41\":-0.10647137758688607,\"42\":-0.09015717315982089,\"43\":-0.1094807662203248,\"44\":-0.06816030601237517,\"45\":-0.05531458579839508,\"46\":-0.03937890804057257,\"47\":-0.03261187026761702,\"48\":0.13924464941494946,\"49\":0.029489414024727108,\"50\":0.21593666206248344,\"51\":0.00044144120235121797,\"52\":0.18701387548387646,\"53\":-0.06089112663906061,\"54\":0.09873227690222872,\"55\":-0.034654301308683036,\"56\":0.055428653547294614,\"57\":-0.29106785004672925,\"58\":-0.040928753292253914}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.04257779690976387,\"1\":-0.09347518094951283,\"2\":0.29594328575242074,\"3\":0.14985041431183302,\"4\":-0.2824448447752057,\"5\":0.23916224087763957,\"6\":0.1264755099278443,\"7\":-0.002142899173573996,\"8\":0.20892614786477412,\"9\":-0.04368064825691694,\"10\":-0.2725770694210779,\"11\":0.149909593270064,\"12\":0.02128039843692495,\"13\":-0.16909636504102707,\"14\":0.11081187507003597,\"15\":0.09741443178553628,\"16\":-0.13360767234817808,\"17\":0.06873402117159765,\"18\":0.17222927428687204,\"19\":-0.2540383508362147,\"20\":0.26984597258324533,\"21\":0.04528998653408651,\"22\":-0.22749039390673975,\"23\":-0.22821525094668152,\"24\":0.2847109311027479,\"25\":-0.011453824060688149,\"26\":0.20090805692783326,\"27\":0.12937136186385895,\"28\":-0.06539333455750272,\"29\":0.10586462160819295,\"30\":0.13438652827628705,\"31\":-0.22711952645834166,\"32\":0.11071886602837888,\"33\":0.029400335497002862,\"34\":-0.11965634039788824,\"35\":0.15744174628597296,\"36\":0.11622271898222045,\"37\":-0.12459206787384476,\"38\":0.0738551682729965,\"39\":-0.0722766099277832,\"40\":-0.11619691149745502,\"41\":-0.10091791309747251,\"42\":0.09144389328827374,\"43\":-0.22680187069199315,\"44\":-0.04508840926101987,\"45\":-0.1838042105167889,\"46\":-0.06697361696511456,\"47\":-0.16799890624765382,\"48\":0.24130039867664624,\"49\":-0.08121178093577071,\"50\":-0.10102432104946901,\"51\":-0.27196932315838757,\"52\":0.013079975509401792,\"53\":0.02728877076107724,\"54\":-0.14600596278946346,\"55\":0.23138550493507448,\"56\":0.14615961588892595,\"57\":0.08923864699104907,\"58\":0.08312913535641754}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.12322423083440415,\"1\":-0.13383293360548768,\"2\":-0.17368261046232522,\"3\":-0.030080866618948505,\"4\":0.10655186638940942,\"5\":0.06389903554848014,\"6\":0.06808059679665679,\"7\":0.07004486901431645,\"8\":-0.0008718187458954167,\"9\":0.012572544897317768,\"10\":0.022867040979564306,\"11\":-0.05220176444949089,\"12\":-0.06099950110798452,\"13\":-0.25271355118849315,\"14\":0.04579301231133458,\"15\":-0.07257230006694391,\"16\":-0.16435261404752485,\"17\":0.06251581758478725,\"18\":0.09034027143301661,\"19\":0.13294892945151332,\"20\":-0.082668872398394,\"21\":0.023912061014927977,\"22\":-0.2704128816735308,\"23\":-0.05950051155038829,\"24\":0.31933575123003904,\"25\":-0.028790152497941552,\"26\":-0.3283732216623513,\"27\":-0.05904273968904255,\"28\":0.0422867422576855,\"29\":-0.13210091329491183,\"30\":-0.09318393727006853,\"31\":-0.10740232507328917,\"32\":0.0994118787677866,\"33\":-0.005130829184389204,\"34\":0.03260514385578187,\"35\":-0.18566206242112998,\"36\":-0.06942560631582662,\"37\":-0.12025634072438822,\"38\":-0.13565200751527062,\"39\":0.03743747328167675,\"40\":0.07903371778509545,\"41\":-0.023931790180951797,\"42\":0.06560655917889105,\"43\":-0.030846239959788777,\"44\":0.005181810047795786,\"45\":0.17284525591471675,\"46\":0.04118701279854405,\"47\":-0.037379828233081516,\"48\":-0.013514502750314255,\"49\":-0.10860492432926203,\"50\":0.03396774178660624,\"51\":0.03781358819052479,\"52\":-0.008142526617880428,\"53\":-0.104090836042394,\"54\":0.16539378917994704,\"55\":-0.034694069581083474,\"56\":-0.02295660367787702,\"57\":-0.16355154805871924,\"58\":0.046164297662070745}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.10403804209982365,\"1\":0.14088850135482828,\"2\":0.043677427468143855,\"3\":-0.1749157814833109,\"4\":-0.018103231299613505,\"5\":-0.19150040894133552,\"6\":0.07277304208863401,\"7\":0.1000664882827224,\"8\":0.1956334654568645,\"9\":-0.07925336084419825,\"10\":0.05419612436660899,\"11\":0.0925605131750983,\"12\":0.0061535557946293075,\"13\":-0.09157401757057522,\"14\":-0.01851689510741964,\"15\":0.013845279225365522,\"16\":-0.07598350627083215,\"17\":0.06355966055013984,\"18\":-0.13851906450449264,\"19\":0.10518392214629717,\"20\":0.019319441446751028,\"21\":0.04266399317552256,\"22\":-0.19423031677121702,\"23\":-0.1150979458141059,\"24\":-0.12068660643746244,\"25\":0.0864969554495802,\"26\":0.036176385653856655,\"27\":-0.08282056743843173,\"28\":0.14063850297697397,\"29\":-0.040237395184223555,\"30\":0.050615429593131686,\"31\":0.03343113235221773,\"32\":0.17242576135261276,\"33\":0.05127327213654172,\"34\":0.17091466766447158,\"35\":-0.14708899377963416,\"36\":0.0630662951196412,\"37\":-0.1711552591251485,\"38\":-0.07466144839999307,\"39\":-0.1955260548234677,\"40\":-0.07524492754586333,\"41\":-0.0011289415656004927,\"42\":0.2156327760030617,\"43\":0.16399971681432043,\"44\":0.023731073768874966,\"45\":-0.007606744321288145,\"46\":-0.10115751453707589,\"47\":-0.09782376680030659,\"48\":-0.037562093827229075,\"49\":0.16272068218463984,\"50\":0.2556489087170718,\"51\":-0.01206838200598207,\"52\":-0.14512545156039544,\"53\":0.006296601992158945,\"54\":-0.02626852907747634,\"55\":-0.15445445253781007,\"56\":0.057733944351613505,\"57\":0.09930929674856169,\"58\":0.12723305609299299}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.24706259467303684,\"1\":0.09751466120134795,\"2\":-0.03695889653580921,\"3\":0.22354932251076667,\"4\":0.014720387115400468,\"5\":-0.14588557175131367,\"6\":0.26641823059156666,\"7\":0.2982083522331111,\"8\":-0.02709310270547586,\"9\":0.06841770281408567,\"10\":0.036872745237842224,\"11\":-0.012223731773919552,\"12\":0.015487330290568146,\"13\":0.08879361526559273,\"14\":-0.13286240565068083,\"15\":0.0685571409939228,\"16\":-0.12593023443701423,\"17\":-0.0922086090062149,\"18\":0.08436185272062893,\"19\":-0.05045873423403831,\"20\":0.14997551982114202,\"21\":0.0015758659076376355,\"22\":0.18780000691646487,\"23\":0.0762590222867275,\"24\":0.09706205522072317,\"25\":-0.040102244647552694,\"26\":-0.13635373573149784,\"27\":-0.027345445841299065,\"28\":-0.07146973174130956,\"29\":-0.1294167519645524,\"30\":0.029621818731045566,\"31\":-0.003712862250235845,\"32\":-0.1965673120937878,\"33\":0.1024842340160247,\"34\":0.06933402583839386,\"35\":0.08865368723028737,\"36\":-0.17382501850909418,\"37\":0.07583615512723026,\"38\":-0.025278582430640996,\"39\":0.07421747579744008,\"40\":0.26021764291772376,\"41\":-0.20737498103939708,\"42\":0.0902143046027829,\"43\":0.37623722262389375,\"44\":0.0611165029626275,\"45\":0.010983905211104903,\"46\":0.13400115199908597,\"47\":0.0026139720945385376,\"48\":0.32466525191632317,\"49\":-0.04277739567922385,\"50\":-0.06497447893491096,\"51\":0.03934600058923769,\"52\":-0.04179763757205716,\"53\":-0.14365124659073195,\"54\":-0.21222345382871294,\"55\":0.1392966728416965,\"56\":0.04585207789204145,\"57\":-0.006605486381599401,\"58\":0.02792658876189761}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.04846595085317987,\"1\":0.20387709304644186,\"2\":0.20536579901621582,\"3\":-0.22626994878437917,\"4\":0.1709634308447612,\"5\":0.0003285258000968922,\"6\":-0.07597220590162684,\"7\":-0.1228043493463975,\"8\":-0.0931175509111238,\"9\":0.12805297664223664,\"10\":0.02146041371368995,\"11\":-0.13528790421679776,\"12\":0.09278313395648985,\"13\":0.15641480718004483,\"14\":-0.08720501938625376,\"15\":-0.08033556250951462,\"16\":-0.14057672203142765,\"17\":0.35028951494480054,\"18\":0.05036489420051958,\"19\":-0.09336215157187161,\"20\":0.12469540676278194,\"21\":-0.2006516163175821,\"22\":0.1353958840643196,\"23\":-0.07477469838639826,\"24\":-0.012619191525431405,\"25\":-0.05490238446017589,\"26\":-0.18085518311637272,\"27\":-0.17917800429094352,\"28\":0.013810426862674334,\"29\":0.03996432483078348,\"30\":0.173393788501786,\"31\":0.03372745307528659,\"32\":-0.09318601938763349,\"33\":0.055289387427733934,\"34\":0.034570448163571924,\"35\":-0.1396457164362276,\"36\":0.05590478013741858,\"37\":0.14940688916601608,\"38\":0.11229261245718114,\"39\":0.021728563320888728,\"40\":0.10911705901171599,\"41\":0.12961707604843462,\"42\":-0.013485614610640172,\"43\":0.07449378467395434,\"44\":0.10084422736061395,\"45\":0.0887925615450275,\"46\":0.09387098233522602,\"47\":-0.06743640355307774,\"48\":0.17748035369054727,\"49\":-0.059033777085872846,\"50\":0.07291669931390937,\"51\":-0.036517041996621334,\"52\":0.050277737531165136,\"53\":0.16859359057727402,\"54\":-0.07392099933433263,\"55\":-0.09501179591331026,\"56\":-0.02704274914203447,\"57\":0.028002184880803586,\"58\":-0.2317016544175261}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.07722168023779304,\"1\":0.06705388341510908,\"2\":0.023669810920014023,\"3\":0.052361635247202686,\"4\":0.06182493193990515,\"5\":-0.1713414335134938,\"6\":0.18005074435648988,\"7\":0.11159390760442503,\"8\":0.05228471587177578,\"9\":-0.04140817284232327,\"10\":-0.13619302649345918,\"11\":0.07158640367602086,\"12\":0.3641296006098528,\"13\":-0.1207281702183481,\"14\":-0.08735591863817851,\"15\":-0.009902792071634239,\"16\":-0.04611716631079469,\"17\":0.11572036029461602,\"18\":0.032831792321832615,\"19\":-0.19979180104359542,\"20\":0.32444017105727857,\"21\":0.07187203958180238,\"22\":-0.14030182703179245,\"23\":0.05919561040413169,\"24\":0.008047038432098337,\"25\":-0.12897390344576248,\"26\":0.0571581685935648,\"27\":0.11590441893978527,\"28\":0.04661834226300743,\"29\":-0.02079164023230836,\"30\":0.07268949332731398,\"31\":-0.08801313169071523,\"32\":-0.08716302184855962,\"33\":0.2749461807480741,\"34\":0.06479149525589036,\"35\":0.13245580321035258,\"36\":0.05565530663290444,\"37\":-0.1404285191533682,\"38\":-0.2024638684005541,\"39\":-0.003347074257867774,\"40\":-0.0046291715812271945,\"41\":0.06189570772629389,\"42\":0.1522421564779237,\"43\":0.18161553236546168,\"44\":0.0664331199826235,\"45\":-0.20351490678840198,\"46\":0.10084415908883904,\"47\":-0.013858155343402156,\"48\":0.15162119011017033,\"49\":-0.14626682469754937,\"50\":0.0034762394369867687,\"51\":-0.013591075788488213,\"52\":0.06095144328686201,\"53\":-0.036626562940812214,\"54\":-0.09825014733523658,\"55\":0.08667242694927921,\"56\":-0.07727610434831718,\"57\":0.03173223656706744,\"58\":0.013227409879306819}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.02487011345631667,\"1\":-0.32866752323914805,\"2\":0.17441509290401394,\"3\":0.108775701026786,\"4\":0.03625335668927838,\"5\":-0.0866066969892879,\"6\":-0.10761214590226265,\"7\":-0.18045414075792499,\"8\":-0.029818255175979243,\"9\":0.24563198591095053,\"10\":-0.12248345221916372,\"11\":0.2365083562861242,\"12\":-0.004674314676447425,\"13\":-0.11206032805757854,\"14\":-0.04714155751714922,\"15\":-0.018640168081349676,\"16\":-0.11146218701673247,\"17\":-0.02738403446775695,\"18\":0.02234945287048563,\"19\":-0.14158561421040872,\"20\":0.13786481622625352,\"21\":-0.13553489378578848,\"22\":-0.11336265078603713,\"23\":0.21634297564082144,\"24\":-0.3711024877868108,\"25\":-0.09236531844927436,\"26\":-0.0355860486999743,\"27\":0.04186451869470284,\"28\":0.05751565342543924,\"29\":-0.1107139893983895,\"30\":0.08143981363638156,\"31\":-0.16123186272187284,\"32\":0.007210314189377484,\"33\":0.05205694193928664,\"34\":0.18675097425055873,\"35\":-0.05027382704354674,\"36\":-0.1288037738074567,\"37\":-0.13183151014620367,\"38\":0.17872051547565185,\"39\":0.17735584533573323,\"40\":0.012000538172511885,\"41\":0.35488751038641425,\"42\":-0.17533091111975385,\"43\":-0.2046366266132933,\"44\":0.22267064730324124,\"45\":-0.05740938628364459,\"46\":-0.04484715077577121,\"47\":-0.14591407257642647,\"48\":0.07473612784555626,\"49\":0.05768647363820853,\"50\":0.16225768437703658,\"51\":-0.2770848437359641,\"52\":0.09032827007093332,\"53\":0.026938865888208468,\"54\":0.0995445833501733,\"55\":0.019940677380482563,\"56\":0.04825246668770191,\"57\":-0.08581702052153958,\"58\":-0.05572236691348164}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.1078178152361788,\"1\":-0.11925686720586176,\"2\":0.21892153639043505,\"3\":-0.016649019637800692,\"4\":-0.12587122251181207,\"5\":0.16607283516941684,\"6\":0.2632777396546263,\"7\":-0.12570771732786434,\"8\":0.14629440698707333,\"9\":-0.043359334606205675,\"10\":-0.2934714137606105,\"11\":0.0269317658493726,\"12\":0.12178652882443784,\"13\":-0.11495989339887934,\"14\":0.22471562546382082,\"15\":0.11950931300821367,\"16\":-0.11844828095956345,\"17\":0.08232973750794982,\"18\":-0.06882947897426389,\"19\":-0.04537743202338537,\"20\":0.033550710354119995,\"21\":-0.05503644194422383,\"22\":0.3616590498383087,\"23\":0.042204859947822686,\"24\":0.0899535871371334,\"25\":-0.11672791577628489,\"26\":-0.04571958175043123,\"27\":-0.0474928918307322,\"28\":-0.07627035369703014,\"29\":0.04201714237916874,\"30\":0.06501806445176668,\"31\":0.054611039677091605,\"32\":-0.16993607410240252,\"33\":-0.31271545205837964,\"34\":-0.12797433272343897,\"35\":0.14405989558363289,\"36\":-0.28286545994398027,\"37\":-0.20192091898347928,\"38\":0.23652935359704622,\"39\":-0.11864687891279821,\"40\":0.11661217288650068,\"41\":0.012084011841445128,\"42\":-0.038118398254963,\"43\":-0.21020016205831496,\"44\":-0.031005081151987853,\"45\":0.24893855997156447,\"46\":-0.2577052085305244,\"47\":0.019400460180509674,\"48\":0.011134919310894848,\"49\":-0.11841455815294992,\"50\":0.16504548130095334,\"51\":-0.13555622087608526,\"52\":0.14908982267855422,\"53\":0.09842603741524543,\"54\":0.06574806379409254,\"55\":0.08755151183458701,\"56\":-0.24032847526063214,\"57\":0.030475078676623527,\"58\":0.10534910091958019}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.25733345314711903,\"1\":-0.007427036431982032,\"2\":0.14246608389579368,\"3\":-0.22593742687607318,\"4\":-0.19438124827105363,\"5\":-0.09994090226949277,\"6\":-0.29933589711490527,\"7\":0.19241077388828984,\"8\":0.004905885014023824,\"9\":-0.030551323967003004,\"10\":0.12679513478911647,\"11\":0.1503070972805836,\"12\":-0.05080373630133431,\"13\":-0.04793728163738969,\"14\":0.07888965525856743,\"15\":-0.06438358770286527,\"16\":0.1021954270683315,\"17\":-0.22926476335105261,\"18\":-0.10772551171302305,\"19\":0.1547610542309044,\"20\":0.054305276899631286,\"21\":-0.02988444787918502,\"22\":0.045100778418975716,\"23\":-0.16593241884290136,\"24\":-0.270017952899743,\"25\":-0.018121112507707354,\"26\":0.05455133489701488,\"27\":-0.11473449528019518,\"28\":-0.13132149247556751,\"29\":0.0014543056624324732,\"30\":-0.09132053512745332,\"31\":-0.27030967581158305,\"32\":-0.06931846586113648,\"33\":-0.018326499368544566,\"34\":-0.12098335540660192,\"35\":-0.0846268992764775,\"36\":0.041368413613965864,\"37\":0.0585764560881287,\"38\":-0.026088010018673016,\"39\":-0.054185333457316104,\"40\":-0.14324127049906127,\"41\":-0.11981652477046807,\"42\":-0.21494562740852288,\"43\":-0.005395277324548113,\"44\":-0.22197065356659346,\"45\":0.08240755764895301,\"46\":-0.0004368806788508827,\"47\":-0.16736136443657534,\"48\":-0.09844916418413066,\"49\":0.08889217782177881,\"50\":0.00007896673134040141,\"51\":-0.09139838356838838,\"52\":0.022400648217016098,\"53\":0.08523799770620814,\"54\":0.0706054182278078,\"55\":0.15889482462384769,\"56\":0.06788275029096426,\"57\":-0.11162757720282501,\"58\":0.0015064456349157544}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.09769197762682046,\"1\":-0.1400997005139776,\"2\":-0.08829111264323013,\"3\":-0.14509251290647004,\"4\":0.17829260151811444,\"5\":-0.012550881775191017,\"6\":0.3657443245366882,\"7\":0.08008688667145324,\"8\":0.19084254665321976,\"9\":0.09453741265375813,\"10\":0.06461025003841275,\"11\":0.10225333765658355,\"12\":0.10976867765100103,\"13\":0.11001030291363487,\"14\":0.021853327198672164,\"15\":-0.06464106117007658,\"16\":-0.1588195115460626,\"17\":0.019820113000378472,\"18\":-0.19268080512429248,\"19\":0.056810918230585816,\"20\":0.14411931415462373,\"21\":0.2572836081798308,\"22\":-0.001005093485395488,\"23\":-0.26087084399572713,\"24\":-0.05041781184333782,\"25\":-0.10537520761042052,\"26\":-0.03468565251767637,\"27\":-0.14236102768166148,\"28\":-0.05442623207022857,\"29\":0.04273325579395789,\"30\":0.0157642138119065,\"31\":-0.020219120738341,\"32\":0.11624628632065238,\"33\":-0.023869808298248082,\"34\":-0.004521952665226693,\"35\":-0.005683363789473387,\"36\":-0.014434272844397678,\"37\":-0.13367133012555268,\"38\":-0.17128674116160214,\"39\":-0.13077248984348902,\"40\":0.12013946245484691,\"41\":-0.10878900176912185,\"42\":0.1812433976437426,\"43\":0.19394716286367802,\"44\":0.019418645289365582,\"45\":0.10093664737935829,\"46\":-0.1871896780647438,\"47\":-0.19006627019523342,\"48\":0.1049413202695915,\"49\":0.08589920316291595,\"50\":-0.012774429054867987,\"51\":0.134176122382898,\"52\":0.035554412906134536,\"53\":-0.09703425910180011,\"54\":-0.3057238982128515,\"55\":0.1366783349568832,\"56\":0.1442659807074122,\"57\":0.21430352666341204,\"58\":-0.10503095225405099}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.1648028106688439,\"1\":0.05689654665421535,\"2\":-0.09014676604510874,\"3\":-0.05867133135138198,\"4\":-0.08819284337318292,\"5\":-0.06339022995919648,\"6\":0.07111109503625908,\"7\":0.07913411854419942,\"8\":-0.19574880783458357,\"9\":-0.034836701985466456,\"10\":0.04397717896967828,\"11\":0.024548375867935488,\"12\":0.19533599983293426,\"13\":0.07545777325822739,\"14\":-0.055010941640566045,\"15\":0.0398464563748754,\"16\":-0.038891359926156596,\"17\":-0.0367327285321565,\"18\":-0.14057642510776178,\"19\":-0.045053101440450036,\"20\":-0.012465242179678265,\"21\":0.00548415953233811,\"22\":0.028056867941183658,\"23\":0.058558569358230284,\"24\":0.0150105287106575,\"25\":0.09325199932480376,\"26\":-0.155960880602356,\"27\":0.18779887155270128,\"28\":0.0056681262274185734,\"29\":-0.18717225631971007,\"30\":0.22139871328737562,\"31\":-0.15431452972654258,\"32\":-0.16812817961817314,\"33\":0.16357709031716527,\"34\":0.24847216782432766,\"35\":-0.08514074447292057,\"36\":0.14858301373086005,\"37\":0.08015458211988925,\"38\":-0.20552241448552624,\"39\":-0.08523906118409025,\"40\":0.08858778263030462,\"41\":-0.06359111239504217,\"42\":0.21874033456420708,\"43\":-0.14610850387755292,\"44\":-0.08103778260878265,\"45\":-0.11500716745477763,\"46\":-0.04642183400435642,\"47\":0.20072215377714697,\"48\":0.027329160809983884,\"49\":-0.04112536504732517,\"50\":0.010131786825755239,\"51\":-0.1306733638334701,\"52\":0.06488547700137837,\"53\":0.13184989843601835,\"54\":-0.10153592140691256,\"55\":0.031909007688491545,\"56\":0.05765766424821353,\"57\":-0.3113422082385935,\"58\":0.040593646328260215}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.02157842805717688,\"1\":-0.06349187731041578,\"2\":-0.10766124024990724,\"3\":-0.06183888120977385,\"4\":0.14101408348460326,\"5\":-0.09539088905143868,\"6\":-0.147418509788236,\"7\":0.015207062271635818,\"8\":-0.044245921065635734,\"9\":0.10185169934654122,\"10\":-0.34426813972170733,\"11\":-0.17699214240148303,\"12\":-0.046035095026748116,\"13\":-0.10850198233664109,\"14\":-0.022783848294731176,\"15\":0.120976186718414,\"16\":0.31614742530815926,\"17\":-0.22021549640753035,\"18\":-0.2530779244232293,\"19\":0.08732836386894594,\"20\":-0.10864755343153815,\"21\":-0.033503003161137586,\"22\":-0.020556637169193436,\"23\":-0.08231324654246985,\"24\":0.17164109936407979,\"25\":-0.0834182036743466,\"26\":0.08048386525412601,\"27\":0.06949357957232069,\"28\":0.024892023450391446,\"29\":0.022933219940841604,\"30\":0.0258285526869341,\"31\":0.03814388283824265,\"32\":0.1561568712331745,\"33\":0.01660206979174914,\"34\":-0.0016665737635287797,\"35\":-0.04546359560546986,\"36\":0.11461746712554623,\"37\":-0.023141758203655112,\"38\":0.13231759914112276,\"39\":0.11571848473457588,\"40\":-0.2310833757583047,\"41\":-0.2248974826462942,\"42\":-0.014124355334818319,\"43\":-0.17165355666527346,\"44\":0.07632816541319365,\"45\":0.061765278786853145,\"46\":0.1258998342986403,\"47\":0.13448753093111088,\"48\":-0.09839117756329775,\"49\":0.08047458408891109,\"50\":-0.1832124113776617,\"51\":0.015065629473034125,\"52\":0.07129106839124576,\"53\":-0.10411248766767929,\"54\":0.006508014562119656,\"55\":-0.10029412932877217,\"56\":0.11800226681958403,\"57\":0.09941690100001381,\"58\":-0.15595700817320793}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.043672957591186855,\"1\":0.24436495795128882,\"2\":-0.13986828074039406,\"3\":-0.02415585112763502,\"4\":0.1987736736281638,\"5\":-0.1841036589986805,\"6\":-0.02370208756773688,\"7\":0.0015413452783972514,\"8\":-0.0008572725830264398,\"9\":-0.0030087712397072774,\"10\":0.029258455125711128,\"11\":-0.019161715738164352,\"12\":0.057581001074892155,\"13\":0.13219897924711826,\"14\":-0.4453310661574591,\"15\":0.09439068558778954,\"16\":0.13102771725418236,\"17\":-0.03503974025768399,\"18\":0.10495777970001789,\"19\":0.27149711649973035,\"20\":-0.09811167020006271,\"21\":-0.0941364077035937,\"22\":0.000040457457624133645,\"23\":0.002646425425917125,\"24\":-0.1676611650590165,\"25\":-0.12416023490450978,\"26\":0.02072316101086969,\"27\":0.0858531635818901,\"28\":0.15410012184171154,\"29\":0.037854344957006646,\"30\":-0.03307922656575176,\"31\":0.057625997501188346,\"32\":-0.07055894419359789,\"33\":0.15014711008960058,\"34\":0.2709957186998232,\"35\":-0.029592338007220245,\"36\":0.09312679318181556,\"37\":-0.025676828581571703,\"38\":-0.24679415266062016,\"39\":-0.11084861650110209,\"40\":0.07655335853269456,\"41\":-0.11720796878498636,\"42\":-0.07369765354627963,\"43\":0.05060476503674645,\"44\":-0.11136871976965332,\"45\":0.1410267819263676,\"46\":-0.05265970373169154,\"47\":-0.10424104550697931,\"48\":0.07294876823671577,\"49\":0.18901330351006715,\"50\":-0.0595958241265558,\"51\":-0.16331418889014257,\"52\":0.19727760032722058,\"53\":-0.0689812114244729,\"54\":0.031694138153306156,\"55\":0.1447475434781611,\"56\":-0.07104532520159917,\"57\":-0.10272760705081871,\"58\":0.012829493111528511}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.20975182871377399,\"1\":0.12169562397045289,\"2\":0.16614646347583364,\"3\":-0.06988024082182577,\"4\":0.07078168513634746,\"5\":0.1670335027351535,\"6\":-0.02456242202712187,\"7\":-0.08197633333800246,\"8\":-0.03660719291286712,\"9\":0.115616531930906,\"10\":0.1666618459203291,\"11\":-0.0672403613103138,\"12\":0.04216704817841574,\"13\":0.09405447647840809,\"14\":-0.006982837459897041,\"15\":0.322808267348953,\"16\":-0.0979383505666536,\"17\":0.1975433764915538,\"18\":0.004323838278204817,\"19\":0.1964248913798657,\"20\":0.07720269051860454,\"21\":-0.23140616752228185,\"22\":0.0321124698743507,\"23\":-0.0939387224158782,\"24\":-0.24835343186278674,\"25\":-0.04321183911263315,\"26\":-0.024389271522562428,\"27\":-0.17658143892968686,\"28\":-0.020345414946928476,\"29\":-0.044478030008987965,\"30\":0.0470152237450258,\"31\":0.0357580098156228,\"32\":0.09891754446243739,\"33\":-0.0077483610973923915,\"34\":-0.0077029013317067,\"35\":0.07647745996544758,\"36\":0.06279824657868477,\"37\":-0.0003007316910823481,\"38\":0.022656422134008966,\"39\":0.011632002878787864,\"40\":0.019039601462430167,\"41\":0.20775207051182806,\"42\":-0.23142690887175388,\"43\":0.10080681405133501,\"44\":-0.15825730149364622,\"45\":-0.011965275857249704,\"46\":-0.1387984761103012,\"47\":-0.11707329173487856,\"48\":-0.041052224471601874,\"49\":0.12171471158842725,\"50\":0.12779715685950044,\"51\":0.07528835764989762,\"52\":-0.11191377207242063,\"53\":-0.25181201939460396,\"54\":0.04714798073287434,\"55\":-0.08602747651593164,\"56\":0.054240898358581355,\"57\":-0.056700589259442206,\"58\":0.05885490066454429}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.054789547156016284,\"1\":-0.019624277845674283,\"2\":0.022782533609310422,\"3\":0.10306600913200227,\"4\":-0.21048955215034865,\"5\":-0.044997373657282604,\"6\":-0.20724595097748735,\"7\":-0.12411625834673556,\"8\":-0.034432934097484366,\"9\":0.24478940064401894,\"10\":-0.24441651619461782,\"11\":-0.07858262196637208,\"12\":0.1619138544135747,\"13\":-0.23759808971255997,\"14\":0.04043245881288533,\"15\":-0.12299942765319655,\"16\":0.25141791868456714,\"17\":0.023464307863560723,\"18\":0.0020646950020868447,\"19\":-0.10803531532273557,\"20\":-0.00457466590345226,\"21\":0.17731321693759663,\"22\":-0.18731551928925955,\"23\":0.18868634596838504,\"24\":0.0009662385263325806,\"25\":0.15625947943741422,\"26\":0.09984731487313206,\"27\":-0.07474858629332534,\"28\":0.031138896434632555,\"29\":-0.18995360331096595,\"30\":-0.10727082735027207,\"31\":0.09250287894518718,\"32\":-0.09178704699044507,\"33\":0.16659500324731052,\"34\":0.05874196036455241,\"35\":0.10871296153373766,\"36\":-0.01940720870316138,\"37\":0.23127699160182982,\"38\":0.037872565548308146,\"39\":0.0881362745665515,\"40\":0.27883380312995765,\"41\":-0.014093289424370726,\"42\":-0.09516975363932564,\"43\":-0.02373525199444126,\"44\":0.02463497397607232,\"45\":0.21269540454318905,\"46\":0.14550017534976117,\"47\":0.0016592920286395167,\"48\":0.09692627647023845,\"49\":-0.05095667161689379,\"50\":0.054199165231194585,\"51\":0.2420260842957942,\"52\":0.17452552151242667,\"53\":0.13083249560708726,\"54\":-0.08260478299621585,\"55\":-0.06793378015239049,\"56\":-0.058136589530623374,\"57\":-0.02290123710140796,\"58\":0.13814345625940824}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.011878881217829916,\"1\":0.15835224018011002,\"2\":-0.10044259270508527,\"3\":0.11967002176245599,\"4\":-0.20098587622368327,\"5\":0.18414880864481345,\"6\":0.05635724198485353,\"7\":-0.10812892896970892,\"8\":-0.11359712044535941,\"9\":-0.05286789530820223,\"10\":0.009226272416927314,\"11\":0.1244763453778881,\"12\":0.10353969564565643,\"13\":-0.04757760550748075,\"14\":0.02193358202576642,\"15\":0.0032186576132118756,\"16\":-0.12328146061817381,\"17\":0.0800942024771989,\"18\":-0.164758067821006,\"19\":-0.07348774429503521,\"20\":-0.012567783158225852,\"21\":-0.06614294237772432,\"22\":-0.12481180098515145,\"23\":0.007511506790501071,\"24\":0.057525690102548106,\"25\":0.033109159691003864,\"26\":0.13560600273597967,\"27\":-0.07762500212315956,\"28\":-0.13145310956967915,\"29\":0.0688436239577288,\"30\":0.027750394776961316,\"31\":-0.04201422942939399,\"32\":0.002729325464659285,\"33\":-0.028028479976644087,\"34\":0.0726294221631201,\"35\":-0.005741382501912396,\"36\":-0.08854951223922532,\"37\":-0.31023825458492016,\"38\":-0.05280277481392314,\"39\":0.04348199745700726,\"40\":-0.10162119575059228,\"41\":-0.35370506878626246,\"42\":0.1110840843482725,\"43\":0.02670027476921734,\"44\":-0.04694883196357,\"45\":0.1607027622233795,\"46\":-0.10244017875577112,\"47\":-0.022552250320356165,\"48\":-0.0315064590913444,\"49\":-0.0025067777457540874,\"50\":0.13500549284698013,\"51\":0.10059846990860408,\"52\":0.05674551473512588,\"53\":-0.1295910118621495,\"54\":0.048560956290937526,\"55\":-0.01527241192697934,\"56\":0.10184922739449874,\"57\":-0.19263507641882918,\"58\":0.043276675703681676}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.03769443507426127,\"1\":0.12563796690666007,\"2\":0.36311387120650074,\"3\":0.12063063000751247,\"4\":0.12434047235302241,\"5\":-0.07900746612545816,\"6\":0.12116587224261333,\"7\":-0.12389680325984934,\"8\":-0.06211528391907796,\"9\":0.19805765565639707,\"10\":0.2341651519855948,\"11\":-0.05448119288500672,\"12\":-0.049324009385934266,\"13\":0.019568474682855514,\"14\":0.039362007957612875,\"15\":0.0482728766499154,\"16\":0.05577075382522916,\"17\":0.1547494023210225,\"18\":0.042535393552141934,\"19\":0.11053337359840318,\"20\":0.03084434327629907,\"21\":0.19979879766961187,\"22\":0.14139809263639821,\"23\":0.13810983299203997,\"24\":0.017382952060915485,\"25\":-0.19809058410286612,\"26\":-0.1735675423124773,\"27\":-0.05840011309380721,\"28\":-0.05998878259007314,\"29\":-0.05952498274013895,\"30\":-0.07851634259502939,\"31\":0.1850336288198006,\"32\":0.402401874324765,\"33\":0.08038005834844868,\"34\":-0.24951663532441953,\"35\":-0.09491829903639322,\"36\":-0.11294631425115097,\"37\":0.06926581574026591,\"38\":0.13715717668260005,\"39\":-0.1407935988751548,\"40\":-0.016680376091915004,\"41\":-0.1252254850295819,\"42\":0.0788537828163978,\"43\":0.08876683614247871,\"44\":-0.09570099283796682,\"45\":0.12884238643073354,\"46\":-0.11239982225925041,\"47\":0.20443635608679245,\"48\":0.04828227614234445,\"49\":-0.0037605357649347273,\"50\":0.0051944890281371,\"51\":-0.17339785370626742,\"52\":0.024212674471500238,\"53\":-0.02009741453859503,\"54\":-0.15073746680086636,\"55\":-0.2187267519958961,\"56\":-0.10201802233734471,\"57\":0.11277670553114755,\"58\":0.0022843508078760257}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.022478763625913008,\"1\":0.06922438235248579,\"2\":-0.17943506307017645,\"3\":0.17195158790107115,\"4\":0.058894562729161715,\"5\":-0.13495492930470138,\"6\":-0.08718985268647851,\"7\":-0.02743120775114876,\"8\":-0.03815699091750287,\"9\":0.11351977549322867,\"10\":-0.15776011141298457,\"11\":-0.1527504846536523,\"12\":0.02304619447154887,\"13\":-0.05404154690285447,\"14\":0.15097786378543626,\"15\":-0.0853892994381821,\"16\":0.07942051490155272,\"17\":0.09470442829155089,\"18\":-0.11112773843544826,\"19\":0.15666855218641845,\"20\":-0.06895431252684141,\"21\":0.06832126515320544,\"22\":-0.05489511080238165,\"23\":-0.06781309496300053,\"24\":-0.14874429516862264,\"25\":0.00914003616811002,\"26\":-0.046114624046060364,\"27\":0.11236742235655965,\"28\":0.14987365596048013,\"29\":-0.08162089524763838,\"30\":0.0797515579959547,\"31\":-0.06644614748571856,\"32\":-0.09465674918902335,\"33\":-0.23700293193608352,\"34\":0.10392134527346666,\"35\":-0.11447965372143384,\"36\":-0.06523854764358282,\"37\":-0.07942703471952176,\"38\":-0.04298347220890719,\"39\":0.022081320525881264,\"40\":0.07687531620865508,\"41\":-0.06209218455507528,\"42\":-0.01686084196470068,\"43\":-0.17135460385969983,\"44\":-0.3584077822767024,\"45\":0.18683035487448144,\"46\":0.13656550294051734,\"47\":0.017859018399991353,\"48\":-0.04848734444372256,\"49\":-0.1522394132444974,\"50\":0.19910635559450598,\"51\":0.012109897425726048,\"52\":0.023386778237284207,\"53\":-0.052710739905274154,\"54\":0.15015455540563172,\"55\":-0.14222915797610847,\"56\":0.05343267164161993,\"57\":0.0710228124534573,\"58\":0.02284600695598594}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.04949595767265131,\"1\":-0.017434481065899034,\"2\":0.15906915253953602,\"3\":0.11875842465649092,\"4\":0.22729522585679468,\"5\":0.0179956997535142,\"6\":-0.008972101883861655,\"7\":0.20982680233176215,\"8\":0.29360518164240024,\"9\":0.017853853921001514,\"10\":0.052013283082880814,\"11\":0.005290006511831842,\"12\":0.19132564508034738,\"13\":-0.23846886650563856,\"14\":-0.004956930823091924,\"15\":0.07341744244501922,\"16\":-0.3237478745718217,\"17\":0.03931417065107709,\"18\":0.0021186345879413426,\"19\":-0.13669066585578946,\"20\":-0.08876047956650639,\"21\":0.03173070651731927,\"22\":0.11771058874809337,\"23\":-0.17131210721211448,\"24\":-0.14183999863146815,\"25\":-0.07569889212609973,\"26\":-0.00448742756026459,\"27\":0.11961338964294235,\"28\":-0.044905317080422426,\"29\":0.06556598381032482,\"30\":0.16665524756344632,\"31\":-0.26867310804609223,\"32\":0.003693921010900807,\"33\":0.1595009940361007,\"34\":0.007422527614115571,\"35\":0.006413128813627673,\"36\":-0.15761855278853498,\"37\":0.011864654653269052,\"38\":-0.26946738072964954,\"39\":0.034676197268787734,\"40\":-0.07057075245563518,\"41\":-0.1286195747144404,\"42\":-0.04660799884341873,\"43\":-0.05408361372962231,\"44\":0.11744240092366687,\"45\":0.11393664260343933,\"46\":-0.06444613571730576,\"47\":-0.14369078730334897,\"48\":0.010652747680762653,\"49\":-0.24759114861055578,\"50\":0.14029827817793403,\"51\":0.10961234389921536,\"52\":0.17693409535244353,\"53\":0.006061396189988744,\"54\":0.108419029938738,\"55\":-0.058110105136616436,\"56\":-0.1400974847049731,\"57\":0.09840891395349706,\"58\":0.032817573739767784}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.05261584069574888,\"1\":0.08655563815606906,\"2\":-0.14877084945631597,\"3\":-0.04407720642327499,\"4\":0.09161174698671123,\"5\":-0.043438996317558466,\"6\":-0.12498267753508398,\"7\":0.23590704529780424,\"8\":0.16188273388288701,\"9\":-0.014187745456528605,\"10\":0.07347956388770244,\"11\":-0.04662735904221409,\"12\":0.013569905546245795,\"13\":-0.05294500801278588,\"14\":-0.16523648802356106,\"15\":-0.08894351443643492,\"16\":-0.1924051205892618,\"17\":0.11822317245839677,\"18\":-0.32511848704121793,\"19\":0.12519777194348297,\"20\":-0.12261182363113693,\"21\":0.21295640238701027,\"22\":0.15281320891438743,\"23\":0.12217523263775339,\"24\":-0.1145714094691844,\"25\":0.16179458647094053,\"26\":-0.16406164478365368,\"27\":0.01849595107880184,\"28\":0.07934354888760452,\"29\":-0.0032191669877324907,\"30\":0.045017647902895086,\"31\":-0.07424009877184455,\"32\":0.00047094066399379017,\"33\":-0.017279865336163963,\"34\":-0.09155919333555568,\"35\":0.10178296798886222,\"36\":-0.05006858075334343,\"37\":0.022465678512739586,\"38\":0.028236691282430802,\"39\":0.12465514772667517,\"40\":-0.016990309072767003,\"41\":0.10398565575800622,\"42\":-0.01046981850116019,\"43\":0.053257104856846,\"44\":0.029668488337094966,\"45\":-0.026177899602836216,\"46\":-0.10216766330383922,\"47\":-0.15375019462016337,\"48\":-0.2569987471772116,\"49\":-0.09405920905704923,\"50\":-0.018663660998119662,\"51\":0.043244270482663306,\"52\":-0.007385482719495137,\"53\":-0.04815849974353108,\"54\":-0.11057066481862775,\"55\":-0.023642412241779362,\"56\":-0.06730947971003272,\"57\":0.03554395792156318,\"58\":0.2706159509734124}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.00569845580064504,\"1\":-0.08770912043619437,\"2\":0.11151130060409938,\"3\":-0.15644631877598247,\"4\":-0.11942706831612564,\"5\":0.3653337819010815,\"6\":-0.0532433180911217,\"7\":-0.13483953459084913,\"8\":0.14938762811504458,\"9\":-0.020780482098760683,\"10\":-0.17199125732881,\"11\":0.31369282403790866,\"12\":-0.019235122456683754,\"13\":-0.37797722129216993,\"14\":0.2165897329391028,\"15\":0.006220076821261394,\"16\":-0.20791999382713572,\"17\":-0.1235658017260911,\"18\":0.07529870474055948,\"19\":-0.2711841579296988,\"20\":0.0690619397469343,\"21\":-0.11669777286182799,\"22\":-0.1391789841127734,\"23\":0.12645139363398783,\"24\":0.03004963256809372,\"25\":-0.16401217519448608,\"26\":0.1258044442105372,\"27\":0.2407044480515829,\"28\":-0.38888097554988876,\"29\":-0.14055774620940592,\"30\":-0.0888472754648661,\"31\":0.159927971856384,\"32\":0.24324256540606617,\"33\":0.02579585395302499,\"34\":0.04539327236880957,\"35\":0.2164488309628098,\"36\":-0.0555990479257566,\"37\":-0.12367427243840338,\"38\":0.11334721561959737,\"39\":-0.06883112128168654,\"40\":-0.03520474167841836,\"41\":0.03316407141591068,\"42\":0.02509737302345682,\"43\":0.2577871502361891,\"44\":0.0782828135614033,\"45\":-0.08613725311851911,\"46\":-0.07735029207580393,\"47\":0.015231033110890555,\"48\":0.0017299287306507562,\"49\":0.0883246957288547,\"50\":-0.2653435601203723,\"51\":-0.0846764693993631,\"52\":-0.24474836947708747,\"53\":-0.026662438025423157,\"54\":0.06561934711704176,\"55\":0.15076058210799792,\"56\":-0.06281067627583894,\"57\":0.060536584749536104,\"58\":0.0652298936144155}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.11915088068301813,\"1\":0.037411274416785455,\"2\":0.0620627789792067,\"3\":-0.019439497952010693,\"4\":-0.2637746676948333,\"5\":0.11566730633549079,\"6\":-0.03818498141474553,\"7\":0.0761949656976353,\"8\":-0.1874689737691149,\"9\":0.10170892195849941,\"10\":0.023860965810805886,\"11\":-0.08708600240273348,\"12\":-0.08731578003447084,\"13\":-0.026319836695508997,\"14\":-0.11128813335583466,\"15\":0.13957504959842773,\"16\":0.018511600118168048,\"17\":0.033728126564538885,\"18\":0.0603979410569108,\"19\":-0.08568736385949541,\"20\":0.16110921688199953,\"21\":0.08592816318200353,\"22\":0.20390676810691286,\"23\":-0.09620079775101525,\"24\":0.15150072418890817,\"25\":0.07323694976336162,\"26\":0.2651024033130653,\"27\":0.011321300992547122,\"28\":-0.02105162049549323,\"29\":-0.14176230362640554,\"30\":0.1564372522506326,\"31\":-0.06268628469468565,\"32\":-0.2892447694552895,\"33\":0.13787676018046408,\"34\":0.06203920625691015,\"35\":-0.053382821913243325,\"36\":0.050712113569041574,\"37\":0.008354816089675832,\"38\":0.04696016504141425,\"39\":0.047400206133876764,\"40\":0.0679531941431432,\"41\":-0.011360048178068547,\"42\":-0.018504221693486884,\"43\":0.06701126675980426,\"44\":-0.09066951168801891,\"45\":-0.09135417558928291,\"46\":-0.046460375361982616,\"47\":-0.03144029601887911,\"48\":0.039615186980137156,\"49\":0.01857930569383879,\"50\":-0.18386369813779488,\"51\":-0.06484772737484373,\"52\":-0.05415506341122631,\"53\":0.09290900929394491,\"54\":-0.06354128164307148,\"55\":-0.22752035585165215,\"56\":-0.001199212510345618,\"57\":0.059688237890598184,\"58\":0.11707311912538683}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.008656350528007232,\"1\":-0.12030197911410978,\"2\":-0.23281048634145962,\"3\":0.15927310794502644,\"4\":-0.2039777824608123,\"5\":0.01423705432503681,\"6\":0.34409885883682734,\"7\":0.0280863145653917,\"8\":0.12707317997192114,\"9\":-0.0168197408609811,\"10\":0.10665720808913455,\"11\":-0.013843623298059124,\"12\":-0.04484521385740006,\"13\":0.02111533297392333,\"14\":-0.034685310258612045,\"15\":0.07926380951865034,\"16\":-0.15029356827903786,\"17\":-0.0744904753453947,\"18\":0.15461248025151397,\"19\":0.1981880004920202,\"20\":0.02627045777179546,\"21\":-0.01595311864914334,\"22\":0.12137106193028167,\"23\":-0.15499375787476943,\"24\":0.025977598003329758,\"25\":0.002689857784541141,\"26\":0.07655915568887357,\"27\":0.02493455575694429,\"28\":-0.29680673533382584,\"29\":0.3030959805838546,\"30\":0.06149759316460997,\"31\":0.0833520324592303,\"32\":0.04414015741841856,\"33\":-0.11346920464929319,\"34\":0.07043992115790212,\"35\":0.0594719313512821,\"36\":0.007560526549640306,\"37\":-0.07764072149813361,\"38\":-0.19460628996212914,\"39\":0.007125462076094644,\"40\":-0.1381487356277867,\"41\":0.08125318194909771,\"42\":-0.06489279246867936,\"43\":0.06423962519203671,\"44\":-0.09063520873034421,\"45\":-0.14045985887137374,\"46\":0.01799603778449124,\"47\":0.09854981709340943,\"48\":0.2333835592696047,\"49\":0.16895593912978973,\"50\":-0.23629191002533012,\"51\":-0.10389826055598095,\"52\":0.12098236256187064,\"53\":-0.038943774614436176,\"54\":0.12143269335528363,\"55\":0.09282913398892155,\"56\":0.07753464460794209,\"57\":0.11348692973946815,\"58\":0.01656881632892868}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.0986104284608211,\"1\":0.13595187605203124,\"2\":0.11497775706775598,\"3\":-0.251230697808649,\"4\":0.08717460751759958,\"5\":-0.06966031981139098,\"6\":-0.07373251768887298,\"7\":0.10279478362194229,\"8\":0.1540396277952989,\"9\":-0.047903255546278826,\"10\":0.21252558043309128,\"11\":0.1146456411129509,\"12\":0.014835007721183176,\"13\":0.17472148873037854,\"14\":0.06993173046595151,\"15\":0.08503153728909951,\"16\":-0.051454620313485924,\"17\":-0.1284520981070157,\"18\":0.13115425335449027,\"19\":0.24204790849850136,\"20\":-0.28189356270981103,\"21\":0.1973628853153974,\"22\":0.011201280805531984,\"23\":0.03893704575291529,\"24\":-0.030375509168569684,\"25\":-0.1304392380067813,\"26\":-0.3327035945682897,\"27\":0.05026340068425382,\"28\":-0.16745802409834762,\"29\":0.045613102602693405,\"30\":-0.04827379633852363,\"31\":0.05451416929704888,\"32\":-0.18553232226801925,\"33\":0.0009356840100446658,\"34\":-0.142881283042355,\"35\":-0.19488736101587248,\"36\":0.0902930242168389,\"37\":-0.02266595200629684,\"38\":-0.2354962953115715,\"39\":0.026222496589677118,\"40\":-0.1401700086182734,\"41\":-0.17084585121714926,\"42\":0.006493129124590507,\"43\":0.08445609530737344,\"44\":0.018772962245905772,\"45\":-0.042989381784209545,\"46\":-0.10187200342907705,\"47\":-0.11733374095767948,\"48\":-0.059514029352316956,\"49\":0.11104395270696252,\"50\":0.11926996874437905,\"51\":0.13028373244656416,\"52\":0.025632515063465124,\"53\":0.16228172530106622,\"54\":-0.07786398079560915,\"55\":0.018822826934060066,\"56\":-0.02178229977518424,\"57\":0.09059391772008339,\"58\":-0.32989928615769104}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.19100674284914237,\"1\":-0.030192522709370024,\"2\":-0.07848615324710786,\"3\":-0.13143724996346365,\"4\":0.1909482269886776,\"5\":-0.16718201316893355,\"6\":-0.04869585935644681,\"7\":-0.011925376633720943,\"8\":0.04898334858564408,\"9\":-0.16694665475113868,\"10\":-0.008172995290663726,\"11\":0.059351846835578155,\"12\":-0.01519180977174187,\"13\":-0.011982288608190804,\"14\":-0.209737691575388,\"15\":-0.07831747185163013,\"16\":0.07749189100841358,\"17\":0.06380156774909518,\"18\":-0.12874660458683942,\"19\":-0.051092688169947345,\"20\":0.09324202310536318,\"21\":-0.3932364623511797,\"22\":0.055944322889585424,\"23\":-0.033118083502935936,\"24\":-0.04587936212239943,\"25\":0.07262579286736252,\"26\":0.14555523187425626,\"27\":0.011129137002795723,\"28\":0.16269170136480313,\"29\":-0.18127337614637076,\"30\":-0.016018337439535336,\"31\":-0.07196182681032436,\"32\":-0.1669507070003957,\"33\":-0.16634995656540524,\"34\":0.018962425033150817,\"35\":-0.1074027481494304,\"36\":0.027827947321648106,\"37\":0.05201701054616499,\"38\":0.14606682972010376,\"39\":-0.19549013759214542,\"40\":0.00030573600823402547,\"41\":0.07503575553759963,\"42\":-0.34413574142907094,\"43\":0.07635219643405972,\"44\":-0.06778148194005226,\"45\":-0.24549147338900665,\"46\":0.1432083524571986,\"47\":-0.0019508583131691093,\"48\":-0.13160846416590907,\"49\":0.021701915649128288,\"50\":-0.004450460751162528,\"51\":-0.09709211421882165,\"52\":0.09198038890080248,\"53\":0.10765416871564616,\"54\":0.04007786887325076,\"55\":0.10175591477408093,\"56\":0.27419966865224527,\"57\":-0.0637643652980814,\"58\":0.027006212821166522}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.2085902798085716,\"1\":0.16769724599536875,\"2\":-0.35028502986232796,\"3\":-0.20341753710497593,\"4\":0.37071306071802107,\"5\":-0.06979308487365006,\"6\":-0.1466236208318597,\"7\":0.09954488857588868,\"8\":-0.18621477416161836,\"9\":-0.01278026313036525,\"10\":0.29941116210546903,\"11\":-0.20308244238594547,\"12\":-0.047685116501063524,\"13\":0.25967689624012047,\"14\":-0.15858512201386363,\"15\":0.13878792377188615,\"16\":0.17806573421806737,\"17\":-0.05701812859596376,\"18\":-0.169931843671813,\"19\":-0.07648470082429824,\"20\":-0.10513466197755295,\"21\":-0.19874538864635877,\"22\":0.17775261506356088,\"23\":-0.11449185393408019,\"24\":0.10823787831126862,\"25\":0.07145907582180845,\"26\":0.11725831802962054,\"27\":-0.05749746099143698,\"28\":0.0268011742914071,\"29\":-0.15930068954559023,\"30\":-0.03353950624381555,\"31\":0.08706692638018072,\"32\":-0.11849999082060889,\"33\":0.02638771285697318,\"34\":-0.12511387701829838,\"35\":0.14057931005408594,\"36\":-0.2970258574923842,\"37\":0.03614237671766536,\"38\":0.24175616573282846,\"39\":-0.026255004099334508,\"40\":-0.042813892667416045,\"41\":0.08285319378226533,\"42\":-0.12632213692510452,\"43\":-0.14305440871906178,\"44\":0.11587742155521868,\"45\":-0.02653258484023198,\"46\":-0.0023316670712971513,\"47\":-0.0317407152807779,\"48\":0.15597119798536363,\"49\":-0.13279688260497863,\"50\":0.12032722285684949,\"51\":-0.07934896748980076,\"52\":-0.10748341242387763,\"53\":0.24496378130064134,\"54\":0.07046598731616602,\"55\":-0.0752465392955477,\"56\":-0.07857845197949215,\"57\":0.04603516611915461,\"58\":-0.2053727301749682}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.04831354227232325,\"1\":-0.14133528064430567,\"2\":0.010705503905820693,\"3\":-0.2023012542725509,\"4\":-0.052460406066471704,\"5\":0.20528191732651144,\"6\":-0.1609781671083767,\"7\":0.2022373077586672,\"8\":-0.09241863289886522,\"9\":0.024341277520665828,\"10\":-0.033085541384490796,\"11\":-0.20148946671980544,\"12\":-0.16186654625095062,\"13\":0.09847188054870537,\"14\":-0.07376953819008632,\"15\":-0.1478884455788805,\"16\":0.10418579504358325,\"17\":0.09828457829760548,\"18\":-0.04315370689476679,\"19\":0.17686226330090787,\"20\":0.12764366009010072,\"21\":-0.3233991327571471,\"22\":0.09884907158963022,\"23\":0.002708106362134053,\"24\":-0.15585337505600969,\"25\":-0.0552928573765635,\"26\":0.13826997323872076,\"27\":-0.0817430589859,\"28\":0.1616039895498707,\"29\":0.03936549514270644,\"30\":-0.04234255281262083,\"31\":0.0279247397307424,\"32\":-0.12236013165223876,\"33\":-0.04182178052103743,\"34\":0.08093815216060637,\"35\":-0.12810591265094054,\"36\":0.15956588045265957,\"37\":-0.051186037156041427,\"38\":0.1462556302594977,\"39\":-0.12120167836149993,\"40\":-0.08299910978460937,\"41\":0.0948746916138153,\"42\":0.09819573366738767,\"43\":0.04971835305379073,\"44\":-0.03683772868274639,\"45\":-0.09580111084229229,\"46\":-0.029523811454254017,\"47\":-0.07840378613273462,\"48\":0.012678565969227057,\"49\":-0.00012877942708906516,\"50\":-0.08490023662507222,\"51\":0.0461999840915831,\"52\":-0.0534984267323783,\"53\":-0.21114466194885184,\"54\":-0.08232535642684763,\"55\":-0.032180765344373,\"56\":0.09859018143055732,\"57\":-0.07569142276280649,\"58\":0.12991175979112368}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.1708684595631505,\"1\":0.04293028713891415,\"2\":-0.0071723491070520475,\"3\":-0.04423150541710322,\"4\":-0.16488812860432273,\"5\":0.12065238845893868,\"6\":0.2132759752881824,\"7\":0.20222645239315892,\"8\":-0.0028129857169253048,\"9\":-0.007434933739805467,\"10\":-0.2532452976763949,\"11\":0.14172188493439458,\"12\":0.004755031708799993,\"13\":0.22162210728215997,\"14\":-0.09016177146032103,\"15\":0.20445442845063438,\"16\":0.0392541231718823,\"17\":0.04296586222038494,\"18\":-0.05254578399338151,\"19\":-0.05593688567628323,\"20\":0.05227145995609886,\"21\":-0.1468752272103814,\"22\":0.13072391511231354,\"23\":0.12815176596637515,\"24\":0.2192177766666295,\"25\":0.005861623512209853,\"26\":-0.16492961147198762,\"27\":0.2026135597565996,\"28\":0.003456298073046997,\"29\":0.20492777742073406,\"30\":0.16765074482869982,\"31\":0.004094664345658699,\"32\":0.03781402292426443,\"33\":-0.1690839858757511,\"34\":0.010022627628518122,\"35\":0.034864310438819025,\"36\":0.06672685653458642,\"37\":0.044058130537656226,\"38\":0.021266034597616678,\"39\":0.15798052161824033,\"40\":-0.0038012163064543984,\"41\":-0.2371908344525049,\"42\":-0.08406931518238726,\"43\":-0.11146801166465414,\"44\":0.1719338752110168,\"45\":0.18531797565881045,\"46\":-0.19283304447185454,\"47\":0.14086964052354212,\"48\":0.020036193648229447,\"49\":0.2545687009716282,\"50\":0.05184263452974394,\"51\":-0.08802795143096256,\"52\":0.029515521992401778,\"53\":-0.1304878933438711,\"54\":0.09666175451358953,\"55\":0.14831493339983431,\"56\":-0.1227135754360975,\"57\":0.054742057032853515,\"58\":0.010387538568548424}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.12395811566718515,\"1\":0.02021015785121648,\"2\":0.0008217312023692748,\"3\":-0.171379659115448,\"4\":-0.09295496338932879,\"5\":-0.03931400411453673,\"6\":-0.21031316601151348,\"7\":-0.15993423619005798,\"8\":-0.1048330353463269,\"9\":0.1282716429033191,\"10\":-0.024618834272345274,\"11\":-0.16803368015479692,\"12\":0.05776304527638124,\"13\":-0.02869588673088357,\"14\":0.10816509635211781,\"15\":-0.17401331149425,\"16\":-0.03392510478753104,\"17\":-0.10279529840798525,\"18\":0.15762927527506224,\"19\":0.2576831211972578,\"20\":-0.050127006685630866,\"21\":-0.2959652600231991,\"22\":-0.01794715648586092,\"23\":-0.011109172107180125,\"24\":-0.02109198471691956,\"25\":0.13586074300547266,\"26\":0.013530513214708051,\"27\":-0.11260371036511946,\"28\":-0.022390000827688227,\"29\":0.09772472669735925,\"30\":-0.04335653352139396,\"31\":-0.04000945210092513,\"32\":-0.22008495826203098,\"33\":0.1986137202867719,\"34\":0.2225964987524871,\"35\":0.09300330070880722,\"36\":-0.0756278415672844,\"37\":-0.10054625050672783,\"38\":-0.10655076672647866,\"39\":-0.06956906740698203,\"40\":-0.13695792498200687,\"41\":-0.030467044463053008,\"42\":-0.04363203744858201,\"43\":-0.13785777487338863,\"44\":0.13509394471586517,\"45\":-0.19473678202611786,\"46\":0.24698184428859735,\"47\":0.17512460657282686,\"48\":-0.017546303214604497,\"49\":0.07632385537422719,\"50\":-0.06544306619054041,\"51\":-0.04905070149193222,\"52\":0.06721501513153477,\"53\":0.2519673699455012,\"54\":-0.10230418816564248,\"55\":0.004078234630410922,\"56\":0.10164348717087816,\"57\":-0.14535398686654724,\"58\":0.05259200432366727}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.009079858776772495,\"1\":-0.08170667859221269,\"2\":0.10260961558652663,\"3\":-0.28311234902493426,\"4\":-0.2297748321386766,\"5\":-0.12269894238532368,\"6\":0.1384374952993827,\"7\":-0.037208077728632556,\"8\":-0.2551235391024287,\"9\":-0.024317531544853038,\"10\":-0.07543616053355652,\"11\":0.14579511787485622,\"12\":0.08600069608261625,\"13\":0.08660862746697189,\"14\":0.16544777129677543,\"15\":-0.10009416903191509,\"16\":0.1661338521088908,\"17\":0.0710017579509859,\"18\":-0.021786267549385167,\"19\":-0.04614420968862766,\"20\":0.047664449128780415,\"21\":0.16930932828133058,\"22\":-0.11475853036232035,\"23\":-0.0984069853572868,\"24\":-0.07873063069519592,\"25\":-0.01205114662331416,\"26\":-0.22706945140912518,\"27\":-0.171459936764608,\"28\":-0.053364298200578544,\"29\":0.0037262968594904177,\"30\":0.009175911699255856,\"31\":0.011883320679977027,\"32\":-0.005571848220765543,\"33\":-0.25971457533395464,\"34\":-0.13682457171347584,\"35\":-0.1307725819745552,\"36\":-0.019564198250289124,\"37\":0.006776669765050624,\"38\":0.2739083034966309,\"39\":-0.16488124583892794,\"40\":0.025070812558921192,\"41\":-0.1385750503938866,\"42\":-0.08046195689980369,\"43\":0.12064278548576203,\"44\":0.1573716266485048,\"45\":0.09931486842761651,\"46\":-0.22854103479833968,\"47\":-0.0030121484267848935,\"48\":0.20688126122288453,\"49\":0.14766159641039095,\"50\":-0.10921044663268333,\"51\":0.09457470855187144,\"52\":0.25856293892635107,\"53\":0.105568125684227,\"54\":0.01542940177943318,\"55\":0.015312898667499589,\"56\":-0.09126621375675538,\"57\":-0.06108545459725546,\"58\":-0.023464302411171832}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.19863897166641634,\"1\":0.05100621704508267,\"2\":-0.10734136305033831,\"3\":-0.046900299557322736,\"4\":-0.03745102562441922,\"5\":-0.18921766844227464,\"6\":-0.11702583578693514,\"7\":0.0863358353338125,\"8\":-0.1237044141522913,\"9\":0.08163908041541103,\"10\":-0.1511269198626774,\"11\":-0.06129123555854054,\"12\":0.059987423174861595,\"13\":-0.21978347658426797,\"14\":-0.24537807828590744,\"15\":0.028265674631613506,\"16\":0.08485946879935603,\"17\":-0.029903067634381622,\"18\":0.24227071254023066,\"19\":-0.21247385388383644,\"20\":0.4300750077172875,\"21\":0.012801340464978337,\"22\":0.0953407282276404,\"23\":-0.11317349956958808,\"24\":-0.25138769488237195,\"25\":0.07226609814821874,\"26\":-0.026107589352794468,\"27\":0.13734714125370803,\"28\":0.05137023429630078,\"29\":-0.17165870222771953,\"30\":-0.1214179321428562,\"31\":-0.13684479875631037,\"32\":-0.2005811481577716,\"33\":0.16205127696379906,\"34\":-0.04508092681028791,\"35\":0.03521076776605202,\"36\":0.29615079530170624,\"37\":0.12640649138158666,\"38\":-0.14405624018241917,\"39\":-0.09689825623720455,\"40\":-0.23018746644939247,\"41\":-0.008612568204998084,\"42\":0.06816050224798001,\"43\":-0.1653853903979658,\"44\":-0.3245039436353602,\"45\":-0.011773869877296993,\"46\":-0.14283520474581898,\"47\":0.2330642926719595,\"48\":0.17763955327112846,\"49\":0.03379518731042467,\"50\":0.03052208098835695,\"51\":0.009775183592544805,\"52\":-0.12315269288987314,\"53\":0.12119143287687831,\"54\":0.09509383848153427,\"55\":-0.23881287293549233,\"56\":-0.06361178929296601,\"57\":-0.1387528888529085,\"58\":-0.20765460934730323}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.1898297319758022,\"1\":-0.14883006751076974,\"2\":-0.271143205228929,\"3\":-0.21979030241449324,\"4\":-0.03698291590381272,\"5\":0.1448552075771971,\"6\":0.0429922971086371,\"7\":-0.1326947846502322,\"8\":-0.16706261430629973,\"9\":0.2338152164947718,\"10\":-0.1670754608716335,\"11\":-0.09331803173352793,\"12\":-0.06858483632877482,\"13\":0.05852024047658634,\"14\":-0.024896798984556653,\"15\":-0.09013031619550144,\"16\":-0.06438075097510948,\"17\":0.10841918755287089,\"18\":0.12244277085433017,\"19\":-0.19174091678993643,\"20\":0.10329907837130271,\"21\":0.16538494852786698,\"22\":-0.09845653154521117,\"23\":0.1414903893783711,\"24\":-0.027651174433341703,\"25\":0.058441303970928275,\"26\":0.1705535179462565,\"27\":0.18767197133045757,\"28\":-0.016752830442869713,\"29\":-0.2837531516155767,\"30\":-0.060972136406389384,\"31\":0.10048450214733065,\"32\":-0.03223748793145789,\"33\":-0.11501238967279367,\"34\":-0.06700295001124348,\"35\":-0.0814804405818706,\"36\":0.054296031731205494,\"37\":-0.38648882284869857,\"38\":-0.024235210119900836,\"39\":-0.11585220870588668,\"40\":-0.023850084839777408,\"41\":-0.18733667495582157,\"42\":0.012092302751810571,\"43\":-0.04913963361679271,\"44\":0.26725693554142455,\"45\":0.19581827411540054,\"46\":0.014169530861095438,\"47\":0.07680418475738546,\"48\":-0.02904699829351504,\"49\":0.173152351291223,\"50\":-0.13354873214475108,\"51\":0.13049865102065322,\"52\":0.27279736311726216,\"53\":0.018886317442773037,\"54\":0.16598301645669541,\"55\":0.0728075152831311,\"56\":-0.10643954547128125,\"57\":-0.20488357650262565,\"58\":0.3560362379185738}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.09560277627958139,\"1\":-0.09170097330407695,\"2\":0.015365594601108094,\"3\":-0.08620088169800195,\"4\":-0.2145978808643475,\"5\":-0.08827767476839041,\"6\":0.13767325551279125,\"7\":-0.4196328240908843,\"8\":0.26448389611157075,\"9\":-0.09078564961203212,\"10\":-0.45755093774306765,\"11\":0.11152845515577842,\"12\":0.007370333794503388,\"13\":-0.27853503897777815,\"14\":0.1769385236838308,\"15\":0.03774374683541787,\"16\":-0.2835344878991271,\"17\":0.033227614800508204,\"18\":0.07263621211484433,\"19\":-0.22524210628199484,\"20\":0.11598622696295538,\"21\":0.011824162294883145,\"22\":-0.2520318070054574,\"23\":0.20398047744541342,\"24\":0.11715215797788275,\"25\":-0.1230101122065836,\"26\":-0.1350137981789052,\"27\":-0.24613706171421315,\"28\":-0.13024350077144542,\"29\":0.13311592967679056,\"30\":-0.07121176342360473,\"31\":0.02761114444324623,\"32\":0.12442149511925814,\"33\":0.06873530960022613,\"34\":-0.15588759755435616,\"35\":-0.04010027336690106,\"36\":0.1957916037126528,\"37\":-0.06259730485381267,\"38\":0.1340477044493676,\"39\":-0.05350064138971777,\"40\":-0.2806022024206797,\"41\":0.06577696697010889,\"42\":0.08993336352453954,\"43\":-0.08807417120154686,\"44\":0.0056773813843045,\"45\":-0.036931081742070146,\"46\":-0.1311096793862985,\"47\":0.1779355628447066,\"48\":0.020899555591842686,\"49\":-0.200407393655619,\"50\":0.17083301236716325,\"51\":0.33382004480979477,\"52\":-0.22963153704284936,\"53\":0.06370542622127855,\"54\":0.19047334370973554,\"55\":0.07150262957957583,\"56\":0.29105900048228966,\"57\":0.186713033536819,\"58\":0.08530082810357204}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.20688174852579944,\"1\":-0.17241046943931734,\"2\":-0.055471437554131434,\"3\":-0.20332274988673885,\"4\":-0.274156841740988,\"5\":0.04928570311801819,\"6\":0.09886561072211399,\"7\":-0.13530509300640217,\"8\":0.20174913789176824,\"9\":-0.19657865659633184,\"10\":-0.13207085075292235,\"11\":-0.10637634113675484,\"12\":0.20103002842718132,\"13\":-0.19849464086026075,\"14\":0.13348136466956403,\"15\":-0.029605087580256123,\"16\":-0.14055863162191157,\"17\":0.11974571081909693,\"18\":-0.23358080417275703,\"19\":-0.02854071903096744,\"20\":-0.05533569404016853,\"21\":-0.19463356480922325,\"22\":0.17561853438385114,\"23\":-0.04004511350269294,\"24\":0.02802383902012358,\"25\":-0.06177503078379898,\"26\":0.043898736489203116,\"27\":-0.1324678321775558,\"28\":0.017096250558977417,\"29\":0.17401896606351688,\"30\":-0.30323076082428413,\"31\":-0.1486026352249212,\"32\":-0.0029042140314992533,\"33\":0.2001663169406606,\"34\":-0.14113210715858143,\"35\":0.061550334397301745,\"36\":0.005309229125238288,\"37\":-0.029434723216495876,\"38\":-0.1828671872577199,\"39\":0.0038709413965114293,\"40\":0.027900799751471694,\"41\":0.08418183809620425,\"42\":-0.2163840087266997,\"43\":0.021807926972521315,\"44\":0.0932227889502879,\"45\":-0.08454073252969534,\"46\":-0.019671571139833453,\"47\":-0.06543668322752572,\"48\":-0.062494596992476475,\"49\":-0.10292029295665325,\"50\":-0.051130664120184265,\"51\":-0.16471092648202582,\"52\":0.1940010127853205,\"53\":0.19127976883108197,\"54\":0.1225208805447118,\"55\":-0.180302180196848,\"56\":0.283179718964309,\"57\":0.21761430637907386,\"58\":-0.10435784358097226}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.05790112433830579,\"1\":0.1831623608372511,\"2\":0.14666504900084112,\"3\":-0.19745921253819565,\"4\":0.0953983376986902,\"5\":-0.259882952540345,\"6\":-0.05550146507176039,\"7\":-0.011929298488132274,\"8\":0.2644197916076395,\"9\":-0.03638827737609929,\"10\":0.018745707218972084,\"11\":-0.23479625707162902,\"12\":-0.04834391413034586,\"13\":-0.15158789069150372,\"14\":-0.010355621000882333,\"15\":-0.16399368867968175,\"16\":0.0815158079051313,\"17\":0.05324738598724686,\"18\":-0.07333645167780159,\"19\":-0.062741758273572,\"20\":0.10256776904589346,\"21\":-0.11836780501489388,\"22\":0.1505520754348691,\"23\":-0.17517436511663165,\"24\":-0.018021302463914184,\"25\":0.04066077878375824,\"26\":-0.1377078439232991,\"27\":-0.026706450157419712,\"28\":0.08042716430645752,\"29\":0.18274728629604703,\"30\":-0.24701076774664307,\"31\":0.06988558349096136,\"32\":0.1371422455027777,\"33\":-0.15827366335647572,\"34\":-0.09085538694050097,\"35\":0.030054223811727118,\"36\":-0.03370037490794572,\"37\":-0.23713876124525746,\"38\":0.11684362777074452,\"39\":-0.08834783554516112,\"40\":0.008658047576130647,\"41\":-0.0708581820008024,\"42\":-0.17974527170941912,\"43\":0.008684116546157989,\"44\":-0.03198928952299698,\"45\":-0.06886228556299777,\"46\":-0.034575750698149665,\"47\":0.007269435720182884,\"48\":-0.005164360525814293,\"49\":0.16697528717859136,\"50\":-0.25383625892819217,\"51\":-0.12276130049731389,\"52\":-0.040720811464498866,\"53\":0.16518648441947073,\"54\":-0.1175360139972267,\"55\":-0.17522684185892062,\"56\":0.018769148005303264,\"57\":0.02333300327854233,\"58\":0.1321583203383574}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.10852496720796337,\"1\":0.18601373832126936,\"2\":-0.0970941414589979,\"3\":-0.08359835341629397,\"4\":-0.10225764617065976,\"5\":0.2200322363244005,\"6\":0.0891989801481349,\"7\":-0.03443558763947192,\"8\":-0.1360847542034255,\"9\":-0.2604753453598247,\"10\":-0.03235325590092934,\"11\":0.17845022111402928,\"12\":-0.10719346685923677,\"13\":-0.00801068413909953,\"14\":-0.25525033518238227,\"15\":-0.0696081315776383,\"16\":-0.3127039427913108,\"17\":-0.10548242635652853,\"18\":-0.027477985546498714,\"19\":0.15994073557897343,\"20\":0.1563252002382061,\"21\":-0.2142807453872266,\"22\":-0.11020450295393099,\"23\":-0.05123134383706066,\"24\":-0.08708872239361067,\"25\":0.01077519613026408,\"26\":0.12574779077965487,\"27\":0.12540691812420884,\"28\":-0.10141388984842287,\"29\":0.18795393126287444,\"30\":-0.09201447778725834,\"31\":-0.07396235481962876,\"32\":-0.02973607638117633,\"33\":-0.10235913753987044,\"34\":0.043713961727793994,\"35\":0.019277243913782688,\"36\":0.110595810982578,\"37\":0.24710571094444725,\"38\":0.00021103203875611263,\"39\":-0.13482067063992198,\"40\":0.05179847517345165,\"41\":-0.2994257277450204,\"42\":-0.057077219565696335,\"43\":-0.06530839954556082,\"44\":0.1640754414771822,\"45\":0.059948597868168,\"46\":0.0718192316411951,\"47\":0.04341532534238135,\"48\":0.1779291438962319,\"49\":0.010794954949317233,\"50\":0.07257157423572333,\"51\":0.017850363013986927,\"52\":0.081052611281516,\"53\":-0.023629548355249615,\"54\":-0.010394149188848324,\"55\":-0.07729822805032815,\"56\":0.11255689316271972,\"57\":0.004778080934147127,\"58\":-0.021658936077011245}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":0.28780127233230646,\"1\":-0.150598270344448,\"2\":-0.09931456217020863,\"3\":-0.1712346788871504,\"4\":0.2218780329675101,\"5\":0.19173115797342055,\"6\":-0.29858515683257564,\"7\":0.0976260223898467,\"8\":-0.20804590244022436,\"9\":0.08971569939927622,\"10\":-0.18727127995750767,\"11\":0.007709107728520943,\"12\":0.2613573606849366,\"13\":0.11417776141120886,\"14\":-0.039935192450703476,\"15\":-0.060268610111541034,\"16\":-0.04157853599683486,\"17\":-0.014032929471369013,\"18\":0.20779138440095246,\"19\":-0.12739255795188162,\"20\":0.14692033491543857,\"21\":0.13607642348297552,\"22\":-0.10674284482458729,\"23\":0.02415711307173056,\"24\":0.1542899631325753,\"25\":-0.055838880404031295,\"26\":0.12134440628054446,\"27\":-0.248271734010997,\"28\":0.18444721060722064,\"29\":-0.09857099994696895,\"30\":-0.06708635651106062,\"31\":0.008286107836283587,\"32\":0.19728614023627222,\"33\":-0.08367394447268818,\"34\":0.21077416773740568,\"35\":0.16902257891131467,\"36\":-0.09779963844799668,\"37\":0.17235151821863656,\"38\":-0.0484064268736835,\"39\":0.2411602927040945,\"40\":0.05680096246172867,\"41\":-0.022998977924160918,\"42\":-0.10775154363516692,\"43\":0.1040409049296284,\"44\":0.08704911628750797,\"45\":-0.11254820922612574,\"46\":0.11860306446111635,\"47\":0.011534261619596213,\"48\":-0.0006709525934250934,\"49\":-0.15915397205751583,\"50\":-0.03661123287510292,\"51\":0.051971398881889085,\"52\":-0.0023946812287954046,\"53\":0.18667773047464017,\"54\":0.041501098624011586,\"55\":0.08875849331660429,\"56\":0.14147805102219388,\"57\":0.09506403847190661,\"58\":0.10499490568529234}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.06283060408931887,\"1\":0.15100316079734985,\"2\":-0.06938986894353676,\"3\":-0.12484666529549222,\"4\":0.2067278082576521,\"5\":0.004085670554812176,\"6\":0.007841813192115589,\"7\":0.36855477384925167,\"8\":0.2028818695963936,\"9\":-0.07482885374156935,\"10\":0.06440151783022452,\"11\":0.0036859690724982005,\"12\":0.10339007239851553,\"13\":0.20663388966185106,\"14\":-0.1589994254039784,\"15\":-0.15007624101797098,\"16\":0.018758221541487995,\"17\":0.005590196270135305,\"18\":-0.07982581919099682,\"19\":0.07880654634395975,\"20\":-0.03043793716350912,\"21\":-0.1640123134113393,\"22\":0.05399940133489805,\"23\":0.10350774076313991,\"24\":-0.18383736860845806,\"25\":-0.11101547362368222,\"26\":-0.04267616709648246,\"27\":-0.18563988695271114,\"28\":-0.01786829147035404,\"29\":-0.08860903771112082,\"30\":0.022426074114572144,\"31\":-0.11818799707832423,\"32\":-0.07884472145807528,\"33\":-0.12288983568777231,\"34\":-0.09435673304389335,\"35\":-0.030588812973457797,\"36\":-0.10953186526006824,\"37\":-0.0063634851152002915,\"38\":-0.0386340752824913,\"39\":-0.09597391934321833,\"40\":-0.01041239326244285,\"41\":0.14180907620995956,\"42\":-0.08800875407900238,\"43\":0.2525171847766867,\"44\":0.2502219025312105,\"45\":-0.20563478101112936,\"46\":-0.18168335046443426,\"47\":-0.012376514189525444,\"48\":0.12293646094319043,\"49\":0.04561815728905593,\"50\":0.12469812997946186,\"51\":-0.07431539940903455,\"52\":-0.003083274007754257,\"53\":0.01522342348010914,\"54\":0.09164915414780507,\"55\":-0.007562759439673787,\"56\":0.11752551543336806,\"57\":0.2342035514336233,\"58\":-0.10749375957197832}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.11284071889694793,\"1\":0.026105193502648585,\"2\":-0.06796217849356885,\"3\":-0.07807931146012623,\"4\":0.07017390498727191,\"5\":-0.1283738359884413,\"6\":0.24922873699950956,\"7\":-0.057371154304642166,\"8\":0.2546979755104917,\"9\":0.06300313535016663,\"10\":-0.1876665721805783,\"11\":0.16833100274312018,\"12\":0.08169590786508713,\"13\":0.0017238701953735793,\"14\":-0.11562445699489882,\"15\":-0.07177650148435621,\"16\":0.10225765784793926,\"17\":-0.09520576704123482,\"18\":-0.16575388275468225,\"19\":-0.09911192504569641,\"20\":0.20696161241408995,\"21\":0.08073165490718973,\"22\":-0.1229671090991901,\"23\":0.20157385265282346,\"24\":-0.13459768375649475,\"25\":-0.22005113720353306,\"26\":-0.009949265905522028,\"27\":-0.1924681642307644,\"28\":-0.14504233714105672,\"29\":-0.16679150046452232,\"30\":-0.049832201839352476,\"31\":0.007959909751445058,\"32\":-0.07493315269163527,\"33\":0.31880143521512855,\"34\":-0.06358843492453407,\"35\":-0.1211110864680189,\"36\":-0.036963101132426485,\"37\":-0.08026302902753332,\"38\":-0.12664723597378966,\"39\":-0.3102384811212467,\"40\":-0.18410495693960585,\"41\":0.06092517841522322,\"42\":0.03868643072061712,\"43\":0.03910323578966644,\"44\":0.009128887506804406,\"45\":-0.16255734786855794,\"46\":0.014447381274401589,\"47\":0.055300254827855944,\"48\":-0.11746838690004155,\"49\":-0.12925017505680234,\"50\":0.21905804473656262,\"51\":-0.17928555490402043,\"52\":0.07761569836107436,\"53\":-0.09041404630504887,\"54\":-0.04033180599231727,\"55\":0.020041695613355226,\"56\":0.010573524792049253,\"57\":-0.030984194560317466,\"58\":-0.035130302221245926}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.20368456284840952,\"1\":-0.09633227031596145,\"2\":-0.13601382136850657,\"3\":-0.06651872702476305,\"4\":0.12352006439824463,\"5\":-0.048296421453522996,\"6\":-0.016706883317985408,\"7\":0.006408248000304105,\"8\":-0.06721218667095383,\"9\":-0.03657439974085104,\"10\":-0.05197311194603761,\"11\":0.020104616956355237,\"12\":-0.058063595171041475,\"13\":0.044300134901733776,\"14\":0.0016253999531014919,\"15\":-0.11965054979344966,\"16\":0.03905594807961153,\"17\":-0.13868420722074964,\"18\":0.05431593749092591,\"19\":0.045587441367401844,\"20\":-0.043969208594468345,\"21\":-0.12325680262176177,\"22\":-0.08487503638534898,\"23\":-0.06520781903381283,\"24\":0.17385321544627072,\"25\":0.1265586038612272,\"26\":-0.07181064159267243,\"27\":0.2541829340354409,\"28\":0.007159987795384122,\"29\":0.2200931520242806,\"30\":-0.08254168372198181,\"31\":0.0004834341510320644,\"32\":-0.10534968865947586,\"33\":0.11354277855222362,\"34\":0.05484621678267246,\"35\":-0.09587430227351905,\"36\":0.08726303669583771,\"37\":0.03229498249621399,\"38\":-0.04796393399618737,\"39\":-0.16431422647225483,\"40\":-0.10923347722225223,\"41\":0.2068702974079067,\"42\":0.1325031321705419,\"43\":0.11873757665709206,\"44\":-0.05958016952541504,\"45\":-0.033576819682558455,\"46\":-0.22841880917986332,\"47\":0.06989276957376067,\"48\":-0.07638415658008782,\"49\":-0.04936099870988821,\"50\":-0.11015126376356703,\"51\":-0.04789175970137861,\"52\":-0.008406299149439939,\"53\":-0.016567521259872795,\"54\":0.023423254539412,\"55\":0.07783931958610443,\"56\":-0.09985700089861207,\"57\":0.011978892780118119,\"58\":0.1278202787300316}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.02078136403473632,\"1\":0.0844965575500309,\"2\":-0.14117305909463657,\"3\":-0.026261556593126442,\"4\":0.15711428375110315,\"5\":0.04348097026430058,\"6\":-0.043532201427637376,\"7\":0.1684728068968971,\"8\":-0.1848129473101105,\"9\":0.24678996112870355,\"10\":-0.07593593753228918,\"11\":-0.1438490944858524,\"12\":-0.03972898978554777,\"13\":-0.07275558635927479,\"14\":0.12408247010907167,\"15\":-0.09661205070827246,\"16\":0.1206052771481575,\"17\":0.01660138559081184,\"18\":0.13260649595884721,\"19\":0.0066445813263382395,\"20\":0.08633361681959473,\"21\":0.02409105907213186,\"22\":-0.03148091535493572,\"23\":-0.11910629083394103,\"24\":0.10109708195961144,\"25\":0.12104449396669789,\"26\":0.04030195871258254,\"27\":0.027706581114075715,\"28\":-0.09478458517624838,\"29\":-0.12614285914168066,\"30\":-0.022211555289925307,\"31\":0.0900239749224769,\"32\":-0.07160649068412497,\"33\":-0.02729624641793961,\"34\":0.1669447568834429,\"35\":-0.056098272976572265,\"36\":0.06068695340899268,\"37\":-0.09471753922004313,\"38\":-0.20818190504083445,\"39\":0.014583648398571741,\"40\":0.058219715311282255,\"41\":-0.19900618990169341,\"42\":-0.035674874815262055,\"43\":0.10610130871671351,\"44\":-0.19215902594917023,\"45\":0.16699048451318746,\"46\":0.11591566395242985,\"47\":-0.20037306612660974,\"48\":-0.03712860775106485,\"49\":-0.04262837870763416,\"50\":0.041979964139125484,\"51\":0.05120830847160079,\"52\":0.16128385636989573,\"53\":-0.07890330146901642,\"54\":-0.11047411610147301,\"55\":0.029225112699329647,\"56\":0.0355352348056504,\"57\":0.05404784637475183,\"58\":-0.20722849766437}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.20748522972660802,\"1\":-0.20365572492409229,\"2\":-0.018644815526260454,\"3\":0.01637370152663402,\"4\":-0.03549335803537069,\"5\":-0.11815165203298834,\"6\":0.13045779679873343,\"7\":0.08798081741809176,\"8\":-0.027256778281654823,\"9\":0.056875725555643665,\"10\":-0.10866473834575834,\"11\":0.03433272758411116,\"12\":0.135667842811708,\"13\":0.003616040544777451,\"14\":-0.13529019128888778,\"15\":-0.18873834497783135,\"16\":-0.06471721012375785,\"17\":0.22419923215116472,\"18\":-0.1984059675599228,\"19\":0.1127702839790929,\"20\":-0.10793852121319839,\"21\":-0.15917010010555954,\"22\":-0.17537723474831804,\"23\":0.0591805665329432,\"24\":0.1036414951044969,\"25\":-0.15122319539567813,\"26\":0.07674700574441662,\"27\":0.10777684112855052,\"28\":0.16932796464114525,\"29\":-0.12301794304082549,\"30\":-0.2395472026502981,\"31\":-0.06064658183114775,\"32\":0.012134304851233641,\"33\":-0.01083686770451756,\"34\":0.10835992585674438,\"35\":-0.0973467280025202,\"36\":0.06439463255657812,\"37\":-0.1381748192454523,\"38\":-0.2321578794755209,\"39\":-0.09379527118835053,\"40\":-0.0394016584225301,\"41\":-0.332299708720334,\"42\":-0.06273187132228689,\"43\":-0.15147283692494495,\"44\":-0.24504389529291237,\"45\":-0.08819077698251447,\"46\":0.002732928862702176,\"47\":0.09131877266823726,\"48\":-0.18263516799330978,\"49\":0.05350239323475176,\"50\":0.10577277072935705,\"51\":0.2647009432183866,\"52\":-0.14480685227792905,\"53\":0.22705470101235628,\"54\":0.1514703821405039,\"55\":0.019202452113612344,\"56\":0.13460871023080542,\"57\":-0.0714995564934837,\"58\":0.048659937154957415}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.03799508552691133,\"1\":0.06133671539172343,\"2\":-0.005985572553236002,\"3\":0.11596549540454623,\"4\":0.06035177956210116,\"5\":0.09369858805234618,\"6\":0.0851749594915799,\"7\":0.09751474821676336,\"8\":0.1123179941679837,\"9\":0.21048081176922898,\"10\":0.24116874183078618,\"11\":-0.0553608733164692,\"12\":-0.013386950660562778,\"13\":-0.12285476369861176,\"14\":-0.1741919947995389,\"15\":0.0681253401918226,\"16\":-0.1266222455372552,\"17\":-0.17176866913531189,\"18\":-0.05978733745146551,\"19\":-0.04202252965320109,\"20\":0.16259078379996605,\"21\":0.05733299375783014,\"22\":0.3687287452987136,\"23\":-0.07448962352269646,\"24\":-0.04444256515640287,\"25\":-0.13086040959678966,\"26\":-0.21581035440699872,\"27\":-0.05619528941489537,\"28\":0.08947749812681677,\"29\":-0.08262768721111251,\"30\":0.17141973614853936,\"31\":0.15818271199037823,\"32\":0.015153124405604767,\"33\":-0.1802373632107703,\"34\":0.14016951488871962,\"35\":-0.1894877551417901,\"36\":-0.18361229296647041,\"37\":-0.03408873993693819,\"38\":0.07319386969002087,\"39\":0.14063786300959205,\"40\":0.06108587895206021,\"41\":-0.047368186222200334,\"42\":-0.027270431528935893,\"43\":0.0037101948180891155,\"44\":-0.0045446810871932536,\"45\":0.018032940699788624,\"46\":-0.011541508967757812,\"47\":0.13091249301397084,\"48\":-0.03798439156320599,\"49\":-0.0885779021127767,\"50\":0.05703183106578752,\"51\":0.10615054841829892,\"52\":0.03410431116224171,\"53\":-0.033938256071478975,\"54\":0.008012082698024527,\"55\":-0.08628439521675788,\"56\":-0.21336820854746677,\"57\":-0.13038979018391492,\"58\":0.045403792173152206}},{\"sx\":1,\"sy\":1,\"depth\":59,\"w\":{\"0\":-0.051209651183752695,\"1\":0.04057649948079998,\"2\":0.04067058257116301,\"3\":-0.2485220262961975,\"4\":-0.09503074668631134,\"5\":0.17818204323870088,\"6\":0.21913980141468592,\"7\":0.04046487480271401,\"8\":-0.22433344080545448,\"9\":-0.050981080345828336,\"10\":0.1862495524255591,\"11\":0.09427065533622853,\"12\":-0.02883082023049503,\"13\":0.038121057192378335,\"14\":-0.1044839689568157,\"15\":-0.06929728918126547,\"16\":-0.0059636080675041555,\"17\":-0.14699891473838542,\"18\":0.2308750343598695,\"19\":0.010787049309001014,\"20\":0.14684802118092788,\"21\":-0.032416290565991025,\"22\":-0.12502506618153444,\"23\":-0.082675013142353,\"24\":0.06935389578453448,\"25\":0.27595324238768915,\"26\":0.08905075021384896,\"27\":0.21734497064691866,\"28\":-0.1193340424208646,\"29\":0.0022787951664239785,\"30\":-0.08252588453166469,\"31\":-0.029361876552764052,\"32\":-0.12072107281638467,\"33\":-0.03220292154239821,\"34\":0.3467457436394743,\"35\":-0.10371663332846691,\"36\":0.018449208520331765,\"37\":-0.04486644958680496,\"38\":0.029240170705131078,\"39\":-0.09869160119793231,\"40\":-0.10460872647128847,\"41\":0.3122033743181877,\"42\":-0.17399631927106646,\"43\":-0.0016166936155365642,\"44\":0.06359833683916574,\"45\":-0.014731156795496154,\"46\":0.019470053923223304,\"47\":0.00789023032948516,\"48\":0.08645777647029713,\"49\":0.13953484021637172,\"50\":-0.07474096649760892,\"51\":-0.036711734760925055,\"52\":0.00457303682237945,\"53\":0.018451348926752056,\"54\":-0.042078700537195465,\"55\":-0.03308731747275802,\"56\":-0.26420057623243326,\"57\":-0.05645352614436499,\"58\":-0.040036017055401225}}],\"biases\":{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.10187224797727137,\"1\":0.09805224949925184,\"2\":0.10132306807370414,\"3\":0.10021117730207314,\"4\":0.09939175955508293,\"5\":0.09990522865251995,\"6\":0.10708157760057713,\"7\":0.09764319013700798,\"8\":0.09534131791295074,\"9\":0.09344452087500049,\"10\":0.09955671377795056,\"11\":0.10026429229272495,\"12\":0.10596114592098733,\"13\":0.10368749050894221,\"14\":0.09936228924812716,\"15\":0.09628154100913917,\"16\":0.0983750032642885,\"17\":0.09618722615223847,\"18\":0.09541198286965469,\"19\":0.10355657144933773,\"20\":0.09849636114422328,\"21\":0.09701776985131987,\"22\":0.09991311086800397,\"23\":0.09831513017422801,\"24\":0.10293368074470959,\"25\":0.1002588280469901,\"26\":0.10366325259679061,\"27\":0.09652520013263341,\"28\":0.09822526734572005,\"29\":0.1000636726041779,\"30\":0.1005468959946613,\"31\":0.09903691656302414,\"32\":0.09641790067881058,\"33\":0.10379434458929596,\"34\":0.09865913282626171,\"35\":0.10046656453095719,\"36\":0.10150185914400399,\"37\":0.09913120148560751,\"38\":0.11016180420023125,\"39\":0.10099633156701002,\"40\":0.10091869201067384,\"41\":0.10017249563803624,\"42\":0.10592271376287563,\"43\":0.09633174977665984,\"44\":0.09796717967271415,\"45\":0.09812420459629408,\"46\":0.10010323278062885,\"47\":0.09871651806995405,\"48\":0.09952125316161545,\"49\":0.09547674708077954}}},{\"out_depth\":50,\"out_sx\":1,\"out_sy\":1,\"layer_type\":\"relu\"},{\"out_depth\":50,\"out_sx\":1,\"out_sy\":1,\"layer_type\":\"fc\",\"num_inputs\":50,\"l1_decay_mul\":0,\"l2_decay_mul\":1,\"filters\":[{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.1853224108500528,\"1\":-0.10189515768088596,\"2\":-0.23260049711729816,\"3\":0.047101092234823394,\"4\":0.04562466486640148,\"5\":-0.19622988998786073,\"6\":-0.06976328609173012,\"7\":0.08870739292302078,\"8\":-0.20605070548979865,\"9\":0.08491815809090199,\"10\":-0.042987892365029534,\"11\":-0.02397600749372326,\"12\":0.21979024886203252,\"13\":-0.16810919606753988,\"14\":0.05990545680743998,\"15\":0.06370890798281922,\"16\":0.026333904173268825,\"17\":-0.016627790956274008,\"18\":-0.037714932157707354,\"19\":-0.006058444364060447,\"20\":-0.11438043254877597,\"21\":0.031773901087319506,\"22\":0.05727332369319286,\"23\":-0.019752045055980685,\"24\":0.02435947519634555,\"25\":0.13855848039579582,\"26\":0.0850253983546395,\"27\":0.05166779949617176,\"28\":0.1092021545686871,\"29\":0.11841955828613068,\"30\":0.21024904529929708,\"31\":-0.20001032498424445,\"32\":-0.0471968909169336,\"33\":-0.1565368346087251,\"34\":-0.1983713294276049,\"35\":0.1534086105730239,\"36\":-0.29403050161748046,\"37\":0.034360600616952224,\"38\":0.2526137383415127,\"39\":-0.05642247522290523,\"40\":0.07764084410983069,\"41\":-0.12699151489295785,\"42\":-0.06943998756687474,\"43\":-0.2640871144570824,\"44\":0.22025058356920588,\"45\":-0.11533072545625235,\"46\":0.020666690495518857,\"47\":-0.10531858686433726,\"48\":0.10963310155970664,\"49\":0.08094967599697342}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.005270728024249398,\"1\":0.21952627747052303,\"2\":0.251001955043352,\"3\":0.03942857653163809,\"4\":-0.02580922759134732,\"5\":0.1100325673232806,\"6\":-0.01712509293687904,\"7\":-0.19503845794215688,\"8\":0.08366947675405596,\"9\":-0.23375680710651456,\"10\":0.1087026988456427,\"11\":-0.4498849740811225,\"12\":0.06755741386993819,\"13\":-0.008909963396811764,\"14\":0.118716395322724,\"15\":-0.11841630683531837,\"16\":0.06383834827924893,\"17\":-0.06546023674988306,\"18\":0.16118668278070947,\"19\":0.27396394656177947,\"20\":-0.11127481942598016,\"21\":0.08702700064790775,\"22\":-0.03164591314545078,\"23\":0.17742650532598067,\"24\":0.09318180069346603,\"25\":-0.007258669621670441,\"26\":-0.17322853954808315,\"27\":-0.04311620472479752,\"28\":0.0009122506740288762,\"29\":0.11515608858610181,\"30\":0.3256103615970619,\"31\":0.3832267600064975,\"32\":-0.047052896302207554,\"33\":-0.12642114682775735,\"34\":-0.1802114781478725,\"35\":-0.04110418850502628,\"36\":0.033894502453931025,\"37\":0.09205834991013587,\"38\":-0.4716355009623336,\"39\":0.048567264753909156,\"40\":0.09753893629838101,\"41\":-0.056170493311090204,\"42\":-0.003651237077931018,\"43\":0.13086907351215493,\"44\":0.049572985135579846,\"45\":0.004759111745443655,\"46\":0.10781299784821964,\"47\":-0.032912709789122,\"48\":0.11114182506976956,\"49\":-0.15758071748744462}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.12266652302427537,\"1\":0.13872058359253855,\"2\":-0.05000264106520195,\"3\":-0.037612564712102795,\"4\":-0.08377572090715364,\"5\":0.1854458156385547,\"6\":0.2648258724807126,\"7\":0.15536090796601848,\"8\":0.16883548077701055,\"9\":0.08534251890788909,\"10\":0.05049569705946387,\"11\":-0.11072836849191973,\"12\":0.3797528812587946,\"13\":-0.15594908734739218,\"14\":-0.3004473042677693,\"15\":0.009680298262331464,\"16\":0.1280381514726686,\"17\":0.07467467239629283,\"18\":-0.16615595990457702,\"19\":-0.025010364530774102,\"20\":-0.03504098997418965,\"21\":-0.020303676890186785,\"22\":-0.09528626862785694,\"23\":0.27769434923071507,\"24\":0.09622004383922325,\"25\":-0.2074010167763192,\"26\":0.18130209454029525,\"27\":0.07802606975869165,\"28\":0.05063165804623928,\"29\":0.10656405846631144,\"30\":0.05910941776909742,\"31\":-0.09718688242220992,\"32\":-0.08627163834656194,\"33\":-0.22271724292619927,\"34\":0.1530269942752308,\"35\":-0.04144586671177827,\"36\":0.04064987749797599,\"37\":-0.202514593495371,\"38\":-0.10180549395965362,\"39\":0.2645625228940753,\"40\":0.028999111536993142,\"41\":0.17289910293226574,\"42\":0.0018762069405149672,\"43\":0.05484836786338026,\"44\":-0.21783893621877118,\"45\":-0.11332127553648146,\"46\":-0.006633169476067014,\"47\":0.1334123388432863,\"48\":-0.07784845089855763,\"49\":-0.025224641230753117}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.37527314253667704,\"1\":-0.02118571244304691,\"2\":-0.29172265071921394,\"3\":-0.07104159733172469,\"4\":0.1639982718723655,\"5\":0.011442894055134979,\"6\":-0.22483317766586314,\"7\":-0.3607891901622349,\"8\":0.1743747607583561,\"9\":0.11572057368784704,\"10\":0.19800399810253055,\"11\":-0.19364187977493458,\"12\":0.03241297085046713,\"13\":0.15049346302589833,\"14\":0.23553614663035274,\"15\":-0.09282899330204132,\"16\":0.13093445011976756,\"17\":0.24521343009931412,\"18\":-0.3058095249550411,\"19\":-0.06300923966920319,\"20\":0.04995450041954091,\"21\":-0.01997670375394692,\"22\":0.06956668398260243,\"23\":-0.025430342150813388,\"24\":0.1592444676090631,\"25\":-0.08113159275758636,\"26\":0.0903421333110435,\"27\":-0.011115986808046551,\"28\":-0.13327909788081405,\"29\":0.005815591864328969,\"30\":-0.2851662573026841,\"31\":0.011943806311964435,\"32\":0.005865852043693093,\"33\":-0.14297096430152814,\"34\":0.04516768955579257,\"35\":0.2953764084393752,\"36\":-0.016623869284373875,\"37\":0.06065650594264304,\"38\":-0.15454959722146197,\"39\":-0.01825135086078505,\"40\":0.09585461323682906,\"41\":0.132106679706091,\"42\":-0.0920549584290864,\"43\":-0.07308441134716559,\"44\":0.18335696587163092,\"45\":0.1327559815943036,\"46\":0.05317145300500458,\"47\":0.08989070168981315,\"48\":-0.15616486661173012,\"49\":0.15767421355524314}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.12877424351202854,\"1\":0.014726451631462521,\"2\":-0.10444777407836933,\"3\":0.02878499807043288,\"4\":0.0975898739580641,\"5\":0.17242162840097916,\"6\":-0.030689888063702726,\"7\":-0.006233922699917402,\"8\":0.07443544910584929,\"9\":-0.12345261159353112,\"10\":-0.032039667186962106,\"11\":0.1752638653358199,\"12\":-0.07350367552947219,\"13\":-0.1560095342210096,\"14\":0.0745801663884592,\"15\":0.32610226971571954,\"16\":0.03362165488379989,\"17\":0.10570441939575886,\"18\":-0.09396061986463003,\"19\":-0.16310144864085907,\"20\":0.10335874293358692,\"21\":-0.10114979386648194,\"22\":-0.14939968623508443,\"23\":0.024685820062493497,\"24\":0.0972043994509521,\"25\":-0.13056090608299967,\"26\":-0.05041650946544552,\"27\":-0.03396136490086666,\"28\":-0.08371156113815527,\"29\":-0.006832590226289177,\"30\":0.011135039858100344,\"31\":0.15126248534957704,\"32\":0.09299218920514883,\"33\":0.11763374349783474,\"34\":0.1384479406844877,\"35\":0.08455922299388799,\"36\":0.04616786210604362,\"37\":0.020717657676816496,\"38\":0.10541741655582833,\"39\":-0.20993560649053514,\"40\":0.09839479435491447,\"41\":-0.1552579817660865,\"42\":0.09066342302982752,\"43\":0.1191129835195795,\"44\":0.10736411565946989,\"45\":-0.04203247566890838,\"46\":0.0821325758863691,\"47\":0.20578464935542143,\"48\":-0.18953496342659992,\"49\":0.2077068432466288}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.06464969137238316,\"1\":0.006923533472099081,\"2\":-0.12150968065785432,\"3\":-0.09311509292313935,\"4\":0.07408843407258134,\"5\":0.1213883303818253,\"6\":0.02157234198244142,\"7\":-0.03869016132116755,\"8\":0.36211011196360426,\"9\":-0.1422765618455522,\"10\":0.07043003500904017,\"11\":-0.17227841856944756,\"12\":0.1589390757980201,\"13\":0.041044613427255926,\"14\":0.027761765698150195,\"15\":0.025770933792694153,\"16\":0.03875449039167629,\"17\":0.1923627591139915,\"18\":-0.18141681801578535,\"19\":-0.12893462069289688,\"20\":0.050075002986458235,\"21\":0.10098270286858695,\"22\":-0.18164424988445443,\"23\":-0.10272609010357145,\"24\":-0.019893708674297243,\"25\":-0.0863434353589763,\"26\":-0.05005004788699831,\"27\":0.04005571610436921,\"28\":-0.05063867333959357,\"29\":0.06749221998419426,\"30\":0.08713424434946822,\"31\":-0.11395118312612618,\"32\":0.11666676842894227,\"33\":0.26533478536366784,\"34\":-0.17229152303051756,\"35\":-0.02145754638186537,\"36\":0.11349199775444035,\"37\":-0.22893068589246535,\"38\":-0.2026152483348926,\"39\":-0.002417008060247272,\"40\":0.108915028602883,\"41\":0.1872961673378562,\"42\":-0.28931288202074373,\"43\":-0.011651471884357147,\"44\":0.1708300950222166,\"45\":0.04985606877790209,\"46\":0.061201094917843445,\"47\":0.1174330031642301,\"48\":0.16833830385195755,\"49\":-0.0626184840255465}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.03170175156639391,\"1\":-0.015222763525661731,\"2\":0.11301742076820637,\"3\":0.08113346953426304,\"4\":-0.0037989249930755163,\"5\":-0.0037934669244735256,\"6\":0.08224376610180345,\"7\":0.0471888832207842,\"8\":0.004018573719718253,\"9\":-0.13868480856180482,\"10\":-0.14176138393544763,\"11\":-0.08148929329679971,\"12\":-0.10639936281423157,\"13\":-0.13188236469067027,\"14\":0.11606678288841772,\"15\":-0.0714792972347016,\"16\":0.23071070189789022,\"17\":0.174600728600308,\"18\":-0.20062451938738007,\"19\":-0.11138415527257693,\"20\":0.09129825949402595,\"21\":0.13904428181515585,\"22\":0.03557021211422418,\"23\":0.1703120030938792,\"24\":-0.029892622140682473,\"25\":-0.11423111993987788,\"26\":-0.2829266862475875,\"27\":0.15059058360877964,\"28\":-0.09564427772598762,\"29\":0.3264282968799083,\"30\":-0.010210889019380793,\"31\":-0.08908380364607138,\"32\":-0.19347865103926545,\"33\":0.08259277000729755,\"34\":-0.004800716938565886,\"35\":-0.0777772486628873,\"36\":0.02825390944594693,\"37\":-0.00209059115727581,\"38\":-0.12432701517613878,\"39\":-0.3241272353336849,\"40\":-0.23871995853761796,\"41\":-0.06894123548690148,\"42\":-0.15597556544221283,\"43\":-0.1792027027309903,\"44\":0.022193077104875458,\"45\":0.06929485222486877,\"46\":0.27343923451273716,\"47\":-0.055289783978165745,\"48\":-0.07797590244228385,\"49\":0.10983295092984716}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.1349353270065452,\"1\":-0.05804403056426138,\"2\":0.06698566896022728,\"3\":-0.07486753003602017,\"4\":-0.1461108147311779,\"5\":-0.12497584112611053,\"6\":-0.16969713339123335,\"7\":-0.10837046541716473,\"8\":0.06814810550696196,\"9\":0.054672274070286755,\"10\":-0.05201285641308196,\"11\":-0.06469386081640312,\"12\":-0.020945278838114107,\"13\":-0.1331200822048052,\"14\":-0.172745469656968,\"15\":-0.14861866300088517,\"16\":-0.012916415391205903,\"17\":0.20844651076762455,\"18\":-0.02667685882557226,\"19\":-0.20338558992413822,\"20\":0.07632186145998097,\"21\":-0.18396930431773714,\"22\":-0.1154281094642035,\"23\":0.0622166782830117,\"24\":0.17177142875213144,\"25\":0.188116201115055,\"26\":0.2094542720696382,\"27\":0.13935302436677555,\"28\":-0.14892368993690538,\"29\":0.0760431585356429,\"30\":-0.0015126203920870444,\"31\":-0.04272974308854098,\"32\":-0.005246217851286983,\"33\":-0.15982825033942819,\"34\":-0.07409527541679956,\"35\":-0.10552178050469795,\"36\":0.274277457526465,\"37\":-0.02624499521576913,\"38\":-0.17961374721323284,\"39\":0.153758906042917,\"40\":0.22604192831115516,\"41\":-0.0830742263504984,\"42\":-0.2538340350321985,\"43\":0.041620617843494634,\"44\":-0.06754969626781303,\"45\":-0.03908974826890864,\"46\":0.0735586095276133,\"47\":0.08194762461746016,\"48\":-0.07646996497143572,\"49\":-0.2507443525877261}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.1038659923616929,\"1\":0.023268570589328377,\"2\":0.13827834761294813,\"3\":0.2427326590660867,\"4\":0.037572826118104384,\"5\":-0.2314795475635177,\"6\":0.30672916294335417,\"7\":0.05890773963850294,\"8\":-0.019036925710733125,\"9\":-0.21377156321434057,\"10\":0.2701994927888267,\"11\":0.22211318963515486,\"12\":0.041574308044966826,\"13\":0.15251619811935443,\"14\":-0.06614192053474884,\"15\":0.1378688732589163,\"16\":0.06421272648323463,\"17\":-0.2672143835089995,\"18\":-0.16225081352522142,\"19\":-0.025572476711362892,\"20\":0.12181406193721851,\"21\":0.03448992676731498,\"22\":0.03615156074549322,\"23\":0.06368228158052695,\"24\":0.021106987439516903,\"25\":-0.07432083053275468,\"26\":0.23446546735104534,\"27\":-0.09327343217379128,\"28\":0.05830455789287707,\"29\":0.11909693356209969,\"30\":-0.12355660559876476,\"31\":-0.016283420991799535,\"32\":-0.05231545688371399,\"33\":0.15714577402340288,\"34\":-0.19608398731735996,\"35\":0.02922693781050615,\"36\":0.11725567337939087,\"37\":0.10483152795544765,\"38\":0.09402258567357216,\"39\":-0.13376964284406725,\"40\":0.05021963392243722,\"41\":-0.03533030300401561,\"42\":-0.042347567889860334,\"43\":-0.13993312065230287,\"44\":-0.1436889937785256,\"45\":-0.04109873268999892,\"46\":-0.22547949984378915,\"47\":-0.12462983432719899,\"48\":0.14524679168178384,\"49\":0.23698954300758066}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.183851253333156,\"1\":-0.015717755843876312,\"2\":0.07169442698487684,\"3\":0.5073038294180436,\"4\":-0.020416484455754454,\"5\":0.10681524965934523,\"6\":0.08216587144791063,\"7\":0.006998976548009643,\"8\":-0.16873474939234057,\"9\":0.14682909478795342,\"10\":-0.16744881811147913,\"11\":-0.28335058195846036,\"12\":0.006951806430167732,\"13\":-0.11979553828646904,\"14\":0.13012455158310274,\"15\":-0.1677753697499878,\"16\":0.007318880783643554,\"17\":0.12902885334484263,\"18\":0.06055594725220843,\"19\":-0.1807726089149697,\"20\":0.17857586089767036,\"21\":-0.058563800715523064,\"22\":0.16746762709378374,\"23\":-0.09645550088084653,\"24\":-0.03522342231060792,\"25\":-0.24370660529302507,\"26\":0.0042061899621536,\"27\":0.21240797775094986,\"28\":0.13972061296968852,\"29\":-0.1578945062719499,\"30\":0.0613054911942949,\"31\":0.1815794163267513,\"32\":0.2107110024786631,\"33\":-0.20577118884687384,\"34\":-0.008402798179097414,\"35\":-0.03138349647308933,\"36\":-0.10861448833511315,\"37\":-0.06630837938242942,\"38\":0.0034693281868517145,\"39\":-0.056840099727595704,\"40\":-0.005384681634286315,\"41\":0.03427423895333617,\"42\":-0.0463256969043417,\"43\":0.10576447646570168,\"44\":0.31522495464308975,\"45\":-0.159225453772524,\"46\":-0.015838607238166987,\"47\":0.1457659375699861,\"48\":-0.031225031687092765,\"49\":-0.01866177353670499}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.07714174420564575,\"1\":-0.03429239210237597,\"2\":-0.2071061175921036,\"3\":0.17240730687408917,\"4\":0.27808901094770855,\"5\":-0.04029852521783259,\"6\":-0.14597664378134148,\"7\":0.2389183691760521,\"8\":-0.25073195951050176,\"9\":0.06355587714847559,\"10\":-0.09459382693243742,\"11\":-0.014892486428744444,\"12\":0.329834558992919,\"13\":-0.0026608560943912818,\"14\":-0.07296025157745002,\"15\":-0.008496973644605244,\"16\":-0.18735285768576787,\"17\":-0.011867487184811698,\"18\":0.11604944724926451,\"19\":0.05419469073759151,\"20\":0.061104161810656976,\"21\":-0.04798417420177768,\"22\":-0.01679866679660273,\"23\":-0.024514040606381095,\"24\":-0.10748530897245039,\"25\":-0.04236917220218612,\"26\":-0.08009726962482545,\"27\":-0.15156053106350612,\"28\":0.02964868964439236,\"29\":0.011164892729599018,\"30\":-0.20313991565597705,\"31\":0.005243230876780001,\"32\":0.03595484098250717,\"33\":0.37337664339769583,\"34\":0.00760458287090518,\"35\":0.14823669051310925,\"36\":0.01266739041811828,\"37\":-0.21298160476138167,\"38\":-0.12585021987947487,\"39\":-0.20202040290252732,\"40\":-0.08734167990304056,\"41\":0.14941660391368808,\"42\":0.006184451790499878,\"43\":-0.26317799167583716,\"44\":0.06610181573168959,\"45\":0.27460293902998884,\"46\":-0.02025709547282075,\"47\":0.11679309359806597,\"48\":0.12150361813481671,\"49\":-0.039146365252331894}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.057228476601687825,\"1\":0.1362734919325489,\"2\":0.06198803178002213,\"3\":0.15577375316652228,\"4\":-0.3329616724597623,\"5\":0.23662577828716266,\"6\":-0.10446412558065107,\"7\":-0.05103434438580807,\"8\":-0.1220399613577296,\"9\":0.15811011672721134,\"10\":0.043019826153214716,\"11\":-0.09212514693083601,\"12\":-0.051359129028285315,\"13\":-0.027180512809466782,\"14\":0.1378963716472264,\"15\":-0.016505355587549213,\"16\":-0.07452787626802511,\"17\":0.1699241014424823,\"18\":-0.03990785292301768,\"19\":-0.018167920556047445,\"20\":0.031330417369014485,\"21\":-0.08768191536294272,\"22\":0.11212978404209173,\"23\":-0.01927655572641196,\"24\":-0.05083004546234159,\"25\":0.01600394514623755,\"26\":-0.14047824173166196,\"27\":0.30383693580530474,\"28\":0.08730124789697008,\"29\":0.07929922400518685,\"30\":0.23481567740572276,\"31\":-0.04754710179698309,\"32\":0.10192143671464497,\"33\":0.17826291613222986,\"34\":-0.12498302418168428,\"35\":-0.10677563737832908,\"36\":0.18381452910664275,\"37\":-0.006335537152826468,\"38\":0.07322465538620923,\"39\":-0.1269147896708463,\"40\":0.09233550045540564,\"41\":-0.13730738898657238,\"42\":0.38453683096537816,\"43\":0.2848931151785473,\"44\":-0.037016489103363796,\"45\":0.06883088794229307,\"46\":-0.09601441360627308,\"47\":-0.007798115967797056,\"48\":0.04630204424988669,\"49\":-0.028016352202198825}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.09012923081835704,\"1\":0.13337584441254188,\"2\":-0.31946296920115663,\"3\":0.17246865553121232,\"4\":0.008029802565941853,\"5\":0.1347941419489747,\"6\":-0.16242097316994497,\"7\":0.10706813069236916,\"8\":-0.01656742868127956,\"9\":0.05867303365304255,\"10\":-0.12344002777987724,\"11\":0.08302234158379132,\"12\":-0.35495208191575445,\"13\":-0.1763901689839624,\"14\":0.13122583254237624,\"15\":-0.13262421860475213,\"16\":0.1465080868641191,\"17\":0.07571300902927161,\"18\":0.33344905152416854,\"19\":0.2025906536736234,\"20\":0.06458022868809402,\"21\":-0.26571731561004674,\"22\":0.18102709860259686,\"23\":-0.09454371724021364,\"24\":-0.007814807952758464,\"25\":-0.02415788343615021,\"26\":0.02831231759924821,\"27\":0.05103274802285442,\"28\":0.050091568161934906,\"29\":0.25610330049101193,\"30\":0.06641500133141705,\"31\":0.14320506644652037,\"32\":-0.023691228600160544,\"33\":0.19062738132198878,\"34\":0.1302612033569704,\"35\":-0.014992830468439189,\"36\":0.05396583619547413,\"37\":-0.012107292056110755,\"38\":-0.2362988952237527,\"39\":0.22219553248371124,\"40\":0.12263758291676138,\"41\":-0.03494210872794885,\"42\":-0.09159825158421037,\"43\":0.266905096289365,\"44\":-0.23610440237672178,\"45\":-0.24693766201164974,\"46\":0.07667414020775677,\"47\":-0.19218073256584808,\"48\":-0.09917681637435587,\"49\":-0.07711862201580351}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.03135579414136092,\"1\":-0.10833900589725623,\"2\":0.2281674234991038,\"3\":-0.00637355028002238,\"4\":-0.022498911385453547,\"5\":0.09755027600773357,\"6\":0.06147955571073156,\"7\":-0.1336675042253424,\"8\":-0.05380133558134986,\"9\":-0.06252295922607028,\"10\":0.1180604792425425,\"11\":0.1671066239462388,\"12\":0.16819280460031633,\"13\":-0.0020985103788432155,\"14\":-0.022806201708395885,\"15\":-0.04371435514350931,\"16\":0.21896845137761178,\"17\":-0.056274089606117836,\"18\":-0.09053864470998468,\"19\":-0.06425629362246353,\"20\":0.20065717342749853,\"21\":-0.20649243916027316,\"22\":-0.08879402580105666,\"23\":-0.1522965109881905,\"24\":0.0841688967011496,\"25\":0.1632272132433588,\"26\":0.2371264996551358,\"27\":-0.13560621021859973,\"28\":-0.08229243427875452,\"29\":-0.044835046620845746,\"30\":-0.06868224725603299,\"31\":0.027396350514128393,\"32\":0.09451668837530336,\"33\":-0.09687906975164318,\"34\":-0.19942461030233988,\"35\":0.2895508411663362,\"36\":0.26027973907187946,\"37\":-0.04070302539025926,\"38\":-0.03434985683666235,\"39\":-0.298251131913984,\"40\":-0.128530465368544,\"41\":0.10776195096581698,\"42\":0.17532816122433512,\"43\":0.051558778631129815,\"44\":0.037005688909209605,\"45\":0.019886399256525956,\"46\":0.05736737519756197,\"47\":-0.23303435765578753,\"48\":-0.18303772017715775,\"49\":0.014217815723232375}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.1714960284251186,\"1\":0.07768951310068364,\"2\":0.034867800437179845,\"3\":0.18826853484494452,\"4\":-0.06513576076962807,\"5\":-0.07038050570542163,\"6\":0.3553708128771309,\"7\":0.10667856878692021,\"8\":0.012535347178541855,\"9\":-0.3119343919187183,\"10\":-0.08904400996700786,\"11\":0.22889655493264113,\"12\":0.12214107408307191,\"13\":0.118614849570764,\"14\":0.008049428999538396,\"15\":0.050440719817624505,\"16\":-0.04773125530762089,\"17\":-0.2820147166821164,\"18\":0.0016470729123003371,\"19\":0.13179121443261246,\"20\":0.08699486113580494,\"21\":-0.10807913950083742,\"22\":-0.06431829600439665,\"23\":0.0280609860039465,\"24\":0.099543041619447,\"25\":0.0950070792990887,\"26\":0.060944610285123324,\"27\":-0.03334334006861657,\"28\":0.18683257473020812,\"29\":-0.023150823109649186,\"30\":-0.12302259775595789,\"31\":-0.016559079780318446,\"32\":-0.05889387629701977,\"33\":-0.02249641966699597,\"34\":0.00023886664134074054,\"35\":-0.20373000688017912,\"36\":0.11063090460675436,\"37\":-0.03402362188020862,\"38\":0.20704945864535085,\"39\":0.034917599808080305,\"40\":0.05474820399879489,\"41\":-0.2072515902696839,\"42\":0.028408751532043277,\"43\":-0.06825815572129083,\"44\":0.2758603611434902,\"45\":0.11155716236806225,\"46\":-0.06063868951142485,\"47\":0.036907059728092564,\"48\":0.05591340173606632,\"49\":-0.1240999984674668}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.07973357337267835,\"1\":-0.17644666741886308,\"2\":0.01635858615808223,\"3\":-0.04153227675104995,\"4\":-0.03415397573769822,\"5\":0.043775380491983824,\"6\":0.042686082971415656,\"7\":-0.038834748761866794,\"8\":0.3128867549389746,\"9\":-0.27918291688850644,\"10\":0.15463265824531164,\"11\":-0.23030940351233076,\"12\":0.24046380820417326,\"13\":0.16904869019897042,\"14\":-0.13589319270534922,\"15\":0.29241888541357713,\"16\":-0.020774138740408222,\"17\":0.09586217182458676,\"18\":-0.15940021655783143,\"19\":0.04535041400030762,\"20\":0.10940645078810779,\"21\":0.39044245285016005,\"22\":-0.10697545418034902,\"23\":-0.1393855001969278,\"24\":-0.12616883719405483,\"25\":0.031284689995003265,\"26\":0.002588135578960563,\"27\":0.186323309486338,\"28\":0.06220131880866045,\"29\":-0.05692313163717367,\"30\":-0.18762377543558942,\"31\":-0.32640635845115196,\"32\":0.004761439079158027,\"33\":-0.013937245033522552,\"34\":-0.0414418123573667,\"35\":-0.012813019603271733,\"36\":-0.07095997689362572,\"37\":0.12076525028243387,\"38\":0.1344646384987786,\"39\":0.10069110939756443,\"40\":-0.22735462102287538,\"41\":-0.08034478103074101,\"42\":0.07436256896089993,\"43\":-0.07719989841185786,\"44\":-0.017504589300889672,\"45\":-0.020238512177966808,\"46\":-0.17415224759564707,\"47\":0.21301936447840808,\"48\":-0.16417249466965847,\"49\":0.07520112009846328}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.10303405136049083,\"1\":0.0075461240010366425,\"2\":0.04496134077859474,\"3\":0.06203666303002158,\"4\":0.12124295439080734,\"5\":-0.009802372327807703,\"6\":-0.19346004458441646,\"7\":-0.2322305041051549,\"8\":0.014174471611627566,\"9\":-0.10817134203925118,\"10\":0.05040401476789833,\"11\":-0.027267578808240198,\"12\":0.14115955405573954,\"13\":0.049079877435041816,\"14\":-0.12802475739113164,\"15\":0.1638945428286032,\"16\":-0.299284910521113,\"17\":-0.17971499524683746,\"18\":-0.12813320664046388,\"19\":0.0195994189527688,\"20\":0.028577121557610035,\"21\":0.1455226073691595,\"22\":-0.2691243186857746,\"23\":-0.04279762161121148,\"24\":0.06344819442771188,\"25\":-0.06057644276645966,\"26\":-0.006229857775334707,\"27\":0.05160021267580937,\"28\":-0.2169326437962493,\"29\":-0.18240509640677335,\"30\":0.0921736863176381,\"31\":-0.043976389034880055,\"32\":-0.23036474868102624,\"33\":-0.14931663501326894,\"34\":-0.028364956277763212,\"35\":0.006796653033225716,\"36\":-0.12715967091172523,\"37\":-0.057208355672790284,\"38\":0.030254658155368565,\"39\":0.14233402519017196,\"40\":-0.11392697446714044,\"41\":-0.18978318156008245,\"42\":-0.029437609193783066,\"43\":-0.22712921315587237,\"44\":-0.1476909497873613,\"45\":0.1346071476078441,\"46\":-0.050064901029402316,\"47\":-0.08168693924251359,\"48\":0.00040811934383246166,\"49\":0.06980435397923283}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.11309273258745026,\"1\":-0.047665537901877726,\"2\":0.005065235332976704,\"3\":-0.06672830217549018,\"4\":0.0839134523136197,\"5\":0.29626538134466895,\"6\":0.29260619842808994,\"7\":-0.19560201587715154,\"8\":-0.04556329568427644,\"9\":-0.11321999042758833,\"10\":0.16448335139546666,\"11\":0.008156791823753272,\"12\":0.21392934094171884,\"13\":0.20055812349011234,\"14\":0.012715138575410496,\"15\":-0.07122775577106104,\"16\":-0.028560815149767025,\"17\":-0.002701975990278055,\"18\":-0.13282973641389753,\"19\":0.16576816248701984,\"20\":-0.17019359148258317,\"21\":-0.007104573785871516,\"22\":0.19337345258331434,\"23\":-0.19892052166959595,\"24\":0.18867641911796212,\"25\":0.18573542099628654,\"26\":0.1369148590870203,\"27\":0.028822250228800514,\"28\":-0.1162388406086976,\"29\":0.011252778212058005,\"30\":0.13146606236499464,\"31\":-0.30427518359322736,\"32\":-0.13417946880148887,\"33\":0.06603450261793001,\"34\":-0.11934709686286904,\"35\":0.3709673070842713,\"36\":-0.03591056183946486,\"37\":0.10271456898573299,\"38\":0.16650242761127734,\"39\":0.22515350700015496,\"40\":-0.015300772451204174,\"41\":0.06228767685740761,\"42\":-0.025614649648638563,\"43\":-0.019642512773084535,\"44\":0.17060767818561193,\"45\":-0.14033242347380837,\"46\":-0.10172483403005073,\"47\":-0.2680553597127562,\"48\":0.12553945801367317,\"49\":0.0803415365770905}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.06891898111496027,\"1\":0.04972464877326931,\"2\":0.07611364010197362,\"3\":-0.13397001523153987,\"4\":-0.21032659144879728,\"5\":-0.29075091785425894,\"6\":-0.1954591977149758,\"7\":-0.029221430050344582,\"8\":-0.09459886743739827,\"9\":0.11264405497263989,\"10\":0.1484323335419648,\"11\":0.3507431667550411,\"12\":-0.16172382016585854,\"13\":0.03676571132704697,\"14\":0.09845592123236648,\"15\":0.011476703325388481,\"16\":-0.022698871344121435,\"17\":-0.04751726201045238,\"18\":-0.33685546936356586,\"19\":0.19727770011624485,\"20\":0.25459928795805864,\"21\":-0.27097769393127774,\"22\":-0.11889363412265687,\"23\":-0.3426098144618639,\"24\":-0.11737135257439305,\"25\":-0.002974481707350254,\"26\":0.25526152689226606,\"27\":-0.16967858522964643,\"28\":-0.20394917100873797,\"29\":0.05319862552407553,\"30\":-0.16178034141129605,\"31\":0.15861373046525581,\"32\":-0.26451110532927313,\"33\":0.01585857704122943,\"34\":0.17513900508654406,\"35\":0.01787777764317756,\"36\":0.0032276116584107548,\"37\":-0.03901150400820407,\"38\":0.21082664658473366,\"39\":-0.21454692487407995,\"40\":-0.061299558695327654,\"41\":-0.03627272262121223,\"42\":-0.10111568622208893,\"43\":0.011183366639708309,\"44\":-0.1300992336913505,\"45\":0.053147163967401705,\"46\":0.21283395114906528,\"47\":0.06677730562515938,\"48\":-0.35138366926073145,\"49\":0.08392121572455606}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.04650009564502186,\"1\":0.14678788886355676,\"2\":0.19045990473526958,\"3\":0.016743845209647737,\"4\":-0.009052071647571193,\"5\":0.25892911786657036,\"6\":0.12799619666105455,\"7\":-0.03933797607179611,\"8\":0.08454160197197562,\"9\":0.21764181829579932,\"10\":0.0795201741335755,\"11\":-0.05326008149376948,\"12\":0.11959969120066555,\"13\":0.07775053575365046,\"14\":0.02670939706548447,\"15\":-0.33496973874151187,\"16\":0.2867735340871889,\"17\":0.0028096253658396737,\"18\":-0.20192604734624356,\"19\":-0.10406191908234028,\"20\":0.14430135679396422,\"21\":-0.14585442428160747,\"22\":0.029310186500317054,\"23\":-0.025241544851578496,\"24\":0.06775570921185368,\"25\":-0.09162808417314272,\"26\":0.09921587210184946,\"27\":0.06075325227335131,\"28\":0.13155846588515624,\"29\":0.14872696765811663,\"30\":-0.01976987184714803,\"31\":-0.005658557144688057,\"32\":0.19799987223249463,\"33\":-0.061845200040431064,\"34\":-0.07260125771811551,\"35\":0.17643798632402877,\"36\":-0.014353595541134174,\"37\":-0.22631257746193256,\"38\":0.037206519345976054,\"39\":0.02133189419363388,\"40\":-0.1634689048634882,\"41\":-0.012312541078865558,\"42\":-0.03491723007951735,\"43\":0.10783357077083806,\"44\":0.013131852557621603,\"45\":0.028499134778869614,\"46\":-0.3345539612230888,\"47\":-0.2335841633427647,\"48\":-0.11857263715358042,\"49\":-0.08073709672899966}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.036924737869714515,\"1\":0.060990446796957816,\"2\":-0.08810651828662994,\"3\":0.043180011602904925,\"4\":-0.12642371509644515,\"5\":-0.045925077241734204,\"6\":-0.032884680136850225,\"7\":-0.05237882889277815,\"8\":-0.1998548768476066,\"9\":-0.02807516567054017,\"10\":-0.03190672935121608,\"11\":0.008068317741048618,\"12\":-0.060749190306997915,\"13\":-0.012289165704803066,\"14\":0.13909067149549495,\"15\":-0.07701698031675916,\"16\":-0.18779852223141344,\"17\":0.23614678345497048,\"18\":-0.08565335432494725,\"19\":0.02510362982483949,\"20\":0.0007242254359147769,\"21\":0.011051673203130413,\"22\":0.20361741709604073,\"23\":0.019159816762216245,\"24\":0.045699264885172085,\"25\":0.03227666277693587,\"26\":0.025436423714018924,\"27\":-0.1331498658629317,\"28\":0.030004099520461597,\"29\":-0.25453262620503303,\"30\":-0.0916692554235607,\"31\":0.2640377035565251,\"32\":-0.23841497593074623,\"33\":-0.003280250496441564,\"34\":0.14005499919407405,\"35\":-0.05865919418061,\"36\":-0.19258417236502243,\"37\":0.1196102241338124,\"38\":0.11786796850301381,\"39\":-0.10730520309569064,\"40\":0.07150004002041718,\"41\":-0.023276089687365293,\"42\":0.04335025718936511,\"43\":0.2288183940480506,\"44\":0.056019926173614364,\"45\":0.0726114235338443,\"46\":-0.1272582847025171,\"47\":-0.002631707658169375,\"48\":0.0006936379134865186,\"49\":-0.12030307428250213}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.10516757480078875,\"1\":-0.06984851121090711,\"2\":0.03603910977440938,\"3\":-0.2120302826873712,\"4\":0.04118961762187801,\"5\":0.03364463938834167,\"6\":-0.1391530948663362,\"7\":-0.1547824068408499,\"8\":0.1451319274121756,\"9\":0.33541521679606734,\"10\":-0.17977359551445976,\"11\":-0.12365847862282689,\"12\":-0.0868475943624997,\"13\":0.018971831946871482,\"14\":0.007179156246573492,\"15\":-0.04879428144377547,\"16\":-0.1582419266354251,\"17\":0.042205971103442284,\"18\":-0.09425955301119761,\"19\":-0.19233200952820553,\"20\":0.08013766529514646,\"21\":0.20745669764084085,\"22\":0.15421921089335253,\"23\":0.05795855706683724,\"24\":-0.11760573745270816,\"25\":0.1056104602577445,\"26\":-0.0212345776899276,\"27\":0.005411435740699297,\"28\":-0.18078778186115832,\"29\":0.14156270984867222,\"30\":0.28998997950916067,\"31\":0.20262756062583612,\"32\":0.07258778250053016,\"33\":-0.000055913439323694514,\"34\":-0.0733143903490695,\"35\":-0.0750204264927876,\"36\":-0.14093524347584507,\"37\":0.058780476813438995,\"38\":-0.0823259200847095,\"39\":0.03690666555575679,\"40\":-0.05817733498240111,\"41\":0.07303810946888031,\"42\":0.0057370857381145056,\"43\":0.10509523596862094,\"44\":0.04979739600069408,\"45\":-0.021452510716809748,\"46\":-0.151793394924295,\"47\":0.0677346758999415,\"48\":0.022881843029634374,\"49\":-0.08223661778771571}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.08957399598754796,\"1\":0.1418823613407175,\"2\":-0.23482893727808063,\"3\":0.11871116284870009,\"4\":-0.16579282062770664,\"5\":0.11248624614745019,\"6\":-0.015582615473962958,\"7\":-0.03182467337549072,\"8\":0.08594080267686263,\"9\":-0.007354521849192615,\"10\":0.017513384153137558,\"11\":0.09626421074258207,\"12\":-0.2270845560621373,\"13\":-0.0945713242829049,\"14\":-0.1550344277196695,\"15\":0.14574249499718211,\"16\":-0.02799226279302192,\"17\":0.33750629026820017,\"18\":-0.026400718521393484,\"19\":-0.04796810272336183,\"20\":0.073321306462392,\"21\":0.14623143237537206,\"22\":-0.1385779278188006,\"23\":-0.032233853935237124,\"24\":-0.05737476751585246,\"25\":-0.03164081298248742,\"26\":-0.2082317587851745,\"27\":0.11316951117460154,\"28\":-0.19841863805685206,\"29\":-0.03288953549453485,\"30\":-0.10242828318148903,\"31\":0.03441486937004115,\"32\":-0.12916453730501481,\"33\":-0.06414634621331389,\"34\":-0.11550772339897623,\"35\":0.10467903694259482,\"36\":0.1433409235562807,\"37\":-0.19188890046127374,\"38\":-0.10573471983224818,\"39\":-0.1028088058109397,\"40\":-0.009588271078491235,\"41\":-0.022416640447759453,\"42\":-0.1076819638353928,\"43\":0.06478283674583914,\"44\":-0.047788026018676516,\"45\":0.0009120893819626266,\"46\":-0.008596139874044152,\"47\":-0.1736625156708728,\"48\":0.10572946541264265,\"49\":0.012797584238570522}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.021106157390478913,\"1\":0.020384448961744777,\"2\":0.005716355800088391,\"3\":-0.07529556857199386,\"4\":0.0389540061207387,\"5\":0.149925510673609,\"6\":-0.03341539911501664,\"7\":0.0026720610593456333,\"8\":-0.026535825293080392,\"9\":0.08019181226869221,\"10\":0.0769909765019689,\"11\":0.11865558146908058,\"12\":-0.2681771761899582,\"13\":0.09748220867049649,\"14\":0.0855195370496579,\"15\":0.05544161218731408,\"16\":0.15265297808235934,\"17\":-0.07415692597191094,\"18\":0.11852558241784342,\"19\":-0.02981814464451437,\"20\":-0.029219983938472513,\"21\":-0.2512420334427996,\"22\":0.15688087309904125,\"23\":-0.08541751611965774,\"24\":0.07845318842044095,\"25\":0.13141155330655382,\"26\":-0.057434299434812965,\"27\":0.16323838228984233,\"28\":0.1134057590914232,\"29\":0.03260258888761382,\"30\":0.05962377778015875,\"31\":-0.09992789039953259,\"32\":0.18469144044806898,\"33\":0.09415483873632374,\"34\":0.046303072532048586,\"35\":-0.15626772192397193,\"36\":0.19689547261837184,\"37\":-0.18428139076833108,\"38\":-0.25511162551577066,\"39\":0.09103131160228901,\"40\":-0.07484793962109244,\"41\":0.09711184956369653,\"42\":-0.04264566583821864,\"43\":0.014596087349053318,\"44\":-0.08668674161155608,\"45\":0.1622605285652196,\"46\":-0.03317546666737611,\"47\":-0.17117354329607015,\"48\":0.15921076421321428,\"49\":-0.026603224060599694}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.059361100506528576,\"1\":0.0005815075824509846,\"2\":-0.4698273975216716,\"3\":-0.03845852098232629,\"4\":-0.04665771977169497,\"5\":-0.1995381735329297,\"6\":0.2319777586702637,\"7\":0.0787935355924958,\"8\":-0.08810527197926865,\"9\":0.1779478845108546,\"10\":0.08006794685748489,\"11\":-0.161309882719687,\"12\":-0.08360664165795287,\"13\":0.05219597279727279,\"14\":-0.010704637436062762,\"15\":0.16965644973177937,\"16\":0.025260189816889933,\"17\":0.08806524460805813,\"18\":0.3929691680078926,\"19\":0.072315979193887,\"20\":-0.11539723967511419,\"21\":0.030198928343208857,\"22\":-0.05082149328331509,\"23\":-0.13109930925841984,\"24\":0.02124479314505768,\"25\":-0.12190136455196418,\"26\":-0.19091025884200868,\"27\":0.2972433429038427,\"28\":0.0762072179151923,\"29\":-0.1046563137499604,\"30\":0.16598960206051822,\"31\":-0.10623059730154649,\"32\":0.10690265680284591,\"33\":0.17842707395059573,\"34\":0.10835273541340658,\"35\":-0.16160306648478281,\"36\":0.0429912017994669,\"37\":-0.15706830161971466,\"38\":-0.09310107528051588,\"39\":0.013621127290700249,\"40\":-0.020859619795438336,\"41\":0.22300582206229946,\"42\":-0.023669448161881705,\"43\":0.04421838205004315,\"44\":-0.14730192380187065,\"45\":0.35302007903471166,\"46\":-0.04783357106342924,\"47\":0.206752022012151,\"48\":0.193790299420535,\"49\":-0.18463734448801858}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.073424319302411,\"1\":-0.060094940443405395,\"2\":0.06008080421247994,\"3\":-0.019222030454422678,\"4\":0.20317597552176356,\"5\":-0.06637425110471946,\"6\":-0.1017649558965198,\"7\":-0.04137933199210296,\"8\":-0.13275089287334918,\"9\":0.05531260492364989,\"10\":-0.1431290680110576,\"11\":-0.13305394963673584,\"12\":-0.12915636290434107,\"13\":0.19657532211195103,\"14\":-0.27155593847270343,\"15\":0.006606953328017658,\"16\":-0.32726089806791164,\"17\":0.05131138105769851,\"18\":-0.09647030268096174,\"19\":-0.12837325011243972,\"20\":-0.17566313286383814,\"21\":-0.011951793190375839,\"22\":-0.04318610018221253,\"23\":0.12839569647741084,\"24\":0.2008034441015191,\"25\":-0.20327006531316794,\"26\":-0.13227577849994052,\"27\":0.13955503486469775,\"28\":-0.0671995206626815,\"29\":0.025707270325074832,\"30\":0.03527940418971705,\"31\":-0.13998327744579317,\"32\":-0.08086622332944038,\"33\":0.01796327832141611,\"34\":-0.10615663139669096,\"35\":-0.10146579396535244,\"36\":0.07985173261617846,\"37\":0.011783623669861779,\"38\":-0.09877790776173033,\"39\":-0.040708009715913124,\"40\":0.11545979321913577,\"41\":-0.1538870941715804,\"42\":0.0009701053270476618,\"43\":0.0023263984877109458,\"44\":0.07406083100705935,\"45\":0.16044762121114609,\"46\":-0.06795049265891942,\"47\":0.0885030562338118,\"48\":-0.18299106366172785,\"49\":-0.09811666809553371}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.04284742915138263,\"1\":0.08948697333344241,\"2\":-0.14294939651708144,\"3\":-0.08255812117794832,\"4\":0.02513794133072476,\"5\":0.20730742191925342,\"6\":-0.17080301459894429,\"7\":0.26455246836581386,\"8\":0.17742662242074644,\"9\":0.06661673861325261,\"10\":0.20836933241596045,\"11\":-0.021298750124789777,\"12\":-0.006307341071629047,\"13\":0.2617081372479506,\"14\":0.23666115128233092,\"15\":-0.21860251640573683,\"16\":0.2706679838886821,\"17\":-0.08874110777305867,\"18\":-0.04611660164618515,\"19\":-0.0659430730385413,\"20\":-0.016157061852755034,\"21\":-0.10853353392971471,\"22\":0.050788678319853744,\"23\":0.030997754817356026,\"24\":0.23403151488891064,\"25\":0.09968967076694417,\"26\":0.13200779360779594,\"27\":0.06522468457233932,\"28\":0.0492869044820748,\"29\":0.14406530023731862,\"30\":0.084719647601508,\"31\":-0.1512819296888117,\"32\":0.07878447506811392,\"33\":0.05423450778029127,\"34\":-0.18709158689049382,\"35\":0.2662978145680039,\"36\":0.09772842219860105,\"37\":0.0021879096106731236,\"38\":0.01578181180535429,\"39\":0.03868734108732461,\"40\":-0.028940727972628276,\"41\":0.029862323821965964,\"42\":0.028025408194690408,\"43\":0.11878378553385213,\"44\":0.08598878608593502,\"45\":0.005193617822313595,\"46\":-0.05958169692604605,\"47\":-0.03140382458034529,\"48\":-0.09397562644132743,\"49\":-0.030224086975100737}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.01275277200636031,\"1\":0.20679858859932065,\"2\":0.036303973924260026,\"3\":-0.15005898241805207,\"4\":-0.0626441044956673,\"5\":-0.10368039746829444,\"6\":0.08246419046184507,\"7\":-0.21952281642113086,\"8\":-0.03147448779340356,\"9\":-0.13552768530709441,\"10\":0.1788611356088912,\"11\":-0.028454260501515102,\"12\":-0.03131462724876237,\"13\":0.010860297503865144,\"14\":-0.08317248491478646,\"15\":-0.09682171524082796,\"16\":0.03415624663074164,\"17\":-0.14404415392226882,\"18\":0.013237953119515472,\"19\":0.18771271417765178,\"20\":0.006012385023792947,\"21\":0.3322209261735688,\"22\":-0.0113918197712346,\"23\":-0.3820452520224558,\"24\":-0.021009925194328368,\"25\":-0.08143500247709302,\"26\":-0.0586813545447799,\"27\":0.018281959821222122,\"28\":-0.023010782629507457,\"29\":-0.07454746850325823,\"30\":-0.10122011817208154,\"31\":-0.05549886482724924,\"32\":0.07066142579467986,\"33\":-0.22757789849092672,\"34\":0.0961434535360455,\"35\":-0.036480002469763795,\"36\":0.3763797609060955,\"37\":-0.10346822759208539,\"38\":-0.1149158995798784,\"39\":0.10620028325819195,\"40\":-0.037046461135796516,\"41\":-0.05424972428061598,\"42\":-0.15303962120800085,\"43\":-0.14948776716989703,\"44\":0.006845693094151477,\"45\":-0.2695138937272486,\"46\":-0.1085663192355169,\"47\":-0.13064926948468278,\"48\":-0.14677078544991123,\"49\":-0.25571033551157873}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.14037721997874605,\"1\":-0.25060398538419854,\"2\":0.3266809626823662,\"3\":-0.0745460397049856,\"4\":0.10745061798601853,\"5\":-0.008433368799174354,\"6\":0.36028545012286867,\"7\":0.02935688761529109,\"8\":-0.16744280725265467,\"9\":0.18201096198362618,\"10\":0.13829669394884278,\"11\":0.02141907618440914,\"12\":-0.06770146881196781,\"13\":-0.037943661975992464,\"14\":-0.06925284408882204,\"15\":0.06219064623582232,\"16\":-0.05363051116771237,\"17\":-0.08840255963111607,\"18\":-0.11687824191565577,\"19\":-0.082761159448701,\"20\":-0.20085966709111383,\"21\":-0.0741021639796352,\"22\":0.015874310053430096,\"23\":-0.08849397162364839,\"24\":-0.20133311166579504,\"25\":0.050906356164137405,\"26\":0.000036726847006887154,\"27\":-0.05255613224296618,\"28\":-0.027515332301133462,\"29\":-0.1048634104792652,\"30\":0.21354244307135212,\"31\":0.06315448824290514,\"32\":-0.14697052316209855,\"33\":0.10221684727650712,\"34\":-0.04464206334780221,\"35\":0.1043049500506956,\"36\":0.15119251085581967,\"37\":0.05322986675844092,\"38\":0.21987425198716676,\"39\":-0.04404030350542553,\"40\":-0.021266465776238298,\"41\":0.15765423073975984,\"42\":-0.08385382322849756,\"43\":-0.10578821000184027,\"44\":0.075695515677995,\"45\":-0.06465355083586427,\"46\":-0.10465715592157358,\"47\":-0.01937371908606455,\"48\":-0.03312935514345372,\"49\":-0.1201767118227738}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.05330242126490279,\"1\":-0.17911884127342956,\"2\":0.013035223387796582,\"3\":-0.12080953159066696,\"4\":0.023583033558365392,\"5\":0.09395663961531264,\"6\":0.039914339228978,\"7\":0.27229549279034965,\"8\":-0.0717557956010388,\"9\":0.0032481293009613307,\"10\":-0.2202845393056113,\"11\":0.10500434461829537,\"12\":-0.2144043792463342,\"13\":-0.18606043132240727,\"14\":0.041026155559083066,\"15\":0.13089344970077693,\"16\":0.051297576355914296,\"17\":-0.24278538530526517,\"18\":-0.018208122915964842,\"19\":-0.08634183321366977,\"20\":0.1989706623846781,\"21\":-0.22979281998249634,\"22\":-0.0258970633238032,\"23\":-0.18444354303224048,\"24\":-0.010662799826850526,\"25\":0.05379624688668673,\"26\":-0.21711988431060836,\"27\":-0.13206962356676732,\"28\":0.0594229992792364,\"29\":0.028954116134092947,\"30\":0.058248093856295265,\"31\":0.22663858828971875,\"32\":-0.18191668511319442,\"33\":0.020324852730440726,\"34\":-0.10061551538893007,\"35\":0.055814920532576945,\"36\":0.00075827483154844,\"37\":0.024520898895801925,\"38\":-0.2569374615289878,\"39\":0.20958785702112961,\"40\":-0.22842050722018808,\"41\":0.02745967349848297,\"42\":-0.2444681089906393,\"43\":0.07200827852951254,\"44\":-0.2083954738141286,\"45\":-0.1398066156191203,\"46\":-0.24154687704473712,\"47\":0.07555935996194682,\"48\":-0.24241954683720857,\"49\":0.16118511519856882}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.0397738352433167,\"1\":-0.06630775528440022,\"2\":-0.07417834231981688,\"3\":0.018890955671245872,\"4\":0.021304703294124577,\"5\":-0.0926872223490953,\"6\":0.631378384829037,\"7\":0.12017405602923911,\"8\":-0.248082963083767,\"9\":0.07850216060893188,\"10\":0.04055523793548315,\"11\":-0.01930923099152183,\"12\":0.19550130973204086,\"13\":0.30972060351462494,\"14\":0.0015930023319479457,\"15\":-0.20003398356480587,\"16\":-0.14551481807495756,\"17\":0.24446046114860187,\"18\":-0.22112810512316391,\"19\":-0.03156407418036397,\"20\":0.36607155654878387,\"21\":0.28466850321555665,\"22\":0.03917600538638974,\"23\":-0.06019200862788454,\"24\":0.16083976860209187,\"25\":0.10850748231115633,\"26\":0.27958429576243243,\"27\":0.10453348201256739,\"28\":-0.0774396291062857,\"29\":-0.07768371969112249,\"30\":-0.26801909430894055,\"31\":-0.07899997925782318,\"32\":-0.023327058033799482,\"33\":-0.047088852366827395,\"34\":-0.06504818925023952,\"35\":0.02814957365599494,\"36\":-0.1197713895499815,\"37\":0.13047997871177866,\"38\":0.2978147415702827,\"39\":0.3648031722525601,\"40\":-0.0966902820487859,\"41\":-0.20765141937713674,\"42\":-0.057412804371472254,\"43\":-0.2250505912616554,\"44\":-0.06501604943722522,\"45\":-0.14251484354681127,\"46\":-0.04625161739026563,\"47\":0.00813203231569062,\"48\":-0.27992477219772327,\"49\":-0.06480077809072551}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.08407444674064847,\"1\":-0.13874313639127447,\"2\":0.057137722711639846,\"3\":-0.23377543416857496,\"4\":-0.07876821999414024,\"5\":-0.05269454651695968,\"6\":-0.06816356482389548,\"7\":-0.15504885204414473,\"8\":-0.12072726250218094,\"9\":-0.09801459213347374,\"10\":0.08008830010045251,\"11\":0.2514447003025935,\"12\":-0.18310894831967808,\"13\":0.20861641733861247,\"14\":0.1638569743125485,\"15\":-0.24639536448664973,\"16\":-0.08781154494977335,\"17\":-0.037478732195446215,\"18\":-0.10629509454041569,\"19\":-0.005247970479589416,\"20\":-0.01855081944042503,\"21\":-0.2962332884011459,\"22\":-0.15651621842925179,\"23\":-0.07921099694381518,\"24\":-0.25780091228153923,\"25\":0.05440957853054901,\"26\":-0.035109584949041886,\"27\":0.13075139390948337,\"28\":-0.2226768827604567,\"29\":0.3065628167759994,\"30\":-0.07418150287852372,\"31\":0.24588189571980332,\"32\":-0.1887054837097094,\"33\":0.09273817135609419,\"34\":0.05505246267783362,\"35\":0.139981484882398,\"36\":0.08302366645856021,\"37\":0.26263844815369247,\"38\":-0.23638246396127993,\"39\":0.06715783677502875,\"40\":0.018467376128820143,\"41\":-0.06622703975142005,\"42\":-0.07223622541159933,\"43\":0.17535807708109608,\"44\":0.02166884567427021,\"45\":0.11201196144096101,\"46\":-0.01419263334443883,\"47\":-0.04426950485815616,\"48\":0.11327239431568199,\"49\":-0.1325815346501818}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.1274325083535853,\"1\":0.008809308165678164,\"2\":-0.004990420257879099,\"3\":-0.0009302917420032738,\"4\":0.0903366201128254,\"5\":-0.061626385028310346,\"6\":0.05127395157943591,\"7\":0.060949741608060784,\"8\":-0.19729578746715526,\"9\":0.13401980662096633,\"10\":-0.16103057515014135,\"11\":-0.119446209733265,\"12\":-0.07430656854336022,\"13\":0.2471321646408605,\"14\":-0.2636157721566468,\"15\":0.0681979963683744,\"16\":0.2125979145004069,\"17\":-0.008338102823993195,\"18\":0.1681866421605445,\"19\":-0.12675817542310747,\"20\":-0.18652798156185024,\"21\":0.10445269693221236,\"22\":-0.10727981507145545,\"23\":0.13474624283604997,\"24\":-0.2675671973455085,\"25\":-0.02766845865708762,\"26\":0.01967966016073058,\"27\":-0.033489466153179666,\"28\":0.34160982231618847,\"29\":0.02917976229368445,\"30\":-0.09114244067724506,\"31\":0.1795692386717093,\"32\":0.0031083229695662677,\"33\":-0.2778713767595223,\"34\":0.13785151249277652,\"35\":-0.07449971771784702,\"36\":-0.08762294557281239,\"37\":0.05755578502407806,\"38\":0.06410247734238803,\"39\":-0.10290138552936846,\"40\":0.12441862759335906,\"41\":0.06123611696181752,\"42\":-0.023448087419953006,\"43\":0.03462673838133483,\"44\":0.10266786482703154,\"45\":-0.0306248159455974,\"46\":-0.2665346467359321,\"47\":-0.07684900953212798,\"48\":-0.0414209967560794,\"49\":0.13136060101873567}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.06150938168108741,\"1\":0.11325732560510642,\"2\":-0.06940730328466631,\"3\":0.16144393695091658,\"4\":-0.008797830805950166,\"5\":0.053005529119230815,\"6\":0.06405550589050688,\"7\":0.06177610933825917,\"8\":-0.027588230664745413,\"9\":-0.036895410552846876,\"10\":-0.005204684409202799,\"11\":0.06562573677985527,\"12\":0.04196067253323098,\"13\":0.06589272717145024,\"14\":-0.027263763190715003,\"15\":0.17250547477159578,\"16\":0.14713309921675718,\"17\":0.08447567423229291,\"18\":0.008098777935878662,\"19\":-0.09334860654940967,\"20\":0.23832625176970856,\"21\":0.02029178551673518,\"22\":-0.011977012439206328,\"23\":-0.13022752712125793,\"24\":-0.17806309540467416,\"25\":0.10391090924229981,\"26\":-0.34461395199330014,\"27\":0.09881659615178852,\"28\":0.056690108574723765,\"29\":-0.10485457905698425,\"30\":-0.05038944303198326,\"31\":-0.07016698552775706,\"32\":0.09603515655867333,\"33\":0.07814703302517721,\"34\":0.0009424283462464006,\"35\":0.2216027097805713,\"36\":0.026810930589862867,\"37\":-0.2060733613817915,\"38\":-0.1566036688176539,\"39\":-0.0030296990501190112,\"40\":-0.02868680658620395,\"41\":-0.12180425591422808,\"42\":-0.25970239617712415,\"43\":-0.02459491176655239,\"44\":0.06433642993761131,\"45\":0.03925037275391965,\"46\":-0.050274649029840385,\"47\":-0.003123836862114018,\"48\":0.14349767033678876,\"49\":0.19568264548870737}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.17746231888188113,\"1\":0.20045664777263295,\"2\":-0.060338019316098335,\"3\":0.21693684000750307,\"4\":0.14144333807298928,\"5\":0.09087912653448058,\"6\":-0.053028157264141104,\"7\":-0.01750212577623444,\"8\":-0.03129640407261841,\"9\":0.07869668438484878,\"10\":0.08630315852968774,\"11\":-0.14440801363345762,\"12\":-0.22462366384415444,\"13\":-0.00922602386878043,\"14\":-0.1371718187680504,\"15\":-0.041412868161592356,\"16\":-0.08431832789211466,\"17\":-0.0792994609772905,\"18\":-0.373729130164818,\"19\":-0.08386996411546972,\"20\":-0.029457028500708943,\"21\":-0.0025967376226657323,\"22\":0.2986993777372991,\"23\":-0.02967522894692712,\"24\":-0.23834433015728979,\"25\":0.10607530634449362,\"26\":-0.22048738450783062,\"27\":0.14598031175595658,\"28\":-0.01068509059161213,\"29\":-0.159991360251049,\"30\":0.07832618583569873,\"31\":-0.08283893545976624,\"32\":-0.06436935038192765,\"33\":-0.02218431083983826,\"34\":0.04263885178213886,\"35\":0.15246815537633704,\"36\":0.002260781773408245,\"37\":0.004512112626818548,\"38\":0.065115406586647,\"39\":0.041981957911390734,\"40\":-0.037275962443992665,\"41\":-0.03796241685240762,\"42\":-0.215632812638788,\"43\":0.18865637766502102,\"44\":0.00003406311923414473,\"45\":-0.0182853746068209,\"46\":-0.047619869141552106,\"47\":-0.1597380482559774,\"48\":0.20834174488719062,\"49\":0.14618503251295073}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.1057088541156333,\"1\":-0.01976854279937721,\"2\":0.1600313806938618,\"3\":-0.11675869126733052,\"4\":0.16633012713861584,\"5\":-0.022684621079202636,\"6\":-0.06309228606077738,\"7\":0.06579358355449239,\"8\":-0.007820593672088354,\"9\":0.12078491076334019,\"10\":0.09389679364077638,\"11\":-0.032626786515607985,\"12\":0.13278970121406758,\"13\":-0.11582864070400388,\"14\":0.31679544208194516,\"15\":0.11114456545434732,\"16\":-0.03371871115719982,\"17\":-0.17212193892164887,\"18\":0.13139832566611195,\"19\":-0.2687075558611948,\"20\":-0.01313257081778307,\"21\":0.001530615605226867,\"22\":-0.14076674514783272,\"23\":-0.03030230146451138,\"24\":-0.17262160612399538,\"25\":-0.03646743469864123,\"26\":-0.11417585152663481,\"27\":0.051864766740024174,\"28\":-0.01779509243117357,\"29\":-0.1456324863579696,\"30\":-0.0328270247939556,\"31\":0.06783574308155275,\"32\":-0.07403120381852361,\"33\":-0.2848129888316052,\"34\":0.12243483938871427,\"35\":-0.015276797251419004,\"36\":-0.21794871651042058,\"37\":0.043245487843822226,\"38\":-0.023827867406853866,\"39\":0.056323428511336995,\"40\":0.15268062502395918,\"41\":0.0844598306792907,\"42\":0.07705201289257145,\"43\":0.1340602005372628,\"44\":-0.12652773174057372,\"45\":-0.1393151648579515,\"46\":-0.06878711881971832,\"47\":-0.0016255111709113851,\"48\":0.0707850243840207,\"49\":-0.18433341364199615}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.18818214034314087,\"1\":0.11871235680487308,\"2\":-0.07853875775023546,\"3\":-0.13569907476993884,\"4\":-0.023360257996040988,\"5\":-0.007674429835539215,\"6\":0.11518384476304912,\"7\":-0.06050253586800735,\"8\":0.10603927572272134,\"9\":0.45973117429678473,\"10\":-0.05942663512693027,\"11\":-0.004795757667781781,\"12\":0.033784274430253246,\"13\":-0.2458625064455496,\"14\":0.21941858466403028,\"15\":0.09120304081029335,\"16\":0.1966507617331368,\"17\":-0.06238944800575487,\"18\":0.24260403660079896,\"19\":-0.1704026968680094,\"20\":0.07063246033254215,\"21\":0.10287028625542727,\"22\":-0.13205721830194045,\"23\":-0.15114145338417884,\"24\":-0.15827878047943147,\"25\":-0.29165523795785764,\"26\":-0.1416401378901316,\"27\":-0.016691844919096067,\"28\":0.09429098533863561,\"29\":0.11800263935822432,\"30\":0.1491239292259451,\"31\":0.3942371605690259,\"32\":0.21461949623801668,\"33\":-0.05379392099814228,\"34\":-0.23121396487651413,\"35\":-0.06936399633083801,\"36\":-0.20039672563237962,\"37\":0.1175846354544961,\"38\":-0.13310772117535297,\"39\":0.00853614182123104,\"40\":0.08274309244168312,\"41\":0.06958165138577727,\"42\":0.0222337656577456,\"43\":0.08428498192163303,\"44\":0.02225183467083293,\"45\":0.09184531863368291,\"46\":0.20473690987605753,\"47\":0.09461572415498444,\"48\":-0.065029485689703,\"49\":-0.005190929175378987}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.2893837613932681,\"1\":-0.06667665665869377,\"2\":-0.08764271283966008,\"3\":-0.20503001927154935,\"4\":0.04817859232817157,\"5\":-0.13968959884954898,\"6\":0.3772716911534136,\"7\":-0.1464084602736542,\"8\":-0.02975338558564314,\"9\":0.19219026547743087,\"10\":0.015621500187529934,\"11\":0.28709941017900675,\"12\":-0.12685194994568466,\"13\":0.05517529054373371,\"14\":0.10254304735336062,\"15\":-0.040583947030593696,\"16\":-0.11857430171019599,\"17\":-0.09755565862593672,\"18\":0.01488713801628651,\"19\":0.08965895429172775,\"20\":-0.09354981192337289,\"21\":0.06425669416669477,\"22\":0.09190449625934419,\"23\":-0.07008000992831644,\"24\":0.4307508467721631,\"25\":0.0022735800331868546,\"26\":0.1523594922646528,\"27\":0.2480932075392493,\"28\":0.1461154563226663,\"29\":-0.11295018852538306,\"30\":-0.13176787854641855,\"31\":-0.0253776739414615,\"32\":0.009615183422516231,\"33\":0.1532157781176015,\"34\":0.006298639220020019,\"35\":-0.15276386841385167,\"36\":0.056826968970597976,\"37\":-0.006477234759709484,\"38\":0.1503660477815096,\"39\":-0.05924696686288088,\"40\":-0.1945715369128711,\"41\":0.0883954418545693,\"42\":0.17078778013979865,\"43\":0.0384591027191167,\"44\":-0.14473192473640978,\"45\":-0.03136582183036166,\"46\":-0.2529082450646899,\"47\":-0.060467995779863504,\"48\":-0.10661168974989474,\"49\":-0.3308755467434623}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.007155676926674756,\"1\":0.030411360172093463,\"2\":-0.0010572224992304944,\"3\":0.17269230642796055,\"4\":0.16340191257797818,\"5\":0.04645488065034573,\"6\":0.14316481042350618,\"7\":0.1319506569548351,\"8\":0.1384011981625903,\"9\":-0.03307279580661774,\"10\":-0.09145447948570527,\"11\":-0.011617510245468577,\"12\":0.03555311583656815,\"13\":-0.04368511721334773,\"14\":0.10585437131039334,\"15\":-0.30241627810171046,\"16\":0.17722001019002742,\"17\":-0.005084731744820275,\"18\":-0.059438936966218534,\"19\":0.188633738553726,\"20\":-0.08981961515429478,\"21\":-0.2965685713161437,\"22\":0.0024601251052584227,\"23\":0.11497706192364147,\"24\":-0.1643233951929895,\"25\":0.175454563729306,\"26\":-0.08948076351872705,\"27\":0.0063128761914637635,\"28\":0.030648973261384892,\"29\":-0.04418252046188064,\"30\":0.09193770531113625,\"31\":-0.06821247766871551,\"32\":-0.17713146624269724,\"33\":0.04147209935665368,\"34\":-0.000821380104567081,\"35\":-0.1190439202363763,\"36\":-0.07018603807409925,\"37\":-0.0766720980804321,\"38\":0.076887700885825,\"39\":-0.11730264594558104,\"40\":-0.0661593096621005,\"41\":-0.1387832531565544,\"42\":-0.16152128715682185,\"43\":0.11464152671968521,\"44\":0.1681313838718283,\"45\":-0.11042229510904235,\"46\":0.08849841352976232,\"47\":-0.1369416407081001,\"48\":-0.13002707733041588,\"49\":0.24731613836671473}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.044346462165310754,\"1\":0.050054438843965994,\"2\":0.204950117286465,\"3\":0.0030175764748113496,\"4\":0.042234346632644686,\"5\":0.08175630420742828,\"6\":-0.20891787769580433,\"7\":0.07476961022751842,\"8\":0.31065685648613617,\"9\":0.0033428462436789663,\"10\":0.010576938903210776,\"11\":0.07629009589143264,\"12\":-0.03545244466889456,\"13\":0.14763503197071112,\"14\":0.15718316028930918,\"15\":0.08299755831418315,\"16\":-0.26780816412040115,\"17\":-0.0002601953999725997,\"18\":0.04061202610356694,\"19\":-0.09089126293394953,\"20\":0.13119418853857082,\"21\":-0.21450868384590677,\"22\":-0.02293778849453384,\"23\":-0.10407622999127417,\"24\":-0.07001427578027115,\"25\":-0.31531433930357,\"26\":0.1221872950729204,\"27\":0.03612878797839433,\"28\":-0.29833343711864385,\"29\":-0.21456458974821296,\"30\":0.10888613594594422,\"31\":0.21754793655555688,\"32\":0.10068666610094022,\"33\":-0.16996407390805518,\"34\":0.0627776477225551,\"35\":-0.15764507008966025,\"36\":0.26613822133716974,\"37\":-0.10842413015038246,\"38\":0.447080783732291,\"39\":0.12116061005279888,\"40\":-0.2014336180524816,\"41\":-0.0021842578763501858,\"42\":-0.16500711104363358,\"43\":0.08626773122204587,\"44\":0.06671391928194792,\"45\":-0.18534837040787114,\"46\":-0.26832332536239795,\"47\":-0.30793434964165434,\"48\":0.08432344636684572,\"49\":-0.20822716906081318}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.0761403258294982,\"1\":-0.015596796467245247,\"2\":-0.0642842612281679,\"3\":-0.04338373335740633,\"4\":0.5112188203941543,\"5\":-0.12742053336589912,\"6\":0.11586378857179501,\"7\":-0.07466817596188792,\"8\":-0.1995593650437697,\"9\":-0.19900635055182436,\"10\":-0.024262892664016673,\"11\":-0.21728206961106716,\"12\":0.27140639663187255,\"13\":0.0610906777213106,\"14\":-0.13107793955724853,\"15\":0.08520100175080171,\"16\":-0.18553521769301878,\"17\":-0.1250069739422076,\"18\":-0.05538039139300089,\"19\":-0.30826542095544995,\"20\":0.07942549362697218,\"21\":-0.0465417140269915,\"22\":-0.2567488519077408,\"23\":0.16361695012330305,\"24\":0.0193692097628096,\"25\":-0.2595006040097845,\"26\":0.05539541553495049,\"27\":-0.09784801884714835,\"28\":-0.10177194781820939,\"29\":0.06415391036893112,\"30\":-0.12205047911681816,\"31\":-0.06051350980682861,\"32\":0.22878459146258273,\"33\":0.16627134883364908,\"34\":-0.2632907937240157,\"35\":0.006657017960804046,\"36\":0.04841502120891586,\"37\":0.19847767746151307,\"38\":0.40046841992673365,\"39\":0.1008748471502096,\"40\":-0.28744358992527175,\"41\":0.13757387964274753,\"42\":0.2659183848503623,\"43\":-0.04161994510275193,\"44\":-0.047121684700192415,\"45\":-0.20557708285198012,\"46\":-0.04252621201296663,\"47\":-0.004095788655185594,\"48\":-0.2211622592986918,\"49\":0.05152211433173007}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.08253615084062775,\"1\":-0.010907525843555243,\"2\":0.19374154411712838,\"3\":0.05598845708764459,\"4\":0.22835944679885375,\"5\":-0.04464656751017737,\"6\":0.17344041937404642,\"7\":0.15712344808074288,\"8\":0.1369082124776541,\"9\":0.1783347532238276,\"10\":-0.08187296242486175,\"11\":0.024084595859896696,\"12\":-0.09568437222036927,\"13\":0.20353578014029064,\"14\":-0.10197158310293286,\"15\":-0.18042649661150906,\"16\":0.02273785599936521,\"17\":0.04546100170418076,\"18\":0.09485976554845482,\"19\":-0.13959406943806904,\"20\":0.13480512648583753,\"21\":0.10572792520358361,\"22\":-0.10762098981707312,\"23\":0.1427524735249244,\"24\":-0.11601861446524384,\"25\":-0.02676718141840779,\"26\":0.14959886753748614,\"27\":0.14097248830527792,\"28\":0.07075267397618906,\"29\":-0.15300933081226015,\"30\":0.056965452242624344,\"31\":0.17066847180119413,\"32\":0.2567965979736894,\"33\":0.0990728809086924,\"34\":-0.11371415468821085,\"35\":0.17294260532485212,\"36\":0.012835710635697965,\"37\":-0.011985849110217158,\"38\":-0.07841973723956404,\"39\":-0.15914893661896995,\"40\":0.1429064353849475,\"41\":0.002736360076035926,\"42\":-0.06807602453608709,\"43\":-0.05161498770684261,\"44\":0.04163239309754489,\"45\":0.09906846928821647,\"46\":-0.06922878340253481,\"47\":0.12303662623221905,\"48\":0.13755420101472604,\"49\":0.16045312119046617}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.12563356656290955,\"1\":-0.1853713366675693,\"2\":0.031563811764191874,\"3\":-0.0849761992918741,\"4\":0.1568683139123595,\"5\":0.16566884484400668,\"6\":0.048777942057950704,\"7\":-0.02364388230614753,\"8\":-0.04998197949273259,\"9\":-0.11147866941262963,\"10\":-0.15266651794256691,\"11\":-0.2691325825448526,\"12\":0.14728543933464622,\"13\":0.0446985214371741,\"14\":0.07578356169157083,\"15\":0.06233768261407479,\"16\":-0.06717936827565611,\"17\":-0.15134117830581864,\"18\":-0.1367834170972571,\"19\":0.0667236028697826,\"20\":-0.05588305005271063,\"21\":-0.013153481532895254,\"22\":-0.013696112808339966,\"23\":0.17177059348524312,\"24\":0.13233240949215275,\"25\":0.4482938944235159,\"26\":0.48027934910584447,\"27\":0.05771902324535139,\"28\":0.059154137722576834,\"29\":-0.02901468912083931,\"30\":-0.18693362557273138,\"31\":-0.24879361152051954,\"32\":-0.04960294198734707,\"33\":0.10711313840387551,\"34\":0.19911478391471243,\"35\":-0.11456070462286568,\"36\":0.11388965887316098,\"37\":0.1467889566501076,\"38\":0.14093654138334105,\"39\":0.04967004961704633,\"40\":0.06734703731529414,\"41\":0.1529283582957386,\"42\":0.020431237319744527,\"43\":0.11035292140663394,\"44\":-0.24883938285350773,\"45\":0.04822056377133267,\"46\":-0.0671016461985847,\"47\":-0.13251879330965333,\"48\":-0.23038681625646917,\"49\":-0.10953534767831195}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.042731417204298516,\"1\":-0.15049316213266078,\"2\":0.008070724863982501,\"3\":-0.12740690215575104,\"4\":0.1092206078573691,\"5\":0.14034362158455285,\"6\":-0.14491247001609509,\"7\":-0.19023904261812227,\"8\":-0.14192081004373666,\"9\":-0.04092425437980338,\"10\":-0.2433921324904964,\"11\":0.01483461262137484,\"12\":-0.2601916446883009,\"13\":-0.0028068379808109975,\"14\":0.06928666177569902,\"15\":-0.03750463175174669,\"16\":0.1599993099067572,\"17\":-0.10817797090109359,\"18\":0.10480682063427742,\"19\":-0.034179577462683505,\"20\":-0.1342609637276207,\"21\":-0.009998198899774475,\"22\":-0.02985514796491119,\"23\":-0.23257629085784157,\"24\":0.047404514621257755,\"25\":-0.1858246865866774,\"26\":-0.10744231689323928,\"27\":0.036694037219219475,\"28\":-0.04224574770643623,\"29\":0.06885799776580223,\"30\":-0.0786160202518058,\"31\":-0.12560650895204292,\"32\":0.1209256935676509,\"33\":0.04784364916440818,\"34\":-0.15002144242179424,\"35\":0.10435549267558629,\"36\":-0.013324033299076185,\"37\":0.07489305145284708,\"38\":-0.060504085234885596,\"39\":-0.07079948894553989,\"40\":-0.032539115214895505,\"41\":0.12679639692385666,\"42\":-0.02484669150217751,\"43\":0.10898305534028079,\"44\":0.0020064348826419956,\"45\":-0.09522009576932065,\"46\":-0.06588249243151802,\"47\":0.14840232232320757,\"48\":-0.15872003449965968,\"49\":0.000235312291367979}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.10170837409944918,\"1\":0.1992372263345654,\"2\":0.020260054561466456,\"3\":0.13317567551854637,\"4\":0.24122051976536887,\"5\":-0.016043689191950802,\"6\":0.13133425099427104,\"7\":-0.10666093007759907,\"8\":0.21503644845558165,\"9\":-0.10801501582896207,\"10\":0.019896034611716917,\"11\":0.07840628399014754,\"12\":-0.024379677772211276,\"13\":-0.24278130919826077,\"14\":0.0029732663076162615,\"15\":0.03283666063650994,\"16\":0.2001166698723027,\"17\":-0.09096082410462958,\"18\":-0.013649847622860157,\"19\":0.14823445257536483,\"20\":0.03946020055598051,\"21\":-0.03648623483916575,\"22\":0.014187801955225844,\"23\":0.010688707158316397,\"24\":-0.2149361210170196,\"25\":0.03760117574056101,\"26\":-0.21468714879791237,\"27\":-0.0531708919879901,\"28\":0.027209711208887707,\"29\":0.046086635577650366,\"30\":0.1072073611297216,\"31\":-0.052209945647233184,\"32\":-0.05152899376221194,\"33\":0.15384316357217673,\"34\":-0.1150081767782475,\"35\":0.08983242750385727,\"36\":-0.2509443063935597,\"37\":-0.08133810379866632,\"38\":-0.2509607805443802,\"39\":-0.11202283289102824,\"40\":0.11866674200885183,\"41\":-0.014722120120800437,\"42\":-0.06326625651385631,\"43\":-0.08757244582393699,\"44\":0.03395094263315658,\"45\":0.06251827086613934,\"46\":-0.06742234433583642,\"47\":0.060758633389797194,\"48\":0.024335181104572806,\"49\":0.10256841178394852}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.08815113357494879,\"1\":0.16713376983596717,\"2\":0.013696662795354177,\"3\":0.06913645087739151,\"4\":0.16191669563843017,\"5\":-0.03379552891615279,\"6\":0.06640578787027321,\"7\":-0.19069334384272402,\"8\":0.1350939263696948,\"9\":-0.047830015565776283,\"10\":0.08181498399429428,\"11\":-0.1420594689973187,\"12\":0.17839473225288302,\"13\":-0.1573992573707544,\"14\":0.1386971978512901,\"15\":-0.16964383910660158,\"16\":0.05751948515149164,\"17\":0.010283757726584132,\"18\":0.13451884188523733,\"19\":-0.03592778458084881,\"20\":0.0943922874855318,\"21\":0.031738720663335884,\"22\":0.19280427886871487,\"23\":-0.10246350364010813,\"24\":-0.17178650046357946,\"25\":-0.0032053334685720226,\"26\":0.29371815185603584,\"27\":-0.033250330288591284,\"28\":-0.09149991907861432,\"29\":0.05237746664062273,\"30\":-0.3809857028248231,\"31\":-0.0935160697985805,\"32\":-0.028243240653991964,\"33\":-0.08568785779282172,\"34\":0.09365830808910476,\"35\":-0.09480476934672016,\"36\":-0.13128041751909894,\"37\":0.12905413354698747,\"38\":-0.14722338028228188,\"39\":-0.024802147623135914,\"40\":-0.0025330609609035665,\"41\":-0.05262531957249671,\"42\":0.028531114026354425,\"43\":-0.3137788240483627,\"44\":0.1701994636962113,\"45\":-0.05498473213896983,\"46\":-0.13723845433913665,\"47\":-0.07361571197415041,\"48\":-0.18854203581105813,\"49\":0.15114362302376852}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.05074716390727825,\"1\":0.03705638176584101,\"2\":0.1559324506750397,\"3\":0.07866711543789792,\"4\":0.017545948765847252,\"5\":0.10545855439510197,\"6\":0.1643285262931136,\"7\":0.04352302844473841,\"8\":0.011115167364832175,\"9\":0.03567282565776592,\"10\":0.07264070814989684,\"11\":-0.022182359002159275,\"12\":0.09251336427242478,\"13\":-0.09581748373293529,\"14\":-0.0908311650549351,\"15\":0.07511054534176953,\"16\":0.223525232822913,\"17\":-0.02130181827316807,\"18\":-0.08179055844455595,\"19\":-0.14539318802191736,\"20\":0.21482761167874706,\"21\":-0.13159307152581634,\"22\":0.08052378903289775,\"23\":0.008599597045961383,\"24\":0.13621267039028048,\"25\":-0.16377051900926248,\"26\":0.15692037679561974,\"27\":0.1452187161563098,\"28\":-0.21027373899123522,\"29\":-0.16234880431217827,\"30\":-0.13262159741628993,\"31\":0.09988526379128798,\"32\":0.02197077172651021,\"33\":-0.09010585152533791,\"34\":0.07295147519716128,\"35\":-0.23479176741614766,\"36\":0.15799556575767953,\"37\":-0.06762181262806508,\"38\":-0.03146263764652533,\"39\":-0.04497431581393414,\"40\":0.046334104637375965,\"41\":0.33475692815441505,\"42\":-0.029613830686048368,\"43\":-0.04634559293443508,\"44\":-0.14270667210939722,\"45\":0.18886859877979564,\"46\":-0.10417945664662495,\"47\":0.31234214848968106,\"48\":-0.10342878202977496,\"49\":-0.13900368912644548}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.3060327079054223,\"1\":-0.07048941097212515,\"2\":-0.08341603448856622,\"3\":0.1881799623095428,\"4\":-0.09222109254106697,\"5\":-0.07008574045525574,\"6\":-0.20561899033589906,\"7\":-0.05590658606010005,\"8\":-0.033553439929746944,\"9\":-0.07078767826833293,\"10\":-0.007362100513967832,\"11\":0.04353787646200073,\"12\":0.041389106086413316,\"13\":-0.0997022754654419,\"14\":0.26924978303136377,\"15\":-0.018936460012673392,\"16\":0.09421297730204135,\"17\":0.02177356045088458,\"18\":0.08194594214281348,\"19\":0.0604008226098707,\"20\":0.14900864498251848,\"21\":0.0858847289441252,\"22\":0.02430550610597307,\"23\":0.056453804567154604,\"24\":0.1271494107795425,\"25\":0.021092176334857982,\"26\":-0.10058578497382184,\"27\":-0.055748779688512023,\"28\":0.07480990559184446,\"29\":0.0031368104185809896,\"30\":0.15397544750712977,\"31\":0.0982932275928155,\"32\":0.056845672168991564,\"33\":0.10310619561740894,\"34\":-0.0747593468405996,\"35\":0.10156738751426359,\"36\":-0.1932234807479668,\"37\":-0.20980471598335654,\"38\":-0.27618010517157504,\"39\":-0.10221596808764812,\"40\":0.06627627903220978,\"41\":-0.12872013013024286,\"42\":0.005806001293389758,\"43\":-0.05718714298452034,\"44\":-0.10167314485517205,\"45\":-0.04709043593903865,\"46\":-0.3136316528250978,\"47\":0.11182468587114268,\"48\":0.0567398828720862,\"49\":0.10593704095545081}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.05592044825950743,\"1\":-0.1863302186253155,\"2\":-0.02595063735171702,\"3\":-0.1305827185376541,\"4\":-0.08946460506753998,\"5\":-0.1523253932861505,\"6\":0.25929925083627225,\"7\":0.07543926501561721,\"8\":0.23684765522702367,\"9\":0.11302986875326541,\"10\":-0.07736166532344262,\"11\":0.2021384130944548,\"12\":0.1782535827905287,\"13\":0.10454220266665422,\"14\":-0.16686584508750857,\"15\":-0.11848155224593289,\"16\":-0.09335202240969591,\"17\":-0.05209926375130208,\"18\":0.08738793913877606,\"19\":0.01152820276932901,\"20\":0.10180798545862024,\"21\":-0.14088172882406164,\"22\":-0.057911928553707095,\"23\":-0.14678539616435365,\"24\":0.2425883105991249,\"25\":-0.003479160030571553,\"26\":0.2883915884785347,\"27\":-0.20447667982739276,\"28\":0.06153809784112446,\"29\":-0.04017422967441595,\"30\":-0.33337506341146356,\"31\":-0.19602915677541996,\"32\":0.03792299055212368,\"33\":-0.052199846210716834,\"34\":0.09773180316250085,\"35\":0.23251762622702724,\"36\":0.21259476932814242,\"37\":0.024931835009093562,\"38\":0.4846849487372203,\"39\":0.13291187346779337,\"40\":-0.20231184787786538,\"41\":-0.09785478551057922,\"42\":0.0766820331236868,\"43\":-0.06829764203927147,\"44\":-0.18548015536509674,\"45\":0.1483281073281258,\"46\":-0.2812718928166674,\"47\":-0.05796220481028413,\"48\":0.06011279872351181,\"49\":0.09620398273926345}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.07619068884451745,\"1\":0.20797323871093287,\"2\":0.05324132316538845,\"3\":-0.14345571378964658,\"4\":-0.07901550706327468,\"5\":0.0734679389709476,\"6\":-0.018334013882567727,\"7\":0.3543098089489324,\"8\":0.022592793457297807,\"9\":0.06344074987625123,\"10\":0.09406675748015009,\"11\":0.12017638012333208,\"12\":-0.013354287791354828,\"13\":-0.06378783523498116,\"14\":-0.19362251367623676,\"15\":-0.0790894612184441,\"16\":0.13443632410078477,\"17\":0.010255456702181604,\"18\":-0.04123743376950679,\"19\":-0.1282078792282458,\"20\":-0.04468809099579367,\"21\":-0.32403002252218366,\"22\":0.09222653611061177,\"23\":0.08626109889374194,\"24\":0.03320982700278411,\"25\":-0.12250065447115227,\"26\":-0.09658117194996742,\"27\":0.121838728924778,\"28\":-0.06272207453403847,\"29\":-0.04264673150076485,\"30\":-0.19131171030422364,\"31\":-0.2977548101187311,\"32\":0.11763782316124866,\"33\":-0.187173272404777,\"34\":-0.1645819012601088,\"35\":0.23583111384280767,\"36\":0.13516713667753502,\"37\":-0.3147149517204107,\"38\":0.03320801379777085,\"39\":-0.22121739768932688,\"40\":0.023743295239459537,\"41\":0.0770296717084656,\"42\":0.1118415281894743,\"43\":0.09630526244310088,\"44\":-0.05134038212869229,\"45\":-0.04256838363904196,\"46\":0.26641686929177977,\"47\":0.06685877371210625,\"48\":-0.004652570769851462,\"49\":-0.021746869742666146}}],\"biases\":{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.09583723674972991,\"1\":0.10172198546225578,\"2\":0.10508576500404114,\"3\":0.0997887526537531,\"4\":0.09586886213500415,\"5\":0.09822043436234278,\"6\":0.1,\"7\":0.09785732085320469,\"8\":0.10137510815170177,\"9\":0.09906690203542823,\"10\":0.10294287423005626,\"11\":0.10813801464397854,\"12\":0.09657573545917035,\"13\":0.09737023226903797,\"14\":0.11107629630534062,\"15\":0.10001867719622626,\"16\":0.1,\"17\":0.1050794074969655,\"18\":0.10000617007978373,\"19\":0.094971244147702,\"20\":0.10184629130400912,\"21\":0.10249220768535605,\"22\":0.1,\"23\":0.09868164846440258,\"24\":0.0887579629516913,\"25\":0.09878824387286479,\"26\":0.09635625258953616,\"27\":0.1,\"28\":0.10436047081343452,\"29\":0.1,\"30\":0.10397679172539417,\"31\":0.10074045864123024,\"32\":0.09676983821325687,\"33\":0.10020598753209742,\"34\":0.09958008986401082,\"35\":0.09496914154402504,\"36\":0.09314573658506024,\"37\":0.10559069963013414,\"38\":0.09810205094643312,\"39\":0.09782972469919748,\"40\":0.10698856192630932,\"41\":0.09359539241992947,\"42\":0.09731507911360866,\"43\":0.1,\"44\":0.10007885481800377,\"45\":0.0983742994355999,\"46\":0.10159573312102022,\"47\":0.1031292705157019,\"48\":0.10616650822460456,\"49\":0.10095574263617262}}},{\"out_depth\":50,\"out_sx\":1,\"out_sy\":1,\"layer_type\":\"relu\"},{\"out_depth\":5,\"out_sx\":1,\"out_sy\":1,\"layer_type\":\"fc\",\"num_inputs\":50,\"l1_decay_mul\":0,\"l2_decay_mul\":1,\"filters\":[{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.038606685219441376,\"1\":-0.3416158712852223,\"2\":-0.01692201474487361,\"3\":0.10767023609837634,\"4\":-0.05543428030586246,\"5\":-0.03955899230977059,\"6\":0.2662216167382007,\"7\":0.29965509599883733,\"8\":0.1381593687816438,\"9\":0.12061571423453554,\"10\":-0.037085982013187836,\"11\":-0.21726241968772078,\"12\":-0.297597847632926,\"13\":0.17850614551729416,\"14\":0.22957472009340252,\"15\":0.4511644119403722,\"16\":0.10922107676979975,\"17\":0.26233082746867753,\"18\":-0.12695120506344568,\"19\":0.03559055595374121,\"20\":-0.1474692595887756,\"21\":-0.17318191655602277,\"22\":-0.13228734930644712,\"23\":0.027713824064595275,\"24\":-0.15983912223450264,\"25\":0.08438147417792019,\"26\":-0.047452476629587514,\"27\":-0.16028557792759313,\"28\":0.07877506845084814,\"29\":0.19614285823318828,\"30\":0.4267675130160026,\"31\":0.18100858645260523,\"32\":-0.05150375653382926,\"33\":0.09017588077495269,\"34\":0.11259542457332962,\"35\":-0.19707361816727256,\"36\":-0.04481078173761631,\"37\":0.12167143692522649,\"38\":-0.08545924044350409,\"39\":0.037965572451065396,\"40\":0.37103800453391816,\"41\":0.08063728798237872,\"42\":0.3542291025090519,\"43\":-0.08704621805207904,\"44\":-0.19074562258201372,\"45\":-0.0075898349816231735,\"46\":0.007776603612773436,\"47\":-0.2300386727746921,\"48\":0.27297486547452565,\"49\":0.11535195491522679}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":0.13640446529737826,\"1\":-0.36971146605671895,\"2\":0.03476210639487296,\"3\":-0.2942881578329163,\"4\":0.14598706266543796,\"5\":-0.18304657977902258,\"6\":0.25921810687910923,\"7\":-0.050398221409099005,\"8\":0.10512561904294221,\"9\":0.1403402630626359,\"10\":-0.035846501330044585,\"11\":-0.20529738003982823,\"12\":-0.31322919471569777,\"13\":0.22730556421512452,\"14\":0.16103704587882786,\"15\":0.08650979236590578,\"16\":-0.1951188423439605,\"17\":0.18201400646534602,\"18\":0.08904009301006213,\"19\":0.061232647591186413,\"20\":-0.09278910207725843,\"21\":0.005430072748545631,\"22\":0.003279980445939515,\"23\":-0.038385536456497574,\"24\":-0.1284455243018669,\"25\":-0.14510933142121954,\"26\":-0.0972191044010523,\"27\":-0.03790734058149046,\"28\":0.11228621304200716,\"29\":-0.06074366930841655,\"30\":0.5270920176166591,\"31\":0.059946371350775254,\"32\":0.06731559283697976,\"33\":-0.34560025330328736,\"34\":0.14609519196058168,\"35\":0.06601161545095431,\"36\":-0.38791364537939116,\"37\":0.20093646153078745,\"38\":0.027418060690699426,\"39\":0.18192136972713954,\"40\":0.39649185491736255,\"41\":0.09418539340872353,\"42\":0.10442384388335779,\"43\":0.0974482353349394,\"44\":-0.16260563848558252,\"45\":0.1988880450309425,\"46\":0.18095435267200885,\"47\":-0.07590022753972156,\"48\":0.4093321668461313,\"49\":0.1115983384214335}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.1017630734627846,\"1\":-0.11606772082263635,\"2\":0.10639600885892288,\"3\":0.13793142483570295,\"4\":-0.13079207825983763,\"5\":0.10376767638851747,\"6\":-0.1249663706427634,\"7\":0.07627942638560486,\"8\":0.3537008965685664,\"9\":0.0011869993274896404,\"10\":0.16879384061252053,\"11\":-0.12487884514217093,\"12\":-0.06133670753092269,\"13\":0.13816288021118583,\"14\":0.009253780080316696,\"15\":0.2714180606236335,\"16\":0.05239852709183428,\"17\":0.40783154399175764,\"18\":-0.06730977445320153,\"19\":0.07899769031614556,\"20\":0.013390213333519916,\"21\":-0.15829868483917056,\"22\":-0.050780711692468075,\"23\":-0.26489619332104525,\"24\":-0.02790665914617481,\"25\":-0.15027163873460908,\"26\":0.024094011997200505,\"27\":-0.10089896352978912,\"28\":0.17139243903745552,\"29\":0.004247869152511552,\"30\":0.3341587569184236,\"31\":-0.020122967991463125,\"32\":0.005195604783928064,\"33\":0.044820543116826005,\"34\":-0.17098489819150434,\"35\":-0.20175326161437823,\"36\":-0.2900020645940205,\"37\":0.14739477969484052,\"38\":0.11569434168499743,\"39\":-0.024172552648227243,\"40\":0.09458226279592813,\"41\":-0.2381298529640961,\"42\":0.06892300281241698,\"43\":0.13938299452448127,\"44\":0.052783176071680586,\"45\":0.1973831229948573,\"46\":-0.13214541921590306,\"47\":-0.13999467291193163,\"48\":0.5260443614134594,\"49\":-0.031983863912040784}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.23545922743318778,\"1\":-0.2438535250345161,\"2\":0.39131044851860347,\"3\":-0.10383599235665328,\"4\":-0.1004567046880051,\"5\":-0.05757285813510648,\"6\":0.09247473904618041,\"7\":0.11473992134686602,\"8\":0.09830173744718788,\"9\":0.057906663986466766,\"10\":0.2756345485050996,\"11\":-0.033794373905444,\"12\":-0.0611531879889028,\"13\":-0.2834756303674794,\"14\":0.28932959095354865,\"15\":0.09594481443060618,\"16\":-0.0853406624253298,\"17\":0.2865461768146097,\"18\":0.15047163127110286,\"19\":-0.09898474241254958,\"20\":-0.16620446685620044,\"21\":-0.08013947122224974,\"22\":0.08030902294759079,\"23\":0.15174540991763158,\"24\":-0.14269402144150684,\"25\":-0.004947774068134641,\"26\":-0.15231016242990614,\"27\":-0.12002853654824178,\"28\":-0.07598796307197893,\"29\":-0.12262983625152764,\"30\":0.21884742828658318,\"31\":-0.05784157442861359,\"32\":0.12246295823563509,\"33\":0.043372361734921296,\"34\":0.13134169469512003,\"35\":-0.11200456789339981,\"36\":-0.15319283331285918,\"37\":0.1994586822044907,\"38\":0.24434951510567532,\"39\":-0.23253310076266664,\"40\":0.10426649292682502,\"41\":0.137836476637596,\"42\":0.1327180407352545,\"43\":0.015822750730107697,\"44\":-0.021565852258860284,\"45\":0.10845574951370777,\"46\":-0.09303492385542522,\"47\":0.036178461166220414,\"48\":0.22874937715309798,\"49\":-0.040851098135790874}},{\"sx\":1,\"sy\":1,\"depth\":50,\"w\":{\"0\":-0.13940740856683664,\"1\":-0.3541552710691714,\"2\":0.06822643373471192,\"3\":-0.0628938069430673,\"4\":0.05700102144009753,\"5\":-0.18855031594432642,\"6\":-0.04234451126504622,\"7\":-0.09651578739715957,\"8\":0.10605300683178161,\"9\":-0.0897218971167401,\"10\":-0.05801959772495126,\"11\":0.1488395067004094,\"12\":-0.31632841578890325,\"13\":0.09143657738601103,\"14\":0.18768207762203115,\"15\":0.06463661308932604,\"16\":-0.12460036027247824,\"17\":-0.0442352801497007,\"18\":0.024017385367595383,\"19\":-0.045371649608848444,\"20\":0.18319989709927917,\"21\":0.02991096537026292,\"22\":0.07716938139476143,\"23\":-0.1457746737865269,\"24\":-0.15951510304991978,\"25\":0.09116178540374022,\"26\":0.016935061528146667,\"27\":0.026606901059175257,\"28\":0.19878842032095578,\"29\":-0.13189879649905883,\"30\":0.2944821251560423,\"31\":0.05833191204409146,\"32\":-0.0705637935898818,\"33\":-0.06764509195136784,\"34\":-0.07709131792935876,\"35\":-0.09113007752908074,\"36\":-0.07497135493264737,\"37\":0.19705071727078374,\"38\":-0.2926083315394679,\"39\":0.09163308723185175,\"40\":0.30533230357591556,\"41\":-0.025118096079164952,\"42\":-0.025217477935271237,\"43\":-0.06645779931851822,\"44\":0.25905187367493865,\"45\":-0.0931755876388544,\"46\":0.0936281752723008,\"47\":-0.24002027522597225,\"48\":0.24084817350249982,\"49\":0.1060167482825272}}],\"biases\":{\"sx\":1,\"sy\":1,\"depth\":5,\"w\":{\"0\":0.10262815711047431,\"1\":0.08446132099085789,\"2\":0.10808705282265585,\"3\":0.1233941124063723,\"4\":0.15530689938020373}}},{\"out_depth\":5,\"out_sx\":1,\"out_sy\":1,\"layer_type\":\"regression\",\"num_inputs\":5}]}\r\n   </textarea>\r\n   <br />\r\n   \r\n   </div>\r\n </body>\r\n</html>\r\n"
  },
  {
    "path": "demo/speedtest.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>Simple speed test</title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"author\" content=\"\">\n\n<script src=\"../build/convnet.js\"></script>\n\n<script>\n\nfunction logEvent(str) {\n  console.log(str);\n  var d = document.createElement('div');\n  d.innerHTML = str;\n  document.getElementById('result').appendChild(d);\n}\n\nn = 0;\ndtall = 0;\nfunction runExample() {\n\n  var t0 = +new Date();\n  layer.forward(x);\n  //layer.backward();\n  var t1 = +new Date();\n  var diff = t1 - t0;\n  dtall += diff;\n  n++;\n\n  logEvent('ran example ' + n + ' in ' + diff + 'ms, estimated average = ' + (dtall / n).toFixed(3) + 'ms');\n}\n\nfunction start() {\n\n  // Conv Layer definition used in convnet benchmarks\n  opt = { in_sx:128, in_sy:128, in_depth:3, sx:11, filters:96, stride: 1, pad: 0};\n  layer = new convnetjs.ConvLayer(opt);\n  x = new convnetjs.Vol(128, 128, 3);\n\n  run1i = setInterval(runExample, 5); // start\n}\n</script>\n</head>\n<body>\n  <button onclick=\"start()\">Convolution Test Start</button>\n  <button onclick=\"window.clearInterval(run1i);\">Stop</button>\n  <div id=\"result\"></div>\n</body>\n</html>\n\n\n\n"
  },
  {
    "path": "demo/trainers.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n  <title>ConvNetJS Trainer Comparison on MNIST</title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"author\" content=\"\">\n  <link rel=\"stylesheet\" href=\"css/style.css\">\n\n<script src=\"js/jquery-1.8.3.min.js\"></script>\n<script src=\"../build/vis.js\"></script>\n<script src=\"../build/util.js\"></script>\n<script src=\"../build/convnet.js\"></script>\n<script src=\"mnist/mnist_labels.js\"></script>\n<script src=\"js/trainers.js\"></script>\n\n</head>\n<body>\n  <div id=\"wrap\">\n  <h2 style=\"text-align: center;\"><a href=\"http://cs.stanford.edu/people/karpathy/convnetjs/\">ConvNetJS</a> Trainer demo on MNIST</h2>\n  <h1>Description</h1>\n  <p>\n    This demo lets you evaluate multiple trainers against each other on MNIST. By default I've set up a little benchmark that puts SGD/SGD with momentum/Adam/Adagrad/Adadelta/Nesterov against each other. For reference math and explanations on these refer to Matthew Zeiler's <a href=\"http://www.matthewzeiler.com/pubs/googleTR2012/googleTR2012.pdf\">Adadelta paper</a> (Windowgrad is Idea #1 in the paper). In my own experience, Adagrad/Adadelta are \"safer\" because they don't depend so strongly on setting of learning rates (with Adadelta being slightly better), but well-tuned SGD+Momentum almost always converges faster and at better final values.\n  </p>\n  <p>Report questions/bugs/suggestions to <a href=\"https://twitter.com/karpathy\">@karpathy</a>.</p>\n\n  <textarea id=\"layerdef\" style=\"width:100%; height:400px;\">\n  </textarea>\n  <br /><br  />\n  <input id=\"buttontp\" type=\"submit\" value=\"re-run\" onclick=\"reload();\" style=\"width: 300px; height: 50px;\"/>\n\n  <h1>Loss vs. Number of examples seen</h1>\n  <canvas id=\"lossgraph\" width=\"800\" height=\"400\"></canvas>\n\n  <h1>Testing Accuracy vs. Number of examples seen</h1>\n  <canvas id=\"testaccgraph\" width=\"800\" height=\"400\"></canvas>\n\n  <h1>Training Accuracy vs. Number of examples seen</h1>\n  <canvas id=\"trainaccgraph\" width=\"800\" height=\"400\"></canvas>\n\n  </div>\n</body>\n</html>\n\n\n\n"
  },
  {
    "path": "src/convnet_export.js",
    "content": "(function(lib) {\n  \"use strict\";\n  if (typeof module === \"undefined\" || typeof module.exports === \"undefined\") {\n    window.convnetjs = lib; // in ordinary browser attach library to window\n  } else {\n    module.exports = lib; // in nodejs\n  }\n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_init.js",
    "content": "var convnetjs = convnetjs || { REVISION: 'ALPHA' };\n"
  },
  {
    "path": "src/convnet_layers_dotproducts.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  // This file contains all layers that do dot products with input,\n  // but usually in a different connectivity pattern and weight sharing\n  // schemes: \n  // - FullyConn is fully connected dot products \n  // - ConvLayer does convolutions (so weight sharing spatially)\n  // putting them together in one file because they are very similar\n  var ConvLayer = function(opt) {\n    var opt = opt || {};\n\n    // required\n    this.out_depth = opt.filters;\n    this.sx = opt.sx; // filter size. Should be odd if possible, it's cleaner.\n    this.in_depth = opt.in_depth;\n    this.in_sx = opt.in_sx;\n    this.in_sy = opt.in_sy;\n    \n    // optional\n    this.sy = typeof opt.sy !== 'undefined' ? opt.sy : this.sx;\n    this.stride = typeof opt.stride !== 'undefined' ? opt.stride : 1; // stride at which we apply filters to input volume\n    this.pad = typeof opt.pad !== 'undefined' ? opt.pad : 0; // amount of 0 padding to add around borders of input volume\n    this.l1_decay_mul = typeof opt.l1_decay_mul !== 'undefined' ? opt.l1_decay_mul : 0.0;\n    this.l2_decay_mul = typeof opt.l2_decay_mul !== 'undefined' ? opt.l2_decay_mul : 1.0;\n\n    // computed\n    // note we are doing floor, so if the strided convolution of the filter doesnt fit into the input\n    // volume exactly, the output volume will be trimmed and not contain the (incomplete) computed\n    // final application.\n    this.out_sx = Math.floor((this.in_sx + this.pad * 2 - this.sx) / this.stride + 1);\n    this.out_sy = Math.floor((this.in_sy + this.pad * 2 - this.sy) / this.stride + 1);\n    this.layer_type = 'conv';\n\n    // initializations\n    var bias = typeof opt.bias_pref !== 'undefined' ? opt.bias_pref : 0.0;\n    this.filters = [];\n    for(var i=0;i<this.out_depth;i++) { this.filters.push(new Vol(this.sx, this.sy, this.in_depth)); }\n    this.biases = new Vol(1, 1, this.out_depth, bias);\n  }\n  ConvLayer.prototype = {\n    forward: function(V, is_training) {\n      // optimized code by @mdda that achieves 2x speedup over previous version\n\n      this.in_act = V;\n      var A = new Vol(this.out_sx |0, this.out_sy |0, this.out_depth |0, 0.0);\n      \n      var V_sx = V.sx |0;\n      var V_sy = V.sy |0;\n      var xy_stride = this.stride |0;\n\n      for(var d=0;d<this.out_depth;d++) {\n        var f = this.filters[d];\n        var x = -this.pad |0;\n        var y = -this.pad |0;\n        for(var ay=0; ay<this.out_sy; y+=xy_stride,ay++) {  // xy_stride\n          x = -this.pad |0;\n          for(var ax=0; ax<this.out_sx; x+=xy_stride,ax++) {  // xy_stride\n\n            // convolve centered at this particular location\n            var a = 0.0;\n            for(var fy=0;fy<f.sy;fy++) {\n              var oy = y+fy; // coordinates in the original input array coordinates\n              for(var fx=0;fx<f.sx;fx++) {\n                var ox = x+fx;\n                if(oy>=0 && oy<V_sy && ox>=0 && ox<V_sx) {\n                  for(var fd=0;fd<f.depth;fd++) {\n                    // avoid function call overhead (x2) for efficiency, compromise modularity :(\n                    a += f.w[((f.sx * fy)+fx)*f.depth+fd] * V.w[((V_sx * oy)+ox)*V.depth+fd];\n                  }\n                }\n              }\n            }\n            a += this.biases.w[d];\n            A.set(ax, ay, d, a);\n          }\n        }\n      }\n      this.out_act = A;\n      return this.out_act;\n    },\n    backward: function() {\n\n      var V = this.in_act;\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt bottom data, we're about to fill it\n\n      var V_sx = V.sx |0;\n      var V_sy = V.sy |0;\n      var xy_stride = this.stride |0;\n\n      for(var d=0;d<this.out_depth;d++) {\n        var f = this.filters[d];\n        var x = -this.pad |0;\n        var y = -this.pad |0;\n        for(var ay=0; ay<this.out_sy; y+=xy_stride,ay++) {  // xy_stride\n          x = -this.pad |0;\n          for(var ax=0; ax<this.out_sx; x+=xy_stride,ax++) {  // xy_stride\n\n            // convolve centered at this particular location\n            var chain_grad = this.out_act.get_grad(ax,ay,d); // gradient from above, from chain rule\n            for(var fy=0;fy<f.sy;fy++) {\n              var oy = y+fy; // coordinates in the original input array coordinates\n              for(var fx=0;fx<f.sx;fx++) {\n                var ox = x+fx;\n                if(oy>=0 && oy<V_sy && ox>=0 && ox<V_sx) {\n                  for(var fd=0;fd<f.depth;fd++) {\n                    // avoid function call overhead (x2) for efficiency, compromise modularity :(\n                    var ix1 = ((V_sx * oy)+ox)*V.depth+fd;\n                    var ix2 = ((f.sx * fy)+fx)*f.depth+fd;\n                    f.dw[ix2] += V.w[ix1]*chain_grad;\n                    V.dw[ix1] += f.w[ix2]*chain_grad;\n                  }\n                }\n              }\n            }\n            this.biases.dw[d] += chain_grad;\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      var response = [];\n      for(var i=0;i<this.out_depth;i++) {\n        response.push({params: this.filters[i].w, grads: this.filters[i].dw, l2_decay_mul: this.l2_decay_mul, l1_decay_mul: this.l1_decay_mul});\n      }\n      response.push({params: this.biases.w, grads: this.biases.dw, l1_decay_mul: 0.0, l2_decay_mul: 0.0});\n      return response;\n    },\n    toJSON: function() {\n      var json = {};\n      json.sx = this.sx; // filter size in x, y dims\n      json.sy = this.sy;\n      json.stride = this.stride;\n      json.in_depth = this.in_depth;\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.l1_decay_mul = this.l1_decay_mul;\n      json.l2_decay_mul = this.l2_decay_mul;\n      json.pad = this.pad;\n      json.filters = [];\n      for(var i=0;i<this.filters.length;i++) {\n        json.filters.push(this.filters[i].toJSON());\n      }\n      json.biases = this.biases.toJSON();\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.sx = json.sx; // filter size in x, y dims\n      this.sy = json.sy;\n      this.stride = json.stride;\n      this.in_depth = json.in_depth; // depth of input volume\n      this.filters = [];\n      this.l1_decay_mul = typeof json.l1_decay_mul !== 'undefined' ? json.l1_decay_mul : 1.0;\n      this.l2_decay_mul = typeof json.l2_decay_mul !== 'undefined' ? json.l2_decay_mul : 1.0;\n      this.pad = typeof json.pad !== 'undefined' ? json.pad : 0;\n      for(var i=0;i<json.filters.length;i++) {\n        var v = new Vol(0,0,0,0);\n        v.fromJSON(json.filters[i]);\n        this.filters.push(v);\n      }\n      this.biases = new Vol(0,0,0,0);\n      this.biases.fromJSON(json.biases);\n    }\n  }\n\n  var FullyConnLayer = function(opt) {\n    var opt = opt || {};\n\n    // required\n    // ok fine we will allow 'filters' as the word as well\n    this.out_depth = typeof opt.num_neurons !== 'undefined' ? opt.num_neurons : opt.filters;\n\n    // optional \n    this.l1_decay_mul = typeof opt.l1_decay_mul !== 'undefined' ? opt.l1_decay_mul : 0.0;\n    this.l2_decay_mul = typeof opt.l2_decay_mul !== 'undefined' ? opt.l2_decay_mul : 1.0;\n\n    // computed\n    this.num_inputs = opt.in_sx * opt.in_sy * opt.in_depth;\n    this.out_sx = 1;\n    this.out_sy = 1;\n    this.layer_type = 'fc';\n\n    // initializations\n    var bias = typeof opt.bias_pref !== 'undefined' ? opt.bias_pref : 0.0;\n    this.filters = [];\n    for(var i=0;i<this.out_depth ;i++) { this.filters.push(new Vol(1, 1, this.num_inputs)); }\n    this.biases = new Vol(1, 1, this.out_depth, bias);\n  }\n\n  FullyConnLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var A = new Vol(1, 1, this.out_depth, 0.0);\n      var Vw = V.w;\n      for(var i=0;i<this.out_depth;i++) {\n        var a = 0.0;\n        var wi = this.filters[i].w;\n        for(var d=0;d<this.num_inputs;d++) {\n          a += Vw[d] * wi[d]; // for efficiency use Vols directly for now\n        }\n        a += this.biases.w[i];\n        A.w[i] = a;\n      }\n      this.out_act = A;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act;\n      V.dw = global.zeros(V.w.length); // zero out the gradient in input Vol\n      \n      // compute gradient wrt weights and data\n      for(var i=0;i<this.out_depth;i++) {\n        var tfi = this.filters[i];\n        var chain_grad = this.out_act.dw[i];\n        for(var d=0;d<this.num_inputs;d++) {\n          V.dw[d] += tfi.w[d]*chain_grad; // grad wrt input data\n          tfi.dw[d] += V.w[d]*chain_grad; // grad wrt params\n        }\n        this.biases.dw[i] += chain_grad;\n      }\n    },\n    getParamsAndGrads: function() {\n      var response = [];\n      for(var i=0;i<this.out_depth;i++) {\n        response.push({params: this.filters[i].w, grads: this.filters[i].dw, l1_decay_mul: this.l1_decay_mul, l2_decay_mul: this.l2_decay_mul});\n      }\n      response.push({params: this.biases.w, grads: this.biases.dw, l1_decay_mul: 0.0, l2_decay_mul: 0.0});\n      return response;\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.num_inputs = this.num_inputs;\n      json.l1_decay_mul = this.l1_decay_mul;\n      json.l2_decay_mul = this.l2_decay_mul;\n      json.filters = [];\n      for(var i=0;i<this.filters.length;i++) {\n        json.filters.push(this.filters[i].toJSON());\n      }\n      json.biases = this.biases.toJSON();\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.num_inputs = json.num_inputs;\n      this.l1_decay_mul = typeof json.l1_decay_mul !== 'undefined' ? json.l1_decay_mul : 1.0;\n      this.l2_decay_mul = typeof json.l2_decay_mul !== 'undefined' ? json.l2_decay_mul : 1.0;\n      this.filters = [];\n      for(var i=0;i<json.filters.length;i++) {\n        var v = new Vol(0,0,0,0);\n        v.fromJSON(json.filters[i]);\n        this.filters.push(v);\n      }\n      this.biases = new Vol(0,0,0,0);\n      this.biases.fromJSON(json.biases);\n    }\n  }\n\n  global.ConvLayer = ConvLayer;\n  global.FullyConnLayer = FullyConnLayer;\n  \n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_layers_dropout.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  // An inefficient dropout layer\n  // Note this is not most efficient implementation since the layer before\n  // computed all these activations and now we're just going to drop them :(\n  // same goes for backward pass. Also, if we wanted to be efficient at test time\n  // we could equivalently be clever and upscale during train and copy pointers during test\n  // todo: make more efficient.\n  var DropoutLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'dropout';\n    this.drop_prob = typeof opt.drop_prob !== 'undefined' ? opt.drop_prob : 0.5;\n    this.dropped = global.zeros(this.out_sx*this.out_sy*this.out_depth);\n  }\n  DropoutLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      if(typeof(is_training)==='undefined') { is_training = false; } // default is prediction mode\n      var V2 = V.clone();\n      var N = V.w.length;\n      if(is_training) {\n        // do dropout\n        for(var i=0;i<N;i++) {\n          if(Math.random()<this.drop_prob) { V2.w[i]=0; this.dropped[i] = true; } // drop!\n          else {this.dropped[i] = false;}\n        }\n      } else {\n        // scale the activations during prediction\n        for(var i=0;i<N;i++) { V2.w[i]*=this.drop_prob; }\n      }\n      this.out_act = V2;\n      return this.out_act; // dummy identity function for now\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var chain_grad = this.out_act;\n      var N = V.w.length;\n      V.dw = global.zeros(N); // zero out gradient wrt data\n      for(var i=0;i<N;i++) {\n        if(!(this.dropped[i])) { \n          V.dw[i] = chain_grad.dw[i]; // copy over the gradient\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.drop_prob = this.drop_prob;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n      this.drop_prob = json.drop_prob;\n    }\n  }\n  \n\n  global.DropoutLayer = DropoutLayer;\n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_layers_input.js",
    "content": "\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  var getopt = global.getopt;\n\n  var InputLayer = function(opt) {\n    var opt = opt || {};\n\n    // required: depth\n    this.out_depth = getopt(opt, ['out_depth', 'depth'], 0);\n\n    // optional: default these dimensions to 1\n    this.out_sx = getopt(opt, ['out_sx', 'sx', 'width'], 1);\n    this.out_sy = getopt(opt, ['out_sy', 'sy', 'height'], 1);\n    \n    // computed\n    this.layer_type = 'input';\n  }\n  InputLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      this.out_act = V;\n      return this.out_act; // simply identity function for now\n    },\n    backward: function() { },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n\n  global.InputLayer = InputLayer;\n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_layers_loss.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  // Layers that implement a loss. Currently these are the layers that \n  // can initiate a backward() pass. In future we probably want a more \n  // flexible system that can accomodate multiple losses to do multi-task\n  // learning, and stuff like that. But for now, one of the layers in this\n  // file must be the final layer in a Net.\n\n  // This is a classifier, with N discrete classes from 0 to N-1\n  // it gets a stream of N incoming numbers and computes the softmax\n  // function (exponentiate and normalize to sum to 1 as probabilities should)\n  var SoftmaxLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.num_inputs = opt.in_sx * opt.in_sy * opt.in_depth;\n    this.out_depth = this.num_inputs;\n    this.out_sx = 1;\n    this.out_sy = 1;\n    this.layer_type = 'softmax';\n  }\n\n  SoftmaxLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n\n      var A = new Vol(1, 1, this.out_depth, 0.0);\n\n      // compute max activation\n      var as = V.w;\n      var amax = V.w[0];\n      for(var i=1;i<this.out_depth;i++) {\n        if(as[i] > amax) amax = as[i];\n      }\n\n      // compute exponentials (carefully to not blow up)\n      var es = global.zeros(this.out_depth);\n      var esum = 0.0;\n      for(var i=0;i<this.out_depth;i++) {\n        var e = Math.exp(as[i] - amax);\n        esum += e;\n        es[i] = e;\n      }\n\n      // normalize and output to sum to one\n      for(var i=0;i<this.out_depth;i++) {\n        es[i] /= esum;\n        A.w[i] = es[i];\n      }\n\n      this.es = es; // save these for backprop\n      this.out_act = A;\n      return this.out_act;\n    },\n    backward: function(y) {\n\n      // compute and accumulate gradient wrt weights and bias of this layer\n      var x = this.in_act;\n      x.dw = global.zeros(x.w.length); // zero out the gradient of input Vol\n\n      for(var i=0;i<this.out_depth;i++) {\n        var indicator = i === y ? 1.0 : 0.0;\n        var mul = -(indicator - this.es[i]);\n        x.dw[i] = mul;\n      }\n\n      // loss is the class negative log likelihood\n      return -Math.log(this.es[y]);\n    },\n    getParamsAndGrads: function() { \n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.num_inputs = this.num_inputs;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.num_inputs = json.num_inputs;\n    }\n  }\n\n  // implements an L2 regression cost layer,\n  // so penalizes \\sum_i(||x_i - y_i||^2), where x is its input\n  // and y is the user-provided array of \"correct\" values.\n  var RegressionLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.num_inputs = opt.in_sx * opt.in_sy * opt.in_depth;\n    this.out_depth = this.num_inputs;\n    this.out_sx = 1;\n    this.out_sy = 1;\n    this.layer_type = 'regression';\n  }\n\n  RegressionLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      this.out_act = V;\n      return V; // identity function\n    },\n    // y is a list here of size num_inputs\n    // or it can be a number if only one value is regressed\n    // or it can be a struct {dim: i, val: x} where we only want to \n    // regress on dimension i and asking it to have value x\n    backward: function(y) { \n\n      // compute and accumulate gradient wrt weights and bias of this layer\n      var x = this.in_act;\n      x.dw = global.zeros(x.w.length); // zero out the gradient of input Vol\n      var loss = 0.0;\n      if(y instanceof Array || y instanceof Float64Array) {\n        for(var i=0;i<this.out_depth;i++) {\n          var dy = x.w[i] - y[i];\n          x.dw[i] = dy;\n          loss += 0.5*dy*dy;\n        }\n      } else if(typeof y === 'number') {\n        // lets hope that only one number is being regressed\n        var dy = x.w[0] - y;\n        x.dw[0] = dy;\n        loss += 0.5*dy*dy;\n      } else {\n        // assume it is a struct with entries .dim and .val\n        // and we pass gradient only along dimension dim to be equal to val\n        var i = y.dim;\n        var yi = y.val;\n        var dy = x.w[i] - yi;\n        x.dw[i] = dy;\n        loss += 0.5*dy*dy;\n      }\n      return loss;\n    },\n    getParamsAndGrads: function() { \n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.num_inputs = this.num_inputs;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.num_inputs = json.num_inputs;\n    }\n  }\n\n  var SVMLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.num_inputs = opt.in_sx * opt.in_sy * opt.in_depth;\n    this.out_depth = this.num_inputs;\n    this.out_sx = 1;\n    this.out_sy = 1;\n    this.layer_type = 'svm';\n  }\n\n  SVMLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      this.out_act = V; // nothing to do, output raw scores\n      return V;\n    },\n    backward: function(y) {\n\n      // compute and accumulate gradient wrt weights and bias of this layer\n      var x = this.in_act;\n      x.dw = global.zeros(x.w.length); // zero out the gradient of input Vol\n\n      // we're using structured loss here, which means that the score\n      // of the ground truth should be higher than the score of any other \n      // class, by a margin\n      var yscore = x.w[y]; // score of ground truth\n      var margin = 1.0;\n      var loss = 0.0;\n      for(var i=0;i<this.out_depth;i++) {\n        if(y === i) { continue; }\n        var ydiff = -yscore + x.w[i] + margin;\n        if(ydiff > 0) {\n          // violating dimension, apply loss\n          x.dw[i] += 1;\n          x.dw[y] -= 1;\n          loss += ydiff;\n        }\n      }\n\n      return loss;\n    },\n    getParamsAndGrads: function() { \n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.num_inputs = this.num_inputs;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.num_inputs = json.num_inputs;\n    }\n  }\n  \n  global.RegressionLayer = RegressionLayer;\n  global.SoftmaxLayer = SoftmaxLayer;\n  global.SVMLayer = SVMLayer;\n\n})(convnetjs);\n\n"
  },
  {
    "path": "src/convnet_layers_nonlinearities.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  // Implements ReLU nonlinearity elementwise\n  // x -> max(0, x)\n  // the output is in [0, inf)\n  var ReluLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'relu';\n  }\n  ReluLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var V2 = V.clone();\n      var N = V.w.length;\n      var V2w = V2.w;\n      for(var i=0;i<N;i++) { \n        if(V2w[i] < 0) V2w[i] = 0; // threshold at 0\n      }\n      this.out_act = V2;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var V2 = this.out_act;\n      var N = V.w.length;\n      V.dw = global.zeros(N); // zero out gradient wrt data\n      for(var i=0;i<N;i++) {\n        if(V2.w[i] <= 0) V.dw[i] = 0; // threshold\n        else V.dw[i] = V2.dw[i];\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n\n  // Implements Sigmoid nnonlinearity elementwise\n  // x -> 1/(1+e^(-x))\n  // so the output is between 0 and 1.\n  var SigmoidLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'sigmoid';\n  }\n  SigmoidLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var V2 = V.cloneAndZero();\n      var N = V.w.length;\n      var V2w = V2.w;\n      var Vw = V.w;\n      for(var i=0;i<N;i++) { \n        V2w[i] = 1.0/(1.0+Math.exp(-Vw[i]));\n      }\n      this.out_act = V2;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var V2 = this.out_act;\n      var N = V.w.length;\n      V.dw = global.zeros(N); // zero out gradient wrt data\n      for(var i=0;i<N;i++) {\n        var v2wi = V2.w[i];\n        V.dw[i] =  v2wi * (1.0 - v2wi) * V2.dw[i];\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n\n  // Implements Maxout nnonlinearity that computes\n  // x -> max(x)\n  // where x is a vector of size group_size. Ideally of course,\n  // the input size should be exactly divisible by group_size\n  var MaxoutLayer = function(opt) {\n    var opt = opt || {};\n\n    // required\n    this.group_size = typeof opt.group_size !== 'undefined' ? opt.group_size : 2;\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = Math.floor(opt.in_depth / this.group_size);\n    this.layer_type = 'maxout';\n\n    this.switches = global.zeros(this.out_sx*this.out_sy*this.out_depth); // useful for backprop\n  }\n  MaxoutLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var N = this.out_depth; \n      var V2 = new Vol(this.out_sx, this.out_sy, this.out_depth, 0.0);\n\n      // optimization branch. If we're operating on 1D arrays we dont have\n      // to worry about keeping track of x,y,d coordinates inside\n      // input volumes. In convnets we do :(\n      if(this.out_sx === 1 && this.out_sy === 1) {\n        for(var i=0;i<N;i++) {\n          var ix = i * this.group_size; // base index offset\n          var a = V.w[ix];\n          var ai = 0;\n          for(var j=1;j<this.group_size;j++) {\n            var a2 = V.w[ix+j];\n            if(a2 > a) {\n              a = a2;\n              ai = j;\n            }\n          }\n          V2.w[i] = a;\n          this.switches[i] = ix + ai;\n        }\n      } else {\n        var n=0; // counter for switches\n        for(var x=0;x<V.sx;x++) {\n          for(var y=0;y<V.sy;y++) {\n            for(var i=0;i<N;i++) {\n              var ix = i * this.group_size;\n              var a = V.get(x, y, ix);\n              var ai = 0;\n              for(var j=1;j<this.group_size;j++) {\n                var a2 = V.get(x, y, ix+j);\n                if(a2 > a) {\n                  a = a2;\n                  ai = j;\n                }\n              }\n              V2.set(x,y,i,a);\n              this.switches[n] = ix + ai;\n              n++;\n            }\n          }\n        }\n\n      }\n      this.out_act = V2;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var V2 = this.out_act;\n      var N = this.out_depth;\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt data\n\n      // pass the gradient through the appropriate switch\n      if(this.out_sx === 1 && this.out_sy === 1) {\n        for(var i=0;i<N;i++) {\n          var chain_grad = V2.dw[i];\n          V.dw[this.switches[i]] = chain_grad;\n        }\n      } else {\n        // bleh okay, lets do this the hard way\n        var n=0; // counter for switches\n        for(var x=0;x<V2.sx;x++) {\n          for(var y=0;y<V2.sy;y++) {\n            for(var i=0;i<N;i++) {\n              var chain_grad = V2.get_grad(x,y,i);\n              V.set_grad(x,y,this.switches[n],chain_grad);\n              n++;\n            }\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.group_size = this.group_size;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n      this.group_size = json.group_size;\n      this.switches = global.zeros(this.group_size);\n    }\n  }\n\n  // a helper function, since tanh is not yet part of ECMAScript. Will be in v6.\n  function tanh(x) {\n    var y = Math.exp(2 * x);\n    return (y - 1) / (y + 1);\n  }\n  // Implements Tanh nnonlinearity elementwise\n  // x -> tanh(x) \n  // so the output is between -1 and 1.\n  var TanhLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'tanh';\n  }\n  TanhLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var V2 = V.cloneAndZero();\n      var N = V.w.length;\n      for(var i=0;i<N;i++) { \n        V2.w[i] = tanh(V.w[i]);\n      }\n      this.out_act = V2;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var V2 = this.out_act;\n      var N = V.w.length;\n      V.dw = global.zeros(N); // zero out gradient wrt data\n      for(var i=0;i<N;i++) {\n        var v2wi = V2.w[i];\n        V.dw[i] = (1.0 - v2wi * v2wi) * V2.dw[i];\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n  \n  global.TanhLayer = TanhLayer;\n  global.MaxoutLayer = MaxoutLayer;\n  global.ReluLayer = ReluLayer;\n  global.SigmoidLayer = SigmoidLayer;\n\n})(convnetjs);\n\n"
  },
  {
    "path": "src/convnet_layers_normalization.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  // a bit experimental layer for now. I think it works but I'm not 100%\n  // the gradient check is a bit funky. I'll look into this a bit later.\n  // Local Response Normalization in window, along depths of volumes\n  var LocalResponseNormalizationLayer = function(opt) {\n    var opt = opt || {};\n\n    // required\n    this.k = opt.k;\n    this.n = opt.n;\n    this.alpha = opt.alpha;\n    this.beta = opt.beta;\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'lrn';\n\n    // checks\n    if(this.n%2 === 0) { console.log('WARNING n should be odd for LRN layer'); }\n  }\n  LocalResponseNormalizationLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n\n      var A = V.cloneAndZero();\n      this.S_cache_ = V.cloneAndZero();\n      var n2 = Math.floor(this.n/2);\n      for(var x=0;x<V.sx;x++) {\n        for(var y=0;y<V.sy;y++) {\n          for(var i=0;i<V.depth;i++) {\n\n            var ai = V.get(x,y,i);\n\n            // normalize in a window of size n\n            var den = 0.0;\n            for(var j=Math.max(0,i-n2);j<=Math.min(i+n2,V.depth-1);j++) {\n              var aa = V.get(x,y,j);\n              den += aa*aa;\n            }\n            den *= this.alpha / this.n;\n            den += this.k;\n            this.S_cache_.set(x,y,i,den); // will be useful for backprop\n            den = Math.pow(den, this.beta);\n            A.set(x,y,i,ai/den);\n          }\n        }\n      }\n\n      this.out_act = A;\n      return this.out_act; // dummy identity function for now\n    },\n    backward: function() { \n      // evaluate gradient wrt data\n      var V = this.in_act; // we need to set dw of this\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt data\n      var A = this.out_act; // computed in forward pass \n\n      var n2 = Math.floor(this.n/2);\n      for(var x=0;x<V.sx;x++) {\n        for(var y=0;y<V.sy;y++) {\n          for(var i=0;i<V.depth;i++) {\n\n            var chain_grad = this.out_act.get_grad(x,y,i);\n            var S = this.S_cache_.get(x,y,i);\n            var SB = Math.pow(S, this.beta);\n            var SB2 = SB*SB;\n\n            // normalize in a window of size n\n            for(var j=Math.max(0,i-n2);j<=Math.min(i+n2,V.depth-1);j++) {              \n              var aj = V.get(x,y,j); \n              var g = -aj*this.beta*Math.pow(S,this.beta-1)*this.alpha/this.n*2*aj;\n              if(j===i) g+= SB;\n              g /= SB2;\n              g *= chain_grad;\n              V.add_grad(x,y,j,g);\n            }\n\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() { return []; },\n    toJSON: function() {\n      var json = {};\n      json.k = this.k;\n      json.n = this.n;\n      json.alpha = this.alpha; // normalize by size\n      json.beta = this.beta;\n      json.out_sx = this.out_sx; \n      json.out_sy = this.out_sy;\n      json.out_depth = this.out_depth;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.k = json.k;\n      this.n = json.n;\n      this.alpha = json.alpha; // normalize by size\n      this.beta = json.beta;\n      this.out_sx = json.out_sx; \n      this.out_sy = json.out_sy;\n      this.out_depth = json.out_depth;\n      this.layer_type = json.layer_type;\n    }\n  }\n  \n\n  global.LocalResponseNormalizationLayer = LocalResponseNormalizationLayer;\n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_layers_pool.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  var PoolLayer = function(opt) {\n\n    var opt = opt || {};\n\n    // required\n    this.sx = opt.sx; // filter size\n    this.in_depth = opt.in_depth;\n    this.in_sx = opt.in_sx;\n    this.in_sy = opt.in_sy;\n\n    // optional\n    this.sy = typeof opt.sy !== 'undefined' ? opt.sy : this.sx;\n    this.stride = typeof opt.stride !== 'undefined' ? opt.stride : 2;\n    this.pad = typeof opt.pad !== 'undefined' ? opt.pad : 0; // amount of 0 padding to add around borders of input volume\n\n    // computed\n    this.out_depth = this.in_depth;\n    this.out_sx = Math.floor((this.in_sx + this.pad * 2 - this.sx) / this.stride + 1);\n    this.out_sy = Math.floor((this.in_sy + this.pad * 2 - this.sy) / this.stride + 1);\n    this.layer_type = 'pool';\n    // store switches for x,y coordinates for where the max comes from, for each output neuron\n    this.switchx = global.zeros(this.out_sx*this.out_sy*this.out_depth);\n    this.switchy = global.zeros(this.out_sx*this.out_sy*this.out_depth);\n  }\n\n  PoolLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n\n      var A = new Vol(this.out_sx, this.out_sy, this.out_depth, 0.0);\n      \n      var n=0; // a counter for switches\n      for(var d=0;d<this.out_depth;d++) {\n        var x = -this.pad;\n        var y = -this.pad;\n        for(var ax=0; ax<this.out_sx; x+=this.stride,ax++) {\n          y = -this.pad;\n          for(var ay=0; ay<this.out_sy; y+=this.stride,ay++) {\n\n            // convolve centered at this particular location\n            var a = -99999; // hopefully small enough ;\\\n            var winx=-1,winy=-1;\n            for(var fx=0;fx<this.sx;fx++) {\n              for(var fy=0;fy<this.sy;fy++) {\n                var oy = y+fy;\n                var ox = x+fx;\n                if(oy>=0 && oy<V.sy && ox>=0 && ox<V.sx) {\n                  var v = V.get(ox, oy, d);\n                  // perform max pooling and store pointers to where\n                  // the max came from. This will speed up backprop \n                  // and can help make nice visualizations in future\n                  if(v > a) { a = v; winx=ox; winy=oy;}\n                }\n              }\n            }\n            this.switchx[n] = winx;\n            this.switchy[n] = winy;\n            n++;\n            A.set(ax, ay, d, a);\n          }\n        }\n      }\n      this.out_act = A;\n      return this.out_act;\n    },\n    backward: function() { \n      // pooling layers have no parameters, so simply compute \n      // gradient wrt data here\n      var V = this.in_act;\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt data\n      var A = this.out_act; // computed in forward pass \n\n      var n = 0;\n      for(var d=0;d<this.out_depth;d++) {\n        var x = -this.pad;\n        var y = -this.pad;\n        for(var ax=0; ax<this.out_sx; x+=this.stride,ax++) {\n          y = -this.pad;\n          for(var ay=0; ay<this.out_sy; y+=this.stride,ay++) {\n\n            var chain_grad = this.out_act.get_grad(ax,ay,d);\n            V.add_grad(this.switchx[n], this.switchy[n], d, chain_grad);\n            n++;\n\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.sx = this.sx;\n      json.sy = this.sy;\n      json.stride = this.stride;\n      json.in_depth = this.in_depth;\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.pad = this.pad;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.sx = json.sx;\n      this.sy = json.sy;\n      this.stride = json.stride;\n      this.in_depth = json.in_depth;\n      this.pad = typeof json.pad !== 'undefined' ? json.pad : 0; // backwards compatibility\n      this.switchx = global.zeros(this.out_sx*this.out_sy*this.out_depth); // need to re-init these appropriately\n      this.switchy = global.zeros(this.out_sx*this.out_sy*this.out_depth);\n    }\n  }\n\n  global.PoolLayer = PoolLayer;\n\n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_magicnet.js",
    "content": "(function(global) {\n  \"use strict\";\n\n  // used utilities, make explicit local references\n  var randf = global.randf;\n  var randi = global.randi;\n  var Net = global.Net;\n  var Trainer = global.Trainer;\n  var maxmin = global.maxmin;\n  var randperm = global.randperm;\n  var weightedSample = global.weightedSample;\n  var getopt = global.getopt;\n  var arrUnique = global.arrUnique;\n\n  /*\n  A MagicNet takes data: a list of convnetjs.Vol(), and labels\n  which for now are assumed to be class indeces 0..K. MagicNet then:\n  - creates data folds for cross-validation\n  - samples candidate networks\n  - evaluates candidate networks on all data folds\n  - produces predictions by model-averaging the best networks\n  */\n  var MagicNet = function(data, labels, opt) {\n    var opt = opt || {};\n    if(typeof data === 'undefined') { data = []; }\n    if(typeof labels === 'undefined') { labels = []; }\n\n    // required inputs\n    this.data = data; // store these pointers to data\n    this.labels = labels;\n\n    // optional inputs\n    this.train_ratio = getopt(opt, 'train_ratio', 0.7);\n    this.num_folds = getopt(opt, 'num_folds', 10);\n    this.num_candidates = getopt(opt, 'num_candidates', 50); // we evaluate several in parallel\n    // how many epochs of data to train every network? for every fold?\n    // higher values mean higher accuracy in final results, but more expensive\n    this.num_epochs = getopt(opt, 'num_epochs', 50); \n    // number of best models to average during prediction. Usually higher = better\n    this.ensemble_size = getopt(opt, 'ensemble_size', 10);\n\n    // candidate parameters\n    this.batch_size_min = getopt(opt, 'batch_size_min', 10);\n    this.batch_size_max = getopt(opt, 'batch_size_max', 300);\n    this.l2_decay_min = getopt(opt, 'l2_decay_min', -4);\n    this.l2_decay_max = getopt(opt, 'l2_decay_max', 2);\n    this.learning_rate_min = getopt(opt, 'learning_rate_min', -4);\n    this.learning_rate_max = getopt(opt, 'learning_rate_max', 0);\n    this.momentum_min = getopt(opt, 'momentum_min', 0.9);\n    this.momentum_max = getopt(opt, 'momentum_max', 0.9);\n    this.neurons_min = getopt(opt, 'neurons_min', 5);\n    this.neurons_max = getopt(opt, 'neurons_max', 30);\n\n    // computed\n    this.folds = []; // data fold indices, gets filled by sampleFolds()\n    this.candidates = []; // candidate networks that are being currently evaluated\n    this.evaluated_candidates = []; // history of all candidates that were fully evaluated on all folds\n    this.unique_labels = arrUnique(labels);\n    this.iter = 0; // iteration counter, goes from 0 -> num_epochs * num_training_data\n    this.foldix = 0; // index of active fold\n\n    // callbacks\n    this.finish_fold_callback = null;\n    this.finish_batch_callback = null;\n\n    // initializations\n    if(this.data.length > 0) {\n      this.sampleFolds();\n      this.sampleCandidates();\n    }\n  };\n\n  MagicNet.prototype = {\n\n    // sets this.folds to a sampling of this.num_folds folds\n    sampleFolds: function() {\n      var N = this.data.length;\n      var num_train = Math.floor(this.train_ratio * N);\n      this.folds = []; // flush folds, if any\n      for(var i=0;i<this.num_folds;i++) {\n        var p = randperm(N);\n        this.folds.push({train_ix: p.slice(0, num_train), test_ix: p.slice(num_train, N)});\n      }\n    },\n\n    // returns a random candidate network\n    sampleCandidate: function() {\n      var input_depth = this.data[0].w.length;\n      var num_classes = this.unique_labels.length;\n\n      // sample network topology and hyperparameters\n      var layer_defs = [];\n      layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth: input_depth});\n      var nl = weightedSample([0,1,2,3], [0.2, 0.3, 0.3, 0.2]); // prefer nets with 1,2 hidden layers\n      for(var q=0;q<nl;q++) {\n        var ni = randi(this.neurons_min, this.neurons_max);\n        var act = ['tanh','maxout','relu'][randi(0,3)];\n        if(randf(0,1)<0.5) {\n          var dp = Math.random();\n          layer_defs.push({type:'fc', num_neurons: ni, activation: act, drop_prob: dp});\n        } else {\n          layer_defs.push({type:'fc', num_neurons: ni, activation: act});\n        }\n      }\n      layer_defs.push({type:'softmax', num_classes: num_classes});\n      var net = new Net();\n      net.makeLayers(layer_defs);\n\n      // sample training hyperparameters\n      var bs = randi(this.batch_size_min, this.batch_size_max); // batch size\n      var l2 = Math.pow(10, randf(this.l2_decay_min, this.l2_decay_max)); // l2 weight decay\n      var lr = Math.pow(10, randf(this.learning_rate_min, this.learning_rate_max)); // learning rate\n      var mom = randf(this.momentum_min, this.momentum_max); // momentum. Lets just use 0.9, works okay usually ;p\n      var tp = randf(0,1); // trainer type\n      var trainer_def;\n      if(tp<0.33) {\n        trainer_def = {method:'adadelta', batch_size:bs, l2_decay:l2};\n      } else if(tp<0.66) {\n        trainer_def = {method:'adagrad', learning_rate: lr, batch_size:bs, l2_decay:l2};\n      } else {\n        trainer_def = {method:'sgd', learning_rate: lr, momentum: mom, batch_size:bs, l2_decay:l2};\n      }\n      \n      var trainer = new Trainer(net, trainer_def);\n\n      var cand = {};\n      cand.acc = [];\n      cand.accv = 0; // this will maintained as sum(acc) for convenience\n      cand.layer_defs = layer_defs;\n      cand.trainer_def = trainer_def;\n      cand.net = net;\n      cand.trainer = trainer;\n      return cand;\n    },\n\n    // sets this.candidates with this.num_candidates candidate nets\n    sampleCandidates: function() {\n      this.candidates = []; // flush, if any\n      for(var i=0;i<this.num_candidates;i++) {\n        var cand = this.sampleCandidate();\n        this.candidates.push(cand);\n      }\n    },\n\n    step: function() {\n      \n      // run an example through current candidate\n      this.iter++;\n\n      // step all candidates on a random data point\n      var fold = this.folds[this.foldix]; // active fold\n      var dataix = fold.train_ix[randi(0, fold.train_ix.length)];\n      for(var k=0;k<this.candidates.length;k++) {\n        var x = this.data[dataix];\n        var l = this.labels[dataix];\n        this.candidates[k].trainer.train(x, l);\n      }\n\n      // process consequences: sample new folds, or candidates\n      var lastiter = this.num_epochs * fold.train_ix.length;\n      if(this.iter >= lastiter) {\n        // finished evaluation of this fold. Get final validation\n        // accuracies, record them, and go on to next fold.\n        var val_acc = this.evalValErrors();\n        for(var k=0;k<this.candidates.length;k++) {\n          var c = this.candidates[k];\n          c.acc.push(val_acc[k]);\n          c.accv += val_acc[k];\n        }\n        this.iter = 0; // reset step number\n        this.foldix++; // increment fold\n\n        if(this.finish_fold_callback !== null) {\n          this.finish_fold_callback();\n        }\n\n        if(this.foldix >= this.folds.length) {\n          // we finished all folds as well! Record these candidates\n          // and sample new ones to evaluate.\n          for(var k=0;k<this.candidates.length;k++) {\n            this.evaluated_candidates.push(this.candidates[k]);\n          }\n          // sort evaluated candidates according to accuracy achieved\n          this.evaluated_candidates.sort(function(a, b) { \n            return (a.accv / a.acc.length) \n                 > (b.accv / b.acc.length) \n                 ? -1 : 1;\n          });\n          // and clip only to the top few ones (lets place limit at 3*ensemble_size)\n          // otherwise there are concerns with keeping these all in memory \n          // if MagicNet is being evaluated for a very long time\n          if(this.evaluated_candidates.length > 3 * this.ensemble_size) {\n            this.evaluated_candidates = this.evaluated_candidates.slice(0, 3 * this.ensemble_size);\n          }\n          if(this.finish_batch_callback !== null) {\n            this.finish_batch_callback();\n          }\n          this.sampleCandidates(); // begin with new candidates\n          this.foldix = 0; // reset this\n        } else {\n          // we will go on to another fold. reset all candidates nets\n          for(var k=0;k<this.candidates.length;k++) {\n            var c = this.candidates[k];\n            var net = new Net();\n            net.makeLayers(c.layer_defs);\n            var trainer = new Trainer(net, c.trainer_def);\n            c.net = net;\n            c.trainer = trainer;\n          }\n        }\n      }\n    },\n\n    evalValErrors: function() {\n      // evaluate candidates on validation data and return performance of current networks\n      // as simple list\n      var vals = [];\n      var fold = this.folds[this.foldix]; // active fold\n      for(var k=0;k<this.candidates.length;k++) {\n        var net = this.candidates[k].net;\n        var v = 0.0;\n        for(var q=0;q<fold.test_ix.length;q++) {\n          var x = this.data[fold.test_ix[q]];\n          var l = this.labels[fold.test_ix[q]];\n          net.forward(x);\n          var yhat = net.getPrediction();\n          v += (yhat === l ? 1.0 : 0.0); // 0 1 loss\n        }\n        v /= fold.test_ix.length; // normalize\n        vals.push(v);\n      }\n      return vals;\n    },\n\n    // returns prediction scores for given test data point, as Vol\n    // uses an averaged prediction from the best ensemble_size models\n    // x is a Vol.\n    predict_soft: function(data) {\n      // forward prop the best networks\n      // and accumulate probabilities at last layer into a an output Vol\n\n      var eval_candidates = [];\n      var nv = 0;\n      if(this.evaluated_candidates.length === 0) {\n        // not sure what to do here, first batch of nets hasnt evaluated yet\n        // lets just predict with current candidates.\n        nv = this.candidates.length;\n        eval_candidates = this.candidates;\n      } else {\n        // forward prop the best networks from evaluated_candidates\n        nv = Math.min(this.ensemble_size, this.evaluated_candidates.length);\n        eval_candidates = this.evaluated_candidates\n      }\n\n      // forward nets of all candidates and average the predictions\n      var xout, n;\n      for(var j=0;j<nv;j++) {\n        var net = eval_candidates[j].net;\n        var x = net.forward(data);\n        if(j===0) { \n          xout = x; \n          n = x.w.length; \n        } else {\n          // add it on\n          for(var d=0;d<n;d++) {\n            xout.w[d] += x.w[d];\n          }\n        }\n      }\n      // produce average\n      for(var d=0;d<n;d++) {\n        xout.w[d] /= nv;\n      }\n      return xout;\n    },\n\n    predict: function(data) {\n      var xout = this.predict_soft(data);\n      if(xout.w.length !== 0) {\n        var stats = maxmin(xout.w);\n        var predicted_label = stats.maxi; \n      } else {\n        var predicted_label = -1; // error out\n      }\n      return predicted_label;\n\n    },\n\n    toJSON: function() {\n      // dump the top ensemble_size networks as a list\n      var nv = Math.min(this.ensemble_size, this.evaluated_candidates.length);\n      var json = {};\n      json.nets = [];\n      for(var i=0;i<nv;i++) {\n        json.nets.push(this.evaluated_candidates[i].net.toJSON());\n      }\n      return json;\n    },\n\n    fromJSON: function(json) {\n      this.ensemble_size = json.nets.length;\n      this.evaluated_candidates = [];\n      for(var i=0;i<this.ensemble_size;i++) {\n        var net = new Net();\n        net.fromJSON(json.nets[i]);\n        var dummy_candidate = {};\n        dummy_candidate.net = net;\n        this.evaluated_candidates.push(dummy_candidate);\n      }\n    },\n\n    // callback functions\n    // called when a fold is finished, while evaluating a batch\n    onFinishFold: function(f) { this.finish_fold_callback = f; },\n    // called when a batch of candidates has finished evaluating\n    onFinishBatch: function(f) { this.finish_batch_callback = f; }\n    \n  };\n\n  global.MagicNet = MagicNet;\n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_net.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  var assert = global.assert;\n\n  // Net manages a set of layers\n  // For now constraints: Simple linear order of layers, first layer input last layer a cost layer\n  var Net = function(options) {\n    this.layers = [];\n  }\n\n  Net.prototype = {\n    \n    // takes a list of layer definitions and creates the network layer objects\n    makeLayers: function(defs) {\n\n      // few checks\n      assert(defs.length >= 2, 'Error! At least one input layer and one loss layer are required.');\n      assert(defs[0].type === 'input', 'Error! First layer must be the input layer, to declare size of inputs');\n\n      // desugar layer_defs for adding activation, dropout layers etc\n      var desugar = function() {\n        var new_defs = [];\n        for(var i=0;i<defs.length;i++) {\n          var def = defs[i];\n          \n          if(def.type==='softmax' || def.type==='svm') {\n            // add an fc layer here, there is no reason the user should\n            // have to worry about this and we almost always want to\n            new_defs.push({type:'fc', num_neurons: def.num_classes});\n          }\n\n          if(def.type==='regression') {\n            // add an fc layer here, there is no reason the user should\n            // have to worry about this and we almost always want to\n            new_defs.push({type:'fc', num_neurons: def.num_neurons});\n          }\n\n          if((def.type==='fc' || def.type==='conv') \n              && typeof(def.bias_pref) === 'undefined'){\n            def.bias_pref = 0.0;\n            if(typeof def.activation !== 'undefined' && def.activation === 'relu') {\n              def.bias_pref = 0.1; // relus like a bit of positive bias to get gradients early\n              // otherwise it's technically possible that a relu unit will never turn on (by chance)\n              // and will never get any gradient and never contribute any computation. Dead relu.\n            }\n          }\n\n          new_defs.push(def);\n\n          if(typeof def.activation !== 'undefined') {\n            if(def.activation==='relu') { new_defs.push({type:'relu'}); }\n            else if (def.activation==='sigmoid') { new_defs.push({type:'sigmoid'}); }\n            else if (def.activation==='tanh') { new_defs.push({type:'tanh'}); }\n            else if (def.activation==='maxout') {\n              // create maxout activation, and pass along group size, if provided\n              var gs = def.group_size !== 'undefined' ? def.group_size : 2;\n              new_defs.push({type:'maxout', group_size:gs});\n            }\n            else { console.log('ERROR unsupported activation ' + def.activation); }\n          }\n          if(typeof def.drop_prob !== 'undefined' && def.type !== 'dropout') {\n            new_defs.push({type:'dropout', drop_prob: def.drop_prob});\n          }\n\n        }\n        return new_defs;\n      }\n      defs = desugar(defs);\n\n      // create the layers\n      this.layers = [];\n      for(var i=0;i<defs.length;i++) {\n        var def = defs[i];\n        if(i>0) {\n          var prev = this.layers[i-1];\n          def.in_sx = prev.out_sx;\n          def.in_sy = prev.out_sy;\n          def.in_depth = prev.out_depth;\n        }\n\n        switch(def.type) {\n          case 'fc': this.layers.push(new global.FullyConnLayer(def)); break;\n          case 'lrn': this.layers.push(new global.LocalResponseNormalizationLayer(def)); break;\n          case 'dropout': this.layers.push(new global.DropoutLayer(def)); break;\n          case 'input': this.layers.push(new global.InputLayer(def)); break;\n          case 'softmax': this.layers.push(new global.SoftmaxLayer(def)); break;\n          case 'regression': this.layers.push(new global.RegressionLayer(def)); break;\n          case 'conv': this.layers.push(new global.ConvLayer(def)); break;\n          case 'pool': this.layers.push(new global.PoolLayer(def)); break;\n          case 'relu': this.layers.push(new global.ReluLayer(def)); break;\n          case 'sigmoid': this.layers.push(new global.SigmoidLayer(def)); break;\n          case 'tanh': this.layers.push(new global.TanhLayer(def)); break;\n          case 'maxout': this.layers.push(new global.MaxoutLayer(def)); break;\n          case 'svm': this.layers.push(new global.SVMLayer(def)); break;\n          default: console.log('ERROR: UNRECOGNIZED LAYER TYPE: ' + def.type);\n        }\n      }\n    },\n\n    // forward prop the network. \n    // The trainer class passes is_training = true, but when this function is\n    // called from outside (not from the trainer), it defaults to prediction mode\n    forward: function(V, is_training) {\n      if(typeof(is_training) === 'undefined') is_training = false;\n      var act = this.layers[0].forward(V, is_training);\n      for(var i=1;i<this.layers.length;i++) {\n        act = this.layers[i].forward(act, is_training);\n      }\n      return act;\n    },\n\n    getCostLoss: function(V, y) {\n      this.forward(V, false);\n      var N = this.layers.length;\n      var loss = this.layers[N-1].backward(y);\n      return loss;\n    },\n    \n    // backprop: compute gradients wrt all parameters\n    backward: function(y) {\n      var N = this.layers.length;\n      var loss = this.layers[N-1].backward(y); // last layer assumed to be loss layer\n      for(var i=N-2;i>=0;i--) { // first layer assumed input\n        this.layers[i].backward();\n      }\n      return loss;\n    },\n    getParamsAndGrads: function() {\n      // accumulate parameters and gradients for the entire network\n      var response = [];\n      for(var i=0;i<this.layers.length;i++) {\n        var layer_reponse = this.layers[i].getParamsAndGrads();\n        for(var j=0;j<layer_reponse.length;j++) {\n          response.push(layer_reponse[j]);\n        }\n      }\n      return response;\n    },\n    getPrediction: function() {\n      // this is a convenience function for returning the argmax\n      // prediction, assuming the last layer of the net is a softmax\n      var S = this.layers[this.layers.length-1];\n      assert(S.layer_type === 'softmax', 'getPrediction function assumes softmax as last layer of the net!');\n\n      var p = S.out_act.w;\n      var maxv = p[0];\n      var maxi = 0;\n      for(var i=1;i<p.length;i++) {\n        if(p[i] > maxv) { maxv = p[i]; maxi = i;}\n      }\n      return maxi; // return index of the class with highest class probability\n    },\n    toJSON: function() {\n      var json = {};\n      json.layers = [];\n      for(var i=0;i<this.layers.length;i++) {\n        json.layers.push(this.layers[i].toJSON());\n      }\n      return json;\n    },\n    fromJSON: function(json) {\n      this.layers = [];\n      for(var i=0;i<json.layers.length;i++) {\n        var Lj = json.layers[i]\n        var t = Lj.layer_type;\n        var L;\n        if(t==='input') { L = new global.InputLayer(); }\n        if(t==='relu') { L = new global.ReluLayer(); }\n        if(t==='sigmoid') { L = new global.SigmoidLayer(); }\n        if(t==='tanh') { L = new global.TanhLayer(); }\n        if(t==='dropout') { L = new global.DropoutLayer(); }\n        if(t==='conv') { L = new global.ConvLayer(); }\n        if(t==='pool') { L = new global.PoolLayer(); }\n        if(t==='lrn') { L = new global.LocalResponseNormalizationLayer(); }\n        if(t==='softmax') { L = new global.SoftmaxLayer(); }\n        if(t==='regression') { L = new global.RegressionLayer(); }\n        if(t==='fc') { L = new global.FullyConnLayer(); }\n        if(t==='maxout') { L = new global.MaxoutLayer(); }\n        if(t==='svm') { L = new global.SVMLayer(); }\n        L.fromJSON(Lj);\n        this.layers.push(L);\n      }\n    }\n  }\n  \n  global.Net = Net;\n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_trainers.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  var Trainer = function(net, options) {\n\n    this.net = net;\n\n    var options = options || {};\n    this.learning_rate = typeof options.learning_rate !== 'undefined' ? options.learning_rate : 0.01;\n    this.l1_decay = typeof options.l1_decay !== 'undefined' ? options.l1_decay : 0.0;\n    this.l2_decay = typeof options.l2_decay !== 'undefined' ? options.l2_decay : 0.0;\n    this.batch_size = typeof options.batch_size !== 'undefined' ? options.batch_size : 1;\n    this.method = typeof options.method !== 'undefined' ? options.method : 'sgd'; // sgd/adam/adagrad/adadelta/windowgrad/netsterov\n\n    this.momentum = typeof options.momentum !== 'undefined' ? options.momentum : 0.9;\n    this.ro = typeof options.ro !== 'undefined' ? options.ro : 0.95; // used in adadelta\n    this.eps = typeof options.eps !== 'undefined' ? options.eps : 1e-8; // used in adam or adadelta\n    this.beta1 = typeof options.beta1 !== 'undefined' ? options.beta1 : 0.9; // used in adam\n    this.beta2 = typeof options.beta2 !== 'undefined' ? options.beta2 : 0.999; // used in adam\n\n    this.k = 0; // iteration counter\n    this.gsum = []; // last iteration gradients (used for momentum calculations)\n    this.xsum = []; // used in adam or adadelta\n\n    // check if regression is expected \n    if(this.net.layers[this.net.layers.length - 1].layer_type === \"regression\")\n      this.regression = true;\n    else\n      this.regression = false;\n  }\n\n  Trainer.prototype = {\n    train: function(x, y) {\n\n      var start = new Date().getTime();\n      this.net.forward(x, true); // also set the flag that lets the net know we're just training\n      var end = new Date().getTime();\n      var fwd_time = end - start;\n\n      var start = new Date().getTime();\n      var cost_loss = this.net.backward(y);\n      var l2_decay_loss = 0.0;\n      var l1_decay_loss = 0.0;\n      var end = new Date().getTime();\n      var bwd_time = end - start;\n\n      if(this.regression && y.constructor !== Array)\n        console.log(\"Warning: a regression net requires an array as training output vector.\");\n      \n      this.k++;\n      if(this.k % this.batch_size === 0) {\n\n        var pglist = this.net.getParamsAndGrads();\n\n        // initialize lists for accumulators. Will only be done once on first iteration\n        if(this.gsum.length === 0 && (this.method !== 'sgd' || this.momentum > 0.0)) {\n          // only vanilla sgd doesnt need either lists\n          // momentum needs gsum\n          // adagrad needs gsum\n          // adam and adadelta needs gsum and xsum\n          for(var i=0;i<pglist.length;i++) {\n            this.gsum.push(global.zeros(pglist[i].params.length));\n            if(this.method === 'adam' || this.method === 'adadelta') {\n              this.xsum.push(global.zeros(pglist[i].params.length));\n            } else {\n              this.xsum.push([]); // conserve memory\n            }\n          }\n        }\n\n        // perform an update for all sets of weights\n        for(var i=0;i<pglist.length;i++) {\n          var pg = pglist[i]; // param, gradient, other options in future (custom learning rate etc)\n          var p = pg.params;\n          var g = pg.grads;\n\n          // learning rate for some parameters.\n          var l2_decay_mul = typeof pg.l2_decay_mul !== 'undefined' ? pg.l2_decay_mul : 1.0;\n          var l1_decay_mul = typeof pg.l1_decay_mul !== 'undefined' ? pg.l1_decay_mul : 1.0;\n          var l2_decay = this.l2_decay * l2_decay_mul;\n          var l1_decay = this.l1_decay * l1_decay_mul;\n\n          var plen = p.length;\n          for(var j=0;j<plen;j++) {\n            l2_decay_loss += l2_decay*p[j]*p[j]/2; // accumulate weight decay loss\n            l1_decay_loss += l1_decay*Math.abs(p[j]);\n            var l1grad = l1_decay * (p[j] > 0 ? 1 : -1);\n            var l2grad = l2_decay * (p[j]);\n\n            var gij = (l2grad + l1grad + g[j]) / this.batch_size; // raw batch gradient\n\n            var gsumi = this.gsum[i];\n            var xsumi = this.xsum[i];\n            if(this.method === 'adam') {\n              // adam update\n              gsumi[j] = gsumi[j] * this.beta1 + (1- this.beta1) * gij; // update biased first moment estimate\n              xsumi[j] = xsumi[j] * this.beta2 + (1-this.beta2) * gij * gij; // update biased second moment estimate\n              var biasCorr1 = gsumi[j] * (1 - Math.pow(this.beta1, this.k)); // correct bias first moment estimate\n              var biasCorr2 = xsumi[j] * (1 - Math.pow(this.beta2, this.k)); // correct bias second moment estimate\n              var dx =  - this.learning_rate * biasCorr1 / (Math.sqrt(biasCorr2) + this.eps);\n              p[j] += dx;\n            } else if(this.method === 'adagrad') {\n              // adagrad update\n              gsumi[j] = gsumi[j] + gij * gij;\n              var dx = - this.learning_rate / Math.sqrt(gsumi[j] + this.eps) * gij;\n              p[j] += dx;\n            } else if(this.method === 'windowgrad') {\n              // this is adagrad but with a moving window weighted average\n              // so the gradient is not accumulated over the entire history of the run. \n              // it's also referred to as Idea #1 in Zeiler paper on Adadelta. Seems reasonable to me!\n              gsumi[j] = this.ro * gsumi[j] + (1-this.ro) * gij * gij;\n              var dx = - this.learning_rate / Math.sqrt(gsumi[j] + this.eps) * gij; // eps added for better conditioning\n              p[j] += dx;\n            } else if(this.method === 'adadelta') {\n              gsumi[j] = this.ro * gsumi[j] + (1-this.ro) * gij * gij;\n              var dx = - Math.sqrt((xsumi[j] + this.eps)/(gsumi[j] + this.eps)) * gij;\n              xsumi[j] = this.ro * xsumi[j] + (1-this.ro) * dx * dx; // yes, xsum lags behind gsum by 1.\n              p[j] += dx;\n            } else if(this.method === 'nesterov') {\n            \tvar dx = gsumi[j];\n            \tgsumi[j] = gsumi[j] * this.momentum + this.learning_rate * gij;\n                dx = this.momentum * dx - (1.0 + this.momentum) * gsumi[j];\n                p[j] += dx;\n            } else {\n              // assume SGD\n              if(this.momentum > 0.0) {\n                // momentum update\n                var dx = this.momentum * gsumi[j] - this.learning_rate * gij; // step\n                gsumi[j] = dx; // back this up for next iteration of momentum\n                p[j] += dx; // apply corrected gradient\n              } else {\n                // vanilla sgd\n                p[j] +=  - this.learning_rate * gij;\n              }\n            }\n            g[j] = 0.0; // zero out gradient so that we can begin accumulating anew\n          }\n        }\n      }\n\n      // appending softmax_loss for backwards compatibility, but from now on we will always use cost_loss\n      // in future, TODO: have to completely redo the way loss is done around the network as currently \n      // loss is a bit of a hack. Ideally, user should specify arbitrary number of loss functions on any layer\n      // and it should all be computed correctly and automatically. \n      return {fwd_time: fwd_time, bwd_time: bwd_time, \n              l2_decay_loss: l2_decay_loss, l1_decay_loss: l1_decay_loss,\n              cost_loss: cost_loss, softmax_loss: cost_loss, \n              loss: cost_loss + l1_decay_loss + l2_decay_loss}\n    }\n  }\n  \n  global.Trainer = Trainer;\n  global.SGDTrainer = Trainer; // backwards compatibility\n})(convnetjs);\n\n"
  },
  {
    "path": "src/convnet_util.js",
    "content": "(function(global) {\n  \"use strict\";\n\n  // Random number utilities\n  var return_v = false;\n  var v_val = 0.0;\n  var gaussRandom = function() {\n    if(return_v) { \n      return_v = false;\n      return v_val; \n    }\n    var u = 2*Math.random()-1;\n    var v = 2*Math.random()-1;\n    var r = u*u + v*v;\n    if(r == 0 || r > 1) return gaussRandom();\n    var c = Math.sqrt(-2*Math.log(r)/r);\n    v_val = v*c; // cache this\n    return_v = true;\n    return u*c;\n  }\n  var randf = function(a, b) { return Math.random()*(b-a)+a; }\n  var randi = function(a, b) { return Math.floor(Math.random()*(b-a)+a); }\n  var randn = function(mu, std){ return mu+gaussRandom()*std; }\n\n  // Array utilities\n  var zeros = function(n) {\n    if(typeof(n)==='undefined' || isNaN(n)) { return []; }\n    if(typeof ArrayBuffer === 'undefined') {\n      // lacking browser support\n      var arr = new Array(n);\n      for(var i=0;i<n;i++) { arr[i]= 0; }\n      return arr;\n    } else {\n      return new Float64Array(n);\n    }\n  }\n\n  var arrContains = function(arr, elt) {\n    for(var i=0,n=arr.length;i<n;i++) {\n      if(arr[i]===elt) return true;\n    }\n    return false;\n  }\n\n  var arrUnique = function(arr) {\n    var b = [];\n    for(var i=0,n=arr.length;i<n;i++) {\n      if(!arrContains(b, arr[i])) {\n        b.push(arr[i]);\n      }\n    }\n    return b;\n  }\n\n  // return max and min of a given non-empty array.\n  var maxmin = function(w) {\n    if(w.length === 0) { return {}; } // ... ;s\n    var maxv = w[0];\n    var minv = w[0];\n    var maxi = 0;\n    var mini = 0;\n    var n = w.length;\n    for(var i=1;i<n;i++) {\n      if(w[i] > maxv) { maxv = w[i]; maxi = i; } \n      if(w[i] < minv) { minv = w[i]; mini = i; } \n    }\n    return {maxi: maxi, maxv: maxv, mini: mini, minv: minv, dv:maxv-minv};\n  }\n\n  // create random permutation of numbers, in range [0...n-1]\n  var randperm = function(n) {\n    var i = n,\n        j = 0,\n        temp;\n    var array = [];\n    for(var q=0;q<n;q++)array[q]=q;\n    while (i--) {\n        j = Math.floor(Math.random() * (i+1));\n        temp = array[i];\n        array[i] = array[j];\n        array[j] = temp;\n    }\n    return array;\n  }\n\n  // sample from list lst according to probabilities in list probs\n  // the two lists are of same size, and probs adds up to 1\n  var weightedSample = function(lst, probs) {\n    var p = randf(0, 1.0);\n    var cumprob = 0.0;\n    for(var k=0,n=lst.length;k<n;k++) {\n      cumprob += probs[k];\n      if(p < cumprob) { return lst[k]; }\n    }\n  }\n\n  // syntactic sugar function for getting default parameter values\n  var getopt = function(opt, field_name, default_value) {\n    if(typeof field_name === 'string') {\n      // case of single string\n      return (typeof opt[field_name] !== 'undefined') ? opt[field_name] : default_value;\n    } else {\n      // assume we are given a list of string instead\n      var ret = default_value;\n      for(var i=0;i<field_name.length;i++) {\n        var f = field_name[i];\n        if (typeof opt[f] !== 'undefined') {\n          ret = opt[f]; // overwrite return value\n        }\n      }\n      return ret;\n    }\n  }\n\n  function assert(condition, message) {\n    if (!condition) {\n      message = message || \"Assertion failed\";\n      if (typeof Error !== \"undefined\") {\n        throw new Error(message);\n      }\n      throw message; // Fallback\n    }\n  }\n\n  global.randf = randf;\n  global.randi = randi;\n  global.randn = randn;\n  global.zeros = zeros;\n  global.maxmin = maxmin;\n  global.randperm = randperm;\n  global.weightedSample = weightedSample;\n  global.arrUnique = arrUnique;\n  global.arrContains = arrContains;\n  global.getopt = getopt;\n  global.assert = assert;\n  \n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_vol.js",
    "content": "(function(global) {\n  \"use strict\";\n\n  // Vol is the basic building block of all data in a net.\n  // it is essentially just a 3D volume of numbers, with a\n  // width (sx), height (sy), and depth (depth).\n  // it is used to hold data for all filters, all volumes,\n  // all weights, and also stores all gradients w.r.t. \n  // the data. c is optionally a value to initialize the volume\n  // with. If c is missing, fills the Vol with random numbers.\n  var Vol = function(sx, sy, depth, c) {\n    // this is how you check if a variable is an array. Oh, Javascript :)\n    if(Object.prototype.toString.call(sx) === '[object Array]') {\n      // we were given a list in sx, assume 1D volume and fill it up\n      this.sx = 1;\n      this.sy = 1;\n      this.depth = sx.length;\n      // we have to do the following copy because we want to use\n      // fast typed arrays, not an ordinary javascript array\n      this.w = global.zeros(this.depth);\n      this.dw = global.zeros(this.depth);\n      for(var i=0;i<this.depth;i++) {\n        this.w[i] = sx[i];\n      }\n    } else {\n      // we were given dimensions of the vol\n      this.sx = sx;\n      this.sy = sy;\n      this.depth = depth;\n      var n = sx*sy*depth;\n      this.w = global.zeros(n);\n      this.dw = global.zeros(n);\n      if(typeof c === 'undefined') {\n        // weight normalization is done to equalize the output\n        // variance of every neuron, otherwise neurons with a lot\n        // of incoming connections have outputs of larger variance\n        var scale = Math.sqrt(1.0/(sx*sy*depth));\n        for(var i=0;i<n;i++) { \n          this.w[i] = global.randn(0.0, scale);\n        }\n      } else {\n        for(var i=0;i<n;i++) { \n          this.w[i] = c;\n        }\n      }\n    }\n  }\n\n  Vol.prototype = {\n    get: function(x, y, d) { \n      var ix=((this.sx * y)+x)*this.depth+d;\n      return this.w[ix];\n    },\n    set: function(x, y, d, v) { \n      var ix=((this.sx * y)+x)*this.depth+d;\n      this.w[ix] = v; \n    },\n    add: function(x, y, d, v) { \n      var ix=((this.sx * y)+x)*this.depth+d;\n      this.w[ix] += v; \n    },\n    get_grad: function(x, y, d) { \n      var ix = ((this.sx * y)+x)*this.depth+d;\n      return this.dw[ix]; \n    },\n    set_grad: function(x, y, d, v) { \n      var ix = ((this.sx * y)+x)*this.depth+d;\n      this.dw[ix] = v; \n    },\n    add_grad: function(x, y, d, v) { \n      var ix = ((this.sx * y)+x)*this.depth+d;\n      this.dw[ix] += v; \n    },\n    cloneAndZero: function() { return new Vol(this.sx, this.sy, this.depth, 0.0)},\n    clone: function() {\n      var V = new Vol(this.sx, this.sy, this.depth, 0.0);\n      var n = this.w.length;\n      for(var i=0;i<n;i++) { V.w[i] = this.w[i]; }\n      return V;\n    },\n    addFrom: function(V) { for(var k=0;k<this.w.length;k++) { this.w[k] += V.w[k]; }},\n    addFromScaled: function(V, a) { for(var k=0;k<this.w.length;k++) { this.w[k] += a*V.w[k]; }},\n    setConst: function(a) { for(var k=0;k<this.w.length;k++) { this.w[k] = a; }},\n\n    toJSON: function() {\n      // todo: we may want to only save d most significant digits to save space\n      var json = {}\n      json.sx = this.sx; \n      json.sy = this.sy;\n      json.depth = this.depth;\n      json.w = this.w;\n      return json;\n      // we wont back up gradients to save space\n    },\n    fromJSON: function(json) {\n      this.sx = json.sx;\n      this.sy = json.sy;\n      this.depth = json.depth;\n\n      var n = this.sx*this.sy*this.depth;\n      this.w = global.zeros(n);\n      this.dw = global.zeros(n);\n      // copy over the elements.\n      for(var i=0;i<n;i++) {\n        this.w[i] = json.w[i];\n      }\n    }\n  }\n\n  global.Vol = Vol;\n})(convnetjs);\n"
  },
  {
    "path": "src/convnet_vol_util.js",
    "content": "(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  // Volume utilities\n  // intended for use with data augmentation\n  // crop is the size of output\n  // dx,dy are offset wrt incoming volume, of the shift\n  // fliplr is boolean on whether we also want to flip left<->right\n  var augment = function(V, crop, dx, dy, fliplr) {\n    // note assumes square outputs of size crop x crop\n    if(typeof(fliplr)==='undefined') var fliplr = false;\n    if(typeof(dx)==='undefined') var dx = global.randi(0, V.sx - crop);\n    if(typeof(dy)==='undefined') var dy = global.randi(0, V.sy - crop);\n    \n    // randomly sample a crop in the input volume\n    var W;\n    if(crop !== V.sx || dx!==0 || dy!==0) {\n      W = new Vol(crop, crop, V.depth, 0.0);\n      for(var x=0;x<crop;x++) {\n        for(var y=0;y<crop;y++) {\n          if(x+dx<0 || x+dx>=V.sx || y+dy<0 || y+dy>=V.sy) continue; // oob\n          for(var d=0;d<V.depth;d++) {\n           W.set(x,y,d,V.get(x+dx,y+dy,d)); // copy data over\n          }\n        }\n      }\n    } else {\n      W = V;\n    }\n\n    if(fliplr) {\n      // flip volume horziontally\n      var W2 = W.cloneAndZero();\n      for(var x=0;x<W.sx;x++) {\n        for(var y=0;y<W.sy;y++) {\n          for(var d=0;d<W.depth;d++) {\n           W2.set(x,y,d,W.get(W.sx - x - 1,y,d)); // copy data over\n          }\n        }\n      }\n      W = W2; //swap\n    }\n    return W;\n  }\n\n  // img is a DOM element that contains a loaded image\n  // returns a Vol of size (W, H, 4). 4 is for RGBA\n  var img_to_vol = function(img, convert_grayscale) {\n\n    if(typeof(convert_grayscale)==='undefined') var convert_grayscale = false;\n\n    var canvas = document.createElement('canvas');\n    canvas.width = img.width;\n    canvas.height = img.height;\n    var ctx = canvas.getContext(\"2d\");\n\n    // due to a Firefox bug\n    try {\n      ctx.drawImage(img, 0, 0);\n    } catch (e) {\n      if (e.name === \"NS_ERROR_NOT_AVAILABLE\") {\n        // sometimes happens, lets just abort\n        return false;\n      } else {\n        throw e;\n      }\n    }\n\n    try {\n      var img_data = ctx.getImageData(0, 0, canvas.width, canvas.height);\n    } catch (e) {\n      if(e.name === 'IndexSizeError') {\n        return false; // not sure what causes this sometimes but okay abort\n      } else {\n        throw e;\n      }\n    }\n\n    // prepare the input: get pixels and normalize them\n    var p = img_data.data;\n    var W = img.width;\n    var H = img.height;\n    var pv = []\n    for(var i=0;i<p.length;i++) {\n      pv.push(p[i]/255.0-0.5); // normalize image pixels to [-0.5, 0.5]\n    }\n    var x = new Vol(W, H, 4, 0.0); //input volume (image)\n    x.w = pv;\n\n    if(convert_grayscale) {\n      // flatten into depth=1 array\n      var x1 = new Vol(W, H, 1, 0.0);\n      for(var i=0;i<W;i++) {\n        for(var j=0;j<H;j++) {\n          x1.set(i,j,0,x.get(i,j,0));\n        }\n      }\n      x = x1;\n    }\n\n    return x;\n  }\n  \n  global.augment = augment;\n  global.img_to_vol = img_to_vol;\n\n})(convnetjs);"
  },
  {
    "path": "test/jasmine/MIT.LICENSE",
    "content": "Copyright (c) 2008-2011 Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "test/jasmine/SpecRunner.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n  <title>Jasmine Spec Runner v2.0.0</title>\n\n  <link rel=\"shortcut icon\" type=\"image/png\" href=\"lib/jasmine-2.0.0/jasmine_favicon.png\">\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"lib/jasmine-2.0.0/jasmine.css\">\n\n  <script type=\"text/javascript\" src=\"lib/jasmine-2.0.0/jasmine.js\"></script>\n  <script type=\"text/javascript\" src=\"lib/jasmine-2.0.0/jasmine-html.js\"></script>\n  <script type=\"text/javascript\" src=\"lib/jasmine-2.0.0/boot.js\"></script>\n\n  <!-- include source files here... -->\n  <script type=\"text/javascript\" src=\"../../build/convnet.js\"></script>\n\n  <!-- include spec files here... -->\n  <script type=\"text/javascript\" src=\"spec/NeuralNetSpec.js\"></script>\n\n</head>\n\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "test/jasmine/lib/jasmine-2.0.0/boot.js",
    "content": "/**\n Starting with version 2.0, this file \"boots\" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.\n\n If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.\n\n The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.\n\n [jasmine-gem]: http://github.com/pivotal/jasmine-gem\n */\n\n(function() {\n\n  /**\n   * ## Require &amp; Instantiate\n   *\n   * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.\n   */\n  window.jasmine = jasmineRequire.core(jasmineRequire);\n\n  /**\n   * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.\n   */\n  jasmineRequire.html(jasmine);\n\n  /**\n   * Create the Jasmine environment. This is used to run all specs in a project.\n   */\n  var env = jasmine.getEnv();\n\n  /**\n   * ## The Global Interface\n   *\n   * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.\n   */\n  var jasmineInterface = {\n    describe: function(description, specDefinitions) {\n      return env.describe(description, specDefinitions);\n    },\n\n    xdescribe: function(description, specDefinitions) {\n      return env.xdescribe(description, specDefinitions);\n    },\n\n    it: function(desc, func) {\n      return env.it(desc, func);\n    },\n\n    xit: function(desc, func) {\n      return env.xit(desc, func);\n    },\n\n    beforeEach: function(beforeEachFunction) {\n      return env.beforeEach(beforeEachFunction);\n    },\n\n    afterEach: function(afterEachFunction) {\n      return env.afterEach(afterEachFunction);\n    },\n\n    expect: function(actual) {\n      return env.expect(actual);\n    },\n\n    pending: function() {\n      return env.pending();\n    },\n\n    spyOn: function(obj, methodName) {\n      return env.spyOn(obj, methodName);\n    },\n\n    jsApiReporter: new jasmine.JsApiReporter({\n      timer: new jasmine.Timer()\n    })\n  };\n\n  /**\n   * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.\n   */\n  if (typeof window == \"undefined\" && typeof exports == \"object\") {\n    extend(exports, jasmineInterface);\n  } else {\n    extend(window, jasmineInterface);\n  }\n\n  /**\n   * Expose the interface for adding custom equality testers.\n   */\n  jasmine.addCustomEqualityTester = function(tester) {\n    env.addCustomEqualityTester(tester);\n  };\n\n  /**\n   * Expose the interface for adding custom expectation matchers\n   */\n  jasmine.addMatchers = function(matchers) {\n    return env.addMatchers(matchers);\n  };\n\n  /**\n   * Expose the mock interface for the JavaScript timeout functions\n   */\n  jasmine.clock = function() {\n    return env.clock;\n  };\n\n  /**\n   * ## Runner Parameters\n   *\n   * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.\n   */\n\n  var queryString = new jasmine.QueryString({\n    getWindowLocation: function() { return window.location; }\n  });\n\n  var catchingExceptions = queryString.getParam(\"catch\");\n  env.catchExceptions(typeof catchingExceptions === \"undefined\" ? true : catchingExceptions);\n\n  /**\n   * ## Reporters\n   * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).\n   */\n  var htmlReporter = new jasmine.HtmlReporter({\n    env: env,\n    onRaiseExceptionsClick: function() { queryString.setParam(\"catch\", !env.catchingExceptions()); },\n    getContainer: function() { return document.body; },\n    createElement: function() { return document.createElement.apply(document, arguments); },\n    createTextNode: function() { return document.createTextNode.apply(document, arguments); },\n    timer: new jasmine.Timer()\n  });\n\n  /**\n   * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results  from JavaScript.\n   */\n  env.addReporter(jasmineInterface.jsApiReporter);\n  env.addReporter(htmlReporter);\n\n  /**\n   * Filter which specs will be run by matching the start of the full name against the `spec` query param.\n   */\n  var specFilter = new jasmine.HtmlSpecFilter({\n    filterString: function() { return queryString.getParam(\"spec\"); }\n  });\n\n  env.specFilter = function(spec) {\n    return specFilter.matches(spec.getFullName());\n  };\n\n  /**\n   * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.\n   */\n  window.setTimeout = window.setTimeout;\n  window.setInterval = window.setInterval;\n  window.clearTimeout = window.clearTimeout;\n  window.clearInterval = window.clearInterval;\n\n  /**\n   * ## Execution\n   *\n   * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.\n   */\n  var currentWindowOnload = window.onload;\n\n  window.onload = function() {\n    if (currentWindowOnload) {\n      currentWindowOnload();\n    }\n    htmlReporter.initialize();\n    env.execute();\n  };\n\n  /**\n   * Helper function for readability above.\n   */\n  function extend(destination, source) {\n    for (var property in source) destination[property] = source[property];\n    return destination;\n  }\n\n}());\n"
  },
  {
    "path": "test/jasmine/lib/jasmine-2.0.0/console.js",
    "content": "/*\nCopyright (c) 2008-2013 Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nfunction getJasmineRequireObj() {\n  if (typeof module !== \"undefined\" && module.exports) {\n    return exports;\n  } else {\n    window.jasmineRequire = window.jasmineRequire || {};\n    return window.jasmineRequire;\n  }\n}\n\ngetJasmineRequireObj().console = function(jRequire, j$) {\n  j$.ConsoleReporter = jRequire.ConsoleReporter();\n};\n\ngetJasmineRequireObj().ConsoleReporter = function() {\n\n  var noopTimer = {\n    start: function(){},\n    elapsed: function(){ return 0; }\n  };\n\n  function ConsoleReporter(options) {\n    var print = options.print,\n      showColors = options.showColors || false,\n      onComplete = options.onComplete || function() {},\n      timer = options.timer || noopTimer,\n      specCount,\n      failureCount,\n      failedSpecs = [],\n      pendingCount,\n      ansi = {\n        green: '\\x1B[32m',\n        red: '\\x1B[31m',\n        yellow: '\\x1B[33m',\n        none: '\\x1B[0m'\n      };\n\n    this.jasmineStarted = function() {\n      specCount = 0;\n      failureCount = 0;\n      pendingCount = 0;\n      print(\"Started\");\n      printNewline();\n      timer.start();\n    };\n\n    this.jasmineDone = function() {\n      printNewline();\n      for (var i = 0; i < failedSpecs.length; i++) {\n        specFailureDetails(failedSpecs[i]);\n      }\n\n      printNewline();\n      var specCounts = specCount + \" \" + plural(\"spec\", specCount) + \", \" +\n        failureCount + \" \" + plural(\"failure\", failureCount);\n\n      if (pendingCount) {\n        specCounts += \", \" + pendingCount + \" pending \" + plural(\"spec\", pendingCount);\n      }\n\n      print(specCounts);\n\n      printNewline();\n      var seconds = timer.elapsed() / 1000;\n      print(\"Finished in \" + seconds + \" \" + plural(\"second\", seconds));\n\n      printNewline();\n\n      onComplete(failureCount === 0);\n    };\n\n    this.specDone = function(result) {\n      specCount++;\n\n      if (result.status == \"pending\") {\n        pendingCount++;\n        print(colored(\"yellow\", \"*\"));\n        return;\n      }\n\n      if (result.status == \"passed\") {\n        print(colored(\"green\", '.'));\n        return;\n      }\n\n      if (result.status == \"failed\") {\n        failureCount++;\n        failedSpecs.push(result);\n        print(colored(\"red\", 'F'));\n      }\n    };\n\n    return this;\n\n    function printNewline() {\n      print(\"\\n\");\n    }\n\n    function colored(color, str) {\n      return showColors ? (ansi[color] + str + ansi.none) : str;\n    }\n\n    function plural(str, count) {\n      return count == 1 ? str : str + \"s\";\n    }\n\n    function repeat(thing, times) {\n      var arr = [];\n      for (var i = 0; i < times; i++) {\n        arr.push(thing);\n      }\n      return arr;\n    }\n\n    function indent(str, spaces) {\n      var lines = (str || '').split(\"\\n\");\n      var newArr = [];\n      for (var i = 0; i < lines.length; i++) {\n        newArr.push(repeat(\" \", spaces).join(\"\") + lines[i]);\n      }\n      return newArr.join(\"\\n\");\n    }\n\n    function specFailureDetails(result) {\n      printNewline();\n      print(result.fullName);\n\n      for (var i = 0; i < result.failedExpectations.length; i++) {\n        var failedExpectation = result.failedExpectations[i];\n        printNewline();\n        print(indent(failedExpectation.stack, 2));\n      }\n\n      printNewline();\n    }\n  }\n\n  return ConsoleReporter;\n};\n"
  },
  {
    "path": "test/jasmine/lib/jasmine-2.0.0/jasmine-html.js",
    "content": "/*\nCopyright (c) 2008-2013 Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\njasmineRequire.html = function(j$) {\n  j$.ResultsNode = jasmineRequire.ResultsNode();\n  j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);\n  j$.QueryString = jasmineRequire.QueryString();\n  j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();\n};\n\njasmineRequire.HtmlReporter = function(j$) {\n\n  var noopTimer = {\n    start: function() {},\n    elapsed: function() { return 0; }\n  };\n\n  function HtmlReporter(options) {\n    var env = options.env || {},\n      getContainer = options.getContainer,\n      createElement = options.createElement,\n      createTextNode = options.createTextNode,\n      onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},\n      timer = options.timer || noopTimer,\n      results = [],\n      specsExecuted = 0,\n      failureCount = 0,\n      pendingSpecCount = 0,\n      htmlReporterMain,\n      symbols;\n\n    this.initialize = function() {\n      htmlReporterMain = createDom(\"div\", {className: \"html-reporter\"},\n        createDom(\"div\", {className: \"banner\"},\n          createDom(\"span\", {className: \"title\"}, \"Jasmine\"),\n          createDom(\"span\", {className: \"version\"}, j$.version)\n        ),\n        createDom(\"ul\", {className: \"symbol-summary\"}),\n        createDom(\"div\", {className: \"alert\"}),\n        createDom(\"div\", {className: \"results\"},\n          createDom(\"div\", {className: \"failures\"})\n        )\n      );\n      getContainer().appendChild(htmlReporterMain);\n\n      symbols = find(\".symbol-summary\");\n    };\n\n    var totalSpecsDefined;\n    this.jasmineStarted = function(options) {\n      totalSpecsDefined = options.totalSpecsDefined || 0;\n      timer.start();\n    };\n\n    var summary = createDom(\"div\", {className: \"summary\"});\n\n    var topResults = new j$.ResultsNode({}, \"\", null),\n      currentParent = topResults;\n\n    this.suiteStarted = function(result) {\n      currentParent.addChild(result, \"suite\");\n      currentParent = currentParent.last();\n    };\n\n    this.suiteDone = function(result) {\n      if (currentParent == topResults) {\n        return;\n      }\n\n      currentParent = currentParent.parent;\n    };\n\n    this.specStarted = function(result) {\n      currentParent.addChild(result, \"spec\");\n    };\n\n    var failures = [];\n    this.specDone = function(result) {\n      if (result.status != \"disabled\") {\n        specsExecuted++;\n      }\n\n      symbols.appendChild(createDom(\"li\", {\n          className: result.status,\n          id: \"spec_\" + result.id,\n          title: result.fullName\n        }\n      ));\n\n      if (result.status == \"failed\") {\n        failureCount++;\n\n        var failure =\n          createDom(\"div\", {className: \"spec-detail failed\"},\n            createDom(\"div\", {className: \"description\"},\n              createDom(\"a\", {title: result.fullName, href: specHref(result)}, result.fullName)\n            ),\n            createDom(\"div\", {className: \"messages\"})\n          );\n        var messages = failure.childNodes[1];\n\n        for (var i = 0; i < result.failedExpectations.length; i++) {\n          var expectation = result.failedExpectations[i];\n          messages.appendChild(createDom(\"div\", {className: \"result-message\"}, expectation.message));\n          messages.appendChild(createDom(\"div\", {className: \"stack-trace\"}, expectation.stack));\n        }\n\n        failures.push(failure);\n      }\n\n      if (result.status == \"pending\") {\n        pendingSpecCount++;\n      }\n    };\n\n    this.jasmineDone = function() {\n      var banner = find(\".banner\");\n      banner.appendChild(createDom(\"span\", {className: \"duration\"}, \"finished in \" + timer.elapsed() / 1000 + \"s\"));\n\n      var alert = find(\".alert\");\n\n      alert.appendChild(createDom(\"span\", { className: \"exceptions\" },\n        createDom(\"label\", { className: \"label\", 'for': \"raise-exceptions\" }, \"raise exceptions\"),\n        createDom(\"input\", {\n          className: \"raise\",\n          id: \"raise-exceptions\",\n          type: \"checkbox\"\n        })\n      ));\n      var checkbox = find(\"input\");\n\n      checkbox.checked = !env.catchingExceptions();\n      checkbox.onclick = onRaiseExceptionsClick;\n\n      if (specsExecuted < totalSpecsDefined) {\n        var skippedMessage = \"Ran \" + specsExecuted + \" of \" + totalSpecsDefined + \" specs - run all\";\n        alert.appendChild(\n          createDom(\"span\", {className: \"bar skipped\"},\n            createDom(\"a\", {href: \"?\", title: \"Run all specs\"}, skippedMessage)\n          )\n        );\n      }\n      var statusBarMessage = \"\" + pluralize(\"spec\", specsExecuted) + \", \" + pluralize(\"failure\", failureCount);\n      if (pendingSpecCount) { statusBarMessage += \", \" + pluralize(\"pending spec\", pendingSpecCount); }\n\n      var statusBarClassName = \"bar \" + ((failureCount > 0) ? \"failed\" : \"passed\");\n      alert.appendChild(createDom(\"span\", {className: statusBarClassName}, statusBarMessage));\n\n      var results = find(\".results\");\n      results.appendChild(summary);\n\n      summaryList(topResults, summary);\n\n      function summaryList(resultsTree, domParent) {\n        var specListNode;\n        for (var i = 0; i < resultsTree.children.length; i++) {\n          var resultNode = resultsTree.children[i];\n          if (resultNode.type == \"suite\") {\n            var suiteListNode = createDom(\"ul\", {className: \"suite\", id: \"suite-\" + resultNode.result.id},\n              createDom(\"li\", {className: \"suite-detail\"},\n                createDom(\"a\", {href: specHref(resultNode.result)}, resultNode.result.description)\n              )\n            );\n\n            summaryList(resultNode, suiteListNode);\n            domParent.appendChild(suiteListNode);\n          }\n          if (resultNode.type == \"spec\") {\n            if (domParent.getAttribute(\"class\") != \"specs\") {\n              specListNode = createDom(\"ul\", {className: \"specs\"});\n              domParent.appendChild(specListNode);\n            }\n            specListNode.appendChild(\n              createDom(\"li\", {\n                  className: resultNode.result.status,\n                  id: \"spec-\" + resultNode.result.id\n                },\n                createDom(\"a\", {href: specHref(resultNode.result)}, resultNode.result.description)\n              )\n            );\n          }\n        }\n      }\n\n      if (failures.length) {\n        alert.appendChild(\n          createDom('span', {className: \"menu bar spec-list\"},\n            createDom(\"span\", {}, \"Spec List | \"),\n            createDom('a', {className: \"failures-menu\", href: \"#\"}, \"Failures\")));\n        alert.appendChild(\n          createDom('span', {className: \"menu bar failure-list\"},\n            createDom('a', {className: \"spec-list-menu\", href: \"#\"}, \"Spec List\"),\n            createDom(\"span\", {}, \" | Failures \")));\n\n        find(\".failures-menu\").onclick = function() {\n          setMenuModeTo('failure-list');\n        };\n        find(\".spec-list-menu\").onclick = function() {\n          setMenuModeTo('spec-list');\n        };\n\n        setMenuModeTo('failure-list');\n\n        var failureNode = find(\".failures\");\n        for (var i = 0; i < failures.length; i++) {\n          failureNode.appendChild(failures[i]);\n        }\n      }\n    };\n\n    return this;\n\n    function find(selector) {\n      return getContainer().querySelector(selector);\n    }\n\n    function createDom(type, attrs, childrenVarArgs) {\n      var el = createElement(type);\n\n      for (var i = 2; i < arguments.length; i++) {\n        var child = arguments[i];\n\n        if (typeof child === 'string') {\n          el.appendChild(createTextNode(child));\n        } else {\n          if (child) {\n            el.appendChild(child);\n          }\n        }\n      }\n\n      for (var attr in attrs) {\n        if (attr == \"className\") {\n          el[attr] = attrs[attr];\n        } else {\n          el.setAttribute(attr, attrs[attr]);\n        }\n      }\n\n      return el;\n    }\n\n    function pluralize(singular, count) {\n      var word = (count == 1 ? singular : singular + \"s\");\n\n      return \"\" + count + \" \" + word;\n    }\n\n    function specHref(result) {\n      return \"?spec=\" + encodeURIComponent(result.fullName);\n    }\n\n    function setMenuModeTo(mode) {\n      htmlReporterMain.setAttribute(\"class\", \"html-reporter \" + mode);\n    }\n  }\n\n  return HtmlReporter;\n};\n\njasmineRequire.HtmlSpecFilter = function() {\n  function HtmlSpecFilter(options) {\n    var filterString = options && options.filterString() && options.filterString().replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");\n    var filterPattern = new RegExp(filterString);\n\n    this.matches = function(specName) {\n      return filterPattern.test(specName);\n    };\n  }\n\n  return HtmlSpecFilter;\n};\n\njasmineRequire.ResultsNode = function() {\n  function ResultsNode(result, type, parent) {\n    this.result = result;\n    this.type = type;\n    this.parent = parent;\n\n    this.children = [];\n\n    this.addChild = function(result, type) {\n      this.children.push(new ResultsNode(result, type, this));\n    };\n\n    this.last = function() {\n      return this.children[this.children.length - 1];\n    };\n  }\n\n  return ResultsNode;\n};\n\njasmineRequire.QueryString = function() {\n  function QueryString(options) {\n\n    this.setParam = function(key, value) {\n      var paramMap = queryStringToParamMap();\n      paramMap[key] = value;\n      options.getWindowLocation().search = toQueryString(paramMap);\n    };\n\n    this.getParam = function(key) {\n      return queryStringToParamMap()[key];\n    };\n\n    return this;\n\n    function toQueryString(paramMap) {\n      var qStrPairs = [];\n      for (var prop in paramMap) {\n        qStrPairs.push(encodeURIComponent(prop) + \"=\" + encodeURIComponent(paramMap[prop]));\n      }\n      return \"?\" + qStrPairs.join('&');\n    }\n\n    function queryStringToParamMap() {\n      var paramStr = options.getWindowLocation().search.substring(1),\n        params = [],\n        paramMap = {};\n\n      if (paramStr.length > 0) {\n        params = paramStr.split('&');\n        for (var i = 0; i < params.length; i++) {\n          var p = params[i].split('=');\n          var value = decodeURIComponent(p[1]);\n          if (value === \"true\" || value === \"false\") {\n            value = JSON.parse(value);\n          }\n          paramMap[decodeURIComponent(p[0])] = value;\n        }\n      }\n\n      return paramMap;\n    }\n\n  }\n\n  return QueryString;\n};\n"
  },
  {
    "path": "test/jasmine/lib/jasmine-2.0.0/jasmine.css",
    "content": "body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }\n\n.html-reporter { font-size: 11px; font-family: Monaco, \"Lucida Console\", monospace; line-height: 14px; color: #333333; }\n.html-reporter a { text-decoration: none; }\n.html-reporter a:hover { text-decoration: underline; }\n.html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; }\n.html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }\n.html-reporter .banner .version { margin-left: 14px; }\n.html-reporter #jasmine_content { position: fixed; right: 100%; }\n.html-reporter .version { color: #aaaaaa; }\n.html-reporter .banner { margin-top: 14px; }\n.html-reporter .duration { color: #aaaaaa; float: right; }\n.html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }\n.html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; }\n.html-reporter .symbol-summary li.passed { font-size: 14px; }\n.html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: \"\\02022\"; }\n.html-reporter .symbol-summary li.failed { line-height: 9px; }\n.html-reporter .symbol-summary li.failed:before { color: #b03911; content: \"x\"; font-weight: bold; margin-left: -1px; }\n.html-reporter .symbol-summary li.disabled { font-size: 14px; }\n.html-reporter .symbol-summary li.disabled:before { color: #bababa; content: \"\\02022\"; }\n.html-reporter .symbol-summary li.pending { line-height: 17px; }\n.html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: \"*\"; }\n.html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }\n.html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }\n.html-reporter .bar.failed { background-color: #b03911; }\n.html-reporter .bar.passed { background-color: #a6b779; }\n.html-reporter .bar.skipped { background-color: #bababa; }\n.html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }\n.html-reporter .bar.menu a { color: #333333; }\n.html-reporter .bar a { color: white; }\n.html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; }\n.html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; }\n.html-reporter .running-alert { background-color: #666666; }\n.html-reporter .results { margin-top: 14px; }\n.html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }\n.html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }\n.html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }\n.html-reporter.showDetails .summary { display: none; }\n.html-reporter.showDetails #details { display: block; }\n.html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }\n.html-reporter .summary { margin-top: 14px; }\n.html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }\n.html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }\n.html-reporter .summary li.passed a { color: #5e7d00; }\n.html-reporter .summary li.failed a { color: #b03911; }\n.html-reporter .summary li.pending a { color: #ba9d37; }\n.html-reporter .description + .suite { margin-top: 0; }\n.html-reporter .suite { margin-top: 14px; }\n.html-reporter .suite a { color: #333333; }\n.html-reporter .failures .spec-detail { margin-bottom: 28px; }\n.html-reporter .failures .spec-detail .description { background-color: #b03911; }\n.html-reporter .failures .spec-detail .description a { color: white; }\n.html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; }\n.html-reporter .result-message span.result { display: block; }\n.html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }\n"
  },
  {
    "path": "test/jasmine/lib/jasmine-2.0.0/jasmine.js",
    "content": "/*\nCopyright (c) 2008-2013 Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nfunction getJasmineRequireObj() {\n  if (typeof module !== \"undefined\" && module.exports) {\n    return exports;\n  } else {\n    window.jasmineRequire = window.jasmineRequire || {};\n    return window.jasmineRequire;\n  }\n}\n\ngetJasmineRequireObj().core = function(jRequire) {\n  var j$ = {};\n\n  jRequire.base(j$);\n  j$.util = jRequire.util();\n  j$.Any = jRequire.Any();\n  j$.CallTracker = jRequire.CallTracker();\n  j$.Clock = jRequire.Clock();\n  j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler();\n  j$.Env = jRequire.Env(j$);\n  j$.ExceptionFormatter = jRequire.ExceptionFormatter();\n  j$.Expectation = jRequire.Expectation();\n  j$.buildExpectationResult = jRequire.buildExpectationResult();\n  j$.JsApiReporter = jRequire.JsApiReporter();\n  j$.matchersUtil = jRequire.matchersUtil(j$);\n  j$.ObjectContaining = jRequire.ObjectContaining(j$);\n  j$.pp = jRequire.pp(j$);\n  j$.QueueRunner = jRequire.QueueRunner();\n  j$.ReportDispatcher = jRequire.ReportDispatcher();\n  j$.Spec = jRequire.Spec(j$);\n  j$.SpyStrategy = jRequire.SpyStrategy();\n  j$.Suite = jRequire.Suite();\n  j$.Timer = jRequire.Timer();\n  j$.version = jRequire.version();\n\n  j$.matchers = jRequire.requireMatchers(jRequire, j$);\n\n  return j$;\n};\n\ngetJasmineRequireObj().requireMatchers = function(jRequire, j$) {\n  var availableMatchers = [\n      \"toBe\",\n      \"toBeCloseTo\",\n      \"toBeDefined\",\n      \"toBeFalsy\",\n      \"toBeGreaterThan\",\n      \"toBeLessThan\",\n      \"toBeNaN\",\n      \"toBeNull\",\n      \"toBeTruthy\",\n      \"toBeUndefined\",\n      \"toContain\",\n      \"toEqual\",\n      \"toHaveBeenCalled\",\n      \"toHaveBeenCalledWith\",\n      \"toMatch\",\n      \"toThrow\",\n      \"toThrowError\"\n    ],\n    matchers = {};\n\n  for (var i = 0; i < availableMatchers.length; i++) {\n    var name = availableMatchers[i];\n    matchers[name] = jRequire[name](j$);\n  }\n\n  return matchers;\n};\n\ngetJasmineRequireObj().base = function(j$) {\n  j$.unimplementedMethod_ = function() {\n    throw new Error(\"unimplemented method\");\n  };\n\n  j$.MAX_PRETTY_PRINT_DEPTH = 40;\n  j$.DEFAULT_TIMEOUT_INTERVAL = 5000;\n\n  j$.getGlobal = (function() {\n    var jasmineGlobal = eval.call(null, \"this\");\n    return function() {\n      return jasmineGlobal;\n    };\n  })();\n\n  j$.getEnv = function(options) {\n    var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options);\n    //jasmine. singletons in here (setTimeout blah blah).\n    return env;\n  };\n\n  j$.isArray_ = function(value) {\n    return j$.isA_(\"Array\", value);\n  };\n\n  j$.isString_ = function(value) {\n    return j$.isA_(\"String\", value);\n  };\n\n  j$.isNumber_ = function(value) {\n    return j$.isA_(\"Number\", value);\n  };\n\n  j$.isA_ = function(typeName, value) {\n    return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';\n  };\n\n  j$.isDomNode = function(obj) {\n    return obj.nodeType > 0;\n  };\n\n  j$.any = function(clazz) {\n    return new j$.Any(clazz);\n  };\n\n  j$.objectContaining = function(sample) {\n    return new j$.ObjectContaining(sample);\n  };\n\n  j$.createSpy = function(name, originalFn) {\n\n    var spyStrategy = new j$.SpyStrategy({\n        name: name,\n        fn: originalFn,\n        getSpy: function() { return spy; }\n      }),\n      callTracker = new j$.CallTracker(),\n      spy = function() {\n        callTracker.track({\n          object: this,\n          args: Array.prototype.slice.apply(arguments)\n        });\n        return spyStrategy.exec.apply(this, arguments);\n      };\n\n    for (var prop in originalFn) {\n      if (prop === 'and' || prop === 'calls') {\n        throw new Error(\"Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon\");\n      }\n\n      spy[prop] = originalFn[prop];\n    }\n\n    spy.and = spyStrategy;\n    spy.calls = callTracker;\n\n    return spy;\n  };\n\n  j$.isSpy = function(putativeSpy) {\n    if (!putativeSpy) {\n      return false;\n    }\n    return putativeSpy.and instanceof j$.SpyStrategy &&\n      putativeSpy.calls instanceof j$.CallTracker;\n  };\n\n  j$.createSpyObj = function(baseName, methodNames) {\n    if (!j$.isArray_(methodNames) || methodNames.length === 0) {\n      throw \"createSpyObj requires a non-empty array of method names to create spies for\";\n    }\n    var obj = {};\n    for (var i = 0; i < methodNames.length; i++) {\n      obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]);\n    }\n    return obj;\n  };\n};\n\ngetJasmineRequireObj().util = function() {\n\n  var util = {};\n\n  util.inherit = function(childClass, parentClass) {\n    var Subclass = function() {\n    };\n    Subclass.prototype = parentClass.prototype;\n    childClass.prototype = new Subclass();\n  };\n\n  util.htmlEscape = function(str) {\n    if (!str) {\n      return str;\n    }\n    return str.replace(/&/g, '&amp;')\n      .replace(/</g, '&lt;')\n      .replace(/>/g, '&gt;');\n  };\n\n  util.argsToArray = function(args) {\n    var arrayOfArgs = [];\n    for (var i = 0; i < args.length; i++) {\n      arrayOfArgs.push(args[i]);\n    }\n    return arrayOfArgs;\n  };\n\n  util.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  return util;\n};\n\ngetJasmineRequireObj().Spec = function(j$) {\n  function Spec(attrs) {\n    this.expectationFactory = attrs.expectationFactory;\n    this.resultCallback = attrs.resultCallback || function() {};\n    this.id = attrs.id;\n    this.description = attrs.description || '';\n    this.fn = attrs.fn;\n    this.beforeFns = attrs.beforeFns || function() { return []; };\n    this.afterFns = attrs.afterFns || function() { return []; };\n    this.onStart = attrs.onStart || function() {};\n    this.exceptionFormatter = attrs.exceptionFormatter || function() {};\n    this.getSpecName = attrs.getSpecName || function() { return ''; };\n    this.expectationResultFactory = attrs.expectationResultFactory || function() { };\n    this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};\n    this.catchingExceptions = attrs.catchingExceptions || function() { return true; };\n\n    this.timer = attrs.timer || {setTimeout: setTimeout, clearTimeout: clearTimeout};\n\n    if (!this.fn) {\n      this.pend();\n    }\n\n    this.result = {\n      id: this.id,\n      description: this.description,\n      fullName: this.getFullName(),\n      failedExpectations: []\n    };\n  }\n\n  Spec.prototype.addExpectationResult = function(passed, data) {\n    if (passed) {\n      return;\n    }\n    this.result.failedExpectations.push(this.expectationResultFactory(data));\n  };\n\n  Spec.prototype.expect = function(actual) {\n    return this.expectationFactory(actual, this);\n  };\n\n  Spec.prototype.execute = function(onComplete) {\n    var self = this,\n        timeout;\n\n    this.onStart(this);\n\n    if (this.markedPending || this.disabled) {\n      complete();\n      return;\n    }\n\n    function timeoutable(fn) {\n      return function(done) {\n        timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {\n          onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));\n          done();\n        }, j$.DEFAULT_TIMEOUT_INTERVAL]]);\n\n        var callDone = function() {\n          clearTimeoutable();\n          done();\n        };\n\n        fn.call(this, callDone); //TODO: do we care about more than 1 arg?\n      };\n    }\n\n    function clearTimeoutable() {\n      Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);\n      timeout = void 0;\n    }\n\n    var allFns = this.beforeFns().concat(this.fn).concat(this.afterFns()),\n      allTimeoutableFns = [];\n    for (var i = 0; i < allFns.length; i++) {\n      var fn = allFns[i];\n      allTimeoutableFns.push(fn.length > 0 ? timeoutable(fn) : fn);\n    }\n\n    this.queueRunnerFactory({\n      fns: allTimeoutableFns,\n      onException: onException,\n      onComplete: complete\n    });\n\n    function onException(e) {\n      clearTimeoutable();\n      if (Spec.isPendingSpecException(e)) {\n        self.pend();\n        return;\n      }\n\n      self.addExpectationResult(false, {\n        matcherName: \"\",\n        passed: false,\n        expected: \"\",\n        actual: \"\",\n        error: e\n      });\n    }\n\n    function complete() {\n      self.result.status = self.status();\n      self.resultCallback(self.result);\n\n      if (onComplete) {\n        onComplete();\n      }\n    }\n  };\n\n  Spec.prototype.disable = function() {\n    this.disabled = true;\n  };\n\n  Spec.prototype.pend = function() {\n    this.markedPending = true;\n  };\n\n  Spec.prototype.status = function() {\n    if (this.disabled) {\n      return 'disabled';\n    }\n\n    if (this.markedPending) {\n      return 'pending';\n    }\n\n    if (this.result.failedExpectations.length > 0) {\n      return 'failed';\n    } else {\n      return 'passed';\n    }\n  };\n\n  Spec.prototype.getFullName = function() {\n    return this.getSpecName(this);\n  };\n\n  Spec.pendingSpecExceptionMessage = \"=> marked Pending\";\n\n  Spec.isPendingSpecException = function(e) {\n    return e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1;\n  };\n\n  return Spec;\n};\n\nif (typeof window == void 0 && typeof exports == \"object\") {\n  exports.Spec = jasmineRequire.Spec;\n}\n\ngetJasmineRequireObj().Env = function(j$) {\n  function Env(options) {\n    options = options || {};\n\n    var self = this;\n    var global = options.global || j$.getGlobal();\n\n    var totalSpecsDefined = 0;\n\n    var catchExceptions = true;\n\n    var realSetTimeout = j$.getGlobal().setTimeout;\n    var realClearTimeout = j$.getGlobal().clearTimeout;\n    this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler());\n\n    var runnableLookupTable = {};\n\n    var spies = [];\n\n    var currentSpec = null;\n    var currentSuite = null;\n\n    var reporter = new j$.ReportDispatcher([\n      \"jasmineStarted\",\n      \"jasmineDone\",\n      \"suiteStarted\",\n      \"suiteDone\",\n      \"specStarted\",\n      \"specDone\"\n    ]);\n\n    this.specFilter = function() {\n      return true;\n    };\n\n    var equalityTesters = [];\n\n    var customEqualityTesters = [];\n    this.addCustomEqualityTester = function(tester) {\n      customEqualityTesters.push(tester);\n    };\n\n    j$.Expectation.addCoreMatchers(j$.matchers);\n\n    var nextSpecId = 0;\n    var getNextSpecId = function() {\n      return 'spec' + nextSpecId++;\n    };\n\n    var nextSuiteId = 0;\n    var getNextSuiteId = function() {\n      return 'suite' + nextSuiteId++;\n    };\n\n    var expectationFactory = function(actual, spec) {\n      return j$.Expectation.Factory({\n        util: j$.matchersUtil,\n        customEqualityTesters: customEqualityTesters,\n        actual: actual,\n        addExpectationResult: addExpectationResult\n      });\n\n      function addExpectationResult(passed, result) {\n        return spec.addExpectationResult(passed, result);\n      }\n    };\n\n    var specStarted = function(spec) {\n      currentSpec = spec;\n      reporter.specStarted(spec.result);\n    };\n\n    var beforeFns = function(suite) {\n      return function() {\n        var befores = [];\n        while(suite) {\n          befores = befores.concat(suite.beforeFns);\n          suite = suite.parentSuite;\n        }\n        return befores.reverse();\n      };\n    };\n\n    var afterFns = function(suite) {\n      return function() {\n        var afters = [];\n        while(suite) {\n          afters = afters.concat(suite.afterFns);\n          suite = suite.parentSuite;\n        }\n        return afters;\n      };\n    };\n\n    var getSpecName = function(spec, suite) {\n      return suite.getFullName() + ' ' + spec.description;\n    };\n\n    // TODO: we may just be able to pass in the fn instead of wrapping here\n    var buildExpectationResult = j$.buildExpectationResult,\n        exceptionFormatter = new j$.ExceptionFormatter(),\n        expectationResultFactory = function(attrs) {\n          attrs.messageFormatter = exceptionFormatter.message;\n          attrs.stackFormatter = exceptionFormatter.stack;\n\n          return buildExpectationResult(attrs);\n        };\n\n    // TODO: fix this naming, and here's where the value comes in\n    this.catchExceptions = function(value) {\n      catchExceptions = !!value;\n      return catchExceptions;\n    };\n\n    this.catchingExceptions = function() {\n      return catchExceptions;\n    };\n\n    var maximumSpecCallbackDepth = 20;\n    var currentSpecCallbackDepth = 0;\n\n    function clearStack(fn) {\n      currentSpecCallbackDepth++;\n      if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) {\n        currentSpecCallbackDepth = 0;\n        realSetTimeout(fn, 0);\n      } else {\n        fn();\n      }\n    }\n\n    var catchException = function(e) {\n      return j$.Spec.isPendingSpecException(e) || catchExceptions;\n    };\n\n    var queueRunnerFactory = function(options) {\n      options.catchException = catchException;\n      options.clearStack = options.clearStack || clearStack;\n\n      new j$.QueueRunner(options).execute();\n    };\n\n    var topSuite = new j$.Suite({\n      env: this,\n      id: getNextSuiteId(),\n      description: 'Jasmine__TopLevel__Suite',\n      queueRunner: queueRunnerFactory,\n      resultCallback: function() {} // TODO - hook this up\n    });\n    runnableLookupTable[topSuite.id] = topSuite;\n    currentSuite = topSuite;\n\n    this.topSuite = function() {\n      return topSuite;\n    };\n\n    this.execute = function(runnablesToRun) {\n      runnablesToRun = runnablesToRun || [topSuite.id];\n\n      var allFns = [];\n      for(var i = 0; i < runnablesToRun.length; i++) {\n        var runnable = runnableLookupTable[runnablesToRun[i]];\n        allFns.push((function(runnable) { return function(done) { runnable.execute(done); }; })(runnable));\n      }\n\n      reporter.jasmineStarted({\n        totalSpecsDefined: totalSpecsDefined\n      });\n\n      queueRunnerFactory({fns: allFns, onComplete: reporter.jasmineDone});\n    };\n\n    this.addReporter = function(reporterToAdd) {\n      reporter.addReporter(reporterToAdd);\n    };\n\n    this.addMatchers = function(matchersToAdd) {\n      j$.Expectation.addMatchers(matchersToAdd);\n    };\n\n    this.spyOn = function(obj, methodName) {\n      if (j$.util.isUndefined(obj)) {\n        throw new Error(\"spyOn could not find an object to spy upon for \" + methodName + \"()\");\n      }\n\n      if (j$.util.isUndefined(obj[methodName])) {\n        throw new Error(methodName + '() method does not exist');\n      }\n\n      if (obj[methodName] && j$.isSpy(obj[methodName])) {\n        //TODO?: should this return the current spy? Downside: may cause user confusion about spy state\n        throw new Error(methodName + ' has already been spied upon');\n      }\n\n      var spy = j$.createSpy(methodName, obj[methodName]);\n\n      spies.push({\n        spy: spy,\n        baseObj: obj,\n        methodName: methodName,\n        originalValue: obj[methodName]\n      });\n\n      obj[methodName] = spy;\n\n      return spy;\n    };\n\n    var suiteFactory = function(description) {\n      var suite = new j$.Suite({\n        env: self,\n        id: getNextSuiteId(),\n        description: description,\n        parentSuite: currentSuite,\n        queueRunner: queueRunnerFactory,\n        onStart: suiteStarted,\n        resultCallback: function(attrs) {\n          reporter.suiteDone(attrs);\n        }\n      });\n\n      runnableLookupTable[suite.id] = suite;\n      return suite;\n    };\n\n    this.describe = function(description, specDefinitions) {\n      var suite = suiteFactory(description);\n\n      var parentSuite = currentSuite;\n      parentSuite.addChild(suite);\n      currentSuite = suite;\n\n      var declarationError = null;\n      try {\n        specDefinitions.call(suite);\n      } catch (e) {\n        declarationError = e;\n      }\n\n      if (declarationError) {\n        this.it(\"encountered a declaration exception\", function() {\n          throw declarationError;\n        });\n      }\n\n      currentSuite = parentSuite;\n\n      return suite;\n    };\n\n    this.xdescribe = function(description, specDefinitions) {\n      var suite = this.describe(description, specDefinitions);\n      suite.disable();\n      return suite;\n    };\n\n    var specFactory = function(description, fn, suite) {\n      totalSpecsDefined++;\n\n      var spec = new j$.Spec({\n        id: getNextSpecId(),\n        beforeFns: beforeFns(suite),\n        afterFns: afterFns(suite),\n        expectationFactory: expectationFactory,\n        exceptionFormatter: exceptionFormatter,\n        resultCallback: specResultCallback,\n        getSpecName: function(spec) {\n          return getSpecName(spec, suite);\n        },\n        onStart: specStarted,\n        description: description,\n        expectationResultFactory: expectationResultFactory,\n        queueRunnerFactory: queueRunnerFactory,\n        fn: fn,\n        timer: {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}\n      });\n\n      runnableLookupTable[spec.id] = spec;\n\n      if (!self.specFilter(spec)) {\n        spec.disable();\n      }\n\n      return spec;\n\n      function removeAllSpies() {\n        for (var i = 0; i < spies.length; i++) {\n          var spyEntry = spies[i];\n          spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;\n        }\n        spies = [];\n      }\n\n      function specResultCallback(result) {\n        removeAllSpies();\n        j$.Expectation.resetMatchers();\n        customEqualityTesters = [];\n        currentSpec = null;\n        reporter.specDone(result);\n      }\n    };\n\n    var suiteStarted = function(suite) {\n      reporter.suiteStarted(suite.result);\n    };\n\n    this.it = function(description, fn) {\n      var spec = specFactory(description, fn, currentSuite);\n      currentSuite.addChild(spec);\n      return spec;\n    };\n\n    this.xit = function(description, fn) {\n      var spec = this.it(description, fn);\n      spec.pend();\n      return spec;\n    };\n\n    this.expect = function(actual) {\n      return currentSpec.expect(actual);\n    };\n\n    this.beforeEach = function(beforeEachFunction) {\n      currentSuite.beforeEach(beforeEachFunction);\n    };\n\n    this.afterEach = function(afterEachFunction) {\n      currentSuite.afterEach(afterEachFunction);\n    };\n\n    this.pending = function() {\n      throw j$.Spec.pendingSpecExceptionMessage;\n    };\n  }\n\n  return Env;\n};\n\ngetJasmineRequireObj().JsApiReporter = function() {\n\n  var noopTimer = {\n    start: function(){},\n    elapsed: function(){ return 0; }\n  };\n\n  function JsApiReporter(options) {\n    var timer = options.timer || noopTimer,\n        status = \"loaded\";\n\n    this.started = false;\n    this.finished = false;\n\n    this.jasmineStarted = function() {\n      this.started = true;\n      status = 'started';\n      timer.start();\n    };\n\n    var executionTime;\n\n    this.jasmineDone = function() {\n      this.finished = true;\n      executionTime = timer.elapsed();\n      status = 'done';\n    };\n\n    this.status = function() {\n      return status;\n    };\n\n    var suites = {};\n\n    this.suiteStarted = function(result) {\n      storeSuite(result);\n    };\n\n    this.suiteDone = function(result) {\n      storeSuite(result);\n    };\n\n    function storeSuite(result) {\n      suites[result.id] = result;\n    }\n\n    this.suites = function() {\n      return suites;\n    };\n\n    var specs = [];\n    this.specStarted = function(result) { };\n\n    this.specDone = function(result) {\n      specs.push(result);\n    };\n\n    this.specResults = function(index, length) {\n      return specs.slice(index, index + length);\n    };\n\n    this.specs = function() {\n      return specs;\n    };\n\n    this.executionTime = function() {\n      return executionTime;\n    };\n\n  }\n\n  return JsApiReporter;\n};\n\ngetJasmineRequireObj().Any = function() {\n\n  function Any(expectedObject) {\n    this.expectedObject = expectedObject;\n  }\n\n  Any.prototype.jasmineMatches = function(other) {\n    if (this.expectedObject == String) {\n      return typeof other == 'string' || other instanceof String;\n    }\n\n    if (this.expectedObject == Number) {\n      return typeof other == 'number' || other instanceof Number;\n    }\n\n    if (this.expectedObject == Function) {\n      return typeof other == 'function' || other instanceof Function;\n    }\n\n    if (this.expectedObject == Object) {\n      return typeof other == 'object';\n    }\n    \n    if (this.expectedObject == Boolean) {\n      return typeof other == 'boolean';\n    }\n\n    return other instanceof this.expectedObject;\n  };\n\n  Any.prototype.jasmineToString = function() {\n    return '<jasmine.any(' + this.expectedClass + ')>';\n  };\n\n  return Any;\n};\n\ngetJasmineRequireObj().CallTracker = function() {\n\n  function CallTracker() {\n    var calls = [];\n\n    this.track = function(context) {\n      calls.push(context);\n    };\n\n    this.any = function() {\n      return !!calls.length;\n    };\n\n    this.count = function() {\n      return calls.length;\n    };\n\n    this.argsFor = function(index) {\n      var call = calls[index];\n      return call ? call.args : [];\n    };\n\n    this.all = function() {\n      return calls;\n    };\n\n    this.allArgs = function() {\n      var callArgs = [];\n      for(var i = 0; i < calls.length; i++){\n        callArgs.push(calls[i].args);\n      }\n\n      return callArgs;\n    };\n\n    this.first = function() {\n      return calls[0];\n    };\n\n    this.mostRecent = function() {\n      return calls[calls.length - 1];\n    };\n\n    this.reset = function() {\n      calls = [];\n    };\n  }\n\n  return CallTracker;\n};\n\ngetJasmineRequireObj().Clock = function() {\n  function Clock(global, delayedFunctionScheduler) {\n    var self = this,\n      realTimingFunctions = {\n        setTimeout: global.setTimeout,\n        clearTimeout: global.clearTimeout,\n        setInterval: global.setInterval,\n        clearInterval: global.clearInterval\n      },\n      fakeTimingFunctions = {\n        setTimeout: setTimeout,\n        clearTimeout: clearTimeout,\n        setInterval: setInterval,\n        clearInterval: clearInterval\n      },\n      installed = false,\n      timer;\n\n    self.install = function() {\n      replace(global, fakeTimingFunctions);\n      timer = fakeTimingFunctions;\n      installed = true;\n    };\n\n    self.uninstall = function() {\n      delayedFunctionScheduler.reset();\n      replace(global, realTimingFunctions);\n      timer = realTimingFunctions;\n      installed = false;\n    };\n\n    self.setTimeout = function(fn, delay, params) {\n      if (legacyIE()) {\n        if (arguments.length > 2) {\n          throw new Error(\"IE < 9 cannot support extra params to setTimeout without a polyfill\");\n        }\n        return timer.setTimeout(fn, delay);\n      }\n      return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);\n    };\n\n    self.setInterval = function(fn, delay, params) {\n      if (legacyIE()) {\n        if (arguments.length > 2) {\n          throw new Error(\"IE < 9 cannot support extra params to setInterval without a polyfill\");\n        }\n        return timer.setInterval(fn, delay);\n      }\n      return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);\n    };\n\n    self.clearTimeout = function(id) {\n      return Function.prototype.call.apply(timer.clearTimeout, [global, id]);\n    };\n\n    self.clearInterval = function(id) {\n      return Function.prototype.call.apply(timer.clearInterval, [global, id]);\n    };\n\n    self.tick = function(millis) {\n      if (installed) {\n        delayedFunctionScheduler.tick(millis);\n      } else {\n        throw new Error(\"Mock clock is not installed, use jasmine.clock().install()\");\n      }\n    };\n\n    return self;\n\n    function legacyIE() {\n      //if these methods are polyfilled, apply will be present\n      return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;\n    }\n\n    function replace(dest, source) {\n      for (var prop in source) {\n        dest[prop] = source[prop];\n      }\n    }\n\n    function setTimeout(fn, delay) {\n      return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));\n    }\n\n    function clearTimeout(id) {\n      return delayedFunctionScheduler.removeFunctionWithId(id);\n    }\n\n    function setInterval(fn, interval) {\n      return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);\n    }\n\n    function clearInterval(id) {\n      return delayedFunctionScheduler.removeFunctionWithId(id);\n    }\n\n    function argSlice(argsObj, n) {\n      return Array.prototype.slice.call(argsObj, 2);\n    }\n  }\n\n  return Clock;\n};\n\ngetJasmineRequireObj().DelayedFunctionScheduler = function() {\n  function DelayedFunctionScheduler() {\n    var self = this;\n    var scheduledLookup = [];\n    var scheduledFunctions = {};\n    var currentTime = 0;\n    var delayedFnCount = 0;\n\n    self.tick = function(millis) {\n      millis = millis || 0;\n      var endTime = currentTime + millis;\n\n      runScheduledFunctions(endTime);\n      currentTime = endTime;\n    };\n\n    self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {\n      var f;\n      if (typeof(funcToCall) === 'string') {\n        /* jshint evil: true */\n        f = function() { return eval(funcToCall); };\n        /* jshint evil: false */\n      } else {\n        f = funcToCall;\n      }\n\n      millis = millis || 0;\n      timeoutKey = timeoutKey || ++delayedFnCount;\n      runAtMillis = runAtMillis || (currentTime + millis);\n\n      var funcToSchedule = {\n        runAtMillis: runAtMillis,\n        funcToCall: f,\n        recurring: recurring,\n        params: params,\n        timeoutKey: timeoutKey,\n        millis: millis\n      };\n\n      if (runAtMillis in scheduledFunctions) {\n        scheduledFunctions[runAtMillis].push(funcToSchedule);\n      } else {\n        scheduledFunctions[runAtMillis] = [funcToSchedule];\n        scheduledLookup.push(runAtMillis);\n        scheduledLookup.sort(function (a, b) {\n          return a - b;\n        });\n      }\n\n      return timeoutKey;\n    };\n\n    self.removeFunctionWithId = function(timeoutKey) {\n      for (var runAtMillis in scheduledFunctions) {\n        var funcs = scheduledFunctions[runAtMillis];\n        var i = indexOfFirstToPass(funcs, function (func) {\n          return func.timeoutKey === timeoutKey;\n        });\n\n        if (i > -1) {\n          if (funcs.length === 1) {\n            delete scheduledFunctions[runAtMillis];\n            deleteFromLookup(runAtMillis);\n          } else {\n            funcs.splice(i, 1);\n          }\n\n          // intervals get rescheduled when executed, so there's never more\n          // than a single scheduled function with a given timeoutKey\n          break;\n        }\n      }\n    };\n\n    self.reset = function() {\n      currentTime = 0;\n      scheduledLookup = [];\n      scheduledFunctions = {};\n      delayedFnCount = 0;\n    };\n\n    return self;\n\n    function indexOfFirstToPass(array, testFn) {\n      var index = -1;\n\n      for (var i = 0; i < array.length; ++i) {\n        if (testFn(array[i])) {\n          index = i;\n          break;\n        }\n      }\n\n      return index;\n    }\n\n    function deleteFromLookup(key) {\n      var value = Number(key);\n      var i = indexOfFirstToPass(scheduledLookup, function (millis) {\n        return millis === value;\n      });\n\n      if (i > -1) {\n        scheduledLookup.splice(i, 1);\n      }\n    }\n\n    function reschedule(scheduledFn) {\n      self.scheduleFunction(scheduledFn.funcToCall,\n        scheduledFn.millis,\n        scheduledFn.params,\n        true,\n        scheduledFn.timeoutKey,\n        scheduledFn.runAtMillis + scheduledFn.millis);\n    }\n\n    function runScheduledFunctions(endTime) {\n      if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {\n        return;\n      }\n\n      do {\n        currentTime = scheduledLookup.shift();\n\n        var funcsToRun = scheduledFunctions[currentTime];\n        delete scheduledFunctions[currentTime];\n\n        for (var i = 0; i < funcsToRun.length; ++i) {\n          var funcToRun = funcsToRun[i];\n          funcToRun.funcToCall.apply(null, funcToRun.params || []);\n\n          if (funcToRun.recurring) {\n            reschedule(funcToRun);\n          }\n        }\n      } while (scheduledLookup.length > 0 &&\n              // checking first if we're out of time prevents setTimeout(0)\n              // scheduled in a funcToRun from forcing an extra iteration\n                 currentTime !== endTime  &&\n                 scheduledLookup[0] <= endTime);\n    }\n  }\n\n  return DelayedFunctionScheduler;\n};\n\ngetJasmineRequireObj().ExceptionFormatter = function() {\n  function ExceptionFormatter() {\n    this.message = function(error) {\n      var message = error.name +\n        ': ' +\n        error.message;\n\n      if (error.fileName || error.sourceURL) {\n        message += \" in \" + (error.fileName || error.sourceURL);\n      }\n\n      if (error.line || error.lineNumber) {\n        message += \" (line \" + (error.line || error.lineNumber) + \")\";\n      }\n\n      return message;\n    };\n\n    this.stack = function(error) {\n      return error ? error.stack : null;\n    };\n  }\n\n  return ExceptionFormatter;\n};\n\ngetJasmineRequireObj().Expectation = function() {\n\n  var matchers = {};\n\n  function Expectation(options) {\n    this.util = options.util || { buildFailureMessage: function() {} };\n    this.customEqualityTesters = options.customEqualityTesters || [];\n    this.actual = options.actual;\n    this.addExpectationResult = options.addExpectationResult || function(){};\n    this.isNot = options.isNot;\n\n    for (var matcherName in matchers) {\n      this[matcherName] = matchers[matcherName];\n    }\n  }\n\n  Expectation.prototype.wrapCompare = function(name, matcherFactory) {\n    return function() {\n      var args = Array.prototype.slice.call(arguments, 0),\n        expected = args.slice(0),\n        message = \"\";\n\n      args.unshift(this.actual);\n\n      var matcher = matcherFactory(this.util, this.customEqualityTesters),\n          matcherCompare = matcher.compare;\n\n      function defaultNegativeCompare() {\n        var result = matcher.compare.apply(null, args);\n        result.pass = !result.pass;\n        return result;\n      }\n\n      if (this.isNot) {\n        matcherCompare = matcher.negativeCompare || defaultNegativeCompare;\n      }\n\n      var result = matcherCompare.apply(null, args);\n\n      if (!result.pass) {\n        if (!result.message) {\n          args.unshift(this.isNot);\n          args.unshift(name);\n          message = this.util.buildFailureMessage.apply(null, args);\n        } else {\n          message = result.message;\n        }\n      }\n\n      if (expected.length == 1) {\n        expected = expected[0];\n      }\n\n      // TODO: how many of these params are needed?\n      this.addExpectationResult(\n        result.pass,\n        {\n          matcherName: name,\n          passed: result.pass,\n          message: message,\n          actual: this.actual,\n          expected: expected // TODO: this may need to be arrayified/sliced\n        }\n      );\n    };\n  };\n\n  Expectation.addCoreMatchers = function(matchers) {\n    var prototype = Expectation.prototype;\n    for (var matcherName in matchers) {\n      var matcher = matchers[matcherName];\n      prototype[matcherName] = prototype.wrapCompare(matcherName, matcher);\n    }\n  };\n\n  Expectation.addMatchers = function(matchersToAdd) {\n    for (var name in matchersToAdd) {\n      var matcher = matchersToAdd[name];\n      matchers[name] = Expectation.prototype.wrapCompare(name, matcher);\n    }\n  };\n\n  Expectation.resetMatchers = function() {\n    for (var name in matchers) {\n      delete matchers[name];\n    }\n  };\n\n  Expectation.Factory = function(options) {\n    options = options || {};\n\n    var expect = new Expectation(options);\n\n    // TODO: this would be nice as its own Object - NegativeExpectation\n    // TODO: copy instead of mutate options\n    options.isNot = true;\n    expect.not = new Expectation(options);\n\n    return expect;\n  };\n\n  return Expectation;\n};\n\n//TODO: expectation result may make more sense as a presentation of an expectation.\ngetJasmineRequireObj().buildExpectationResult = function() {\n  function buildExpectationResult(options) {\n    var messageFormatter = options.messageFormatter || function() {},\n      stackFormatter = options.stackFormatter || function() {};\n\n    return {\n      matcherName: options.matcherName,\n      expected: options.expected,\n      actual: options.actual,\n      message: message(),\n      stack: stack(),\n      passed: options.passed\n    };\n\n    function message() {\n      if (options.passed) {\n        return \"Passed.\";\n      } else if (options.message) {\n        return options.message;\n      } else if (options.error) {\n        return messageFormatter(options.error);\n      }\n      return \"\";\n    }\n\n    function stack() {\n      if (options.passed) {\n        return \"\";\n      }\n\n      var error = options.error;\n      if (!error) {\n        try {\n          throw new Error(message());\n        } catch (e) {\n          error = e;\n        }\n      }\n      return stackFormatter(error);\n    }\n  }\n\n  return buildExpectationResult;\n};\n\ngetJasmineRequireObj().ObjectContaining = function(j$) {\n\n  function ObjectContaining(sample) {\n    this.sample = sample;\n  }\n\n  ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {\n    if (typeof(this.sample) !== \"object\") { throw new Error(\"You must provide an object to objectContaining, not '\"+this.sample+\"'.\"); }\n\n    mismatchKeys = mismatchKeys || [];\n    mismatchValues = mismatchValues || [];\n\n    var hasKey = function(obj, keyName) {\n      return obj !== null && !j$.util.isUndefined(obj[keyName]);\n    };\n\n    for (var property in this.sample) {\n      if (!hasKey(other, property) && hasKey(this.sample, property)) {\n        mismatchKeys.push(\"expected has key '\" + property + \"', but missing from actual.\");\n      }\n      else if (!j$.matchersUtil.equals(this.sample[property], other[property])) {\n        mismatchValues.push(\"'\" + property + \"' was '\" + (other[property] ? j$.util.htmlEscape(other[property].toString()) : other[property]) + \"' in actual, but was '\" + (this.sample[property] ? j$.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + \"' in expected.\");\n      }\n    }\n\n    return (mismatchKeys.length === 0 && mismatchValues.length === 0);\n  };\n\n  ObjectContaining.prototype.jasmineToString = function() {\n    return \"<jasmine.objectContaining(\" + j$.pp(this.sample) + \")>\";\n  };\n\n  return ObjectContaining;\n};\n\ngetJasmineRequireObj().pp = function(j$) {\n\n  function PrettyPrinter() {\n    this.ppNestLevel_ = 0;\n  }\n\n  PrettyPrinter.prototype.format = function(value) {\n    this.ppNestLevel_++;\n    try {\n      if (j$.util.isUndefined(value)) {\n        this.emitScalar('undefined');\n      } else if (value === null) {\n        this.emitScalar('null');\n      } else if (value === j$.getGlobal()) {\n        this.emitScalar('<global>');\n      } else if (value.jasmineToString) {\n        this.emitScalar(value.jasmineToString());\n      } else if (typeof value === 'string') {\n        this.emitString(value);\n      } else if (j$.isSpy(value)) {\n        this.emitScalar(\"spy on \" + value.and.identity());\n      } else if (value instanceof RegExp) {\n        this.emitScalar(value.toString());\n      } else if (typeof value === 'function') {\n        this.emitScalar('Function');\n      } else if (typeof value.nodeType === 'number') {\n        this.emitScalar('HTMLNode');\n      } else if (value instanceof Date) {\n        this.emitScalar('Date(' + value + ')');\n      } else if (value.__Jasmine_been_here_before__) {\n        this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');\n      } else if (j$.isArray_(value) || j$.isA_('Object', value)) {\n        value.__Jasmine_been_here_before__ = true;\n        if (j$.isArray_(value)) {\n          this.emitArray(value);\n        } else {\n          this.emitObject(value);\n        }\n        delete value.__Jasmine_been_here_before__;\n      } else {\n        this.emitScalar(value.toString());\n      }\n    } finally {\n      this.ppNestLevel_--;\n    }\n  };\n\n  PrettyPrinter.prototype.iterateObject = function(obj, fn) {\n    for (var property in obj) {\n      if (!obj.hasOwnProperty(property)) { continue; }\n      if (property == '__Jasmine_been_here_before__') { continue; }\n      fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) &&\n          obj.__lookupGetter__(property) !== null) : false);\n    }\n  };\n\n  PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_;\n  PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_;\n  PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_;\n  PrettyPrinter.prototype.emitString = j$.unimplementedMethod_;\n\n  function StringPrettyPrinter() {\n    PrettyPrinter.call(this);\n\n    this.string = '';\n  }\n\n  j$.util.inherit(StringPrettyPrinter, PrettyPrinter);\n\n  StringPrettyPrinter.prototype.emitScalar = function(value) {\n    this.append(value);\n  };\n\n  StringPrettyPrinter.prototype.emitString = function(value) {\n    this.append(\"'\" + value + \"'\");\n  };\n\n  StringPrettyPrinter.prototype.emitArray = function(array) {\n    if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {\n      this.append(\"Array\");\n      return;\n    }\n\n    this.append('[ ');\n    for (var i = 0; i < array.length; i++) {\n      if (i > 0) {\n        this.append(', ');\n      }\n      this.format(array[i]);\n    }\n    this.append(' ]');\n  };\n\n  StringPrettyPrinter.prototype.emitObject = function(obj) {\n    if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {\n      this.append(\"Object\");\n      return;\n    }\n\n    var self = this;\n    this.append('{ ');\n    var first = true;\n\n    this.iterateObject(obj, function(property, isGetter) {\n      if (first) {\n        first = false;\n      } else {\n        self.append(', ');\n      }\n\n      self.append(property);\n      self.append(' : ');\n      if (isGetter) {\n        self.append('<getter>');\n      } else {\n        self.format(obj[property]);\n      }\n    });\n\n    this.append(' }');\n  };\n\n  StringPrettyPrinter.prototype.append = function(value) {\n    this.string += value;\n  };\n\n  return function(value) {\n    var stringPrettyPrinter = new StringPrettyPrinter();\n    stringPrettyPrinter.format(value);\n    return stringPrettyPrinter.string;\n  };\n};\n\ngetJasmineRequireObj().QueueRunner = function() {\n\n  function QueueRunner(attrs) {\n    this.fns = attrs.fns || [];\n    this.onComplete = attrs.onComplete || function() {};\n    this.clearStack = attrs.clearStack || function(fn) {fn();};\n    this.onException = attrs.onException || function() {};\n    this.catchException = attrs.catchException || function() { return true; };\n    this.userContext = {};\n  }\n\n  QueueRunner.prototype.execute = function() {\n    this.run(this.fns, 0);\n  };\n\n  QueueRunner.prototype.run = function(fns, recursiveIndex) {\n    var length = fns.length,\n        self = this,\n        iterativeIndex;\n\n    for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {\n      var fn = fns[iterativeIndex];\n      if (fn.length > 0) {\n        return attemptAsync(fn);\n      } else {\n        attemptSync(fn);\n      }\n    }\n\n    var runnerDone = iterativeIndex >= length;\n\n    if (runnerDone) {\n      this.clearStack(this.onComplete);\n    }\n\n    function attemptSync(fn) {\n      try {\n        fn.call(self.userContext);\n      } catch (e) {\n        handleException(e);\n      }\n    }\n\n    function attemptAsync(fn) {\n      var next = function () { self.run(fns, iterativeIndex + 1); };\n\n      try {\n        fn.call(self.userContext, next);\n      } catch (e) {\n        handleException(e);\n        next();\n      }\n    }\n\n    function handleException(e) {\n      self.onException(e);\n      if (!self.catchException(e)) {\n        //TODO: set a var when we catch an exception and\n        //use a finally block to close the loop in a nice way..\n        throw e;\n      }\n    }\n  };\n\n  return QueueRunner;\n};\n\ngetJasmineRequireObj().ReportDispatcher = function() {\n  function ReportDispatcher(methods) {\n\n    var dispatchedMethods = methods || [];\n\n    for (var i = 0; i < dispatchedMethods.length; i++) {\n      var method = dispatchedMethods[i];\n      this[method] = (function(m) {\n        return function() {\n          dispatch(m, arguments);\n        };\n      }(method));\n    }\n\n    var reporters = [];\n\n    this.addReporter = function(reporter) {\n      reporters.push(reporter);\n    };\n\n    return this;\n\n    function dispatch(method, args) {\n      for (var i = 0; i < reporters.length; i++) {\n        var reporter = reporters[i];\n        if (reporter[method]) {\n          reporter[method].apply(reporter, args);\n        }\n      }\n    }\n  }\n\n  return ReportDispatcher;\n};\n\n\ngetJasmineRequireObj().SpyStrategy = function() {\n\n  function SpyStrategy(options) {\n    options = options || {};\n\n    var identity = options.name || \"unknown\",\n        originalFn = options.fn || function() {},\n        getSpy = options.getSpy || function() {},\n        plan = function() {};\n\n    this.identity = function() {\n      return identity;\n    };\n\n    this.exec = function() {\n      return plan.apply(this, arguments);\n    };\n\n    this.callThrough = function() {\n      plan = originalFn;\n      return getSpy();\n    };\n\n    this.returnValue = function(value) {\n      plan = function() {\n        return value;\n      };\n      return getSpy();\n    };\n\n    this.throwError = function(something) {\n      var error = (something instanceof Error) ? something : new Error(something);\n      plan = function() {\n        throw error;\n      };\n      return getSpy();\n    };\n\n    this.callFake = function(fn) {\n      plan = fn;\n      return getSpy();\n    };\n\n    this.stub = function(fn) {\n      plan = function() {};\n      return getSpy();\n    };\n  }\n\n  return SpyStrategy;\n};\n\ngetJasmineRequireObj().Suite = function() {\n  function Suite(attrs) {\n    this.env = attrs.env;\n    this.id = attrs.id;\n    this.parentSuite = attrs.parentSuite;\n    this.description = attrs.description;\n    this.onStart = attrs.onStart || function() {};\n    this.resultCallback = attrs.resultCallback || function() {};\n    this.clearStack = attrs.clearStack || function(fn) {fn();};\n\n    this.beforeFns = [];\n    this.afterFns = [];\n    this.queueRunner = attrs.queueRunner || function() {};\n    this.disabled = false;\n\n    this.children = [];\n\n    this.result = {\n      id: this.id,\n      status: this.disabled ? 'disabled' : '',\n      description: this.description,\n      fullName: this.getFullName()\n    };\n  }\n\n  Suite.prototype.getFullName = function() {\n    var fullName = this.description;\n    for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {\n      if (parentSuite.parentSuite) {\n        fullName = parentSuite.description + ' ' + fullName;\n      }\n    }\n    return fullName;\n  };\n\n  Suite.prototype.disable = function() {\n    this.disabled = true;\n  };\n\n  Suite.prototype.beforeEach = function(fn) {\n    this.beforeFns.unshift(fn);\n  };\n\n  Suite.prototype.afterEach = function(fn) {\n    this.afterFns.unshift(fn);\n  };\n\n  Suite.prototype.addChild = function(child) {\n    this.children.push(child);\n  };\n\n  Suite.prototype.execute = function(onComplete) {\n    var self = this;\n    if (this.disabled) {\n      complete();\n      return;\n    }\n\n    var allFns = [];\n\n    for (var i = 0; i < this.children.length; i++) {\n      allFns.push(wrapChildAsAsync(this.children[i]));\n    }\n\n    this.onStart(this);\n\n    this.queueRunner({\n      fns: allFns,\n      onComplete: complete\n    });\n\n    function complete() {\n      self.resultCallback(self.result);\n\n      if (onComplete) {\n        onComplete();\n      }\n    }\n\n    function wrapChildAsAsync(child) {\n      return function(done) { child.execute(done); };\n    }\n  };\n\n  return Suite;\n};\n\nif (typeof window == void 0 && typeof exports == \"object\") {\n  exports.Suite = jasmineRequire.Suite;\n}\n\ngetJasmineRequireObj().Timer = function() {\n  function Timer(options) {\n    options = options || {};\n\n    var now = options.now || function() { return new Date().getTime(); },\n        startTime;\n\n    this.start = function() {\n      startTime = now();\n    };\n\n    this.elapsed = function() {\n      return now() - startTime;\n    };\n  }\n\n  return Timer;\n};\n\ngetJasmineRequireObj().matchersUtil = function(j$) {\n  // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter?\n\n  return {\n    equals: function(a, b, customTesters) {\n      customTesters = customTesters || [];\n\n      return eq(a, b, [], [], customTesters);\n    },\n\n    contains: function(haystack, needle, customTesters) {\n      customTesters = customTesters || [];\n\n      if (Object.prototype.toString.apply(haystack) === \"[object Array]\") {\n        for (var i = 0; i < haystack.length; i++) {\n          if (eq(haystack[i], needle, [], [], customTesters)) {\n            return true;\n          }\n        }\n        return false;\n      }\n      return haystack.indexOf(needle) >= 0;\n    },\n\n    buildFailureMessage: function() {\n      var args = Array.prototype.slice.call(arguments, 0),\n        matcherName = args[0],\n        isNot = args[1],\n        actual = args[2],\n        expected = args.slice(3),\n        englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });\n\n      var message = \"Expected \" +\n        j$.pp(actual) +\n        (isNot ? \" not \" : \" \") +\n        englishyPredicate;\n\n      if (expected.length > 0) {\n        for (var i = 0; i < expected.length; i++) {\n          if (i > 0) {\n            message += \",\";\n          }\n          message += \" \" + j$.pp(expected[i]);\n        }\n      }\n\n      return message + \".\";\n    }\n  };\n\n  // Equality function lovingly adapted from isEqual in\n  //   [Underscore](http://underscorejs.org)\n  function eq(a, b, aStack, bStack, customTesters) {\n    var result = true;\n\n    for (var i = 0; i < customTesters.length; i++) {\n      var customTesterResult = customTesters[i](a, b);\n      if (!j$.util.isUndefined(customTesterResult)) {\n        return customTesterResult;\n      }\n    }\n\n    if (a instanceof j$.Any) {\n      result = a.jasmineMatches(b);\n      if (result) {\n        return true;\n      }\n    }\n\n    if (b instanceof j$.Any) {\n      result = b.jasmineMatches(a);\n      if (result) {\n        return true;\n      }\n    }\n\n    if (b instanceof j$.ObjectContaining) {\n      result = b.jasmineMatches(a);\n      if (result) {\n        return true;\n      }\n    }\n\n    if (a instanceof Error && b instanceof Error) {\n      return a.message == b.message;\n    }\n\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) { return a !== 0 || 1 / a == 1 / b; }\n    // A strict comparison is necessary because `null == undefined`.\n    if (a === null || b === null) { return a === b; }\n    var className = Object.prototype.toString.call(a);\n    if (className != Object.prototype.toString.call(b)) { return false; }\n    switch (className) {\n      // Strings, numbers, dates, and booleans are compared by value.\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return a == String(b);\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for\n        // other numeric values.\n        return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b);\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a == +b;\n      // RegExps are compared by their source patterns and flags.\n      case '[object RegExp]':\n        return a.source == b.source &&\n          a.global == b.global &&\n          a.multiline == b.multiline &&\n          a.ignoreCase == b.ignoreCase;\n    }\n    if (typeof a != 'object' || typeof b != 'object') { return false; }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] == a) { return bStack[length] == b; }\n    }\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n    var size = 0;\n    // Recursively compare objects and arrays.\n    if (className == '[object Array]') {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      size = a.length;\n      result = size == b.length;\n      if (result) {\n        // Deep compare the contents, ignoring non-numeric properties.\n        while (size--) {\n          if (!(result = eq(a[size], b[size], aStack, bStack, customTesters))) { break; }\n        }\n      }\n    } else {\n      // Objects with different constructors are not equivalent, but `Object`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(isFunction(aCtor) && (aCtor instanceof aCtor) &&\n        isFunction(bCtor) && (bCtor instanceof bCtor))) {\n        return false;\n      }\n      // Deep compare objects.\n      for (var key in a) {\n        if (has(a, key)) {\n          // Count the expected number of properties.\n          size++;\n          // Deep compare each member.\n          if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; }\n        }\n      }\n      // Ensure that both objects contain the same number of properties.\n      if (result) {\n        for (key in b) {\n          if (has(b, key) && !(size--)) { break; }\n        }\n        result = !size;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n\n    return result;\n\n    function has(obj, key) {\n      return obj.hasOwnProperty(key);\n    }\n\n    function isFunction(obj) {\n      return typeof obj === 'function';\n    }\n  }\n};\n\ngetJasmineRequireObj().toBe = function() {\n  function toBe() {\n    return {\n      compare: function(actual, expected) {\n        return {\n          pass: actual === expected\n        };\n      }\n    };\n  }\n\n  return toBe;\n};\n\ngetJasmineRequireObj().toBeCloseTo = function() {\n\n  function toBeCloseTo() {\n    return {\n      compare: function(actual, expected, precision) {\n        if (precision !== 0) {\n          precision = precision || 2;\n        }\n\n        return {\n          pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2)\n        };\n      }\n    };\n  }\n\n  return toBeCloseTo;\n};\n\ngetJasmineRequireObj().toBeDefined = function() {\n  function toBeDefined() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: (void 0 !== actual)\n        };\n      }\n    };\n  }\n\n  return toBeDefined;\n};\n\ngetJasmineRequireObj().toBeFalsy = function() {\n  function toBeFalsy() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: !!!actual\n        };\n      }\n    };\n  }\n\n  return toBeFalsy;\n};\n\ngetJasmineRequireObj().toBeGreaterThan = function() {\n\n  function toBeGreaterThan() {\n    return {\n      compare: function(actual, expected) {\n        return {\n          pass: actual > expected\n        };\n      }\n    };\n  }\n\n  return toBeGreaterThan;\n};\n\n\ngetJasmineRequireObj().toBeLessThan = function() {\n  function toBeLessThan() {\n    return {\n\n      compare: function(actual, expected) {\n        return {\n          pass: actual < expected\n        };\n      }\n    };\n  }\n\n  return toBeLessThan;\n};\ngetJasmineRequireObj().toBeNaN = function(j$) {\n\n  function toBeNaN() {\n    return {\n      compare: function(actual) {\n        var result = {\n          pass: (actual !== actual)\n        };\n\n        if (result.pass) {\n          result.message = \"Expected actual not to be NaN.\";\n        } else {\n          result.message = \"Expected \" + j$.pp(actual) + \" to be NaN.\";\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toBeNaN;\n};\n\ngetJasmineRequireObj().toBeNull = function() {\n\n  function toBeNull() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: actual === null\n        };\n      }\n    };\n  }\n\n  return toBeNull;\n};\n\ngetJasmineRequireObj().toBeTruthy = function() {\n\n  function toBeTruthy() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: !!actual\n        };\n      }\n    };\n  }\n\n  return toBeTruthy;\n};\n\ngetJasmineRequireObj().toBeUndefined = function() {\n\n  function toBeUndefined() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: void 0 === actual\n        };\n      }\n    };\n  }\n\n  return toBeUndefined;\n};\n\ngetJasmineRequireObj().toContain = function() {\n  function toContain(util, customEqualityTesters) {\n    customEqualityTesters = customEqualityTesters || [];\n\n    return {\n      compare: function(actual, expected) {\n\n        return {\n          pass: util.contains(actual, expected, customEqualityTesters)\n        };\n      }\n    };\n  }\n\n  return toContain;\n};\n\ngetJasmineRequireObj().toEqual = function() {\n\n  function toEqual(util, customEqualityTesters) {\n    customEqualityTesters = customEqualityTesters || [];\n\n    return {\n      compare: function(actual, expected) {\n        var result = {\n          pass: false\n        };\n\n        result.pass = util.equals(actual, expected, customEqualityTesters);\n\n        return result;\n      }\n    };\n  }\n\n  return toEqual;\n};\n\ngetJasmineRequireObj().toHaveBeenCalled = function(j$) {\n\n  function toHaveBeenCalled() {\n    return {\n      compare: function(actual) {\n        var result = {};\n\n        if (!j$.isSpy(actual)) {\n          throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');\n        }\n\n        if (arguments.length > 1) {\n          throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');\n        }\n\n        result.pass = actual.calls.any();\n\n        result.message = result.pass ?\n          \"Expected spy \" + actual.and.identity() + \" not to have been called.\" :\n          \"Expected spy \" + actual.and.identity() + \" to have been called.\";\n\n        return result;\n      }\n    };\n  }\n\n  return toHaveBeenCalled;\n};\n\ngetJasmineRequireObj().toHaveBeenCalledWith = function(j$) {\n\n  function toHaveBeenCalledWith(util) {\n    return {\n      compare: function() {\n        var args = Array.prototype.slice.call(arguments, 0),\n          actual = args[0],\n          expectedArgs = args.slice(1),\n          result = { pass: false };\n\n        if (!j$.isSpy(actual)) {\n          throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');\n        }\n\n        if (!actual.calls.any()) {\n          result.message = \"Expected spy \" + actual.and.identity() + \" to have been called with \" + j$.pp(expectedArgs) + \" but it was never called.\";\n          return result;\n        }\n\n        if (util.contains(actual.calls.allArgs(), expectedArgs)) {\n          result.pass = true;\n          result.message = \"Expected spy \" + actual.and.identity() + \" not to have been called with \" + j$.pp(expectedArgs) + \" but it was.\";\n        } else {\n          result.message = \"Expected spy \" + actual.and.identity() + \" to have been called with \" + j$.pp(expectedArgs) + \" but actual calls were \" + j$.pp(actual.calls.allArgs()).replace(/^\\[ | \\]$/g, '') + \".\";\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toHaveBeenCalledWith;\n};\n\ngetJasmineRequireObj().toMatch = function() {\n\n  function toMatch() {\n    return {\n      compare: function(actual, expected) {\n        var regexp = new RegExp(expected);\n\n        return {\n          pass: regexp.test(actual)\n        };\n      }\n    };\n  }\n\n  return toMatch;\n};\n\ngetJasmineRequireObj().toThrow = function(j$) {\n\n  function toThrow(util) {\n    return {\n      compare: function(actual, expected) {\n        var result = { pass: false },\n          threw = false,\n          thrown;\n\n        if (typeof actual != \"function\") {\n          throw new Error(\"Actual is not a Function\");\n        }\n\n        try {\n          actual();\n        } catch (e) {\n          threw = true;\n          thrown = e;\n        }\n\n        if (!threw) {\n          result.message = \"Expected function to throw an exception.\";\n          return result;\n        }\n\n        if (arguments.length == 1) {\n          result.pass = true;\n          result.message = \"Expected function not to throw, but it threw \" + j$.pp(thrown) + \".\";\n\n          return result;\n        }\n\n        if (util.equals(thrown, expected)) {\n          result.pass = true;\n          result.message = \"Expected function not to throw \" + j$.pp(expected) + \".\";\n        } else {\n          result.message = \"Expected function to throw \" + j$.pp(expected) + \", but it threw \" +  j$.pp(thrown) + \".\";\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toThrow;\n};\n\ngetJasmineRequireObj().toThrowError = function(j$) {\n  function toThrowError (util) {\n    return {\n      compare: function(actual) {\n        var threw = false,\n          thrown,\n          errorType,\n          message,\n          regexp,\n          name,\n          constructorName;\n\n        if (typeof actual != \"function\") {\n          throw new Error(\"Actual is not a Function\");\n        }\n\n        extractExpectedParams.apply(null, arguments);\n\n        try {\n          actual();\n        } catch (e) {\n          threw = true;\n          thrown = e;\n        }\n\n        if (!threw) {\n          return fail(\"Expected function to throw an Error.\");\n        }\n\n        if (!(thrown instanceof Error)) {\n          return fail(\"Expected function to throw an Error, but it threw \" + thrown + \".\");\n        }\n\n        if (arguments.length == 1) {\n          return pass(\"Expected function not to throw an Error, but it threw \" + fnNameFor(thrown) + \".\");\n        }\n\n        if (errorType) {\n          name = fnNameFor(errorType);\n          constructorName = fnNameFor(thrown.constructor);\n        }\n\n        if (errorType && message) {\n          if (thrown.constructor == errorType && util.equals(thrown.message, message)) {\n            return pass(\"Expected function not to throw \" + name + \" with message \\\"\" + message + \"\\\".\");\n          } else {\n            return fail(\"Expected function to throw \" + name + \" with message \\\"\" + message +\n                        \"\\\", but it threw \" + constructorName + \" with message \\\"\" + thrown.message + \"\\\".\");\n          }\n        }\n\n        if (errorType && regexp) {\n          if (thrown.constructor == errorType && regexp.test(thrown.message)) {\n            return pass(\"Expected function not to throw \" + name + \" with message matching \" + regexp + \".\");\n          } else {\n            return fail(\"Expected function to throw \" + name + \" with message matching \" + regexp +\n                        \", but it threw \" + constructorName + \" with message \\\"\" + thrown.message + \"\\\".\");\n          }\n        }\n\n        if (errorType) {\n          if (thrown.constructor == errorType) {\n            return pass(\"Expected function not to throw \" + name + \".\");\n          } else {\n            return fail(\"Expected function to throw \" + name + \", but it threw \" + constructorName + \".\");\n          }\n        }\n\n        if (message) {\n          if (thrown.message == message) {\n            return pass(\"Expected function not to throw an exception with message \" + j$.pp(message) + \".\");\n          } else {\n            return fail(\"Expected function to throw an exception with message \" + j$.pp(message) +\n                        \", but it threw an exception with message \" + j$.pp(thrown.message) + \".\");\n          }\n        }\n\n        if (regexp) {\n          if (regexp.test(thrown.message)) {\n            return pass(\"Expected function not to throw an exception with a message matching \" + j$.pp(regexp) + \".\");\n          } else {\n            return fail(\"Expected function to throw an exception with a message matching \" + j$.pp(regexp) +\n                        \", but it threw an exception with message \" + j$.pp(thrown.message) + \".\");\n          }\n        }\n\n        function fnNameFor(func) {\n            return func.name || func.toString().match(/^\\s*function\\s*(\\w*)\\s*\\(/)[1];\n        }\n\n        function pass(notMessage) {\n          return {\n            pass: true,\n            message: notMessage\n          };\n        }\n\n        function fail(message) {\n          return {\n            pass: false,\n            message: message\n          };\n        }\n\n        function extractExpectedParams() {\n          if (arguments.length == 1) {\n            return;\n          }\n\n          if (arguments.length == 2) {\n            var expected = arguments[1];\n\n            if (expected instanceof RegExp) {\n              regexp = expected;\n            } else if (typeof expected == \"string\") {\n              message = expected;\n            } else if (checkForAnErrorType(expected)) {\n              errorType = expected;\n            }\n\n            if (!(errorType || message || regexp)) {\n              throw new Error(\"Expected is not an Error, string, or RegExp.\");\n            }\n          } else {\n            if (checkForAnErrorType(arguments[1])) {\n              errorType = arguments[1];\n            } else {\n              throw new Error(\"Expected error type is not an Error.\");\n            }\n\n            if (arguments[2] instanceof RegExp) {\n              regexp = arguments[2];\n            } else if (typeof arguments[2] == \"string\") {\n              message = arguments[2];\n            } else {\n              throw new Error(\"Expected error message is not a string or RegExp.\");\n            }\n          }\n        }\n\n        function checkForAnErrorType(type) {\n          if (typeof type !== \"function\") {\n            return false;\n          }\n\n          var Surrogate = function() {};\n          Surrogate.prototype = type.prototype;\n          return (new Surrogate()) instanceof Error;\n        }\n      }\n    };\n  }\n\n  return toThrowError;\n};\n\ngetJasmineRequireObj().version = function() {\n  return \"2.0.0\";\n};\n"
  },
  {
    "path": "test/jasmine/spec/NeuralNetSpec.js",
    "content": "describe(\"Simple Fully-Connected Neural Net Classifier\", function() {\n  var net;\n  var trainer;\n\n  beforeEach(function() {\n    net = new convnetjs.Net();\n\n    var layer_defs = [];\n    layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:2});\n    layer_defs.push({type:'fc', num_neurons:5, activation:'tanh'});\n    layer_defs.push({type:'fc', num_neurons:5, activation:'tanh'});\n    layer_defs.push({type:'softmax', num_classes:3});\n    net.makeLayers(layer_defs);\n\n    trainer = new convnetjs.SGDTrainer(net, \n          {learning_rate:0.0001, momentum:0.0, batch_size:1, l2_decay:0.0});\n  });\n\n  it(\"should be possible to initialize\", function() {\n    \n    // tanh are their own layers. Softmax gets its own fully connected layer.\n    // this should all get desugared just fine.\n    expect(net.layers.length).toEqual(7); \n    \n  });\n\n  it(\"should forward prop volumes to probabilities\", function() {\n\n    var x = new convnetjs.Vol([0.2, -0.3]);\n    var probability_volume = net.forward(x);\n\n    expect(probability_volume.w.length).toEqual(3); // 3 classes output\n    var w = probability_volume.w;\n    for(var i=0;i<3;i++) {\n      expect(w[i]).toBeGreaterThan(0);\n      expect(w[i]).toBeLessThan(1.0);\n    }\n    expect(w[0]+w[1]+w[2]).toBeCloseTo(1.0);\n\n  });\n\n  it(\"should increase probabilities for ground truth class when trained\", function() {\n\n    // lets test 100 random point and label settings\n    // note that this should work since l2 and l1 regularization are off\n    // an issue is that if step size is too high, this could technically fail...\n    for(var k=0;k<100;k++) {\n      var x = new convnetjs.Vol([Math.random() * 2 - 1, Math.random() * 2 - 1]);\n      var pv = net.forward(x);\n      var gti = Math.floor(Math.random() * 3);\n      trainer.train(x, gti);\n      var pv2 = net.forward(x);\n      expect(pv2.w[gti]).toBeGreaterThan(pv.w[gti]);\n    }\n\n  });\n\n  it(\"should compute correct gradient at data\", function() {\n\n    // here we only test the gradient at data, but if this is\n    // right then that's comforting, because it is a function \n    // of all gradients above, for all layers.\n\n    var x = new convnetjs.Vol([Math.random() * 2 - 1, Math.random() * 2 - 1]);\n    var gti = Math.floor(Math.random() * 3); // ground truth index\n    trainer.train(x, gti); // computes gradients at all layers, and at x\n\n    var delta = 0.000001;\n\n    for(var i=0;i<x.w.length;i++) {\n\n      var grad_analytic = x.dw[i];\n\n      var xold = x.w[i];\n      x.w[i] += delta;\n      var c0 = net.getCostLoss(x, gti);\n      x.w[i] -= 2*delta;\n      var c1 = net.getCostLoss(x, gti);\n      x.w[i] = xold; // reset\n\n      var grad_numeric = (c0 - c1)/(2 * delta);\n      var rel_error = Math.abs(grad_analytic - grad_numeric)/Math.abs(grad_analytic + grad_numeric);\n      console.log(i + ': numeric: ' + grad_numeric + ', analytic: ' + grad_analytic + ' => rel error ' + rel_error);\n      expect(rel_error).toBeLessThan(1e-2);\n\n    }\n  });\n});\n"
  }
]