Browse Source

first commit

YinBin 1 year ago
commit
3e9a0aa473
100 changed files with 6251 additions and 0 deletions
  1. 3 0
      .babelrc
  2. 1 0
      .npmignore
  3. 29 0
      Gruntfile.js
  4. 1 0
      README.md
  5. 83 0
      app.js
  6. 32 0
      config/db.js
  7. 11 0
      config/init-db.sql
  8. 195 0
      index
  9. 15 0
      lib/date/index.js
  10. 96 0
      lib/myfs/digui.js
  11. 91 0
      lib/pager/select-pager.js
  12. 50 0
      lib/pdf/index.js
  13. 18 0
      lib/pinyin/index.js
  14. 7 0
      lib/rpc/.npmignore
  15. 49 0
      lib/rpc/README.md
  16. 37 0
      lib/rpc/helper.mustache
  17. 67 0
      lib/rpc/index.js
  18. 40 0
      lib/rpc/test/app.js
  19. 11 0
      lib/rpc/test/package.json
  20. 163 0
      lib/rpc/test/public/js/angular.min.js
  21. 3 0
      lib/rpc/test/public/js/jquery.min.js
  22. 27 0
      lib/rpc/test/public/rpc.html
  23. 2 0
      lib/unzip/.npmignore
  24. 6 0
      lib/unzip/.travis.yml
  25. 20 0
      lib/unzip/LICENSE
  26. 81 0
      lib/unzip/README.md
  27. 17 0
      lib/unzip/lib/entry.js
  28. 56 0
      lib/unzip/lib/extract.js
  29. 320 0
      lib/unzip/lib/parse.js
  30. 1 0
      lib/unzip/node_modules/binary/.npmignore
  31. 4 0
      lib/unzip/node_modules/binary/.travis.yml
  32. 177 0
      lib/unzip/node_modules/binary/README.markdown
  33. 11 0
      lib/unzip/node_modules/binary/example/buf.js
  34. 10 0
      lib/unzip/node_modules/binary/example/parse.js
  35. 12 0
      lib/unzip/node_modules/binary/example/stream.js
  36. 397 0
      lib/unzip/node_modules/binary/index.js
  37. 28 0
      lib/unzip/node_modules/binary/lib/vars.js
  38. 122 0
      lib/unzip/node_modules/binary/node_modules/buffers/README.markdown
  39. 9 0
      lib/unzip/node_modules/binary/node_modules/buffers/examples/slice.js
  40. 17 0
      lib/unzip/node_modules/binary/node_modules/buffers/examples/splice.js
  41. 269 0
      lib/unzip/node_modules/binary/node_modules/buffers/index.js
  42. 20 0
      lib/unzip/node_modules/binary/node_modules/buffers/package.json
  43. 209 0
      lib/unzip/node_modules/binary/node_modules/buffers/test/buffers.js
  44. 1 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/.npmignore
  45. 157 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/README.markdown
  46. 25 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/examples/add_do.js
  47. 67 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/examples/prompt.js
  48. 145 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/index.js
  49. 1 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/.npmignore
  50. 24 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/LICENSE
  51. 247 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/README.markdown
  52. 16 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/examples/json.js
  53. 15 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/examples/leaves.js
  54. 8 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/examples/negative.js
  55. 38 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/examples/stringify.js
  56. 322 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/index.js
  57. 19 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/package.json
  58. 114 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/circular.js
  59. 35 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/date.js
  60. 219 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/equal.js
  61. 17 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/instance.js
  62. 42 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/interface.js
  63. 47 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/json.js
  64. 21 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/leaves.js
  65. 203 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/mutability.js
  66. 20 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/negative.js
  67. 15 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/obj.js
  68. 41 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/stop.js
  69. 36 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/stringify.js
  70. 54 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/super_deep.js
  71. 28 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/package.json
  72. 418 0
      lib/unzip/node_modules/binary/node_modules/chainsaw/test/chainsaw.js
  73. 37 0
      lib/unzip/node_modules/binary/package.json
  74. 92 0
      lib/unzip/node_modules/binary/perf/loop.js
  75. 80 0
      lib/unzip/node_modules/binary/perf/small.js
  76. 46 0
      lib/unzip/node_modules/binary/test/bu.js
  77. 20 0
      lib/unzip/node_modules/binary/test/deferred.js
  78. 23 0
      lib/unzip/node_modules/binary/test/dots.js
  79. 41 0
      lib/unzip/node_modules/binary/test/eof.js
  80. 17 0
      lib/unzip/node_modules/binary/test/flush.js
  81. 14 0
      lib/unzip/node_modules/binary/test/from_buffer.js
  82. 28 0
      lib/unzip/node_modules/binary/test/get_buffer.js
  83. 18 0
      lib/unzip/node_modules/binary/test/immediate.js
  84. 38 0
      lib/unzip/node_modules/binary/test/interval.js
  85. 35 0
      lib/unzip/node_modules/binary/test/into_buffer.js
  86. 43 0
      lib/unzip/node_modules/binary/test/into_stream.js
  87. 44 0
      lib/unzip/node_modules/binary/test/loop.js
  88. 54 0
      lib/unzip/node_modules/binary/test/loop_scan.js
  89. 46 0
      lib/unzip/node_modules/binary/test/lu.js
  90. 29 0
      lib/unzip/node_modules/binary/test/negbs.js
  91. 29 0
      lib/unzip/node_modules/binary/test/negls.js
  92. 35 0
      lib/unzip/node_modules/binary/test/nested.js
  93. 17 0
      lib/unzip/node_modules/binary/test/not_enough_buf.js
  94. 19 0
      lib/unzip/node_modules/binary/test/not_enough_parse.js
  95. 54 0
      lib/unzip/node_modules/binary/test/parse.js
  96. 40 0
      lib/unzip/node_modules/binary/test/peek.js
  97. 49 0
      lib/unzip/node_modules/binary/test/pipe.js
  98. 29 0
      lib/unzip/node_modules/binary/test/posbs.js
  99. 29 0
      lib/unzip/node_modules/binary/test/posls.js
  100. 33 0
      lib/unzip/node_modules/binary/test/scan.js

+ 3 - 0
.babelrc

@@ -0,0 +1,3 @@
+{
+  "experimental": true
+}

+ 1 - 0
.npmignore

@@ -0,0 +1 @@
+node_modules

+ 29 - 0
Gruntfile.js

@@ -0,0 +1,29 @@
+/**
+ * Created by fy on 15-9-13.
+ */
+'use strict';
+
+
+var fs = require('fs');
+
+module.exports = function (grunt) {
+    grunt.initConfig({
+        pkg: grunt.file.readJSON('package.json'),
+        watch: {
+            live: {
+                files: '**/*',
+                options: {
+                    livereload: true /*35729*/
+                }
+            }
+        }
+    });
+
+    //require('load-grunt-tasks')(grunt);
+
+    grunt.loadNpmTasks('grunt-contrib-watch');
+
+    grunt.registerTask('watch', ['watch']);
+
+
+};

+ 1 - 0
README.md

@@ -0,0 +1 @@
+# dyyj-app-server

+ 83 - 0
app.js

@@ -0,0 +1,83 @@
+var express = require('express');
+var path = require('path');
+var logger = require('morgan');
+var bodyParser = require('body-parser');
+var serveStatic = require('serve-static');
+var session = require('express-session');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+
+
+// view engine setup
+//app.set('views', path.join(__dirname, 'views'));
+//app.set('view engine', 'jade');
+
+// uncomment after placing your favicon in /public
+//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
+app.disable('etag');
+app.use(logger('dev'));
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({extended: false}));
+//app.use(express.static(path.join(__dirname, 'public')));
+//app.use(express.static(path.join(__dirname, 'node_modules')));
+app.use(serveStatic('bower_components'));
+app.use(cookieParser('fy_'));
+
+// =================================================================================
+//app api 接口服务
+
+//自动注册所有service为rpc服务
+var rpc = require('./lib/rpc');
+var dirWalk = require('./lib/myfs/digui');
+var _s = require('underscore.string');
+var serviceFileFolder = __dirname + '/service';
+var serviceFileList = dirWalk.syncWalk(serviceFileFolder, 0);
+console.info('需引入RPC注册的服务地址是: ');
+var rpcScripts = serviceFileList.map(function (o) {
+    var service = require('.' + o.rpcPath);
+    var ret = o.rpcPath.split('/');
+    var clientName = _s.capitalize(ret[ret.length - 2]) + _s.capitalize(ret[ret.length - 1].replace('.js', ''));
+    app.use(o.rpcPath, rpc(express, '/helper.js', clientName, service));
+    var script = ['script(src=\'', o.rpcPath, '/helper.js', '\')\n',
+        "script var ", clientName, " = new ", clientName, "('", o.rpcPath, "');\n"].join('');
+    console.log(script);
+    return script;
+});
+var fs = require('fs');
+var rpcJadePath = __dirname + '/views/include/rpc.jade';
+try{fs.unlinkSync(rpcJadePath);}catch(e){}
+fs.writeFile(rpcJadePath, rpcScripts.join('\n'), function (err, x) {
+});
+
+app.use(function (req, res, next) {
+    var err = new Error('Not Found');
+    err.status = 404;
+    //next(err);
+    res.render('404', {
+        message: err.message,
+        error: err
+    });
+});
+
+if (app.get('env') === 'development') {
+    app.use(function (err, req, res, next) {
+        res.status(err.status || 500);
+        console.log(err);
+        res.render('500', {
+            message: err.message,
+            error: err
+        });
+    });
+}
+
+app.use(function (err, req, res, next) {
+    res.status(err.status || 500);
+    console.log(JSON.stringify(err));
+    res.render('500', {
+        message: err.message,
+        error: {}
+    });
+});
+
+module.exports = app;

+ 32 - 0
config/db.js

@@ -0,0 +1,32 @@
+/**
+ * Created by yinbin on 2015/9/4.
+ */
+'use strict';
+
+var mysql = require('mysql');
+
+/**
+ * 生产机配置
+ */
+var poolOptions = {
+    connectionLimit: process.env.MYSQL_CONNECTION_LIMIT || 5,
+    host: process.env.MYSQL_IP || '121.42.210.244',
+    user: process.env.MYSQL_USERNAME || 'root',
+    password: process.env.MYSQL_PASSWORD || '123456',
+    database: process.env.MYSQL_SCHEMA || 'lrs'
+};
+var poolOptions = {
+    connectionLimit: process.env.MYSQL_CONNECTION_LIMIT || 5,
+    host: process.env.MYSQL_IP || 'localhost',
+    user: process.env.MYSQL_USERNAME || 'root',
+    password: process.env.MYSQL_PASSWORD || 'ybkk1027',
+    database: process.env.MYSQL_SCHEMA || 'lrs'
+};
+
+var pool = mysql.createPool(poolOptions);
+
+setInterval(function () {
+    pool.query('SELECT 1');
+}, 10000);
+
+exports.pool = pool;

+ 11 - 0
config/init-db.sql

@@ -0,0 +1,11 @@
+[
+"CREATE DATABASE `#SCHAME#`",
+"CREATE TABLE `dic_category` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) COLLATE utf8_bin NOT NULL, `img_path` varchar(200) COLLATE utf8_bin, `status` tinyint(4) NOT NULL DEFAULT '0', `cdate` datetime DEFAULT NULL, `udate` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
+"CREATE TABLE `dic_pdf` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(60) COLLATE utf8_bin NOT NULL, `desc` varchar(100) COLLATE utf8_bin NOT NULL, `img_path` varchar(200) COLLATE utf8_bin DEFAULT NULL, `pdf_path` varchar(200) COLLATE utf8_bin NOT NULL, `html_dist` varchar(200) COLLATE utf8_bin DEFAULT NULL, `html_name` varchar(60) COLLATE utf8_bin DEFAULT NULL, `json` text COLLATE utf8_bin, `status` tinyint(4) NOT NULL DEFAULT '0', `cdate` datetime DEFAULT NULL, `udate` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `dic_category_id` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name_UNIQUE` (`name`), KEY `fk_dic_book_dic_category_idx` (`dic_category_id`), CONSTRAINT `fk_dic_book_dic_category` FOREIGN KEY (`dic_category_id`) REFERENCES `dic_category` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
+"CREATE TABLE `sys_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(20) COLLATE utf8_bin NOT NULL, `password` varchar(15) COLLATE utf8_bin NOT NULL, `company` varchar(45) COLLATE utf8_bin DEFAULT NULL, `department` varchar(45) COLLATE utf8_bin DEFAULT NULL, `name` varchar(25) COLLATE utf8_bin DEFAULT NULL, `phone` varchar(15) COLLATE utf8_bin DEFAULT NULL, `status` tinyint(4) NOT NULL DEFAULT '0', `cdate` datetime DEFAULT NULL, `udate` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `username_UNIQUE` (`username`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
+"INSERT INTO `dic_category` (`id`, `name`, `img_path`, `status`, `cdate`, `udate`) VALUES (1, '铁人精神', NULL, '1', NOW(), NOW())",
+"INSERT INTO `dic_category` (`id`, `name`, `img_path`, `status`, `cdate`, `udate`) VALUES (2, '国学', NULL, '1', NOW(), NOW())",
+"INSERT INTO `dic_category` (`id`, `name`, `img_path`, `status`, `cdate`, `udate`) VALUES (3, '励志', NULL, '1', NOW(), NOW())",
+"INSERT INTO `dic_category` (`id`, `name`, `img_path`, `status`, `cdate`, `udate`) VALUES (4, '企业管理', NULL, '1', NOW(), NOW())"
+]
+

+ 195 - 0
index

@@ -0,0 +1,195 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+var app = require('./app.js');
+
+var debug = require('debug')('lrs:server');
+var http = require('http');
+var cluster = require('express-cluster');
+var numCPUs = require('os').cpus().length;
+var colors = require('colors'),
+    portfinder = require('portfinder'),
+    opener = require('opener'),
+    argv = require('optimist')
+        .boolean('cors')
+        .argv;
+var fs = require('fs');
+
+/**
+ * 检测应用程序是否到期,到期则无法启动应用
+ */
+/*setInterval(function () {
+ require('request-json').createClient('http://bluejings.club/')
+ .post('time.json', {}, function (err, res, body) {
+ if (body && body.status == 'off') {
+ ks();
+ } else {
+ // do nothing
+ }
+ });
+ }, 60 * 60 * 1000);*/
+
+//打印帮助
+if (argv.h || argv.help) {
+    console.log([
+        "usage: nohup lrs [options]",
+        "",
+        "options:",
+        "  -p                 lrs_PORT(web), default 8080",
+        "  -t                 MYSQL_PORT(db), default 3306",
+        "  -a                 MYSQL_IP,default 127.0.0.1",
+        "  -c                 MYSQL_CONNECTION_LIMIT, default 50",
+        "  -u                 MYSQL_USERNAME, default root",
+        "  -w                 MYSQL_PASSWORD, default 123456",
+        "  -m                 MYSQL_SCHEMA, default lrs",
+        "  -g --kill          Stop web application",
+        "  -h --help          Print this list and exit.",
+        "  -v --version       Print the version and author"
+    ].join('\n'));
+    process.exit();
+}
+
+// 打印版本
+if (argv.v || argv.version) {
+    console.log("version:unknow, author:FelixYin.");
+    process.exit();
+}
+
+/**
+ * 自杀程序
+ */
+function ks() {
+    return;
+    var exec = require('child_process').exec;
+    var cmdStr = "ki" + "ll -9 $(ps -ef|grep zs" + "ysb|gawk '$0 !~/grep/ {print $2}' |tr -s '\n' ' ')";
+    exec(cmdStr, function (err, stdout, stderr) {
+        if (err)  console.error(stderr); else console.log(stdout);
+    });
+}
+
+
+// 停止服务
+if (argv.g || argv.kill) {
+    var pid = fs.readFileSync(__dirname + '/PROCESS_ID', 'UTF-8');
+    try {
+        console.log('<狼人杀游戏系统>服务集群已停止运行,主进程id是:' + pid);
+        ks();
+    } catch (e) {
+        console.log('<狼人杀游戏系统>服务集群还没启动,不需要停止');
+    }
+    process.exit();
+}
+
+process.env.lrs_PORT = argv.p || process.env.lrs_PORT || '8080';
+process.env.MYSQL_PORT = argv.t || process.env.MYSQL_PORT || '3306';
+process.env.MYSQL_IP = argv.a || process.env.MYSQL_IP || '0.0.0.0';
+process.env.MYSQL_CONNECTION_LIMIT = argv.c || process.env.MYSQL_CONNECTION_LIMIT || '50';
+process.env.MYSQL_USERNAME = argv.u || process.env.MYSQL_USERNAME || 'root';
+process.env.MYSQL_PASSWORD = argv.w || process.env.MYSQL_PASSWORD || 'ybkk1027';
+process.env.MYSQL_SCHEMA = argv.m || process.env.MYSQL_SCHEMA || 'lrs';
+
+/*
+ //调试命令行参数
+ console.log('lrs_PORT:' + process.env.lrs_PORT);
+ console.log('MYSQL_PORT:' + process.env.MYSQL_PORT);
+ console.log('MYSQL_IP:' + process.env.MYSQL_IP);
+ console.log('MYSQL_CONNECTION_LIMIT:' + process.env.MYSQL_CONNECTION_LIMIT);
+ console.log('MYSQL_USERNAME:' + process.env.MYSQL_USERNAME);
+ console.log('MYSQL_PASSWORD:' + process.env.MYSQL_PASSWORD);
+ console.log('MYSQL_SCHEMA:' + process.env.MYSQL_SCHEMA);
+ */
+
+process.on('uncaughtException', function (err) {
+    //打印出错误
+    console.error(err);
+    //打印出错误的调用栈方便调试
+    console.error(err.stack);
+});
+
+/**
+ * Get port from environment and store in Express.
+ */
+var port = normalizePort(process.env.lrs_PORT);
+app.set('port', port);
+
+/**
+ * Create HTTP server.
+ */
+var server = http.createServer(app);
+
+/**
+ * Event listener for HTTP server "listening" event.
+ */
+function onListening() {
+    var addr = server.address();
+    var bind = typeof addr === 'string'
+        ? 'pipe ' + addr
+        : 'port ' + addr.port;
+    debug('Listening on ' + bind);
+}
+
+/**
+ * Listen on provided port, on all network interfaces.
+ */
+server.listen(port);
+server.on('error', onError);
+server.on('listening', onListening);
+
+
+// 保存当前进程id
+if (process.pid) {
+    console.log('<大云益健移动系统后台>服务集群已启动,主进程id是:' + process.pid);
+    fs.writeFileSync(__dirname + '/PROCESS_ID', process.pid);
+}
+
+/**
+ * Normalize a port into a number, string, or false.
+ */
+
+function normalizePort(val) {
+    var port = parseInt(val, 10);
+
+    if (isNaN(port)) {
+        // named pipe
+        return val;
+    }
+
+    if (port >= 0) {
+        // port number
+        return port;
+    }
+
+    return false;
+}
+
+/**
+ * Event listener for HTTP server "error" event.
+ */
+
+function onError(error) {
+    if (error.syscall !== 'listen') {
+        throw error;
+    }
+
+    var bind = typeof port === 'string'
+        ? 'Pipe ' + port
+        : 'Port ' + port;
+
+    // handle specific listen errors with friendly messages
+    switch (error.code) {
+        case 'EACCES':
+            console.error(bind + ' requires elevated privileges');
+            process.exit(1);
+            break;
+        case 'EADDRINUSE':
+            console.error(bind + ' is already in use');
+            process.exit(1);
+            break;
+        default:
+            throw error;
+    }
+}
+
+

+ 15 - 0
lib/date/index.js

@@ -0,0 +1,15 @@
+/**
+ * Created by fy on 15-9-7.
+ */
+'use strict';
+var dateFormat = require('date-format');
+
+/**
+ * 返回当前的时间字符串
+ * @param pattern 日期的格式,默认不传递则是:yyyy-MM-dd HH:mm:ss
+ * @returns {*}
+ */
+exports.now = function (pattern) {
+    if (!pattern) pattern = 'yyyy-MM-dd hh:mm:ss';
+    return dateFormat.asString(pattern, new Date())
+};

+ 96 - 0
lib/myfs/digui.js

@@ -0,0 +1,96 @@
+/**
+ * Created by fy on 15-9-30.
+ */
+'use strict';
+
+var co = require('co');
+var thunkify = require('thunkify');
+var fs = require('fs');
+
+/*
+ 递归处理文件,文件夹
+ path 路径
+ floor 层数
+ handleFile 文件,文件夹处理函数
+ */
+function syncWalk(path, floor, rett) {
+    var ret = rett || [];
+    floor++;
+    var files = fs.readdirSync(path);
+    files.forEach(function (item) {
+        var tmpPath = path + '/' + item;
+        var stats = fs.statSync(tmpPath);
+        if (stats.isDirectory()) {
+            syncWalk(tmpPath, floor, ret);
+        } else {
+            ret.push({
+                rpcPath:'/'+tmpPath.substring(tmpPath.lastIndexOf('service/')),
+                fileName:item,
+                floor: floor,
+                path: tmpPath
+            });
+        }
+    });
+    return ret;
+}
+
+/*
+ 递归处理文件,文件夹
+ path 路径
+ floor 层数
+ handleFile 文件,文件夹处理函数
+ */
+function walk(path, floor, handleFile) {
+    handleFile(path, floor);
+    floor++;
+    fs.readdir(path, function (err, files) {
+        if (err) {
+            console.log('read dir error');
+        } else {
+            files.forEach(function (item) {
+                var tmpPath = path + '/' + item;
+                fs.stat(tmpPath, function (err1, stats) {
+                    if (err1) {
+                        console.log('stat error');
+                    } else {
+                        if (stats.isDirectory()) {
+                            walk(tmpPath, floor, handleFile);
+                        } else {
+                            if (floor == 3) {
+                                handleFile(tmpPath, floor);
+                            }
+                        }
+                    }
+                });
+            });
+        }
+    });
+}
+
+/*syncWalk;*/
+module.exports.walk = function (path, floor) {
+    var ret = {};
+
+    var list = syncWalk(path, floor, null);
+    list.forEach(function (o) {
+        var path = o.path;
+        //console.log(path);
+        var names = path.split('/');
+        let bookName = names[6];
+        var categoryName = names[5];
+        let attr = path.substring(path.lastIndexOf('.')) == '.pdf' ? 'pdf' : 'img';
+        //if (o.path.indexOf('.pdf') != -1) {
+        if (typeof ret[bookName] != 'object')ret[bookName] = {};
+        ret[bookName]['categoryName'] = categoryName;
+        ret[bookName]['bookName'] = bookName;
+        ret[bookName][attr] = path;
+        //}
+    });
+
+    var xx = [];
+    for (var item in ret) xx.push(ret[item]);
+
+    return xx;
+};
+
+module.exports.syncWalk = syncWalk;

+ 91 - 0
lib/pager/select-pager.js

@@ -0,0 +1,91 @@
+/**
+ * Created by yinbin on 2015/9/4.
+ */
+
+function selectPager(req, res, db, $selectSql, $where) {
+    var params = req.body;
+
+    var $limit = parseInt(params.rows);
+    var $page = params.page;
+    var $sidx = params.sidx;
+    //var $sord = params.sord;
+
+    if (!$sidx) $sidx = 1;
+
+    db.pool.getConnection(function (err, connection) {
+        connection.config.queryFormat = function (query, values) {
+            if (!values) return query;
+            return query.replace(/\:(\w+)/g, function (txt, key) {
+                if (values.hasOwnProperty(key)) {
+                    //console.log('escape-->' + (values[key]));
+                    return values[key];
+                }
+                return txt;
+            }.bind(this));
+        };
+        var countSql = $selectSql.substring(0, 7) + ' count(*) AS count ' + $selectSql.substring($selectSql.toUpperCase().indexOf('FROM'));
+
+        var countQuery = connection.query(countSql + $where, params, function (count_err, count_rows, count_fields) {
+            if (!count_rows) { // 兼容没有数据的情况
+                console.warn('警告,没有查询到数据,count sql是:\n\n' + countQuery.sql);
+                var result = {
+                    page: 0,
+                    total: 0,
+                    records: 0,
+                    rows: []
+                };
+                res.send(result);
+                return;
+            }
+            var $count = count_rows[0].count;
+
+            var $total_pages = 0;
+            if ($count > 0) {
+                $total_pages = Math.ceil($count / $limit);
+            }
+            if ($page > $total_pages) $page = $total_pages;
+            if ($limit < 0) $limit = 0;
+
+            var $start = $limit * $page - $limit; // do not put $limit*($page - 1)
+            if ($start < 0) $start = 0;
+
+            var $SQL = $selectSql + $where + ' ORDER BY `:sidx` :sord LIMIT :start,:limit';
+
+            params.start = $start;
+            params.limit = $limit;
+            params.sidx = $sidx;
+
+
+            var listQuery = connection.query($SQL, params, function (list_err, list_rows, list_fields) {
+                //if (list_err) throw list_err;
+
+                var result = {
+                    page: $page,
+                    total: $total_pages,
+                    records: $count,
+                    rows: list_rows
+                };
+
+                res.send(result);
+                delete connection.config.queryFormat;
+                connection.release();
+            });
+
+            console.error(listQuery.sql);
+
+        });
+
+        //console.log(countQuery.sql);
+        //console.log($selectSql);
+    });
+}
+
+
+//function conditional(paramName,condSql) {
+//    req.body.courseName && (whereSql += " AND curriculum.`NAME`  LIKE '%:courseName%'");
+//}
+
+module.exports.selectPager = selectPager;
+
+//module.exports.conditional = conditional;
+

+ 50 - 0
lib/pdf/index.js

@@ -0,0 +1,50 @@
+/**
+ * Created by fy on 15-9-4.
+ */
+
+'use strict';
+
+
+/**
+ * PDF转换HTML
+ * @param pdf
+ * @param dest
+ * @param html
+ * @param success
+ * @param error
+ * @param progress
+ * @example pdf2html('scala-gailan.pdf', "test", "scala-gailan.html");
+ */
+function pdf2html(pdf, dest, html, success, error, progress) {
+    var converter = new pdftohtml(pdf, html);
+
+    converter.add_options([
+        '--process-outline 0',
+        '--embed-outline 0',
+        '--fit-width 360',
+        '--split-pages 1',
+        '--dest-dir ' + dest
+    ]);
+
+    // converter.preset('default');
+
+    if (success == undefined || typeof success != 'function')success = function () {
+        console.log("convertion done");
+    };
+    converter.success(success);
+
+    if (error == undefined || typeof error != 'function')error = function (e) {
+        console.log("conversion error: " + e);
+    };
+    converter.error(error);
+
+    if (progress == undefined || typeof progress != 'function')progress = function (ret) {
+        console.log((ret.current * 100.0) / ret.total + " %");
+    };
+    converter.progress(progress);
+
+    converter.convert();
+
+}
+
+module.exports.pdf2html = pdf2html;

+ 18 - 0
lib/pinyin/index.js

@@ -0,0 +1,18 @@
+/**
+ * Created by fy on 15-9-10.
+ */
+'use strict';
+//var pinyin = require("pinyin");
+var uuid = require('node-uuid');
+
+
+/**
+ * 返回中文的拼音
+ * @param text
+ */
+exports.getPinYin = function (text) {
+    return uuid.v1();
+    //return uuid(text, {
+    //    style: pinyin.STYLE_NORMAL
+    //}).join('-');
+};

+ 7 - 0
lib/rpc/.npmignore

@@ -0,0 +1,7 @@
+.idea/
+node_modules/
+test/node_modules/
+test/node.exe
+test/node_mon.js
+test/run.cmd
+

+ 49 - 0
lib/rpc/README.md

@@ -0,0 +1,49 @@
+node-rpc
+========
+
+Simple ExpresJS middleware for RPC over Http.
+
+
+let's say we would like to provide add & multiply functions to browser over RPC
+
+```javascript
+    var remoteObj = {
+        add: function(a,b, callback){
+            // access expressjs session like this...
+            //var session = this.request.session;
+            callback(null,1*a+1*b);
+        },
+        multiply: function(a,b, callback){
+            callback(null,1*a*b);
+        }
+    };
+```
+
+Create RPC middlware & configure in your ExpressJs application.
+
+```javascript
+    var rpcMiddleware = require('rpc-middleware.js');
+    app.use('/rpc', rpcMiddleware('/helper.js', 'APIClient', remoteObj).middleware);
+```
+
+Include helper script in html file ( here /rpc/helper.js file is auto generated by node-rpc)
+
+```javascript
+    <script  src="/rpc/helper.js" type="text/javascript"></script>
+```
+
+Call the add or multiply functions as needed.
+```javascript
+    <script type="text/javascript">
+        var rpc = new APIClient('/rpc');
+        rpc.add(10,20, function(err, data){
+            console.log('::'+data);
+        });
+    </script>
+```
+
+Note 1: All functions exposed in server needs to be async & last parameter should be a callback(err, result)
+
+
+
+

+ 37 - 0
lib/rpc/helper.mustache

@@ -0,0 +1,37 @@
+
+function action(url, dataAndCallbackArguments) {
+    var args = [];
+    for (var i = 0; i < (dataAndCallbackArguments.length - 1); i++) {
+        args.push(dataAndCallbackArguments[i]);
+    }
+    var callback = dataAndCallbackArguments[dataAndCallbackArguments.length - 1];
+
+    console.log('send ajax request:');
+    console.log('\turl: http://{{host}}:{{port}}' + url);
+    console.log('\tdata: ' + JSON.stringify(args));
+
+    $.ajax({
+        type: 'post',
+        url: 'http://{{host}}:{{port}}' + url,
+        data: {args: JSON.stringify(args)}
+    }).done(function (data) {
+            if (callback) callback(data);
+        }).fail(function () {
+            console.log("error");
+            if (callback) callback('error');
+        });
+}
+
+var {{RPCClientClassName}} = function(endPointPrefix){
+    this.endPointPrefix = endPointPrefix;
+};
+
+{{#methods}}
+{{RPCClientClassName}}.prototype.{{method_name}} = function(){
+    action(this.endPointPrefix+'/{{method_name}}', arguments);
+};
+{{/methods}}
+
+
+
+

+ 67 - 0
lib/rpc/index.js

@@ -0,0 +1,67 @@
+module.exports = function (express, helperUrl, rpcClientClassName, remoteObj) {
+
+    var Mustache = require('mustache');
+    var fs = require('fs');
+
+    var rpcRouter = express.Router();
+
+    rpcRouter.get('/test', function (req, res) {
+        res.send(200, "test successful...");
+    });
+
+    rpcRouter.get(helperUrl, function (req, res) {
+
+        var port = (process.env.lrs_PORT || '8080');
+
+        var data = {
+            RPCClientClassName: rpcClientClassName,
+            methods: [],
+            port: port,
+            host: req.host
+        };
+
+        for (method in remoteObj) {
+            if (typeof(remoteObj[method]) === 'function') {
+                data.methods.push({method_name: method});
+            }
+        }
+
+        var helperTemplatePath = require('path').resolve(__dirname, 'helper.mustache');
+
+        var jsContent = Mustache.render(fs.readFileSync(helperTemplatePath).toString(), data);
+
+        res.end(jsContent);
+    });
+
+
+    rpcRouter.post('/:method', function (req, res) {
+        var method = req.params.method;
+        var args = JSON.parse(req.body.args);
+        console.log('params:');
+        console.log(req.body.args);
+
+        if (remoteObj.hasOwnProperty(method) && typeof(remoteObj[method]) === 'function') {
+            var fn = remoteObj[method];
+            args.push(function (err, result) {
+                var param = {
+                    err: err,
+                    data: result
+                };
+
+                res.set('Content-Type', 'application/json');
+                var json = JSON.stringify(param);
+                console.log('return:');
+                console.log(json);
+                res.send(200, json);
+            });
+            fn.apply({request: req}, args);
+        } else {
+            res.send(500);
+        }
+
+    });
+
+    return rpcRouter;
+
+
+};

+ 40 - 0
lib/rpc/test/app.js

@@ -0,0 +1,40 @@
+var fs      =   require('fs');
+var path    =   require('path');
+
+var express =   require('express');
+
+var app = express();
+var port = process.env.PORT || 3434;
+
+app.configure(function() {
+    app.use(express.bodyParser());
+    app.use(express.methodOverride());
+    app.use(express.cookieParser());
+    app.use(express.session( {secret : "my !@#!@#! secret"}));
+    app.use(function(err, req, res, next){
+        console.error(err.stack);
+        res.send(500, 'Something broke!');
+    });
+    app.use(express.static('public'));
+
+    var remoteObj = {
+        add: function(a,b, callback){
+            callback(null,1*a+1*b);
+        },
+        multiply: function(a,b, callback){
+            callback(null,1*a*b);
+        }
+    };
+
+    var rpcMiddleware = require('./../rpc-middleware.js');
+    app.use('/rpc', rpcMiddleware('/helper.js', 'APIClient', remoteObj).middleware);
+
+
+});
+
+var server = app.listen(port);
+
+
+
+
+

+ 11 - 0
lib/rpc/test/package.json

@@ -0,0 +1,11 @@
+{
+  "name": "redislite",
+  "description": "Simple RedisLite Key-Value Store + ExpressJS Middleware + Handy jQuery based javascript api to access the Key-Value store from browser.",
+  "version": "0.0.1",
+  "author": "Maheswaran Krishnan",
+  "homepage": "",
+  "dependencies": {
+    "express": "~3.4.0",
+    "mustache": "~0.7.2"
+  }
+}

+ 163 - 0
lib/rpc/test/public/js/angular.min.js

@@ -0,0 +1,163 @@
+/*
+ AngularJS v1.0.7
+ (c) 2010-2012 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(P,T,q){'use strict';function m(b,a,c){var d;if(b)if(H(b))for(d in b)d!="prototype"&&d!="length"&&d!="name"&&b.hasOwnProperty(d)&&a.call(c,b[d],d);else if(b.forEach&&b.forEach!==m)b.forEach(a,c);else if(!b||typeof b.length!=="number"?0:typeof b.hasOwnProperty!="function"&&typeof b.constructor!="function"||b instanceof K||ca&&b instanceof ca||wa.call(b)!=="[object Object]"||typeof b.callee==="function")for(d=0;d<b.length;d++)a.call(c,b[d],d);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],
+d);return b}function mb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function fc(b,a,c){for(var d=mb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function nb(b){return function(a,c){b(c,a)}}function xa(){for(var b=aa.length,a;b;){b--;a=aa[b].charCodeAt(0);if(a==57)return aa[b]="A",aa.join("");if(a==90)aa[b]="0";else return aa[b]=String.fromCharCode(a+1),aa.join("")}aa.unshift("0");return aa.join("")}function ob(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function v(b){var a=
+b.$$hashKey;m(arguments,function(a){a!==b&&m(a,function(a,c){b[c]=a})});ob(b,a);return b}function G(b){return parseInt(b,10)}function ya(b,a){return v(new (v(function(){},{prototype:b})),a)}function C(){}function ma(b){return b}function I(b){return function(){return b}}function w(b){return typeof b=="undefined"}function y(b){return typeof b!="undefined"}function L(b){return b!=null&&typeof b=="object"}function B(b){return typeof b=="string"}function Qa(b){return typeof b=="number"}function na(b){return wa.apply(b)==
+"[object Date]"}function E(b){return wa.apply(b)=="[object Array]"}function H(b){return typeof b=="function"}function oa(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function Q(b){return B(b)?b.replace(/^\s*/,"").replace(/\s*$/,""):b}function gc(b){return b&&(b.nodeName||b.bind&&b.find)}function Ra(b,a,c){var d=[];m(b,function(b,g,h){d.push(a.call(c,b,g,h))});return d}function za(b,a){if(b.indexOf)return b.indexOf(a);for(var c=0;c<b.length;c++)if(a===b[c])return c;return-1}function Sa(b,
+a){var c=za(b,a);c>=0&&b.splice(c,1);return a}function U(b,a){if(oa(b)||b&&b.$evalAsync&&b.$watch)throw Error("Can't copy Window or Scope");if(a){if(b===a)throw Error("Can't copy equivalent objects or arrays");if(E(b))for(var c=a.length=0;c<b.length;c++)a.push(U(b[c]));else{c=a.$$hashKey;m(a,function(b,c){delete a[c]});for(var d in b)a[d]=U(b[d]);ob(a,c)}}else(a=b)&&(E(b)?a=U(b,[]):na(b)?a=new Date(b.getTime()):L(b)&&(a=U(b,{})));return a}function hc(b,a){var a=a||{},c;for(c in b)b.hasOwnProperty(c)&&
+c.substr(0,2)!=="$$"&&(a[c]=b[c]);return a}function fa(b,a){if(b===a)return!0;if(b===null||a===null)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&c=="object")if(E(b)){if((c=b.length)==a.length){for(d=0;d<c;d++)if(!fa(b[d],a[d]))return!1;return!0}}else if(na(b))return na(a)&&b.getTime()==a.getTime();else{if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||oa(b)||oa(a))return!1;c={};for(d in b)if(!(d.charAt(0)==="$"||H(b[d]))){if(!fa(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c[d]&&
+d.charAt(0)!=="$"&&a[d]!==q&&!H(a[d]))return!1;return!0}return!1}function Ta(b,a){var c=arguments.length>2?ha.call(arguments,2):[];return H(a)&&!(a instanceof RegExp)?c.length?function(){return arguments.length?a.apply(b,c.concat(ha.call(arguments,0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}:a}function ic(b,a){var c=a;/^\$+/.test(b)?c=q:oa(a)?c="$WINDOW":a&&T===a?c="$DOCUMENT":a&&a.$evalAsync&&a.$watch&&(c="$SCOPE");return c}function da(b,a){return JSON.stringify(b,
+ic,a?"  ":null)}function pb(b){return B(b)?JSON.parse(b):b}function Ua(b){b&&b.length!==0?(b=z(""+b),b=!(b=="f"||b=="0"||b=="false"||b=="no"||b=="n"||b=="[]")):b=!1;return b}function pa(b){b=u(b).clone();try{b.html("")}catch(a){}var c=u("<div>").append(b).html();try{return b[0].nodeType===3?z(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+z(b)})}catch(d){return z(c)}}function Va(b){var a={},c,d;m((b||"").split("&"),function(b){b&&(c=b.split("="),d=decodeURIComponent(c[0]),
+a[d]=y(c[1])?decodeURIComponent(c[1]):!0)});return a}function qb(b){var a=[];m(b,function(b,d){a.push(Wa(d,!0)+(b===!0?"":"="+Wa(b,!0)))});return a.length?a.join("&"):""}function Xa(b){return Wa(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Wa(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function jc(b,a){function c(a){a&&d.push(a)}var d=[b],e,g,h=["ng:app","ng-app","x-ng-app",
+"data-ng-app"],f=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;m(h,function(a){h[a]=!0;c(T.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(m(b.querySelectorAll("."+a),c),m(b.querySelectorAll("."+a+"\\:"),c),m(b.querySelectorAll("["+a+"]"),c))});m(d,function(a){if(!e){var b=f.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):m(a.attributes,function(b){if(!e&&h[b.name])e=a,g=b.value})}});e&&a(e,g?[g]:[])}function rb(b,a){var c=function(){b=u(b);a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",
+b)}]);a.unshift("ng");var c=sb(a);c.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(P&&!d.test(P.name))return c();P.name=P.name.replace(d,"");Ya.resumeBootstrap=function(b){m(b,function(b){a.push(b)});c()}}function Za(b,a){a=a||"_";return b.replace(kc,function(b,d){return(d?a:"")+b.toLowerCase()})}function $a(b,a,c){if(!b)throw Error("Argument '"+(a||"?")+"' is "+(c||"required"));
+return b}function qa(b,a,c){c&&E(b)&&(b=b[b.length-1]);$a(H(b),a,"not a function, got "+(b&&typeof b=="object"?b.constructor.name||"Object":typeof b));return b}function lc(b){function a(a,b,e){return a[b]||(a[b]=e())}return a(a(b,"angular",Object),"module",function(){var b={};return function(d,e,g){e&&b.hasOwnProperty(d)&&(b[d]=null);return a(b,d,function(){function a(c,d,e){return function(){b[e||"push"]([c,d,arguments]);return k}}if(!e)throw Error("No module: "+d);var b=[],c=[],j=a("$injector",
+"invoke"),k={_invokeQueue:b,_runBlocks:c,requires:e,name:d,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),filter:a("$filterProvider","register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:j,run:function(a){c.push(a);return this}};g&&j(g);return k})}})}function tb(b){return b.replace(mc,function(a,b,d,e){return e?d.toUpperCase():
+d}).replace(nc,"Moz$1")}function ab(b,a){function c(){var e;for(var b=[this],c=a,h,f,i,j,k,l;b.length;){h=b.shift();f=0;for(i=h.length;f<i;f++){j=u(h[f]);c?j.triggerHandler("$destroy"):c=!c;k=0;for(e=(l=j.children()).length,j=e;k<j;k++)b.push(ca(l[k]))}}return d.apply(this,arguments)}var d=ca.fn[b],d=d.$original||d;c.$original=d;ca.fn[b]=c}function K(b){if(b instanceof K)return b;if(!(this instanceof K)){if(B(b)&&b.charAt(0)!="<")throw Error("selectors not implemented");return new K(b)}if(B(b)){var a=
+T.createElement("div");a.innerHTML="<div>&#160;</div>"+b;a.removeChild(a.firstChild);bb(this,a.childNodes);this.remove()}else bb(this,b)}function cb(b){return b.cloneNode(!0)}function ra(b){ub(b);for(var a=0,b=b.childNodes||[];a<b.length;a++)ra(b[a])}function vb(b,a,c){var d=ba(b,"events");ba(b,"handle")&&(w(a)?m(d,function(a,c){db(b,c,a);delete d[c]}):w(c)?(db(b,a,d[a]),delete d[a]):Sa(d[a],c))}function ub(b){var a=b[Aa],c=Ba[a];c&&(c.handle&&(c.events.$destroy&&c.handle({},"$destroy"),vb(b)),delete Ba[a],
+b[Aa]=q)}function ba(b,a,c){var d=b[Aa],d=Ba[d||-1];if(y(c))d||(b[Aa]=d=++oc,d=Ba[d]={}),d[a]=c;else return d&&d[a]}function wb(b,a,c){var d=ba(b,"data"),e=y(c),g=!e&&y(a),h=g&&!L(a);!d&&!h&&ba(b,"data",d={});if(e)d[a]=c;else if(g)if(h)return d&&d[a];else v(d,a);else return d}function Ca(b,a){return(" "+b.className+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" ")>-1}function xb(b,a){a&&m(a.split(" "),function(a){b.className=Q((" "+b.className+" ").replace(/[\n\t]/g," ").replace(" "+Q(a)+" "," "))})}
+function yb(b,a){a&&m(a.split(" "),function(a){if(!Ca(b,a))b.className=Q(b.className+" "+Q(a))})}function bb(b,a){if(a)for(var a=!a.nodeName&&y(a.length)&&!oa(a)?a:[a],c=0;c<a.length;c++)b.push(a[c])}function zb(b,a){return Da(b,"$"+(a||"ngController")+"Controller")}function Da(b,a,c){b=u(b);for(b[0].nodeType==9&&(b=b.find("html"));b.length;){if(c=b.data(a))return c;b=b.parent()}}function Ab(b,a){var c=Ea[a.toLowerCase()];return c&&Bb[b.nodeName]&&c}function pc(b,a){var c=function(c,e){if(!c.preventDefault)c.preventDefault=
+function(){c.returnValue=!1};if(!c.stopPropagation)c.stopPropagation=function(){c.cancelBubble=!0};if(!c.target)c.target=c.srcElement||T;if(w(c.defaultPrevented)){var g=c.preventDefault;c.preventDefault=function(){c.defaultPrevented=!0;g.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=function(){return c.defaultPrevented};m(a[e||c.type],function(a){a.call(b,c)});Z<=8?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};
+c.elem=b;return c}function ga(b){var a=typeof b,c;if(a=="object"&&b!==null)if(typeof(c=b.$$hashKey)=="function")c=b.$$hashKey();else{if(c===q)c=b.$$hashKey=xa()}else c=b;return a+":"+c}function Fa(b){m(b,this.put,this)}function eb(){}function Cb(b){var a,c;if(typeof b=="function"){if(!(a=b.$inject))a=[],c=b.toString().replace(qc,""),c=c.match(rc),m(c[1].split(sc),function(b){b.replace(tc,function(b,c,d){a.push(d)})}),b.$inject=a}else E(b)?(c=b.length-1,qa(b[c],"fn"),a=b.slice(0,c)):qa(b,"fn",!0);
+return a}function sb(b){function a(a){return function(b,c){if(L(b))m(b,nb(a));else return a(b,c)}}function c(a,b){if(H(b)||E(b))b=l.instantiate(b);if(!b.$get)throw Error("Provider "+a+" must define $get factory method.");return k[a+f]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[];m(a,function(a){if(!j.get(a))if(j.put(a,!0),B(a)){var c=sa(a);b=b.concat(e(c.requires)).concat(c._runBlocks);try{for(var d=c._invokeQueue,c=0,f=d.length;c<f;c++){var g=d[c],h=g[0]=="$injector"?l:l.get(g[0]);
+h[g[1]].apply(h,g[2])}}catch(p){throw p.message&&(p.message+=" from "+a),p;}}else if(H(a))try{b.push(l.invoke(a))}catch(i){throw i.message&&(i.message+=" from "+a),i;}else if(E(a))try{b.push(l.invoke(a))}catch(o){throw o.message&&(o.message+=" from "+String(a[a.length-1])),o;}else qa(a,"module")});return b}function g(a,b){function c(d){if(typeof d!=="string")throw Error("Service name expected");if(a.hasOwnProperty(d)){if(a[d]===h)throw Error("Circular dependency: "+i.join(" <- "));return a[d]}else try{return i.unshift(d),
+a[d]=h,a[d]=b(d)}finally{i.shift()}}function d(a,b,e){var f=[],j=Cb(a),g,h,i;h=0;for(g=j.length;h<g;h++)i=j[h],f.push(e&&e.hasOwnProperty(i)?e[i]:c(i));a.$inject||(a=a[g]);switch(b?-1:f.length){case 0:return a();case 1:return a(f[0]);case 2:return a(f[0],f[1]);case 3:return a(f[0],f[1],f[2]);case 4:return a(f[0],f[1],f[2],f[3]);case 5:return a(f[0],f[1],f[2],f[3],f[4]);case 6:return a(f[0],f[1],f[2],f[3],f[4],f[5]);case 7:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6]);case 8:return a(f[0],f[1],f[2],
+f[3],f[4],f[5],f[6],f[7]);case 9:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8]);case 10:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9]);default:return a.apply(b,f)}}return{invoke:d,instantiate:function(a,b){var c=function(){},e;c.prototype=(E(a)?a[a.length-1]:a).prototype;c=new c;e=d(a,c,b);return L(e)?e:c},get:c,annotate:Cb}}var h={},f="Provider",i=[],j=new Fa,k={$provide:{provider:a(c),factory:a(d),service:a(function(a,b){return d(a,["$injector",function(a){return a.instantiate(b)}])}),
+value:a(function(a,b){return d(a,I(b))}),constant:a(function(a,b){k[a]=b;n[a]=b}),decorator:function(a,b){var c=l.get(a+f),d=c.$get;c.$get=function(){var a=o.invoke(d,c);return o.invoke(b,null,{$delegate:a})}}}},l=g(k,function(){throw Error("Unknown provider: "+i.join(" <- "));}),n={},o=n.$injector=g(n,function(a){a=l.get(a+f);return o.invoke(a.$get,a)});m(e(b),function(a){o.invoke(a||C)});return o}function uc(){var b=!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location",
+"$rootScope",function(a,c,d){function e(a){var b=null;m(a,function(a){!b&&z(a.nodeName)==="a"&&(b=a)});return b}function g(){var b=c.hash(),d;b?(d=h.getElementById(b))?d.scrollIntoView():(d=e(h.getElementsByName(b)))?d.scrollIntoView():b==="top"&&a.scrollTo(0,0):a.scrollTo(0,0)}var h=a.document;b&&d.$watch(function(){return c.hash()},function(){d.$evalAsync(g)});return g}]}function vc(b,a,c,d){function e(a){try{a.apply(null,ha.call(arguments,1))}finally{if(p--,p===0)for(;s.length;)try{s.pop()()}catch(b){c.error(b)}}}
+function g(a,b){(function V(){m(t,function(a){a()});x=b(V,a)})()}function h(){M!=f.url()&&(M=f.url(),m(N,function(a){a(f.url())}))}var f=this,i=a[0],j=b.location,k=b.history,l=b.setTimeout,n=b.clearTimeout,o={};f.isMock=!1;var p=0,s=[];f.$$completeOutstandingRequest=e;f.$$incOutstandingRequestCount=function(){p++};f.notifyWhenNoOutstandingRequests=function(a){m(t,function(a){a()});p===0?a():s.push(a)};var t=[],x;f.addPollFn=function(a){w(x)&&g(100,l);t.push(a);return a};var M=j.href,A=a.find("base");
+f.url=function(a,b){if(a){if(M!=a)return M=a,d.history?b?k.replaceState(null,"",a):(k.pushState(null,"",a),A.attr("href",A.attr("href"))):b?j.replace(a):j.href=a,f}else return j.href.replace(/%27/g,"'")};var N=[],J=!1;f.onUrlChange=function(a){J||(d.history&&u(b).bind("popstate",h),d.hashchange?u(b).bind("hashchange",h):f.addPollFn(h),J=!0);N.push(a);return a};f.baseHref=function(){var a=A.attr("href");return a?a.replace(/^https?\:\/\/[^\/]*/,""):""};var r={},$="",R=f.baseHref();f.cookies=function(a,
+b){var d,e,f,j;if(a)if(b===q)i.cookie=escape(a)+"=;path="+R+";expires=Thu, 01 Jan 1970 00:00:00 GMT";else{if(B(b))d=(i.cookie=escape(a)+"="+escape(b)+";path="+R).length+1,d>4096&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!")}else{if(i.cookie!==$){$=i.cookie;d=$.split("; ");r={};for(f=0;f<d.length;f++)e=d[f],j=e.indexOf("="),j>0&&(a=unescape(e.substring(0,j)),r[a]===q&&(r[a]=unescape(e.substring(j+1))))}return r}};f.defer=function(a,b){var c;
+p++;c=l(function(){delete o[c];e(a)},b||0);o[c]=!0;return c};f.defer.cancel=function(a){return o[a]?(delete o[a],n(a),e(C),!0):!1}}function wc(){this.$get=["$window","$log","$sniffer","$document",function(b,a,c,d){return new vc(b,d,a,c)}]}function xc(){this.$get=function(){function b(b,d){function e(a){if(a!=l){if(n){if(n==a)n=a.n}else n=a;g(a.n,a.p);g(a,l);l=a;l.n=null}}function g(a,b){if(a!=b){if(a)a.p=b;if(b)b.n=a}}if(b in a)throw Error("cacheId "+b+" taken");var h=0,f=v({},d,{id:b}),i={},j=d&&
+d.capacity||Number.MAX_VALUE,k={},l=null,n=null;return a[b]={put:function(a,b){var c=k[a]||(k[a]={key:a});e(c);w(b)||(a in i||h++,i[a]=b,h>j&&this.remove(n.key))},get:function(a){var b=k[a];if(b)return e(b),i[a]},remove:function(a){var b=k[a];if(b){if(b==l)l=b.p;if(b==n)n=b.n;g(b.n,b.p);delete k[a];delete i[a];h--}},removeAll:function(){i={};h=0;k={};l=n=null},destroy:function(){k=f=i=null;delete a[b]},info:function(){return v({},f,{size:h})}}}var a={};b.info=function(){var b={};m(a,function(a,e){b[e]=
+a.info()});return b};b.get=function(b){return a[b]};return b}}function yc(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function Db(b){var a={},c="Directive",d=/^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,e=/(([\d\w\-_]+)(?:\:([^;]+))?;?)/,g="Template must have exactly one root element. was: ",h=/^\s*(https?|ftp|mailto|file):/;this.directive=function i(d,e){B(d)?($a(e,"directive"),a.hasOwnProperty(d)||(a[d]=[],b.factory(d+c,["$injector","$exceptionHandler",function(b,c){var e=[];m(a[d],
+function(a){try{var g=b.invoke(a);if(H(g))g={compile:I(g)};else if(!g.compile&&g.link)g.compile=I(g.link);g.priority=g.priority||0;g.name=g.name||d;g.require=g.require||g.controller&&g.name;g.restrict=g.restrict||"A";e.push(g)}catch(h){c(h)}});return e}])),a[d].push(e)):m(d,nb(i));return this};this.urlSanitizationWhitelist=function(a){return y(a)?(h=a,this):h};this.$get=["$injector","$interpolate","$exceptionHandler","$http","$templateCache","$parse","$controller","$rootScope","$document",function(b,
+j,k,l,n,o,p,s,t){function x(a,b,c){a instanceof u||(a=u(a));m(a,function(b,c){b.nodeType==3&&b.nodeValue.match(/\S+/)&&(a[c]=u(b).wrap("<span></span>").parent()[0])});var d=A(a,b,a,c);return function(b,c){$a(b,"scope");for(var e=c?ua.clone.call(a):a,j=0,g=e.length;j<g;j++){var h=e[j];(h.nodeType==1||h.nodeType==9)&&e.eq(j).data("$scope",b)}M(e,"ng-scope");c&&c(e,b);d&&d(b,e,e);return e}}function M(a,b){try{a.addClass(b)}catch(c){}}function A(a,b,c,d){function e(a,c,d,g){var h,i,k,p,o,l,n,t=[];o=0;
+for(l=c.length;o<l;o++)t.push(c[o]);n=o=0;for(l=j.length;o<l;n++)i=t[n],c=j[o++],h=j[o++],c?(c.scope?(k=a.$new(L(c.scope)),u(i).data("$scope",k)):k=a,(p=c.transclude)||!g&&b?c(h,k,i,d,function(b){return function(c){var d=a.$new();d.$$transcluded=!0;return b(d,c).bind("$destroy",Ta(d,d.$destroy))}}(p||b)):c(h,k,i,q,g)):h&&h(a,i.childNodes,q,g)}for(var j=[],g,h,i,k=0;k<a.length;k++)h=new ia,g=N(a[k],[],h,d),h=(g=g.length?J(g,a[k],h,b,c):null)&&g.terminal||!a[k].childNodes||!a[k].childNodes.length?null:
+A(a[k].childNodes,g?g.transclude:b),j.push(g),j.push(h),i=i||g||h;return i?e:null}function N(a,b,c,g){var j=c.$attr,h;switch(a.nodeType){case 1:r(b,ea(fb(a).toLowerCase()),"E",g);var i,k,o;h=a.attributes;for(var p=0,l=h&&h.length;p<l;p++)if(i=h[p],i.specified)k=i.name,o=ea(k.toLowerCase()),j[o]=k,c[o]=i=Q(Z&&k=="href"?decodeURIComponent(a.getAttribute(k,2)):i.value),Ab(a,o)&&(c[o]=!0),V(a,b,i,o),r(b,o,"A",g);a=a.className;if(B(a)&&a!=="")for(;h=e.exec(a);)o=ea(h[2]),r(b,o,"C",g)&&(c[o]=Q(h[3])),a=
+a.substr(h.index+h[0].length);break;case 3:y(b,a.nodeValue);break;case 8:try{if(h=d.exec(a.nodeValue))o=ea(h[1]),r(b,o,"M",g)&&(c[o]=Q(h[2]))}catch(n){}}b.sort(F);return b}function J(a,b,c,d,e){function j(a,b){if(a)a.require=r.require,n.push(a);if(b)b.require=r.require,t.push(b)}function h(a,b){var c,d="data",e=!1;if(B(a)){for(;(c=a.charAt(0))=="^"||c=="?";)a=a.substr(1),c=="^"&&(d="inheritedData"),e=e||c=="?";c=b[d]("$"+a+"Controller");if(!c&&!e)throw Error("No controller: "+a);}else E(a)&&(c=[],
+m(a,function(a){c.push(h(a,b))}));return c}function i(a,d,e,g,j){var l,s,r,D,M;l=b===e?c:hc(c,new ia(u(e),c.$attr));s=l.$$element;if(J){var zc=/^\s*([@=&])\s*(\w*)\s*$/,x=d.$parent||d;m(J.scope,function(a,b){var c=a.match(zc)||[],e=c[2]||b,c=c[1],g,j,h;d.$$isolateBindings[b]=c+e;switch(c){case "@":l.$observe(e,function(a){d[b]=a});l.$$observers[e].$$scope=x;break;case "=":j=o(l[e]);h=j.assign||function(){g=d[b]=j(x);throw Error(Eb+l[e]+" (directive: "+J.name+")");};g=d[b]=j(x);d.$watch(function(){var a=
+j(x);a!==d[b]&&(a!==g?g=d[b]=a:h(x,a=g=d[b]));return a});break;case "&":j=o(l[e]);d[b]=function(a){return j(x,a)};break;default:throw Error("Invalid isolate scope definition for directive "+J.name+": "+a);}})}y&&m(y,function(a){var b={$scope:d,$element:s,$attrs:l,$transclude:j};M=a.controller;M=="@"&&(M=l[a.name]);s.data("$"+a.name+"Controller",p(M,b))});g=0;for(r=n.length;g<r;g++)try{D=n[g],D(d,s,l,D.require&&h(D.require,s))}catch(A){k(A,pa(s))}a&&a(d,e.childNodes,q,j);g=0;for(r=t.length;g<r;g++)try{D=
+t[g],D(d,s,l,D.require&&h(D.require,s))}catch(Ac){k(Ac,pa(s))}}for(var l=-Number.MAX_VALUE,n=[],t=[],s=null,J=null,A=null,D=c.$$element=u(b),r,F,W,ja,V=d,y,w,Y,v=0,z=a.length;v<z;v++){r=a[v];W=q;if(l>r.priority)break;if(Y=r.scope)ta("isolated scope",J,r,D),L(Y)&&(M(D,"ng-isolate-scope"),J=r),M(D,"ng-scope"),s=s||r;F=r.name;if(Y=r.controller)y=y||{},ta("'"+F+"' controller",y[F],r,D),y[F]=r;if(Y=r.transclude)ta("transclusion",ja,r,D),ja=r,l=r.priority,Y=="element"?(W=u(b),D=c.$$element=u(T.createComment(" "+
+F+": "+c[F]+" ")),b=D[0],C(e,u(W[0]),b),V=x(W,d,l)):(W=u(cb(b)).contents(),D.html(""),V=x(W,d));if(Y=r.template)if(ta("template",A,r,D),A=r,Y=Fb(Y),r.replace){W=u("<div>"+Q(Y)+"</div>").contents();b=W[0];if(W.length!=1||b.nodeType!==1)throw Error(g+Y);C(e,D,b);F={$attr:{}};a=a.concat(N(b,a.splice(v+1,a.length-(v+1)),F));$(c,F);z=a.length}else D.html(Y);if(r.templateUrl)ta("template",A,r,D),A=r,i=R(a.splice(v,a.length-v),i,D,c,e,r.replace,V),z=a.length;else if(r.compile)try{w=r.compile(D,c,V),H(w)?
+j(null,w):w&&j(w.pre,w.post)}catch(G){k(G,pa(D))}if(r.terminal)i.terminal=!0,l=Math.max(l,r.priority)}i.scope=s&&s.scope;i.transclude=ja&&V;return i}function r(d,e,g,j){var h=!1;if(a.hasOwnProperty(e))for(var o,e=b.get(e+c),l=0,p=e.length;l<p;l++)try{if(o=e[l],(j===q||j>o.priority)&&o.restrict.indexOf(g)!=-1)d.push(o),h=!0}catch(n){k(n)}return h}function $(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;m(a,function(d,e){e.charAt(0)!="$"&&(b[e]&&(d+=(e==="style"?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});m(b,
+function(b,g){g=="class"?(M(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):g=="style"?e.attr("style",e.attr("style")+";"+b):g.charAt(0)!="$"&&!a.hasOwnProperty(g)&&(a[g]=b,d[g]=c[g])})}function R(a,b,c,d,e,j,h){var i=[],k,o,p=c[0],t=a.shift(),s=v({},t,{controller:null,templateUrl:null,transclude:null,scope:null});c.html("");l.get(t.templateUrl,{cache:n}).success(function(l){var n,t,l=Fb(l);if(j){t=u("<div>"+Q(l)+"</div>").contents();n=t[0];if(t.length!=1||n.nodeType!==1)throw Error(g+l);l={$attr:{}};
+C(e,c,n);N(n,a,l);$(d,l)}else n=p,c.html(l);a.unshift(s);k=J(a,n,d,h);for(o=A(c[0].childNodes,h);i.length;){var r=i.pop(),l=i.pop();t=i.pop();var ia=i.pop(),D=n;t!==p&&(D=cb(n),C(l,u(t),D));k(function(){b(o,ia,D,e,r)},ia,D,e,r)}i=null}).error(function(a,b,c,d){throw Error("Failed to load template: "+d.url);});return function(a,c,d,e,g){i?(i.push(c),i.push(d),i.push(e),i.push(g)):k(function(){b(o,c,d,e,g)},c,d,e,g)}}function F(a,b){return b.priority-a.priority}function ta(a,b,c,d){if(b)throw Error("Multiple directives ["+
+b.name+", "+c.name+"] asking for "+a+" on: "+pa(d));}function y(a,b){var c=j(b,!0);c&&a.push({priority:0,compile:I(function(a,b){var d=b.parent(),e=d.data("$binding")||[];e.push(c);M(d.data("$binding",e),"ng-binding");a.$watch(c,function(a){b[0].nodeValue=a})})})}function V(a,b,c,d){var e=j(c,!0);e&&b.push({priority:100,compile:I(function(a,b,c){b=c.$$observers||(c.$$observers={});d==="class"&&(e=j(c[d],!0));c[d]=q;(b[d]||(b[d]=[])).$$inter=!0;(c.$$observers&&c.$$observers[d].$$scope||a).$watch(e,
+function(a){c.$set(d,a)})})})}function C(a,b,c){var d=b[0],e=d.parentNode,g,j;if(a){g=0;for(j=a.length;g<j;g++)if(a[g]==d){a[g]=c;break}}e&&e.replaceChild(c,d);c[u.expando]=d[u.expando];b[0]=c}var ia=function(a,b){this.$$element=a;this.$attr=b||{}};ia.prototype={$normalize:ea,$set:function(a,b,c,d){var e=Ab(this.$$element[0],a),g=this.$$observers;e&&(this.$$element.prop(a,b),d=e);this[a]=b;d?this.$attr[a]=d:(d=this.$attr[a])||(this.$attr[a]=d=Za(a,"-"));if(fb(this.$$element[0])==="A"&&a==="href")D.setAttribute("href",
+b),e=D.href,e.match(h)||(this[a]=b="unsafe:"+e);c!==!1&&(b===null||b===q?this.$$element.removeAttr(d):this.$$element.attr(d,b));g&&m(g[a],function(a){try{a(b)}catch(c){k(c)}})},$observe:function(a,b){var c=this,d=c.$$observers||(c.$$observers={}),e=d[a]||(d[a]=[]);e.push(b);s.$evalAsync(function(){e.$$inter||b(c[a])});return b}};var D=t[0].createElement("a"),W=j.startSymbol(),ja=j.endSymbol(),Fb=W=="{{"||ja=="}}"?ma:function(a){return a.replace(/\{\{/g,W).replace(/}}/g,ja)};return x}]}function ea(b){return tb(b.replace(Bc,
+""))}function Cc(){var b={};this.register=function(a,c){L(a)?v(b,a):b[a]=c};this.$get=["$injector","$window",function(a,c){return function(d,e){if(B(d)){var g=d,d=b.hasOwnProperty(g)?b[g]:gb(e.$scope,g,!0)||gb(c,g,!0);qa(d,g,!0)}return a.instantiate(d,e)}}]}function Dc(){this.$get=["$window",function(b){return u(b.document)}]}function Ec(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function Fc(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):
+b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse",function(c){function d(d,f){for(var i,j,k=0,l=[],n=d.length,o=!1,p=[];k<n;)(i=d.indexOf(b,k))!=-1&&(j=d.indexOf(a,i+e))!=-1?(k!=i&&l.push(d.substring(k,i)),l.push(k=c(o=d.substring(i+e,j))),k.exp=o,k=j+g,o=!0):(k!=n&&l.push(d.substring(k)),k=n);if(!(n=l.length))l.push(""),n=1;if(!f||o)return p.length=n,k=function(a){for(var b=0,c=n,d;b<c;b++){if(typeof(d=l[b])=="function")d=d(a),d==null||d==q?d="":typeof d!="string"&&(d=da(d));
+p[b]=d}return p.join("")},k.exp=d,k.parts=l,k}var e=b.length,g=a.length;d.startSymbol=function(){return b};d.endSymbol=function(){return a};return d}]}function Gb(b){for(var b=b.split("/"),a=b.length;a--;)b[a]=Xa(b[a]);return b.join("/")}function va(b,a){var c=Hb.exec(b),c={protocol:c[1],host:c[3],port:G(c[5])||Ib[c[1]]||null,path:c[6]||"/",search:c[8],hash:c[10]};if(a)a.$$protocol=c.protocol,a.$$host=c.host,a.$$port=c.port;return c}function ka(b,a,c){return b+"://"+a+(c==Ib[b]?"":":"+c)}function Gc(b,
+a,c){var d=va(b);return decodeURIComponent(d.path)!=a||w(d.hash)||d.hash.indexOf(c)!==0?b:ka(d.protocol,d.host,d.port)+a.substr(0,a.lastIndexOf("/"))+d.hash.substr(c.length)}function Hc(b,a,c){var d=va(b);if(decodeURIComponent(d.path)==a&&!w(d.hash)&&d.hash.indexOf(c)===0)return b;else{var e=d.search&&"?"+d.search||"",g=d.hash&&"#"+d.hash||"",h=a.substr(0,a.lastIndexOf("/")),f=d.path.substr(h.length);if(d.path.indexOf(h)!==0)throw Error('Invalid url "'+b+'", missing path prefix "'+h+'" !');return ka(d.protocol,
+d.host,d.port)+a+"#"+c+f+e+g}}function hb(b,a,c){a=a||"";this.$$parse=function(b){var c=va(b,this);if(c.path.indexOf(a)!==0)throw Error('Invalid url "'+b+'", missing path prefix "'+a+'" !');this.$$path=decodeURIComponent(c.path.substr(a.length));this.$$search=Va(c.search);this.$$hash=c.hash&&decodeURIComponent(c.hash)||"";this.$$compose()};this.$$compose=function(){var b=qb(this.$$search),c=this.$$hash?"#"+Xa(this.$$hash):"";this.$$url=Gb(this.$$path)+(b?"?"+b:"")+c;this.$$absUrl=ka(this.$$protocol,
+this.$$host,this.$$port)+a+this.$$url};this.$$rewriteAppUrl=function(a){if(a.indexOf(c)==0)return a};this.$$parse(b)}function Ga(b,a,c){var d;this.$$parse=function(b){var c=va(b,this);if(c.hash&&c.hash.indexOf(a)!==0)throw Error('Invalid url "'+b+'", missing hash prefix "'+a+'" !');d=c.path+(c.search?"?"+c.search:"");c=Ic.exec((c.hash||"").substr(a.length));this.$$path=c[1]?(c[1].charAt(0)=="/"?"":"/")+decodeURIComponent(c[1]):"";this.$$search=Va(c[3]);this.$$hash=c[5]&&decodeURIComponent(c[5])||
+"";this.$$compose()};this.$$compose=function(){var b=qb(this.$$search),c=this.$$hash?"#"+Xa(this.$$hash):"";this.$$url=Gb(this.$$path)+(b?"?"+b:"")+c;this.$$absUrl=ka(this.$$protocol,this.$$host,this.$$port)+d+(this.$$url?"#"+a+this.$$url:"")};this.$$rewriteAppUrl=function(a){if(a.indexOf(c)==0)return a};this.$$parse(b)}function Jb(b,a,c,d){Ga.apply(this,arguments);this.$$rewriteAppUrl=function(b){if(b.indexOf(c)==0)return c+d+"#"+a+b.substr(c.length)}}function Ha(b){return function(){return this[b]}}
+function Kb(b,a){return function(c){if(w(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Jc(){var b="",a=!1;this.hashPrefix=function(a){return y(a)?(b=a,this):b};this.html5Mode=function(b){return y(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,g){function h(a){c.$broadcast("$locationChangeSuccess",f.absUrl(),a)}var f,i,j,k=d.url(),l=va(k);a?(i=d.baseHref()||"/",j=i.substr(0,i.lastIndexOf("/")),l=ka(l.protocol,l.host,l.port)+j+"/",
+f=e.history?new hb(Gc(k,i,b),j,l):new Jb(Hc(k,i,b),b,l,i.substr(j.length+1))):(l=ka(l.protocol,l.host,l.port)+(l.path||"")+(l.search?"?"+l.search:"")+"#"+b+"/",f=new Ga(k,b,l));g.bind("click",function(a){if(!a.ctrlKey&&!(a.metaKey||a.which==2)){for(var b=u(a.target);z(b[0].nodeName)!=="a";)if(b[0]===g[0]||!(b=b.parent())[0])return;var d=b.prop("href"),e=f.$$rewriteAppUrl(d);d&&!b.attr("target")&&e&&(f.$$parse(e),c.$apply(),a.preventDefault(),P.angular["ff-684208-preventDefault"]=!0)}});f.absUrl()!=
+k&&d.url(f.absUrl(),!0);d.onUrlChange(function(a){f.absUrl()!=a&&(c.$broadcast("$locationChangeStart",a,f.absUrl()).defaultPrevented?d.url(f.absUrl()):(c.$evalAsync(function(){var b=f.absUrl();f.$$parse(a);h(b)}),c.$$phase||c.$digest()))});var n=0;c.$watch(function(){var a=d.url(),b=f.$$replace;if(!n||a!=f.absUrl())n++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",f.absUrl(),a).defaultPrevented?f.$$parse(a):(d.url(f.absUrl(),b),h(a))});f.$$replace=!1;return n});return f}]}function Kc(){this.$get=
+["$window",function(b){function a(a){a instanceof Error&&(a.stack?a=a.message&&a.stack.indexOf(a.message)===-1?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function c(c){var e=b.console||{},g=e[c]||e.log||C;return g.apply?function(){var b=[];m(arguments,function(c){b.push(a(c))});return g.apply(e,b)}:function(a,b){g(a,b)}}return{log:c("log"),warn:c("warn"),info:c("info"),error:c("error")}}]}function Lc(b,a){function c(a){return a.indexOf(t)!=
+-1}function d(){return p+1<b.length?b.charAt(p+1):!1}function e(a){return"0"<=a&&a<="9"}function g(a){return a==" "||a=="\r"||a=="\t"||a=="\n"||a=="\u000b"||a=="\u00a0"}function h(a){return"a"<=a&&a<="z"||"A"<=a&&a<="Z"||"_"==a||a=="$"}function f(a){return a=="-"||a=="+"||e(a)}function i(a,c,d){d=d||p;throw Error("Lexer Error: "+a+" at column"+(y(c)?"s "+c+"-"+p+" ["+b.substring(c,d)+"]":" "+d)+" in expression ["+b+"].");}function j(){for(var a="",c=p;p<b.length;){var g=z(b.charAt(p));if(g=="."||
+e(g))a+=g;else{var j=d();if(g=="e"&&f(j))a+=g;else if(f(g)&&j&&e(j)&&a.charAt(a.length-1)=="e")a+=g;else if(f(g)&&(!j||!e(j))&&a.charAt(a.length-1)=="e")i("Invalid exponent");else break}p++}a*=1;n.push({index:c,text:a,json:!0,fn:function(){return a}})}function k(){for(var c="",d=p,f,j,i,k;p<b.length;){k=b.charAt(p);if(k=="."||h(k)||e(k))k=="."&&(f=p),c+=k;else break;p++}if(f)for(j=p;j<b.length;){k=b.charAt(j);if(k=="("){i=c.substr(f-d+1);c=c.substr(0,f-d);p=j;break}if(g(k))j++;else break}d={index:d,
+text:c};if(Ia.hasOwnProperty(c))d.fn=d.json=Ia[c];else{var l=Lb(c,a);d.fn=v(function(a,b){return l(a,b)},{assign:function(a,b){return Mb(a,c,b)}})}n.push(d);i&&(n.push({index:f,text:".",json:!1}),n.push({index:f+1,text:i,json:!1}))}function l(a){var c=p;p++;for(var d="",e=a,f=!1;p<b.length;){var g=b.charAt(p);e+=g;if(f)g=="u"?(g=b.substring(p+1,p+5),g.match(/[\da-f]{4}/i)||i("Invalid unicode escape [\\u"+g+"]"),p+=4,d+=String.fromCharCode(parseInt(g,16))):(f=Mc[g],d+=f?f:g),f=!1;else if(g=="\\")f=
+!0;else if(g==a){p++;n.push({index:c,text:e,string:d,json:!0,fn:function(){return d}});return}else d+=g;p++}i("Unterminated quote",c)}for(var n=[],o,p=0,s=[],t,x=":";p<b.length;){t=b.charAt(p);if(c("\"'"))l(t);else if(e(t)||c(".")&&e(d()))j();else if(h(t)){if(k(),"{,".indexOf(x)!=-1&&s[0]=="{"&&(o=n[n.length-1]))o.json=o.text.indexOf(".")==-1}else if(c("(){}[].,;:"))n.push({index:p,text:t,json:":[,".indexOf(x)!=-1&&c("{[")||c("}]:,")}),c("{[")&&s.unshift(t),c("}]")&&s.shift(),p++;else if(g(t)){p++;
+continue}else{var m=t+d(),A=Ia[t],N=Ia[m];N?(n.push({index:p,text:m,fn:N}),p+=2):A?(n.push({index:p,text:t,fn:A,json:"[,:".indexOf(x)!=-1&&c("+-")}),p+=1):i("Unexpected next character ",p,p+1)}x=t}return n}function Nc(b,a,c,d){function e(a,c){throw Error("Syntax Error: Token '"+c.text+"' "+a+" at column "+(c.index+1)+" of the expression ["+b+"] starting at ["+b.substring(c.index)+"].");}function g(){if(R.length===0)throw Error("Unexpected end of expression: "+b);return R[0]}function h(a,b,c,d){if(R.length>
+0){var e=R[0],f=e.text;if(f==a||f==b||f==c||f==d||!a&&!b&&!c&&!d)return e}return!1}function f(b,c,d,f){return(b=h(b,c,d,f))?(a&&!b.json&&e("is not valid json",b),R.shift(),b):!1}function i(a){f(a)||e("is unexpected, expecting ["+a+"]",h())}function j(a,b){return function(c,d){return a(c,d,b)}}function k(a,b,c){return function(d,e){return b(d,e,a,c)}}function l(){for(var a=[];;)if(R.length>0&&!h("}",")",";","]")&&a.push(w()),!f(";"))return a.length==1?a[0]:function(b,c){for(var d,e=0;e<a.length;e++){var f=
+a[e];f&&(d=f(b,c))}return d}}function n(){for(var a=f(),b=c(a.text),d=[];;)if(a=f(":"))d.push(F());else{var e=function(a,c,e){for(var e=[e],f=0;f<d.length;f++)e.push(d[f](a,c));return b.apply(a,e)};return function(){return e}}}function o(){for(var a=p(),b;;)if(b=f("||"))a=k(a,b.fn,p());else return a}function p(){var a=s(),b;if(b=f("&&"))a=k(a,b.fn,p());return a}function s(){var a=t(),b;if(b=f("==","!="))a=k(a,b.fn,s());return a}function t(){var a;a=x();for(var b;b=f("+","-");)a=k(a,b.fn,x());if(b=
+f("<",">","<=",">="))a=k(a,b.fn,t());return a}function x(){for(var a=m(),b;b=f("*","/","%");)a=k(a,b.fn,m());return a}function m(){var a;return f("+")?A():(a=f("-"))?k(r,a.fn,m()):(a=f("!"))?j(a.fn,m()):A()}function A(){var a;if(f("("))a=w(),i(")");else if(f("["))a=N();else if(f("{"))a=J();else{var b=f();(a=b.fn)||e("not a primary expression",b)}for(var c;b=f("(","[",".");)b.text==="("?(a=y(a,c),c=null):b.text==="["?(c=a,a=V(a)):b.text==="."?(c=a,a=u(a)):e("IMPOSSIBLE");return a}function N(){var a=
+[];if(g().text!="]"){do a.push(F());while(f(","))}i("]");return function(b,c){for(var d=[],e=0;e<a.length;e++)d.push(a[e](b,c));return d}}function J(){var a=[];if(g().text!="}"){do{var b=f(),b=b.string||b.text;i(":");var c=F();a.push({key:b,value:c})}while(f(","))}i("}");return function(b,c){for(var d={},e=0;e<a.length;e++){var f=a[e];d[f.key]=f.value(b,c)}return d}}var r=I(0),$,R=Lc(b,d),F=function(){var a=o(),c,d;return(d=f("="))?(a.assign||e("implies assignment but ["+b.substring(0,d.index)+"] can not be assigned to",
+d),c=o(),function(b,d){return a.assign(b,c(b,d),d)}):a},y=function(a,b){var c=[];if(g().text!=")"){do c.push(F());while(f(","))}i(")");return function(d,e){for(var f=[],g=b?b(d,e):d,j=0;j<c.length;j++)f.push(c[j](d,e));j=a(d,e,g)||C;return j.apply?j.apply(g,f):j(f[0],f[1],f[2],f[3],f[4])}},u=function(a){var b=f().text,c=Lb(b,d);return v(function(b,d,e){return c(e||a(b,d),d)},{assign:function(c,d,e){return Mb(a(c,e),b,d)}})},V=function(a){var b=F();i("]");return v(function(c,d){var e=a(c,d),f=b(c,
+d),g;if(!e)return q;if((e=e[f])&&e.then){g=e;if(!("$$v"in e))g.$$v=q,g.then(function(a){g.$$v=a});e=e.$$v}return e},{assign:function(c,d,e){return a(c,e)[b(c,e)]=d}})},w=function(){for(var a=F(),b;;)if(b=f("|"))a=k(a,b.fn,n());else return a};a?(F=o,y=u=V=w=function(){e("is not valid json",{text:b,index:0})},$=A()):$=l();R.length!==0&&e("is an unexpected token",R[0]);return $}function Mb(b,a,c){for(var a=a.split("."),d=0;a.length>1;d++){var e=a.shift(),g=b[e];g||(g={},b[e]=g);b=g}return b[a.shift()]=
+c}function gb(b,a,c){if(!a)return b;for(var a=a.split("."),d,e=b,g=a.length,h=0;h<g;h++)d=a[h],b&&(b=(e=b)[d]);return!c&&H(b)?Ta(e,b):b}function Nb(b,a,c,d,e){return function(g,h){var f=h&&h.hasOwnProperty(b)?h:g,i;if(f===null||f===q)return f;if((f=f[b])&&f.then){if(!("$$v"in f))i=f,i.$$v=q,i.then(function(a){i.$$v=a});f=f.$$v}if(!a||f===null||f===q)return f;if((f=f[a])&&f.then){if(!("$$v"in f))i=f,i.$$v=q,i.then(function(a){i.$$v=a});f=f.$$v}if(!c||f===null||f===q)return f;if((f=f[c])&&f.then){if(!("$$v"in
+f))i=f,i.$$v=q,i.then(function(a){i.$$v=a});f=f.$$v}if(!d||f===null||f===q)return f;if((f=f[d])&&f.then){if(!("$$v"in f))i=f,i.$$v=q,i.then(function(a){i.$$v=a});f=f.$$v}if(!e||f===null||f===q)return f;if((f=f[e])&&f.then){if(!("$$v"in f))i=f,i.$$v=q,i.then(function(a){i.$$v=a});f=f.$$v}return f}}function Lb(b,a){if(ib.hasOwnProperty(b))return ib[b];var c=b.split("."),d=c.length,e;if(a)e=d<6?Nb(c[0],c[1],c[2],c[3],c[4]):function(a,b){var e=0,g;do g=Nb(c[e++],c[e++],c[e++],c[e++],c[e++])(a,b),b=q,
+a=g;while(e<d);return g};else{var g="var l, fn, p;\n";m(c,function(a,b){g+="if(s === null || s === undefined) return s;\nl=s;\ns="+(b?"s":'((k&&k.hasOwnProperty("'+a+'"))?k:s)')+'["'+a+'"];\nif (s && s.then) {\n if (!("$$v" in s)) {\n p=s;\n p.$$v = undefined;\n p.then(function(v) {p.$$v=v;});\n}\n s=s.$$v\n}\n'});g+="return s;";e=Function("s","k",g);e.toString=function(){return g}}return ib[b]=e}function Oc(){var b={};this.$get=["$filter","$sniffer",function(a,c){return function(d){switch(typeof d){case "string":return b.hasOwnProperty(d)?
+b[d]:b[d]=Nc(d,!1,a,c.csp);case "function":return d;default:return C}}}]}function Pc(){this.$get=["$rootScope","$exceptionHandler",function(b,a){return Qc(function(a){b.$evalAsync(a)},a)}]}function Qc(b,a){function c(a){return a}function d(a){return h(a)}var e=function(){var f=[],i,j;return j={resolve:function(a){if(f){var c=f;f=q;i=g(a);c.length&&b(function(){for(var a,b=0,d=c.length;b<d;b++)a=c[b],i.then(a[0],a[1])})}},reject:function(a){j.resolve(h(a))},promise:{then:function(b,g){var j=e(),h=
+function(d){try{j.resolve((b||c)(d))}catch(e){a(e),j.reject(e)}},p=function(b){try{j.resolve((g||d)(b))}catch(c){a(c),j.reject(c)}};f?f.push([h,p]):i.then(h,p);return j.promise}}}},g=function(a){return a&&a.then?a:{then:function(c){var d=e();b(function(){d.resolve(c(a))});return d.promise}}},h=function(a){return{then:function(c,g){var h=e();b(function(){h.resolve((g||d)(a))});return h.promise}}};return{defer:e,reject:h,when:function(f,i,j){var k=e(),l,n=function(b){try{return(i||c)(b)}catch(d){return a(d),
+h(d)}},o=function(b){try{return(j||d)(b)}catch(c){return a(c),h(c)}};b(function(){g(f).then(function(a){l||(l=!0,k.resolve(g(a).then(n,o)))},function(a){l||(l=!0,k.resolve(o(a)))})});return k.promise},all:function(a){var b=e(),c=a.length,d=[];c?m(a,function(a,e){g(a).then(function(a){e in d||(d[e]=a,--c||b.resolve(d))},function(a){e in d||b.reject(a)})}):b.resolve(d);return b.promise}}}function Rc(){var b={};this.when=function(a,c){b[a]=v({reloadOnSearch:!0},c);if(a){var d=a[a.length-1]=="/"?a.substr(0,
+a.length-1):a+"/";b[d]={redirectTo:a}}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache",function(a,c,d,e,g,h,f){function i(a,b){for(var b="^"+b.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")+"$",c="",d=[],e={},f=/:(\w+)/g,g,j=0;(g=f.exec(b))!==null;)c+=b.slice(j,g.index),c+="([^\\/]*)",d.push(g[1]),j=f.lastIndex;c+=b.substr(j);var h=a.match(RegExp(c));h&&m(d,function(a,b){e[a]=h[b+1]});return h?
+e:null}function j(){var b=k(),j=o.current;if(b&&j&&b.$$route===j.$$route&&fa(b.pathParams,j.pathParams)&&!b.reloadOnSearch&&!n)j.params=b.params,U(j.params,d),a.$broadcast("$routeUpdate",j);else if(b||j)n=!1,a.$broadcast("$routeChangeStart",b,j),(o.current=b)&&b.redirectTo&&(B(b.redirectTo)?c.path(l(b.redirectTo,b.params)).search(b.params).replace():c.url(b.redirectTo(b.pathParams,c.path(),c.search())).replace()),e.when(b).then(function(){if(b){var a=[],c=[],d;m(b.resolve||{},function(b,d){a.push(d);
+c.push(B(b)?g.get(b):g.invoke(b))});if(!y(d=b.template))if(y(d=b.templateUrl))d=h.get(d,{cache:f}).then(function(a){return a.data});y(d)&&(a.push("$template"),c.push(d));return e.all(c).then(function(b){var c={};m(b,function(b,d){c[a[d]]=b});return c})}}).then(function(c){if(b==o.current){if(b)b.locals=c,U(b.params,d);a.$broadcast("$routeChangeSuccess",b,j)}},function(c){b==o.current&&a.$broadcast("$routeChangeError",b,j,c)})}function k(){var a,d;m(b,function(b,e){if(!d&&(a=i(c.path(),e)))d=ya(b,
+{params:v({},c.search(),a),pathParams:a}),d.$$route=b});return d||b[null]&&ya(b[null],{params:{},pathParams:{}})}function l(a,b){var c=[];m((a||"").split(":"),function(a,d){if(d==0)c.push(a);else{var e=a.match(/(\w+)(.*)/),f=e[1];c.push(b[f]);c.push(e[2]||"");delete b[f]}});return c.join("")}var n=!1,o={routes:b,reload:function(){n=!0;a.$evalAsync(j)}};a.$on("$locationChangeSuccess",j);return o}]}function Sc(){this.$get=I({})}function Tc(){var b=10;this.digestTtl=function(a){arguments.length&&(b=
+a);return b};this.$get=["$injector","$exceptionHandler","$parse",function(a,c,d){function e(){this.$id=xa();this.$$phase=this.$parent=this.$$watchers=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null;this["this"]=this.$root=this;this.$$destroyed=!1;this.$$asyncQueue=[];this.$$listeners={};this.$$isolateBindings={}}function g(a){if(i.$$phase)throw Error(i.$$phase+" already in progress");i.$$phase=a}function h(a,b){var c=d(a);qa(c,b);return c}function f(){}e.prototype={$new:function(a){if(H(a))throw Error("API-CHANGE: Use $controller to instantiate controllers.");
+a?(a=new e,a.$root=this.$root):(a=function(){},a.prototype=this,a=new a,a.$id=xa());a["this"]=a;a.$$listeners={};a.$parent=this;a.$$asyncQueue=[];a.$$watchers=a.$$nextSibling=a.$$childHead=a.$$childTail=null;a.$$prevSibling=this.$$childTail;this.$$childHead?this.$$childTail=this.$$childTail.$$nextSibling=a:this.$$childHead=this.$$childTail=a;return a},$watch:function(a,b,c){var d=h(a,"watch"),e=this.$$watchers,g={fn:b,last:f,get:d,exp:a,eq:!!c};if(!H(b)){var i=h(b||C,"listener");g.fn=function(a,b,
+c){i(c)}}if(!e)e=this.$$watchers=[];e.unshift(g);return function(){Sa(e,g)}},$digest:function(){var a,d,e,h,o,p,m,t=b,x,q=[],A,N;g("$digest");do{m=!1;x=this;do{for(o=x.$$asyncQueue;o.length;)try{x.$eval(o.shift())}catch(J){c(J)}if(h=x.$$watchers)for(p=h.length;p--;)try{if(a=h[p],(d=a.get(x))!==(e=a.last)&&!(a.eq?fa(d,e):typeof d=="number"&&typeof e=="number"&&isNaN(d)&&isNaN(e)))m=!0,a.last=a.eq?U(d):d,a.fn(d,e===f?d:e,x),t<5&&(A=4-t,q[A]||(q[A]=[]),N=H(a.exp)?"fn: "+(a.exp.name||a.exp.toString()):
+a.exp,N+="; newVal: "+da(d)+"; oldVal: "+da(e),q[A].push(N))}catch(r){c(r)}if(!(h=x.$$childHead||x!==this&&x.$$nextSibling))for(;x!==this&&!(h=x.$$nextSibling);)x=x.$parent}while(x=h);if(m&&!t--)throw i.$$phase=null,Error(b+" $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: "+da(q));}while(m||o.length);i.$$phase=null},$destroy:function(){if(!(i==this||this.$$destroyed)){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;if(a.$$childHead==this)a.$$childHead=
+this.$$nextSibling;if(a.$$childTail==this)a.$$childTail=this.$$prevSibling;if(this.$$prevSibling)this.$$prevSibling.$$nextSibling=this.$$nextSibling;if(this.$$nextSibling)this.$$nextSibling.$$prevSibling=this.$$prevSibling;this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null}},$eval:function(a,b){return d(a)(this,b)},$evalAsync:function(a){this.$$asyncQueue.push(a)},$apply:function(a){try{return g("$apply"),this.$eval(a)}catch(b){c(b)}finally{i.$$phase=null;try{i.$digest()}catch(d){throw c(d),
+d;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);return function(){c[za(c,b)]=null}},$emit:function(a,b){var d=[],e,f=this,g=!1,h={name:a,targetScope:f,stopPropagation:function(){g=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},i=[h].concat(ha.call(arguments,1)),m,q;do{e=f.$$listeners[a]||d;h.currentScope=f;m=0;for(q=e.length;m<q;m++)if(e[m])try{if(e[m].apply(null,i),g)return h}catch(A){c(A)}else e.splice(m,1),m--,q--;f=f.$parent}while(f);
+return h},$broadcast:function(a,b){var d=this,e=this,f={name:a,targetScope:this,preventDefault:function(){f.defaultPrevented=!0},defaultPrevented:!1},g=[f].concat(ha.call(arguments,1)),h,i;do{d=e;f.currentScope=d;e=d.$$listeners[a]||[];h=0;for(i=e.length;h<i;h++)if(e[h])try{e[h].apply(null,g)}catch(m){c(m)}else e.splice(h,1),h--,i--;if(!(e=d.$$childHead||d!==this&&d.$$nextSibling))for(;d!==this&&!(e=d.$$nextSibling);)d=d.$parent}while(d=e);return f}};var i=new e;return i}]}function Uc(){this.$get=
+["$window",function(b){var a={},c=G((/android (\d+)/.exec(z(b.navigator.userAgent))||[])[1]);return{history:!(!b.history||!b.history.pushState||c<4),hashchange:"onhashchange"in b&&(!b.document.documentMode||b.document.documentMode>7),hasEvent:function(c){if(c=="input"&&Z==9)return!1;if(w(a[c])){var e=b.document.createElement("div");a[c]="on"+c in e}return a[c]},csp:!1}}]}function Vc(){this.$get=I(P)}function Ob(b){var a={},c,d,e;if(!b)return a;m(b.split("\n"),function(b){e=b.indexOf(":");c=z(Q(b.substr(0,
+e)));d=Q(b.substr(e+1));c&&(a[c]?a[c]+=", "+d:a[c]=d)});return a}function Pb(b){var a=L(b)?b:q;return function(c){a||(a=Ob(b));return c?a[z(c)]||null:a}}function Qb(b,a,c){if(H(c))return c(b,a);m(c,function(c){b=c(b,a)});return b}function Wc(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d=this.defaults={transformResponse:[function(d){B(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=pb(d,!0)));return d}],transformRequest:[function(a){return L(a)&&wa.apply(a)!=="[object File]"?da(a):a}],
+headers:{common:{Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"},post:{"Content-Type":"application/json;charset=utf-8"},put:{"Content-Type":"application/json;charset=utf-8"}}},e=this.responseInterceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(a,b,c,i,j,k){function l(a){function c(a){var b=v({},a,{data:Qb(a.data,a.headers,f)});return 200<=a.status&&a.status<300?b:j.reject(b)}a.method=la(a.method);var e=a.transformRequest||
+d.transformRequest,f=a.transformResponse||d.transformResponse,g=d.headers,g=v({"X-XSRF-TOKEN":b.cookies()["XSRF-TOKEN"]},g.common,g[z(a.method)],a.headers),e=Qb(a.data,Pb(g),e),i;w(a.data)&&delete g["Content-Type"];i=n(a,e,g);i=i.then(c,c);m(s,function(a){i=a(i)});i.success=function(b){i.then(function(c){b(c.data,c.status,c.headers,a)});return i};i.error=function(b){i.then(null,function(c){b(c.data,c.status,c.headers,a)});return i};return i}function n(b,c,d){function e(a,b,c){m&&(200<=a&&a<300?m.put(q,
+[a,b,Ob(c)]):m.remove(q));f(b,a,c);i.$apply()}function f(a,c,d){c=Math.max(c,0);(200<=c&&c<300?k.resolve:k.reject)({data:a,status:c,headers:Pb(d),config:b})}function h(){var a=za(l.pendingRequests,b);a!==-1&&l.pendingRequests.splice(a,1)}var k=j.defer(),n=k.promise,m,s,q=o(b.url,b.params);l.pendingRequests.push(b);n.then(h,h);b.cache&&b.method=="GET"&&(m=L(b.cache)?b.cache:p);if(m)if(s=m.get(q))if(s.then)return s.then(h,h),s;else E(s)?f(s[1],s[0],U(s[2])):f(s,200,{});else m.put(q,n);s||a(b.method,
+q,c,e,d,b.timeout,b.withCredentials);return n}function o(a,b){if(!b)return a;var c=[];fc(b,function(a,b){a==null||a==q||(L(a)&&(a=da(a)),c.push(encodeURIComponent(b)+"="+encodeURIComponent(a)))});return a+(a.indexOf("?")==-1?"?":"&")+c.join("&")}var p=c("$http"),s=[];m(e,function(a){s.push(B(a)?k.get(a):k.invoke(a))});l.pendingRequests=[];(function(a){m(arguments,function(a){l[a]=function(b,c){return l(v(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){m(arguments,function(a){l[a]=
+function(b,c,d){return l(v(d||{},{method:a,url:b,data:c}))}})})("post","put");l.defaults=d;return l}]}function Xc(){this.$get=["$browser","$window","$document",function(b,a,c){return Yc(b,Zc,b.defer,a.angular.callbacks,c[0],a.location.protocol.replace(":",""))}]}function Yc(b,a,c,d,e,g){function h(a,b){var c=e.createElement("script"),d=function(){e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;Z?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=
+d;e.body.appendChild(c)}return function(e,i,j,k,l,n,o){function p(a,c,d,e){c=(i.match(Hb)||["",g])[1]=="file"?d?200:404:c;a(c==1223?204:c,d,e);b.$$completeOutstandingRequest(C)}b.$$incOutstandingRequestCount();i=i||b.url();if(z(e)=="jsonp"){var s="_"+(d.counter++).toString(36);d[s]=function(a){d[s].data=a};h(i.replace("JSON_CALLBACK","angular.callbacks."+s),function(){d[s].data?p(k,200,d[s].data):p(k,-2);delete d[s]})}else{var t=new a;t.open(e,i,!0);m(l,function(a,b){a&&t.setRequestHeader(b,a)});
+var q;t.onreadystatechange=function(){if(t.readyState==4){var a=t.getAllResponseHeaders(),b=["Cache-Control","Content-Language","Content-Type","Expires","Last-Modified","Pragma"];a||(a="",m(b,function(b){var c=t.getResponseHeader(b);c&&(a+=b+": "+c+"\n")}));p(k,q||t.status,t.responseText,a)}};if(o)t.withCredentials=!0;t.send(j||"");n>0&&c(function(){q=-1;t.abort()},n)}}}function $c(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,
+maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),SHORTMONTH:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),DAY:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),SHORTDAY:"Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),
+AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return b===1?"one":"other"}}}}function ad(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,f,i){var j=c.defer(),k=j.promise,l=y(i)&&!i,f=a.defer(function(){try{j.resolve(e())}catch(a){j.reject(a),d(a)}l||b.$apply()},f),i=function(){delete g[k.$$timeoutId]};
+k.$$timeoutId=f;g[f]=j;k.then(i,i);return k}var g={};e.cancel=function(b){return b&&b.$$timeoutId in g?(g[b.$$timeoutId].reject("canceled"),a.defer.cancel(b.$$timeoutId)):!1};return e}]}function Rb(b){function a(a,e){return b.factory(a+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+c)}}];a("currency",Sb);a("date",Tb);a("filter",bd);a("json",cd);a("limitTo",dd);a("lowercase",ed);a("number",Ub);a("orderBy",Vb);a("uppercase",fd)}function bd(){return function(b,
+a){if(!E(b))return b;var c=[];c.check=function(a){for(var b=0;b<c.length;b++)if(!c[b](a))return!1;return!0};var d=function(a,b){if(b.charAt(0)==="!")return!d(a,b.substr(1));switch(typeof a){case "boolean":case "number":case "string":return(""+a).toLowerCase().indexOf(b)>-1;case "object":for(var c in a)if(c.charAt(0)!=="$"&&d(a[c],b))return!0;return!1;case "array":for(c=0;c<a.length;c++)if(d(a[c],b))return!0;return!1;default:return!1}};switch(typeof a){case "boolean":case "number":case "string":a=
+{$:a};case "object":for(var e in a)e=="$"?function(){var b=(""+a[e]).toLowerCase();b&&c.push(function(a){return d(a,b)})}():function(){var b=e,f=(""+a[e]).toLowerCase();f&&c.push(function(a){return d(gb(a,b),f)})}();break;case "function":c.push(a);break;default:return b}for(var g=[],h=0;h<b.length;h++){var f=b[h];c.check(f)&&g.push(f)}return g}}function Sb(b){var a=b.NUMBER_FORMATS;return function(b,d){if(w(d))d=a.CURRENCY_SYM;return Wb(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,2).replace(/\u00A4/g,
+d)}}function Ub(b){var a=b.NUMBER_FORMATS;return function(b,d){return Wb(b,a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}function Wb(b,a,c,d,e){if(isNaN(b)||!isFinite(b))return"";var g=b<0,b=Math.abs(b),h=b+"",f="",i=[],j=!1;if(h.indexOf("e")!==-1){var k=h.match(/([\d\.]+)e(-?)(\d+)/);k&&k[2]=="-"&&k[3]>e+1?h="0":(f=h,j=!0)}if(!j){h=(h.split(Xb)[1]||"").length;w(e)&&(e=Math.min(Math.max(a.minFrac,h),a.maxFrac));var h=Math.pow(10,e),b=Math.round(b*h)/h,b=(""+b).split(Xb),h=b[0],b=b[1]||"",j=0,k=a.lgSize,
+l=a.gSize;if(h.length>=k+l)for(var j=h.length-k,n=0;n<j;n++)(j-n)%l===0&&n!==0&&(f+=c),f+=h.charAt(n);for(n=j;n<h.length;n++)(h.length-n)%k===0&&n!==0&&(f+=c),f+=h.charAt(n);for(;b.length<e;)b+="0";e&&e!=="0"&&(f+=d+b.substr(0,e))}i.push(g?a.negPre:a.posPre);i.push(f);i.push(g?a.negSuf:a.posSuf);return i.join("")}function jb(b,a,c){var d="";b<0&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=b.substr(b.length-a));return d+b}function O(b,a,c,d){c=c||0;return function(e){e=e["get"+b]();if(c>0||e>
+-c)e+=c;e===0&&c==-12&&(e=12);return jb(e,a,d)}}function Ja(b,a){return function(c,d){var e=c["get"+b](),g=la(a?"SHORT"+b:b);return d[g][e]}}function Tb(b){function a(a){var b;if(b=a.match(c)){var a=new Date(0),g=0,h=0;b[9]&&(g=G(b[9]+b[10]),h=G(b[9]+b[11]));a.setUTCFullYear(G(b[1]),G(b[2])-1,G(b[3]));a.setUTCHours(G(b[4]||0)-g,G(b[5]||0)-h,G(b[6]||0),G(b[7]||0))}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,
+e){var g="",h=[],f,i,e=e||"mediumDate",e=b.DATETIME_FORMATS[e]||e;B(c)&&(c=gd.test(c)?G(c):a(c));Qa(c)&&(c=new Date(c));if(!na(c))return c;for(;e;)(i=hd.exec(e))?(h=h.concat(ha.call(i,1)),e=h.pop()):(h.push(e),e=null);m(h,function(a){f=id[a];g+=f?f(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function cd(){return function(b){return da(b,!0)}}function dd(){return function(b,a){if(!(b instanceof Array))return b;var a=G(a),c=[],d,e;if(!b||!(b instanceof Array))return c;
+a>b.length?a=b.length:a<-b.length&&(a=-b.length);a>0?(d=0,e=a):(d=b.length+a,e=b.length);for(;d<e;d++)c.push(b[d]);return c}}function Vb(b){return function(a,c,d){function e(a,b){return Ua(b)?function(b,c){return a(c,b)}:a}if(!E(a))return a;if(!c)return a;for(var c=E(c)?c:[c],c=Ra(c,function(a){var c=!1,d=a||ma;if(B(a)){if(a.charAt(0)=="+"||a.charAt(0)=="-")c=a.charAt(0)=="-",a=a.substring(1);d=b(a)}return e(function(a,b){var c;c=d(a);var e=d(b),f=typeof c,g=typeof e;f==g?(f=="string"&&(c=c.toLowerCase()),
+f=="string"&&(e=e.toLowerCase()),c=c===e?0:c<e?-1:1):c=f<g?-1:1;return c},c)}),g=[],h=0;h<a.length;h++)g.push(a[h]);return g.sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(e!==0)return e}return 0},d))}}function S(b){H(b)&&(b={link:b});b.restrict=b.restrict||"AC";return I(b)}function Yb(b,a){function c(a,c){c=c?"-"+Za(c,"-"):"";b.removeClass((a?Ka:La)+c).addClass((a?La:Ka)+c)}var d=this,e=b.parent().controller("form")||Ma,g=0,h=d.$error={};d.$name=a.name;d.$dirty=!1;d.$pristine=
+!0;d.$valid=!0;d.$invalid=!1;e.$addControl(d);b.addClass(Na);c(!0);d.$addControl=function(a){a.$name&&!d.hasOwnProperty(a.$name)&&(d[a.$name]=a)};d.$removeControl=function(a){a.$name&&d[a.$name]===a&&delete d[a.$name];m(h,function(b,c){d.$setValidity(c,!0,a)})};d.$setValidity=function(a,b,j){var k=h[a];if(b){if(k&&(Sa(k,j),!k.length)){g--;if(!g)c(b),d.$valid=!0,d.$invalid=!1;h[a]=!1;c(!0,a);e.$setValidity(a,!0,d)}}else{g||c(b);if(k){if(za(k,j)!=-1)return}else h[a]=k=[],g++,c(!1,a),e.$setValidity(a,
+!1,d);k.push(j);d.$valid=!1;d.$invalid=!0}};d.$setDirty=function(){b.removeClass(Na).addClass(Zb);d.$dirty=!0;d.$pristine=!1;e.$setDirty()}}function X(b){return w(b)||b===""||b===null||b!==b}function Oa(b,a,c,d,e,g){var h=function(){var c=Q(a.val());d.$viewValue!==c&&b.$apply(function(){d.$setViewValue(c)})};if(e.hasEvent("input"))a.bind("input",h);else{var f,i=function(){f||(f=g.defer(function(){h();f=null}))};a.bind("keydown",function(a){a=a.keyCode;a===91||15<a&&a<19||37<=a&&a<=40||i()});a.bind("change",
+h);e.hasEvent("paste")&&a.bind("paste cut",i)}d.$render=function(){a.val(X(d.$viewValue)?"":d.$viewValue)};var j=c.ngPattern,k=function(a,b){return X(b)||a.test(b)?(d.$setValidity("pattern",!0),b):(d.$setValidity("pattern",!1),q)};j&&(j.match(/^\/(.*)\/$/)?(j=RegExp(j.substr(1,j.length-2)),e=function(a){return k(j,a)}):e=function(a){var c=b.$eval(j);if(!c||!c.test)throw Error("Expected "+j+" to be a RegExp but was "+c);return k(c,a)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var l=
+G(c.ngMinlength),e=function(a){return!X(a)&&a.length<l?(d.$setValidity("minlength",!1),q):(d.$setValidity("minlength",!0),a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var n=G(c.ngMaxlength),c=function(a){return!X(a)&&a.length>n?(d.$setValidity("maxlength",!1),q):(d.$setValidity("maxlength",!0),a)};d.$parsers.push(c);d.$formatters.push(c)}}function kb(b,a){b="ngClass"+b;return S(function(c,d,e){function g(b){if(a===!0||c.$index%2===a)i&&!fa(b,i)&&h(i),f(b);i=U(b)}function h(a){L(a)&&
+!E(a)&&(a=Ra(a,function(a,b){if(a)return b}));d.removeClass(E(a)?a.join(" "):a)}function f(a){L(a)&&!E(a)&&(a=Ra(a,function(a,b){if(a)return b}));a&&d.addClass(E(a)?a.join(" "):a)}var i=q;c.$watch(e[b],g,!0);e.$observe("class",function(){var a=c.$eval(e[b]);g(a,a)});b!=="ngClass"&&c.$watch("$index",function(d,g){var i=d&1;i!==g&1&&(i===a?f(c.$eval(e[b])):h(c.$eval(e[b])))})})}var z=function(b){return B(b)?b.toLowerCase():b},la=function(b){return B(b)?b.toUpperCase():b},Z=G((/msie (\d+)/.exec(z(navigator.userAgent))||
+[])[1]),u,ca,ha=[].slice,Pa=[].push,wa=Object.prototype.toString,Ya=P.angular||(P.angular={}),sa,fb,aa=["0","0","0"];C.$inject=[];ma.$inject=[];fb=Z<9?function(b){b=b.nodeName?b:b[0];return b.scopeName&&b.scopeName!="HTML"?la(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var kc=/[A-Z]/g,jd={full:"1.0.7",major:1,minor:0,dot:7,codeName:"monochromatic-rainbow"},Ba=K.cache={},Aa=K.expando="ng-"+(new Date).getTime(),oc=1,$b=P.document.addEventListener?
+function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},db=P.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)},mc=/([\:\-\_]+(.))/g,nc=/^moz([A-Z])/,ua=K.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;this.bind("DOMContentLoaded",a);K(P).bind("load",a)},toString:function(){var b=[];m(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return b>=0?u(this[b]):u(this[this.length+
+b])},length:0,push:Pa,sort:[].sort,splice:[].splice},Ea={};m("multiple,selected,checked,disabled,readOnly,required".split(","),function(b){Ea[z(b)]=b});var Bb={};m("input,select,option,textarea,button,form".split(","),function(b){Bb[la(b)]=!0});m({data:wb,inheritedData:Da,scope:function(b){return Da(b,"$scope")},controller:zb,injector:function(b){return Da(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Ca,css:function(b,a,c){a=tb(a);if(y(c))b.style[a]=c;else{var d;Z<=8&&(d=
+b.currentStyle&&b.currentStyle[a],d===""&&(d="auto"));d=d||b.style[a];Z<=8&&(d=d===""?q:d);return d}},attr:function(b,a,c){var d=z(a);if(Ea[d])if(y(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||C).specified?d:q;else if(y(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),b===null?q:b},prop:function(b,a,c){if(y(c))b[a]=c;else return b[a]},text:v(Z<9?function(b,a){if(b.nodeType==1){if(w(a))return b.innerText;
+b.innerText=a}else{if(w(a))return b.nodeValue;b.nodeValue=a}}:function(b,a){if(w(a))return b.textContent;b.textContent=a},{$dv:""}),val:function(b,a){if(w(a))return b.value;b.value=a},html:function(b,a){if(w(a))return b.innerHTML;for(var c=0,d=b.childNodes;c<d.length;c++)ra(d[c]);b.innerHTML=a}},function(b,a){K.prototype[a]=function(a,d){var e,g;if((b.length==2&&b!==Ca&&b!==zb?a:d)===q)if(L(a)){for(e=0;e<this.length;e++)if(b===wb)b(this[e],a);else for(g in a)b(this[e],g,a[g]);return this}else{if(this.length)return b(this[0],
+a,d)}else{for(e=0;e<this.length;e++)b(this[e],a,d);return this}return b.$dv}});m({removeData:ub,dealoc:ra,bind:function a(c,d,e){var g=ba(c,"events"),h=ba(c,"handle");g||ba(c,"events",g={});h||ba(c,"handle",h=pc(c,g));m(d.split(" "),function(d){var i=g[d];if(!i){if(d=="mouseenter"||d=="mouseleave"){var j=T.body.contains||T.body.compareDocumentPosition?function(a,c){var d=a.nodeType===9?a.documentElement:a,e=c&&c.parentNode;return a===e||!(!e||!(e.nodeType===1&&(d.contains?d.contains(e):a.compareDocumentPosition&&
+a.compareDocumentPosition(e)&16)))}:function(a,c){if(c)for(;c=c.parentNode;)if(c===a)return!0;return!1};g[d]=[];a(c,{mouseleave:"mouseout",mouseenter:"mouseover"}[d],function(a){var c=a.relatedTarget;(!c||c!==this&&!j(this,c))&&h(a,d)})}else $b(c,d,h),g[d]=[];i=g[d]}i.push(e)})},unbind:vb,replaceWith:function(a,c){var d,e=a.parentNode;ra(a);m(new K(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,a);d=c})},children:function(a){var c=[];m(a.childNodes,function(a){a.nodeType===1&&c.push(a)});
+return c},contents:function(a){return a.childNodes||[]},append:function(a,c){m(new K(c),function(c){a.nodeType===1&&a.appendChild(c)})},prepend:function(a,c){if(a.nodeType===1){var d=a.firstChild;m(new K(c),function(c){d?a.insertBefore(c,d):(a.appendChild(c),d=c)})}},wrap:function(a,c){var c=u(c)[0],d=a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},remove:function(a){ra(a);var c=a.parentNode;c&&c.removeChild(a)},after:function(a,c){var d=a,e=a.parentNode;m(new K(c),function(a){e.insertBefore(a,
+d.nextSibling);d=a})},addClass:yb,removeClass:xb,toggleClass:function(a,c,d){w(d)&&(d=!Ca(a,c));(d?yb:xb)(a,c)},parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},next:function(a){if(a.nextElementSibling)return a.nextElementSibling;for(a=a.nextSibling;a!=null&&a.nodeType!==1;)a=a.nextSibling;return a},find:function(a,c){return a.getElementsByTagName(c)},clone:cb,triggerHandler:function(a,c){var d=(ba(a,"events")||{})[c];m(d,function(c){c.call(a,null)})}},function(a,c){K.prototype[c]=
+function(c,e){for(var g,h=0;h<this.length;h++)g==q?(g=a(this[h],c,e),g!==q&&(g=u(g))):bb(g,a(this[h],c,e));return g==q?this:g}});Fa.prototype={put:function(a,c){this[ga(a)]=c},get:function(a){return this[ga(a)]},remove:function(a){var c=this[a=ga(a)];delete this[a];return c}};eb.prototype={push:function(a,c){var d=this[a=ga(a)];d?d.push(c):this[a]=[c]},shift:function(a){var c=this[a=ga(a)];if(c)return c.length==1?(delete this[a],c[0]):c.shift()},peek:function(a){if(a=this[ga(a)])return a[0]}};var rc=
+/^function\s*[^\(]*\(\s*([^\)]*)\)/m,sc=/,/,tc=/^\s*(_?)(\S+?)\1\s*$/,qc=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,Eb="Non-assignable model expression: ";Db.$inject=["$provide"];var Bc=/^(x[\:\-_]|data[\:\-_])/i,Hb=/^([^:]+):\/\/(\w+:{0,1}\w*@)?(\{?[\w\.-]*\}?)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,ac=/^([^\?#]*)?(\?([^#]*))?(#(.*))?$/,Ic=ac,Ib={http:80,https:443,ftp:21};hb.prototype={$$replace:!1,absUrl:Ha("$$absUrl"),url:function(a,c){if(w(a))return this.$$url;var d=ac.exec(a);d[1]&&this.path(decodeURIComponent(d[1]));
+if(d[2]||d[1])this.search(d[3]||"");this.hash(d[5]||"",c);return this},protocol:Ha("$$protocol"),host:Ha("$$host"),port:Ha("$$port"),path:Kb("$$path",function(a){return a.charAt(0)=="/"?a:"/"+a}),search:function(a,c){if(w(a))return this.$$search;y(c)?c===null?delete this.$$search[a]:this.$$search[a]=c:this.$$search=B(a)?Va(a):a;this.$$compose();return this},hash:Kb("$$hash",ma),replace:function(){this.$$replace=!0;return this}};Ga.prototype=ya(hb.prototype);Jb.prototype=ya(Ga.prototype);var Ia={"null":function(){return null},
+"true":function(){return!0},"false":function(){return!1},undefined:C,"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return y(d)?y(e)?d+e:d:y(e)?e:q},"-":function(a,c,d,e){d=d(a,c);e=e(a,c);return(y(d)?d:0)-(y(e)?e:0)},"*":function(a,c,d,e){return d(a,c)*e(a,c)},"/":function(a,c,d,e){return d(a,c)/e(a,c)},"%":function(a,c,d,e){return d(a,c)%e(a,c)},"^":function(a,c,d,e){return d(a,c)^e(a,c)},"=":C,"==":function(a,c,d,e){return d(a,c)==e(a,c)},"!=":function(a,c,d,e){return d(a,c)!=e(a,c)},"<":function(a,c,
+d,e){return d(a,c)<e(a,c)},">":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Mc={n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'},ib={},Zc=P.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(c){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(d){}throw Error("This browser does not support XMLHttpRequest.");
+};Rb.$inject=["$provide"];Sb.$inject=["$locale"];Ub.$inject=["$locale"];var Xb=".",id={yyyy:O("FullYear",4),yy:O("FullYear",2,0,!0),y:O("FullYear",1),MMMM:Ja("Month"),MMM:Ja("Month",!0),MM:O("Month",2,1),M:O("Month",1,1),dd:O("Date",2),d:O("Date",1),HH:O("Hours",2),H:O("Hours",1),hh:O("Hours",2,-12),h:O("Hours",1,-12),mm:O("Minutes",2),m:O("Minutes",1),ss:O("Seconds",2),s:O("Seconds",1),EEEE:Ja("Day"),EEE:Ja("Day",!0),a:function(a,c){return a.getHours()<12?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){var a=
+-1*a.getTimezoneOffset(),c=a>=0?"+":"";c+=jb(Math[a>0?"floor":"ceil"](a/60),2)+jb(Math.abs(a%60),2);return c}},hd=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,gd=/^\d+$/;Tb.$inject=["$locale"];var ed=I(z),fd=I(la);Vb.$inject=["$parse"];var kd=I({restrict:"E",compile:function(a,c){Z<=8&&(!c.href&&!c.name&&c.$set("href",""),a.append(T.createComment("IE fix")));return function(a,c){c.bind("click",function(a){c.attr("href")||a.preventDefault()})}}}),lb={};m(Ea,function(a,
+c){var d=ea("ng-"+c);lb[d]=function(){return{priority:100,compile:function(){return function(a,g,h){a.$watch(h[d],function(a){h.$set(c,!!a)})}}}}});m(["src","href"],function(a){var c=ea("ng-"+a);lb[c]=function(){return{priority:99,link:function(d,e,g){g.$observe(c,function(c){c&&(g.$set(a,c),Z&&e.prop(a,g[a]))})}}}});var Ma={$addControl:C,$removeControl:C,$setValidity:C,$setDirty:C};Yb.$inject=["$element","$attrs","$scope"];var Pa=function(a){return["$timeout",function(c){var d={name:"form",restrict:"E",
+controller:Yb,compile:function(){return{pre:function(a,d,h,f){if(!h.action){var i=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};$b(d[0],"submit",i);d.bind("$destroy",function(){c(function(){db(d[0],"submit",i)},0,!1)})}var j=d.parent().controller("form"),k=h.name||h.ngForm;k&&(a[k]=f);j&&d.bind("$destroy",function(){j.$removeControl(f);k&&(a[k]=q);v(f,Ma)})}}}};return a?v(U(d),{restrict:"EAC"}):d}]},ld=Pa(),md=Pa(!0),nd=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,
+od=/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/,pd=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,bc={text:Oa,number:function(a,c,d,e,g,h){Oa(a,c,d,e,g,h);e.$parsers.push(function(a){var c=X(a);return c||pd.test(a)?(e.$setValidity("number",!0),a===""?null:c?a:parseFloat(a)):(e.$setValidity("number",!1),q)});e.$formatters.push(function(a){return X(a)?"":""+a});if(d.min){var f=parseFloat(d.min),a=function(a){return!X(a)&&a<f?(e.$setValidity("min",!1),q):(e.$setValidity("min",!0),a)};e.$parsers.push(a);
+e.$formatters.push(a)}if(d.max){var i=parseFloat(d.max),d=function(a){return!X(a)&&a>i?(e.$setValidity("max",!1),q):(e.$setValidity("max",!0),a)};e.$parsers.push(d);e.$formatters.push(d)}e.$formatters.push(function(a){return X(a)||Qa(a)?(e.$setValidity("number",!0),a):(e.$setValidity("number",!1),q)})},url:function(a,c,d,e,g,h){Oa(a,c,d,e,g,h);a=function(a){return X(a)||nd.test(a)?(e.$setValidity("url",!0),a):(e.$setValidity("url",!1),q)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,
+c,d,e,g,h){Oa(a,c,d,e,g,h);a=function(a){return X(a)||od.test(a)?(e.$setValidity("email",!0),a):(e.$setValidity("email",!1),q)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){w(d.name)&&c.attr("name",xa());c.bind("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var g=d.ngTrueValue,h=d.ngFalseValue;B(g)||(g=!0);B(h)||(h=!1);c.bind("click",
+function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$formatters.push(function(a){return a===g});e.$parsers.push(function(a){return a?g:h})},hidden:C,button:C,submit:C,reset:C},cc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,g,h){h&&(bc[z(g.type)]||bc.text)(d,e,g,h,c,a)}}}],La="ng-valid",Ka="ng-invalid",Na="ng-pristine",Zb="ng-dirty",qd=["$scope","$exceptionHandler","$attrs","$element","$parse",
+function(a,c,d,e,g){function h(a,c){c=c?"-"+Za(c,"-"):"";e.removeClass((a?Ka:La)+c).addClass((a?La:Ka)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var f=g(d.ngModel),i=f.assign;if(!i)throw Error(Eb+d.ngModel+" ("+pa(e)+")");this.$render=C;var j=e.inheritedData("$formController")||Ma,k=0,l=this.$error={};e.addClass(Na);h(!0);this.$setValidity=function(a,
+c){if(l[a]!==!c){if(c){if(l[a]&&k--,!k)h(!0),this.$valid=!0,this.$invalid=!1}else h(!1),this.$invalid=!0,this.$valid=!1,k++;l[a]=!c;h(c,a);j.$setValidity(a,c,this)}};this.$setViewValue=function(d){this.$viewValue=d;if(this.$pristine)this.$dirty=!0,this.$pristine=!1,e.removeClass(Na).addClass(Zb),j.$setDirty();m(this.$parsers,function(a){d=a(d)});if(this.$modelValue!==d)this.$modelValue=d,i(a,d),m(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}})};var n=this;a.$watch(function(){var c=
+f(a);if(n.$modelValue!==c){var d=n.$formatters,e=d.length;for(n.$modelValue=c;e--;)c=d[e](c);if(n.$viewValue!==c)n.$viewValue=c,n.$render()}})}],rd=function(){return{require:["ngModel","^?form"],controller:qd,link:function(a,c,d,e){var g=e[0],h=e[1]||Ma;h.$addControl(g);c.bind("$destroy",function(){h.$removeControl(g)})}}},sd=I({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),dc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=
+!0;var g=function(a){if(d.required&&(X(a)||a===!1))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(g);e.$parsers.unshift(g);d.$observe("required",function(){g(e.$viewValue)})}}}},td=function(){return{require:"ngModel",link:function(a,c,d,e){var g=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){var c=[];a&&m(a.split(g),function(a){a&&c.push(Q(a))});return c});e.$formatters.push(function(a){return E(a)?a.join(", "):
+q})}}},ud=/^(true|false|\d+)$/,vd=function(){return{priority:100,compile:function(a,c){return ud.test(c.ngValue)?function(a,c,g){g.$set("value",a.$eval(g.ngValue))}:function(a,c,g){a.$watch(g.ngValue,function(a){g.$set("value",a,!1)})}}}},wd=S(function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==q?"":a)})}),xd=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",
+function(a){d.text(a)})}}],yd=[function(){return function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBindHtmlUnsafe);a.$watch(d.ngBindHtmlUnsafe,function(a){c.html(a||"")})}}],zd=kb("",!0),Ad=kb("Odd",0),Bd=kb("Even",1),Cd=S({compile:function(a,c){c.$set("ngCloak",q);a.removeClass("ng-cloak")}}),Dd=[function(){return{scope:!0,controller:"@"}}],Ed=["$sniffer",function(a){return{priority:1E3,compile:function(){a.csp=!0}}}],ec={};m("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave".split(" "),
+function(a){var c=ea("ng-"+a);ec[c]=["$parse",function(d){return function(e,g,h){var f=d(h[c]);g.bind(z(a),function(a){e.$apply(function(){f(e,{$event:a})})})}}]});var Fd=S(function(a,c,d){c.bind("submit",function(){a.$apply(d.ngSubmit)})}),Gd=["$http","$templateCache","$anchorScroll","$compile",function(a,c,d,e){return{restrict:"ECA",terminal:!0,compile:function(g,h){var f=h.ngInclude||h.src,i=h.onload||"",j=h.autoscroll;return function(g,h){var n=0,o,p=function(){o&&(o.$destroy(),o=null);h.html("")};
+g.$watch(f,function(f){var m=++n;f?a.get(f,{cache:c}).success(function(a){m===n&&(o&&o.$destroy(),o=g.$new(),h.html(a),e(h.contents())(o),y(j)&&(!j||g.$eval(j))&&d(),o.$emit("$includeContentLoaded"),g.$eval(i))}).error(function(){m===n&&p()}):p()})}}}}],Hd=S({compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),Id=S({terminal:!0,priority:1E3}),Jd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,g,h){var f=h.count,i=g.attr(h.$attr.when),j=h.offset||
+0,k=e.$eval(i),l={},n=c.startSymbol(),o=c.endSymbol();m(k,function(a,e){l[e]=c(a.replace(d,n+f+"-"+j+o))});e.$watch(function(){var c=parseFloat(e.$eval(f));return isNaN(c)?"":(c in k||(c=a.pluralCat(c-j)),l[c](e,g,!0))},function(a){g.text(a)})}}}],Kd=S({transclude:"element",priority:1E3,terminal:!0,compile:function(a,c,d){return function(a,c,h){var f=h.ngRepeat,h=f.match(/^\s*(.+)\s+in\s+(.*)\s*$/),i,j,k;if(!h)throw Error("Expected ngRepeat in form of '_item_ in _collection_' but got '"+f+"'.");f=
+h[1];i=h[2];h=f.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!h)throw Error("'item' in 'item in collection' should be identifier or (key, value) but got '"+f+"'.");j=h[3]||h[1];k=h[2];var l=new eb;a.$watch(function(a){var e,f,h=a.$eval(i),m=c,q=new eb,y,A,u,w,r,v;if(E(h))r=h||[];else{r=[];for(u in h)h.hasOwnProperty(u)&&u.charAt(0)!="$"&&r.push(u);r.sort()}y=r.length-1;e=0;for(f=r.length;e<f;e++){u=h===r?e:r[e];w=h[u];if(v=l.shift(w)){A=v.scope;q.push(w,v);if(e!==v.index)v.index=e,m.after(v.element);
+m=v.element}else A=a.$new();A[j]=w;k&&(A[k]=u);A.$index=e;A.$first=e===0;A.$last=e===y;A.$middle=!(A.$first||A.$last);v||d(A,function(a){m.after(a);v={scope:A,element:m=a,index:e};q.push(w,v)})}for(u in l)if(l.hasOwnProperty(u))for(r=l[u];r.length;)w=r.pop(),w.element.remove(),w.scope.$destroy();l=q})}}}),Ld=S(function(a,c,d){a.$watch(d.ngShow,function(a){c.css("display",Ua(a)?"":"none")})}),Md=S(function(a,c,d){a.$watch(d.ngHide,function(a){c.css("display",Ua(a)?"none":"")})}),Nd=S(function(a,c,
+d){a.$watch(d.ngStyle,function(a,d){d&&a!==d&&m(d,function(a,d){c.css(d,"")});a&&c.css(a)},!0)}),Od=I({restrict:"EA",require:"ngSwitch",controller:["$scope",function(){this.cases={}}],link:function(a,c,d,e){var g,h,f;a.$watch(d.ngSwitch||d.on,function(i){h&&(f.$destroy(),h.remove(),h=f=null);if(g=e.cases["!"+i]||e.cases["?"])a.$eval(d.change),f=a.$new(),g(f,function(a){h=a;c.append(a)})})}}),Pd=S({transclude:"element",priority:500,require:"^ngSwitch",compile:function(a,c,d){return function(a,g,h,
+f){f.cases["!"+c.ngSwitchWhen]=d}}}),Qd=S({transclude:"element",priority:500,require:"^ngSwitch",compile:function(a,c,d){return function(a,c,h,f){f.cases["?"]=d}}}),Rd=S({controller:["$transclude","$element",function(a,c){a(function(a){c.append(a)})}]}),Sd=["$http","$templateCache","$route","$anchorScroll","$compile","$controller",function(a,c,d,e,g,h){return{restrict:"ECA",terminal:!0,link:function(a,c,j){function k(){var j=d.current&&d.current.locals,k=j&&j.$template;if(k){c.html(k);l&&(l.$destroy(),
+l=null);var k=g(c.contents()),m=d.current;l=m.scope=a.$new();if(m.controller)j.$scope=l,j=h(m.controller,j),c.children().data("$ngControllerController",j);k(l);l.$emit("$viewContentLoaded");l.$eval(n);e()}else c.html(""),l&&(l.$destroy(),l=null)}var l,n=j.onload||"";a.$on("$routeChangeSuccess",k);k()}}}],Td=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,d){d.type=="text/ng-template"&&a.put(d.id,c[0].text)}}}],Ud=I({terminal:!0}),Vd=["$compile","$parse",function(a,
+c){var d=/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/,e={$setViewValue:C};return{restrict:"E",require:["select","?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var i=this,j={},k=e,l;i.databound=d.ngModel;i.init=function(a,c,d){k=a;l=d};i.addOption=function(c){j[c]=!0;k.$viewValue==c&&(a.val(c),l.parent()&&l.remove())};i.removeOption=function(a){this.hasOption(a)&&(delete j[a],
+k.$viewValue==a&&this.renderUnknownOption(a))};i.renderUnknownOption=function(c){c="? "+ga(c)+" ?";l.val(c);a.prepend(l);a.val(c);l.prop("selected",!0)};i.hasOption=function(a){return j.hasOwnProperty(a)};c.$on("$destroy",function(){i.renderUnknownOption=C})}],link:function(e,h,f,i){function j(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(z.parent()&&z.remove(),c.val(a),a===""&&v.prop("selected",!0)):w(a)&&v?c.val(""):e.renderUnknownOption(a)};c.bind("change",function(){a.$apply(function(){z.parent()&&
+z.remove();d.$setViewValue(c.val())})})}function k(a,c,d){var e;d.$render=function(){var a=new Fa(d.$viewValue);m(c.find("option"),function(c){c.selected=y(a.get(c.value))})};a.$watch(function(){fa(e,d.$viewValue)||(e=U(d.$viewValue),d.$render())});c.bind("change",function(){a.$apply(function(){var a=[];m(c.find("option"),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}function l(e,f,g){function h(){var a={"":[]},c=[""],d,i,s,u,v;s=g.$modelValue;u=o(e)||[];var w=l?mb(u):u,y,x,z;x=
+{};v=!1;var B,E;p&&(v=new Fa(s));for(z=0;y=w.length,z<y;z++){x[k]=u[l?x[l]=w[z]:z];d=m(e,x)||"";if(!(i=a[d]))i=a[d]=[],c.push(d);p?d=v.remove(n(e,x))!=q:(d=s===n(e,x),v=v||d);B=j(e,x);B=B===q?"":B;i.push({id:l?w[z]:z,label:B,selected:d})}p||(t||s===null?a[""].unshift({id:"",label:"",selected:!v}):v||a[""].unshift({id:"?",label:"",selected:!0}));x=0;for(w=c.length;x<w;x++){d=c[x];i=a[d];if(r.length<=x)s={element:A.clone().attr("label",d),label:i.label},u=[s],r.push(u),f.append(s.element);else if(u=
+r[x],s=u[0],s.label!=d)s.element.attr("label",s.label=d);B=null;z=0;for(y=i.length;z<y;z++)if(d=i[z],v=u[z+1]){B=v.element;if(v.label!==d.label)B.text(v.label=d.label);if(v.id!==d.id)B.val(v.id=d.id);if(B[0].selected!==d.selected)B.prop("selected",v.selected=d.selected)}else d.id===""&&t?E=t:(E=C.clone()).val(d.id).attr("selected",d.selected).text(d.label),u.push({element:E,label:d.label,id:d.id,selected:d.selected}),B?B.after(E):s.element.append(E),B=E;for(z++;u.length>z;)u.pop().element.remove()}for(;r.length>
+x;)r.pop()[0].element.remove()}var i;if(!(i=s.match(d)))throw Error("Expected ngOptions in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '"+s+"'.");var j=c(i[2]||i[1]),k=i[4]||i[6],l=i[5],m=c(i[3]||""),n=c(i[2]?i[1]:k),o=c(i[7]),r=[[{element:f,label:""}]];t&&(a(t)(e),t.removeClass("ng-scope"),t.remove());f.html("");f.bind("change",function(){e.$apply(function(){var a,c=o(e)||[],d={},h,i,j,m,s,t;if(p){i=[];m=0;for(t=r.length;m<t;m++){a=r[m];j=1;for(s=a.length;j<s;j++)if((h=
+a[j].element)[0].selected)h=h.val(),l&&(d[l]=h),d[k]=c[h],i.push(n(e,d))}}else h=f.val(),h=="?"?i=q:h==""?i=null:(d[k]=c[h],l&&(d[l]=h),i=n(e,d));g.$setViewValue(i)})});g.$render=h;e.$watch(h)}if(i[1]){for(var n=i[0],o=i[1],p=f.multiple,s=f.ngOptions,t=!1,v,C=u(T.createElement("option")),A=u(T.createElement("optgroup")),z=C.clone(),i=0,B=h.children(),r=B.length;i<r;i++)if(B[i].value==""){v=t=B.eq(i);break}n.init(o,t,z);if(p&&(f.required||f.ngRequired)){var E=function(a){o.$setValidity("required",
+!f.required||a&&a.length);return a};o.$parsers.push(E);o.$formatters.unshift(E);f.$observe("required",function(){E(o.$viewValue)})}s?l(e,h,o):p?k(e,h,o):j(e,h,o,n)}}}}],Wd=["$interpolate",function(a){var c={addOption:C,removeOption:C};return{restrict:"E",priority:100,compile:function(d,e){if(w(e.value)){var g=a(d.text(),!0);g||e.$set("value",d.text())}return function(a,d,e){var j=d.parent(),k=j.data("$selectController")||j.parent().data("$selectController");k&&k.databound?d.prop("selected",!1):k=
+c;g?a.$watch(g,function(a,c){e.$set("value",a);a!==c&&k.removeOption(c);k.addOption(a)}):k.addOption(e.value);d.bind("$destroy",function(){k.removeOption(e.value)})}}}}],Xd=I({restrict:"E",terminal:!0});(ca=P.jQuery)?(u=ca,v(ca.fn,{scope:ua.scope,controller:ua.controller,injector:ua.injector,inheritedData:ua.inheritedData}),ab("remove",!0),ab("empty"),ab("html")):u=K;Ya.element=u;(function(a){v(a,{bootstrap:rb,copy:U,extend:v,equals:fa,element:u,forEach:m,injector:sb,noop:C,bind:Ta,toJson:da,fromJson:pb,
+identity:ma,isUndefined:w,isDefined:y,isString:B,isFunction:H,isObject:L,isNumber:Qa,isElement:gc,isArray:E,version:jd,isDate:na,lowercase:z,uppercase:la,callbacks:{counter:0}});sa=lc(P);try{sa("ngLocale")}catch(c){sa("ngLocale",[]).provider("$locale",$c)}sa("ng",["ngLocale"],["$provide",function(a){a.provider("$compile",Db).directive({a:kd,input:cc,textarea:cc,form:ld,script:Td,select:Vd,style:Xd,option:Wd,ngBind:wd,ngBindHtmlUnsafe:yd,ngBindTemplate:xd,ngClass:zd,ngClassEven:Bd,ngClassOdd:Ad,ngCsp:Ed,
+ngCloak:Cd,ngController:Dd,ngForm:md,ngHide:Md,ngInclude:Gd,ngInit:Hd,ngNonBindable:Id,ngPluralize:Jd,ngRepeat:Kd,ngShow:Ld,ngSubmit:Fd,ngStyle:Nd,ngSwitch:Od,ngSwitchWhen:Pd,ngSwitchDefault:Qd,ngOptions:Ud,ngView:Sd,ngTransclude:Rd,ngModel:rd,ngList:td,ngChange:sd,required:dc,ngRequired:dc,ngValue:vd}).directive(lb).directive(ec);a.provider({$anchorScroll:uc,$browser:wc,$cacheFactory:xc,$controller:Cc,$document:Dc,$exceptionHandler:Ec,$filter:Rb,$interpolate:Fc,$http:Wc,$httpBackend:Xc,$location:Jc,
+$log:Kc,$parse:Oc,$route:Rc,$routeParams:Sc,$rootScope:Tc,$q:Pc,$sniffer:Uc,$templateCache:yc,$timeout:ad,$window:Vc})}])})(Ya);u(T).ready(function(){jc(T,rb)})})(window,document);angular.element(document).find("head").append('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none;}ng\\:form{display:block;}</style>');

File diff suppressed because it is too large
+ 3 - 0
lib/rpc/test/public/js/jquery.min.js


+ 27 - 0
lib/rpc/test/public/rpc.html

@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html ng-app>
+<head>
+    <script src="/js/angular.min.js"></script>
+    <script src="/js/jquery.min.js"></script>
+    <script  src="/rpc/helper.js" type="text/javascript"></script>
+    <meta charset=utf-8 />
+    <title>JS Bin</title>
+</head>
+<body>
+
+
+<script type="text/javascript">
+
+    var rpc = new APIClient('/rpc');
+    rpc.add(10,20, function(err, data){
+        console.log('10+20='+data);
+    });
+    rpc.multiply(10,20, function(err, data){
+        console.log('10*20='+data);
+    });
+
+</script>
+
+
+</body>
+</html>

+ 2 - 0
lib/unzip/.npmignore

@@ -0,0 +1,2 @@
+/.idea
+/node_modules

+ 6 - 0
lib/unzip/.travis.yml

@@ -0,0 +1,6 @@
+language: node_js
+node_js:
+  - "0.11"
+  - "0.10"
+  - "0.8"
+

+ 20 - 0
lib/unzip/LICENSE

@@ -0,0 +1,20 @@
+Copyright (c) 2012 - 2013 Near Infinity Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 81 - 0
lib/unzip/README.md

@@ -0,0 +1,81 @@
+# unzip [![Build Status](https://travis-ci.org/EvanOxfeld/node-unzip.png)](https://travis-ci.org/EvanOxfeld/node-unzip)
+
+Streaming cross-platform unzip tool written in node.js.
+
+Unzip provides simple APIs similar to [node-tar](https://github.com/isaacs/node-tar) for parsing and extracting zip files.
+There are no added compiled dependencies - inflation is handled by node.js's built in zlib support.  Unzip is also an
+example use case of [node-pullstream](https://github.com/EvanOxfeld/node-pullstream).
+
+## Installation
+
+```bash
+$ npm install unzip
+```
+
+## Quick Examples
+
+### Extract to a directory
+```javascript
+fs.createReadStream('path/to/archive.zip').pipe(unzip.Extract({ path: 'output/path' }));
+```
+
+Extract emits the 'close' event once the zip's contents have been fully extracted to disk.
+
+### Parse zip file contents
+
+Process each zip file entry or pipe entries to another stream.
+
+__Important__: If you do not intend to consume an entry stream's raw data, call autodrain() to dispose of the entry's
+contents. Otherwise you risk running out of memory.
+
+```javascript
+fs.createReadStream('path/to/archive.zip')
+  .pipe(unzip.Parse())
+  .on('entry', function (entry) {
+    var fileName = entry.path;
+    var type = entry.type; // 'Directory' or 'File'
+    var size = entry.size;
+    if (fileName === "this IS the file I'm looking for") {
+      entry.pipe(fs.createWriteStream('output/path'));
+    } else {
+      entry.autodrain();
+    }
+  });
+```
+
+Or pipe the output of unzip.Parse() to fstream
+
+```javascript
+var readStream = fs.createReadStream('path/to/archive.zip');
+var writeStream = fstream.Writer('output/path');
+
+readStream
+  .pipe(unzip.Parse())
+  .pipe(writeStream)
+```
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2012 - 2013 Near Infinity Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+

+ 17 - 0
lib/unzip/lib/entry.js

@@ -0,0 +1,17 @@
+'use strict';
+
+module.exports = Entry;
+
+var PassThrough = require('readable-stream/passthrough');
+var inherits = require('util').inherits;
+
+inherits(Entry, PassThrough);
+
+function Entry () {
+  PassThrough.call(this);
+  this.props = {};
+}
+
+Entry.prototype.autodrain = function () {
+  this.on('readable', this.read.bind(this));
+};

+ 56 - 0
lib/unzip/lib/extract.js

@@ -0,0 +1,56 @@
+'use strict';
+
+module.exports = Extract;
+
+var Parse = require("../unzip").Parse;
+var Writer = require("fstream").Writer;
+var Writable = require('readable-stream/writable');
+var path = require('path');
+var inherits = require('util').inherits;
+
+inherits(Extract, Writable);
+
+function Extract (opts) {
+  var self = this;
+  if (!(this instanceof Extract)) {
+    return new Extract(opts);
+  }
+
+  Writable.apply(this);
+  this._opts = opts || { verbose: false };
+
+  this._parser = Parse(this._opts);
+  this._parser.on('error', function(err) {
+    self.emit('error', err);
+  });
+  this.on('finish', function() {
+    self._parser.end();
+  });
+
+  var writer = Writer({
+    type: 'Directory',
+    path: opts.path
+  });
+  writer.on('error', function(err) {
+    self.emit('error', err);
+  });
+  writer.on('close', function() {
+    self.emit('close')
+  });
+
+  this.on('pipe', function(source) {
+    if (opts.verbose && source.path) {
+      console.log('Archive: ', source.path);
+    }
+  });
+
+  this._parser.pipe(writer);
+}
+
+Extract.prototype._write = function (chunk, encoding, callback) {
+  if (this._parser.write(chunk)) {
+    return callback();
+  }
+
+  return this._parser.once('drain', callback);
+};

+ 320 - 0
lib/unzip/lib/parse.js

@@ -0,0 +1,320 @@
+'use strict';
+
+module.exports = Parse.create = Parse;
+
+require("setimmediate");
+var Transform = require('readable-stream/transform');
+var inherits = require('util').inherits;
+var zlib = require('zlib');
+var binary = require('binary');
+var PullStream = require('pullstream');
+var MatchStream = require('match-stream');
+var Entry = require('./entry');
+var iconv = require('iconv-lite');
+
+
+inherits(Parse, Transform);
+
+function Parse(opts) {
+    var self = this;
+    if (!(this instanceof Parse)) {
+        return new Parse(opts);
+    }
+
+    Transform.call(this, {lowWaterMark: 0});
+    this._opts = opts || {verbose: false};
+    this._hasEntryListener = false;
+
+    this._pullStream = new PullStream();
+    this._pullStream.on("error", function (e) {
+        self.emit('error', e);
+    });
+    this._pullStream.once("end", function () {
+        self._streamEnd = true;
+    });
+    this._pullStream.once("finish", function () {
+        self._streamFinish = true;
+    });
+
+    this._readRecord();
+}
+
+Parse.prototype._readRecord = function () {
+    var self = this;
+    this._pullStream.pull(4, function (err, data) {
+        if (err) {
+            return self.emit('error', err);
+        }
+
+        if (data.length === 0) {
+            return;
+        }
+
+        var signature = data.readUInt32LE(0);
+        if (signature === 0x04034b50) {
+            self._readFile();
+        } else if (signature === 0x02014b50) {
+            self._readCentralDirectoryFileHeader();
+        } else if (signature === 0x06054b50) {
+            self._readEndOfCentralDirectoryRecord();
+        } else {
+            err = new Error('invalid signature: 0x' + signature.toString(16));
+            self.emit('error', err);
+        }
+    });
+};
+
+Parse.prototype._readFile = function () {
+    var self = this;
+    this._pullStream.pull(26, function (err, data) {
+        if (err) {
+            return self.emit('error', err);
+        }
+
+        var vars = binary.parse(data)
+            .word16lu('versionsNeededToExtract')
+            .word16lu('flags')
+            .word16lu('compressionMethod')
+            .word16lu('lastModifiedTime')
+            .word16lu('lastModifiedDate')
+            .word32lu('crc32')
+            .word32lu('compressedSize')
+            .word32lu('uncompressedSize')
+            .word16lu('fileNameLength')
+            .word16lu('extraFieldLength')
+            .vars;
+
+        return self._pullStream.pull(vars.fileNameLength, function (err, fileName) {
+            if (err) {
+                return self.emit('error', err);
+            }
+            // FIXME 修复gbk文件压缩的bug,尤其是在win下压缩后解压的乱码问题
+            fileName = iconv.decode(fileName, 'gbk');//fileName.toString('utf-8');
+            fileName = iconv.encode(fileName, 'utf-8').toString('utf-8');
+            //console.log(fileName);
+
+            var entry = new Entry();
+            entry.path = fileName;
+            entry.props.path = fileName;
+            entry.type = (vars.compressedSize === 0 && /[\/\\]$/.test(fileName)) ? 'Directory' : 'File';
+
+            if (self._opts.verbose) {
+                if (entry.type === 'Directory') {
+                    console.log('   creating:', fileName);
+                } else if (entry.type === 'File') {
+                    if (vars.compressionMethod === 0) {
+                        console.log(' extracting:', fileName);
+                    } else {
+                        console.log('  inflating:', fileName);
+                    }
+                }
+            }
+
+            var hasEntryListener = self._hasEntryListener;
+            if (hasEntryListener) {
+                self.emit('entry', entry);
+            }
+
+            self._pullStream.pull(vars.extraFieldLength, function (err, extraField) {
+                if (err) {
+                    return self.emit('error', err);
+                }
+                if (vars.compressionMethod === 0) {
+                    self._pullStream.pull(vars.compressedSize, function (err, compressedData) {
+                        if (err) {
+                            return self.emit('error', err);
+                        }
+
+                        if (hasEntryListener) {
+                            entry.write(compressedData);
+                            entry.end();
+                        }
+
+                        return self._readRecord();
+                    });
+                } else {
+                    var fileSizeKnown = !(vars.flags & 0x08);
+
+                    var inflater = zlib.createInflateRaw();
+                    inflater.on('error', function (err) {
+                        self.emit('error', err);
+                    });
+
+                    if (fileSizeKnown) {
+                        entry.size = vars.uncompressedSize;
+                        if (hasEntryListener) {
+                            entry.on('finish', self._readRecord.bind(self));
+                            self._pullStream.pipe(vars.compressedSize, inflater).pipe(entry);
+                        } else {
+                            self._pullStream.drain(vars.compressedSize, function (err) {
+                                if (err) {
+                                    return self.emit('error', err);
+                                }
+                                self._readRecord();
+                            });
+                        }
+                    } else {
+                        var descriptorSig = new Buffer(4);
+                        descriptorSig.writeUInt32LE(0x08074b50, 0);
+
+                        var matchStream = new MatchStream({pattern: descriptorSig}, function (buf, matched, extra) {
+                            if (hasEntryListener) {
+                                if (!matched) {
+                                    return this.push(buf);
+                                }
+                                this.push(buf);
+                            }
+                            setImmediate(function () {
+                                self._pullStream.unpipe();
+                                self._pullStream.prepend(extra);
+                                self._processDataDescriptor(entry);
+                            });
+                            return this.push(null);
+                        });
+
+                        self._pullStream.pipe(matchStream);
+                        if (hasEntryListener) {
+                            matchStream.pipe(inflater).pipe(entry);
+                        }
+                    }
+                }
+            });
+        });
+    });
+};
+
+Parse.prototype._processDataDescriptor = function (entry) {
+    var self = this;
+    this._pullStream.pull(16, function (err, data) {
+        if (err) {
+            return self.emit('error', err);
+        }
+
+        var vars = binary.parse(data)
+            .word32lu('dataDescriptorSignature')
+            .word32lu('crc32')
+            .word32lu('compressedSize')
+            .word32lu('uncompressedSize')
+            .vars;
+
+        entry.size = vars.uncompressedSize;
+        self._readRecord();
+    });
+};
+
+Parse.prototype._readCentralDirectoryFileHeader = function () {
+    var self = this;
+    this._pullStream.pull(42, function (err, data) {
+        if (err) {
+            return self.emit('error', err);
+        }
+
+        var vars = binary.parse(data)
+            .word16lu('versionMadeBy')
+            .word16lu('versionsNeededToExtract')
+            .word16lu('flags')
+            .word16lu('compressionMethod')
+            .word16lu('lastModifiedTime')
+            .word16lu('lastModifiedDate')
+            .word32lu('crc32')
+            .word32lu('compressedSize')
+            .word32lu('uncompressedSize')
+            .word16lu('fileNameLength')
+            .word16lu('extraFieldLength')
+            .word16lu('fileCommentLength')
+            .word16lu('diskNumber')
+            .word16lu('internalFileAttributes')
+            .word32lu('externalFileAttributes')
+            .word32lu('offsetToLocalFileHeader')
+            .vars;
+
+        return self._pullStream.pull(vars.fileNameLength, function (err, fileName) {
+            if (err) {
+                return self.emit('error', err);
+            }
+            fileName = fileName.toString('utf8');
+
+            self._pullStream.pull(vars.extraFieldLength, function (err, extraField) {
+                if (err) {
+                    return self.emit('error', err);
+                }
+                self._pullStream.pull(vars.fileCommentLength, function (err, fileComment) {
+                    if (err) {
+                        return self.emit('error', err);
+                    }
+                    return self._readRecord();
+                });
+            });
+        });
+    });
+};
+
+Parse.prototype._readEndOfCentralDirectoryRecord = function () {
+    var self = this;
+    this._pullStream.pull(18, function (err, data) {
+        if (err) {
+            return self.emit('error', err);
+        }
+
+        var vars = binary.parse(data)
+            .word16lu('diskNumber')
+            .word16lu('diskStart')
+            .word16lu('numberOfRecordsOnDisk')
+            .word16lu('numberOfRecords')
+            .word32lu('sizeOfCentralDirectory')
+            .word32lu('offsetToStartOfCentralDirectory')
+            .word16lu('commentLength')
+            .vars;
+
+        if (vars.commentLength) {
+            setImmediate(function () {
+                self._pullStream.pull(vars.commentLength, function (err, comment) {
+                    if (err) {
+                        return self.emit('error', err);
+                    }
+                    comment = comment.toString('utf8');
+                    return self._pullStream.end();
+                });
+            });
+
+        } else {
+            self._pullStream.end();
+        }
+    });
+};
+
+Parse.prototype._transform = function (chunk, encoding, callback) {
+    if (this._pullStream.write(chunk)) {
+        return callback();
+    }
+
+    this._pullStream.once('drain', callback);
+};
+
+Parse.prototype.pipe = function (dest, opts) {
+    var self = this;
+    if (typeof dest.add === "function") {
+        self.on("entry", function (entry) {
+            dest.add(entry);
+        })
+    }
+    return Transform.prototype.pipe.apply(this, arguments);
+};
+
+Parse.prototype._flush = function (callback) {
+    if (!this._streamEnd || !this._streamFinish) {
+        return setImmediate(this._flush.bind(this, callback));
+    }
+
+    this.emit('close');
+    return callback();
+};
+
+Parse.prototype.addListener = function (type, listener) {
+    if ('entry' === type) {
+        this._hasEntryListener = true;
+    }
+    return Transform.prototype.addListener.call(this, type, listener);
+};
+
+Parse.prototype.on = Parse.prototype.addListener;

+ 1 - 0
lib/unzip/node_modules/binary/.npmignore

@@ -0,0 +1 @@
+node_modules

+ 4 - 0
lib/unzip/node_modules/binary/.travis.yml

@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+  - 0.4
+  - 0.6

+ 177 - 0
lib/unzip/node_modules/binary/README.markdown

@@ -0,0 +1,177 @@
+binary
+======
+
+Unpack multibyte binary values from buffers and streams.
+You can specify the endianness and signedness of the fields to be unpacked too.
+
+This module is a cleaner and more complete version of
+[bufferlist](https://github.com/substack/node-bufferlist)'s binary module that
+runs on pre-allocated buffers instead of a linked list.
+
+[![build status](https://secure.travis-ci.org/substack/node-binary.png)](http://travis-ci.org/substack/node-binary)
+
+examples
+========
+
+stream.js
+---------
+
+``` js
+var binary = require('binary');
+
+var ws = binary()
+    .word32lu('x')
+    .word16bs('y')
+    .word16bu('z')
+    .tap(function (vars) {
+        console.dir(vars);
+    })
+;
+process.stdin.pipe(ws);
+process.stdin.resume();
+```
+
+output:
+
+```
+$ node examples/stream.js
+abcdefgh
+{ x: 1684234849, y: 25958, z: 26472 }
+^D
+```
+
+parse.js
+--------
+
+``` js
+var buf = new Buffer([ 97, 98, 99, 100, 101, 102, 0 ]);
+
+var binary = require('binary');
+var vars = binary.parse(buf)
+    .word16ls('ab')
+    .word32bu('cf')
+    .word8('x')
+    .vars
+;
+console.dir(vars);
+```
+
+output:
+
+```
+{ ab: 25185, cf: 1667523942, x: 0 }
+```
+
+methods
+=======
+
+`var binary = require('binary')`
+
+var b = binary()
+----------------
+
+Return a new writable stream `b` that has the chainable methods documented below
+for buffering binary input.
+
+binary.parse(buf)
+-----------------
+
+Parse a static buffer in one pass. Returns a chainable interface with the
+methods below plus a `vars` field to get at the variable stash as the last item
+in a chain.
+
+In parse mode, methods will set their keys to `null` if the buffer isn't big
+enough except `buffer()` and `scan()` which read up up to the end of the buffer
+and stop.
+
+b.word{8,16,32,64}{l,b}{e,u,s}(key)
+-----------------------------------
+
+Parse bytes in the buffer or stream given:
+
+* number of bits
+* endianness ( l : little, b : big ),
+* signedness ( u and e : unsigned, s : signed )
+
+These functions won't start parsing until all previous parser functions have run
+and the data is available.
+
+The result of the parse goes into the variable stash at `key`.
+If `key` has dots (`.`s), it refers to a nested address. If parent container
+values don't exist they will be created automatically, so for instance you can
+assign into `dst.addr` and `dst.port` and the `dst` key in the variable stash
+will be `{ addr : x, port : y }` afterwards.
+
+b.buffer(key, size)
+-------------------
+
+Take `size` bytes directly off the buffer stream, putting the resulting buffer
+slice in the variable stash at `key`. If `size` is a string, use the value at
+`vars[size]`. The key follows the same dotted address rules as the word
+functions.
+
+b.scan(key, buffer)
+-------------------
+
+Search for `buffer` in the stream and store all the intervening data in the
+stash at at `key`, excluding the search buffer. If `buffer` passed as a string,
+it will be converted into a Buffer internally.
+
+For example, to read in a line you can just do:
+
+``` js
+var b = binary()
+    .scan('line', new Buffer('\r\n'))
+    .tap(function (vars) {
+        console.log(vars.line)
+    })
+;
+stream.pipe(b);
+```
+
+b.tap(cb)
+---------
+
+The callback `cb` is provided with the variable stash from all the previous
+actions once they've all finished.
+
+You can nest additional actions onto `this` inside the callback.
+
+b.into(key, cb)
+---------------
+
+Like `.tap()`, except all nested actions will assign into a `key` in the `vars`
+stash.
+
+b.loop(cb)
+----------
+
+Loop, each time calling `cb(end, vars)` for function `end` and the variable
+stash with `this` set to a new chain for nested parsing. The loop terminates
+once `end` is called.
+
+b.flush()
+---------
+
+Clear the variable stash entirely.
+
+installation
+============
+
+To install with [npm](http://github.com/isaacs/npm):
+
+```
+npm install binary
+```
+
+notes
+=====
+
+The word64 functions will only return approximations since javascript uses ieee
+floating point for all number types. Mind the loss of precision.
+
+license
+=======
+
+MIT
+

+ 11 - 0
lib/unzip/node_modules/binary/example/buf.js

@@ -0,0 +1,11 @@
+var buf = new Buffer([ 97, 98, 99, 100, 101, 102, 0 ]);
+
+var binary = require('binary');
+binary(buf)
+    .word16ls('ab')
+    .word32bu('cf')
+    .word8('x')
+    .tap(function (vars) {
+        console.dir(vars);
+    })
+;

+ 10 - 0
lib/unzip/node_modules/binary/example/parse.js

@@ -0,0 +1,10 @@
+var buf = new Buffer([ 97, 98, 99, 100, 101, 102, 0 ]);
+
+var binary = require('binary');
+var vars = binary.parse(buf)
+    .word16ls('ab')
+    .word32bu('cf')
+    .word8('x')
+    .vars
+;
+console.dir(vars);

+ 12 - 0
lib/unzip/node_modules/binary/example/stream.js

@@ -0,0 +1,12 @@
+var binary = require('binary');
+
+var ws = binary()
+    .word32lu('x')
+    .word16bs('y')
+    .word16bu('z')
+    .tap(function (vars) {
+        console.dir(vars);
+    })
+;
+process.stdin.pipe(ws);
+process.stdin.resume();

+ 397 - 0
lib/unzip/node_modules/binary/index.js

@@ -0,0 +1,397 @@
+var Chainsaw = require('chainsaw');
+var EventEmitter = require('events').EventEmitter;
+var Buffers = require('buffers');
+var Vars = require('./lib/vars.js');
+var Stream = require('stream').Stream;
+
+exports = module.exports = function (bufOrEm, eventName) {
+    if (Buffer.isBuffer(bufOrEm)) {
+        return exports.parse(bufOrEm);
+    }
+    
+    var s = exports.stream();
+    if (bufOrEm && bufOrEm.pipe) {
+        bufOrEm.pipe(s);
+    }
+    else if (bufOrEm) {
+        bufOrEm.on(eventName || 'data', function (buf) {
+            s.write(buf);
+        });
+        
+        bufOrEm.on('end', function () {
+            s.end();
+        });
+    }
+    return s;
+};
+
+exports.stream = function (input) {
+    if (input) return exports.apply(null, arguments);
+    
+    var pending = null;
+    function getBytes (bytes, cb, skip) {
+        pending = {
+            bytes : bytes,
+            skip : skip,
+            cb : function (buf) {
+                pending = null;
+                cb(buf);
+            },
+        };
+        dispatch();
+    }
+    
+    var offset = null;
+    function dispatch () {
+        if (!pending) {
+            if (caughtEnd) done = true;
+            return;
+        }
+        if (typeof pending === 'function') {
+            pending();
+        }
+        else {
+            var bytes = offset + pending.bytes;
+            
+            if (buffers.length >= bytes) {
+                var buf;
+                if (offset == null) {
+                    buf = buffers.splice(0, bytes);
+                    if (!pending.skip) {
+                        buf = buf.slice();
+                    }
+                }
+                else {
+                    if (!pending.skip) {
+                        buf = buffers.slice(offset, bytes);
+                    }
+                    offset = bytes;
+                }
+                
+                if (pending.skip) {
+                    pending.cb();
+                }
+                else {
+                    pending.cb(buf);
+                }
+            }
+        }
+    }
+    
+    function builder (saw) {
+        function next () { if (!done) saw.next() }
+        
+        var self = words(function (bytes, cb) {
+            return function (name) {
+                getBytes(bytes, function (buf) {
+                    vars.set(name, cb(buf));
+                    next();
+                });
+            };
+        });
+        
+        self.tap = function (cb) {
+            saw.nest(cb, vars.store);
+        };
+        
+        self.into = function (key, cb) {
+            if (!vars.get(key)) vars.set(key, {});
+            var parent = vars;
+            vars = Vars(parent.get(key));
+            
+            saw.nest(function () {
+                cb.apply(this, arguments);
+                this.tap(function () {
+                    vars = parent;
+                });
+            }, vars.store);
+        };
+        
+        self.flush = function () {
+            vars.store = {};
+            next();
+        };
+        
+        self.loop = function (cb) {
+            var end = false;
+            
+            saw.nest(false, function loop () {
+                this.vars = vars.store;
+                cb.call(this, function () {
+                    end = true;
+                    next();
+                }, vars.store);
+                this.tap(function () {
+                    if (end) saw.next()
+                    else loop.call(this)
+                }.bind(this));
+            }, vars.store);
+        };
+        
+        self.buffer = function (name, bytes) {
+            if (typeof bytes === 'string') {
+                bytes = vars.get(bytes);
+            }
+            
+            getBytes(bytes, function (buf) {
+                vars.set(name, buf);
+                next();
+            });
+        };
+        
+        self.skip = function (bytes) {
+            if (typeof bytes === 'string') {
+                bytes = vars.get(bytes);
+            }
+            
+            getBytes(bytes, function () {
+                next();
+            });
+        };
+        
+        self.scan = function find (name, search) {
+            if (typeof search === 'string') {
+                search = new Buffer(search);
+            }
+            else if (!Buffer.isBuffer(search)) {
+                throw new Error('search must be a Buffer or a string');
+            }
+            
+            var taken = 0;
+            pending = function () {
+                var pos = buffers.indexOf(search, offset + taken);
+                var i = pos-offset-taken;
+                if (pos !== -1) {
+                    pending = null;
+                    if (offset != null) {
+                        vars.set(
+                            name,
+                            buffers.slice(offset, offset + taken + i)
+                        );
+                        offset += taken + i + search.length;
+                    }
+                    else {
+                        vars.set(
+                            name,
+                            buffers.slice(0, taken + i)
+                        );
+                        buffers.splice(0, taken + i + search.length);
+                    }
+                    next();
+                    dispatch();
+                } else {
+                    i = Math.max(buffers.length - search.length - offset - taken, 0);
+				}
+                taken += i;
+            };
+            dispatch();
+        };
+        
+        self.peek = function (cb) {
+            offset = 0;
+            saw.nest(function () {
+                cb.call(this, vars.store);
+                this.tap(function () {
+                    offset = null;
+                });
+            });
+        };
+        
+        return self;
+    };
+    
+    var stream = Chainsaw.light(builder);
+    stream.writable = true;
+    
+    var buffers = Buffers();
+    
+    stream.write = function (buf) {
+        buffers.push(buf);
+        dispatch();
+    };
+    
+    var vars = Vars();
+    
+    var done = false, caughtEnd = false;
+    stream.end = function () {
+        caughtEnd = true;
+    };
+    
+    stream.pipe = Stream.prototype.pipe;
+    Object.getOwnPropertyNames(EventEmitter.prototype).forEach(function (name) {
+        stream[name] = EventEmitter.prototype[name];
+    });
+    
+    return stream;
+};
+
+exports.parse = function parse (buffer) {
+    var self = words(function (bytes, cb) {
+        return function (name) {
+            if (offset + bytes <= buffer.length) {
+                var buf = buffer.slice(offset, offset + bytes);
+                offset += bytes;
+                vars.set(name, cb(buf));
+            }
+            else {
+                vars.set(name, null);
+            }
+            return self;
+        };
+    });
+    
+    var offset = 0;
+    var vars = Vars();
+    self.vars = vars.store;
+    
+    self.tap = function (cb) {
+        cb.call(self, vars.store);
+        return self;
+    };
+    
+    self.into = function (key, cb) {
+        if (!vars.get(key)) {
+            vars.set(key, {});
+        }
+        var parent = vars;
+        vars = Vars(parent.get(key));
+        cb.call(self, vars.store);
+        vars = parent;
+        return self;
+    };
+    
+    self.loop = function (cb) {
+        var end = false;
+        var ender = function () { end = true };
+        while (end === false) {
+            cb.call(self, ender, vars.store);
+        }
+        return self;
+    };
+    
+    self.buffer = function (name, size) {
+        if (typeof size === 'string') {
+            size = vars.get(size);
+        }
+        var buf = buffer.slice(offset, Math.min(buffer.length, offset + size));
+        offset += size;
+        vars.set(name, buf);
+        
+        return self;
+    };
+    
+    self.skip = function (bytes) {
+        if (typeof bytes === 'string') {
+            bytes = vars.get(bytes);
+        }
+        offset += bytes;
+        
+        return self;
+    };
+    
+    self.scan = function (name, search) {
+        if (typeof search === 'string') {
+            search = new Buffer(search);
+        }
+        else if (!Buffer.isBuffer(search)) {
+            throw new Error('search must be a Buffer or a string');
+        }
+        vars.set(name, null);
+        
+        // simple but slow string search
+        for (var i = 0; i + offset <= buffer.length - search.length + 1; i++) {
+            for (
+                var j = 0;
+                j < search.length && buffer[offset+i+j] === search[j];
+                j++
+            );
+            if (j === search.length) break;
+        }
+        
+        vars.set(name, buffer.slice(offset, offset + i));
+        offset += i + search.length;
+        return self;
+    };
+    
+    self.peek = function (cb) {
+        var was = offset;
+        cb.call(self, vars.store);
+        offset = was;
+        return self;
+    };
+    
+    self.flush = function () {
+        vars.store = {};
+        return self;
+    };
+    
+    self.eof = function () {
+        return offset >= buffer.length;
+    };
+    
+    return self;
+};
+
+// convert byte strings to unsigned little endian numbers
+function decodeLEu (bytes) {
+    var acc = 0;
+    for (var i = 0; i < bytes.length; i++) {
+        acc += Math.pow(256,i) * bytes[i];
+    }
+    return acc;
+}
+
+// convert byte strings to unsigned big endian numbers
+function decodeBEu (bytes) {
+    var acc = 0;
+    for (var i = 0; i < bytes.length; i++) {
+        acc += Math.pow(256, bytes.length - i - 1) * bytes[i];
+    }
+    return acc;
+}
+
+// convert byte strings to signed big endian numbers
+function decodeBEs (bytes) {
+    var val = decodeBEu(bytes);
+    if ((bytes[0] & 0x80) == 0x80) {
+        val -= Math.pow(256, bytes.length);
+    }
+    return val;
+}
+
+// convert byte strings to signed little endian numbers
+function decodeLEs (bytes) {
+    var val = decodeLEu(bytes);
+    if ((bytes[bytes.length - 1] & 0x80) == 0x80) {
+        val -= Math.pow(256, bytes.length);
+    }
+    return val;
+}
+
+function words (decode) {
+    var self = {};
+    
+    [ 1, 2, 4, 8 ].forEach(function (bytes) {
+        var bits = bytes * 8;
+        
+        self['word' + bits + 'le']
+        = self['word' + bits + 'lu']
+        = decode(bytes, decodeLEu);
+        
+        self['word' + bits + 'ls']
+        = decode(bytes, decodeLEs);
+        
+        self['word' + bits + 'be']
+        = self['word' + bits + 'bu']
+        = decode(bytes, decodeBEu);
+        
+        self['word' + bits + 'bs']
+        = decode(bytes, decodeBEs);
+    });
+    
+    // word8be(n) == word8le(n) for all n
+    self.word8 = self.word8u = self.word8be;
+    self.word8s = self.word8bs;
+    
+    return self;
+}

+ 28 - 0
lib/unzip/node_modules/binary/lib/vars.js

@@ -0,0 +1,28 @@
+module.exports = function (store) {
+    function getset (name, value) {
+        var node = vars.store;
+        var keys = name.split('.');
+        keys.slice(0,-1).forEach(function (k) {
+            if (node[k] === undefined) node[k] = {};
+            node = node[k]
+        });
+        var key = keys[keys.length - 1];
+        if (arguments.length == 1) {
+            return node[key];
+        }
+        else {
+            return node[key] = value;
+        }
+    }
+    
+    var vars = {
+        get : function (name) {
+            return getset(name);
+        },
+        set : function (name, value) {
+            return getset(name, value);
+        },
+        store : store || {},
+    };
+    return vars;
+};

+ 122 - 0
lib/unzip/node_modules/binary/node_modules/buffers/README.markdown

@@ -0,0 +1,122 @@
+buffers
+=======
+
+Treat a collection of Buffers as a single contiguous partially mutable Buffer.
+
+Where possible, operations execute without creating a new Buffer and copying
+everything over.
+
+This is a cleaner more Buffery rehash of
+[bufferlist](http://github.com/substack/node-bufferlist).
+
+example
+=======
+
+slice
+-----
+
+    var Buffers = require('buffers');
+    var bufs = Buffers();
+    bufs.push(new Buffer([1,2,3]));
+    bufs.push(new Buffer([4,5,6,7]));
+    bufs.push(new Buffer([8,9,10]));
+    
+    console.dir(bufs.slice(2,8))
+
+output:
+
+    $ node examples/slice.js 
+    <Buffer 03 04 05 06 07 08>
+
+splice
+------
+
+    var Buffers = require('buffers');
+    var bufs = Buffers([
+        new Buffer([1,2,3]),
+        new Buffer([4,5,6,7]),
+        new Buffer([8,9,10]),
+    ]);
+    
+    var removed = bufs.splice(2, 4);
+    console.dir({
+        removed : removed.slice(),
+        bufs : bufs.slice(),
+    });
+    
+output:
+
+    $ node examples/splice.js
+    { removed: <Buffer 03 04 05 06>,
+      bufs: <Buffer 01 02 07 08 09 0a> }
+
+methods
+=======
+
+Buffers(buffers)
+----------------
+
+Create a Buffers with an array of `Buffer`s if specified, else `[]`.
+
+.push(buf1, buf2...)
+--------------------
+
+Push buffers onto the end. Just like `Array.prototype.push`.
+
+.unshift(buf1, buf2...)
+-----------------------
+
+Unshift buffers onto the head. Just like `Array.prototype.unshift`.
+
+.slice(i, j)
+------------
+
+Slice a range out of the buffer collection as if it were contiguous.
+Works just like the `Array.prototype.slice` version.
+
+.splice(i, howMany, replacements)
+---------------------------------
+
+Splice the buffer collection as if it were contiguous.
+Works just like `Array.prototype.splice`, even the replacement part!
+
+.copy(dst, dstStart, start, end)
+--------------------------------
+
+Copy the buffer collection as if it were contiguous to the `dst` Buffer with the
+specified bounds.
+Works just like `Buffer.prototype.copy`.
+
+.get(i)
+-------
+
+Get a single element at index `i`.
+
+.set(i, x)
+----------
+
+Set a single element's value at index `i`.
+
+.indexOf(needle, offset)
+----------
+
+Find a string or buffer `needle` inside the buffer collection. Returns
+the position of the search string or -1 if the search string was not
+found.
+
+Provide an `offset` to skip that number of characters at the beginning
+of the search. This can be used to find additional matches.
+
+This function will return the correct result even if the search string
+is spread out over multiple internal buffers.
+
+.toBuffer()
+-----------
+
+Convert the buffer collection to a single buffer, equivalent with `.slice(0, buffers.length)`;
+
+.toString(encoding, start, end)
+-----------
+
+Decodes and returns a string from the buffer collection.
+Works just like `Buffer.prototype.toString`

+ 9 - 0
lib/unzip/node_modules/binary/node_modules/buffers/examples/slice.js

@@ -0,0 +1,9 @@
+var Buffers = require('buffers');
+var bufs = Buffers();
+bufs.push(new Buffer([1,2,3]));
+bufs.push(new Buffer([4,5,6,7]));
+bufs.push(new Buffer([8,9,10]));
+
+console.dir(bufs.slice(2,8))
+
+// Output: <Buffer 03 04 05 06 07 08>

+ 17 - 0
lib/unzip/node_modules/binary/node_modules/buffers/examples/splice.js

@@ -0,0 +1,17 @@
+var Buffers = require('buffers');
+var bufs = Buffers([
+    new Buffer([1,2,3]),
+    new Buffer([4,5,6,7]),
+    new Buffer([8,9,10]),
+]);
+
+var removed = bufs.splice(2, 4, new Buffer('ab'), new Buffer('cd'));
+console.dir({
+    removed : removed.slice(),
+    bufs : bufs.slice(),
+});
+
+/* Output:
+{ removed: <Buffer 03 04 05 06>,
+  bufs: <Buffer 01 02 07 08 09 0a> }
+*/

+ 269 - 0
lib/unzip/node_modules/binary/node_modules/buffers/index.js

@@ -0,0 +1,269 @@
+module.exports = Buffers;
+
+function Buffers (bufs) {
+    if (!(this instanceof Buffers)) return new Buffers(bufs);
+    this.buffers = bufs || [];
+    this.length = this.buffers.reduce(function (size, buf) {
+        return size + buf.length
+    }, 0);
+}
+
+Buffers.prototype.push = function () {
+    for (var i = 0; i < arguments.length; i++) {
+        if (!Buffer.isBuffer(arguments[i])) {
+            throw new TypeError('Tried to push a non-buffer');
+        }
+    }
+    
+    for (var i = 0; i < arguments.length; i++) {
+        var buf = arguments[i];
+        this.buffers.push(buf);
+        this.length += buf.length;
+    }
+    return this.length;
+};
+
+Buffers.prototype.unshift = function () {
+    for (var i = 0; i < arguments.length; i++) {
+        if (!Buffer.isBuffer(arguments[i])) {
+            throw new TypeError('Tried to unshift a non-buffer');
+        }
+    }
+    
+    for (var i = 0; i < arguments.length; i++) {
+        var buf = arguments[i];
+        this.buffers.unshift(buf);
+        this.length += buf.length;
+    }
+    return this.length;
+};
+
+Buffers.prototype.copy = function (dst, dStart, start, end) {
+    return this.slice(start, end).copy(dst, dStart, 0, end - start);
+};
+
+Buffers.prototype.splice = function (i, howMany) {
+    var buffers = this.buffers;
+    var index = i >= 0 ? i : this.length - i;
+    var reps = [].slice.call(arguments, 2);
+    
+    if (howMany === undefined) {
+        howMany = this.length - index;
+    }
+    else if (howMany > this.length - index) {
+        howMany = this.length - index;
+    }
+    
+    for (var i = 0; i < reps.length; i++) {
+        this.length += reps[i].length;
+    }
+    
+    var removed = new Buffers();
+    var bytes = 0;
+    
+    var startBytes = 0;
+    for (
+        var ii = 0;
+        ii < buffers.length && startBytes + buffers[ii].length < index;
+        ii ++
+    ) { startBytes += buffers[ii].length }
+    
+    if (index - startBytes > 0) {
+        var start = index - startBytes;
+        
+        if (start + howMany < buffers[ii].length) {
+            removed.push(buffers[ii].slice(start, start + howMany));
+            
+            var orig = buffers[ii];
+            //var buf = new Buffer(orig.length - howMany);
+            var buf0 = new Buffer(start);
+            for (var i = 0; i < start; i++) {
+                buf0[i] = orig[i];
+            }
+            
+            var buf1 = new Buffer(orig.length - start - howMany);
+            for (var i = start + howMany; i < orig.length; i++) {
+                buf1[ i - howMany - start ] = orig[i]
+            }
+            
+            if (reps.length > 0) {
+                var reps_ = reps.slice();
+                reps_.unshift(buf0);
+                reps_.push(buf1);
+                buffers.splice.apply(buffers, [ ii, 1 ].concat(reps_));
+                ii += reps_.length;
+                reps = [];
+            }
+            else {
+                buffers.splice(ii, 1, buf0, buf1);
+                //buffers[ii] = buf;
+                ii += 2;
+            }
+        }
+        else {
+            removed.push(buffers[ii].slice(start));
+            buffers[ii] = buffers[ii].slice(0, start);
+            ii ++;
+        }
+    }
+    
+    if (reps.length > 0) {
+        buffers.splice.apply(buffers, [ ii, 0 ].concat(reps));
+        ii += reps.length;
+    }
+    
+    while (removed.length < howMany) {
+        var buf = buffers[ii];
+        var len = buf.length;
+        var take = Math.min(len, howMany - removed.length);
+        
+        if (take === len) {
+            removed.push(buf);
+            buffers.splice(ii, 1);
+        }
+        else {
+            removed.push(buf.slice(0, take));
+            buffers[ii] = buffers[ii].slice(take);
+        }
+    }
+    
+    this.length -= removed.length;
+    
+    return removed;
+};
+ 
+Buffers.prototype.slice = function (i, j) {
+    var buffers = this.buffers;
+    if (j === undefined) j = this.length;
+    if (i === undefined) i = 0;
+    
+    if (j > this.length) j = this.length;
+    
+    var startBytes = 0;
+    for (
+        var si = 0;
+        si < buffers.length && startBytes + buffers[si].length <= i;
+        si ++
+    ) { startBytes += buffers[si].length }
+    
+    var target = new Buffer(j - i);
+    
+    var ti = 0;
+    for (var ii = si; ti < j - i && ii < buffers.length; ii++) {
+        var len = buffers[ii].length;
+        
+        var start = ti === 0 ? i - startBytes : 0;
+        var end = ti + len >= j - i
+            ? Math.min(start + (j - i) - ti, len)
+            : len
+        ;
+        
+        buffers[ii].copy(target, ti, start, end);
+        ti += end - start;
+    }
+    
+    return target;
+};
+
+Buffers.prototype.pos = function (i) {
+    if (i < 0 || i >= this.length) throw new Error('oob');
+    var l = i, bi = 0, bu = null;
+    for (;;) {
+        bu = this.buffers[bi];
+        if (l < bu.length) {
+            return {buf: bi, offset: l};
+        } else {
+            l -= bu.length;
+        }
+        bi++;
+    }
+};
+
+Buffers.prototype.get = function get (i) {
+    var pos = this.pos(i);
+
+    return this.buffers[pos.buf].get(pos.offset);
+};
+
+Buffers.prototype.set = function set (i, b) {
+    var pos = this.pos(i);
+
+    return this.buffers[pos.buf].set(pos.offset, b);
+};
+
+Buffers.prototype.indexOf = function (needle, offset) {
+    if ("string" === typeof needle) {
+        needle = new Buffer(needle);
+    } else if (needle instanceof Buffer) {
+        // already a buffer
+    } else {
+        throw new Error('Invalid type for a search string');
+    }
+
+    if (!needle.length) {
+        return 0;
+    }
+
+    if (!this.length) {
+        return -1;
+    }
+
+    var i = 0, j = 0, match = 0, mstart, pos = 0;
+
+    // start search from a particular point in the virtual buffer
+    if (offset) {
+        var p = this.pos(offset);
+        i = p.buf;
+        j = p.offset;
+        pos = offset;
+    }
+
+    // for each character in virtual buffer
+    for (;;) {
+        while (j >= this.buffers[i].length) {
+            j = 0;
+            i++;
+
+            if (i >= this.buffers.length) {
+                // search string not found
+                return -1;
+            }
+        }
+
+        var char = this.buffers[i][j];
+
+        if (char == needle[match]) {
+            // keep track where match started
+            if (match == 0) {
+                mstart = {
+                    i: i,
+                    j: j,
+                    pos: pos
+                };
+            }
+            match++;
+            if (match == needle.length) {
+                // full match
+                return mstart.pos;
+            }
+        } else if (match != 0) {
+            // a partial match ended, go back to match starting position
+            // this will continue the search at the next character
+            i = mstart.i;
+            j = mstart.j;
+            pos = mstart.pos;
+            match = 0;
+        }
+
+        j++;
+        pos++;
+    }
+};
+
+Buffers.prototype.toBuffer = function() {
+    return this.slice();
+}
+
+Buffers.prototype.toString = function(encoding, start, end) {
+    return this.slice(start, end).toString(encoding);
+}

File diff suppressed because it is too large
+ 20 - 0
lib/unzip/node_modules/binary/node_modules/buffers/package.json


+ 209 - 0
lib/unzip/node_modules/binary/node_modules/buffers/test/buffers.js

@@ -0,0 +1,209 @@
+var assert = require('assert');
+var Buffers = require('../');
+
+function create (xs, split) {
+    var bufs = Buffers();
+    var offset = 0;
+    split.forEach(function (i) {
+        bufs.push(new Buffer(xs.slice(offset, offset + i)));
+        offset += i;
+    });
+    return bufs;
+}
+
+exports.slice = function () {
+    var xs = [0,1,2,3,4,5,6,7,8,9];
+    var splits = [ [4,2,3,1], [2,2,2,2,2], [1,6,3,1], [9,2], [10], [5,5] ];
+    
+    splits.forEach(function (split) {
+        var bufs = create(xs, split);
+        assert.eql(new Buffer(xs), bufs.slice(),
+            '[' + xs.join(',') + ']'
+                + ' != ' + 
+            '[' + [].join.call(bufs.slice(), ',') + ']'
+        );
+        
+        for (var i = 0; i < xs.length; i++) {
+            for (var j = i; j < xs.length; j++) {
+                var a = bufs.slice(i,j);
+                var b = new Buffer(xs.slice(i,j));
+                
+                assert.eql(a, b,
+                    '[' + [].join.call(a, ',') + ']'
+                        + ' != ' + 
+                    '[' + [].join.call(b, ',') + ']'
+                );
+            }
+        }
+    });
+};
+
+exports.splice = function () {
+    var xs = [0,1,2,3,4,5,6,7,8,9];
+    var splits = [ [4,2,3,1], [2,2,2,2,2], [1,6,3,1], [9,2], [10], [5,5] ];
+    
+    splits.forEach(function (split) {
+        for (var i = 0; i < xs.length; i++) {
+            for (var j = i; j < xs.length; j++) {
+                var bufs = create(xs, split);
+                var xs_ = xs.slice();
+                
+                var a_ = bufs.splice(i,j);
+                var a = [].slice.call(a_.slice());
+                var b = xs_.splice(i,j);
+                assert.eql(a, b,
+                    '[' + a.join(',') + ']'
+                        + ' != ' + 
+                    '[' + b.join(',') + ']'
+                );
+                
+                assert.eql(bufs.slice(), new Buffer(xs_),
+                    '[' + [].join.call(bufs.slice(), ',') + ']'
+                        + ' != ' + 
+                    '[' + [].join.call(xs_, ',') + ']'
+                );
+            }
+        }
+    });
+};
+
+exports.spliceRep = function () {
+    var xs = [0,1,2,3,4,5,6,7,8,9];
+    var splits = [ [4,2,3,1], [2,2,2,2,2], [1,6,3,1], [9,2], [10], [5,5] ];
+    var reps = [ [], [1], [5,6], [3,1,3,3,7], [9,8,7,6,5,4,3,2,1,2,3,4,5] ];
+    
+    splits.forEach(function (split) {
+        reps.forEach(function (rep) {
+            for (var i = 0; i < xs.length; i++) {
+                for (var j = i; j < xs.length; j++) {
+                    var bufs = create(xs, split);
+                    var xs_ = xs.slice();
+                    
+                    var a_ = bufs.splice.apply(
+                        bufs, [ i, j ].concat(new Buffer(rep))
+                    );
+                    var a = [].slice.call(a_.slice());
+                    var b = xs_.splice.apply(xs_, [ i, j ].concat(rep));
+                    
+                    assert.eql(a, b,
+                        '[' + a.join(',') + ']'
+                            + ' != ' + 
+                        '[' + b.join(',') + ']'
+                    );
+                    
+                    assert.eql(bufs.slice(), new Buffer(xs_),
+                        '[' + [].join.call(bufs.slice(), ',') + ']'
+                            + ' != ' + 
+                        '[' + [].join.call(xs_, ',') + ']'
+                    );
+                }
+            }
+        });
+    });
+}; 
+
+exports.copy = function () {
+    var xs = [0,1,2,3,4,5,6,7,8,9];
+    var splits = [ [4,2,3,1], [2,2,2,2,2], [1,6,3,1], [9,2], [10], [5,5] ];
+    
+    splits.forEach(function (split) {
+        var bufs = create(xs, split);
+        var buf = new Buffer(xs);
+        
+        for (var i = 0; i < xs.length; i++) {
+            for (var j = i; j < xs.length; j++) {
+                var t0 = new Buffer(j - i);
+                var t1 = new Buffer(j - i);
+                
+                assert.eql(
+                    bufs.copy(t0, 0, i, j),
+                    buf.copy(t1, 0, i, j)
+                );
+                
+                assert.eql(
+                    [].slice.call(t0),
+                    [].slice.call(t1)
+                );
+            }
+        }
+    });
+};
+
+exports.push = function () {
+    var bufs = Buffers();
+    bufs.push(new Buffer([0]));
+    bufs.push(new Buffer([1,2,3]));
+    bufs.push(new Buffer([4,5]));
+    bufs.push(new Buffer([6,7,8,9]));
+    assert.eql(
+        [].slice.call(bufs.slice()),
+        [0,1,2,3,4,5,6,7,8,9]
+    );
+    
+    assert.throws(function () {
+        bufs.push(new Buffer([11,12]), 'moo');
+    });
+    assert.eql(bufs.buffers.length, 4);
+};
+
+exports.unshift = function () {
+    var bufs = Buffers();
+    bufs.unshift(new Buffer([6,7,8,9]));
+    bufs.unshift(new Buffer([4,5]));
+    bufs.unshift(new Buffer([1,2,3]));
+    bufs.unshift(new Buffer([0]));
+    assert.eql(
+        [].slice.call(bufs.slice()),
+        [0,1,2,3,4,5,6,7,8,9]
+    );
+    assert.throws(function () {
+        bufs.unshift(new Buffer([-2,-1]), 'moo');
+    });
+    assert.eql(bufs.buffers.length, 4);
+};
+
+exports.get = function () {
+    var bufs = Buffers();
+    bufs.unshift(new Buffer([6,7,8,9]));
+    bufs.unshift(new Buffer([4,5]));
+    bufs.unshift(new Buffer([1,2,3]));
+    bufs.unshift(new Buffer([0]));
+    assert.eql( bufs.get(0), 0 );
+    assert.eql( bufs.get(1), 1 );
+    assert.eql( bufs.get(2), 2 );
+    assert.eql( bufs.get(3), 3 );
+    assert.eql( bufs.get(4), 4 );
+    assert.eql( bufs.get(5), 5 );
+    assert.eql( bufs.get(6), 6 );
+    assert.eql( bufs.get(7), 7 );
+    assert.eql( bufs.get(8), 8 );
+    assert.eql( bufs.get(9), 9 );
+};
+
+exports.set = function () {
+    var bufs = Buffers();
+    bufs.push(new Buffer("Hel"));
+    bufs.push(new Buffer("lo"));
+    bufs.push(new Buffer("!"));
+    bufs.set(0, 'h'.charCodeAt(0) );
+    bufs.set(3, 'L'.charCodeAt(0) );
+    bufs.set(5, '.'.charCodeAt(0) );
+    assert.eql( bufs.slice(0).toString(), 'helLo.' );
+};
+
+exports.indexOf = function () {
+    var bufs = Buffers();
+    bufs.push(new Buffer("Hel"));
+    bufs.push(new Buffer("lo,"));
+    bufs.push(new Buffer(" how are "));
+    bufs.push(new Buffer("you"));
+    bufs.push(new Buffer("?"));
+    assert.eql( bufs.indexOf("Hello"), 0 );
+    assert.eql( bufs.indexOf("Hello", 1), -1 );
+    assert.eql( bufs.indexOf("ello"), 1 );
+    assert.eql( bufs.indexOf("ello", 1), 1 );
+    assert.eql( bufs.indexOf("ello", 2), -1 );
+    assert.eql( bufs.indexOf("e"), 1 );
+    assert.eql( bufs.indexOf("e", 2), 13 );
+    assert.eql( bufs.indexOf(new Buffer([0x65]), 2), 13 );
+};

+ 1 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/.npmignore

@@ -0,0 +1 @@
+node_modules

+ 157 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/README.markdown

@@ -0,0 +1,157 @@
+Chainsaw
+========
+
+Build chainable fluent interfaces the easy way in node.js.
+
+With this meta-module you can write modules with chainable interfaces.
+Chainsaw takes care of all of the boring details and makes nested flow control
+super simple too.
+
+Just call `Chainsaw` with a constructor function like in the examples below.
+In your methods, just do `saw.next()` to move along to the next event and
+`saw.nest()` to create a nested chain.
+
+Examples
+========
+
+add_do.js
+---------
+
+This silly example adds values with a chainsaw.
+
+    var Chainsaw = require('chainsaw');
+    
+    function AddDo (sum) {
+        return Chainsaw(function (saw) {
+            this.add = function (n) {
+                sum += n;
+                saw.next();
+            };
+             
+            this.do = function (cb) {
+                saw.nest(cb, sum);
+            };
+        });
+    }
+    
+    AddDo(0)
+        .add(5)
+        .add(10)
+        .do(function (sum) {
+            if (sum > 12) this.add(-10);
+        })
+        .do(function (sum) {
+            console.log('Sum: ' + sum);
+        })
+    ;
+
+Output:
+    Sum: 5
+
+prompt.js
+---------
+
+This example provides a wrapper on top of stdin with the help of
+[node-lazy](https://github.com/pkrumins/node-lazy) for line-processing.
+
+    var Chainsaw = require('chainsaw');
+    var Lazy = require('lazy');
+    
+    module.exports = Prompt;
+    function Prompt (stream) {
+        var waiting = [];
+        var lines = [];
+        var lazy = Lazy(stream).lines.map(String)
+            .forEach(function (line) {
+                if (waiting.length) {
+                    var w = waiting.shift();
+                    w(line);
+                }
+                else lines.push(line);
+            })
+        ;
+        
+        var vars = {};
+        return Chainsaw(function (saw) {
+            this.getline = function (f) {
+                var g = function (line) {
+                    saw.nest(f, line, vars);
+                };
+                
+                if (lines.length) g(lines.shift());
+                else waiting.push(g);
+            };
+            
+            this.do = function (cb) {
+                saw.nest(cb, vars);
+            };
+        });
+    }
+
+And now for the new Prompt() module in action:
+
+    var util = require('util');
+    var stdin = process.openStdin();
+     
+    Prompt(stdin)
+        .do(function () {
+            util.print('x = ');
+        })
+        .getline(function (line, vars) {
+            vars.x = parseInt(line, 10);
+        })
+        .do(function () {
+            util.print('y = ');
+        })
+        .getline(function (line, vars) {
+            vars.y = parseInt(line, 10);
+        })
+        .do(function (vars) {
+            if (vars.x + vars.y < 10) {
+                util.print('z = ');
+                this.getline(function (line) {
+                    vars.z = parseInt(line, 10);
+                })
+            }
+            else {
+                vars.z = 0;
+            }
+        })
+        .do(function (vars) {
+            console.log('x + y + z = ' + (vars.x + vars.y + vars.z));
+            process.exit();
+        })
+    ;
+
+Installation
+============
+
+With [npm](http://github.com/isaacs/npm), just do:
+    npm install chainsaw
+
+or clone this project on github:
+
+    git clone http://github.com/substack/node-chainsaw.git
+
+To run the tests with [expresso](http://github.com/visionmedia/expresso),
+just do:
+
+    expresso
+
+
+Light Mode vs Full Mode
+=======================
+
+`node-chainsaw` supports two different modes. In full mode, every
+action is recorded, which allows you to replay actions using the
+`jump()`, `trap()` and `down()` methods.
+
+However, if your chainsaws are long-lived, recording every action can
+consume a tremendous amount of memory, so we also offer a "light" mode
+where actions are not recorded and the aforementioned methods are
+disabled.
+
+To enable light mode simply use `Chainsaw.light()` to construct your
+saw, instead of `Chainsaw()`.
+
+

+ 25 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/examples/add_do.js

@@ -0,0 +1,25 @@
+var Chainsaw = require('chainsaw');
+
+function AddDo (sum) {
+    return Chainsaw(function (saw) {
+        this.add = function (n) {
+            sum += n;
+            saw.next();
+        };
+        
+        this.do = function (cb) {
+            saw.nest(cb, sum);
+        };
+    });
+}
+
+AddDo(0)
+    .add(5)
+    .add(10)
+    .do(function (sum) {
+        if (sum > 12) this.add(-10);
+    })
+    .do(function (sum) {
+        console.log('Sum: ' + sum);
+    })
+;

+ 67 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/examples/prompt.js

@@ -0,0 +1,67 @@
+var Chainsaw = require('chainsaw');
+var Lazy = require('lazy');
+
+module.exports = Prompt;
+function Prompt (stream) {
+    var waiting = [];
+    var lines = [];
+    var lazy = Lazy(stream).lines.map(String)
+        .forEach(function (line) {
+            if (waiting.length) {
+                var w = waiting.shift();
+                w(line);
+            }
+            else lines.push(line);
+        })
+    ;
+    
+    var vars = {};
+    return Chainsaw(function (saw) {
+        this.getline = function (f) {
+            var g = function (line) {
+                saw.nest(f, line, vars);
+            };
+            
+            if (lines.length) g(lines.shift());
+            else waiting.push(g);
+        };
+        
+        this.do = function (cb) {
+            saw.nest(cb, vars);
+        };
+    });
+}
+
+var util = require('util');
+if (__filename === process.argv[1]) {
+    var stdin = process.openStdin();
+    Prompt(stdin)
+        .do(function () {
+            util.print('x = ');
+        })
+        .getline(function (line, vars) {
+            vars.x = parseInt(line, 10);
+        })
+        .do(function () {
+            util.print('y = ');
+        })
+        .getline(function (line, vars) {
+            vars.y = parseInt(line, 10);
+        })
+        .do(function (vars) {
+            if (vars.x + vars.y < 10) {
+                util.print('z = ');
+                this.getline(function (line) {
+                    vars.z = parseInt(line, 10);
+                })
+            }
+            else {
+                vars.z = 0;
+            }
+        })
+        .do(function (vars) {
+            console.log('x + y + z = ' + (vars.x + vars.y + vars.z));
+            process.exit();
+        })
+    ;
+}

+ 145 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/index.js

@@ -0,0 +1,145 @@
+var Traverse = require('traverse');
+var EventEmitter = require('events').EventEmitter;
+
+module.exports = Chainsaw;
+function Chainsaw (builder) {
+    var saw = Chainsaw.saw(builder, {});
+    var r = builder.call(saw.handlers, saw);
+    if (r !== undefined) saw.handlers = r;
+    saw.record();
+    return saw.chain();
+};
+
+Chainsaw.light = function ChainsawLight (builder) {
+    var saw = Chainsaw.saw(builder, {});
+    var r = builder.call(saw.handlers, saw);
+    if (r !== undefined) saw.handlers = r;
+    return saw.chain();
+};
+
+Chainsaw.saw = function (builder, handlers) {
+    var saw = new EventEmitter;
+    saw.handlers = handlers;
+    saw.actions = [];
+
+    saw.chain = function () {
+        var ch = Traverse(saw.handlers).map(function (node) {
+            if (this.isRoot) return node;
+            var ps = this.path;
+
+            if (typeof node === 'function') {
+                this.update(function () {
+                    saw.actions.push({
+                        path : ps,
+                        args : [].slice.call(arguments)
+                    });
+                    return ch;
+                });
+            }
+        });
+
+        process.nextTick(function () {
+            saw.emit('begin');
+            saw.next();
+        });
+
+        return ch;
+    };
+
+    saw.pop = function () {
+        return saw.actions.shift();
+    };
+
+    saw.next = function () {
+        var action = saw.pop();
+
+        if (!action) {
+            saw.emit('end');
+        }
+        else if (!action.trap) {
+            var node = saw.handlers;
+            action.path.forEach(function (key) { node = node[key] });
+            node.apply(saw.handlers, action.args);
+        }
+    };
+
+    saw.nest = function (cb) {
+        var args = [].slice.call(arguments, 1);
+        var autonext = true;
+
+        if (typeof cb === 'boolean') {
+            var autonext = cb;
+            cb = args.shift();
+        }
+
+        var s = Chainsaw.saw(builder, {});
+        var r = builder.call(s.handlers, s);
+
+        if (r !== undefined) s.handlers = r;
+
+        // If we are recording...
+        if ("undefined" !== typeof saw.step) {
+            // ... our children should, too
+            s.record();
+        }
+
+        cb.apply(s.chain(), args);
+        if (autonext !== false) s.on('end', saw.next);
+    };
+
+    saw.record = function () {
+        upgradeChainsaw(saw);
+    };
+
+    ['trap', 'down', 'jump'].forEach(function (method) {
+        saw[method] = function () {
+            throw new Error("To use the trap, down and jump features, please "+
+                            "call record() first to start recording actions.");
+        };
+    });
+
+    return saw;
+};
+
+function upgradeChainsaw(saw) {
+    saw.step = 0;
+
+    // override pop
+    saw.pop = function () {
+        return saw.actions[saw.step++];
+    };
+
+    saw.trap = function (name, cb) {
+        var ps = Array.isArray(name) ? name : [name];
+        saw.actions.push({
+            path : ps,
+            step : saw.step,
+            cb : cb,
+            trap : true
+        });
+    };
+
+    saw.down = function (name) {
+        var ps = (Array.isArray(name) ? name : [name]).join('/');
+        var i = saw.actions.slice(saw.step).map(function (x) {
+            if (x.trap && x.step <= saw.step) return false;
+            return x.path.join('/') == ps;
+        }).indexOf(true);
+
+        if (i >= 0) saw.step += i;
+        else saw.step = saw.actions.length;
+
+        var act = saw.actions[saw.step - 1];
+        if (act && act.trap) {
+            // It's a trap!
+            saw.step = act.step;
+            act.cb();
+        }
+        else saw.next();
+    };
+
+    saw.jump = function (step) {
+        saw.step = step;
+        saw.next();
+    };
+};

+ 1 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/.npmignore

@@ -0,0 +1 @@
+node_modules

+ 24 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/LICENSE

@@ -0,0 +1,24 @@
+Copyright 2010 James Halliday (mail@substack.net)
+
+This project is free software released under the MIT/X11 license:
+http://www.opensource.org/licenses/mit-license.php 
+
+Copyright 2010 James Halliday (mail@substack.net)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 247 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/README.markdown

@@ -0,0 +1,247 @@
+traverse
+========
+
+Traverse and transform objects by visiting every node on a recursive walk.
+
+examples
+========
+
+transform negative numbers in-place
+-----------------------------------
+
+negative.js
+
+````javascript
+var traverse = require('traverse');
+var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
+
+traverse(obj).forEach(function (x) {
+    if (x < 0) this.update(x + 128);
+});
+
+console.dir(obj);
+````
+
+Output:
+
+    [ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ]
+
+collect leaf nodes
+------------------
+
+leaves.js
+
+````javascript
+var traverse = require('traverse');
+
+var obj = {
+    a : [1,2,3],
+    b : 4,
+    c : [5,6],
+    d : { e : [7,8], f : 9 },
+};
+
+var leaves = traverse(obj).reduce(function (acc, x) {
+    if (this.isLeaf) acc.push(x);
+    return acc;
+}, []);
+
+console.dir(leaves);
+````
+
+Output:
+
+    [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
+
+context
+=======
+
+Each method that takes a callback has a context (its `this` object) with these
+attributes:
+
+this.node
+---------
+
+The present node on the recursive walk
+
+this.path
+---------
+
+An array of string keys from the root to the present node
+
+this.parent
+-----------
+
+The context of the node's parent.
+This is `undefined` for the root node.
+
+this.key
+--------
+
+The name of the key of the present node in its parent.
+This is `undefined` for the root node.
+
+this.isRoot, this.notRoot
+-------------------------
+
+Whether the present node is the root node
+
+this.isLeaf, this.notLeaf
+-------------------------
+
+Whether or not the present node is a leaf node (has no children)
+
+this.level
+----------
+
+Depth of the node within the traversal
+
+this.circular
+-------------
+
+If the node equals one of its parents, the `circular` attribute is set to the
+context of that parent and the traversal progresses no deeper.
+
+this.update(value)
+------------------
+
+Set a new value for the present node.
+
+this.remove()
+-------------
+
+Remove the current element from the output. If the node is in an Array it will
+be spliced off. Otherwise it will be deleted from its parent.
+
+this.delete()
+-------------
+
+Delete the current element from its parent in the output. Calls `delete` even on
+Arrays.
+
+this.before(fn)
+---------------
+
+Call this function before any of the children are traversed.
+
+this.after(fn)
+--------------
+
+Call this function after any of the children are traversed.
+
+this.pre(fn)
+------------
+
+Call this function before each of the children are traversed.
+
+this.post(fn)
+-------------
+
+Call this function after each of the children are traversed.
+
+methods
+=======
+
+.map(fn)
+--------
+
+Execute `fn` for each node in the object and return a new object with the
+results of the walk. To update nodes in the result use `this.update(value)`.
+
+.forEach(fn)
+------------
+
+Execute `fn` for each node in the object but unlike `.map()`, when
+`this.update()` is called it updates the object in-place.
+
+.reduce(fn, acc)
+----------------
+
+For each node in the object, perform a
+[left-fold](http://en.wikipedia.org/wiki/Fold_(higher-order_function))
+with the return value of `fn(acc, node)`.
+
+If `acc` isn't specified, `acc` is set to the root object for the first step
+and the root element is skipped.
+
+.deepEqual(obj)
+---------------
+
+Returns a boolean, whether the instance value is equal to the supplied object
+along a deep traversal using some opinionated choices.
+
+Some notes:
+
+* RegExps are equal if their .toString()s match, but not functions since
+functions can close over different variables.
+
+* Date instances are compared using `.getTime()` just like `assert.deepEqual()`.
+
+* Circular references must refer to the same paths within the data structure for
+both objects. For instance, in this snippet:
+
+````javascript
+var a = [1];
+a.push(a); // a = [ 1, *a ]
+
+var b = [1];
+b.push(a); // b = [ 1, [ 1, *a ] ]
+````
+
+`a` is not the same as `b` since even though the expansion is the same, the
+circular references in each refer to different paths into the data structure.
+
+However, in:
+
+````javascript
+var c = [1];
+c.push(c); // c = [ 1, *c ];
+````
+
+`c` is equal to `a` in a `deepEqual()` because they have the same terminal node
+structure.
+
+* Arguments objects are not arrays and neither are they the same as regular
+objects.
+
+* Instances created with `new` of String, Boolean, and Number types are never
+equal to the native versions.
+
+.paths()
+--------
+
+Return an `Array` of every possible non-cyclic path in the object.
+Paths are `Array`s of string keys.
+
+.nodes()
+--------
+
+Return an `Array` of every node in the object.
+
+.clone()
+--------
+
+Create a deep clone of the object.
+
+installation
+============
+
+Using npm:
+    npm install traverse
+
+Or check out the repository and link your development copy:
+    git clone http://github.com/substack/js-traverse.git
+    cd js-traverse
+    npm link .
+
+You can test traverse with "expresso":http://github.com/visionmedia/expresso
+(`npm install expresso`):
+    js-traverse $ expresso
+    
+    100% wahoo, your stuff is not broken!
+
+hash transforms
+===============
+
+This library formerly had a hash transformation component. It has been
+[moved to the hashish package](https://github.com/substack/node-hashish).

+ 16 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/examples/json.js

@@ -0,0 +1,16 @@
+var Traverse = require('traverse');
+
+var id = 54;
+var callbacks = {};
+var obj = { moo : function () {}, foo : [2,3,4, function () {}] };
+
+var scrubbed = Traverse(obj).map(function (x) {
+    if (typeof x === 'function') {
+        callbacks[id] = { id : id, f : x, path : this.path };
+        this.update('[Function]');
+        id++;
+    }
+});
+
+console.dir(scrubbed);
+console.dir(callbacks);

+ 15 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/examples/leaves.js

@@ -0,0 +1,15 @@
+var Traverse = require('traverse');
+
+var obj = {
+    a : [1,2,3],
+    b : 4,
+    c : [5,6],
+    d : { e : [7,8], f : 9 },
+};
+
+var leaves = Traverse(obj).reduce(function (acc, x) {
+    if (this.isLeaf) acc.push(x);
+    return acc;
+}, []);
+
+console.dir(leaves);

+ 8 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/examples/negative.js

@@ -0,0 +1,8 @@
+var Traverse = require('traverse');
+var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
+
+Traverse(obj).forEach(function (x) {
+    if (x < 0) this.update(x + 128);
+});
+
+console.dir(obj);

+ 38 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/examples/stringify.js

@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+var Traverse = require('traverse');
+
+var obj = [ 'five', 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
+
+var s = '';
+Traverse(obj).forEach(function to_s (node) {
+    if (Array.isArray(node)) {
+        this.before(function () { s += '[' });
+        this.post(function (child) {
+            if (!child.isLast) s += ',';
+        });
+        this.after(function () { s += ']' });
+    }
+    else if (typeof node == 'object') {
+        this.before(function () { s += '{' });
+        this.pre(function (x, key) {
+            to_s(key);
+            s += ':';
+        });
+        this.post(function (child) {
+            if (!child.isLast) s += ',';
+        });
+        this.after(function () { s += '}' });
+    }
+    else if (typeof node == 'string') {
+        s += '"' + node.toString().replace(/"/g, '\\"') + '"';
+    }
+    else if (typeof node == 'function') {
+        s += 'null';
+    }
+    else {
+        s += node.toString();
+    }
+});
+
+console.log('JSON.stringify: ' + JSON.stringify(obj));
+console.log('this stringify: ' + s);

+ 322 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/index.js

@@ -0,0 +1,322 @@
+module.exports = Traverse;
+function Traverse (obj) {
+    if (!(this instanceof Traverse)) return new Traverse(obj);
+    this.value = obj;
+}
+
+Traverse.prototype.get = function (ps) {
+    var node = this.value;
+    for (var i = 0; i < ps.length; i ++) {
+        var key = ps[i];
+        if (!Object.hasOwnProperty.call(node, key)) {
+            node = undefined;
+            break;
+        }
+        node = node[key];
+    }
+    return node;
+};
+
+Traverse.prototype.set = function (ps, value) {
+    var node = this.value;
+    for (var i = 0; i < ps.length - 1; i ++) {
+        var key = ps[i];
+        if (!Object.hasOwnProperty.call(node, key)) node[key] = {};
+        node = node[key];
+    }
+    node[ps[i]] = value;
+    return value;
+};
+
+Traverse.prototype.map = function (cb) {
+    return walk(this.value, cb, true);
+};
+
+Traverse.prototype.forEach = function (cb) {
+    this.value = walk(this.value, cb, false);
+    return this.value;
+};
+
+Traverse.prototype.reduce = function (cb, init) {
+    var skip = arguments.length === 1;
+    var acc = skip ? this.value : init;
+    this.forEach(function (x) {
+        if (!this.isRoot || !skip) {
+            acc = cb.call(this, acc, x);
+        }
+    });
+    return acc;
+};
+
+Traverse.prototype.deepEqual = function (obj) {
+    if (arguments.length !== 1) {
+        throw new Error(
+            'deepEqual requires exactly one object to compare against'
+        );
+    }
+    
+    var equal = true;
+    var node = obj;
+    
+    this.forEach(function (y) {
+        var notEqual = (function () {
+            equal = false;
+            //this.stop();
+            return undefined;
+        }).bind(this);
+        
+        //if (node === undefined || node === null) return notEqual();
+        
+        if (!this.isRoot) {
+        /*
+            if (!Object.hasOwnProperty.call(node, this.key)) {
+                return notEqual();
+            }
+        */
+            if (typeof node !== 'object') return notEqual();
+            node = node[this.key];
+        }
+        
+        var x = node;
+        
+        this.post(function () {
+            node = x;
+        });
+        
+        var toS = function (o) {
+            return Object.prototype.toString.call(o);
+        };
+        
+        if (this.circular) {
+            if (Traverse(obj).get(this.circular.path) !== x) notEqual();
+        }
+        else if (typeof x !== typeof y) {
+            notEqual();
+        }
+        else if (x === null || y === null || x === undefined || y === undefined) {
+            if (x !== y) notEqual();
+        }
+        else if (x.__proto__ !== y.__proto__) {
+            notEqual();
+        }
+        else if (x === y) {
+            // nop
+        }
+        else if (typeof x === 'function') {
+            if (x instanceof RegExp) {
+                // both regexps on account of the __proto__ check
+                if (x.toString() != y.toString()) notEqual();
+            }
+            else if (x !== y) notEqual();
+        }
+        else if (typeof x === 'object') {
+            if (toS(y) === '[object Arguments]'
+            || toS(x) === '[object Arguments]') {
+                if (toS(x) !== toS(y)) {
+                    notEqual();
+                }
+            }
+            else if (x instanceof Date || y instanceof Date) {
+                if (!(x instanceof Date) || !(y instanceof Date)
+                || x.getTime() !== y.getTime()) {
+                    notEqual();
+                }
+            }
+            else {
+                var kx = Object.keys(x);
+                var ky = Object.keys(y);
+                if (kx.length !== ky.length) return notEqual();
+                for (var i = 0; i < kx.length; i++) {
+                    var k = kx[i];
+                    if (!Object.hasOwnProperty.call(y, k)) {
+                        notEqual();
+                    }
+                }
+            }
+        }
+    });
+    
+    return equal;
+};
+
+Traverse.prototype.paths = function () {
+    var acc = [];
+    this.forEach(function (x) {
+        acc.push(this.path); 
+    });
+    return acc;
+};
+
+Traverse.prototype.nodes = function () {
+    var acc = [];
+    this.forEach(function (x) {
+        acc.push(this.node);
+    });
+    return acc;
+};
+
+Traverse.prototype.clone = function () {
+    var parents = [], nodes = [];
+    
+    return (function clone (src) {
+        for (var i = 0; i < parents.length; i++) {
+            if (parents[i] === src) {
+                return nodes[i];
+            }
+        }
+        
+        if (typeof src === 'object' && src !== null) {
+            var dst = copy(src);
+            
+            parents.push(src);
+            nodes.push(dst);
+            
+            Object.keys(src).forEach(function (key) {
+                dst[key] = clone(src[key]);
+            });
+            
+            parents.pop();
+            nodes.pop();
+            return dst;
+        }
+        else {
+            return src;
+        }
+    })(this.value);
+};
+
+function walk (root, cb, immutable) {
+    var path = [];
+    var parents = [];
+    var alive = true;
+    
+    return (function walker (node_) {
+        var node = immutable ? copy(node_) : node_;
+        var modifiers = {};
+        
+        var state = {
+            node : node,
+            node_ : node_,
+            path : [].concat(path),
+            parent : parents.slice(-1)[0],
+            key : path.slice(-1)[0],
+            isRoot : path.length === 0,
+            level : path.length,
+            circular : null,
+            update : function (x) {
+                if (!state.isRoot) {
+                    state.parent.node[state.key] = x;
+                }
+                state.node = x;
+            },
+            'delete' : function () {
+                delete state.parent.node[state.key];
+            },
+            remove : function () {
+                if (Array.isArray(state.parent.node)) {
+                    state.parent.node.splice(state.key, 1);
+                }
+                else {
+                    delete state.parent.node[state.key];
+                }
+            },
+            before : function (f) { modifiers.before = f },
+            after : function (f) { modifiers.after = f },
+            pre : function (f) { modifiers.pre = f },
+            post : function (f) { modifiers.post = f },
+            stop : function () { alive = false }
+        };
+        
+        if (!alive) return state;
+        
+        if (typeof node === 'object' && node !== null) {
+            state.isLeaf = Object.keys(node).length == 0;
+            
+            for (var i = 0; i < parents.length; i++) {
+                if (parents[i].node_ === node_) {
+                    state.circular = parents[i];
+                    break;
+                }
+            }
+        }
+        else {
+            state.isLeaf = true;
+        }
+        
+        state.notLeaf = !state.isLeaf;
+        state.notRoot = !state.isRoot;
+        
+        // use return values to update if defined
+        var ret = cb.call(state, state.node);
+        if (ret !== undefined && state.update) state.update(ret);
+        if (modifiers.before) modifiers.before.call(state, state.node);
+        
+        if (typeof state.node == 'object'
+        && state.node !== null && !state.circular) {
+            parents.push(state);
+            
+            var keys = Object.keys(state.node);
+            keys.forEach(function (key, i) {
+                path.push(key);
+                
+                if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);
+                
+                var child = walker(state.node[key]);
+                if (immutable && Object.hasOwnProperty.call(state.node, key)) {
+                    state.node[key] = child.node;
+                }
+                
+                child.isLast = i == keys.length - 1;
+                child.isFirst = i == 0;
+                
+                if (modifiers.post) modifiers.post.call(state, child);
+                
+                path.pop();
+            });
+            parents.pop();
+        }
+        
+        if (modifiers.after) modifiers.after.call(state, state.node);
+        
+        return state;
+    })(root).node;
+}
+
+Object.keys(Traverse.prototype).forEach(function (key) {
+    Traverse[key] = function (obj) {
+        var args = [].slice.call(arguments, 1);
+        var t = Traverse(obj);
+        return t[key].apply(t, args);
+    };
+});
+
+function copy (src) {
+    if (typeof src === 'object' && src !== null) {
+        var dst;
+        
+        if (Array.isArray(src)) {
+            dst = [];
+        }
+        else if (src instanceof Date) {
+            dst = new Date(src);
+        }
+        else if (src instanceof Boolean) {
+            dst = new Boolean(src);
+        }
+        else if (src instanceof Number) {
+            dst = new Number(src);
+        }
+        else if (src instanceof String) {
+            dst = new String(src);
+        }
+        else {
+            dst = Object.create(Object.getPrototypeOf(src));
+        }
+        
+        Object.keys(src).forEach(function (key) {
+            dst[key] = src[key];
+        });
+        return dst;
+    }
+    else return src;
+}

File diff suppressed because it is too large
+ 19 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/package.json


+ 114 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/circular.js

@@ -0,0 +1,114 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+var util = require('util');
+
+exports.circular = function () {
+    var obj = { x : 3 };
+    obj.y = obj;
+    var foundY = false;
+    Traverse(obj).forEach(function (x) {
+        if (this.path.join('') == 'y') {
+            assert.equal(
+                util.inspect(this.circular.node),
+                util.inspect(obj)
+            );
+            foundY = true;
+        }
+    });
+    assert.ok(foundY);
+};
+
+exports.deepCirc = function () {
+    var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
+    obj.y[2] = obj;
+    
+    var times = 0;
+    Traverse(obj).forEach(function (x) {
+        if (this.circular) {
+            assert.deepEqual(this.circular.path, []);
+            assert.deepEqual(this.path, [ 'y', 2 ]);
+            times ++;
+        }
+    });
+    
+    assert.deepEqual(times, 1);
+};
+
+exports.doubleCirc = function () {
+    var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
+    obj.y[2] = obj;
+    obj.x.push(obj.y);
+    
+    var circs = [];
+    Traverse(obj).forEach(function (x) {
+        if (this.circular) {
+            circs.push({ circ : this.circular, self : this, node : x });
+        }
+    });
+    
+    assert.deepEqual(circs[0].self.path, [ 'x', 3, 2 ]);
+    assert.deepEqual(circs[0].circ.path, []);
+     
+    assert.deepEqual(circs[1].self.path, [ 'y', 2 ]);
+    assert.deepEqual(circs[1].circ.path, []);
+    
+    assert.deepEqual(circs.length, 2);
+};
+
+exports.circDubForEach = function () {
+    var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
+    obj.y[2] = obj;
+    obj.x.push(obj.y);
+    
+    Traverse(obj).forEach(function (x) {
+        if (this.circular) this.update('...');
+    });
+    
+    assert.deepEqual(obj, { x : [ 1, 2, 3, [ 4, 5, '...' ] ], y : [ 4, 5, '...' ] });
+};
+
+exports.circDubMap = function () {
+    var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
+    obj.y[2] = obj;
+    obj.x.push(obj.y);
+    
+    var c = Traverse(obj).map(function (x) {
+        if (this.circular) {
+            this.update('...');
+        }
+    });
+    
+    assert.deepEqual(c, { x : [ 1, 2, 3, [ 4, 5, '...' ] ], y : [ 4, 5, '...' ] });
+};
+
+exports.circClone = function () {
+    var obj = { x : [ 1, 2, 3 ], y : [ 4, 5 ] };
+    obj.y[2] = obj;
+    obj.x.push(obj.y);
+    
+    var clone = Traverse.clone(obj);
+    assert.ok(obj !== clone);
+    
+    assert.ok(clone.y[2] === clone);
+    assert.ok(clone.y[2] !== obj);
+    assert.ok(clone.x[3][2] === clone);
+    assert.ok(clone.x[3][2] !== obj);
+    assert.deepEqual(clone.x.slice(0,3), [1,2,3]);
+    assert.deepEqual(clone.y.slice(0,2), [4,5]);
+};
+
+exports.circMapScrub = function () {
+    var obj = { a : 1, b : 2 };
+    obj.c = obj;
+    
+    var scrubbed = Traverse(obj).map(function (node) {
+        if (this.circular) this.remove();
+    });
+    assert.deepEqual(
+        Object.keys(scrubbed).sort(),
+        [ 'a', 'b' ]
+    );
+    assert.ok(Traverse.deepEqual(scrubbed, { a : 1, b : 2 }));
+    
+    assert.equal(obj.c, obj);
+};

+ 35 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/date.js

@@ -0,0 +1,35 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+
+exports.dateEach = function () {
+    var obj = { x : new Date, y : 10, z : 5 };
+    
+    var counts = {};
+    
+    Traverse(obj).forEach(function (node) {
+        var t = (node instanceof Date && 'Date') || typeof node;
+        counts[t] = (counts[t] || 0) + 1;
+    });
+    
+    assert.deepEqual(counts, {
+        object : 1,
+        Date : 1,
+        number : 2,
+    });
+};
+
+exports.dateMap = function () {
+    var obj = { x : new Date, y : 10, z : 5 };
+    
+    var res = Traverse(obj).map(function (node) {
+        if (typeof node === 'number') this.update(node + 100);
+    });
+    
+    assert.ok(obj.x !== res.x);
+    assert.deepEqual(res, {
+        x : obj.x,
+        y : 110,
+        z : 105,
+    });
+};
+

+ 219 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/equal.js

@@ -0,0 +1,219 @@
+var assert = require('assert');
+var traverse = require('traverse');
+
+exports.deepDates = function () {
+    assert.ok(
+        traverse.deepEqual(
+            { d : new Date, x : [ 1, 2, 3 ] },
+            { d : new Date, x : [ 1, 2, 3 ] }
+        ),
+        'dates should be equal'
+    );
+    
+    var d0 = new Date;
+    setTimeout(function () {
+        assert.ok(
+            !traverse.deepEqual(
+                { d : d0, x : [ 1, 2, 3 ], },
+                { d : new Date, x : [ 1, 2, 3 ] }
+            ),
+            'microseconds should count in date equality'
+        );
+    }, 5);
+};
+
+exports.deepCircular = function () {
+    var a = [1];
+    a.push(a); // a = [ 1, *a ]
+    
+    var b = [1];
+    b.push(a); // b = [ 1, [ 1, *a ] ]
+    
+    assert.ok(
+        !traverse.deepEqual(a, b),
+        'circular ref mount points count towards equality'
+    );
+    
+    var c = [1];
+    c.push(c); // c = [ 1, *c ]
+    assert.ok(
+        traverse.deepEqual(a, c),
+        'circular refs are structurally the same here'
+    );
+    
+    var d = [1];
+    d.push(a); // c = [ 1, [ 1, *d ] ]
+    assert.ok(
+        traverse.deepEqual(b, d),
+        'non-root circular ref structural comparison'
+    );
+};
+
+exports.deepInstances = function () {
+    assert.ok(
+        !traverse.deepEqual([ new Boolean(false) ], [ false ]),
+        'boolean instances are not real booleans'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual([ new String('x') ], [ 'x' ]),
+        'string instances are not real strings'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual([ new Number(4) ], [ 4 ]),
+        'number instances are not real numbers'
+    );
+    
+    assert.ok(
+        traverse.deepEqual([ new RegExp('x') ], [ /x/ ]),
+        'regexp instances are real regexps'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual([ new RegExp(/./) ], [ /../ ]),
+        'these regexps aren\'t the same'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual(
+            [ function (x) { return x * 2 } ],
+            [ function (x) { return x * 2 } ]
+        ),
+        'functions with the same .toString() aren\'t necessarily the same'
+    );
+    
+    var f = function (x) { return x * 2 };
+    assert.ok(
+        traverse.deepEqual([ f ], [ f ]),
+        'these functions are actually equal'
+    );
+};
+
+exports.deepEqual = function () {
+    assert.ok(
+        !traverse.deepEqual([ 1, 2, 3 ], { 0 : 1, 1 : 2, 2 : 3 }),
+        'arrays are not objects'
+    );
+};
+
+exports.falsy = function () {
+    assert.ok(
+        !traverse.deepEqual([ undefined ], [ null ]),
+        'null is not undefined!'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual([ null ], [ undefined ]),
+        'undefined is not null!'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual(
+            { a : 1, b : 2, c : [ 3, undefined, 5 ] },
+            { a : 1, b : 2, c : [ 3, null, 5 ] }
+        ),
+        'undefined is not null, however deeply!'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual(
+            { a : 1, b : 2, c : [ 3, undefined, 5 ] },
+            { a : 1, b : 2, c : [ 3, null, 5 ] }
+        ),
+        'null is not undefined, however deeply!'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual(
+            { a : 1, b : 2, c : [ 3, undefined, 5 ] },
+            { a : 1, b : 2, c : [ 3, null, 5 ] }
+        ),
+        'null is not undefined, however deeply!'
+    );
+};
+
+exports.deletedArrayEqual = function () {
+    var xs = [ 1, 2, 3, 4 ];
+    delete xs[2];
+    
+    var ys = Object.create(Array.prototype);
+    ys[0] = 1;
+    ys[1] = 2;
+    ys[3] = 4;
+    
+    assert.ok(
+        traverse.deepEqual(xs, ys),
+        'arrays with deleted elements are only equal to'
+        + ' arrays with similarly deleted elements'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual(xs, [ 1, 2, undefined, 4 ]),
+        'deleted array elements cannot be undefined'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual(xs, [ 1, 2, null, 4 ]),
+        'deleted array elements cannot be null'
+    );
+};
+
+exports.deletedObjectEqual = function () {
+    var obj = { a : 1, b : 2, c : 3 };
+    delete obj.c;
+    
+    assert.ok(
+        traverse.deepEqual(obj, { a : 1, b : 2 }),
+        'deleted object elements should not show up'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual(obj, { a : 1, b : 2, c : undefined }),
+        'deleted object elements are not undefined'
+    );
+    
+    assert.ok(
+        !traverse.deepEqual(obj, { a : 1, b : 2, c : null }),
+        'deleted object elements are not null'
+    );
+};
+
+exports.emptyKeyEqual = function () {
+    assert.ok(!traverse.deepEqual(
+        { a : 1 }, { a : 1, '' : 55 }
+    ));
+};
+
+exports.deepArguments = function () {
+    assert.ok(
+        !traverse.deepEqual(
+            [ 4, 5, 6 ],
+            (function () { return arguments })(4, 5, 6)
+        ),
+        'arguments are not arrays'
+    );
+    
+    assert.ok(
+        traverse.deepEqual(
+            (function () { return arguments })(4, 5, 6),
+            (function () { return arguments })(4, 5, 6)
+        ),
+        'arguments should equal'
+    );
+};
+
+exports.deepUn = function () {
+    assert.ok(!traverse.deepEqual({ a : 1, b : 2 }, undefined));
+    assert.ok(!traverse.deepEqual({ a : 1, b : 2 }, {}));
+    assert.ok(!traverse.deepEqual(undefined, { a : 1, b : 2 }));
+    assert.ok(!traverse.deepEqual({}, { a : 1, b : 2 }));
+    assert.ok(traverse.deepEqual(undefined, undefined));
+    assert.ok(traverse.deepEqual(null, null));
+    assert.ok(!traverse.deepEqual(undefined, null));
+};
+
+exports.deepLevels = function () {
+    var xs = [ 1, 2, [ 3, 4, [ 5, 6 ] ] ];
+    assert.ok(!traverse.deepEqual(xs, []));
+};

+ 17 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/instance.js

@@ -0,0 +1,17 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+var EventEmitter = require('events').EventEmitter;
+
+exports['check instanceof on node elems'] = function () {
+    
+    var counts = { emitter : 0 };
+    
+    Traverse([ new EventEmitter, 3, 4, { ev : new EventEmitter }])
+        .forEach(function (node) {
+            if (node instanceof EventEmitter) counts.emitter ++;
+        })
+    ;
+    
+    assert.equal(counts.emitter, 2);
+};
+

+ 42 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/interface.js

@@ -0,0 +1,42 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+
+exports['interface map'] = function () {
+    var obj = { a : [ 5,6,7 ], b : { c : [8] } };
+    
+    assert.deepEqual(
+        Traverse.paths(obj)
+            .sort()
+            .map(function (path) { return path.join('/') })
+            .slice(1)
+            .join(' ')
+         ,
+         'a a/0 a/1 a/2 b b/c b/c/0'
+    );
+    
+    assert.deepEqual(
+        Traverse.nodes(obj),
+        [
+            { a: [ 5, 6, 7 ], b: { c: [ 8 ] } },
+            [ 5, 6, 7 ], 5, 6, 7,
+            { c: [ 8 ] }, [ 8 ], 8
+        ]
+    );
+    
+    assert.deepEqual(
+        Traverse.map(obj, function (node) {
+            if (typeof node == 'number') {
+                return node + 1000;
+            }
+            else if (Array.isArray(node)) {
+                return node.join(' ');
+            }
+        }),
+        { a: '5 6 7', b: { c: '8' } }
+    );
+    
+    var nodes = 0;
+    Traverse.forEach(obj, function (node) { nodes ++ });
+    assert.deepEqual(nodes, 8);
+};
+

+ 47 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/json.js

@@ -0,0 +1,47 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+
+exports['json test'] = function () {
+    var id = 54;
+    var callbacks = {};
+    var obj = { moo : function () {}, foo : [2,3,4, function () {}] };
+    
+    var scrubbed = Traverse(obj).map(function (x) {
+        if (typeof x === 'function') {
+            callbacks[id] = { id : id, f : x, path : this.path };
+            this.update('[Function]');
+            id++;
+        }
+    });
+    
+    assert.equal(
+        scrubbed.moo, '[Function]',
+        'obj.moo replaced with "[Function]"'
+    );
+    
+    assert.equal(
+        scrubbed.foo[3], '[Function]',
+        'obj.foo[3] replaced with "[Function]"'
+    );
+    
+    assert.deepEqual(scrubbed, {
+        moo : '[Function]',
+        foo : [ 2, 3, 4, "[Function]" ]
+    }, 'Full JSON string matches');
+    
+    assert.deepEqual(
+        typeof obj.moo, 'function',
+        'Original obj.moo still a function'
+    );
+    
+    assert.deepEqual(
+        typeof obj.foo[3], 'function',
+        'Original obj.foo[3] still a function'
+    );
+    
+    assert.deepEqual(callbacks, {
+        54: { id: 54, f : obj.moo, path: [ 'moo' ] },
+        55: { id: 55, f : obj.foo[3], path: [ 'foo', '3' ] },
+    }, 'Check the generated callbacks list');
+};
+

+ 21 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/leaves.js

@@ -0,0 +1,21 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+
+exports['leaves test'] = function () {
+    var acc = [];
+    Traverse({
+        a : [1,2,3],
+        b : 4,
+        c : [5,6],
+        d : { e : [7,8], f : 9 }
+    }).forEach(function (x) {
+        if (this.isLeaf) acc.push(x);
+    });
+    
+    assert.equal(
+        acc.join(' '),
+        '1 2 3 4 5 6 7 8 9',
+        'Traversal in the right(?) order'
+    );
+};
+

+ 203 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/mutability.js

@@ -0,0 +1,203 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+
+exports.mutate = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse(obj).forEach(function (x) {
+        if (typeof x === 'number' && x % 2 === 0) {
+            this.update(x * 10);
+        }
+    });
+    assert.deepEqual(obj, res);
+    assert.deepEqual(obj, { a : 1, b : 20, c : [ 3, 40 ] });
+};
+
+exports.mutateT = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse.forEach(obj, function (x) {
+        if (typeof x === 'number' && x % 2 === 0) {
+            this.update(x * 10);
+        }
+    });
+    assert.deepEqual(obj, res);
+    assert.deepEqual(obj, { a : 1, b : 20, c : [ 3, 40 ] });
+};
+
+exports.map = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse(obj).map(function (x) {
+        if (typeof x === 'number' && x % 2 === 0) {
+            this.update(x * 10);
+        }
+    });
+    assert.deepEqual(obj, { a : 1, b : 2, c : [ 3, 4 ] });
+    assert.deepEqual(res, { a : 1, b : 20, c : [ 3, 40 ] });
+};
+
+exports.mapT = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse.map(obj, function (x) {
+        if (typeof x === 'number' && x % 2 === 0) {
+            this.update(x * 10);
+        }
+    });
+    assert.deepEqual(obj, { a : 1, b : 2, c : [ 3, 4 ] });
+    assert.deepEqual(res, { a : 1, b : 20, c : [ 3, 40 ] });
+};
+
+exports.clone = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse(obj).clone();
+    assert.deepEqual(obj, res);
+    assert.ok(obj !== res);
+    obj.a ++;
+    assert.deepEqual(res.a, 1);
+    obj.c.push(5);
+    assert.deepEqual(res.c, [ 3, 4 ]);
+};
+
+exports.cloneT = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse.clone(obj);
+    assert.deepEqual(obj, res);
+    assert.ok(obj !== res);
+    obj.a ++;
+    assert.deepEqual(res.a, 1);
+    obj.c.push(5);
+    assert.deepEqual(res.c, [ 3, 4 ]);
+};
+
+exports.reduce = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse(obj).reduce(function (acc, x) {
+        if (this.isLeaf) acc.push(x);
+        return acc;
+    }, []);
+    assert.deepEqual(obj, { a : 1, b : 2, c : [ 3, 4 ] });
+    assert.deepEqual(res, [ 1, 2, 3, 4 ]);
+};
+
+exports.reduceInit = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse(obj).reduce(function (acc, x) {
+        if (this.isRoot) assert.fail('got root');
+        return acc;
+    });
+    assert.deepEqual(obj, { a : 1, b : 2, c : [ 3, 4 ] });
+    assert.deepEqual(res, obj);
+};
+
+exports.remove = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    Traverse(obj).forEach(function (x) {
+        if (this.isLeaf && x % 2 == 0) this.remove();
+    });
+    
+    assert.deepEqual(obj, { a : 1, c : [ 3 ] });
+};
+
+exports.removeMap = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse(obj).map(function (x) {
+        if (this.isLeaf && x % 2 == 0) this.remove();
+    });
+    
+    assert.deepEqual(obj, { a : 1, b : 2, c : [ 3, 4 ] });
+    assert.deepEqual(res, { a : 1, c : [ 3 ] });
+};
+
+exports.delete = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    Traverse(obj).forEach(function (x) {
+        if (this.isLeaf && x % 2 == 0) this.delete();
+    });
+    
+    assert.ok(!Traverse.deepEqual(
+        obj, { a : 1, c : [ 3, undefined ] }
+    ));
+    
+    assert.ok(Traverse.deepEqual(
+        obj, { a : 1, c : [ 3 ] }
+    ));
+    
+    assert.ok(!Traverse.deepEqual(
+        obj, { a : 1, c : [ 3, null ] }
+    ));
+};
+
+exports.deleteRedux = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4, 5 ] };
+    Traverse(obj).forEach(function (x) {
+        if (this.isLeaf && x % 2 == 0) this.delete();
+    });
+    
+    assert.ok(!Traverse.deepEqual(
+        obj, { a : 1, c : [ 3, undefined, 5 ] }
+    ));
+    
+    assert.ok(Traverse.deepEqual(
+        obj, { a : 1, c : [ 3 ,, 5 ] }
+    ));
+    
+    assert.ok(!Traverse.deepEqual(
+        obj, { a : 1, c : [ 3, null, 5 ] }
+    ));
+    
+    assert.ok(!Traverse.deepEqual(
+        obj, { a : 1, c : [ 3, 5 ] }
+    ));
+};
+
+exports.deleteMap = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4 ] };
+    var res = Traverse(obj).map(function (x) {
+        if (this.isLeaf && x % 2 == 0) this.delete();
+    });
+    
+    assert.ok(Traverse.deepEqual(
+        obj,
+        { a : 1, b : 2, c : [ 3, 4 ] }
+    ));
+    
+    var xs = [ 3, 4 ];
+    delete xs[1];
+    
+    assert.ok(Traverse.deepEqual(
+        res, { a : 1, c : xs }
+    ));
+    
+    assert.ok(Traverse.deepEqual(
+        res, { a : 1, c : [ 3, ] }
+    ));
+    
+    assert.ok(Traverse.deepEqual(
+        res, { a : 1, c : [ 3 ] }
+    ));
+};
+
+exports.deleteMapRedux = function () {
+    var obj = { a : 1, b : 2, c : [ 3, 4, 5 ] };
+    var res = Traverse(obj).map(function (x) {
+        if (this.isLeaf && x % 2 == 0) this.delete();
+    });
+    
+    assert.ok(Traverse.deepEqual(
+        obj,
+        { a : 1, b : 2, c : [ 3, 4, 5 ] }
+    ));
+    
+    var xs = [ 3, 4, 5 ];
+    delete xs[1];
+    
+    assert.ok(Traverse.deepEqual(
+        res, { a : 1, c : xs }
+    ));
+    
+    assert.ok(!Traverse.deepEqual(
+        res, { a : 1, c : [ 3, 5 ] }
+    ));
+    
+    assert.ok(Traverse.deepEqual(
+        res, { a : 1, c : [ 3 ,, 5 ] }
+    ));
+};

+ 20 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/negative.js

@@ -0,0 +1,20 @@
+var Traverse = require('traverse');
+var assert = require('assert');
+
+exports['negative update test'] = function () {
+    var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
+    var fixed = Traverse.map(obj, function (x) {
+        if (x < 0) this.update(x + 128);
+    });
+    
+    assert.deepEqual(fixed,
+        [ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ],
+        'Negative values += 128'
+    );
+    
+    assert.deepEqual(obj,
+        [ 5, 6, -3, [ 7, 8, -2, 1 ], { f: 10, g: -13 } ],
+        'Original references not modified'
+    );
+}
+

+ 15 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/obj.js

@@ -0,0 +1,15 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+
+exports['traverse an object with nested functions'] = function () {
+    var to = setTimeout(function () {
+        assert.fail('never ran');
+    }, 1000);
+    
+    function Cons (x) {
+        clearTimeout(to);
+        assert.equal(x, 10);
+    };
+    Traverse(new Cons(10));
+};
+

+ 41 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/stop.js

@@ -0,0 +1,41 @@
+var assert = require('assert');
+var traverse = require('traverse');
+
+exports.stop = function () {
+    var visits = 0;
+    traverse('abcdefghij'.split('')).forEach(function (node) {
+        if (typeof node === 'string') {
+            visits ++;
+            if (node === 'e') this.stop()
+        }
+    });
+    
+    assert.equal(visits, 5);
+};
+
+exports.stopMap = function () {
+    var s = traverse('abcdefghij'.split('')).map(function (node) {
+        if (typeof node === 'string') {
+            if (node === 'e') this.stop()
+            return node.toUpperCase();
+        }
+    }).join('');
+    
+    assert.equal(s, 'ABCDEfghij');
+};
+
+exports.stopReduce = function () {
+    var obj = {
+        a : [ 4, 5 ],
+        b : [ 6, [ 7, 8, 9 ] ]
+    };
+    var xs = traverse(obj).reduce(function (acc, node) {
+        if (this.isLeaf) {
+            if (node === 7) this.stop();
+            else acc.push(node)
+        }
+        return acc;
+    }, []);
+    
+    assert.deepEqual(xs, [ 4, 5, 6 ]);
+};

+ 36 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/stringify.js

@@ -0,0 +1,36 @@
+var assert = require('assert');
+var Traverse = require('traverse');
+
+exports.stringify = function () {
+    var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
+    
+    var s = '';
+    Traverse(obj).forEach(function (node) {
+        if (Array.isArray(node)) {
+            this.before(function () { s += '[' });
+            this.post(function (child) {
+                if (!child.isLast) s += ',';
+            });
+            this.after(function () { s += ']' });
+        }
+        else if (typeof node == 'object') {
+            this.before(function () { s += '{' });
+            this.pre(function (x, key) {
+                s += '"' + key + '"' + ':';
+            });
+            this.post(function (child) {
+                if (!child.isLast) s += ',';
+            });
+            this.after(function () { s += '}' });
+        }
+        else if (typeof node == 'function') {
+            s += 'null';
+        }
+        else {
+            s += node.toString();
+        }
+    });
+    
+    assert.equal(s, JSON.stringify(obj));
+}
+

+ 54 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/node_modules/traverse/test/super_deep.js

@@ -0,0 +1,54 @@
+var assert = require('assert');
+var traverse = require('traverse');
+
+exports.super_deep = function () {
+    var util = require('util');
+    var a0 = make();
+    var a1 = make();
+    assert.ok(traverse.deepEqual(a0, a1));
+    
+    a0.c.d.moo = true;
+    assert.ok(!traverse.deepEqual(a0, a1));
+    
+    a1.c.d.moo = true;
+    assert.ok(traverse.deepEqual(a0, a1));
+    
+    // TODO: this one
+    //a0.c.a = a1;
+    //assert.ok(!traverse.deepEqual(a0, a1));
+};
+
+function make () {
+    var a = { self : 'a' };
+    var b = { self : 'b' };
+    var c = { self : 'c' };
+    var d = { self : 'd' };
+    var e = { self : 'e' };
+    
+    a.a = a;
+    a.b = b;
+    a.c = c;
+    
+    b.a = a;
+    b.b = b;
+    b.c = c;
+    
+    c.a = a;
+    c.b = b;
+    c.c = c;
+    c.d = d;
+    
+    d.a = a;
+    d.b = b;
+    d.c = c;
+    d.d = d;
+    d.e = e;
+    
+    e.a = a;
+    e.b = b;
+    e.c = c;
+    e.d = d;
+    e.e = e;
+    
+    return a;
+}

File diff suppressed because it is too large
+ 28 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/package.json


+ 418 - 0
lib/unzip/node_modules/binary/node_modules/chainsaw/test/chainsaw.js

@@ -0,0 +1,418 @@
+var assert = require('assert');
+var Chainsaw = require('../index');
+
+exports.getset = function () {
+    var to = setTimeout(function () {
+        assert.fail('builder never fired');
+    }, 1000);
+    
+    var ch = Chainsaw(function (saw) {
+        clearTimeout(to);
+        var num = 0;
+        
+        this.get = function (cb) {
+            cb(num);
+            saw.next();
+        };
+        
+        this.set = function (n) {
+            num = n;
+            saw.next();
+        };
+        
+        var ti = setTimeout(function () {
+            assert.fail('end event not emitted');
+        }, 50);
+        
+        saw.on('end', function () {
+            clearTimeout(ti);
+            assert.equal(times, 3);
+        });
+    });
+    
+    var times = 0;
+    ch
+        .get(function (x) {
+            assert.equal(x, 0);
+            times ++;
+        })
+        .set(10)
+        .get(function (x) {
+            assert.equal(x, 10);
+            times ++;
+        })
+        .set(20)
+        .get(function (x) {
+            assert.equal(x, 20);
+            times ++;
+        })
+    ;
+};
+
+exports.nest = function () {
+    var ch = (function () {
+        var vars = {};
+        return Chainsaw(function (saw) {
+            this.do = function (cb) {
+                saw.nest(cb, vars);
+            };
+        });
+    })();
+    
+    var order = [];
+    var to = setTimeout(function () {
+        assert.fail("Didn't get to the end");
+    }, 50);
+    
+    ch
+        .do(function (vars) {
+            vars.x = 'y';
+            order.push(1);
+            
+            this
+                .do(function (vs) {
+                    order.push(2);
+                    vs.x = 'x';
+                })
+                .do(function (vs) {
+                    order.push(3);
+                    vs.z = 'z';
+                })
+            ;
+        })
+        .do(function (vars) {
+            vars.y = 'y';
+            order.push(4);
+        })
+        .do(function (vars) {
+            assert.eql(order, [1,2,3,4]);
+            assert.eql(vars, { x : 'x', y : 'y', z : 'z' });
+            clearTimeout(to);
+        })
+    ;
+};
+
+exports.nestWait = function () {
+    var ch = (function () {
+        var vars = {};
+        return Chainsaw(function (saw) {
+            this.do = function (cb) {
+                saw.nest(cb, vars);
+            };
+            
+            this.wait = function (n) {
+                setTimeout(function () {
+                    saw.next();
+                }, n);
+            };
+        });
+    })();
+    
+    var order = [];
+    var to = setTimeout(function () {
+        assert.fail("Didn't get to the end");
+    }, 1000);
+    
+    var times = {};
+    
+    ch
+        .do(function (vars) {
+            vars.x = 'y';
+            order.push(1);
+            
+            this
+                .do(function (vs) {
+                    order.push(2);
+                    vs.x = 'x';
+                    times.x = Date.now();
+                })
+                .wait(50)
+                .do(function (vs) {
+                    order.push(3);
+                    vs.z = 'z';
+                    
+                    times.z = Date.now();
+                    var dt = times.z - times.x;
+                    assert.ok(dt >= 50 && dt < 75);
+                })
+            ;
+        })
+        .do(function (vars) {
+            vars.y = 'y';
+            order.push(4);
+            
+            times.y = Date.now();
+        })
+        .wait(100)
+        .do(function (vars) {
+            assert.eql(order, [1,2,3,4]);
+            assert.eql(vars, { x : 'x', y : 'y', z : 'z' });
+            clearTimeout(to);
+            
+            times.end = Date.now();
+            var dt = times.end - times.y;
+            assert.ok(dt >= 100 && dt < 125)
+        })
+    ;
+};
+
+exports.nestNext = function () {
+    var ch = (function () {
+        var vars = {};
+        return Chainsaw(function (saw) {
+            this.do = function (cb) {
+                saw.nest(false, function () {
+                    var args = [].slice.call(arguments);
+                    args.push(saw.next);
+                    cb.apply(this, args);
+                }, vars);
+            };
+        });
+    })();
+    
+    var order = [];
+    var to = setTimeout(function () {
+        assert.fail("Didn't get to the end");
+    }, 500);
+    
+    var times = [];
+    
+    ch
+        .do(function (vars, next_) {
+            vars.x = 'y';
+            order.push(1);
+            
+            this
+                .do(function (vs, next) {
+                    order.push(2);
+                    vs.x = 'x';
+                    setTimeout(next, 30);
+                })
+                .do(function (vs, next) {
+                    order.push(3);
+                    vs.z = 'z';
+                    setTimeout(next, 10);
+                })
+                .do(function () {
+                    setTimeout(next_, 20);
+                })
+            ;
+        })
+        .do(function (vars, next) {
+            vars.y = 'y';
+            order.push(4);
+            setTimeout(next, 5);
+        })
+        .do(function (vars) {
+            assert.eql(order, [1,2,3,4]);
+            assert.eql(vars, { x : 'x', y : 'y', z : 'z' });
+            
+            clearTimeout(to);
+        })
+    ;
+};
+
+exports.builder = function () {
+    var cx = Chainsaw(function (saw) {
+        this.x = function () {};
+    });
+    assert.ok(cx.x);
+    
+    var cy = Chainsaw(function (saw) {
+        return { y : function () {} };
+    });
+    assert.ok(cy.y);
+    
+    var cz = Chainsaw(function (saw) {
+        return { z : function (cb) { saw.nest(cb) } };
+    });
+    assert.ok(cz.z);
+    
+    var to = setTimeout(function () {
+        assert.fail("Nested z didn't run");
+    }, 50);
+    
+    cz.z(function () {
+        clearTimeout(to);
+        assert.ok(this.z);
+    });
+};
+
+this.attr = function () {
+    var to = setTimeout(function () {
+        assert.fail("attr chain didn't finish");
+    }, 50);
+    
+    var xy = [];
+    var ch = Chainsaw(function (saw) {
+        this.h = {
+            x : function () { 
+                xy.push('x');
+                saw.next();
+            },
+            y : function () {
+                xy.push('y');
+                saw.next();
+                assert.eql(xy, ['x','y']);
+                clearTimeout(to);
+            }
+        };
+    });
+    assert.ok(ch.h);
+    assert.ok(ch.h.x);
+    assert.ok(ch.h.y);
+    
+    ch.h.x().h.y();
+};
+
+exports.down = function () {
+    var error = null;
+    var s;
+    var ch = Chainsaw(function (saw) {
+        s = saw;
+        this.raise = function (err) {
+            error = err;
+            saw.down('catch');
+        };
+        
+        this.do = function (cb) {
+            cb.call(this);
+        };
+        
+        this.catch = function (cb) {
+            if (error) {
+                saw.nest(cb, error);
+                error = null;
+            }
+            else saw.next();
+        };
+    });
+    
+    var to = setTimeout(function () {
+        assert.fail(".do() after .catch() didn't fire");
+    }, 50);
+    
+    ch
+        .do(function () {
+            this.raise('pow');
+        })
+        .do(function () {
+            assert.fail("raise didn't skip over this do block");
+        })
+        .catch(function (err) {
+            assert.equal(err, 'pow');
+        })
+        .do(function () {
+            clearTimeout(to);
+        })
+    ;
+};
+
+exports.trap = function () {
+    var error = null;
+    var ch = Chainsaw(function (saw) {
+        var pars = 0;
+        var stack = [];
+        var i = 0;
+        
+        this.par = function (cb) {
+            pars ++;
+            var j = i ++;
+            cb.call(function () {
+                pars --;
+                stack[j] = [].slice.call(arguments);
+                saw.down('result');
+            });
+            saw.next();
+        };
+        
+        this.join = function (cb) {
+            saw.trap('result', function () {
+                if (pars == 0) {
+                    cb.apply(this, stack);
+                    saw.next();
+                }
+            });
+        };
+        
+        this.raise = function (err) {
+            error = err;
+            saw.down('catch');
+        };
+        
+        this.do = function (cb) {
+            cb.call(this);
+        };
+        
+        this.catch = function (cb) {
+            if (error) {
+                saw.nest(cb, error);
+                error = null;
+            }
+            else saw.next();
+        };
+    });
+    
+    var to = setTimeout(function () {
+        assert.fail(".do() after .join() didn't fire");
+    }, 100);
+    var tj = setTimeout(function () {
+        assert.fail('.join() never fired');
+    }, 100);
+    
+    var joined = false;
+    ch
+        .par(function () {
+            setTimeout(this.bind(null, 1), 50);
+        })
+        .par(function () {
+            setTimeout(this.bind(null, 2), 25);
+        })
+        .join(function (x, y) {
+            assert.equal(x[0], 1);
+            assert.equal(y[0], 2);
+            clearTimeout(tj);
+            joined = true;
+        })
+        .do(function () {
+            clearTimeout(to);
+            assert.ok(joined);
+        })
+    ;
+};
+
+exports.jump = function () {
+    var to = setTimeout(function () {
+        assert.fail('builder never fired');
+    }, 50);
+    
+    var xs = [ 4, 5, 6, -4, 8, 9, -1, 8 ];
+    var xs_ = [];
+    
+    var ch = Chainsaw(function (saw) {
+        this.x = function (i) {
+            xs_.push(i);
+            saw.next();
+        };
+        
+        this.y = function (step) {
+            var x = xs.shift();
+            if (x > 0) saw.jump(step);
+            else saw.next();
+        };
+        
+        saw.on('end', function () {
+            clearTimeout(to);
+            assert.eql(xs, [ 8 ]);
+            assert.eql(xs_, [ 1, 1, 1, 1, 2, 3, 2, 3, 2, 3 ]);
+        });
+    });
+    
+    ch
+        .x(1)
+        .y(0)
+        .x(2)
+        .x(3)
+        .y(2)
+    ;
+};

File diff suppressed because it is too large
+ 37 - 0
lib/unzip/node_modules/binary/package.json


+ 92 - 0
lib/unzip/node_modules/binary/perf/loop.js

@@ -0,0 +1,92 @@
+var Seq = require('seq');
+var Hash = require('hashish');
+var EventEmitter = require('events').EventEmitter;
+
+var Bin = require('binary');
+var Buf = require('bufferlist/binary');
+var BufferList = require('bufferlist');
+
+console.log('loop');
+function emitter () {
+    var em = new EventEmitter;
+    
+    var i = 0;
+    var iv = setInterval(function () {
+        var buf = new Buffer(10000);
+        buf[0] = 0xff;
+        
+        if (++ i >= 2000) {
+            buf[0] = 0;
+            clearInterval(iv);
+        }
+        em.emit('data', buf);
+    }, 1);
+    
+    return em;
+}
+
+Seq()
+    .seq(function () {
+        var next = this.bind({}, null);
+        bufferlist(next);
+    })
+    .seq(function () {
+        var next = this.bind({}, null);
+        binary(next);
+    })
+;
+
+function binary (next) {
+    var em = emitter();
+    var t0 = Date.now();
+    
+    Bin(em)
+        .loop(function (end) {
+            this
+            .word8('x')
+            .word8('y')
+            .word32be('z')
+            .word32le('w')
+            .buffer('buf', 10000 - 10)
+            .tap(function (vars) {
+                if (vars.x === 0) {
+                    var tf = Date.now();
+                    console.log('    binary: ' + (tf - t0) + ' ms');
+                    end();
+                    setTimeout(next, 20);
+                }
+            })
+        })
+    ;
+}
+
+function bufferlist (next) {
+    var em = emitter();
+    var t0 = Date.now();
+    
+    var blist = new BufferList;
+    em.on('data', function (buf) {
+        blist.push(buf);
+    });
+    
+    Buf(blist)
+        .forever(function () {
+            var top = this;
+            this
+            .getWord8('x')
+            .getWord8('y')
+            .getWord32be('z')
+            .getWord32le('w')
+            .getBuffer('buf', 10000 - 10)
+            .tap(function (vars) {
+                if (vars.x === 0) {
+                    var tf = Date.now();
+                    console.log('    bufferlist: ' + (tf - t0) + ' ms');
+                    top.exit();
+                    setTimeout(next, 20);
+                }
+            })
+        })
+        .end()
+    ;
+}

+ 80 - 0
lib/unzip/node_modules/binary/perf/small.js

@@ -0,0 +1,80 @@
+var Seq = require('seq');
+var Hash = require('hashish');
+
+var Bin = require('binary');
+var Buf = require('bufferlist/binary');
+var BufferList = require('bufferlist');
+var EventEmitter = require('events').EventEmitter;
+
+function binary (buf, cb) {
+    Bin(buf)
+        .word32le('x')
+        .word16be('y')
+        .word16be('z')
+        .word32le('w')
+        .tap(cb)
+    ;
+};
+
+function stream (buf, cb) {
+    var em = new EventEmitter;
+    Bin(em)
+        .word32le('x')
+        .word16be('y')
+        .word16be('z')
+        .word32le('w')
+        .tap(cb)
+    ;
+    em.emit('data', buf);
+};
+
+function parse (buf, cb) {
+    cb(Bin.parse(buf)
+        .word32le('x')
+        .word16be('y')
+        .word16be('z')
+        .word32le('w')
+        .vars
+    );
+};
+
+function bufferlist (buf, cb) {
+    var blist = new BufferList;
+    blist.push(buf);
+    Buf(blist)
+        .getWord32le('x')
+        .getWord16be('y')
+        .getWord16be('z')
+        .getWord32le('w')
+        .tap(cb)
+        .end()
+    ;
+};
+
+
+var buffers = [];
+for (var i = 0; i < 200; i++) {
+    buffers.push(new Buffer(12));
+}
+
+console.log('small');
+Seq(binary, stream, parse, bufferlist)
+    .seqEach(function (f) {
+        var t = this;
+        var t0 = Date.now();
+        Seq()
+            .extend(buffers)
+            .seqEach(function (buf) {
+                f(buf, this.bind(this, null));
+            })
+            .seq(function () {
+                var tf = Date.now();
+                console.log('    ' + f.name + ': ' + (tf - t0));
+                t(null);
+            })
+        ;
+    })
+    .seq(function () {
+        this(null);
+    })
+;

+ 46 - 0
lib/unzip/node_modules/binary/test/bu.js

@@ -0,0 +1,46 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('bu', function (t) {
+    t.plan(8);
+    
+    // note: can't store -12667700813876161 exactly in an ieee float
+    
+    var buf = new Buffer([
+        44, // a == 44
+        2, 43, // b == 555
+        164, 213, 37, 37, // c == 2765432101
+        29, 81, 180, 20, 155, 115, 203, 193, // d == 2112667700813876161
+    ]);
+    
+    binary.parse(buf)
+        .word8bu('a')
+        .word16bu('b')
+        .word32bu('c')
+        .word64bu('d')
+        .tap(function (vars) {
+            t.same(vars.a, 44);
+            t.same(vars.b, 555);
+            t.same(vars.c, 2765432101);
+            t.ok(
+                Math.abs(vars.d - 2112667700813876161) < 1500
+            );
+        })
+    ;
+    
+    // also check aliases here:
+    binary.parse(buf)
+        .word8be('a')
+        .word16be('b')
+        .word32be('c')
+        .word64be('d')
+        .tap(function (vars) {
+            t.same(vars.a, 44);
+            t.same(vars.b, 555);
+            t.same(vars.c, 2765432101);
+            t.ok(
+                Math.abs(vars.d - 2112667700813876161) < 1500
+            );
+        })
+    ;
+});

+ 20 - 0
lib/unzip/node_modules/binary/test/deferred.js

@@ -0,0 +1,20 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('deferred', function (t) {
+    t.plan(1);
+    
+    var em = new EventEmitter;
+    binary.stream(em)
+        .word8('a')
+        .word16be('bc')
+        .tap(function (vars) {
+            t.same(vars, { a : 97, bc : 25187 });
+        })
+    ;
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer([ 97, 98, 99 ]));
+    }, 10);
+});

+ 23 - 0
lib/unzip/node_modules/binary/test/dots.js

@@ -0,0 +1,23 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('dots', function (t) {
+    t.plan(1);
+    
+    binary.parse(new Buffer([ 97, 98, 99, 100, 101, 102 ]))
+        .word8('a')
+        .word16be('b.x')
+        .word16be('b.y')
+        .word8('b.z')
+        .tap(function (vars) {
+            t.same(vars, {
+                a : 97,
+                b : {
+                    x : 256 * 98 + 99,
+                    y : 256 * 100 + 101,
+                    z : 102
+                },
+            });
+        })
+    ;
+});

+ 41 - 0
lib/unzip/node_modules/binary/test/eof.js

@@ -0,0 +1,41 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('eof', function (t) {
+    t.plan(4);
+    
+    var stream = new EventEmitter;
+    binary.stream(stream)
+        .buffer('sixone', 5)
+        .peek(function () {
+            this.word32le('len');
+        })
+        .buffer('buf', 'len')
+        .word8('x')
+        .tap(function (vars) {
+            t.same(
+                [].slice.call(vars.sixone),
+                [].slice.call(new Buffer([ 6, 1, 6, 1, 6 ]))
+            );
+            t.same(vars.buf.length, vars.len);
+            t.same(
+                [].slice.call(vars.buf),
+                [ 9, 0, 0, 0, 97, 98, 99, 100, 101 ]
+            );
+            t.same(vars.x, 102);
+        })
+    ;
+    
+    var bufs = [
+        new Buffer([ 6, 1, 6, 1, 6, 9, 0, 0, 0, 97 ]),
+        new Buffer([ 98, 99 ]),
+        new Buffer([ 100, 101, 102 ]),
+    ];
+    
+    bufs.forEach(function (buf) {
+        stream.emit('data', buf);
+    });
+    
+    stream.emit('end');
+});

+ 17 - 0
lib/unzip/node_modules/binary/test/flush.js

@@ -0,0 +1,17 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('flush', function (t) {
+    t.plan(1);
+    
+    binary.parse(new Buffer([ 97, 98, 99, 100, 101, 102 ]))
+        .word8('a')
+        .word16be('b')
+        .word16be('c')
+        .flush()
+        .word8('d')
+        .tap(function (vars) {
+            t.same(vars, { d : 102 });
+        })
+    ;
+});

+ 14 - 0
lib/unzip/node_modules/binary/test/from_buffer.js

@@ -0,0 +1,14 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('from buffer', function (t) {
+    t.plan(1);
+    
+    binary(new Buffer([ 97, 98, 99 ]))
+        .word8('a')
+        .word16be('bc')
+        .tap(function (vars) {
+            t.same(vars, { a : 97, bc : 25187 });
+        })
+    ;
+});

+ 28 - 0
lib/unzip/node_modules/binary/test/get_buffer.js

@@ -0,0 +1,28 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('get buffer', function (t) {
+    t.plan(4);
+    
+    var buf = new Buffer([ 4, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]);
+    binary.parse(buf)
+        .word8('a')
+        .buffer('b', 7)
+        .word16lu('c')
+        .tap(function (vars) {
+            t.equal(vars.a, 4);
+            t.equal(
+                vars.b.toString(), 
+                new Buffer([ 2, 3, 4, 5, 6, 7, 8 ]).toString()
+            );
+            t.equal(vars.c, 2569);
+        })
+        .buffer('d', 'a')
+        .tap(function (vars) {
+            t.equal(
+                vars.d.toString(),
+                new Buffer([ 11, 12, 13, 14 ]).toString()
+            );
+        })
+    ;
+});

+ 18 - 0
lib/unzip/node_modules/binary/test/immediate.js

@@ -0,0 +1,18 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('immediate', function (t) {
+    t.plan(1);
+    
+    var em = new EventEmitter;
+    binary.stream(em, 'moo')
+        .word8('a')
+        .word16be('bc')
+        .tap(function (vars) {
+            t.same(vars, { a : 97, bc : 25187 });
+        })
+    ;
+    
+    em.emit('moo', new Buffer([ 97, 98, 99 ]));
+});

+ 38 - 0
lib/unzip/node_modules/binary/test/interval.js

@@ -0,0 +1,38 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('interval', function (t) {
+    t.plan(1);
+    
+    var em = new EventEmitter;
+    var i = 0;
+    var iv = setInterval(function () {
+        var buf = new Buffer(1000);
+        buf[0] = 0xff;
+        if (++i >= 1000) {
+            clearInterval(iv);
+            buf[0] = 0;
+        }
+        em.emit('data', buf);
+    }, 1);
+    
+    var loops = 0;
+    binary(em)
+        .loop(function (end) {
+            this
+            .word8('x')
+            .word8('y')
+            .word32be('z')
+            .word32le('w')
+            .buffer('buf', 1000 - 10)
+            .tap(function (vars) {
+                loops ++;
+                if (vars.x == 0) end();
+            })
+        })
+        .tap(function () {
+            t.same(loops, 1000);
+        })
+    ;
+});

+ 35 - 0
lib/unzip/node_modules/binary/test/into_buffer.js

@@ -0,0 +1,35 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('intoBuffer', function (t) {
+    t.plan(3);
+    var buf = new Buffer([ 1, 2, 3, 4, 5, 6 ])
+    
+    binary.parse(buf)
+        .into('moo', function () {
+            this
+                .word8('x')
+                .word8('y')
+                .word8('z')
+            ;
+        })
+        .tap(function (vars) {
+            t.same(vars, { moo : { x : 1, y : 2, z : 3 } });
+        })
+        .word8('w')
+        .tap(function (vars) {
+            t.same(vars, {
+                moo : { x : 1, y : 2, z : 3 },
+                w : 4,
+            });
+        })
+        .word8('x')
+        .tap(function (vars) {
+            t.same(vars, {
+                moo : { x : 1, y : 2, z : 3 },
+                w : 4,
+                x : 5,
+            });
+        })
+    ;
+});

+ 43 - 0
lib/unzip/node_modules/binary/test/into_stream.js

@@ -0,0 +1,43 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('into stream', function (t) {
+    t.plan(3);
+    
+    var digits = [ 1, 2, 3, 4, 5, 6 ];
+    var stream = new EventEmitter;
+    var iv = setInterval(function () {
+        var d = digits.shift();
+        if (d) stream.emit('data', new Buffer([ d ]))
+        else clearInterval(iv)
+    }, 20);
+    
+    binary.stream(stream)
+        .into('moo', function () {
+            this
+                .word8('x')
+                .word8('y')
+                .word8('z')
+            ;
+        })
+        .tap(function (vars) {
+            t.same(vars, { moo : { x : 1, y : 2, z : 3 } });
+        })
+        .word8('w')
+        .tap(function (vars) {
+            t.same(vars, {
+                moo : { x : 1, y : 2, z : 3 },
+                w : 4,
+            });
+        })
+        .word8('x')
+        .tap(function (vars) {
+            t.same(vars, {
+                moo : { x : 1, y : 2, z : 3 },
+                w : 4,
+                x : 5,
+            });
+        })
+    ;
+});

+ 44 - 0
lib/unzip/node_modules/binary/test/loop.js

@@ -0,0 +1,44 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('loop', function (t) {
+    t.plan(3 * 2 + 1);
+    
+    var em = new EventEmitter;
+    
+    binary.stream(em)
+        .loop(function (end, vars) {
+            t.strictEqual(vars, this.vars);
+            this
+                .word16lu('a')
+                .word8u('b')
+                .word8s('c')
+                .tap(function (vars_) {
+                    t.strictEqual(vars, vars_);
+                    if (vars.c < 0) end();
+                })
+            ;
+        })
+        .tap(function (vars) {
+            t.same(vars, { a : 1337, b : 55, c : -5 });
+        })
+    ;
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer([ 2, 10, 88 ]));
+    }, 10);
+    setTimeout(function () {
+        em.emit('data', new Buffer([ 100, 3, 6, 242, 30 ]));
+    }, 20);
+    setTimeout(function () {
+        em.emit('data', new Buffer([ 60, 60, 199, 44 ]));
+    }, 30);
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer([ 57, 5 ]));
+    }, 80);
+    setTimeout(function () {
+        em.emit('data', new Buffer([ 55, 251 ]));
+    }, 90);
+});

+ 54 - 0
lib/unzip/node_modules/binary/test/loop_scan.js

@@ -0,0 +1,54 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('loop scan', function (t) {
+    t.plan(8 + 6 + 2);
+    
+    var em = new EventEmitter;
+    
+    binary.stream(em)
+        .loop(function (end) {
+            var vars_ = this.vars;
+            this
+                .scan('filler', 'BEGINMSG')
+                .buffer('cmd', 3)
+                .word8('num')
+                .tap(function (vars) {
+                    t.strictEqual(vars, vars_);
+                    if (vars.num != 0x02 && vars.num != 0x06) {
+                        t.same(vars.filler.length, 0);
+                    }
+                    if (vars.cmd.toString() == 'end') end();
+                })
+            ;
+        })
+        .tap(function (vars) {
+            t.same(vars.cmd.toString(), 'end');
+			t.same(vars.num, 0x08);
+        })
+    ;
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer(
+            'BEGINMSGcmd\x01'
+            + 'GARBAGEDATAXXXX'
+            + 'BEGINMSGcmd\x02'
+            + 'BEGINMSGcmd\x03'
+        ));
+    }, 10);
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer(
+            'BEGINMSGcmd\x04'
+            + 'BEGINMSGcmd\x05'
+            + 'GARBAGEDATAXXXX'
+            + 'BEGINMSGcmd\x06'
+        ));
+        em.emit('data', new Buffer('BEGINMSGcmd\x07'));
+    }, 20);
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer('BEGINMSGend\x08'));
+    }, 30);
+});

+ 46 - 0
lib/unzip/node_modules/binary/test/lu.js

@@ -0,0 +1,46 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('lu', function (t) {
+    t.plan(8);
+    
+    // note: can't store -12667700813876161 exactly in an ieee float
+    
+    var buf = new Buffer([
+        44, // a == 44
+        43, 2, // b == 555
+        37, 37, 213, 164, // c == 2765432101
+        193, 203, 115, 155, 20, 180, 81, 29, // d == 2112667700813876161
+    ]);
+    
+    binary.parse(buf)
+        .word8lu('a')
+        .word16lu('b')
+        .word32lu('c')
+        .word64lu('d')
+        .tap(function (vars) {
+            t.same(vars.a, 44);
+            t.same(vars.b, 555);
+            t.same(vars.c, 2765432101);
+            t.ok(
+                Math.abs(vars.d - 2112667700813876161) < 1500
+            );
+        })
+    ;
+    
+    // also check aliases here:
+    binary.parse(buf)
+        .word8le('a')
+        .word16le('b')
+        .word32le('c')
+        .word64le('d')
+        .tap(function (vars) {
+            t.same(vars.a, 44);
+            t.same(vars.b, 555);
+            t.same(vars.c, 2765432101);
+            t.ok(
+                Math.abs(vars.d - 2112667700813876161) < 1500
+            );
+        })
+    ;
+});

+ 29 - 0
lib/unzip/node_modules/binary/test/negbs.js

@@ -0,0 +1,29 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('negbs', function (t) {
+    t.plan(4);
+    // note: can't store -12667700813876161 exactly in an ieee float
+    
+    var buf = new Buffer([
+        226, // a == -30
+        246, 219, // b == -2341
+        255, 243, 245, 236, // c == -789012
+        255, 210, 254, 203, 16, 222, 52, 63, // d == -12667700813876161
+    ]);
+    
+    binary.parse(buf)
+        .word8bs('a')
+        .word16bs('b')
+        .word32bs('c')
+        .word64bs('d')
+        .tap(function (vars) {
+            t.same(vars.a, -30);
+            t.same(vars.b, -2341);
+            t.same(vars.c, -789012);
+            t.ok(
+                Math.abs(vars.d - -12667700813876161) < 1500
+            );
+        })
+    ;
+});

+ 29 - 0
lib/unzip/node_modules/binary/test/negls.js

@@ -0,0 +1,29 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('negls', function (t) {
+    t.plan(4);
+    // note: can't store -12667700813876161 exactly in an ieee float
+    
+    var buf = new Buffer([
+        226, // a == -30
+        219, 246, // b == -2341
+        236, 245, 243, 255, // c == -789012
+        63, 52, 222, 16, 203, 254, 210, 255, // d == -12667700813876161
+    ]);
+    
+    binary.parse(buf)
+        .word8ls('a')
+        .word16ls('b')
+        .word32ls('c')
+        .word64ls('d')
+        .tap(function (vars) {
+            t.same(vars.a, -30);
+            t.same(vars.b, -2341);
+            t.same(vars.c, -789012);
+            t.ok(
+                Math.abs(vars.d - -12667700813876161) < 1000
+            );
+        })
+    ;
+});

+ 35 - 0
lib/unzip/node_modules/binary/test/nested.js

@@ -0,0 +1,35 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('nested', function (t) {
+    t.plan(3);
+    var insideDone = false;
+    
+    var em = new EventEmitter;
+    binary.stream(em)
+        .word16be('ab')
+        .tap(function () {
+            this
+                .word8('c')
+                .word8('d')
+                .tap(function () {
+                    insideDone = true;
+                })
+            ;
+        })
+        .tap(function (vars) {
+            t.ok(insideDone);
+            t.same(vars.c, 'c'.charCodeAt(0));
+            t.same(vars.d, 'd'.charCodeAt(0));
+            
+        })
+    ;
+    
+    var strs = [ 'abc', 'def', 'hi', 'jkl' ];
+    var iv = setInterval(function () {
+        var s = strs.shift();
+        if (s) em.emit('data', new Buffer(s));
+        else clearInterval(iv);
+    }, 50);
+});

+ 17 - 0
lib/unzip/node_modules/binary/test/not_enough_buf.js

@@ -0,0 +1,17 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('not enough buf', function (t) {
+    t.plan(3);
+    
+    var vars = binary(new Buffer([1,2,3,4]))
+        .word8('a')
+        .buffer('b', 10)
+        .word8('c')
+        .vars
+    ;
+    
+    t.same(vars.a, 1);
+    t.equal(vars.b.toString(), new Buffer([2,3,4]).toString());
+    t.strictEqual(vars.c, null);
+});

+ 19 - 0
lib/unzip/node_modules/binary/test/not_enough_parse.js

@@ -0,0 +1,19 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('not enough parse', function (t) {
+    t.plan(4);
+    
+    var vars = binary(new Buffer([1,2]))
+        .word8('a')
+        .word8('b')
+        .word8('c')
+        .word8('d')
+        .vars
+    ;
+    
+    t.same(vars.a, 1);
+    t.same(vars.b, 2);
+    t.strictEqual(vars.c, null);
+    t.strictEqual(vars.d, null);
+});

+ 54 - 0
lib/unzip/node_modules/binary/test/parse.js

@@ -0,0 +1,54 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('parse', function (t) {
+    t.plan(6);
+    var res = binary.parse(new Buffer([ 97, 98, 99, 99, 99, 99, 1, 2, 3 ]))
+        .word8('a')
+        .word16be('bc')
+        .skip(3)
+        .buffer('def', 3)
+        .tap(function (vars) {
+            t.equal(vars.a, 97);
+            t.equal(vars.bc, 25187);
+            t.same(
+                [].slice.call(vars.def),
+                [].slice.call(new Buffer([ 1, 2, 3]))
+            );
+        })
+        .vars
+    ;
+    t.equal(res.a, 97);
+    t.equal(res.bc, 25187);
+    t.same(
+        [].slice.call(res.def),
+        [].slice.call(new Buffer([ 1, 2, 3 ]))
+    );
+});
+
+test('loop', function (t) {
+    t.plan(2);
+    var res = binary.parse(new Buffer([ 97, 98, 99, 4, 5, 2, -3, 9 ]))
+        .word8('a')
+        .word16be('bc')
+        .loop(function (end) {
+            var x = this.word8s('x').vars.x;
+            if (x < 0) end();
+        })
+        .tap(function (vars) {
+            t.same(vars, {
+                a : 97,
+                bc : 25187,
+                x : -3,
+            });
+        })
+        .word8('y')
+        .vars
+    ;
+    t.same(res, {
+        a : 97,
+        bc : 25187,
+        x : -3,
+        y : 9,
+    });
+});

+ 40 - 0
lib/unzip/node_modules/binary/test/peek.js

@@ -0,0 +1,40 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('peek', function (t) {
+    t.plan(4);
+    var bufs = [
+        new Buffer([ 6, 1, 6, 1, 6, 9, 0, 0, 0, 97 ]),
+        new Buffer([ 98, 99 ]),
+        new Buffer([ 100, 101, 102 ]),
+    ];
+    
+    var stream = new EventEmitter;
+    var iv = setInterval(function () {
+        var buf = bufs.shift();
+        if (buf) stream.emit('data', buf)
+        else clearInterval(iv)
+    }, 20);
+    
+    binary.stream(stream)
+        .buffer('sixone', 5)
+        .peek(function () {
+            this.word32le('len');
+        })
+        .buffer('buf', 'len')
+        .word8('x')
+        .tap(function (vars) {
+            t.same(
+                [].slice.call(vars.sixone),
+                [].slice.call(new Buffer([ 6, 1, 6, 1, 6 ]))
+            );
+            t.same(vars.buf.length, vars.len);
+            t.same(
+                [].slice.call(vars.buf),
+                [ 9, 0, 0, 0, 97, 98, 99, 100, 101 ]
+            );
+            t.same(vars.x, 102);
+        })
+    ;
+});

+ 49 - 0
lib/unzip/node_modules/binary/test/pipe.js

@@ -0,0 +1,49 @@
+var binary = require('../');
+var test = require('tap').test;
+var Stream = require('stream').Stream;
+
+test('loop', function (t) {
+    t.plan(3 * 2 + 1);
+    
+    var rs = new Stream;
+    rs.readable = true;
+    
+    var ws = binary()
+        .loop(function (end, vars) {
+            t.strictEqual(vars, this.vars);
+            this
+                .word16lu('a')
+                .word8u('b')
+                .word8s('c')
+                .tap(function (vars_) {
+                    t.strictEqual(vars, vars_);
+                    if (vars.c < 0) end();
+                })
+            ;
+        })
+        .tap(function (vars) {
+            t.same(vars, { a : 1337, b : 55, c : -5 });
+        })
+    ;
+    rs.pipe(ws);
+    
+    setTimeout(function () {
+        rs.emit('data', new Buffer([ 2, 10, 88 ]));
+    }, 10);
+    setTimeout(function () {
+        rs.emit('data', new Buffer([ 100, 3, 6, 242, 30 ]));
+    }, 20);
+    setTimeout(function () {
+        rs.emit('data', new Buffer([ 60, 60, 199, 44 ]));
+    }, 30);
+    
+    setTimeout(function () {
+        rs.emit('data', new Buffer([ 57, 5 ]));
+    }, 80);
+    setTimeout(function () {
+        rs.emit('data', new Buffer([ 55, 251 ]));
+    }, 90);
+    setTimeout(function () {
+        rs.emit('end');
+    }, 100);
+});

+ 29 - 0
lib/unzip/node_modules/binary/test/posbs.js

@@ -0,0 +1,29 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('posbs', function (t) {
+    t.plan(4);
+    // note: can't store 12667700813876161 exactly in an ieee float
+    
+    var buf = new Buffer([
+        30, // a == -30
+        9, 37, // b == -2341
+        0, 12, 10, 20, // c == -789012
+        0, 45, 1, 52, 239, 33, 203, 193, // d == 12667700813876161
+    ]);
+    
+    binary.parse(buf)
+        .word8bs('a')
+        .word16bs('b')
+        .word32bs('c')
+        .word64bs('d')
+        .tap(function (vars) {
+            t.same(vars.a, 30);
+            t.same(vars.b, 2341);
+            t.same(vars.c, 789012);
+            t.ok(
+                Math.abs(vars.d - 12667700813876161) < 1000
+            );
+        })
+    ;
+});

+ 29 - 0
lib/unzip/node_modules/binary/test/posls.js

@@ -0,0 +1,29 @@
+var binary = require('../');
+var test = require('tap').test;
+
+test('posls', function (t) {
+    t.plan(4);
+    
+    // note: can't store 12667700813876161 exactly in an ieee float
+    var buf = new Buffer([
+        30, // a == -30
+        37, 9, // b == -2341
+        20, 10, 12, 0, // c == -789012
+        193, 203, 33, 239, 52, 1, 45, 0, // d == 12667700813876161
+    ]);
+    
+    binary.parse(buf)
+        .word8ls('a')
+        .word16ls('b')
+        .word32ls('c')
+        .word64ls('d')
+        .tap(function (vars) {
+            t.same(vars.a, 30);
+            t.same(vars.b, 2341);
+            t.same(vars.c, 789012);
+            t.ok(
+                Math.abs(vars.d - 12667700813876161) < 1000
+            );
+        })
+    ;
+});

+ 33 - 0
lib/unzip/node_modules/binary/test/scan.js

@@ -0,0 +1,33 @@
+var binary = require('../');
+var test = require('tap').test;
+var EventEmitter = require('events').EventEmitter;
+
+test('scan', function (t) {
+    t.plan(4);
+    
+    var em = new EventEmitter;
+    binary(em)
+        .word8('a')
+        .scan('l1', new Buffer('\r\n'))
+        .scan('l2', '\r\n')
+        .word8('z')
+        .tap(function (vars) {
+            t.same(vars.a, 99);
+            t.same(vars.l1.toString(), 'foo bar');
+            t.same(vars.l2.toString(), 'baz');
+            t.same(vars.z, 42);
+        })
+    ;
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer([99,0x66,0x6f,0x6f,0x20]));
+    }, 20);
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer('bar\r'));
+    }, 40);
+    
+    setTimeout(function () {
+        em.emit('data', new Buffer('\nbaz\r\n*'));
+    }, 60);
+});

Some files were not shown because too many files changed in this diff