Merge branch 'develop' into 'master'

Version 2.2

Pull Request tracking changes leading up to version 2.2

See merge request !1
This commit is contained in:
Timothy Warren 2016-02-10 12:29:39 -05:00
commit 1fb95adfbf
71 changed files with 4744 additions and 4138 deletions

19
.gitignore vendored
View File

@ -1,21 +1,22 @@
.codelite
.phing_targets
.sonar/
*.phprj
*.workspace
vendor
app/cache/*
app/logs/*
**/cache/**
**/logs/**
**/coverage/**
**/docs/**
public/images/*
public/js/cache/*
composer.lock
*.sqlite
*.db
*.sqlite3
docs/*
coverage/*
tests/test_data/sessions/*
build/coverage/*
build/logs/*
build/pdepend/*
build/phpdox/*
cache.properties
tests/test_data/cache/*
build/**
!build/*.txt
!build/*.xml
!build/*.php

7
.htaccess Normal file
View File

@ -0,0 +1,7 @@
#Rewrite index.php out of the app urls
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(public)
RewriteRule ^(.*)$ index.php/$1 [L]

View File

@ -15,9 +15,12 @@ script:
- phpunit -c build
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover build/logs/coverage.clover
- CODECLIMATE_REPO_TOKEN=2cbddcebcb9256b3402867282e119dbe61de0b31039325356af3c7d72ed6d058 vendor/bin/test-reporter
matrix:
allow_failures:
- php: nightly
addons:
code_climate:
repo_token: 2cbddcebcb9256b3402867282e119dbe61de0b31039325356af3c7d72ed6d058

View File

@ -42,9 +42,36 @@ A self-hosted client that allows custom formatting of data from the hummingbird
2. Configure settings in `app/config/config.php` to your liking
3. Create the following directories if they don't exist, and make sure they are world writable
* app/cache
* public/js/cache
* public/images/manga
* public/images/anime
* public/js/cache
### Server Setup
#### nginx
Basic nginx setup
```nginx
server {
location / {
try_files $uri $uri/ /index.php$uri?$args;
}
location ~ ^(.+\.php)($|/) {
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_index index.php;
}
location ^~ /vendor {
deny all;
}
}
```
#### Apache
Make sure to have `mod_rewrite` and `AllowOverride All` enabled in order to take
advantage of the included `.htaccess` file. If you don't wish to use an `.htaccess` file,
include the contents of the `.htaccess` file in your Apache configuration.
#### Anime Collection Additional Installation
* Run `php /vendor/bin/phinx migrate -e development` to create the database tables

View File

@ -15,45 +15,67 @@
/* $config = */require 'config.php';
// Should we use myth to preprocess?
$use_myth = FALSE;
return [
/*
|--------------------------------------------------------------------------
| CSS Folder
|--------------------------------------------------------------------------
|
| The folder where css files exist, in relation to the document root
|
*/
$css_root = $config['asset_dir'] . '/css/';
/*
|--------------------------------------------------------------------------
| CSS Folder
|--------------------------------------------------------------------------
|
| The folder where css files exist, in relation to the document root
|
*/
'css_root' => $config['asset_dir'] . '/css/',
/*
|--------------------------------------------------------------------------
| Path from
|--------------------------------------------------------------------------
|
| Path fragment to rewrite in css files
|
*/
$path_from = '';
/*
|--------------------------------------------------------------------------
| Path from
|--------------------------------------------------------------------------
|
| Path fragment to rewrite in css files
|
*/
'path_from' => '',
/*
|--------------------------------------------------------------------------
| Path to
|--------------------------------------------------------------------------
|
| The path fragment replacement for the css files
|
*/
$path_to = '';
/*
|--------------------------------------------------------------------------
| Path to
|--------------------------------------------------------------------------
|
| The path fragment replacement for the css files
|
*/
'path_to' => '',
/*
|--------------------------------------------------------------------------
| JS Folder
|--------------------------------------------------------------------------
|
| The folder where javascript files exist, in relation to the document root
|
*/
$js_root = $config['asset_dir'] . '/js/';
/*
|--------------------------------------------------------------------------
| CSS Groups file
|--------------------------------------------------------------------------
|
| The file where the css groups are configured
|
*/
'css_groups_file' => realpath(__DIR__ . '/minify_css_groups.php'),
/*
|--------------------------------------------------------------------------
| JS Folder
|--------------------------------------------------------------------------
|
| The folder where javascript files exist, in relation to the document root
|
*/
'js_root' => $config['asset_dir'] . '/js/',
/*
|--------------------------------------------------------------------------
| JS Groups file
|--------------------------------------------------------------------------
|
| The file where the javascript groups are configured
|
*/
'js_groups_file' => realpath(__DIR__ . '/minify_js_groups.php'),
];
// End of minify_config.php

View File

@ -17,45 +17,33 @@
* This is the config array for javascript files to concatenate and minify
*/
return [
/*
For each group create an array like so
'my_group' => array(
'path/to/js/file1.js',
'path/to/js/file2.js'
),
*/
'table' => [
'lib/jquery.min.js',
'lib/table_sorter/jquery.tablesorter.min.js',
'sort_tables.js'
'base' => [
'base/classList.js',
'base/AnimeClient.js',
],
'edit' => [
'lib/jquery.min.js',
'show_message.js',
'anime_edit.js',
'manga_edit.js'
'event' => [
'base/events.js',
],
'table' => [
'base/sort_tables.js',
],
'table_edit' => [
'lib/jquery.min.js',
'lib/table_sorter/jquery.tablesorter.min.js',
'sort_tables.js',
'show_message.js',
'anime_edit.js',
'manga_edit.js'
'manga_edit.js',
],
'edit' => [
'anime_edit.js',
'manga_edit.js',
],
'anime_collection' => [
'lib/jquery.min.js',
'lib/jquery.throttle-debounce.js',
'lib/jsrender.js',
'anime_collection.js'
'lib/mustache.js',
'anime_collection.js',
],
'manga_collection' => [
'lib/jquery.min.js',
'lib/jquery.throttle-debounce.js',
'lib/jsrender.js',
'manga_collection.js'
]
'lib/mustache.js',
'manga_collection.js',
],
];
// End of js_groups.php

View File

@ -20,9 +20,6 @@ return [
// Specify default paths and views
// -------------------------------------------------------------------------
'route_config' => [
// Subfolder prefix for url, if in a subdirectory of the web root
'subfolder_prefix' => '',
// Path to public directory, where images/css/javascript are located,
// appended to the url
'asset_path' => '/public',
@ -56,6 +53,30 @@ return [
'action' => 'add',
'verb' => 'post'
],
'anime_detail' => [
'path' => '/anime/details/{id}',
'action' => 'details',
'tokens' => [
'id' => '[a-z0-9\-]+'
]
],
// ---------------------------------------------------------------------
// Manga Routes
// ---------------------------------------------------------------------
'manga_search' => [
'path' => '/manga/search',
'action' => 'search',
],
'manga_add_form' => [
'path' => '/manga/add',
'action' => 'add_form',
'verb' => 'get'
],
'manga_add' => [
'path' => '/manga/add',
'action' => 'add',
'verb' => 'post'
],
// ---------------------------------------------------------------------
// Anime Collection Routes
// ---------------------------------------------------------------------
@ -96,9 +117,10 @@ return [
// ---------------------------------------------------------------------
// Default / Shared routes
// ---------------------------------------------------------------------
'login' => [
'login_form' => [
'path' => '/{controller}/login',
'action' => 'login',
'verb' => 'get'
],
'login_post' => [
'path' => '/{controller}/login',
@ -130,7 +152,7 @@ return [
'action' => 'edit',
'tokens' => [
'id' => '[0-9a-z_]+',
'status' => '[a-zA-z\- ]+',
'status' => '([a-zA-Z\- ]|%20)+',
]
],
'list' => [

View File

@ -3,6 +3,11 @@
<h2>Add Anime to your List</h2>
<form action="<?= $action_url ?>" method="post">
<section>
<div class="cssload-loader" hidden="hidden">
<div class="cssload-inner cssload-one"></div>
<div class="cssload-inner cssload-two"></div>
<div class="cssload-inner cssload-three"></div>
</div>
<label for="search">Search for anime by name:&nbsp;&nbsp;&nbsp;&nbsp;<input type="search" id="search" /></label>
<section id="series_list" class="media-wrap">
</section>
@ -30,11 +35,5 @@
</table>
</form>
</main>
<template id="show_list">
<article class="media">
<div class="name"><label><input type="radio" name="id" value="{{:slug}}" />&nbsp;<span>{{:title}}<br />{{:alternate_title}}</span></label></div>
<img src="{{:cover_image}}" alt="{{:title}}" />
</article>
</template>
<script src="<?= $urlGenerator->asset_url('js.php?g=anime_collection') ?>"></script>
<script src="<?= $urlGenerator->asset_url('js.php/g/anime_collection') ?>"></script>
<?php endif ?>

View File

@ -65,5 +65,5 @@
<?php endif ?>
</main>
<?php if ($auth->is_authenticated()): ?>
<script src="<?= $urlGenerator->asset_url('js.php?g=edit') ?>"></script>
<script src="<?= $urlGenerator->asset_url('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -0,0 +1,11 @@
<main>
<h2><a href="<?= $data['url'] ?>"><?= $data['title'] ?></a></h2>
<?php if( ! empty($data['alternate_title'])): ?>
<h3><?= $data['alternate_title'] ?></h3>
<?php endif ?>
<img src="<?= $data['cover_image'] ?>" alt="<?= $data['title'] ?> cover image" />
<p><?= nl2br($data['synopsis']) ?></p>
<pre><?= print_r($data, TRUE) ?></pre>
</main>

View File

@ -85,5 +85,5 @@
</table>
</form>
</main>
<script src="<?= $urlGenerator->asset_url('js.php?g=edit') ?>"></script>
<script src="<?= $urlGenerator->asset_url('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -11,7 +11,7 @@
<thead>
<tr>
<?php if($auth->is_authenticated()): ?>
<th>&nbsp;</th>
<td class="no_border">&nbsp;</td>
<?php endif ?>
<th>Title</th>
<th>Airing Status</th>
@ -33,7 +33,7 @@
<a class="bracketed" href="<?= $urlGenerator->url("/anime/edit/{$item['id']}/{$item['watching_status']}") ?>">Edit</a>
</td>
<?php endif ?>
<td class="align_left">
<td class="justify">
<a href="<?= $item['anime']['url'] ?>" target="_blank">
<?= $item['anime']['title'] ?>
</a>
@ -42,7 +42,7 @@
<td class="align_left"><?= $item['airing']['status'] ?></td>
<td><?= $item['user_rating'] ?> / 10 </td>
<td><?= $item['anime']['type'] ?></td>
<td id="<?= $item['anime']['slug'] ?>">
<td class="align_left" id="<?= $item['anime']['slug'] ?>">
Episodes: <br />
<span class="completed_number"><?= $item['episodes']['watched'] ?></span>&nbsp;/&nbsp;<span class="total_number"><?= $item['episodes']['total'] ?></span>
</td>
@ -74,4 +74,4 @@
<?php endif ?>
</main>
<?php $group = ($auth->is_authenticated()) ? 'table_edit' : 'table' ?>
<script src="<?= $urlGenerator->asset_url("js.php?g={$group}") ?>"></script>
<script src="<?= $urlGenerator->asset_url("js.php/g/{$group}") ?>"></script>

View File

@ -3,6 +3,11 @@
<h2>Add Anime to your Collection</h2>
<form action="<?= $action_url ?>" method="post">
<section>
<div class="cssload-loader" hidden="hidden">
<div class="cssload-inner cssload-one"></div>
<div class="cssload-inner cssload-two"></div>
<div class="cssload-inner cssload-three"></div>
</div>
<label for="search">Search for anime by name:&nbsp;&nbsp;&nbsp;&nbsp;<input type="search" id="search" name="search" /></label>
<section id="series_list" class="media-wrap">
</section>
@ -34,11 +39,5 @@
</table>
</form>
</main>
<template id="show_list">
<article class="media">
<div class="name"><label><input type="radio" name="id" value="{{:id}}" />&nbsp;<span>{{:title}}<br />{{:alternate_title}}</span></label></div>
<img src="{{:cover_image}}" alt="{{:title}}" />
</article>
</template>
<script src="<?= $urlGenerator->asset_url('js.php?g=anime_collection') ?>"></script>
<script src="<?= $urlGenerator->asset_url('js.php/g/anime_collection') ?>"></script>
<?php endif ?>

View File

@ -52,5 +52,5 @@
<img src="{{:cover_image}}" alt="{{:title}}" />
</article>
</template>
<script src="<?= $urlGenerator->asset_url('js.php?g=anime_collection') ?>"></script>
<script src="<?= $urlGenerator->asset_url('js.php/g/anime_collection') ?>"></script>
<?php endif ?>

View File

@ -49,4 +49,4 @@
<?php endforeach ?>
<?php endif ?>
</main>
<script src="<?= $urlGenerator->asset_url('js.php?g=table') ?>"></script>
<script src="<?= $urlGenerator->asset_url('js.php/g/table') ?>"></script>

View File

@ -1,2 +1,3 @@
<script src="<?= $urlGenerator->asset_url('js.php/g/event') ?>"></script>
</body>
</html>

View File

@ -4,11 +4,10 @@
<head>
<title><?= $title ?></title>
<meta charset="utf-8" />
<link rel="stylesheet" href="<?= $urlGenerator->asset_url('css.php?g=base') ?>" />
<script>
var BASE_URL = "<?= $urlGenerator->base_url($url_type) ?>";
var CONTROLLER = "<?= $url_type ?>";
</script>
<meta http-equiv="cache-control" content="no-store" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self'" />
<link rel="stylesheet" href="<?= $urlGenerator->asset_url('css.php/g/base') ?>" />
<script src="<?= $urlGenerator->asset_url('js.php/g/base') ?>"></script>
</head>
<body class="<?= $escape->attr($url_type) ?> list">
<header>
@ -48,11 +47,8 @@
</ul>
<?php endif ?>
</nav>
<?php if(isset($message) && is_array($message)):
extract($message);
include 'message.php';
endif ?>
</header>
<?php if(isset($message) && is_array($message)): ?>
<div class="message <?= $escape->attr($message['message_type']) ?>">
<span class="icon"></span>
<?= $escape->html($message['message']) ?>
<span class="close" onclick="this.parentElement.style.display='none'">x</span>
</div>
<?php endif ?>

View File

@ -0,0 +1,39 @@
<?php if ($auth->is_authenticated()): ?>
<main>
<h2>Add Manga to your List</h2>
<form action="<?= $action_url ?>" method="post">
<section>
<div class="cssload-loader" hidden="hidden">
<div class="cssload-inner cssload-one"></div>
<div class="cssload-inner cssload-two"></div>
<div class="cssload-inner cssload-three"></div>
</div>
<label for="search">Search for manga by name:&nbsp;&nbsp;&nbsp;&nbsp;<input type="search" id="search" /></label>
<section id="series_list" class="media-wrap">
</section>
</section>
<br />
<table class="form">
<tbody>
<tr>
<td><label for="status">Reading Status</label></td>
<td>
<select name="status" id="status">
<?php foreach($status_list as $status_key => $status_title): ?>
<option value="<?= $status_key ?>"><?= $status_title ?></option>
<?php endforeach ?>
</select>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<button type="submit">Save</button>
</td>
</tr>
</tbody>
</table>
</form>
</main>
<script src="<?= $urlGenerator->asset_url('js.php/g/manga_collection') ?>"></script>
<?php endif ?>

View File

@ -1,4 +1,7 @@
<main>
<?php if ($auth->is_authenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->url('manga/add') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
<h3>There's nothing here!</h3>
<?php else: ?>
@ -53,5 +56,5 @@
<?php endif ?>
</main>
<?php if ($auth->is_authenticated()): ?>
<script src="<?= $urlGenerator->asset_url('js.php?g=edit') ?>"></script>
<script src="<?= $urlGenerator->asset_url('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -85,5 +85,4 @@
</table>
</form>
</main>
<script src="<?= $urlGenerator->asset_url('js.php?g=edit') ?>"></script>
<?php endif ?>

View File

@ -1,4 +1,7 @@
<main>
<?php if ($auth->is_authenticated()): ?>
<a class="bracketed" href="<?= $urlGenerator->url('manga/add') ?>">Add Item</a>
<?php endif ?>
<?php if (empty($sections)): ?>
<h3>There's nothing here!</h3>
<?php else: ?>
@ -42,4 +45,4 @@
<?php endforeach ?>
<?php endif ?>
</main>
<script src="<?= $urlGenerator->asset_url('js.php?g=table') ?>"></script>
<script src="<?= $urlGenerator->asset_url('js.php/g/table') ?>"></script>

5
app/views/message.ms Normal file
View File

@ -0,0 +1,5 @@
<div class="message {{message_type}}">
<span class="icon"></span>
{{message}}
<span class="close">x</span>
</div>

View File

@ -1,5 +1,5 @@
<div class="message <?= $escape->attr($message_type) ?>">
<span class="icon"></span>
<?= $escape->html($message) ?>
<span class="close" onclick="this.parentElement.style.display='none'">x</span>
<span class="close"></span>
</div>

114
build.xml
View File

@ -13,10 +13,6 @@
depends="prepare,static-analysis,phpunit,phpdox,sonar"
description="Performs static analysis, runs the tests, and generates project documentation"
/>
<target name="full-build-parallel"
depends="prepare,static-analysis-parallel,phpunit,phpdox"
description="Performs static analysis (executing the tools in parallel), runs the tests, and generates project documentation"
/>
<target name="quick-build"
depends="prepare,lint,phpunit-no-coverage"
description="Performs a lint check and runs the tests (without generating code coverage reports)"
@ -26,18 +22,6 @@
description="Performs static analysis"
/>
<!-- Adjust the threadCount attribute's value to the number of CPUs -->
<target name="static-analysis-parallel" description="Performs static analysis (executing the tools in parallel)">
<parallel threadCount="6">
<sequential>
<antcall target="pdepend" />
</sequential>
<antcall target="lint" />
<antcall target="phpcpd-ci" />
<antcall target="phploc-ci" />
</parallel>
</target>
<target name="clean" unless="clean.done" description="Cleanup build artifacts">
<delete dir="build/api" />
<delete dir="build/coverage" />
@ -57,23 +41,38 @@
</target>
<target name="lint" unless="lint.done" description="Perform syntax check of sourcecode files">
<apply executable="php" taskname="lint">
<parallel threadcount="6">
<apply executable="php" passthru="true" taskname="lint">
<arg value="-l" />
<fileset dir="src">
<include name="**/*.php" />
</fileset>
<fileset dir="tests">
<include name="**/*.php" />
<fileset dir=".">
<include name="src/Aviat/AnimeClient/**/*.php" />
</fileset>
</apply>
<apply executable="php" passthru="true" taskname="lint">
<arg value="-l" />
<fileset dir=".">
<include name="src/Aviat/Ion/**/*.php" />
</fileset>
</apply>
<apply executable="php" passthru="true" taskname="lint">
<arg value="-l" />
<fileset dir=".">
<include name="tests/AnimeClient/**/*.php" />
</fileset>
</apply>
<apply executable="php" passthru="true" taskname="lint">
<arg value="-l" />
<fileset dir=".">
<include name="tests/Ion/**/*.php" />
</fileset>
</apply>
</parallel>
<property name="lint.done" value="true" />
</target>
<target name="phploc" unless="phploc.done" description="Measure project size using PHPLOC and print human readable output. Intended for usage on the command line.">
<exec executable="${phploc}" taskname="phploc">
<exec executable="${phploc}" passthru="true" taskname="phploc">
<arg value="--count-tests" />
<arg path="src" />
<arg path="tests" />
@ -83,50 +82,61 @@
</target>
<target name="phploc-ci" depends="prepare" unless="phploc.done" description="Measure project size using PHPLOC and log result in CSV and XML format. Intended for usage within a continuous integration environment.">
<exec executable="${phploc}" taskname="phploc">
<arg value="--count-tests" />
<arg value="--log-csv" />
<arg path="build/logs/phploc.csv" />
<arg value="--log-xml" />
<arg path="build/logs/phploc.xml" />
<arg path="src" />
<arg path="tests" />
</exec>
<parallel threadcount="2">
<phploc countTests="true" reportType="csv" reportDirectory="build/logs" reportName="phploc" taskname="csv report">
<fileset dir=".">
<include name="src/**/*.php" />
<include name="tests/**/*.php" />
</fileset>
</phploc>
<phploc countTests="true" reportType="xml" reportDirectory="build/logs" reportName="phploc" taskname="xml report">
<fileset dir=".">
<include name="src/**/*.php" />
<include name="tests/**/*.php" />
</fileset>
</phploc>
</parallel>
<property name="phploc.done" value="true" />
</target>
<target name="pdepend" depends="prepare" unless="pdepend.done" description="Calculate software metrics using PHP_Depend and log result in XML format. Intended for usage within a continuous integration environment.">
<exec executable="${pdepend}" taskname="pdepend">
<arg value="--jdepend-xml=build/logs/jdepend.xml" />
<arg value="--jdepend-chart=build/pdepend/dependencies.svg" />
<arg value="--overview-pyramid=build/pdepend/overview-pyramid.svg" />
<arg path="src" />
</exec>
<phpdepend>
<fileset dir=".">
<include name="src/**/*.php" />
</fileset>
<logger type="jdepend-xml" outfile="build/logs/jdepend.xml" />
<logger type="jdepend-chart" outfile="build/pdepend/dependencies.svg" />
<logger type="overview-pyramid" outfile="build/pdepend/overview-pyramid.svg" />
</phpdepend>
<property name="pdepend.done" value="true" />
</target>
<target name="phpcpd" unless="phpcpd.done" description="Find duplicate code using PHPCPD and print human readable output. Intended for usage on the command line before committing.">
<exec executable="${phpcpd}" taskname="phpcpd">
<arg path="src" />
</exec>
<phpcpd>
<formatter type="default" usefile="false" />
<fileset dir=".">
<include name="src/**/*.php" />
</fileset>
</phpcpd>
<property name="phpcpd.done" value="true" />
</target>
<target name="phpcpd-ci" depends="prepare" unless="phpcpd.done" description="Find duplicate code using PHPCPD and log result in XML format. Intended for usage within a continuous integration environment.">
<exec executable="${phpcpd}" taskname="phpcpd">
<arg value="--log-pmd" />
<arg path="build/logs/pmd-cpd.xml" />
<arg path="src" />
</exec>
<phpcpd>
<formatter type="pmd" outfile="build/logs/pmd-cpd.xml" />
<fileset dir=".">
<include name="src/**/*.php" />
</fileset>
</phpcpd>
<property name="phpcpd.done" value="true" />
</target>
<target name="phpunit" unless="phpunit.done" depends="prepare" description="Run unit tests with PHPUnit">
<exec executable="${phpunit}" taskname="phpunit">
<exec executable="${phpunit}" logoutput="true" passthru="true" checkreturn="true" taskname="phpunit">
<arg value="--configuration" />
<arg path="build/phpunit.xml" />
</exec>
@ -135,7 +145,7 @@
</target>
<target name="phpunit-no-coverage" depends="prepare" unless="phpunit.done" description="Run unit tests with PHPUnit (without generating code coverage reports)">
<exec executable="${phpunit}" failonerror="true" taskname="phpunit">
<exec executable="${phpunit}" passthru="true" taskname="phpunit">
<arg value="--configuration" />
<arg path="build/phpunit.xml" />
<arg value="--no-coverage" />
@ -145,13 +155,13 @@
</target>
<target name="phpdox" depends="phploc-ci,phpunit" unless="phpdox.done" description="Generate project documentation using phpDox">
<exec dir="build" executable="${phpdox}" taskname="phpdox" />
<exec dir="build" executable="${phpdox}" passthru="true" taskname="phpdox" />
<property name="phpdox.done" value="true" />
</target>
<target name="sonar" depends="phpunit" unless="sonar.done" description="Generate code analysis with sonarqube">
<exec executable="${sonar}" taskname="sonar" />
<exec executable="${sonar}" passthru="true" taskname="sonar" />
<property name="sonar.done" value="true" />
</target>

View File

@ -17,5 +17,8 @@
"psr/log": "~1.0",
"robmorgan/phinx": "0.4.*",
"yosymfony/toml": "0.3.*"
},
"require-dev": {
"codeclimate/php-test-reporter": "dev-master"
}
}

View File

@ -11,20 +11,61 @@
* @license MIT
*/
// --------------------------------------------------------------------------
namespace Aviat\EasyMin;
//Get config files
require('../app/config/minify_config.php');
require_once('./min.php');
//Include the css groups
$groups = require("../app/config/minify_css_groups.php");
//Function for compressing the CSS as tightly as possible
/**
* @param string $buffer
* Simple CSS Minifier
*/
function compress($buffer) {
class CSSMin extends BaseMin {
protected $css_root;
protected $path_from;
protected $path_to;
protected $group;
protected $last_modified;
protected $requested_time;
public function __construct(array $config, array $groups)
{
$group = $_GET['g'];
$this->css_root = $config['css_root'];
$this->path_from = $config['path_from'];
$this->path_to = $config['path_to'];
$this->group = $groups[$group];
$this->last_modified = $this->get_last_modified();
$this->send();
}
/**
* Send the CSS
*
* @return void
*/
protected function send()
{
if($this->last_modified >= $this->get_if_modified() && $this->is_not_debug())
{
throw new FileNotChangedException();
}
$css = ( ! array_key_exists('debug', $_GET))
? $this->compress($this->get_css())
: $this->get_css();
$this->output($css);
}
/**
* Function for compressing the CSS as tightly as possible
*
* @param string $buffer
* @return string
*/
protected function compress($buffer)
{
//Remove CSS comments
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
@ -48,90 +89,89 @@ function compress($buffer) {
$buffer = str_replace('} ', '}', $buffer);
return $buffer;
}
function get_last_modifed()
{
global $groups, $css_root;
}
/**
* Get the most recent file modification date
*
* @return int
*/
protected function get_last_modified()
{
$modified = array();
// Get all the css files, and concatenate them together
if(isset($groups[$_GET['g']]))
if(isset($this->group))
{
foreach($groups[$_GET['g']] as $file)
foreach($this->group as $file)
{
$new_file = realpath($css_root.$file);
$new_file = realpath("{$this->css_root}{$file}");
$modified[] = filemtime($new_file);
}
}
//Add myth css file for last modified check
$modified[] = filemtime(realpath("css/base.myth.css"));
//Add this page for last modified check
$modified[] = filemtime(__FILE__);
//Get the latest modified date
rsort($modified);
$last_modified = $modified[0];
return $last_modified;
}
function get_css()
{
global $groups, $path_from, $path_to, $css_root;
return array_shift($modified);
}
/**
* Get the css to display
*
* @return string
*/
protected function get_css()
{
$css = '';
if(isset($groups[$_GET['g']]))
foreach($this->group as $file)
{
foreach($groups[$_GET['g']] as $file)
{
$new_file = realpath($css_root.$file);
$new_file = realpath("{$this->css_root}{$file}");
$css .= file_get_contents($new_file);
$modified[] = filemtime($new_file);
}
}
// If not in debug mode, minify the css
if( ! isset($_GET['debug']))
{
$css = compress($css);
}
// Correct paths that have changed due to concatenation
// based on rules in the config file
$css = strtr($css, $path_from, $path_to);
$css = str_replace($this->path_from, $this->path_to, $css);
return $css;
}
/**
* Output the CSS
*
* @return void
*/
protected function output($css)
{
$this->send_final_output($css, 'text/css', $this->last_modified);
}
}
// --------------------------------------------------------------------------
$last_modified = get_last_modifed();
// ! Start Minifying
// --------------------------------------------------------------------------
$requested_time=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: 0;
//Get config files
$config = require('../app/config/minify_config.php');
$groups = require($config['css_groups_file']);
// Send 304 when not modified for faster response
if($last_modified === $requested_time)
if ( ! array_key_exists($_GET['g'], $groups))
{
header("HTTP/1.1 304 Not Modified");
exit();
throw new InvalidArgumentException('You must specify a css group that exists');
}
//This GZIPs the CSS for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
try
{
new CSSMin($config, $groups);
}
catch (FileNotChangedException $e)
{
BaseMin::send304();
}
header("Content-Type: text/css; charset=utf8");
header("Cache-control: public, max-age=691200, must-revalidate");
header("Last-Modified: ".gmdate('D, d M Y H:i:s', $last_modified)." GMT");
header("Expires: ".gmdate('D, d M Y H:i:s', (filemtime(basename(__FILE__)) + 691200))." GMT");
echo get_css();
ob_end_flush();
//End of css.php

View File

@ -6,53 +6,46 @@ body {
margin: 0.5em;
}
a:hover,
a:active {
color: #7d12db;
button {
background: rgba(255,255,255,0.65);
margin: 0;
}
table {
width: 85%;
min-width: 85%;
margin: 0 auto;
}
tbody > tr:nth-child(odd) {
background: #ddd;
td {
padding: 1em;
padding: 1rem;
}
thead td,
thead th {
padding: 0.5em;
padding: 0.5rem;
}
input[type=number] {
width: 4em;
}
.form {
width: 100%;
tbody > tr:nth-child(odd) {
background: #ddd;
}
.form tr > td:nth-child(odd) {
text-align: right;
min-width: 25px;
max-width: 30%;
a:hover,
a:active {
color: #7d12db;
}
.form tr > td:nth-child(even) {
text-align: left;
min-width: 70%;
}
/* -----------------------------------------------------------------------------
Utility classes
------------------------------------------------------------------------------*/
.form thead th,
.form thead tr {
background: inherit;
border: 0;
}
.form.invisible tr:nth-child(odd) {
background: inherit;
}
.form.invisible tr,
.form.invisible td,
.form.invisible th {
border: 0;
.bracketed {
color: #12db18;
}
.bracketed,
@ -68,10 +61,6 @@ h1 a {
content: '\00a0]';
}
.bracketed {
color: #12db18;
}
.bracketed:hover,
.bracketed:active {
color: #db7d12;
@ -132,6 +121,10 @@ h1 a {
font-size: 1.6rem;
}
.justify {
text-align: justify;
}
.align_center {
text-align: center;
}
@ -144,11 +137,257 @@ h1 a {
text-align: right;
}
.no_border {
border: none;
}
.media-wrap {
text-align: center;
margin: 0 auto;
}
/* -----------------------------------------------------------------------------
CSS loading icon
------------------------------------------------------------------------------*/
.cssload-loader {
position: relative;
left: calc(50% - 31px);
width: 62px;
height: 62px;
border-radius: 50%;
-webkit-perspective: 780px;
perspective: 780px;
}
.cssload-inner {
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
border-radius: 50%;
}
.cssload-inner.cssload-one {
left: 0%;
top: 0%;
-webkit-animation: cssload-rotate-one 1.15s linear infinite;
animation: cssload-rotate-one 1.15s linear infinite;
border-bottom: 3px solid rgb(0,0,0);
}
.cssload-inner.cssload-two {
right: 0%;
top: 0%;
-webkit-animation: cssload-rotate-two 1.15s linear infinite;
animation: cssload-rotate-two 1.15s linear infinite;
border-right: 3px solid rgb(0,0,0);
}
.cssload-inner.cssload-three {
right: 0%;
bottom: 0%;
-webkit-animation: cssload-rotate-three 1.15s linear infinite;
animation: cssload-rotate-three 1.15s linear infinite;
border-top: 3px solid rgb(0,0,0);
}
@-webkit-keyframes cssload-rotate-one {
0% {
-webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
-webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
@keyframes cssload-rotate-one {
0% {
-webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
-webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
@-webkit-keyframes cssload-rotate-two {
0% {
-webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
-webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
@keyframes cssload-rotate-two {
0% {
-webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
-webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
@-webkit-keyframes cssload-rotate-three {
0% {
-webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
-webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
@keyframes cssload-rotate-three {
0% {
-webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
-webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
/* -----------------------------------------------------------------------------
Table sorting and form styles
------------------------------------------------------------------------------*/
.sorting,
.sorting_asc,
.sorting_desc {
vertical-align: text-bottom;
}
.sorting::before {
content: " ↕\00a0";
}
.sorting_asc::before {
content: " ↑\00a0";
}
.sorting_desc::before {
content: " ↓\00a0";
}
.form {
width: 100%;
}
.form thead th,
.form thead tr {
background: inherit;
border: 0;
}
.form tr > td:nth-child(odd) {
text-align: right;
min-width: 25px;
max-width: 30%;
}
.form tr > td:nth-child(even) {
text-align: left;
min-width: 70%;
}
.form.invisible tr:nth-child(odd) {
background: inherit;
}
.form.invisible tr,
.form.invisible td,
.form.invisible th {
border: 0;
}
/* -----------------------------------------------------------------------------
Message boxes
------------------------------------------------------------------------------*/
.message {
position: relative;
margin: 0.5em auto;
padding: 0.5em;
width: 95%;
}
.message .close {
width: 1em;
height: 1em;
position: absolute;
right: 0.5em;
top: 0.5em;
text-align: center;
vertical-align: middle;
line-height: 1em;
}
/*.message .close:after {
content: '☐';
}*/
.message:hover .close:after {
content: '☒';
}
.message:hover {
cursor: pointer;
}
.message .icon {
left: 0.5em;
top: 0.5em;
margin-right: 1em;
}
.message.error {
border: 1px solid #924949;
background: #f3e6e6;
}
.message.error .icon::after {
content: '✘';
}
.message.success {
border: 1px solid #1f8454;
background: #70dda9;
}
.message.success .icon::after {
content: '✔';
}
.message.info {
border: 1px solid #bfbe3a;
background: #FFFFCC;
}
.message.info .icon::after {
content: '⚠';
}
/* -----------------------------------------------------------------------------
Base list styles
------------------------------------------------------------------------------*/
.media {
position: relative;
vertical-align: top;
@ -159,11 +398,6 @@ h1 a {
margin: 0.25em;
}
button {
background: rgba(255,255,255,0.65);
margin: 0;
}
.media .edit_buttons > button {
margin: 0.5em auto;
}
@ -224,53 +458,6 @@ button {
text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.85);
}
/* -----------------------------------------------------------------------------
Message boxes
------------------------------------------------------------------------------*/
.message {
position: relative;
margin: 0.5em auto;
padding: 0.5em;
width: 95%;
}
.message .close {
width: 1em;
height: 1em;
position: absolute;
right: 0.5em;
top: 0.5em;
text-align: center;
vertical-align: middle;
line-height: 1em;
}
.message .close:hover {
cursor: pointer;
}
.message .icon {
left: 0.5em;
top: 0.5em;
margin-right: 1em;
}
.message.error {
border: 1px solid #924949;
background: #f3e6e6;
}
.message.success {
border: 1px solid #1f8454;
background: #70dda9;
}
.message.info {
border: 1px solid #bfbe3a;
background: #FFFFCC;
}
/* -----------------------------------------------------------------------------
Anime-list-specific styles
------------------------------------------------------------------------------*/
@ -371,3 +558,52 @@ button {
left: 5px;
left: calc(50% - 95px);
}
/* -----------------------------------------------------------------------------
Page-specific styles
------------------------------------------------------------------------------*/
.media.search > .name {
background-color: #555;
background-color: rgba(000,000,000,0.35);
background-size: cover;
background-size: contain;
background-repeat: no-repeat;
}
.big-check {
display: none;
}
.big-check:checked + label {
-webkit-transition: .25s ease;
transition: .25s ease;
background: rgba(0,0,0,0.75);
}
.big-check:checked + label:after {
content: '✓';
font-size: 15em;
font-size: 15rem;
text-align: center;
color: greenyellow;
position: absolute;
top: 5px;
left: 0;
height: 100%;
width: 100%;
}
#series_list article.media {
position: relative;
}
#series_list .name,
#series_list .name label {
position: absolute;
display: block;
top: 0;
height: 100%;
width: 100%;
vertical-align: middle;
}

View File

@ -13,54 +13,50 @@ template {display:none}
body {margin: 0.5em;}
a:hover, a:active {
color: var(--link-hover-color)
button {
background:rgba(255,255,255,0.65);
margin: 0;
}
table {
width:85%;
min-width:85%;
margin: 0 auto;
}
tbody > tr:nth-child(odd) {
background: #ddd;
td {
padding:1em;
padding:1rem;
}
thead td, thead th {
padding:0.5em;
padding:0.5rem;
}
input[type=number] {
width: 4em;
}
.form { width:100%; }
.form tr > td:nth-child(odd) {
text-align:right;
min-width:25px;
max-width:30%;
}
.form tr > td:nth-child(even) {
text-align:left;
min-width:70%;
tbody > tr:nth-child(odd) {
background: #ddd;
}
.form thead th, .form thead tr {
background: inherit;
border:0;
a:hover, a:active {
color: var(--link-hover-color)
}
.form.invisible tr:nth-child(odd) {
background: inherit;
}
.form.invisible tr, .form.invisible td, .form.invisible th {
border:0;
}
/* -----------------------------------------------------------------------------
Utility classes
------------------------------------------------------------------------------*/
.bracketed {
color: var(--edit-link-color);
}
.bracketed, h1 a {
text-shadow: var(--link-shadow);
}
.bracketed:before {content: '[\00a0'}
.bracketed:after {content: '\00a0]'}
.bracketed {
color: var(--edit-link-color);
}
.bracketed:hover, .bracketed:active {
color: var(--edit-link-hover-color)
}
@ -78,15 +74,202 @@ input[type=number] {
font-size:1.6rem;
}
.justify {text-align:justify}
.align_center {text-align:center}
.align_left {text-align:left;}
.align_right {text-align:right;}
.align_left {text-align:left}
.align_right {text-align:right}
.no_border {border:none}
.media-wrap {
text-align:center;
margin:0 auto;
}
/* -----------------------------------------------------------------------------
CSS loading icon
------------------------------------------------------------------------------*/
.cssload-loader {
position: relative;
left: calc(50% - 31px);
width: 62px;
height: 62px;
border-radius: 50%;
perspective: 780px;
}
.cssload-inner {
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
border-radius: 50%;
}
.cssload-inner.cssload-one {
left: 0%;
top: 0%;
animation: cssload-rotate-one 1.15s linear infinite;
border-bottom: 3px solid rgb(0,0,0);
}
.cssload-inner.cssload-two {
right: 0%;
top: 0%;
animation: cssload-rotate-two 1.15s linear infinite;
border-right: 3px solid rgb(0,0,0);
}
.cssload-inner.cssload-three {
right: 0%;
bottom: 0%;
animation: cssload-rotate-three 1.15s linear infinite;
border-top: 3px solid rgb(0,0,0);
}
@keyframes cssload-rotate-one {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
@keyframes cssload-rotate-two {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
@keyframes cssload-rotate-three {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
/* -----------------------------------------------------------------------------
Table sorting and form styles
------------------------------------------------------------------------------*/
.sorting,
/*.sorting::before,*/
.sorting_asc,
/*.sorting_asc::before,*/
.sorting_desc
/*.sorting_desc::before*/ {
vertical-align:text-bottom;
}
.sorting::before {
content: " ↕\00a0";
}
.sorting_asc::before {
content: " ↑\00a0";
}
.sorting_desc::before {
content: " ↓\00a0";
}
.form { width:100%; }
.form thead th, .form thead tr {
background: inherit;
border:0;
}
.form tr > td:nth-child(odd) {
text-align:right;
min-width:25px;
max-width:30%;
}
.form tr > td:nth-child(even) {
text-align:left;
min-width:70%;
}
.form.invisible tr:nth-child(odd) {
background: inherit;
}
.form.invisible tr, .form.invisible td, .form.invisible th {
border:0;
}
/* -----------------------------------------------------------------------------
Message boxes
------------------------------------------------------------------------------*/
.message{
position:relative;
margin:0.5em auto;
padding:0.5em;
width:95%;
}
.message .close{
width:1em;
height:1em;
position:absolute;
right:0.5em;
top:0.5em;
text-align:center;
vertical-align:middle;
line-height:1em;
}
/*.message .close:after {
content: '☐';
}*/
.message:hover .close:after {
content: '☒';
}
.message:hover {
cursor:pointer;
}
.message .icon{
left:0.5em;
top:0.5em;
margin-right:1em;
}
.message.error{
border:1px solid #924949;
background: #f3e6e6;
}
.message.error .icon::after {
content: '✘';
}
.message.success{
border:1px solid #1f8454;
background: #70dda9;
}
.message.success .icon::after {
content: '✔'
}
.message.info{
border:1px solid #bfbe3a;
background: #FFFFCC;
}
.message.info .icon::after {
content: '⚠';
}
/* -----------------------------------------------------------------------------
Base list styles
------------------------------------------------------------------------------*/
.media {
position:relative;
vertical-align:top;
@ -97,11 +280,6 @@ input[type=number] {
margin: var(--normal-padding);
}
button {
background:rgba(255,255,255,0.65);
margin: 0;
}
.media .edit_buttons > button {
margin:0.5em auto;
}
@ -161,52 +339,7 @@ button {
text-shadow: var(--shadow);
}
/* -----------------------------------------------------------------------------
Message boxes
------------------------------------------------------------------------------*/
.message{
position:relative;
margin:0.5em auto;
padding:0.5em;
width:95%;
}
.message .close{
width:1em;
height:1em;
position:absolute;
right:0.5em;
top:0.5em;
text-align:center;
vertical-align:middle;
line-height:1em;
}
.message .close:hover {
cursor:pointer;
}
.message .icon{
left:0.5em;
top:0.5em;
margin-right:1em;
}
.message.error{
border:1px solid #924949;
background: #f3e6e6;
}
.message.success{
border:1px solid #1f8454;
background: #70dda9;
}
.message.info{
border:1px solid #bfbe3a;
background: #FFFFCC;
}
/* -----------------------------------------------------------------------------
Anime-list-specific styles
@ -293,3 +426,52 @@ button {
left: 5px;
left: calc(50% - 95px);
}
/* -----------------------------------------------------------------------------
Page-specific styles
------------------------------------------------------------------------------*/
.media.search > .name {
background-color:#555;
background-color: rgba(000,000,000,0.35);
background-size: cover;
background-size: contain;
background-repeat: no-repeat;
}
.big-check {
display:none;
}
.big-check:checked + label {
transition: .25s ease;
background:rgba(0,0,0,0.75);
}
.big-check:checked + label:after {
content: '✓';
font-size: 15em;
font-size: 15rem;
text-align:center;
color: greenyellow;
position:absolute;
top:5px;
left:0;
height:100%;
width:100%;
}
#series_list article.media {
position:relative;
}
#series_list .name, #series_list .name label {
position:absolute;
display:block;
top:0;
height:100%;
width:100%;
vertical-align:middle;
}

View File

@ -111,7 +111,6 @@ button,
input,
select,
textarea {
/*background-color: transparent;*/
border: .1rem solid #ccc;
color: inherit;
font-family: inherit;
@ -507,7 +506,7 @@ textarea {
input[type=submit],
button {
background-color: transparent;
/*background-color: transparent;*/
border: .2rem solid #444;
border-radius: 0;
color: #444;

View File

@ -78,7 +78,6 @@ audio, canvas, iframe, img, svg, video {
vertical-align: middle; }
button, input, select, textarea {
/*background-color: transparent;*/
border: .1rem solid #ccc;
color: inherit;
font-family: inherit;
@ -342,7 +341,7 @@ textarea {
vertical-align: middle; }
input[type=submit], button {
background-color: transparent;
/*background-color: transparent;*/
border: .2rem solid #444;
border-radius: 0;
color: #444;

View File

@ -11,216 +11,236 @@
* @license MIT
*/
// --------------------------------------------------------------------------
namespace Aviat\EasyMin;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
//Get config files
require_once('../app/config/minify_config.php');
//Include the js groups
$groups_file = "../app/config/minify_js_groups.php";
$groups = require_once($groups_file);
// Include guzzle
require_once('../vendor/autoload.php');
//The name of this file
$this_file = __FILE__;
// --------------------------------------------------------------------------
require_once('./min.php');
/**
* Simple Javascript minfier, using google closure compiler
*/
class JSMin extends BaseMin {
protected $js_root;
protected $js_group;
protected $js_groups_file;
protected $cache_file;
protected $last_modified;
protected $requested_time;
protected $cache_modified;
public function __construct(array $config, array $groups)
{
$group = $_GET['g'];
$this->js_root = $config['js_root'];
$this->js_group = $groups[$group];
$this->js_groups_file = $config['js_groups_file'];
$this->cache_file = "{$this->js_root}cache/{$group}";
$this->last_modified = $this->get_last_modified();
$this->cache_modified = (is_file($this->cache_file))
? filemtime($this->cache_file)
: 0;
// Output some JS!
$this->send();
}
protected function send()
{
// Override caching if debug key is set
if($this->is_debug_call())
{
return $this->output($this->get_files());
}
// If the browser's cached version is up to date,
// don't resend the file
if($this->last_modified == $this->get_if_modified() && $this->is_not_debug())
{
throw new FileNotChangedException();
}
if($this->cache_modified < $this->last_modified)
{
$js = $this->minify($this->get_files());
//Make sure cache file gets created/updated
if (file_put_contents($this->cache_file, $js) === FALSE)
{
echo 'Cache file was not created. Make sure you have the correct folder permissions.';
return;
}
return $this->output($js);
}
else
{
return $this->output(file_get_contents($this->cache_file));
}
}
/**
* Makes a call to google closure compiler service
*
* @param array $options - Form parameters
* @return object
*/
protected function closure_call(array $options)
{
$client = new Client();
$response = $client->post('http://closure-compiler.appspot.com/compile', [
'headers' => [
'Accept-Encoding' => 'gzip',
'Content-type' => 'application/x-www-form-urlencoded'
],
'form_params' => $options
]);
return $response;
}
/**
* Do a call to the closure compiler to check for compilation errors
*
* @param array $options
* @return void
*/
protected function check_minify_errors($options)
{
$error_res = $this->closure_call($options);
$error_json = $error_res->getBody();
$error_obj = json_decode($error_json) ?: (object)[];
// Show error if exists
if ( ! empty($error_obj->errors) || ! empty($error_obj->serverErrors))
{
$error_json = json_encode($error_obj, JSON_PRETTY_PRINT);
header('Content-type: application/javascript');
echo "console.error(${error_json});";
die();
}
}
/**
* Get Files
*
* Concatenates the javascript files for the current
* group as a string
*
* @return string
*/
function get_files()
{
global $groups, $js_root;
protected function get_files()
{
$js = '';
foreach($groups[$_GET['g']] as $file)
foreach($this->js_group as $file)
{
$new_file = realpath($js_root.$file);
$new_file = realpath("{$this->js_root}{$file}");
$js .= file_get_contents($new_file) . "\n\n";
}
return $js;
}
}
// --------------------------------------------------------------------------
/**
* Google Min
/**
* Get the most recent modified date
*
* Minifies javascript using google's closure compiler
* @param string $new_file
* @return string
* @return int
*/
function google_min($new_file)
{
$options = [
'output_info' => 'errors',
'output_format' => 'json',
'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
'js_code' => $new_file,
'language' => 'ECMASCRIPT5',
'language_out' => 'ECMASCRIPT5_STRICT'
];
// First check for errors
$error_client = new Client();
$error_res = $error_client->post('http://closure-compiler.appspot.com/compile', [
'headers' => [
'Accept-Encoding' => 'gzip',
"Content-type" => "application/x-www-form-urlencoded"
],
'form_params' => $options
]);
$error_json = $error_res->getBody();
$error_obj = json_decode($error_json);
if ( ! empty($error_obj->errors))
protected function get_last_modified()
{
?><pre><?= json_encode($err_obj, JSON_PRETTY_PRINT) ?></pre><?php
die();
}
$modified = array();
// Now actually retrieve the compiled code
$options['output_info'] = 'compiled_code';
$client = new Client();
$res = $client->post('http://closure-compiler.appspot.com/compile', [
'headers' => [
'Accept-Encoding' => 'gzip',
"Content-type" => "application/x-www-form-urlencoded"
],
'form_params' => $options
]);
$json = $res->getBody();
$obj = json_decode($json);
return $obj->compiledCode;
}
// --------------------------------------------------------------------------
//Creative rewriting of /g/groupname to ?g=groupname
$pi = $_SERVER['PATH_INFO'];
$pia = explode('/', $pi);
$pia_len = count($pia);
$i = 1;
while($i < $pia_len)
{
$j = $i+1;
$j = (isset($pia[$j])) ? $j : $i;
$_GET[$pia[$i]] = $pia[$j];
$i = $j + 1;
};
// --------------------------------------------------------------------------
$js = '';
$modified = array();
// --------------------------------------------------------------------------
//Aggregate the last modified times of the files
if(isset($groups[$_GET['g']]))
{
if ( ! is_dir($js_root . 'cache'))
foreach($this->js_group as $file)
{
mkdir($js_root . 'cache');
}
$cache_file = $js_root.'cache/'.$_GET['g'];
foreach($groups[$_GET['g']] as $file)
{
$new_file = realpath($js_root.$file);
$new_file = realpath("{$this->js_root}{$file}");
$modified[] = filemtime($new_file);
}
//Add this page too, as well as the groups file
$modified[] = filemtime($this_file);
$modified[] = filemtime($groups_file);
$modified[] = filemtime(__FILE__);
$modified[] = filemtime($this->js_groups_file);
$cache_modified = 0;
rsort($modified);
$last_modified = $modified[0];
//Add the cache file
if(is_file($cache_file))
return $last_modified;
}
/**
* Minifies javascript using google's closure compiler
*
* @param string $js
* @return string
*/
protected function minify($js)
{
$cache_modified = filemtime($cache_file);
$options = [
'output_info' => 'errors',
'output_format' => 'json',
'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
//'compilation_level' => 'ADVANCED_OPTIMIZATIONS',
'js_code' => $js,
'language' => 'ECMASCRIPT6_STRICT',
'language_out' => 'ECMASCRIPT5_STRICT'
];
// Check for errors
$this->check_minify_errors($options);
// Now actually retrieve the compiled code
$options['output_info'] = 'compiled_code';
$res = $this->closure_call($options);
$json = $res->getBody();
$obj = json_decode($json);
return $obj->compiledCode;
}
/**
* Output the minified javascript
*
* @param string $js
* @return void
*/
protected function output($js)
{
$this->send_final_output($js, 'application/javascript', $this->last_modified);
}
}
else //Nothing to display? Just exit
{
die("You must specify a group that exists");
}
// --------------------------------------------------------------------------
//Get the latest modified date
rsort($modified);
$last_modified = $modified[0];
$requested_time=(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: time();
// If the browser's cached version is up to date,
// don't resend the file
if($last_modified === $requested_time)
{
header("HTTP/1.1 304 Not Modified");
exit();
}
// ! Start Minifying
// --------------------------------------------------------------------------
//Determine what to do: rebuild cache, send files as is, or send cache.
// If debug is set, just concatenate
if(isset($_GET['debug']))
{
$js = get_files();
}
else if($cache_modified < $last_modified)
{
$js = google_min(get_files());
$config = require_once('../app/config/minify_config.php');
$groups = require_once($config['js_groups_file']);
$cache_dir = "{$config['js_root']}cache";
//Make sure cache file gets created/updated
if(file_put_contents($cache_file, $js) === FALSE)
{
die("Cache file was not created. Make sure you have the correct folder permissions.");
}
}
// Otherwise, send the cached file
else
if ( ! is_dir($cache_dir))
{
$js = file_get_contents($cache_file);
mkdir($cache_dir);
}
// --------------------------------------------------------------------------
if ( ! array_key_exists($_GET['g'], $groups))
{
throw new InvalidArgumentException('You must specify a js group that exists');
}
//This GZIPs the js for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
try
{
new JSMin($config, $groups);
}
catch (FileNotChangedException $e)
{
BaseMin::send304();
}
// Set important caching headers
header("Content-Type: application/javascript; charset=utf8");
header("Cache-control: public, max-age=691200, must-revalidate");
header("Last-Modified: ".gmdate('D, d M Y H:i:s', $last_modified)." GMT");
header("Expires: ".gmdate('D, d M Y H:i:s', (filemtime($this_file) + 691200))." GMT");
echo $js;
ob_end_flush();
//end of js.php

View File

@ -1,17 +1,32 @@
(function($, undefined) {
((_) => {
function search(query, callback)
{
$.get(BASE_URL + 'collection/search', {'query':query}, callback);
'use strict';
const search = (tempHtml, query) => {
_.$('.cssload-loader')[0].removeAttribute('hidden');
_.get(_.url('/collection/search'), {'query':query}, (searchResults, status) => {
searchResults = JSON.parse(searchResults);
_.$('.cssload-loader')[0].setAttribute('hidden', 'hidden');
// Give mustache a key to iterate over
searchResults = {
anime: searchResults
};
Mustache.parse(tempHtml);
_.$('#series_list')[0].innerHTML = Mustache.render(tempHtml, searchResults);
});
};
_.get('/public/templates/anime-ajax-search-results.html', tempHtml => {
_.on('#search', 'keyup', _.throttle(250, function(e) {
let query = encodeURIComponent(this.value);
if (query === '') {
return;
}
$("#search").on('keypress', $.throttle(750, function(e) {
var query = encodeURIComponent($(this).val());
search(query, function(res) {
var template = $.templates("#show_list");
var html = template.render(res);
$('#series_list').html(html);
});
search(tempHtml, query);
}));
});
}(jQuery));
})(AnimeClient);

View File

@ -1,62 +1,58 @@
/**
* Javascript for editing anime, if logged in
*/
(function($){
((_) => {
"use strict";
if (CONTROLLER !== "anime") return;
'use strict';
// Action to increment episode count
$(".plus_one").on("click", function(e) {
e.stopPropagation();
_.on('body.anime.list', 'click', '.plus_one', function(e) {
let this_sel = this;
let parent_sel = _.closestParent(this, 'article');
var self = this;
var this_sel = $(this);
var parent_sel = $(this).closest("article, td");
var watched_count = parseInt(parent_sel.find('.completed_number').text(), 10);
var total_count = parseInt(parent_sel.find('.total_number').text(), 10);
var title = parent_sel.find('.name a').text();
let watched_count = parseInt(_.$('.completed_number', parent_sel)[0].textContent, 10);
let total_count = parseInt(_.$('.total_number', parent_sel)[0].textContent, 10);
let title = _.$('.name a', parent_sel)[0].textContent;
// Setup the update data
var data = {
id: this_sel.parent('article, td').attr('id'),
let data = {
id: parent_sel.id,
increment_episodes: true
};
// If the episode count is 0, and incremented,
// change status to currently watching
if (isNaN(watched_count) || watched_count === 0)
{
data.status = "currently-watching";
if (isNaN(watched_count) || watched_count === 0) {
data.status = 'currently-watching';
}
// If you increment at the last episode, mark as completed
if (( ! isNaN(watched_count)) && (watched_count + 1) === total_count)
{
if (( ! isNaN(watched_count)) && (watched_count + 1) === total_count) {
delete data.increment_episodes;
data.status = "completed";
data.status = 'completed';
}
// okay, lets actually make some changes!
$.ajax({
_.ajax(_.url('/anime/update'), {
data: data,
dataType: 'json',
method: 'POST',
type: 'POST',
mimeType: 'application/json',
url: BASE_URL + CONTROLLER + '/update'
}).done(function(res) {
if (res.status === 'completed')
{
$(self).closest('article, tr').hide();
success: (res) => {
if (res.status === 'completed') {
this.parentElement.addAttribute('hidden', 'hidden');
}
add_message('success', "Sucessfully updated " + title);
parent_sel.find('.completed_number').text(++watched_count);
}).fail(function() {
add_message('error', "Failed to updated " + title);
_.showMessage('success', `Sucessfully updated ${title}`);
_.$('.completed_number', parent_sel)[0].textContent = ++watched_count;
_.scrollToTop();
},
error: (xhr, errorType, error) => {
console.error(error);
_.showMessage('error', `Failed to updated ${title}. `);
_.scrollToTop();
}
});
});
}(jQuery));
})(AnimeClient);

View File

@ -0,0 +1,274 @@
var AnimeClient = (function(w) {
'use strict';
const slice = Array.prototype.slice;
// -------------------------------------------------------------------------
// ! Base
// -------------------------------------------------------------------------
function matches(elm, selector) {
let matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),
i = matches.length;
while (--i >= 0 && matches.item(i) !== elm);
return i > -1;
}
const _ = {
/**
* Placeholder function
*/
noop: () => {},
/**
* DOM selector
*
* @param {string} selector - The dom selector string
* @param {object} context
* @return {array} - array of dom elements
*/
$(selector, context) {
if (typeof selector != "string" || selector === undefined) {
return selector;
}
context = (context != null && context.nodeType === 1)
? context
: document;
let elements = [];
if (selector.match(/^#([\w]+$)/)) {
elements.push(document.getElementById(selector.split('#')[1]));
} else {
elements = slice.apply(context.querySelectorAll(selector));
}
return elements;
},
/**
* Scroll to the top of the Page
*
* @return {void}
*/
scrollToTop() {
w.scroll(0,0);
},
/**
* Display a message box
*
* @param {String} type - message type: info, error, success
* @param {String} message - the message itself
* @return {void}
*/
showMessage(type, message) {
let template =
`<div class="message ${type}">
<span class="icon"></span>
${message}
<span class="close"></span>
</div>`;
let sel = AnimeClient.$('.message')[0];
if (sel !== undefined) {
sel.innerHTML = template;
sel.removeAttribute('hidden');
} else {
_.$('header')[0].insertAdjacentHTML('beforeend', template);
}
},
/**
* Finds the closest parent element matching the passed selector
*
* @param {DOMElement} current - the current DOMElement
* @param {string} parentSelector - selector for the parent element
* @return {DOMElement|null} - the parent element
*/
closestParent(current, parentSelector) {
if (Element.prototype.closest !== undefined) {
return current.closest(parentSelector);
}
while (current !== document.documentElement) {
if (matches(current, parentSelector)) {
return current;
}
current = current.parentElement;
}
return null;
},
/**
* Generate a full url from a relative path
*
* @param {String} path - url path
* @return {String} - full url
*/
url(path) {
let uri = `//${document.location.host}`;
uri += (path.charAt(0) === '/') ? path : `/${path}`;
return uri;
},
/**
* Throttle execution of a function
*
* @see https://remysharp.com/2010/07/21/throttling-function-calls
* @see https://jsfiddle.net/jonathansampson/m7G64/
* @param {Number} interval - the minimum throttle time in ms
* @param {Function} fn - the function to throttle
* @param {Object} scope - the 'this' object for the function
* @return {void}
*/
throttle(interval, fn, scope) {
var wait = false;
return function () {
var context = scope || this;
var args = arguments;
if ( ! wait) {
fn.apply(context, args);
wait = true;
setTimeout(function() {
wait = false;
}, interval);
}
};
},
};
// -------------------------------------------------------------------------
// ! Events
// -------------------------------------------------------------------------
function addEvent(sel, event, listener) {
// Recurse!
if (! event.match(/^([\w\-]+)$/)) {
event.split(' ').forEach((evt) => {
addEvent(sel, evt, listener);
});
}
sel.addEventListener(event, listener, false);
}
function delegateEvent(sel, target, event, listener) {
// Attach the listener to the parent
addEvent(sel, event, (e) => {
// Get live version of the target selector
_.$(target, sel).forEach((element) => {
if(e.target == element) {
listener.call(element, e);
e.stopPropagation();
}
});
});
}
_.on = function (sel, event, target, listener) {
if (arguments.length === 3) {
listener = target;
_.$(sel).forEach((el) => {
addEvent(el, event, listener);
});
} else {
_.$(sel).forEach((el) => {
delegateEvent(el, target, event, listener);
});
}
}
// -------------------------------------------------------------------------
// ! Ajax
// -------------------------------------------------------------------------
/**
* Url encoding for non-get requests
*
* @param data
* @returns {string}
* @private
*/
function ajaxSerialize(data) {
let pairs = [];
Object.keys(data).forEach((name) => {
let value = data[name].toString();
name = encodeURIComponent(name);
value = encodeURIComponent(value);
pairs.push(`${name}=${value}`);
});
return pairs.join("&");
};
_.ajax = function(url, config) {
// Set some sane defaults
config = config || {};
config.data = config.data || {};
config.type = config.type || 'GET';
config.dataType = config.dataType || '';
config.success = config.success || _.noop;
config.error = config.error || _.noop;
let request = new XMLHttpRequest();
let method = String(config.type).toUpperCase();
if (method === "GET") {
url += (url.match(/\?/))
? ajaxSerialize(config.data)
: `?${ajaxSerialize(config.data)}`;
}
request.open(method, url);
request.onreadystatechange = () => {
if (request.readyState === 4) {
let responseText = '';
if (request.responseType == 'json') {
responseText = JSON.parse(request.responseText);
} else {
responseText = request.responseText;
}
if (request.status > 400) {
config.error.call(null, request.status, responseText, request.response);
} else {
config.success.call(null, responseText, request.status);
}
}
};
switch (method) {
case "GET":
request.send(null);
break;
default:
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(ajaxSerialize(config.data));
break;
}
};
_.get = function(url, data, callback) {
if (arguments.length === 2) {
callback = data;
data = {};
}
return _.ajax(url, {
data: data,
success: callback
});
};
// -------------------------------------------------------------------------
// Export
// -------------------------------------------------------------------------
return _;
})(window);

227
public/js/base/classList.js Normal file
View File

@ -0,0 +1,227 @@
/*
* classList.js: Cross-browser full element.classList implementation.
* 2014-07-23
*
* By Eli Grey, http://eligrey.com
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
/*global self, document, DOMException */
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
if ("document" in self) {
// Full polyfill for browsers with no classList support
if (!("classList" in document.createElement("_"))) {
(function(view) {
"use strict";
if (!('Element' in view)) return;
var
classListProp = "classList",
protoProp = "prototype",
elemCtrProto = view.Element[protoProp],
objCtr = Object,
strTrim = String[protoProp].trim || function() {
return this.replace(/^\s+|\s+$/g, "");
},
arrIndexOf = Array[protoProp].indexOf || function(item) {
var
i = 0,
len = this.length;
for (; i < len; i++) {
if (i in this && this[i] === item) {
return i;
}
}
return -1;
}
// Vendors: please allow content code to instantiate DOMExceptions
,
DOMEx = function(type, message) {
this.name = type;
this.code = DOMException[type];
this.message = message;
},
checkTokenAndGetIndex = function(classList, token) {
if (token === "") {
throw new DOMEx(
"SYNTAX_ERR", "An invalid or illegal string was specified"
);
}
if (/\s/.test(token)) {
throw new DOMEx(
"INVALID_CHARACTER_ERR", "String contains an invalid character"
);
}
return arrIndexOf.call(classList, token);
},
ClassList = function(elem) {
var
trimmedClasses = strTrim.call(elem.getAttribute("class") || ""),
classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [],
i = 0,
len = classes.length;
for (; i < len; i++) {
this.push(classes[i]);
}
this._updateClassName = function() {
elem.setAttribute("class", this.toString());
};
},
classListProto = ClassList[protoProp] = [],
classListGetter = function() {
return new ClassList(this);
};
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function(i) {
return this[i] || null;
};
classListProto.contains = function(token) {
token += "";
return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function() {
var
tokens = arguments,
i = 0,
l = tokens.length,
token, updated = false;
do {
token = tokens[i] + "";
if (checkTokenAndGetIndex(this, token) === -1) {
this.push(token);
updated = true;
}
}
while (++i < l);
if (updated) {
this._updateClassName();
}
};
classListProto.remove = function() {
var
tokens = arguments,
i = 0,
l = tokens.length,
token, updated = false,
index;
do {
token = tokens[i] + "";
index = checkTokenAndGetIndex(this, token);
while (index !== -1) {
this.splice(index, 1);
updated = true;
index = checkTokenAndGetIndex(this, token);
}
}
while (++i < l);
if (updated) {
this._updateClassName();
}
};
classListProto.toggle = function(token, force) {
token += "";
var
result = this.contains(token),
method = result ?
force !== true && "remove" :
force !== false && "add";
if (method) {
this[method](token);
}
if (force === true || force === false) {
return force;
} else {
return !result;
}
};
classListProto.toString = function() {
return this.join(" ");
};
if (objCtr.defineProperty) {
var classListPropDesc = {
get: classListGetter,
enumerable: true,
configurable: true
};
try {
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
} catch (ex) { // IE 8 doesn't support enumerable:true
if (ex.number === -0x7FF5EC54) {
classListPropDesc.enumerable = false;
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
}
}
} else if (objCtr[protoProp].__defineGetter__) {
elemCtrProto.__defineGetter__(classListProp, classListGetter);
}
}(self));
} else {
// There is full or partial native classList support, so just check if we need
// to normalize the add/remove and toggle APIs.
(function() {
"use strict";
var testElement = document.createElement("_");
testElement.classList.add("c1", "c2");
// Polyfill for IE 10/11 and Firefox <26, where classList.add and
// classList.remove exist but support only one argument at a time.
if (!testElement.classList.contains("c2")) {
var createMethod = function(method) {
var original = DOMTokenList.prototype[method];
DOMTokenList.prototype[method] = function(token) {
var i, len = arguments.length;
for (i = 0; i < len; i++) {
token = arguments[i];
original.call(this, token);
}
};
};
createMethod('add');
createMethod('remove');
}
testElement.classList.toggle("c3", false);
// Polyfill for IE 10 and Firefox <24, where classList.toggle does not
// support the second argument.
if (testElement.classList.contains("c3")) {
var _toggle = DOMTokenList.prototype.toggle;
DOMTokenList.prototype.toggle = function(token, force) {
if (1 in arguments && !this.contains(token) === !force) {
return force;
} else {
return _toggle.call(this, token);
}
};
}
testElement = null;
}());
}
}

13
public/js/base/events.js Normal file
View File

@ -0,0 +1,13 @@
/**
* Event handlers
*/
((ac) => {
'use strict';
// Close event for messages
ac.on('header', 'click', '.message', function () {
this.setAttribute('hidden', 'hidden');
});
})(AnimeClient);

View File

@ -0,0 +1,75 @@
const LightTableSorter = (function() {
let _cellIndex, _onClickEvent, _order, _reset, _sort, _text, _th, _toggle;
_th = null;
_cellIndex = null;
_order = '';
_text = function(row) {
return row.cells.item(_cellIndex).textContent.toLowerCase();
};
_sort = function(a, b) {
let n, textA, textB;
textA = _text(a);
textB = _text(b);
n = parseInt(textA, 10);
if (n) {
textA = n;
textB = parseInt(textB, 10);
}
if (textA > textB) {
return 1;
}
if (textA < textB) {
return -1;
}
return 0;
};
_toggle = function() {
let c;
c = _order !== 'sorting_asc' ? 'sorting_asc' : 'sorting_desc';
_th.className = (_th.className.replace(_order, '') + ' ' + c).trim();
return _order = c;
};
_reset = function() {
_th.className = _th.className.replace('sorting_asc', 'sorting').replace('sorting_desc', 'sorting');
return _order = '';
};
_onClickEvent = function(e) {
let row, rows, tbody, _i, _len;
if (_th && (_cellIndex !== e.target.cellIndex)) {
_reset();
}
_th = e.target;
if (_th.nodeName.toLowerCase() === 'th') {
_cellIndex = _th.cellIndex;
tbody = _th.offsetParent.getElementsByTagName('tbody')[0];
rows = tbody.rows;
if (rows) {
rows = Array.prototype.slice.call(rows, 0);
rows = Array.prototype.sort.call(rows, _sort);
if (_order === 'sorting_asc') {
Array.prototype.reverse.call(rows);
}
_toggle();
tbody.innerHtml = '';
for (_i = 0, _len = rows.length; _i < _len; _i++) {
row = rows[_i];
tbody.appendChild(row);
}
}
}
};
return {
init: function() {
let ths = document.getElementsByTagName('th');
let _results = [];
for (let _i = 0, _len = ths.length; _i < _len; _i++) {
let th = ths[_i];
th.className = 'sorting';
_results.push(th.onclick = _onClickEvent);
}
return _results;
}
};
})();
LightTableSorter.init();

File diff suppressed because one or more lines are too long

View File

@ -1,252 +0,0 @@
/*!
* jQuery throttle / debounce - v1.1 - 3/7/2010
* http://benalman.com/projects/jquery-throttle-debounce-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
// Script: jQuery throttle / debounce: Sometimes, less is more!
//
// *Version: 1.1, Last updated: 3/7/2010*
//
// Project Home - http://benalman.com/projects/jquery-throttle-debounce-plugin/
// GitHub - http://github.com/cowboy/jquery-throttle-debounce/
// Source - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.js
// (Minified) - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.min.js (0.7kb)
//
// About: License
//
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
//
// About: Examples
//
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
//
// Throttle - http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
// Debounce - http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/
//
// About: Support and Testing
//
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
//
// jQuery Versions - none, 1.3.2, 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1.
// Unit Tests - http://benalman.com/code/projects/jquery-throttle-debounce/unit/
//
// About: Release History
//
// 1.1 - (3/7/2010) Fixed a bug in <jQuery.throttle> where trailing callbacks
// executed later than they should. Reworked a fair amount of internal
// logic as well.
// 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over
// from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the
// no_trailing throttle parameter and debounce functionality.
//
// Topic: Note for non-jQuery users
//
// jQuery isn't actually required for this plugin, because nothing internal
// uses any jQuery methods or properties. jQuery is just used as a namespace
// under which these methods can exist.
//
// Since jQuery isn't actually required for this plugin, if jQuery doesn't exist
// when this plugin is loaded, the method described below will be created in
// the `Cowboy` namespace. Usage will be exactly the same, but instead of
// $.method() or jQuery.method(), you'll need to use Cowboy.method().
(function(window,undefined){
'$:nomunge'; // Used by YUI compressor.
// Since jQuery really isn't required for this plugin, use `jQuery` as the
// namespace only if it already exists, otherwise use the `Cowboy` namespace,
// creating it if necessary.
var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ),
// Internal method reference.
jq_throttle;
// Method: jQuery.throttle
//
// Throttle execution of a function. Especially useful for rate limiting
// execution of handlers on events like resize and scroll. If you want to
// rate-limit execution of a function to a single time, see the
// <jQuery.debounce> method.
//
// In this visualization, | is a throttled-function call and X is the actual
// callback execution:
//
// > Throttled with `no_trailing` specified as false or unspecified:
// > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
// > X X X X X X X X X X X X
// >
// > Throttled with `no_trailing` specified as true:
// > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
// > X X X X X X X X X X
//
// Usage:
//
// > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback );
// >
// > jQuery('selector').bind( 'someevent', throttled );
// > jQuery('selector').unbind( 'someevent', throttled );
//
// This also works in jQuery 1.4+:
//
// > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) );
// > jQuery('selector').unbind( 'someevent', callback );
//
// Arguments:
//
// delay - (Number) A zero-or-greater delay in milliseconds. For event
// callbacks, values around 100 or 250 (or even higher) are most useful.
// no_trailing - (Boolean) Optional, defaults to false. If no_trailing is
// true, callback will only execute every `delay` milliseconds while the
// throttled-function is being called. If no_trailing is false or
// unspecified, callback will be executed one final time after the last
// throttled-function call. (After the throttled-function has not been
// called for `delay` milliseconds, the internal counter is reset)
// callback - (Function) A function to be executed after delay milliseconds.
// The `this` context and all arguments are passed through, as-is, to
// `callback` when the throttled-function is executed.
//
// Returns:
//
// (Function) A new, throttled, function.
$.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) {
// After wrapper has stopped being called, this timeout ensures that
// `callback` is executed at the proper times in `throttle` and `end`
// debounce modes.
var timeout_id,
// Keep track of the last time `callback` was executed.
last_exec = 0;
// `no_trailing` defaults to falsy.
if ( typeof no_trailing !== 'boolean' ) {
debounce_mode = callback;
callback = no_trailing;
no_trailing = undefined;
}
// The `wrapper` function encapsulates all of the throttling / debouncing
// functionality and when executed will limit the rate at which `callback`
// is executed.
function wrapper() {
var that = this,
elapsed = +new Date() - last_exec,
args = arguments;
// Execute `callback` and update the `last_exec` timestamp.
function exec() {
last_exec = +new Date();
callback.apply( that, args );
};
// If `debounce_mode` is true (at_begin) this is used to clear the flag
// to allow future `callback` executions.
function clear() {
timeout_id = undefined;
};
if ( debounce_mode && !timeout_id ) {
// Since `wrapper` is being called for the first time and
// `debounce_mode` is true (at_begin), execute `callback`.
exec();
}
// Clear any existing timeout.
timeout_id && clearTimeout( timeout_id );
if ( debounce_mode === undefined && elapsed > delay ) {
// In throttle mode, if `delay` time has been exceeded, execute
// `callback`.
exec();
} else if ( no_trailing !== true ) {
// In trailing throttle mode, since `delay` time has not been
// exceeded, schedule `callback` to execute `delay` ms after most
// recent execution.
//
// If `debounce_mode` is true (at_begin), schedule `clear` to execute
// after `delay` ms.
//
// If `debounce_mode` is false (at end), schedule `callback` to
// execute after `delay` ms.
timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay );
}
};
// Set the guid of `wrapper` function to the same of original callback, so
// it can be removed in jQuery 1.4+ .unbind or .die by using the original
// callback as a reference.
if ( $.guid ) {
wrapper.guid = callback.guid = callback.guid || $.guid++;
}
// Return the wrapper function.
return wrapper;
};
// Method: jQuery.debounce
//
// Debounce execution of a function. Debouncing, unlike throttling,
// guarantees that a function is only executed a single time, either at the
// very beginning of a series of calls, or at the very end. If you want to
// simply rate-limit execution of a function, see the <jQuery.throttle>
// method.
//
// In this visualization, | is a debounced-function call and X is the actual
// callback execution:
//
// > Debounced with `at_begin` specified as false or unspecified:
// > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
// > X X
// >
// > Debounced with `at_begin` specified as true:
// > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
// > X X
//
// Usage:
//
// > var debounced = jQuery.debounce( delay, [ at_begin, ] callback );
// >
// > jQuery('selector').bind( 'someevent', debounced );
// > jQuery('selector').unbind( 'someevent', debounced );
//
// This also works in jQuery 1.4+:
//
// > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) );
// > jQuery('selector').unbind( 'someevent', callback );
//
// Arguments:
//
// delay - (Number) A zero-or-greater delay in milliseconds. For event
// callbacks, values around 100 or 250 (or even higher) are most useful.
// at_begin - (Boolean) Optional, defaults to false. If at_begin is false or
// unspecified, callback will only be executed `delay` milliseconds after
// the last debounced-function call. If at_begin is true, callback will be
// executed only at the first debounced-function call. (After the
// throttled-function has not been called for `delay` milliseconds, the
// internal counter is reset)
// callback - (Function) A function to be executed after delay milliseconds.
// The `this` context and all arguments are passed through, as-is, to
// `callback` when the debounced-function is executed.
//
// Returns:
//
// (Function) A new, debounced, function.
$.debounce = function( delay, at_begin, callback ) {
return callback === undefined
? jq_throttle( delay, at_begin, false )
: jq_throttle( delay, callback, at_begin !== false );
};
})(this);

File diff suppressed because it is too large Load Diff

629
public/js/lib/mustache.js Normal file
View File

@ -0,0 +1,629 @@
/*!
* mustache.js - Logic-less {{mustache}} templates with JavaScript
* http://github.com/janl/mustache.js
*/
/*global define: false Mustache: true*/
(function defineMustache (global, factory) {
if (typeof exports === 'object' && exports && typeof exports.nodeName !== 'string') {
factory(exports); // CommonJS
} else if (typeof define === 'function' && define.amd) {
define(['exports'], factory); // AMD
} else {
global.Mustache = {};
factory(global.Mustache); // script, wsh, asp
}
}(this, function mustacheFactory (mustache) {
var objectToString = Object.prototype.toString;
var isArray = Array.isArray || function isArrayPolyfill (object) {
return objectToString.call(object) === '[object Array]';
};
function isFunction (object) {
return typeof object === 'function';
}
/**
* More correct typeof string handling array
* which normally returns typeof 'object'
*/
function typeStr (obj) {
return isArray(obj) ? 'array' : typeof obj;
}
function escapeRegExp (string) {
return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
}
/**
* Null safe way of checking whether or not an object,
* including its prototype, has a given property
*/
function hasProperty (obj, propName) {
return obj != null && typeof obj === 'object' && (propName in obj);
}
// Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
// See https://github.com/janl/mustache.js/issues/189
var regExpTest = RegExp.prototype.test;
function testRegExp (re, string) {
return regExpTest.call(re, string);
}
var nonSpaceRe = /\S/;
function isWhitespace (string) {
return !testRegExp(nonSpaceRe, string);
}
var entityMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;',
'/': '&#x2F;',
'`': '&#x60;',
'=': '&#x3D;'
};
function escapeHtml (string) {
return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap (s) {
return entityMap[s];
});
}
var whiteRe = /\s*/;
var spaceRe = /\s+/;
var equalsRe = /\s*=/;
var curlyRe = /\s*\}/;
var tagRe = /#|\^|\/|>|\{|&|=|!/;
/**
* Breaks up the given `template` string into a tree of tokens. If the `tags`
* argument is given here it must be an array with two string values: the
* opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of
* course, the default is to use mustaches (i.e. mustache.tags).
*
* A token is an array with at least 4 elements. The first element is the
* mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag
* did not contain a symbol (i.e. {{myValue}}) this element is "name". For
* all text that appears outside a symbol this element is "text".
*
* The second element of a token is its "value". For mustache tags this is
* whatever else was inside the tag besides the opening symbol. For text tokens
* this is the text itself.
*
* The third and fourth elements of the token are the start and end indices,
* respectively, of the token in the original template.
*
* Tokens that are the root node of a subtree contain two more elements: 1) an
* array of tokens in the subtree and 2) the index in the original template at
* which the closing tag for that section begins.
*/
function parseTemplate (template, tags) {
if (!template)
return [];
var sections = []; // Stack to hold section tokens
var tokens = []; // Buffer to hold the tokens
var spaces = []; // Indices of whitespace tokens on the current line
var hasTag = false; // Is there a {{tag}} on the current line?
var nonSpace = false; // Is there a non-space char on the current line?
// Strips all whitespace tokens array for the current line
// if there was a {{#tag}} on it and otherwise only space.
function stripSpace () {
if (hasTag && !nonSpace) {
while (spaces.length)
delete tokens[spaces.pop()];
} else {
spaces = [];
}
hasTag = false;
nonSpace = false;
}
var openingTagRe, closingTagRe, closingCurlyRe;
function compileTags (tagsToCompile) {
if (typeof tagsToCompile === 'string')
tagsToCompile = tagsToCompile.split(spaceRe, 2);
if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)
throw new Error('Invalid tags: ' + tagsToCompile);
openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*');
closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1]));
closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1]));
}
compileTags(tags || mustache.tags);
var scanner = new Scanner(template);
var start, type, value, chr, token, openSection;
while (!scanner.eos()) {
start = scanner.pos;
// Match any text between tags.
value = scanner.scanUntil(openingTagRe);
if (value) {
for (var i = 0, valueLength = value.length; i < valueLength; ++i) {
chr = value.charAt(i);
if (isWhitespace(chr)) {
spaces.push(tokens.length);
} else {
nonSpace = true;
}
tokens.push([ 'text', chr, start, start + 1 ]);
start += 1;
// Check for whitespace on the current line.
if (chr === '\n')
stripSpace();
}
}
// Match the opening tag.
if (!scanner.scan(openingTagRe))
break;
hasTag = true;
// Get the tag type.
type = scanner.scan(tagRe) || 'name';
scanner.scan(whiteRe);
// Get the tag value.
if (type === '=') {
value = scanner.scanUntil(equalsRe);
scanner.scan(equalsRe);
scanner.scanUntil(closingTagRe);
} else if (type === '{') {
value = scanner.scanUntil(closingCurlyRe);
scanner.scan(curlyRe);
scanner.scanUntil(closingTagRe);
type = '&';
} else {
value = scanner.scanUntil(closingTagRe);
}
// Match the closing tag.
if (!scanner.scan(closingTagRe))
throw new Error('Unclosed tag at ' + scanner.pos);
token = [ type, value, start, scanner.pos ];
tokens.push(token);
if (type === '#' || type === '^') {
sections.push(token);
} else if (type === '/') {
// Check section nesting.
openSection = sections.pop();
if (!openSection)
throw new Error('Unopened section "' + value + '" at ' + start);
if (openSection[1] !== value)
throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
} else if (type === 'name' || type === '{' || type === '&') {
nonSpace = true;
} else if (type === '=') {
// Set the tags for the next time around.
compileTags(value);
}
}
// Make sure there are no open sections when we're done.
openSection = sections.pop();
if (openSection)
throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
return nestTokens(squashTokens(tokens));
}
/**
* Combines the values of consecutive text tokens in the given `tokens` array
* to a single token.
*/
function squashTokens (tokens) {
var squashedTokens = [];
var token, lastToken;
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
token = tokens[i];
if (token) {
if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
lastToken[1] += token[1];
lastToken[3] = token[3];
} else {
squashedTokens.push(token);
lastToken = token;
}
}
}
return squashedTokens;
}
/**
* Forms the given array of `tokens` into a nested tree structure where
* tokens that represent a section have two additional items: 1) an array of
* all tokens that appear in that section and 2) the index in the original
* template that represents the end of that section.
*/
function nestTokens (tokens) {
var nestedTokens = [];
var collector = nestedTokens;
var sections = [];
var token, section;
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
token = tokens[i];
switch (token[0]) {
case '#':
case '^':
collector.push(token);
sections.push(token);
collector = token[4] = [];
break;
case '/':
section = sections.pop();
section[5] = token[2];
collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
break;
default:
collector.push(token);
}
}
return nestedTokens;
}
/**
* A simple string scanner that is used by the template parser to find
* tokens in template strings.
*/
function Scanner (string) {
this.string = string;
this.tail = string;
this.pos = 0;
}
/**
* Returns `true` if the tail is empty (end of string).
*/
Scanner.prototype.eos = function eos () {
return this.tail === '';
};
/**
* Tries to match the given regular expression at the current position.
* Returns the matched text if it can match, the empty string otherwise.
*/
Scanner.prototype.scan = function scan (re) {
var match = this.tail.match(re);
if (!match || match.index !== 0)
return '';
var string = match[0];
this.tail = this.tail.substring(string.length);
this.pos += string.length;
return string;
};
/**
* Skips all text until the given regular expression can be matched. Returns
* the skipped string, which is the entire tail if no match can be made.
*/
Scanner.prototype.scanUntil = function scanUntil (re) {
var index = this.tail.search(re), match;
switch (index) {
case -1:
match = this.tail;
this.tail = '';
break;
case 0:
match = '';
break;
default:
match = this.tail.substring(0, index);
this.tail = this.tail.substring(index);
}
this.pos += match.length;
return match;
};
/**
* Represents a rendering context by wrapping a view object and
* maintaining a reference to the parent context.
*/
function Context (view, parentContext) {
this.view = view;
this.cache = { '.': this.view };
this.parent = parentContext;
}
/**
* Creates a new context using the given view with this context
* as the parent.
*/
Context.prototype.push = function push (view) {
return new Context(view, this);
};
/**
* Returns the value of the given name in this context, traversing
* up the context hierarchy if the value is absent in this context's view.
*/
Context.prototype.lookup = function lookup (name) {
var cache = this.cache;
var value;
if (cache.hasOwnProperty(name)) {
value = cache[name];
} else {
var context = this, names, index, lookupHit = false;
while (context) {
if (name.indexOf('.') > 0) {
value = context.view;
names = name.split('.');
index = 0;
/**
* Using the dot notion path in `name`, we descend through the
* nested objects.
*
* To be certain that the lookup has been successful, we have to
* check if the last object in the path actually has the property
* we are looking for. We store the result in `lookupHit`.
*
* This is specially necessary for when the value has been set to
* `undefined` and we want to avoid looking up parent contexts.
**/
while (value != null && index < names.length) {
if (index === names.length - 1)
lookupHit = hasProperty(value, names[index]);
value = value[names[index++]];
}
} else {
value = context.view[name];
lookupHit = hasProperty(context.view, name);
}
if (lookupHit)
break;
context = context.parent;
}
cache[name] = value;
}
if (isFunction(value))
value = value.call(this.view);
return value;
};
/**
* A Writer knows how to take a stream of tokens and render them to a
* string, given a context. It also maintains a cache of templates to
* avoid the need to parse the same template twice.
*/
function Writer () {
this.cache = {};
}
/**
* Clears all cached templates in this writer.
*/
Writer.prototype.clearCache = function clearCache () {
this.cache = {};
};
/**
* Parses and caches the given `template` and returns the array of tokens
* that is generated from the parse.
*/
Writer.prototype.parse = function parse (template, tags) {
var cache = this.cache;
var tokens = cache[template];
if (tokens == null)
tokens = cache[template] = parseTemplate(template, tags);
return tokens;
};
/**
* High-level method that is used to render the given `template` with
* the given `view`.
*
* The optional `partials` argument may be an object that contains the
* names and templates of partials that are used in the template. It may
* also be a function that is used to load partial templates on the fly
* that takes a single argument: the name of the partial.
*/
Writer.prototype.render = function render (template, view, partials) {
var tokens = this.parse(template);
var context = (view instanceof Context) ? view : new Context(view);
return this.renderTokens(tokens, context, partials, template);
};
/**
* Low-level method that renders the given array of `tokens` using
* the given `context` and `partials`.
*
* Note: The `originalTemplate` is only ever used to extract the portion
* of the original template that was contained in a higher-order section.
* If the template doesn't use higher-order sections, this argument may
* be omitted.
*/
Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate) {
var buffer = '';
var token, symbol, value;
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
value = undefined;
token = tokens[i];
symbol = token[0];
if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate);
else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate);
else if (symbol === '>') value = this.renderPartial(token, context, partials, originalTemplate);
else if (symbol === '&') value = this.unescapedValue(token, context);
else if (symbol === 'name') value = this.escapedValue(token, context);
else if (symbol === 'text') value = this.rawValue(token);
if (value !== undefined)
buffer += value;
}
return buffer;
};
Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate) {
var self = this;
var buffer = '';
var value = context.lookup(token[1]);
// This function is used to render an arbitrary template
// in the current context by higher-order sections.
function subRender (template) {
return self.render(template, context, partials);
}
if (!value) return;
if (isArray(value)) {
for (var j = 0, valueLength = value.length; j < valueLength; ++j) {
buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate);
}
} else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') {
buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate);
} else if (isFunction(value)) {
if (typeof originalTemplate !== 'string')
throw new Error('Cannot use higher-order sections without the original template');
// Extract the portion of the original template that the section contains.
value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);
if (value != null)
buffer += value;
} else {
buffer += this.renderTokens(token[4], context, partials, originalTemplate);
}
return buffer;
};
Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate) {
var value = context.lookup(token[1]);
// Use JavaScript's definition of falsy. Include empty arrays.
// See https://github.com/janl/mustache.js/issues/186
if (!value || (isArray(value) && value.length === 0))
return this.renderTokens(token[4], context, partials, originalTemplate);
};
Writer.prototype.renderPartial = function renderPartial (token, context, partials) {
if (!partials) return;
var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
if (value != null)
return this.renderTokens(this.parse(value), context, partials, value);
};
Writer.prototype.unescapedValue = function unescapedValue (token, context) {
var value = context.lookup(token[1]);
if (value != null)
return value;
};
Writer.prototype.escapedValue = function escapedValue (token, context) {
var value = context.lookup(token[1]);
if (value != null)
return mustache.escape(value);
};
Writer.prototype.rawValue = function rawValue (token) {
return token[1];
};
mustache.name = 'mustache.js';
mustache.version = '2.2.1';
mustache.tags = [ '{{', '}}' ];
// All high-level mustache.* functions use this writer.
var defaultWriter = new Writer();
/**
* Clears all cached templates in the default writer.
*/
mustache.clearCache = function clearCache () {
return defaultWriter.clearCache();
};
/**
* Parses and caches the given template in the default writer and returns the
* array of tokens it contains. Doing this ahead of time avoids the need to
* parse templates on the fly as they are rendered.
*/
mustache.parse = function parse (template, tags) {
return defaultWriter.parse(template, tags);
};
/**
* Renders the `template` with the given `view` and `partials` using the
* default writer.
*/
mustache.render = function render (template, view, partials) {
if (typeof template !== 'string') {
throw new TypeError('Invalid template! Template should be a "string" ' +
'but "' + typeStr(template) + '" was given as the first ' +
'argument for mustache#render(template, view, partials)');
}
return defaultWriter.render(template, view, partials);
};
// This is here for backwards compatibility with 0.4.x.,
/*eslint-disable */ // eslint wants camel cased function name
mustache.to_html = function to_html (template, view, partials, send) {
/*eslint-enable*/
var result = mustache.render(template, view, partials);
if (isFunction(send)) {
send(result);
} else {
return result;
}
};
// Export the escaping function so that the user may override it.
// See https://github.com/janl/mustache.js/issues/244
mustache.escape = escapeHtml;
// Export these mainly for testing, but also for advanced usage.
mustache.Scanner = Scanner;
mustache.Context = Context;
mustache.Writer = Writer;
}));

View File

@ -1,122 +0,0 @@
/*
* Metadata - jQuery plugin for parsing metadata from elements
*
* Copyright (c) 2006 John Resig, Yehuda Katz, J<EFBFBD>örn Zaefferer, Paul McLanahan
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id$
*
*/
/**
* Sets the type of metadata to use. Metadata is encoded in JSON, and each property
* in the JSON will become a property of the element itself.
*
* There are three supported types of metadata storage:
*
* attr: Inside an attribute. The name parameter indicates *which* attribute.
*
* class: Inside the class attribute, wrapped in curly braces: { }
*
* elem: Inside a child element (e.g. a script tag). The
* name parameter indicates *which* element.
*
* The metadata for an element is loaded the first time the element is accessed via jQuery.
*
* As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
* matched by expr, then redefine the metadata type and run another $(expr) for other elements.
*
* @name $.metadata.setType
*
* @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
* @before $.metadata.setType("class")
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
* @desc Reads metadata from the class attribute
*
* @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
* @before $.metadata.setType("attr", "data")
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
* @desc Reads metadata from a "data" attribute
*
* @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
* @before $.metadata.setType("elem", "script")
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
* @desc Reads metadata from a nested script element
*
* @param String type The encoding type
* @param String name The name of the attribute to be used to get metadata (optional)
* @cat Plugins/Metadata
* @descr Sets the type of encoding to be used when loading metadata for the first time
* @type undefined
* @see metadata()
*/
(function($) {
$.extend({
metadata : {
defaults : {
type: 'class',
name: 'metadata',
cre: /({.*})/,
single: 'metadata'
},
setType: function( type, name ){
this.defaults.type = type;
this.defaults.name = name;
},
get: function( elem, opts ){
var settings = $.extend({},this.defaults,opts);
// check for empty string in single property
if ( !settings.single.length ) settings.single = 'metadata';
var data = $.data(elem, settings.single);
// returned cached data if it already exists
if ( data ) return data;
data = "{}";
if ( settings.type == "class" ) {
var m = settings.cre.exec( elem.className );
if ( m )
data = m[1];
} else if ( settings.type == "elem" ) {
if( !elem.getElementsByTagName )
return undefined;
var e = elem.getElementsByTagName(settings.name);
if ( e.length )
data = $.trim(e[0].innerHTML);
} else if ( elem.getAttribute != undefined ) {
var attr = elem.getAttribute( settings.name );
if ( attr )
data = attr;
}
if ( data.indexOf( '{' ) <0 )
data = "{" + data + "}";
data = eval("(" + data + ")");
$.data( elem, settings.single, data );
return data;
}
}
});
/**
* Returns the metadata object for the first member of the jQuery object.
*
* @name metadata
* @descr Returns element's metadata object
* @param Object opts An object contianing settings to override the defaults
* @type jQuery
* @cat Plugins/Metadata
*/
$.fn.metadata = function( opts ){
return $.metadata.get( this[0], opts );
};
})(jQuery);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

902
public/js/lib/zepto.js Normal file
View File

@ -0,0 +1,902 @@
/* Zepto v1.1.4-95-g601372a - zepto event ajax form - zeptojs.com/license */
var Zepto = (function() {
var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice,
document = window.document,
elementDisplay = {}, classCache = {},
cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },
fragmentRE = /^\s*<(\w+|!)[^>]*>/,
singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
rootNodeRE = /^(?:body|html)$/i,
capitalRE = /([A-Z])/g,
// special attributes that should be get/set via method calls
methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],
table = document.createElement('table'),
tableRow = document.createElement('tr'),
containers = {
'tr': document.createElement('tbody'),
'tbody': table, 'thead': table, 'tfoot': table,
'td': tableRow, 'th': tableRow,
'*': document.createElement('div')
},
readyRE = /complete|loaded|interactive/,
simpleSelectorRE = /^[\w-]*$/,
class2type = {},
toString = class2type.toString,
zepto = {},
camelize, uniq,
tempParent = document.createElement('div'),
propMap = {
'tabindex': 'tabIndex',
'readonly': 'readOnly',
'for': 'htmlFor',
'class': 'className',
'maxlength': 'maxLength',
'cellspacing': 'cellSpacing',
'cellpadding': 'cellPadding',
'rowspan': 'rowSpan',
'colspan': 'colSpan',
'usemap': 'useMap',
'frameborder': 'frameBorder',
'contenteditable': 'contentEditable'
},
isArray = Array.isArray ||
function(object){ return object instanceof Array }
zepto.matches = function(element, selector) {
if (!selector || !element || element.nodeType !== 1) return false
var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector ||
element.oMatchesSelector || element.matchesSelector
if (matchesSelector) return matchesSelector.call(element, selector)
// fall back to performing a selector:
var match, parent = element.parentNode, temp = !parent
if (temp) (parent = tempParent).appendChild(element)
match = ~zepto.qsa(parent, selector).indexOf(element)
temp && tempParent.removeChild(element)
return match
}
function type(obj) {
return obj == null ? String(obj) :
class2type[toString.call(obj)] || "object"
}
function isFunction(value) { return type(value) == "function" }
function isWindow(obj) { return obj != null && obj == obj.window }
function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }
function isObject(obj) { return type(obj) == "object" }
function isPlainObject(obj) {
return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype
}
function likeArray(obj) { return typeof obj.length == 'number' }
function compact(array) { return filter.call(array, function(item){ return item != null }) }
function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }
camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
function dasherize(str) {
return str.replace(/::/g, '/')
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
.replace(/_/g, '-')
.toLowerCase()
}
uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }
function classRE(name) {
return name in classCache ?
classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))
}
function maybeAddPx(name, value) {
return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value
}
function defaultDisplay(nodeName) {
var element, display
if (!elementDisplay[nodeName]) {
element = document.createElement(nodeName)
document.body.appendChild(element)
display = getComputedStyle(element, '').getPropertyValue("display")
element.parentNode.removeChild(element)
display == "none" && (display = "block")
elementDisplay[nodeName] = display
}
return elementDisplay[nodeName]
}
function children(element) {
return 'children' in element ?
slice.call(element.children) :
$.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
}
function Z(dom, selector) {
var i, len = dom ? dom.length : 0
for (i = 0; i < len; i++) this[i] = dom[i]
this.length = len
this.selector = selector || ''
}
// `$.zepto.fragment` takes a html string and an optional tag name
// to generate DOM nodes from the given html string.
// The generated DOM nodes are returned as an array.
// This function can be overridden in plugins for example to make
// it compatible with browsers that don't support the DOM fully.
zepto.fragment = function(html, name, properties) {
var dom, nodes, container
// A special case optimization for a single tag
if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))
if (!dom) {
if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>")
if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
if (!(name in containers)) name = '*'
container = containers[name]
container.innerHTML = '' + html
dom = $.each(slice.call(container.childNodes), function(){
container.removeChild(this)
})
}
if (isPlainObject(properties)) {
nodes = $(dom)
$.each(properties, function(key, value) {
if (methodAttributes.indexOf(key) > -1) nodes[key](value)
else nodes.attr(key, value)
})
}
return dom
}
// `$.zepto.Z` swaps out the prototype of the given `dom` array
// of nodes with `$.fn` and thus supplying all the Zepto functions
// to the array. This method can be overridden in plugins.
zepto.Z = function(dom, selector) {
return new Z(dom, selector)
}
// `$.zepto.isZ` should return `true` if the given object is a Zepto
// collection. This method can be overridden in plugins.
zepto.isZ = function(object) {
return object instanceof zepto.Z
}
// `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and
// takes a CSS selector and an optional context (and handles various
// special cases).
// This method can be overridden in plugins.
zepto.init = function(selector, context) {
var dom
// If nothing given, return an empty Zepto collection
if (!selector) return zepto.Z()
// Optimize for string selectors
else if (typeof selector == 'string') {
selector = selector.trim()
// If it's a html fragment, create nodes from it
// Note: In both Chrome 21 and Firefox 15, DOM error 12
// is thrown if the fragment doesn't begin with <
if (selector[0] == '<' && fragmentRE.test(selector))
dom = zepto.fragment(selector, RegExp.$1, context), selector = null
// If there's a context, create a collection on that context first, and select
// nodes from there
else if (context !== undefined) return $(context).find(selector)
// If it's a CSS selector, use it to select nodes.
else dom = zepto.qsa(document, selector)
}
// If a function is given, call it when the DOM is ready
else if (isFunction(selector)) return $(document).ready(selector)
// If a Zepto collection is given, just return it
else if (zepto.isZ(selector)) return selector
else {
// normalize array if an array of nodes is given
if (isArray(selector)) dom = compact(selector)
// Wrap DOM nodes.
else if (isObject(selector))
dom = [selector], selector = null
// If it's a html fragment, create nodes from it
else if (fragmentRE.test(selector))
dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
// If there's a context, create a collection on that context first, and select
// nodes from there
else if (context !== undefined) return $(context).find(selector)
// And last but no least, if it's a CSS selector, use it to select nodes.
else dom = zepto.qsa(document, selector)
}
// create a new Zepto collection from the nodes found
return zepto.Z(dom, selector)
}
// `$` will be the base `Zepto` object. When calling this
// function just call `$.zepto.init, which makes the implementation
// details of selecting nodes and creating Zepto collections
// patchable in plugins.
$ = function(selector, context){
return zepto.init(selector, context)
}
function extend(target, source, deep) {
for (key in source)
if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
if (isPlainObject(source[key]) && !isPlainObject(target[key]))
target[key] = {}
if (isArray(source[key]) && !isArray(target[key]))
target[key] = []
extend(target[key], source[key], deep)
}
else if (source[key] !== undefined) target[key] = source[key]
}
// Copy all but undefined properties from one or more
// objects to the `target` object.
$.extend = function(target){
var deep, args = slice.call(arguments, 1)
if (typeof target == 'boolean') {
deep = target
target = args.shift()
}
args.forEach(function(arg){ extend(target, arg, deep) })
return target
}
// `$.zepto.qsa` is Zepto's CSS selector implementation which
// uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.
// This method can be overridden in plugins.
zepto.qsa = function(element, selector){
var found,
maybeID = selector[0] == '#',
maybeClass = !maybeID && selector[0] == '.',
nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked
isSimple = simpleSelectorRE.test(nameOnly)
return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById
( (found = element.getElementById(nameOnly)) ? [found] : [] ) :
(element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] :
slice.call(
isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName
maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class
element.getElementsByTagName(selector) : // Or a tag
element.querySelectorAll(selector) // Or it's not simple, and we need to query all
)
}
function filtered(nodes, selector) {
return selector == null ? $(nodes) : $(nodes).filter(selector)
}
$.contains = document.documentElement.contains ?
function(parent, node) {
return parent !== node && parent.contains(node)
} :
function(parent, node) {
while (node && (node = node.parentNode))
if (node === parent) return true
return false
}
function funcArg(context, arg, idx, payload) {
return isFunction(arg) ? arg.call(context, idx, payload) : arg
}
function setAttribute(node, name, value) {
value == null ? node.removeAttribute(name) : node.setAttribute(name, value)
}
// access className property while respecting SVGAnimatedString
function className(node, value){
var klass = node.className || '',
svg = klass && klass.baseVal !== undefined
if (value === undefined) return svg ? klass.baseVal : klass
svg ? (klass.baseVal = value) : (node.className = value)
}
// "true" => true
// "false" => false
// "null" => null
// "42" => 42
// "42.5" => 42.5
// "08" => "08"
// JSON => parse if valid
// String => self
function deserializeValue(value) {
try {
return value ?
value == "true" ||
( value == "false" ? false :
value == "null" ? null :
+value + "" == value ? +value :
/^[\[\{]/.test(value) ? $.parseJSON(value) :
value )
: value
} catch(e) {
return value
}
}
$.type = type
$.isFunction = isFunction
$.isWindow = isWindow
$.isArray = isArray
$.isPlainObject = isPlainObject
$.isEmptyObject = function(obj) {
var name
for (name in obj) return false
return true
}
$.inArray = function(elem, array, i){
return emptyArray.indexOf.call(array, elem, i)
}
$.camelCase = camelize
$.trim = function(str) {
return str == null ? "" : String.prototype.trim.call(str)
}
// plugin compatibility
$.uuid = 0
$.support = { }
$.expr = { }
$.noop = function() {}
$.map = function(elements, callback){
var value, values = [], i, key
if (likeArray(elements))
for (i = 0; i < elements.length; i++) {
value = callback(elements[i], i)
if (value != null) values.push(value)
}
else
for (key in elements) {
value = callback(elements[key], key)
if (value != null) values.push(value)
}
return flatten(values)
}
$.each = function(elements, callback){
var i, key
if (likeArray(elements)) {
for (i = 0; i < elements.length; i++)
if (callback.call(elements[i], i, elements[i]) === false) return elements
} else {
for (key in elements)
if (callback.call(elements[key], key, elements[key]) === false) return elements
}
return elements
}
$.grep = function(elements, callback){
return filter.call(elements, callback)
}
if (window.JSON) $.parseJSON = JSON.parse
// Populate the class2type map
$.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase()
})
// Define methods that will be available on all
// Zepto collections
$.fn = {
constructor: zepto.Z,
length: 0,
// Because a collection acts like an array
// copy over these useful array functions.
forEach: emptyArray.forEach,
reduce: emptyArray.reduce,
push: emptyArray.push,
sort: emptyArray.sort,
splice: emptyArray.splice,
indexOf: emptyArray.indexOf,
concat: function(){
var i, value, args = []
for (i = 0; i < arguments.length; i++) {
value = arguments[i]
args[i] = zepto.isZ(value) ? value.toArray() : value
}
return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)
},
// `map` and `slice` in the jQuery API work differently
// from their array counterparts
map: function(fn){
return $($.map(this, function(el, i){ return fn.call(el, i, el) }))
},
slice: function(){
return $(slice.apply(this, arguments))
},
ready: function(callback){
// need to check if document.body exists for IE as that browser reports
// document ready when it hasn't yet created the body element
if (readyRE.test(document.readyState) && document.body) callback($)
else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)
return this
},
get: function(idx){
return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
},
toArray: function(){ return this.get() },
size: function(){
return this.length
},
remove: function(){
return this.each(function(){
if (this.parentNode != null)
this.parentNode.removeChild(this)
})
},
each: function(callback){
emptyArray.every.call(this, function(el, idx){
return callback.call(el, idx, el) !== false
})
return this
},
filter: function(selector){
if (isFunction(selector)) return this.not(this.not(selector))
return $(filter.call(this, function(element){
return zepto.matches(element, selector)
}))
},
add: function(selector,context){
return $(uniq(this.concat($(selector,context))))
},
is: function(selector){
return this.length > 0 && zepto.matches(this[0], selector)
},
not: function(selector){
var nodes=[]
if (isFunction(selector) && selector.call !== undefined)
this.each(function(idx){
if (!selector.call(this,idx)) nodes.push(this)
})
else {
var excludes = typeof selector == 'string' ? this.filter(selector) :
(likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
this.forEach(function(el){
if (excludes.indexOf(el) < 0) nodes.push(el)
})
}
return $(nodes)
},
has: function(selector){
return this.filter(function(){
return isObject(selector) ?
$.contains(this, selector) :
$(this).find(selector).size()
})
},
eq: function(idx){
return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)
},
first: function(){
var el = this[0]
return el && !isObject(el) ? el : $(el)
},
last: function(){
var el = this[this.length - 1]
return el && !isObject(el) ? el : $(el)
},
find: function(selector){
var result, $this = this
if (!selector) result = $()
else if (typeof selector == 'object')
result = $(selector).filter(function(){
var node = this
return emptyArray.some.call($this, function(parent){
return $.contains(parent, node)
})
})
else if (this.length == 1) result = $(zepto.qsa(this[0], selector))
else result = this.map(function(){ return zepto.qsa(this, selector) })
return result
},
closest: function(selector, context){
var node = this[0], collection = false
if (typeof selector == 'object') collection = $(selector)
while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))
node = node !== context && !isDocument(node) && node.parentNode
return $(node)
},
parents: function(selector){
var ancestors = [], nodes = this
while (nodes.length > 0)
nodes = $.map(nodes, function(node){
if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {
ancestors.push(node)
return node
}
})
return filtered(ancestors, selector)
},
parent: function(selector){
return filtered(uniq(this.pluck('parentNode')), selector)
},
children: function(selector){
return filtered(this.map(function(){ return children(this) }), selector)
},
contents: function() {
return this.map(function() { return this.contentDocument || slice.call(this.childNodes) })
},
siblings: function(selector){
return filtered(this.map(function(i, el){
return filter.call(children(el.parentNode), function(child){ return child!==el })
}), selector)
},
empty: function(){
return this.each(function(){ this.innerHTML = '' })
},
// `pluck` is borrowed from Prototype.js
pluck: function(property){
return $.map(this, function(el){ return el[property] })
},
show: function(){
return this.each(function(){
this.style.display == "none" && (this.style.display = '')
if (getComputedStyle(this, '').getPropertyValue("display") == "none")
this.style.display = defaultDisplay(this.nodeName)
})
},
replaceWith: function(newContent){
return this.before(newContent).remove()
},
wrap: function(structure){
var func = isFunction(structure)
if (this[0] && !func)
var dom = $(structure).get(0),
clone = dom.parentNode || this.length > 1
return this.each(function(index){
$(this).wrapAll(
func ? structure.call(this, index) :
clone ? dom.cloneNode(true) : dom
)
})
},
wrapAll: function(structure){
if (this[0]) {
$(this[0]).before(structure = $(structure))
var children
// drill down to the inmost element
while ((children = structure.children()).length) structure = children.first()
$(structure).append(this)
}
return this
},
wrapInner: function(structure){
var func = isFunction(structure)
return this.each(function(index){
var self = $(this), contents = self.contents(),
dom = func ? structure.call(this, index) : structure
contents.length ? contents.wrapAll(dom) : self.append(dom)
})
},
unwrap: function(){
this.parent().each(function(){
$(this).replaceWith($(this).children())
})
return this
},
clone: function(){
return this.map(function(){ return this.cloneNode(true) })
},
hide: function(){
return this.css("display", "none")
},
toggle: function(setting){
return this.each(function(){
var el = $(this)
;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide()
})
},
prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },
next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },
html: function(html){
return 0 in arguments ?
this.each(function(idx){
var originHtml = this.innerHTML
$(this).empty().append( funcArg(this, html, idx, originHtml) )
}) :
(0 in this ? this[0].innerHTML : null)
},
text: function(text){
return 0 in arguments ?
this.each(function(idx){
var newText = funcArg(this, text, idx, this.textContent)
this.textContent = newText == null ? '' : ''+newText
}) :
(0 in this ? this.pluck('textContent').join("") : null)
},
attr: function(name, value){
var result
return (typeof name == 'string' && !(1 in arguments)) ?
(!this.length || this[0].nodeType !== 1 ? undefined :
(!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result
) :
this.each(function(idx){
if (this.nodeType !== 1) return
if (isObject(name)) for (key in name) setAttribute(this, key, name[key])
else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))
})
},
removeAttr: function(name){
return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){
setAttribute(this, attribute)
}, this)})
},
prop: function(name, value){
name = propMap[name] || name
return (1 in arguments) ?
this.each(function(idx){
this[name] = funcArg(this, value, idx, this[name])
}) :
(this[0] && this[0][name])
},
data: function(name, value){
var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase()
var data = (1 in arguments) ?
this.attr(attrName, value) :
this.attr(attrName)
return data !== null ? deserializeValue(data) : undefined
},
val: function(value){
return 0 in arguments ?
this.each(function(idx){
this.value = funcArg(this, value, idx, this.value)
}) :
(this[0] && (this[0].multiple ?
$(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :
this[0].value)
)
},
offset: function(coordinates){
if (coordinates) return this.each(function(index){
var $this = $(this),
coords = funcArg(this, coordinates, index, $this.offset()),
parentOffset = $this.offsetParent().offset(),
props = {
top: coords.top - parentOffset.top,
left: coords.left - parentOffset.left
}
if ($this.css('position') == 'static') props['position'] = 'relative'
$this.css(props)
})
if (!this.length) return null
if (!$.contains(document.documentElement, this[0]))
return {top: 0, left: 0}
var obj = this[0].getBoundingClientRect()
return {
left: obj.left + window.pageXOffset,
top: obj.top + window.pageYOffset,
width: Math.round(obj.width),
height: Math.round(obj.height)
}
},
css: function(property, value){
if (arguments.length < 2) {
var computedStyle, element = this[0]
if(!element) return
computedStyle = getComputedStyle(element, '')
if (typeof property == 'string')
return element.style[camelize(property)] || computedStyle.getPropertyValue(property)
else if (isArray(property)) {
var props = {}
$.each(property, function(_, prop){
props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop))
})
return props
}
}
var css = ''
if (type(property) == 'string') {
if (!value && value !== 0)
this.each(function(){ this.style.removeProperty(dasherize(property)) })
else
css = dasherize(property) + ":" + maybeAddPx(property, value)
} else {
for (key in property)
if (!property[key] && property[key] !== 0)
this.each(function(){ this.style.removeProperty(dasherize(key)) })
else
css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'
}
return this.each(function(){ this.style.cssText += ';' + css })
},
index: function(element){
return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])
},
hasClass: function(name){
if (!name) return false
return emptyArray.some.call(this, function(el){
return this.test(className(el))
}, classRE(name))
},
addClass: function(name){
if (!name) return this
return this.each(function(idx){
if (!('className' in this)) return
classList = []
var cls = className(this), newName = funcArg(this, name, idx, cls)
newName.split(/\s+/g).forEach(function(klass){
if (!$(this).hasClass(klass)) classList.push(klass)
}, this)
classList.length && className(this, cls + (cls ? " " : "") + classList.join(" "))
})
},
removeClass: function(name){
return this.each(function(idx){
if (!('className' in this)) return
if (name === undefined) return className(this, '')
classList = className(this)
funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){
classList = classList.replace(classRE(klass), " ")
})
className(this, classList.trim())
})
},
toggleClass: function(name, when){
if (!name) return this
return this.each(function(idx){
var $this = $(this), names = funcArg(this, name, idx, className(this))
names.split(/\s+/g).forEach(function(klass){
(when === undefined ? !$this.hasClass(klass) : when) ?
$this.addClass(klass) : $this.removeClass(klass)
})
})
},
scrollTop: function(value){
if (!this.length) return
var hasScrollTop = 'scrollTop' in this[0]
if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset
return this.each(hasScrollTop ?
function(){ this.scrollTop = value } :
function(){ this.scrollTo(this.scrollX, value) })
},
scrollLeft: function(value){
if (!this.length) return
var hasScrollLeft = 'scrollLeft' in this[0]
if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset
return this.each(hasScrollLeft ?
function(){ this.scrollLeft = value } :
function(){ this.scrollTo(value, this.scrollY) })
},
position: function() {
if (!this.length) return
var elem = this[0],
// Get *real* offsetParent
offsetParent = this.offsetParent(),
// Get correct offsets
offset = this.offset(),
parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset()
// Subtract element margins
// note: when an element has margin: auto the offsetLeft and marginLeft
// are the same in Safari causing offset.left to incorrectly be 0
offset.top -= parseFloat( $(elem).css('margin-top') ) || 0
offset.left -= parseFloat( $(elem).css('margin-left') ) || 0
// Add offsetParent borders
parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0
parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0
// Subtract the two offsets
return {
top: offset.top - parentOffset.top,
left: offset.left - parentOffset.left
}
},
offsetParent: function() {
return this.map(function(){
var parent = this.offsetParent || document.body
while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static")
parent = parent.offsetParent
return parent
})
}
}
// for now
$.fn.detach = $.fn.remove
// Generate the `width` and `height` functions
;['width', 'height'].forEach(function(dimension){
var dimensionProperty =
dimension.replace(/./, function(m){ return m[0].toUpperCase() })
$.fn[dimension] = function(value){
var offset, el = this[0]
if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] :
isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :
(offset = this.offset()) && offset[dimension]
else return this.each(function(idx){
el = $(this)
el.css(dimension, funcArg(this, value, idx, el[dimension]()))
})
}
})
function traverseNode(node, fun) {
fun(node)
for (var i = 0, len = node.childNodes.length; i < len; i++)
traverseNode(node.childNodes[i], fun)
}
// Generate the `after`, `prepend`, `before`, `append`,
// `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.
adjacencyOperators.forEach(function(operator, operatorIndex) {
var inside = operatorIndex % 2 //=> prepend, append
$.fn[operator] = function(){
// arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
var argType, nodes = $.map(arguments, function(arg) {
argType = type(arg)
return argType == "object" || argType == "array" || arg == null ?
arg : zepto.fragment(arg)
}),
parent, copyByClone = this.length > 1
if (nodes.length < 1) return this
return this.each(function(_, target){
parent = inside ? target : target.parentNode
// convert all methods to a "before" operation
target = operatorIndex == 0 ? target.nextSibling :
operatorIndex == 1 ? target.firstChild :
operatorIndex == 2 ? target :
null
var parentInDocument = $.contains(document.documentElement, parent)
nodes.forEach(function(node){
if (copyByClone) node = node.cloneNode(true)
else if (!parent) return $(node).remove()
parent.insertBefore(node, target)
if (parentInDocument) traverseNode(node, function(el){
if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
(!el.type || el.type === 'text/javascript') && !el.src)
window['eval'].call(window, el.innerHTML)
})
})
})
}
// after => insertAfter
// prepend => prependTo
// before => insertBefore
// append => appendTo
$.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){
$(html)[operator](this)
return this
}
})
zepto.Z.prototype = Z.prototype = $.fn
// Export internal API functions in the `$.zepto` namespace
zepto.uniq = uniq
zepto.deserializeValue = deserializeValue
$.zepto = zepto
return $
})()
window.Zepto = Zepto
window.$ === undefined && (window.$ = Zepto)

View File

@ -0,0 +1,27 @@
((_) => {
'use strict';
const search = (tempHtml, query) => {
_.$('.cssload-loader')[0].removeAttribute('hidden');
_.get(_.url('/manga/search'), {'query':query,}, (searchResults, status) => {
searchResults = JSON.parse(searchResults);
_.$('.cssload-loader')[0].setAttribute('hidden', 'hidden');
Mustache.parse(tempHtml);
_.$('#series_list')[0].innerHTML = Mustache.render(tempHtml, searchResults);
});
};
_.get('/public/templates/manga-ajax-search-results.html', tempHtml => {
_.on('#search', 'keyup', _.throttle(250, function(e) {
let query = encodeURIComponent(this.value);
if (query === '') {
return;
}
search(tempHtml, query);
}));
});
})(AnimeClient);

View File

@ -1,48 +1,46 @@
/**
* Javascript for editing manga, if logged in
*/
(function ($) {
((_) => {
"use strict";
'use strict';
if (CONTROLLER !== "manga") return;
_.on('.manga.list', 'click', '.edit_buttons button', function(e) {
let this_sel = this;
let parent_sel = _.closestParent(this, 'article');
let manga_id = parent_sel.id.replace("manga-", "");
let type = this_sel.classList.contains("plus_one_chapter") ? 'chapter' : 'volume';
let completed = parseInt(_.$(`.${type}s_read`, parent_sel)[0].textContent, 10);
let total = parseInt(_.$(`.${type}_count`, parent_sel)[0].textContent, 10);
let manga_name = _.$('.name', parent_sel)[0].textContent;
$(".edit_buttons button").on("click", function(e) {
var this_sel = $(this);
var parent_sel = $(this).closest("article");
var manga_id = parent_sel.attr("id").replace("manga-", "");
var type = this_sel.is(".plus_one_chapter") ? 'chapter' : 'volume';
var completed = parseInt(parent_sel.find("." + type + "s_read").text(), 10);
var total = parseInt(parent_sel.find("."+type+"_count").text(), 10);
console.log(completed);
console.log(total);
if (isNaN(completed))
{
if (isNaN(completed)) {
completed = 0;
}
var data = {
let data = {
id: manga_id
};
// Update the total count
data[type + "s_read"] = ++completed;
$.ajax({
_.ajax(_.url('/manga/update'), {
data: data,
dataType: 'json',
method: 'POST',
type: 'POST',
mimeType: 'application/json',
url: BASE_URL + CONTROLLER + '/update'
}).done(function(res) {
console.table(res);
parent_sel.find("."+type+"s_read").text(completed);
add_message('success', "Sucessfully updated " + res.manga[0].romaji_title);
}).fail(function() {
add_message('error', "Failed to updated " + res.manga[0].romaji_title);
success: (res) => {
_.$(`.${type}s_read`, parent_sel)[0].textContent = completed;
_.showMessage('success', `Sucessfully updated ${manga_name}`);
_.scrollToTop();
},
error: (xhr, errorType, error) => {
console.error(error);
_.showMessage('error', `Failed to updated ${manga_name}`);
_.scrollToTop();
}
});
});
}(jQuery));
})(AnimeClient);

View File

@ -1,13 +0,0 @@
function add_message(type, message)
{
var template = '<div class="message ' + type + '"><span class="icon"></span>' + message + '<span class="close" onclick="this.parentElement.style.display=\'none\'">x</span></div>';
if ($(".message").length > 0)
{
$(".message").replaceWith(template);
}
else
{
$("main").prepend(template);
}
}

View File

@ -1,3 +0,0 @@
$(function() {
$('table').tablesorter();
});

117
public/min.php Normal file
View File

@ -0,0 +1,117 @@
<?php
/**
* Hummingbird Anime Client
*
* An API client for Hummingbird to manage anime and manga watch lists
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @link https://github.com/timw4mail/HummingBirdAnimeClient
* @license MIT
*/
namespace Aviat\EasyMin;
//Creative rewriting of /g/groupname to ?g=groupname
$pi = $_SERVER['PATH_INFO'];
$pia = explode('/', $pi);
$pia_len = count($pia);
$i = 1;
while($i < $pia_len)
{
$j = $i+1;
$j = (isset($pia[$j])) ? $j : $i;
$_GET[$pia[$i]] = $pia[$j];
$i = $j + 1;
};
class FileNotChangedException extends \Exception {}
class BaseMin {
/**
* Get value of the if-modified-since header
*
* @return int - timestamp to compare for cache control
*/
protected function get_if_modified()
{
return (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: time();
}
/**
* Get value of etag to compare to hash of output
*
* @return string - the etag to compare
*/
protected function get_if_none_match()
{
return (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER))
? $_SERVER['HTTP_IF_NONE_MATCH']
: '';
}
/**
* Determine whether or not to send debug version
*
* @return boolean
*/
protected function is_not_debug()
{
return ! $this->is_debug_call();
}
/**
* Determine whether or not to send debug version
*
* @return boolean
*/
protected function is_debug_call()
{
return array_key_exists('debug', $_GET);
}
/**
* Send actual output to browser
*
* @param string $content - the body of the response
* @param string $mime_type - the content type
* @param int $last_modified - the last modified date
* @return void
*/
protected function send_final_output($content, $mime_type, $last_modified)
{
//This GZIPs the CSS for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
$expires = $last_modified + 691200;
$last_modified_date = gmdate('D, d M Y H:i:s', $last_modified);
$expires_date = gmdate('D, d M Y H:i:s', $expires);
header("Content-Type: {$mime_type}; charset=utf8");
header("Cache-control: public, max-age=691200, must-revalidate");
header("Last-Modified: {$last_modified_date} GMT");
header("Expires: {$expires_date} GMT");
echo $content;
ob_end_flush();
}
/**
* Send a 304 Not Modified header
*
* @return void
*/
public static function send304()
{
header("status: 304 Not Modified", true, 304);
}
}

View File

@ -0,0 +1,10 @@
{{#anime}}
<article class="media search">
<div class="name" style="background-image:url({{cover_image}})">
<input type="radio" class="big-check" id="{{slug}}" name="id" value="{{slug}}" />
<label for="{{slug}}">
<span>{{title}}<br />{{alternate_title}}</span>
</label>
</div>
</article>
{{/anime}}

View File

@ -0,0 +1,10 @@
{{#search}}
<article class="media search">
<div class="name" style="background-image:url({{image}})">
<input type="radio" class="big-check" id="{{link}}" name="id" value="{{link}}" />
<label for="{{link}}">
<span>{{title}}</span>
</label>
</div>
</article>
{{/search}}

33
public/test/ajax.php Normal file
View File

@ -0,0 +1,33 @@
<?php
$verb = strtolower($_SERVER['REQUEST_METHOD']);
// Send request method if nothing else is specified
if (empty($_GET))
{
echo $verb;
}
else if (isset($_GET['data']))
{
switch($verb)
{
case "get":
$var =& $_GET;
break;
case "post":
$var =& $_POST;
break;
default:
parse_str(file_get_contents('php://input'), $var);
break;
}
header('Content-type: application/json');
echo json_encode($var);
}
else if (isset($_GET['bad']))
{
http_response_code('401');
}

44
public/test/index.html Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hummingbird AnimeClient Front-end Testsuite</title>
<link rel="stylesheet" href="lib/mocha.css">
</head>
<body>
<section id="parentTest">
<article class="child">
<div class="grandChild"></div>
</article>
</section>
<div id="mocha">
<ul id="mocha-stats">
<li class="progress"></li>
<li class="passes"></li>
<li class="failures"></li>
<li class="duration"></li>
</ul>
<ul id="mocha-report"></ul>
</div>
<script src="../js/base/classList.js"></script>
<script src="lib/testBundle.js"></script>
<script>
var expect = chai.expect;
mocha.setup('tdd');
</script>
<!-- include source files here... -->
<script src="../js/base/AnimeClient.js"></script>
<!-- include test files here... -->
<script src="tests/AnimeClient.js"></script>
<script src="tests/ajax.js"></script>
<script>
mocha.checkLeaks();
mocha.globals(['AnimeClient']);
mocha.run();
</script>
</body>
</html>

305
public/test/lib/mocha.css Normal file
View File

@ -0,0 +1,305 @@
@charset "utf-8";
body {
margin:0;
}
#mocha {
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 60px 50px;
}
#mocha ul,
#mocha li {
margin: 0;
padding: 0;
}
#mocha ul {
list-style: none;
}
#mocha h1,
#mocha h2 {
margin: 0;
}
#mocha h1 {
margin-top: 15px;
font-size: 1em;
font-weight: 200;
}
#mocha h1 a {
text-decoration: none;
color: inherit;
}
#mocha h1 a:hover {
text-decoration: underline;
}
#mocha .suite .suite h1 {
margin-top: 0;
font-size: .8em;
}
#mocha .hidden {
display: none;
}
#mocha h2 {
font-size: 12px;
font-weight: normal;
cursor: pointer;
}
#mocha .suite {
margin-left: 15px;
}
#mocha .test {
margin-left: 15px;
overflow: hidden;
}
#mocha .test.pending:hover h2::after {
content: '(pending)';
font-family: arial, sans-serif;
}
#mocha .test.pass.medium .duration {
background: #c09853;
}
#mocha .test.pass.slow .duration {
background: #b94a48;
}
#mocha .test.pass::before {
content: '✓';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #00d6b2;
}
#mocha .test.pass .duration {
font-size: 9px;
margin-left: 5px;
padding: 2px 5px;
color: #fff;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}
#mocha .test.pass.fast .duration {
display: none;
}
#mocha .test.pending {
color: #0b97c4;
}
#mocha .test.pending::before {
content: '◦';
color: #0b97c4;
}
#mocha .test.fail {
color: #c00;
}
#mocha .test.fail pre {
color: black;
}
#mocha .test.fail::before {
content: '✖';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #c00;
}
#mocha .test pre.error {
color: #c00;
max-height: 300px;
overflow: auto;
}
#mocha .test .html-error {
overflow: auto;
color: black;
line-height: 1.5;
display: block;
float: left;
clear: left;
font: 12px/1.5 monaco, monospace;
margin: 5px;
padding: 15px;
border: 1px solid #eee;
max-width: 85%; /*(1)*/
max-width: calc(100% - 42px); /*(2)*/
max-height: 300px;
word-wrap: break-word;
border-bottom-color: #ddd;
-webkit-border-radius: 3px;
-webkit-box-shadow: 0 1px 3px #eee;
-moz-border-radius: 3px;
-moz-box-shadow: 0 1px 3px #eee;
border-radius: 3px;
}
#mocha .test .html-error pre.error {
border: none;
-webkit-border-radius: none;
-webkit-box-shadow: none;
-moz-border-radius: none;
-moz-box-shadow: none;
padding: 0;
margin: 0;
margin-top: 18px;
max-height: none;
}
/**
* (1): approximate for browsers not supporting calc
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
* ^^ seriously
*/
#mocha .test pre {
display: block;
float: left;
clear: left;
font: 12px/1.5 monaco, monospace;
margin: 5px;
padding: 15px;
border: 1px solid #eee;
max-width: 85%; /*(1)*/
max-width: calc(100% - 42px); /*(2)*/
word-wrap: break-word;
border-bottom-color: #ddd;
-webkit-border-radius: 3px;
-webkit-box-shadow: 0 1px 3px #eee;
-moz-border-radius: 3px;
-moz-box-shadow: 0 1px 3px #eee;
border-radius: 3px;
}
#mocha .test h2 {
position: relative;
}
#mocha .test a.replay {
position: absolute;
top: 3px;
right: 0;
text-decoration: none;
vertical-align: middle;
display: block;
width: 15px;
height: 15px;
line-height: 15px;
text-align: center;
background: #eee;
font-size: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
-webkit-transition: opacity 200ms;
-moz-transition: opacity 200ms;
transition: opacity 200ms;
opacity: 0.3;
color: #888;
}
#mocha .test:hover a.replay {
opacity: 1;
}
#mocha-report.pass .test.fail {
display: none;
}
#mocha-report.fail .test.pass {
display: none;
}
#mocha-report.pending .test.pass,
#mocha-report.pending .test.fail {
display: none;
}
#mocha-report.pending .test.pass.pending {
display: block;
}
#mocha-error {
color: #c00;
font-size: 1.5em;
font-weight: 100;
letter-spacing: 1px;
}
#mocha-stats {
position: fixed;
top: 15px;
right: 10px;
font-size: 12px;
margin: 0;
color: #888;
z-index: 1;
}
#mocha-stats .progress {
float: right;
padding-top: 0;
}
#mocha-stats em {
color: black;
}
#mocha-stats a {
text-decoration: none;
color: inherit;
}
#mocha-stats a:hover {
border-bottom: 1px solid #eee;
}
#mocha-stats li {
display: inline-block;
margin: 0 5px;
list-style: none;
padding-top: 11px;
}
#mocha-stats canvas {
width: 40px;
height: 40px;
}
#mocha code .comment { color: #ddd; }
#mocha code .init { color: #2f6fad; }
#mocha code .string { color: #5890ad; }
#mocha code .keyword { color: #8a6343; }
#mocha code .number { color: #2f6fad; }
@media screen and (max-device-width: 480px) {
#mocha {
margin: 60px 0px;
}
#mocha #stats {
position: absolute;
}
}

View File

@ -0,0 +1,312 @@
(function e$$0(m,g,c){function l(e,a){if(!g[e]){if(!m[e]){var h="function"==typeof require&&require;if(!a&&h)return h(e,!0);if(b)return b(e,!0);h=Error("Cannot find module '"+e+"'");throw h.code="MODULE_NOT_FOUND",h;}h=g[e]={exports:{}};m[e][0].call(h.exports,function(a){var b=m[e][1][a];return l(b?b:a)},h,h.exports,e$$0,m,g,c)}return g[e].exports}for(var b="function"==typeof require&&require,e=0;e<c.length;e++)l(c[e]);return l})({1:[function(f,m,g){g=f("_process");m.exports=g.env.COV?f("./lib-cov/mocha"):
f("./lib/mocha")},{"./lib-cov/mocha":void 0,"./lib/mocha":14,_process:51}],2:[function(f,m,g){m.exports=function(c){return function(){}}},{}],3:[function(f,m,g){function c(e){return"[object Array]"===b.call(e)}function l(){}g.EventEmitter=l;var b=Object.prototype.toString;l.prototype.on=function(b,k){this.$events||(this.$events={});this.$events[b]?c(this.$events[b])?this.$events[b].push(k):this.$events[b]=[this.$events[b],k]:this.$events[b]=k;return this};l.prototype.addListener=l.prototype.on;l.prototype.once=
function(b,k){function a(){h.removeListener(b,a);k.apply(this,arguments)}var h=this;a.listener=k;this.on(b,a);return this};l.prototype.removeListener=function(b,k){if(this.$events&&this.$events[b]){var a=this.$events[b];if(c(a)){for(var h=-1,d=0,l=a.length;d<l;d++)if(a[d]===k||a[d].listener&&a[d].listener===k){h=d;break}if(0>h)return this;a.splice(h,1);a.length||delete this.$events[b]}else(a===k||a.listener&&a.listener===k)&&delete this.$events[b]}return this};l.prototype.removeAllListeners=function(b){if(void 0===
b)return this.$events={},this;this.$events&&this.$events[b]&&(this.$events[b]=null);return this};l.prototype.listeners=function(b){this.$events||(this.$events={});this.$events[b]||(this.$events[b]=[]);c(this.$events[b])||(this.$events[b]=[this.$events[b]]);return this.$events[b]};l.prototype.emit=function(b){if(!this.$events)return!1;var k=this.$events[b];if(!k)return!1;var a=Array.prototype.slice.call(arguments,1);if("function"===typeof k)k.apply(this,a);else if(c(k))for(var k=k.slice(),h=0,d=k.length;h<
d;h++)k[h].apply(this,a);else return!1;return!0}},{}],4:[function(f,m,g){function c(){this.percent=0;this.size(0);this.fontSize(11);this.font("helvetica, arial, sans-serif")}m.exports=c;c.prototype.size=function(c){this._size=c;return this};c.prototype.text=function(c){this._text=c;return this};c.prototype.fontSize=function(c){this._fontSize=c;return this};c.prototype.font=function(c){this._font=c;return this};c.prototype.update=function(c){this.percent=c;return this};c.prototype.draw=function(c){try{var b=
Math.min(this.percent,100),e=this._size,k=e/2,a=k-1,h=this._fontSize;c.font=h+"px "+this._font;var d=b/100*Math.PI*2;c.clearRect(0,0,e,e);c.strokeStyle="#9f9f9f";c.beginPath();c.arc(k,k,a,0,d,!1);c.stroke();c.strokeStyle="#eee";c.beginPath();c.arc(k,k,a-1,0,d,!0);c.stroke();var t=this._text||(b|0)+"%",f=c.measureText(t).width;c.fillText(t,k-f/2+1,k+h/2-1)}catch(g){}return this}},{}],5:[function(f,m,g){(function(c){g.isatty=function(){return!0};g.getWindowSize=function(){return"innerHeight"in c?[c.innerHeight,
c.innerWidth]:[640,480]}}).call(this,"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{}],6:[function(f,m,g){function c(){}m.exports=c;c.prototype.runnable=function(c){if(!arguments.length)return this._runnable;this.test=this._runnable=c;return this};c.prototype.timeout=function(c){if(!arguments.length)return this.runnable().timeout();this.runnable().timeout(c);return this};c.prototype.enableTimeouts=function(c){this.runnable().enableTimeouts(c);
return this};c.prototype.slow=function(c){this.runnable().slow(c);return this};c.prototype.skip=function(){this.runnable().skip();return this};c.prototype.retries=function(c){if(!arguments.length)return this.runnable().retries();this.runnable().retries(c);return this};c.prototype.inspect=function(){return JSON.stringify(this,function(c,b){return"runnable"===c||"test"===c?void 0:b},2)}},{}],7:[function(f,m,g){function c(b,c){l.call(this,b,c);this.type="hook"}var l=f("./runnable");f=f("./utils").inherits;
m.exports=c;f(c,l);c.prototype.error=function(b){if(!arguments.length)return b=this._error,this._error=null,b;this._error=b}},{"./runnable":35,"./utils":39}],8:[function(f,m,g){var c=f("../suite"),l=f("../test"),b=f("escape-string-regexp");m.exports=function(e){var k=[e];e.on("pre-require",function(a,h,d){var t=f("./common")(k,a);a.before=t.before;a.after=t.after;a.beforeEach=t.beforeEach;a.afterEach=t.afterEach;a.run=d.options.delay&&t.runWithSuite(e);a.describe=a.context=function(a,d){var b=c.create(k[0],
a);b.file=h;k.unshift(b);d.call(b);k.shift();return b};a.xdescribe=a.xcontext=a.describe.skip=function(a,d){var b=c.create(k[0],a);b.pending=!0;k.unshift(b);d.call(b);k.shift()};a.describe.only=function(b,h){var c=a.describe(b,h);d.grep(c.fullTitle());return c};var g=a.it=a.specify=function(a,d){var b=k[0];b.pending&&(d=null);var c=new l(a,d);c.file=h;b.addTest(c);return c};a.it.only=function(a,h){var c=g(a,h),e="^"+b(c.fullTitle())+"$";d.grep(new RegExp(e));return c};a.xit=a.xspecify=a.it.skip=function(d){a.it(d)};
a.it.retries=function(d){a.retries(d)}})}},{"../suite":37,"../test":38,"./common":9,"escape-string-regexp":68}],9:[function(f,m,g){m.exports=function(c,l){return{runWithSuite:function(b){return function(){b.run()}},before:function(b,e){c[0].beforeAll(b,e)},after:function(b,e){c[0].afterAll(b,e)},beforeEach:function(b,e){c[0].beforeEach(b,e)},afterEach:function(b,e){c[0].afterEach(b,e)},test:{skip:function(b){l.test(b)},retries:function(b){l.retries(b)}}}}},{}],10:[function(f,m,g){var c=f("../suite"),
l=f("../test");m.exports=function(b){function e(a,b){var d,t;for(t in a)if("function"===typeof a[t])switch(d=a[t],t){case "before":k[0].beforeAll(d);break;case "after":k[0].afterAll(d);break;case "beforeEach":k[0].beforeEach(d);break;case "afterEach":k[0].afterEach(d);break;default:d=new l(t,d),d.file=b,k[0].addTest(d)}else d=c.create(k[0],t),k.unshift(d),e(a[t],b),k.shift()}var k=[b];b.on("require",e)}},{"../suite":37,"../test":38}],11:[function(f,m,g){g.bdd=f("./bdd");g.tdd=f("./tdd");g.qunit=f("./qunit");
g.exports=f("./exports")},{"./bdd":8,"./exports":10,"./qunit":12,"./tdd":13}],12:[function(f,m,g){var c=f("../suite"),l=f("../test"),b=f("escape-string-regexp");m.exports=function(e){var k=[e];e.on("pre-require",function(a,h,d){var t=f("./common")(k,a);a.before=t.before;a.after=t.after;a.beforeEach=t.beforeEach;a.afterEach=t.afterEach;a.run=d.options.delay&&t.runWithSuite(e);a.suite=function(a){1<k.length&&k.shift();a=c.create(k[0],a);a.file=h;k.unshift(a);return a};a.suite.only=function(b,h){var c=
a.suite(b,h);d.grep(c.fullTitle())};a.test=function(a,d){var b=new l(a,d);b.file=h;k[0].addTest(b);return b};a.test.only=function(h,c){var e=a.test(h,c),e="^"+b(e.fullTitle())+"$";d.grep(new RegExp(e))};a.test.skip=t.test.skip;a.test.retries=t.test.retries})}},{"../suite":37,"../test":38,"./common":9,"escape-string-regexp":68}],13:[function(f,m,g){var c=f("../suite"),l=f("../test"),b=f("escape-string-regexp");m.exports=function(e){var k=[e];e.on("pre-require",function(a,h,d){var t=f("./common")(k,
a);a.setup=t.beforeEach;a.teardown=t.afterEach;a.suiteSetup=t.before;a.suiteTeardown=t.after;a.run=d.options.delay&&t.runWithSuite(e);a.suite=function(a,b){var d=c.create(k[0],a);d.file=h;k.unshift(d);b.call(d);k.shift();return d};a.suite.skip=function(a,d){var b=c.create(k[0],a);b.pending=!0;k.unshift(b);d.call(b);k.shift()};a.suite.only=function(b,h){var c=a.suite(b,h);d.grep(c.fullTitle())};a.test=function(a,b){var d=k[0];d.pending&&(b=null);var c=new l(a,b);c.file=h;d.addTest(c);return c};a.test.only=
function(c,h){var e=a.test(c,h),e="^"+b(e.fullTitle())+"$";d.grep(new RegExp(e))};a.test.skip=t.test.skip;a.test.retries=t.test.retries})}},{"../suite":37,"../test":38,"./common":9,"escape-string-regexp":68}],14:[function(f,m,g){(function(c,l,b){function e(a){a=a||{};this.files=[];this.options=a;a.grep&&this.grep(new RegExp(a.grep));a.fgrep&&this.grep(a.fgrep);this.suite=new g.Suite("",new g.Context);this.ui(a.ui);this.bail(a.bail);this.reporter(a.reporter,a.reporterOptions);"undefined"!==typeof a.timeout&&
null!==a.timeout&&this.timeout(a.timeout);"undefined"!==typeof a.retries&&null!==a.retries&&this.retries(a.retries);this.useColors(a.useColors);null!==a.enableTimeouts&&this.enableTimeouts(a.enableTimeouts);a.slow&&this.slow(a.slow);this.suite.on("pre-require",function(a){g.afterEach=a.afterEach||a.teardown;g.after=a.after||a.suiteTeardown;g.beforeEach=a.beforeEach||a.setup;g.before=a.before||a.suiteSetup;g.describe=a.describe||a.suite;g.it=a.it||a.test;g.setup=a.setup||a.beforeEach;g.suiteSetup=
a.suiteSetup||a.before;g.suiteTeardown=a.suiteTeardown||a.after;g.suite=a.suite||a.describe;g.teardown=a.teardown||a.afterEach;g.test=a.test||a.it;g.run=a.run})}var k=f("escape-string-regexp"),a=f("path"),h=f("./reporters"),d=f("./utils");g=m.exports=e;c.browser||(c=c.cwd(),m.paths.push(c,a.join(c,"node_modules")));g.utils=d;g.interfaces=f("./interfaces");g.reporters=h;g.Runnable=f("./runnable");g.Context=f("./context");g.Runner=f("./runner");g.Suite=f("./suite");g.Hook=f("./hook");g.Test=f("./test");
e.prototype.bail=function(a){arguments.length||(a=!0);this.suite.bail(a);return this};e.prototype.addFile=function(a){this.files.push(a);return this};e.prototype.reporter=function(a,b){if("function"===typeof a)this._reporter=a;else{a=a||"spec";var d;h[a]&&(d=h[a]);if(!d)try{d=f(a)}catch(c){-1!==c.message.indexOf("Cannot find module")?console.warn('"'+a+'" reporter not found'):console.warn('"'+a+'" reporter blew up with error:\n'+c.stack)}d||"teamcity"!==a||console.warn("The Teamcity reporter was moved to a package named mocha-teamcity-reporter (https://npmjs.org/package/mocha-teamcity-reporter).");
if(!d)throw Error('invalid reporter "'+a+'"');this._reporter=d}this.options.reporterOptions=b;return this};e.prototype.ui=function(a){a=a||"bdd";this._ui=g.interfaces[a];if(!this._ui)try{this._ui=f(a)}catch(d){throw Error('invalid interface "'+a+'"');}this._ui=this._ui(this.suite);return this};e.prototype.loadFiles=function(d){var b=this,c=this.suite;this.files.forEach(function(d){d=a.resolve(d);c.emit("pre-require",l,d,b);c.emit("require",f(d),d,b);c.emit("post-require",l,d,b)});d&&d()};e.prototype._growl=
function(d,c){var h=f("growl");d.on("end",function(){var e=c.stats;e.failures?h(e.failures+" of "+d.total+" tests failed",{name:"mocha",title:"Failed",image:a.join(b,"../images","error.png")}):h(e.passes+" tests passed in "+e.duration+"ms",{name:"mocha",title:"Passed",image:a.join(b,"../images","ok.png")})})};e.prototype.grep=function(a){this.options.grep="string"===typeof a?new RegExp(k(a)):a;return this};e.prototype.invert=function(){this.options.invert=!0;return this};e.prototype.ignoreLeaks=function(a){this.options.ignoreLeaks=
!!a;return this};e.prototype.checkLeaks=function(){this.options.ignoreLeaks=!1;return this};e.prototype.fullTrace=function(){this.options.fullStackTrace=!0;return this};e.prototype.growl=function(){this.options.growl=!0;return this};e.prototype.globals=function(a){this.options.globals=(this.options.globals||[]).concat(a);return this};e.prototype.useColors=function(a){void 0!==a&&(this.options.useColors=a);return this};e.prototype.useInlineDiffs=function(a){this.options.useInlineDiffs=void 0!==a&&
a;return this};e.prototype.timeout=function(a){this.suite.timeout(a);return this};e.prototype.retries=function(a){this.suite.retries(a);return this};e.prototype.slow=function(a){this.suite.slow(a);return this};e.prototype.enableTimeouts=function(a){this.suite.enableTimeouts(arguments.length&&void 0!==a?a:!0);return this};e.prototype.asyncOnly=function(){this.options.asyncOnly=!0;return this};e.prototype.noHighlighting=function(){this.options.noHighlighting=!0;return this};e.prototype.allowUncaught=
function(){this.options.allowUncaught=!0;return this};e.prototype.delay=function(){this.options.delay=!0;return this};e.prototype.run=function(a){this.files.length&&this.loadFiles();var d=this.suite,b=this.options;b.files=this.files;var d=new g.Runner(d,b.delay),c=new this._reporter(d,b);d.ignoreLeaks=!1!==b.ignoreLeaks;d.fullStackTrace=b.fullStackTrace;d.asyncOnly=b.asyncOnly;d.allowUncaught=b.allowUncaught;b.grep&&d.grep(b.grep,b.invert);b.globals&&d.globals(b.globals);b.growl&&this._growl(d,c);
void 0!==b.useColors&&(g.reporters.Base.useColors=b.useColors);g.reporters.Base.inlineDiffs=b.useInlineDiffs;return d.run(function(d){c.done?c.done(d,a):a&&a(d)})}}).call(this,f("_process"),"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{},"/lib")},{"./context":6,"./hook":7,"./interfaces":11,"./reporters":22,"./runnable":35,"./runner":36,"./suite":37,"./test":38,"./utils":39,_process:51,"escape-string-regexp":68,growl:69,path:41}],15:[function(f,
m,g){function c(b){if(b=/^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(b)){var c=parseFloat(b[1]);switch((b[2]||"ms").toLowerCase()){case "years":case "year":case "y":return 315576E5*c;case "days":case "day":case "d":return 864E5*c;case "hours":case "hour":case "h":return 36E5*c;case "minutes":case "minute":case "m":return 6E4*c;case "seconds":case "second":case "s":return 1E3*c;case "ms":return c}}}function l(b,c,k){if(!(b<c))return b<1.5*c?Math.floor(b/c)+" "+
k:Math.ceil(b/c)+" "+k+"s"}m.exports=function(b,e){e=e||{};return"string"===typeof b?c(b):e["long"]?l(b,864E5,"day")||l(b,36E5,"hour")||l(b,6E4,"minute")||l(b,1E3,"second")||b+" ms":864E5<=b?Math.round(b/864E5)+"d":36E5<=b?Math.round(b/36E5)+"h":6E4<=b?Math.round(b/6E4)+"m":1E3<=b?Math.round(b/1E3)+"s":b+"ms"}},{}],16:[function(f,m,g){m.exports=function(c){this.message=c}},{}],17:[function(f,m,g){(function(c,l){function b(a){var d=this.stats={suites:0,tests:0,passes:0,pending:0,failures:0},b=this.failures=
[];a&&(this.runner=a,a.stats=d,a.on("start",function(){d.start=new D}),a.on("suite",function(a){d.suites=d.suites||0;a.root||d.suites++}),a.on("test end",function(){d.tests=d.tests||0;d.tests++}),a.on("pass",function(a){d.passes=d.passes||0;a.duration>a.slow()?a.speed="slow":a.duration>a.slow()/2?a.speed="medium":a.speed="fast";d.passes++}),a.on("fail",function(a,c){d.failures=d.failures||0;d.failures++;a.err=c;b.push(a)}),a.on("end",function(){d.end=new D;d.duration=new D-d.start}),a.on("pending",
function(){d.pending++}))}function e(d,b){var c=a(d,"WordsWithSpace",b),h=c.split("\n");if(4<h.length)var n=String(h.length).length,c=h.map(function(a,d){var b=++d,b=String(b);return Array(n-b.length+1).join(" ")+b+" | "+a}).join("\n");c="\n"+w("diff removed","actual")+" "+w("diff added","expected")+"\n\n"+c+"\n";return c=c.replace(/^/gm," ")}function k(a,b){var c=r.createPatch("string",a.actual,a.expected).split("\n").splice(4);return"\n "+d("diff added","+ expected")+" "+d("diff removed",
"- actual")+"\n\n"+c.map(function(a){b&&(a=h(a));return"+"===a[0]?" "+d("diff added",a):"-"===a[0]?" "+d("diff removed",a):a.match(/\@\@/)||a.match(/\\ No newline/)?null:" "+a}).filter(function(a){return"undefined"!==typeof a&&null!==a}).join("\n")}function a(a,b,c){var e=c?h(a.actual):a.actual;a=c?h(a.expected):a.expected;return r["diff"+b](e,a).map(function(a){return a.added?d("diff added",a.value):a.removed?d("diff removed",a.value):a.value}).join("")}function h(a){return a.replace(/\t/g,
"<tab>").replace(/\r/g,"<CR>").replace(/\n/g,"<LF>\n")}function d(a,d){return d.split("\n").map(function(d){return w(a,d)}).join("\n")}var t=f("tty"),r=f("diff"),q=f("../ms"),x=f("../utils"),u=c.browser?null:f("supports-color");g=m.exports=b;var D=l.Date,E=t.isatty(1)&&t.isatty(2);g.useColors=!c.browser&&(u||void 0!==c.env.MOCHA_COLORS);g.inlineDiffs=!1;g.colors={pass:90,fail:31,"bright pass":92,"bright fail":91,"bright yellow":93,pending:36,suite:0,"error title":0,"error message":31,"error stack":90,
checkmark:32,fast:90,medium:33,slow:31,green:32,light:90,"diff gutter":90,"diff added":32,"diff removed":31};g.symbols={ok:"\u2713",err:"\u2716",dot:"\u2024"};"win32"===c.platform&&(g.symbols.ok="\u221a",g.symbols.err="\u00d7",g.symbols.dot=".");var w=g.color=function(a,d){return g.useColors?"\u001b["+g.colors[a]+"m"+d+"\u001b[0m":String(d)};g.window={width:75};E&&(g.window.width=c.stdout.getWindowSize?c.stdout.getWindowSize(1)[0]:t.getWindowSize()[1]);g.cursor={hide:function(){E&&c.stdout.write("\u001b[?25l")},
show:function(){E&&c.stdout.write("\u001b[?25h")},deleteLine:function(){E&&c.stdout.write("\u001b[2K")},beginningOfLine:function(){E&&c.stdout.write("\u001b[0G")},CR:function(){E?(g.cursor.deleteLine(),g.cursor.beginningOfLine()):c.stdout.write("\r")}};g.list=function(a){console.log();a.forEach(function(a,d){var b=w("error title"," %s) %s:\n")+w("error message"," %s")+w("error stack","\n%s\n"),c,h=a.err,l;l=h.message?h.message:"function"===typeof h.inspect?h.inspect()+"":"";var f=h.stack||l,
t=f.indexOf(l),r=h.actual,C=h.expected,H=!0;-1===t?c=l:(t+=l.length,c=f.slice(0,t),f=f.slice(t+1));h.uncaught&&(c="Uncaught "+c);if(H=!1!==h.showDiff)H=A.call(r)===A.call(C);H&&void 0!==C&&(H=!1,x.isString(r)&&x.isString(C)||(h.actual=x.stringify(r),h.expected=x.stringify(C)),b=w("error title"," %s) %s:\n%s")+w("error stack","\n%s\n"),l=l.match(/^([^:]+): expected/),c="\n "+w("error message",l?l[1]:c),c=g.inlineDiffs?c+e(h,H):c+k(h,H));f=f.replace(/^/gm," ");console.log(b,d+1,a.fullTitle(),
c,f)})};b.prototype.epilogue=function(){var a=this.stats,d;console.log();d=w("bright pass"," ")+w("green"," %d passing")+w("light"," (%s)");console.log(d,a.passes||0,q(a.duration));a.pending&&(d=w("pending"," ")+w("pending"," %d pending"),console.log(d,a.pending));a.failures&&(d=w("fail"," %d failing"),console.log(d,a.failures),b.list(this.failures),console.log());console.log()};var A=Object.prototype.toString}).call(this,f("_process"),"undefined"!==typeof global?global:"undefined"!==typeof self?
self:"undefined"!==typeof window?window:{})},{"../ms":15,"../utils":39,_process:51,diff:67,"supports-color":41,tty:5}],18:[function(f,m,g){var c=f("./base"),l=f("../utils");m.exports=function(b){function e(){return Array(k).join(" ")}c.call(this,b);var k=2;b.on("suite",function(a){a.root||(++k,console.log('%s<section class="suite">',e()),++k,console.log("%s<h1>%s</h1>",e(),l.escape(a.title)),console.log("%s<dl>",e()))});b.on("suite end",function(a){a.root||(console.log("%s</dl>",e()),--k,console.log("%s</section>",
e()),--k)});b.on("pass",function(a){console.log("%s <dt>%s</dt>",e(),l.escape(a.title));a=l.escape(l.clean(a.body));console.log("%s <dd><pre><code>%s</code></pre></dd>",e(),a)});b.on("fail",function(a,b){console.log('%s <dt class="error">%s</dt>',e(),l.escape(a.title));var d=l.escape(l.clean(a.fn.body));console.log('%s <dd class="error"><pre><code>%s</code></pre></dd>',e(),d);console.log('%s <dd class="error">%s</dd>',e(),l.escape(b))})}},{"../utils":39,"./base":17}],19:[function(f,m,g){(function(c){function l(a){b.call(this,
a);var h=this,d=.75*b.window.width|0,e=-1;a.on("start",function(){c.stdout.write("\n")});a.on("pending",function(){0===++e%d&&c.stdout.write("\n ");c.stdout.write(k("pending",b.symbols.dot))});a.on("pass",function(a){0===++e%d&&c.stdout.write("\n ");"slow"===a.speed?c.stdout.write(k("bright yellow",b.symbols.dot)):c.stdout.write(k(a.speed,b.symbols.dot))});a.on("fail",function(){0===++e%d&&c.stdout.write("\n ");c.stdout.write(k("fail",b.symbols.dot))});a.on("end",function(){console.log();h.epilogue()})}
var b=f("./base"),e=f("../utils").inherits,k=b.color;m.exports=l;e(l,b)}).call(this,f("_process"))},{"../utils":39,"./base":17,_process:51}],20:[function(f,m,g){(function(c,l){function b(a){return 75<=a?"high":50<=a?"medium":25<=a?"low":"terrible"}var e=f("./json-cov"),k=f("fs").readFileSync,a=f("path").join;m.exports=function(h){var d=f("jade"),g=a(l,"/templates/coverage.jade"),r=k(g,"utf8"),m=d.compile(r,{filename:g}),x=this;e.call(this,h,!1);h.on("end",function(){c.stdout.write(m({cov:x.cov,coverageClass:b}))})}}).call(this,
f("_process"),"/lib/reporters")},{"./json-cov":23,_process:51,fs:41,jade:41,path:41}],21:[function(f,m,g){(function(c){function l(b){g.call(this,b);var c=this,l=this.stats,f=e(E),y=f.getElementsByTagName("li"),z=y[1].getElementsByTagName("em")[0],n=y[1].getElementsByTagName("a")[0],p=y[2].getElementsByTagName("em")[0],G=y[2].getElementsByTagName("a")[0],J=y[3].getElementsByTagName("em")[0],y=f.getElementsByTagName("canvas")[0],v=e('<ul id="mocha-report"></ul>'),m=[v],C,H,I=document.getElementById("mocha");
if(y.getContext){var L=window.devicePixelRatio||1;y.style.width=y.width;y.style.height=y.height;y.width*=L;y.height*=L;H=y.getContext("2d");H.scale(L,L);C=new q}I?(d(n,"click",function(){a();var d=/pass/.test(v.className)?"":" pass";v.className=v.className.replace(/fail|pass/g,"")+d;v.className.trim()&&k("test pass")}),d(G,"click",function(){a();var d=/fail/.test(v.className)?"":" fail";v.className=v.className.replace(/fail|pass/g,"")+d;v.className.trim()&&k("test fail")}),I.appendChild(f),I.appendChild(v),
C&&C.size(40),b.on("suite",function(a){if(!a.root){var d=c.suiteURL(a);a=e('<li class="suite"><h1><a href="%s">%s</a></h1></li>',d,u(a.title));m[0].appendChild(a);m.unshift(document.createElement("ul"));a.appendChild(m[0])}}),b.on("suite end",function(a){a.root||m.shift()}),b.on("fail",function(a){"hook"!==a.type&&"test"!==a.type||b.emit("test end",a)}),b.on("test end",function(a){var b=l.tests/this.total*100|0;C&&C.update(b).draw(H);b=new D-l.start;h(z,l.passes);h(p,l.failures);h(J,(b/1E3).toFixed(2));
if("passed"===a.state)b=c.testURL(a),b=e('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="%s" class="replay">\u2023</a></h2></li>',a.speed,a.title,a.duration,b);else if(a.pending)b=e('<li class="test pass pending"><h2>%e</h2></li>',a.title);else{var b=e('<li class="test fail"><h2>%e <a href="%e" class="replay">\u2023</a></h2></li>',a.title,c.testURL(a)),n,k=a.err.toString();"[object Error]"===k&&(k=a.err.message);a.err.stack?(n=a.err.stack.indexOf(a.err.message),n=-1===
n?a.err.stack:a.err.stack.substr(a.err.message.length+n)):a.err.sourceURL&&void 0!==a.err.line&&(n="\n("+a.err.sourceURL+":"+a.err.line+")");n=n||"";a.err.htmlMessage&&n?b.appendChild(e('<div class="html-error">%s\n<pre class="error">%e</pre></div>',a.err.htmlMessage,n)):a.err.htmlMessage?b.appendChild(e('<div class="html-error">%s</div>',a.err.htmlMessage)):b.appendChild(e('<pre class="error">%e%e</pre>',k,n))}if(!a.pending){n=b.getElementsByTagName("h2")[0];d(n,"click",function(){I.style.display=
"none"===I.style.display?"block":"none"});var I=e("<pre><code>%e</code></pre>",r.clean(a.body));b.appendChild(I);I.style.display="none"}m[0]&&m[0].appendChild(b)})):document.body.appendChild(e('<div id="mocha-error">%s</div>',"#mocha div missing, add it to your document"))}function b(a){var d=window.location.search;d&&(d=d.replace(/[?&]grep=[^&\s]*/g,"").replace(/^&/,"?"));return window.location.pathname+(d?d+"&":"?")+"grep="+encodeURIComponent(x(a))}function e(a){var d=arguments,b=document.createElement("div"),
c=1;b.innerHTML=a.replace(/%([se])/g,function(a,b){switch(b){case "s":return String(d[c++]);case "e":return u(d[c++])}});return b.firstChild}function k(a){for(var d=document.getElementsByClassName("suite"),b=0;b<d.length;b++)d[b].getElementsByClassName(a).length||(d[b].className+=" hidden")}function a(){for(var a=document.getElementsByClassName("suite hidden"),d=0;d<a.length;++d)a[d].className=a[d].className.replace("suite hidden","suite")}function h(a,d){a.textContent?a.textContent=d:a.innerText=
d}function d(a,d,b){a.addEventListener?a.addEventListener(d,b,!1):a.attachEvent("on"+d,b)}var g=f("./base"),r=f("../utils"),q=f("../browser/progress"),x=f("escape-string-regexp"),u=r.escape,D=c.Date;m.exports=l;var E='<ul id="mocha-stats"><li class="progress"><canvas width="40" height="40"></canvas></li><li class="passes"><a href="javascript:void(0);">passes:</a> <em>0</em></li><li class="failures"><a href="javascript:void(0);">failures:</a> <em>0</em></li><li class="duration">duration: <em>0</em>s</li></ul>';
l.prototype.suiteURL=function(a){return b(a.fullTitle())};l.prototype.testURL=function(a){return b(a.fullTitle())}}).call(this,"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{"../browser/progress":4,"../utils":39,"./base":17,"escape-string-regexp":68}],22:[function(f,m,g){g.Base=g.base=f("./base");g.Dot=g.dot=f("./dot");g.Doc=g.doc=f("./doc");g.TAP=g.tap=f("./tap");g.JSON=g.json=f("./json");g.HTML=g.html=f("./html");g.List=g.list=f("./list");
g.Min=g.min=f("./min");g.Spec=g.spec=f("./spec");g.Nyan=g.nyan=f("./nyan");g.XUnit=g.xunit=f("./xunit");g.Markdown=g.markdown=f("./markdown");g.Progress=g.progress=f("./progress");g.Landing=g.landing=f("./landing");g.JSONCov=g["json-cov"]=f("./json-cov");g.HTMLCov=g["html-cov"]=f("./html-cov");g.JSONStream=g["json-stream"]=f("./json-stream")},{"./base":17,"./doc":18,"./dot":19,"./html":21,"./html-cov":20,"./json":25,"./json-cov":23,"./json-stream":24,"./landing":26,"./list":27,"./markdown":28,"./min":29,
"./nyan":30,"./progress":31,"./spec":32,"./tap":33,"./xunit":34}],23:[function(f,m,g){(function(c,l){function b(a){var d={instrumentation:"node-jscoverage",sloc:0,hits:0,misses:0,coverage:0,files:[]},b;for(b in a)if(Object.prototype.hasOwnProperty.call(a,b)){var c=e(b,a[b]);d.files.push(c);d.hits+=c.hits;d.misses+=c.misses;d.sloc+=c.sloc}d.files.sort(function(a,d){return a.filename.localeCompare(d.filename)});0<d.sloc&&(d.coverage=d.hits/d.sloc*100);return d}function e(a,d){var b={filename:a,coverage:0,
hits:0,misses:0,sloc:0,source:{}};d.source.forEach(function(a,c){c++;0===d[c]?(b.misses++,b.sloc++):void 0!==d[c]&&(b.hits++,b.sloc++);b.source[c]={source:a,coverage:void 0===d[c]?"":d[c]}});b.coverage=b.hits/b.sloc*100;return b}function k(a){return{duration:a.duration,currentRetry:a.currentRetry(),fullTitle:a.fullTitle(),title:a.title}}var a=f("./base");m.exports=function(h,d){a.call(this,h);d=1===arguments.length||d;var e=this,f=[],g=[],m=[];h.on("test end",function(a){f.push(a)});h.on("pass",function(a){m.push(a)});
h.on("fail",function(a){g.push(a)});h.on("end",function(){var a=e.cov=b(l._$jscoverage||{});a.stats=e.stats;a.tests=f.map(k);a.failures=g.map(k);a.passes=m.map(k);d&&c.stdout.write(JSON.stringify(a,null,2))})}}).call(this,f("_process"),"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{"./base":17,_process:51}],24:[function(f,m,g){(function(c){function l(b){return{title:b.title,fullTitle:b.fullTitle(),duration:b.duration,currentRetry:b.currentRetry()}}
var b=f("./base");m.exports=function(e){b.call(this,e);var k=this,a=e.total;e.on("start",function(){console.log(JSON.stringify(["start",{total:a}]))});e.on("pass",function(a){console.log(JSON.stringify(["pass",l(a)]))});e.on("fail",function(a,d){a=l(a);a.err=d.message;a.stack=d.stack||null;console.log(JSON.stringify(["fail",a]))});e.on("end",function(){c.stdout.write(JSON.stringify(["end",k.stats]))})}}).call(this,f("_process"))},{"./base":17,_process:51}],25:[function(f,m,g){(function(c){function l(c){return{title:c.title,
fullTitle:c.fullTitle(),duration:c.duration,currentRetry:c.currentRetry(),err:b(c.err||{})}}function b(b){var a={};Object.getOwnPropertyNames(b).forEach(function(c){a[c]=b[c]},b);return a}var e=f("./base");m.exports=function(b){e.call(this,b);var a=this,h=[],d=[],f=[],g=[];b.on("test end",function(a){h.push(a)});b.on("pass",function(a){g.push(a)});b.on("fail",function(a){f.push(a)});b.on("pending",function(a){d.push(a)});b.on("end",function(){var e={stats:a.stats,tests:h.map(l),pending:d.map(l),failures:f.map(l),
passes:g.map(l)};b.testResults=e;c.stdout.write(JSON.stringify(e,null,2))})}}).call(this,f("_process"))},{"./base":17,_process:51}],26:[function(f,m,g){(function(c){function l(h){function d(){var b=Array(l).join("-");return" "+a("runway",b)}b.call(this,h);var e=this,l=.75*b.window.width|0,f=h.total,g=c.stdout,m=a("plane","\u2708"),D=-1,E=0;h.on("start",function(){g.write("\n\n\n ");k.hide()});h.on("test end",function(b){var c=-1===D?l*++E/f|0:D;"failed"===b.state&&(m=a("plane crash","\u2708"),D=
c);g.write("\u001b["+(l+1)+"D\u001b[2A");g.write(d());g.write("\n ");g.write(a("runway",Array(c).join("\u22c5")));g.write(m);g.write(a("runway",Array(l-c).join("\u22c5")+"\n"));g.write(d());g.write("\u001b[0m")});h.on("end",function(){k.show();console.log();e.epilogue()})}var b=f("./base"),e=f("../utils").inherits,k=b.cursor,a=b.color;m.exports=l;b.colors.plane=0;b.colors["plane crash"]=31;b.colors.runway=90;e(l,b)}).call(this,f("_process"))},{"../utils":39,"./base":17,_process:51}],27:[function(f,
m,g){(function(c){function l(h){b.call(this,h);var d=0;h.on("start",function(){console.log()});h.on("test",function(a){c.stdout.write(k("pass"," "+a.fullTitle()+": "))});h.on("pending",function(a){var b=k("checkmark"," -")+k("pending"," %s");console.log(b,a.fullTitle())});h.on("pass",function(d){var c=k("checkmark"," "+b.symbols.dot)+k("pass"," %s: ")+k(d.speed,"%dms");a.CR();console.log(c,d.fullTitle(),d.duration)});h.on("fail",function(b){a.CR();console.log(k("fail"," %d) %s"),++d,b.fullTitle())});
h.on("end",this.epilogue.bind(this))}var b=f("./base"),e=f("../utils").inherits,k=b.color,a=b.cursor;m.exports=l;e(l,b)}).call(this,f("_process"))},{"../utils":39,"./base":17,_process:51}],28:[function(f,m,g){(function(c){var l=f("./base"),b=f("../utils");m.exports=function(e){function k(a,b){var d=b,c="$"+a.title;b=b[c]=b[c]||{suite:a};a.suites.forEach(function(a){k(a,b)});return d}function a(d,c){++c;var h="",e,k;for(k in d)"suite"!==k&&("$"!==k&&(e=" - ["+k.substring(1)+"]",e+="(#"+b.slug(d[k].suite.fullTitle())+
")\n",h+=Array(c).join(" ")+e),h+=a(d[k],c));return h}function h(b){b=k(b,{});return a(b,0)}l.call(this,e);var d=0,f="";h(e.suite);e.on("suite",function(a){++d;var c=b.slug(a.fullTitle()),c=f+='<a name="'+c+'"></a>\n';a=a.title;a=Array(d).join("#")+" "+a;f=c+(a+"\n")});e.on("suite end",function(){--d});e.on("pass",function(a){var d=b.clean(a.body);f+=a.title+".\n";f+="\n```js\n";f+=d+"\n";f+="```\n\n"});e.on("end",function(){c.stdout.write("# TOC\n");c.stdout.write(h(e.suite));c.stdout.write(f)})}}).call(this,
f("_process"))},{"../utils":39,"./base":17,_process:51}],29:[function(f,m,g){(function(c){function l(e){b.call(this,e);e.on("start",function(){c.stdout.write("\u001b[2J");c.stdout.write("\u001b[1;3H")});e.on("end",this.epilogue.bind(this))}var b=f("./base"),e=f("../utils").inherits;m.exports=l;e(l,b)}).call(this,f("_process"))},{"../utils":39,"./base":17,_process:51}],30:[function(f,m,g){(function(c){function l(a){e.call(this,a);var c=this,d=.75*e.window.width|0,k=this.nyanCatWidth=11;this.colorIndex=
0;this.numberOfLines=4;this.rainbowColors=c.generateColors();this.scoreboardWidth=5;this.tick=0;this.trajectories=[[],[],[],[]];this.trajectoryWidthMax=d-k;a.on("start",function(){e.cursor.hide();c.draw()});a.on("pending",function(){c.draw()});a.on("pass",function(){c.draw()});a.on("fail",function(){c.draw()});a.on("end",function(){e.cursor.show();for(var a=0;a<c.numberOfLines;a++)b("\n");c.epilogue()})}function b(a){c.stdout.write(a)}var e=f("./base"),k=f("../utils").inherits;m.exports=l;k(l,e);
l.prototype.draw=function(){this.appendRainbow();this.drawScoreboard();this.drawRainbow();this.drawNyanCat();this.tick=!this.tick};l.prototype.drawScoreboard=function(){function a(a,c){b(" ");b(e.color(a,c));b("\n")}var c=this.stats;a("green",c.passes);a("fail",c.failures);a("pending",c.pending);b("\n");this.cursorUp(this.numberOfLines)};l.prototype.appendRainbow=function(){for(var a=this.rainbowify(this.tick?"_":"-"),b=0;b<this.numberOfLines;b++){var d=this.trajectories[b];d.length>=this.trajectoryWidthMax&&
d.shift();d.push(a)}};l.prototype.drawRainbow=function(){var a=this;this.trajectories.forEach(function(c){b("\u001b["+a.scoreboardWidth+"C");b(c.join(""));b("\n")});this.cursorUp(this.numberOfLines)};l.prototype.drawNyanCat=function(){var a="\u001b["+(this.scoreboardWidth+this.trajectories[0].length)+"C",c="";b(a);b("_,------,");b("\n");b(a);c=this.tick?" ":" ";b("_|"+c+"/\\_/\\ ");b("\n");b(a);c=this.tick?"_":"__";b((this.tick?"~":"^")+"|"+c+this.face()+" ");b("\n");b(a);c=this.tick?" ":" ";
b(c+'"" "" ');b("\n");this.cursorUp(this.numberOfLines)};l.prototype.face=function(){var a=this.stats;return a.failures?"( x .x)":a.pending?"( o .o)":a.passes?"( ^ .^)":"( - .-)"};l.prototype.cursorUp=function(a){b("\u001b["+a+"A")};l.prototype.cursorDown=function(a){b("\u001b["+a+"B")};l.prototype.generateColors=function(){for(var a=[],b=0;42>b;b++){var d=Math.floor(Math.PI/3),c=1/6*b;a.push(36*Math.floor(3*Math.sin(c)+3)+6*Math.floor(3*Math.sin(c+2*d)+3)+Math.floor(3*Math.sin(c+4*d)+3)+16)}return a};
l.prototype.rainbowify=function(a){if(!e.useColors)return a;var b=this.rainbowColors[this.colorIndex%this.rainbowColors.length];this.colorIndex+=1;return"\u001b[38;5;"+b+"m"+a+"\u001b[0m"}}).call(this,f("_process"))},{"../utils":39,"./base":17,_process:51}],31:[function(f,m,g){(function(c){function l(e,d){b.call(this,e);var f=this,l=.5*b.window.width|0,g=e.total,m=0,u=-1;d=d||{};d.open=d.open||"[";d.complete=d.complete||"\u25ac";d.incomplete=d.incomplete||b.symbols.dot;d.close=d.close||"]";d.verbose=
!1;e.on("start",function(){console.log();a.hide()});e.on("test end",function(){m++;var b=m/g*l|0,e=l-b;if(b!==u||d.verbose)u=b,a.CR(),c.stdout.write("\u001b[J"),c.stdout.write(k("progress"," "+d.open)),c.stdout.write(Array(b).join(d.complete)),c.stdout.write(Array(e).join(d.incomplete)),c.stdout.write(k("progress",d.close)),d.verbose&&c.stdout.write(k("progress"," "+m+" of "+g))});e.on("end",function(){a.show();console.log();f.epilogue()})}var b=f("./base"),e=f("../utils").inherits,k=b.color,a=b.cursor;
m.exports=l;b.colors.progress=90;e(l,b)}).call(this,f("_process"))},{"../utils":39,"./base":17,_process:51}],32:[function(f,m,g){function c(c){function a(){return Array(h).join(" ")}l.call(this,c);var h=0,d=0;c.on("start",function(){console.log()});c.on("suite",function(d){++h;console.log(b("suite","%s%s"),a(),d.title)});c.on("suite end",function(){--h;1===h&&console.log()});c.on("pending",function(d){var c=a()+b("pending"," - %s");console.log(c,d.title)});c.on("pass",function(d){var c;"fast"===
d.speed?(c=a()+b("checkmark"," "+l.symbols.ok)+b("pass"," %s"),e.CR(),console.log(c,d.title)):(c=a()+b("checkmark"," "+l.symbols.ok)+b("pass"," %s")+b(d.speed," (%dms)"),e.CR(),console.log(c,d.title,d.duration))});c.on("fail",function(c){e.CR();console.log(a()+b("fail"," %d) %s"),++d,c.title)});c.on("end",this.epilogue.bind(this))}var l=f("./base");f=f("../utils").inherits;var b=l.color,e=l.cursor;m.exports=c;f(c,l)},{"../utils":39,"./base":17}],33:[function(f,m,g){var c=f("./base");m.exports=
function(f){c.call(this,f);var b=1,e=0,k=0;f.on("start",function(){var a=f.grepTotal(f.suite);console.log("%d..%d",1,a)});f.on("test end",function(){++b});f.on("pending",function(a){console.log("ok %d %s # SKIP -",b,a.fullTitle().replace(/#/g,""))});f.on("pass",function(a){e++;console.log("ok %d %s",b,a.fullTitle().replace(/#/g,""))});f.on("fail",function(a,c){k++;console.log("not ok %d %s",b,a.fullTitle().replace(/#/g,""));c.stack&&console.log(c.stack.replace(/^/gm," "))});f.on("end",function(){console.log("# tests "+
(e+k));console.log("# pass "+e);console.log("# fail "+k)})}},{"./base":17}],34:[function(f,m,g){(function(c,l){function b(b,d){a.call(this,b);var c=this.stats,h=[],k=this;if(d.reporterOptions&&d.reporterOptions.output){if(!g.createWriteStream)throw Error("file output not supported in browser");q.sync(x.dirname(d.reporterOptions.output));k.fileStream=g.createWriteStream(d.reporterOptions.output)}b.on("pending",function(a){h.push(a)});b.on("pass",function(a){h.push(a)});b.on("fail",function(a){h.push(a)});
b.on("end",function(){k.write(e("testsuite",{name:"Mocha Tests",tests:c.tests,failures:c.failures,errors:c.failures,skipped:c.tests-c.failures-c.passes,timestamp:(new u).toUTCString(),time:c.duration/1E3||0},!1));h.forEach(function(a){k.test(a)});k.write("</testsuite>")})}function e(a,b,d,c){d=d?"/>":">";var e=[],h;for(h in b)Object.prototype.hasOwnProperty.call(b,h)&&e.push(h+'="'+r(b[h])+'"');b="<"+a+(e.length?" "+e.join(" "):"")+d;c&&(b+=c+"</"+a+d);return b}function k(a){return"<![CDATA["+r(a)+
"]]\x3e"}var a=f("./base"),h=f("../utils"),d=h.inherits,g=f("fs"),r=h.escape,q=f("mkdirp"),x=f("path"),u=l.Date;m.exports=b;d(b,a);b.prototype.done=function(a,b){this.fileStream?this.fileStream.end(function(){b(a)}):b(a)};b.prototype.write=function(a){this.fileStream?this.fileStream.write(a+"\n"):"object"===typeof c&&c.stdout?c.stdout.write(a+"\n"):console.log(a)};b.prototype.test=function(a){var b={classname:a.parent.fullTitle(),name:a.title,time:a.duration/1E3||0};"failed"===a.state?(a=a.err,this.write(e("testcase",
b,!1,e("failure",{},!1,k(r(a.message)+"\n"+a.stack))))):a.pending?this.write(e("testcase",b,!1,e("skipped",{},!0))):this.write(e("testcase",b,!0))}}).call(this,f("_process"),"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{"../utils":39,"./base":17,_process:51,fs:41,mkdirp:70,path:41}],35:[function(f,m,g){(function(c){function l(a,b){this.title=a;this.async=(this.fn=b)&&b.length;this.sync=!this.async;this._timeout=2E3;this._slow=75;this._enableTimeouts=
!0;this.timedOut=!1;this._trace=Error("done() called multiple times");this._retries=-1;this._currentRetry=0}var b=f("events").EventEmitter,e=f("./pending"),k=f("debug")("mocha:runnable"),a=f("./ms"),h=f("./utils"),d=h.inherits,g=c.Date,r=c.setTimeout,q=c.clearTimeout,x=Object.prototype.toString;m.exports=l;d(l,b);l.prototype.timeout=function(b){if(!arguments.length)return this._timeout;0===b&&(this._enableTimeouts=!1);"string"===typeof b&&(b=a(b));k("timeout %d",b);this._timeout=b;this.timer&&this.resetTimeout();
return this};l.prototype.slow=function(b){if(!arguments.length)return this._slow;"string"===typeof b&&(b=a(b));k("timeout %d",b);this._slow=b;return this};l.prototype.enableTimeouts=function(a){if(!arguments.length)return this._enableTimeouts;k("enableTimeouts %s",a);this._enableTimeouts=a;return this};l.prototype.skip=function(){throw new e;};l.prototype.retries=function(a){if(!arguments.length)return this._retries;this._retries=a};l.prototype.currentRetry=function(a){if(!arguments.length)return this._currentRetry;
this._currentRetry=a};l.prototype.fullTitle=function(){return this.parent.fullTitle()+" "+this.title};l.prototype.clearTimeout=function(){q(this.timer)};l.prototype.inspect=function(){return JSON.stringify(this,function(a,b){if("_"!==a[0])return"parent"===a?"#<Suite>":"ctx"===a?"#<Context>":b},2)};l.prototype.resetTimeout=function(){var a=this,b=this.timeout()||1E9;this._enableTimeouts&&(this.clearTimeout(),this.timer=r(function(){a._enableTimeouts&&(a.callback(Error("timeout of "+b+"ms exceeded. Ensure the done() callback is being called in this test.")),
a.timedOut=!0)},b))};l.prototype.globals=function(a){if(!arguments.length)return this._allowedGlobals;this._allowedGlobals=a};l.prototype.run=function(a){function b(d){var c=e.timeout();e.timedOut||(l?(d=d||e._trace,z||(z=!0,e.emit("error",d||Error("done() called multiple times; stacktrace may be inaccurate")))):(e.clearTimeout(),e.duration=new g-k,l=!0,!d&&e.duration>c&&e._enableTimeouts&&(d=Error("timeout of "+c+"ms exceeded. Ensure the done() callback is being called in this test.")),a(d)))}function d(a){if((a=
a.call(f))&&"function"===typeof a.then)e.resetTimeout(),a.then(function(){b();return null},function(a){b(a||Error("Promise rejected with no or falsy reason"))});else{if(e.asyncOnly)return b(Error("--async-only option in use without declaring `done()` or returning a promise"));b()}}function c(a){a.call(f,function(a){if(a instanceof Error||"[object Error]"===x.call(a))return b(a);if(a)return"[object Object]"===Object.prototype.toString.call(a)?b(Error("done() invoked with non-Error: "+JSON.stringify(a))):
b(Error("done() invoked with non-Error: "+a));b()})}var e=this,k=new g,f=this.ctx,l,z;f&&f.runnable&&f.runnable(this);this.callback=b;if(this.async){this.resetTimeout();if(this.allowUncaught)return c(this.fn);try{c(this.fn)}catch(n){b(h.getError(n))}}else if(this.allowUncaught)d(this.fn),b();else try{this.pending?b():d(this.fn)}catch(n){b(h.getError(n))}}}).call(this,"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{"./ms":15,"./pending":16,
"./utils":39,debug:2,events:3}],36:[function(f,m,g){(function(c,l){function b(b,d){var c=this;this._globals=[];this._abort=!1;this._delay=d;this.suite=b;this.started=!1;this.total=b.total();this.failures=0;this.on("test end",function(a){c.checkGlobals(a)});this.on("hook end",function(a){c.checkGlobals(a)});this._defaultGrep=/.*/;this.grep(this._defaultGrep);this.globals(this.globalProps().concat(a()))}function e(a){function b(a){for(var d=0;d<a.length;d++)delete a[d].fn}y(a._beforeAll)&&b(a._beforeAll);
y(a._beforeEach)&&b(a._beforeEach);y(a._afterAll)&&b(a._afterAll);y(a._afterEach)&&b(a._afterEach);for(var d=0;d<a.tests.length;d++)delete a.tests[d].fn}function k(a,b){return u(b,function(b){return/^d+/.test(b)||l.navigator&&/^getInterface/.test(b)||l.navigator&&/^\d+/.test(b)||/^mocha-/.test(b)?!1:!u(a,function(a){return~a.indexOf("*")?0===b.indexOf(a.split("*")[0]):b===a}).length&&(!l.navigator||"onerror"!==b)})}function a(){if("object"===typeof c&&"string"===typeof c.version){var a=c.version.split(".");
if(2315>g.reduce(a,function(a,b){return a<<8|b}))return["errno"]}return[]}var h=f("events").EventEmitter,d=f("./pending"),g=f("./utils"),r=g.inherits,q=f("debug")("mocha:runner"),x=f("./runnable"),u=g.filter,D=g.indexOf,E=g.keys,w=g.stackTraceFilter(),A=g.stringify,F=g.type,B=g.undefinedError,y=g.isArray,z="setTimeout clearTimeout setInterval clearInterval XMLHttpRequest Date setImmediate clearImmediate".split(" ");m.exports=b;b.immediately=l.setImmediate||c.nextTick;r(b,h);b.prototype.grep=function(a,
b){q("grep %s",a);this._grep=a;this._invert=b;this.total=this.grepTotal(this.suite);return this};b.prototype.grepTotal=function(a){var b=this,d=0;a.eachTest(function(a){a=b._grep.test(a.fullTitle());b._invert&&(a=!a);a&&d++});return d};b.prototype.globalProps=function(){for(var a=E(l),b=0;b<z.length;++b)~D(a,z[b])||a.push(z[b]);return a};b.prototype.globals=function(a){if(!arguments.length)return this._globals;q("globals %j",a);this._globals=this._globals.concat(a);return this};b.prototype.checkGlobals=
function(a){if(!this.ignoreLeaks){var b=this._globals,d=this.globalProps();a&&(b=b.concat(a._allowedGlobals||[]));this.prevGlobalsLength!==d.length&&(this.prevGlobalsLength=d.length,b=k(b,d),this._globals=this._globals.concat(b),1<b.length?this.fail(a,Error("global leaks detected: "+b.join(", ")+"")):b.length&&this.fail(a,Error("global leak detected: "+b[0])))}};b.prototype.fail=function(a,b){++this.failures;a.state="failed";b instanceof Error||b&&"string"===typeof b.message||(b=Error("the "+F(b)+
" "+A(b)+" was thrown, throw an Error :)"));b.stack=this.fullStackTrace||!b.stack?b.stack:w(b.stack);this.emit("fail",a,b)};b.prototype.failHook=function(a,b){a.ctx&&a.ctx.currentTest&&(a.originalTitle=a.originalTitle||a.title,a.title=a.originalTitle+' for "'+a.ctx.currentTest.title+'"');this.fail(a,b);this.suite.bail()&&this.emit("end")};b.prototype.hook=function(a,c){function e(a){var b=k[a];if(!b)return c();f.currentRunnable=b;b.ctx.currentTest=f.test;f.emit("hook",b);if(!b.listeners("error").length)b.on("error",
function(a){f.failHook(b,a)});b.run(function(I){var k=b.error();k&&f.fail(f.test,k);if(I)if(I instanceof d)h.pending=!0;else return f.failHook(b,I),c(I);f.emit("hook end",b);delete b.ctx.currentTest;e(++a)})}var h=this.suite,k=h["_"+a],f=this;b.immediately(function(){e(0)})};b.prototype.hooks=function(a,b,d){function c(C){e.suite=C;if(!C)return e.suite=h,d();e.hook(a,function(a){if(a){var C=e.suite;e.suite=h;return d(a,C)}c(b.pop())})}var e=this,h=this.suite;c(b.pop())};b.prototype.hookUp=function(a,
b){var d=[this.suite].concat(this.parents()).reverse();this.hooks(a,d,b)};b.prototype.hookDown=function(a,b){var d=[this.suite].concat(this.parents());this.hooks(a,d,b)};b.prototype.parents=function(){for(var a=this.suite,b=[];a.parent;)a=a.parent,b.push(a);return b};b.prototype.runTest=function(a){var b=this,d=this.test;this.asyncOnly&&(d.asyncOnly=!0);if(this.allowUncaught)return d.allowUncaught=!0,d.run(a);try{d.on("error",function(a){b.fail(d,a)}),d.run(a)}catch(c){a(c)}};b.prototype.runTests=
function(a,c){function e(a,b,d){var C=k.suite;k.suite=d?b.parent:b;k.suite?k.hookUp("afterEach",function(a,d){k.suite=C;if(a)return e(a,d,!0);c(b)}):(k.suite=C,c(b))}function h(H,I){function l(a){return a.pending||a.parent&&l(a.parent)}if(k.failures&&a._bail||k._abort)return c();if(H)return e(H,I,!0);C=f.shift();if(!C)return c();var g=k._grep.test(C.fullTitle());k._invert&&(g=!g);if(g){if(C.pending||l(C.parent))return k.emit("pending",C),k.emit("test end",C),h();k.emit("test",k.test=C);k.hookDown("beforeEach",
function(b,c){if(a.pending)return k.emit("pending",C),k.emit("test end",C),h();if(b)return e(b,c,!1);k.currentRunnable=k.test;k.runTest(function(a){C=k.test;if(a){var b=C.currentRetry();if(a instanceof d)C.pending=!0,k.emit("pending",C);else{if(b<C.retries())return a=C.clone(),a.currentRetry(b+1),f.unshift(a),k.hookUp("afterEach",h);k.fail(C,a)}k.emit("test end",C);return a instanceof d?h():k.hookUp("afterEach",h)}C.state="passed";k.emit("pass",C);k.emit("test end",C);k.hookUp("afterEach",h)})})}else k._grep!==
k._defaultGrep?b.immediately(h):h()}var k=this,f=a.tests.slice(),C;this.next=h;this.hookErr=e;h()};b.prototype.runSuite=function(a,d){function c(d){if(d)return d===a?e():e(d);if(k._abort)return e();var C=a.suites[h++];if(!C)return e();k._grep!==k._defaultGrep?b.immediately(function(){k.runSuite(C,c)}):k.runSuite(C,c)}function e(b){k.suite=a;k.nextSuite=c;H?d(b):(H=!0,delete k.test,k.hook("afterAll",function(){k.emit("suite end",a);d(b)}))}var h=0,k=this,C=this.grepTotal(a),H=!1;q("run suite %s",a.fullTitle());
if(!C||k.failures&&a._bail)return d();this.emit("suite",this.suite=a);this.nextSuite=c;this.hook("beforeAll",function(b){if(b)return e();k.runTests(a,c)})};b.prototype.uncaught=function(a){a?q("uncaught exception %s",a!==function(){return this}.call(a)?a:a.message||a):(q("uncaught undefined exception"),a=B());a.uncaught=!0;var b=this.currentRunnable;if(b){if(b.clearTimeout(),!b.state)if(this.fail(b,a),"test"===b.type)this.emit("test end",b),this.hookUp("afterEach",this.next);else{if("hook"===b.type){var d=
this.suite;return-1<b.fullTitle().indexOf("after each")?this.hookErr(a,d,!0):-1<b.fullTitle().indexOf("before each")?this.hookErr(a,d,!1):this.nextSuite(d)}this.emit("end")}}else b=new x("Uncaught error outside test suite"),b.parent=this.suite,this.started?this.fail(b,a):(this.emit("start"),this.fail(b,a),this.emit("end"))};b.prototype.run=function(a){function b(a){h.uncaught(a)}function d(){h.started=!0;h.emit("start");h.runSuite(k,function(){q("finished running");h.emit("end")})}var h=this,k=this.suite;
a=a||function(){};q("start");this.on("suite end",e);this.on("end",function(){q("end");c.removeListener("uncaughtException",b);a(h.failures)});c.on("uncaughtException",b);this._delay?(this.emit("waiting",k),k.once("run",d)):d();return this};b.prototype.abort=function(){q("aborting");this._abort=!0;return this}}).call(this,f("_process"),"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{"./pending":16,"./runnable":35,"./utils":39,_process:51,debug:2,
events:3}],37:[function(f,m,g){function c(a,b){function c(){}this.title=a;c.prototype=b;this.ctx=new c;this.suites=[];this.tests=[];this.pending=!1;this._beforeEach=[];this._beforeAll=[];this._afterEach=[];this._afterAll=[];this.root=!a;this._timeout=2E3;this._enableTimeouts=!0;this._slow=75;this._bail=!1;this._retries=-1;this.delayed=!1}var l=f("events").EventEmitter,b=f("./hook"),e=f("./utils"),k=e.inherits,a=f("debug")("mocha:suite"),h=f("./ms");g=m.exports=c;g.create=function(a,b){var e=new c(b,
a.ctx);e.parent=a;a.pending&&(e.pending=!0);e.fullTitle();a.addSuite(e);return e};k(c,l);c.prototype.clone=function(){var b=new c(this.title);a("clone");b.ctx=this.ctx;b.timeout(this.timeout());b.retries(this.retries());b.enableTimeouts(this.enableTimeouts());b.slow(this.slow());b.bail(this.bail());return b};c.prototype.timeout=function(b){if(!arguments.length)return this._timeout;"0"===b.toString()&&(this._enableTimeouts=!1);"string"===typeof b&&(b=h(b));a("timeout %d",b);this._timeout=parseInt(b,
10);return this};c.prototype.retries=function(b){if(!arguments.length)return this._retries;a("retries %d",b);this._retries=parseInt(b,10)||0;return this};c.prototype.enableTimeouts=function(b){if(!arguments.length)return this._enableTimeouts;a("enableTimeouts %s",b);this._enableTimeouts=b;return this};c.prototype.slow=function(b){if(!arguments.length)return this._slow;"string"===typeof b&&(b=h(b));a("slow %d",b);this._slow=b;return this};c.prototype.bail=function(b){if(!arguments.length)return this._bail;
a("bail %s",b);this._bail=b;return this};c.prototype.beforeAll=function(a,c){if(this.pending)return this;"function"===typeof a&&(c=a,a=c.name);var e=new b('"before all" hook'+(a?": "+a:""),c);e.parent=this;e.timeout(this.timeout());e.retries(this.retries());e.enableTimeouts(this.enableTimeouts());e.slow(this.slow());e.ctx=this.ctx;this._beforeAll.push(e);this.emit("beforeAll",e);return this};c.prototype.afterAll=function(a,c){if(this.pending)return this;"function"===typeof a&&(c=a,a=c.name);var e=
new b('"after all" hook'+(a?": "+a:""),c);e.parent=this;e.timeout(this.timeout());e.retries(this.retries());e.enableTimeouts(this.enableTimeouts());e.slow(this.slow());e.ctx=this.ctx;this._afterAll.push(e);this.emit("afterAll",e);return this};c.prototype.beforeEach=function(a,c){if(this.pending)return this;"function"===typeof a&&(c=a,a=c.name);var e=new b('"before each" hook'+(a?": "+a:""),c);e.parent=this;e.timeout(this.timeout());e.retries(this.retries());e.enableTimeouts(this.enableTimeouts());
e.slow(this.slow());e.ctx=this.ctx;this._beforeEach.push(e);this.emit("beforeEach",e);return this};c.prototype.afterEach=function(a,c){if(this.pending)return this;"function"===typeof a&&(c=a,a=c.name);var e=new b('"after each" hook'+(a?": "+a:""),c);e.parent=this;e.timeout(this.timeout());e.retries(this.retries());e.enableTimeouts(this.enableTimeouts());e.slow(this.slow());e.ctx=this.ctx;this._afterEach.push(e);this.emit("afterEach",e);return this};c.prototype.addSuite=function(a){a.parent=this;a.timeout(this.timeout());
a.retries(this.retries());a.enableTimeouts(this.enableTimeouts());a.slow(this.slow());a.bail(this.bail());this.suites.push(a);this.emit("suite",a);return this};c.prototype.addTest=function(a){a.parent=this;a.timeout(this.timeout());a.retries(this.retries());a.enableTimeouts(this.enableTimeouts());a.slow(this.slow());a.ctx=this.ctx;this.tests.push(a);this.emit("test",a);return this};c.prototype.fullTitle=function(){if(this.parent){var a=this.parent.fullTitle();if(a)return a+" "+this.title}return this.title};
c.prototype.total=function(){return e.reduce(this.suites,function(a,b){return a+b.total()},0)+this.tests.length};c.prototype.eachTest=function(a){e.forEach(this.tests,a);e.forEach(this.suites,function(b){b.eachTest(a)});return this};c.prototype.run=function(){this.root&&this.emit("run")}},{"./hook":7,"./ms":15,"./utils":39,debug:2,events:3}],38:[function(f,m,g){function c(b,c){l.call(this,b,c);this.pending=!c;this.type="test";this.body=(c||"").toString()}var l=f("./runnable");f=f("./utils").inherits;
m.exports=c;f(c,l);c.prototype.clone=function(){var b=new c(this.title,this.fn);b.timeout(this.timeout());b.slow(this.slow());b.enableTimeouts(this.enableTimeouts());b.retries(this.retries());b.currentRetry(this.currentRetry());b.globals(this.globals());b.parent=this.parent;b.file=this.file;b.ctx=this.ctx;return b}},{"./runnable":35,"./utils":39}],39:[function(f,m,g){(function(c,l){function b(a){return!~D.indexOf(a)}function e(a,b){b=b||g.type(a);switch(b){case "function":return"[Function]";case "object":return"{}";
case "array":return"[]";default:return a.toString()}}function k(a,b,c){function d(a,b){return Array(b).join(a)}function e(a){switch(g.type(a)){case "null":case "undefined":a="["+a+"]";break;case "array":case "object":a=k(a,b,c+1);break;case "boolean":case "regexp":case "number":a=0===a&&-Infinity===1/a?"-0":a.toString();break;case "date":a="[Date: "+(isNaN(a.getTime())?a.toString():a.toISOString())+"]";break;case "buffer":a=a.toJSON();a=a.data&&a.type?a.data:a;a="[Buffer: "+k(a,2,c+1)+"]";break;default:a=
"[Function]"===a||"[Circular]"===a?a:JSON.stringify(a)}return a}if("undefined"===typeof b)return e(a);c=c||1;var h=b*c,f=E(a)?"[":"{",l=E(a)?"]":"}",G=a.length||g.keys(a).length,t;for(t in a)a.hasOwnProperty(t)&&(--G,f+="\n "+d(" ",h)+(E(a)?"":'"'+t+'": ')+e(a[t])+(G?",":""));return f+(1!==f.length?"\n"+d(" ",--h)+l:l)}var a=f("path").basename,h=f("debug")("mocha:watch"),d=f("fs").existsSync||f("path").existsSync,t=f("glob"),m=f("path").join,q=f("fs").readdirSync,x=f("fs").statSync,u=f("fs").watchFile,
D=["node_modules",".git"];g.inherits=f("util").inherits;g.escape=function(a){return String(a).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};g.forEach=function(a,b,c){for(var d=0,e=a.length;d<e;d++)b.call(c,a[d],d)};g.isString=function(a){return"string"===typeof a};g.map=function(a,b,c){for(var d=[],e=0,h=a.length;e<h;e++)d.push(b.call(c,a[e],e,a));return d};g.indexOf=function(a,b,c){c=c||0;for(var d=a.length;c<d;c++)if(a[c]===b)return c;return-1};g.reduce=
function(a,b,c){for(var d=0,e=a.length;d<e;d++)c=b(c,a[d],d,a);return c};g.filter=function(a,b){for(var c=[],d=0,e=a.length;d<e;d++){var h=a[d];b(h,d,a)&&c.push(h)}return c};g.keys="function"===typeof Object.keys?Object.keys:function(a){var b=[],c=Object.prototype.hasOwnProperty,d;for(d in a)c.call(a,d)&&b.push(d);return b};g.watch=function(a,b){var c={interval:100};a.forEach(function(a){h("file %s",a);u(a,c,function(c,d){d.mtime<c.mtime&&b(a)})})};var E="function"===typeof Array.isArray?Array.isArray:
function(a){return"[object Array]"===Object.prototype.toString.call(a)};g.isArray=E;"undefined"!==typeof l&&l.prototype&&(l.prototype.toJSON=l.prototype.toJSON||function(){return Array.prototype.slice.call(this,0)});g.files=function(a,c,d){d=d||[];c=c||["js"];var e=new RegExp("\\.("+c.join("|")+")$");q(a).filter(b).forEach(function(b){b=m(a,b);x(b).isDirectory()?g.files(b,c,d):b.match(e)&&d.push(b)});return d};g.slug=function(a){return a.toLowerCase().replace(/ +/g,"-").replace(/[^-\w]/g,"")};g.clean=
function(a){a=a.replace(/\r\n?|[\n\u2028\u2029]/g,"\n").replace(/^\uFEFF/,"").replace(/^function *\(.*\)\s*\{|\(.*\) *=> *\{?/,"").replace(/\s+\}$/,"");var b=a.match(/^\n?( *)/)[1].length,c=a.match(/^\n?(\t*)/)[1].length;a=a.replace(new RegExp("^\n?"+(c?"\t":" ")+"{"+(c?c:b)+"}","gm"),"");return g.trim(a)};g.trim=function(a){return a.replace(/^\s+|\s+$/g,"")};g.parseQuery=function(a){return g.reduce(a.replace("?","").split("&"),function(a,b){var c=b.indexOf("="),d=b.slice(0,c),c=b.slice(++c);a[d]=
decodeURIComponent(c);return a},{})};g.highlightTags=function(a){a=document.getElementById("mocha").getElementsByTagName(a);for(var b=0,c=a.length;b<c;++b)a[b].innerHTML=a[b].innerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\/\/(.*)/gm,'<span class="comment">//$1</span>').replace(/('.*?')/gm,'<span class="string">$1</span>').replace(/(\d+\.\d+)/gm,'<span class="number">$1</span>').replace(/(\d+)/gm,'<span class="number">$1</span>').replace(/\bnew[ \t]+(\w+)/gm,'<span class="keyword">new</span> <span class="init">$1</span>').replace(/\b(function|new|throw|return|var|if|else)\b/gm,
'<span class="keyword">$1</span>')};g.type=function(a){return void 0===a?"undefined":null===a?"null":"undefined"!==typeof l&&l.isBuffer(a)?"buffer":Object.prototype.toString.call(a).replace(/^\[.+\s(.+?)\]$/,"$1").toLowerCase()};g.stringify=function(a){var b=g.type(a);if(!~g.indexOf(["object","array","function"],b)){if("buffer"!==b)return k(a);a=a.toJSON();return k(a.data&&a.type?a.data:a,2).replace(/,(\n|$)/g,"$1")}for(var c in a)if(Object.prototype.hasOwnProperty.call(a,c))return k(g.canonicalize(a),
2).replace(/,(\n|$)/g,"$1");return e(a,b)};g.isBuffer=function(a){return"undefined"!==typeof l&&l.isBuffer(a)};g.canonicalize=function(a,b){function c(a,d){b.push(a);d();b.pop()}var d,h,k=g.type(a);b=b||[];if(-1!==g.indexOf(b,a))return"[Circular]";switch(k){case "undefined":case "buffer":case "null":d=a;break;case "array":c(a,function(){d=g.map(a,function(a){return g.canonicalize(a,b)})});break;case "function":for(h in a){d={};break}if(!d){d=e(a,k);break}case "object":d=d||{};c(a,function(){g.forEach(g.keys(a).sort(),
function(c){d[c]=g.canonicalize(a[c],b)})});break;case "date":case "number":case "regexp":case "boolean":d=a;break;default:d=a+""}return d};g.lookupFiles=function A(b,c,e){var h=[],k=new RegExp("\\.("+c.join("|")+")$");if(!d(b))if(d(b+".js"))b+=".js";else{h=t.sync(b);if(!h.length)throw Error("cannot resolve path (or pattern) '"+b+"'");return h}try{if(x(b).isFile())return b}catch(f){return}q(b).forEach(function(d){d=m(b,d);try{var f=x(d);if(f.isDirectory()){e&&(h=h.concat(A(d,c,e)));return}}catch(l){return}f.isFile()&&
k.test(d)&&"."!==a(d)[0]&&h.push(d)});return h};g.undefinedError=function(){return Error("Caught undefined error, did you throw without specifying what?")};g.getError=function(a){return a||g.undefinedError()};g.stackTraceFilter=function(){var a="undefined"===typeof document?{node:!0}:{browser:!0},b=a.node?c.cwd()+"/":("undefined"===typeof location?window.location:location).href.replace(/\/[^\/]*$/,"/");return function(c){c=c.split("\n");c=g.reduce(c,function(c,d){if(~d.indexOf("node_modules/mocha/")||
~d.indexOf("components/mochajs/")||~d.indexOf("components/mocha/")||~d.indexOf("/mocha.js"))return c;var e;if(e=a.node)e=~d.indexOf("(timers.js:")||~d.indexOf("(events.js:")||~d.indexOf("(node.js:")||~d.indexOf("(module.js:")||~d.indexOf("GeneratorFunctionPrototype.next (native)")||!1;if(e)return c;c.push(d.replace(b,""));return c},[]);return c.join("\n")}}}).call(this,f("_process"),f("buffer").Buffer)},{_process:51,buffer:43,debug:2,fs:41,glob:41,path:41,util:66}],40:[function(f,m,g){(function(c){function l(c){if(!(this instanceof
l))return new l(c);c=c||{};b.call(this,c);this.label=void 0!==c.label?c.label:"stdout"}var b=f("stream").Writable,e=f("util").inherits;m.exports=l;e(l,b);l.prototype._write=function(b,a,e){b=b.toString?b.toString():b;!1===this.label?console.log(b):console.log(this.label+":",b);c.nextTick(e)}}).call(this,f("_process"))},{_process:51,stream:63,util:66}],41:[function(f,m,g){},{}],42:[function(f,m,g){arguments[4][41][0].apply(g,arguments)},{dup:41}],43:[function(f,m,g){function c(a){if(!(this instanceof
c))return 1<arguments.length?new c(a,arguments[1]):new c(a);this.length=0;this.parent=void 0;if("number"===typeof a){var b;b=e(this,0>a?0:k(a)|0);if(!c.TYPED_ARRAY_SUPPORT)for(var d=0;d<a;d++)b[d]=0;return b}if("string"===typeof a){b=this;d=1<arguments.length?arguments[1]:"utf8";if("string"!==typeof d||""===d)d="utf8";var f=h(a,d)|0;b=e(b,f);b.write(a,d);return b}return l(this,a)}function l(a,d){if(c.isBuffer(d)){var h=a,f=k(d.length)|0,h=e(h,f);d.copy(h,0,0,f);return h}if(p(d)){for(var h=a,f=k(d.length)|
0,h=e(h,f),l=0;l<f;l+=1)h[l]=d[l]&255;return h}if(null==d)throw new TypeError("must start with number, buffer, array or string");if("undefined"!==typeof ArrayBuffer){if(d.buffer instanceof ArrayBuffer)return b(a,d);if(d instanceof ArrayBuffer)return h=a,c.TYPED_ARRAY_SUPPORT?(d.byteLength,h=c._augment(new Uint8Array(d))):h=b(h,new Uint8Array(d)),h}if(d.length){h=a;f=k(d.length)|0;h=e(h,f);for(l=0;l<f;l+=1)h[l]=d[l]&255;return h}h=a;l=0;"Buffer"===d.type&&p(d.data)&&(f=d.data,l=k(f.length)|0);for(var h=
e(h,l),g=0;g<l;g+=1)h[g]=f[g]&255;return h}function b(a,b){var c=k(b.length)|0;a=e(a,c);for(var d=0;d<c;d+=1)a[d]=b[d]&255;return a}function e(a,b){c.TYPED_ARRAY_SUPPORT?a=c._augment(new Uint8Array(b)):(a.length=b,a._isBuffer=!0);0!==b&&b<=c.poolSize>>>1&&(a.parent=G);return a}function k(a){if(a>=(c.TYPED_ARRAY_SUPPORT?2147483647:1073741823))throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+(c.TYPED_ARRAY_SUPPORT?2147483647:1073741823).toString(16)+" bytes");return a|
0}function a(b,d){if(!(this instanceof a))return new a(b,d);var e=new c(b,d);delete e.parent;return e}function h(a,b){"string"!==typeof a&&(a=""+a);var c=a.length;if(0===c)return 0;for(var d=!1;;)switch(b){case "ascii":case "binary":case "raw":case "raws":return c;case "utf8":case "utf-8":return F(a).length;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return 2*c;case "hex":return c>>>1;case "base64":return z.toByteArray(A(a)).length;default:if(d)return F(a).length;b=(""+b).toLowerCase();
d=!0}}function d(a,b,c){var d=!1;b|=0;c=void 0===c||Infinity===c?this.length:c|0;a||(a="utf8");0>b&&(b=0);c>this.length&&(c=this.length);if(c<=b)return"";for(;;)switch(a){case "hex":a=b;b=c;c=this.length;if(!a||0>a)a=0;if(!b||0>b||b>c)b=c;d="";for(c=a;c<b;c++)a=d,d=this[c],d=16>d?"0"+d.toString(16):d.toString(16),d=a+d;return d;case "utf8":case "utf-8":return t(this,b,c);case "ascii":a="";for(c=Math.min(this.length,c);b<c;b++)a+=String.fromCharCode(this[b]&127);return a;case "binary":a="";for(c=Math.min(this.length,
c);b<c;b++)a+=String.fromCharCode(this[b]);return a;case "base64":return b=0===b&&c===this.length?z.fromByteArray(this):z.fromByteArray(this.slice(b,c)),b;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":b=this.slice(b,c);c="";for(a=0;a<b.length;a+=2)c+=String.fromCharCode(b[a]+256*b[a+1]);return c;default:if(d)throw new TypeError("Unknown encoding: "+a);a=(a+"").toLowerCase();d=!0}}function t(a,b,c){c=Math.min(a.length,c);for(var d=[];b<c;){var e=a[b],h=null,k=239<e?4:223<e?3:191<e?2:1;if(b+
k<=c){var f,l,g;switch(k){case 1:128>e&&(h=e);break;case 2:f=a[b+1];128===(f&192)&&(e=(e&31)<<6|f&63,127<e&&(h=e));break;case 3:f=a[b+1];l=a[b+2];128===(f&192)&&128===(l&192)&&(e=(e&15)<<12|(f&63)<<6|l&63,2047<e&&(55296>e||57343<e)&&(h=e));break;case 4:f=a[b+1],l=a[b+2],g=a[b+3],128===(f&192)&&128===(l&192)&&128===(g&192)&&(e=(e&15)<<18|(f&63)<<12|(l&63)<<6|g&63,65535<e&&1114112>e&&(h=e))}}null===h?(h=65533,k=1):65535<h&&(h-=65536,d.push(h>>>10&1023|55296),h=56320|h&1023);d.push(h);b+=k}a=d.length;
if(a<=J)d=String.fromCharCode.apply(String,d);else{c="";for(b=0;b<a;)c+=String.fromCharCode.apply(String,d.slice(b,b+=J));d=c}return d}function r(a,b,c){if(0!==a%1||0>a)throw new RangeError("offset is not uint");if(a+b>c)throw new RangeError("Trying to access beyond buffer length");}function q(a,b,d,e,h,k){if(!c.isBuffer(a))throw new TypeError("buffer must be a Buffer instance");if(b>h||b<k)throw new RangeError("value is out of bounds");if(d+e>a.length)throw new RangeError("index out of range");}
function x(a,b,c,d){0>b&&(b=65535+b+1);for(var e=0,h=Math.min(a.length-c,2);e<h;e++)a[c+e]=(b&255<<8*(d?e:1-e))>>>8*(d?e:1-e)}function u(a,b,c,d){0>b&&(b=4294967295+b+1);for(var e=0,h=Math.min(a.length-c,4);e<h;e++)a[c+e]=b>>>8*(d?e:3-e)&255}function D(a,b,c,d,e,h){if(b>e||b<h)throw new RangeError("value is out of bounds");if(c+d>a.length)throw new RangeError("index out of range");if(0>c)throw new RangeError("index out of range");}function E(a,b,c,d,e){e||D(a,b,c,4,3.4028234663852886E38,-3.4028234663852886E38);
n.write(a,b,c,d,23,4);return c+4}function w(a,b,c,d,e){e||D(a,b,c,8,1.7976931348623157E308,-1.7976931348623157E308);n.write(a,b,c,d,52,8);return c+8}function A(a){a=a.trim?a.trim():a.replace(/^\s+|\s+$/g,"");a=a.replace(K,"");if(2>a.length)return"";for(;0!==a.length%4;)a+="=";return a}function F(a,b){b=b||Infinity;for(var c,d=a.length,e=null,h=[],k=0;k<d;k++){c=a.charCodeAt(k);if(55295<c&&57344>c){if(!e){if(56319<c){-1<(b-=3)&&h.push(239,191,189);continue}else if(k+1===d){-1<(b-=3)&&h.push(239,191,
189);continue}e=c;continue}if(56320>c){-1<(b-=3)&&h.push(239,191,189);e=c;continue}c=e-55296<<10|c-56320|65536}else e&&-1<(b-=3)&&h.push(239,191,189);e=null;if(128>c){if(0>--b)break;h.push(c)}else if(2048>c){if(0>(b-=2))break;h.push(c>>6|192,c&63|128)}else if(65536>c){if(0>(b-=3))break;h.push(c>>12|224,c>>6&63|128,c&63|128)}else if(1114112>c){if(0>(b-=4))break;h.push(c>>18|240,c>>12&63|128,c>>6&63|128,c&63|128)}else throw Error("Invalid code point");}return h}function B(a){for(var b=[],c=0;c<a.length;c++)b.push(a.charCodeAt(c)&
255);return b}function y(a,b,c,d){for(var e=0;e<d&&!(e+c>=b.length||e>=a.length);e++)b[e+c]=a[e];return e}var z=f("base64-js"),n=f("ieee754"),p=f("is-array");g.Buffer=c;g.SlowBuffer=a;g.INSPECT_MAX_BYTES=50;c.poolSize=8192;var G={};c.TYPED_ARRAY_SUPPORT=function(){function a(){}try{var b=new Uint8Array(1);b.foo=function(){return 42};b.constructor=a;return 42===b.foo()&&b.constructor===a&&"function"===typeof b.subarray&&0===b.subarray(1,1).byteLength}catch(c){return!1}}();c.isBuffer=function(a){return!(null==
a||!a._isBuffer)};c.compare=function(a,b){if(!c.isBuffer(a)||!c.isBuffer(b))throw new TypeError("Arguments must be Buffers");if(a===b)return 0;for(var d=a.length,e=b.length,h=0,k=Math.min(d,e);h<k&&a[h]===b[h];)++h;h!==k&&(d=a[h],e=b[h]);return d<e?-1:e<d?1:0};c.isEncoding=function(a){switch(String(a).toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "binary":case "base64":case "raw":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return!0;default:return!1}};c.concat=function(a,
b){if(!p(a))throw new TypeError("list argument must be an Array of Buffers.");if(0===a.length)return new c(0);var d;if(void 0===b)for(d=b=0;d<a.length;d++)b+=a[d].length;var e=new c(b),h=0;for(d=0;d<a.length;d++){var k=a[d];k.copy(e,h);h+=k.length}return e};c.byteLength=h;c.prototype.length=void 0;c.prototype.parent=void 0;c.prototype.toString=function(){var a=this.length|0;return 0===a?"":0===arguments.length?t(this,0,a):d.apply(this,arguments)};c.prototype.equals=function(a){if(!c.isBuffer(a))throw new TypeError("Argument must be a Buffer");
return this===a?!0:0===c.compare(this,a)};c.prototype.inspect=function(){var a="",b=g.INSPECT_MAX_BYTES;0<this.length&&(a=this.toString("hex",0,b).match(/.{2}/g).join(" "),this.length>b&&(a+=" ... "));return"<Buffer "+a+">"};c.prototype.compare=function(a){if(!c.isBuffer(a))throw new TypeError("Argument must be a Buffer");return this===a?0:c.compare(this,a)};c.prototype.indexOf=function(a,b){function d(a,b,c){for(var e=-1,h=0;c+h<a.length;h++)if(a[c+h]===b[-1===e?0:h-e]){if(-1===e&&(e=h),h-e+1===
b.length)return c+e}else e=-1;return-1}2147483647<b?b=2147483647:-2147483648>b&&(b=-2147483648);b>>=0;if(0===this.length||b>=this.length)return-1;0>b&&(b=Math.max(this.length+b,0));if("string"===typeof a)return 0===a.length?-1:String.prototype.indexOf.call(this,a,b);if(c.isBuffer(a))return d(this,a,b);if("number"===typeof a)return c.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,a,b):d(this,[a],b);throw new TypeError("val must be string, number or Buffer");
};c.prototype.get=function(a){console.log(".get() is deprecated. Access using array indexes instead.");return this.readUInt8(a)};c.prototype.set=function(a,b){console.log(".set() is deprecated. Access using array indexes instead.");return this.writeUInt8(a,b)};c.prototype.write=function(a,b,c,d){if(void 0===b)d="utf8",c=this.length,b=0;else if(void 0===c&&"string"===typeof b)d=b,c=this.length,b=0;else if(isFinite(b))b|=0,isFinite(c)?(c|=0,void 0===d&&(d="utf8")):(d=c,c=void 0);else{var e=d;d=b;b=
c|0;c=e}e=this.length-b;if(void 0===c||c>e)c=e;if(0<a.length&&(0>c||0>b)||b>this.length)throw new RangeError("attempt to write outside buffer bounds");d||(d="utf8");for(e=!1;;)switch(d){case "hex":b=Number(b)||0;d=this.length-b;c?(c=Number(c),c>d&&(c=d)):c=d;d=a.length;if(0!==d%2)throw Error("Invalid hex string");c>d/2&&(c=d/2);for(d=0;d<c;d++){e=parseInt(a.substr(2*d,2),16);if(isNaN(e))throw Error("Invalid hex string");this[b+d]=e}return d;case "utf8":case "utf-8":return y(F(a,this.length-b),this,
b,c);case "ascii":return y(B(a),this,b,c);case "binary":return y(B(a),this,b,c);case "base64":return y(z.toByteArray(A(a)),this,b,c);case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":d=this.length-b;for(var h=void 0,h=e=void 0,k=[],f=0;f<a.length&&!(0>(d-=2));f++)h=a.charCodeAt(f),e=h>>8,h%=256,k.push(h),k.push(e);return y(k,this,b,c);default:if(e)throw new TypeError("Unknown encoding: "+d);d=(""+d).toLowerCase();e=!0}};c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||
this,0)}};var J=4096;c.prototype.slice=function(a,b){var d=this.length;a=~~a;b=void 0===b?d:~~b;0>a?(a+=d,0>a&&(a=0)):a>d&&(a=d);0>b?(b+=d,0>b&&(b=0)):b>d&&(b=d);b<a&&(b=a);if(c.TYPED_ARRAY_SUPPORT)d=c._augment(this.subarray(a,b));else for(var e=b-a,d=new c(e,void 0),h=0;h<e;h++)d[h]=this[h+a];d.length&&(d.parent=this.parent||this);return d};c.prototype.readUIntLE=function(a,b,c){a|=0;b|=0;c||r(a,b,this.length);c=this[a];for(var d=1,e=0;++e<b&&(d*=256);)c+=this[a+e]*d;return c};c.prototype.readUIntBE=
function(a,b,c){a|=0;b|=0;c||r(a,b,this.length);c=this[a+--b];for(var d=1;0<b&&(d*=256);)c+=this[a+--b]*d;return c};c.prototype.readUInt8=function(a,b){b||r(a,1,this.length);return this[a]};c.prototype.readUInt16LE=function(a,b){b||r(a,2,this.length);return this[a]|this[a+1]<<8};c.prototype.readUInt16BE=function(a,b){b||r(a,2,this.length);return this[a]<<8|this[a+1]};c.prototype.readUInt32LE=function(a,b){b||r(a,4,this.length);return(this[a]|this[a+1]<<8|this[a+2]<<16)+16777216*this[a+3]};c.prototype.readUInt32BE=
function(a,b){b||r(a,4,this.length);return 16777216*this[a]+(this[a+1]<<16|this[a+2]<<8|this[a+3])};c.prototype.readIntLE=function(a,b,c){a|=0;b|=0;c||r(a,b,this.length);c=this[a];for(var d=1,e=0;++e<b&&(d*=256);)c+=this[a+e]*d;c>=128*d&&(c-=Math.pow(2,8*b));return c};c.prototype.readIntBE=function(a,b,c){a|=0;b|=0;c||r(a,b,this.length);c=b;for(var d=1,e=this[a+--c];0<c&&(d*=256);)e+=this[a+--c]*d;e>=128*d&&(e-=Math.pow(2,8*b));return e};c.prototype.readInt8=function(a,b){b||r(a,1,this.length);return this[a]&
128?-1*(255-this[a]+1):this[a]};c.prototype.readInt16LE=function(a,b){b||r(a,2,this.length);var c=this[a]|this[a+1]<<8;return c&32768?c|4294901760:c};c.prototype.readInt16BE=function(a,b){b||r(a,2,this.length);var c=this[a+1]|this[a]<<8;return c&32768?c|4294901760:c};c.prototype.readInt32LE=function(a,b){b||r(a,4,this.length);return this[a]|this[a+1]<<8|this[a+2]<<16|this[a+3]<<24};c.prototype.readInt32BE=function(a,b){b||r(a,4,this.length);return this[a]<<24|this[a+1]<<16|this[a+2]<<8|this[a+3]};
c.prototype.readFloatLE=function(a,b){b||r(a,4,this.length);return n.read(this,a,!0,23,4)};c.prototype.readFloatBE=function(a,b){b||r(a,4,this.length);return n.read(this,a,!1,23,4)};c.prototype.readDoubleLE=function(a,b){b||r(a,8,this.length);return n.read(this,a,!0,52,8)};c.prototype.readDoubleBE=function(a,b){b||r(a,8,this.length);return n.read(this,a,!1,52,8)};c.prototype.writeUIntLE=function(a,b,c,d){a=+a;b|=0;c|=0;d||q(this,a,b,c,Math.pow(2,8*c),0);d=1;var e=0;for(this[b]=a&255;++e<c&&(d*=256);)this[b+
e]=a/d&255;return b+c};c.prototype.writeUIntBE=function(a,b,c,d){a=+a;b|=0;c|=0;d||q(this,a,b,c,Math.pow(2,8*c),0);d=c-1;var e=1;for(this[b+d]=a&255;0<=--d&&(e*=256);)this[b+d]=a/e&255;return b+c};c.prototype.writeUInt8=function(a,b,d){a=+a;b|=0;d||q(this,a,b,1,255,0);c.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));this[b]=a;return b+1};c.prototype.writeUInt16LE=function(a,b,d){a=+a;b|=0;d||q(this,a,b,2,65535,0);c.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):x(this,a,b,!0);return b+2};c.prototype.writeUInt16BE=
function(a,b,d){a=+a;b|=0;d||q(this,a,b,2,65535,0);c.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):x(this,a,b,!1);return b+2};c.prototype.writeUInt32LE=function(a,b,d){a=+a;b|=0;d||q(this,a,b,4,4294967295,0);c.TYPED_ARRAY_SUPPORT?(this[b+3]=a>>>24,this[b+2]=a>>>16,this[b+1]=a>>>8,this[b]=a):u(this,a,b,!0);return b+4};c.prototype.writeUInt32BE=function(a,b,d){a=+a;b|=0;d||q(this,a,b,4,4294967295,0);c.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+2]=a>>>8,this[b+3]=a):u(this,a,b,!1);
return b+4};c.prototype.writeIntLE=function(a,b,c,d){a=+a;b|=0;d||(d=Math.pow(2,8*c-1),q(this,a,b,c,d-1,-d));d=0;var e=1,h=0>a?1:0;for(this[b]=a&255;++d<c&&(e*=256);)this[b+d]=(a/e>>0)-h&255;return b+c};c.prototype.writeIntBE=function(a,b,c,d){a=+a;b|=0;d||(d=Math.pow(2,8*c-1),q(this,a,b,c,d-1,-d));d=c-1;var e=1,h=0>a?1:0;for(this[b+d]=a&255;0<=--d&&(e*=256);)this[b+d]=(a/e>>0)-h&255;return b+c};c.prototype.writeInt8=function(a,b,d){a=+a;b|=0;d||q(this,a,b,1,127,-128);c.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));
0>a&&(a=255+a+1);this[b]=a;return b+1};c.prototype.writeInt16LE=function(a,b,d){a=+a;b|=0;d||q(this,a,b,2,32767,-32768);c.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):x(this,a,b,!0);return b+2};c.prototype.writeInt16BE=function(a,b,d){a=+a;b|=0;d||q(this,a,b,2,32767,-32768);c.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):x(this,a,b,!1);return b+2};c.prototype.writeInt32LE=function(a,b,d){a=+a;b|=0;d||q(this,a,b,4,2147483647,-2147483648);c.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8,this[b+
2]=a>>>16,this[b+3]=a>>>24):u(this,a,b,!0);return b+4};c.prototype.writeInt32BE=function(a,b,d){a=+a;b|=0;d||q(this,a,b,4,2147483647,-2147483648);0>a&&(a=4294967295+a+1);c.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+2]=a>>>8,this[b+3]=a):u(this,a,b,!1);return b+4};c.prototype.writeFloatLE=function(a,b,c){return E(this,a,b,!0,c)};c.prototype.writeFloatBE=function(a,b,c){return E(this,a,b,!1,c)};c.prototype.writeDoubleLE=function(a,b,c){return w(this,a,b,!0,c)};c.prototype.writeDoubleBE=
function(a,b,c){return w(this,a,b,!1,c)};c.prototype.copy=function(a,b,d,e){d||(d=0);e||0===e||(e=this.length);b>=a.length&&(b=a.length);b||(b=0);0<e&&e<d&&(e=d);if(e===d||0===a.length||0===this.length)return 0;if(0>b)throw new RangeError("targetStart out of bounds");if(0>d||d>=this.length)throw new RangeError("sourceStart out of bounds");if(0>e)throw new RangeError("sourceEnd out of bounds");e>this.length&&(e=this.length);a.length-b<e-d&&(e=a.length-b+d);var h=e-d;if(this===a&&d<b&&b<e)for(e=h-1;0<=
e;e--)a[e+b]=this[e+d];else if(1E3>h||!c.TYPED_ARRAY_SUPPORT)for(e=0;e<h;e++)a[e+b]=this[e+d];else a._set(this.subarray(d,d+h),b);return h};c.prototype.fill=function(a,b,c){a||(a=0);b||(b=0);c||(c=this.length);if(c<b)throw new RangeError("end < start");if(c!==b&&0!==this.length){if(0>b||b>=this.length)throw new RangeError("start out of bounds");if(0>c||c>this.length)throw new RangeError("end out of bounds");if("number"===typeof a)for(;b<c;b++)this[b]=a;else{a=F(a.toString());for(var d=a.length;b<
c;b++)this[b]=a[b%d]}return this}};c.prototype.toArrayBuffer=function(){if("undefined"!==typeof Uint8Array){if(c.TYPED_ARRAY_SUPPORT)return(new c(this)).buffer;for(var a=new Uint8Array(this.length),b=0,d=a.length;b<d;b+=1)a[b]=this[b];return a.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser");};var v=c.prototype;c._augment=function(a){a.constructor=c;a._isBuffer=!0;a._set=a.set;a.get=v.get;a.set=v.set;a.write=v.write;a.toString=v.toString;a.toLocaleString=v.toString;
a.toJSON=v.toJSON;a.equals=v.equals;a.compare=v.compare;a.indexOf=v.indexOf;a.copy=v.copy;a.slice=v.slice;a.readUIntLE=v.readUIntLE;a.readUIntBE=v.readUIntBE;a.readUInt8=v.readUInt8;a.readUInt16LE=v.readUInt16LE;a.readUInt16BE=v.readUInt16BE;a.readUInt32LE=v.readUInt32LE;a.readUInt32BE=v.readUInt32BE;a.readIntLE=v.readIntLE;a.readIntBE=v.readIntBE;a.readInt8=v.readInt8;a.readInt16LE=v.readInt16LE;a.readInt16BE=v.readInt16BE;a.readInt32LE=v.readInt32LE;a.readInt32BE=v.readInt32BE;a.readFloatLE=v.readFloatLE;
a.readFloatBE=v.readFloatBE;a.readDoubleLE=v.readDoubleLE;a.readDoubleBE=v.readDoubleBE;a.writeUInt8=v.writeUInt8;a.writeUIntLE=v.writeUIntLE;a.writeUIntBE=v.writeUIntBE;a.writeUInt16LE=v.writeUInt16LE;a.writeUInt16BE=v.writeUInt16BE;a.writeUInt32LE=v.writeUInt32LE;a.writeUInt32BE=v.writeUInt32BE;a.writeIntLE=v.writeIntLE;a.writeIntBE=v.writeIntBE;a.writeInt8=v.writeInt8;a.writeInt16LE=v.writeInt16LE;a.writeInt16BE=v.writeInt16BE;a.writeInt32LE=v.writeInt32LE;a.writeInt32BE=v.writeInt32BE;a.writeFloatLE=
v.writeFloatLE;a.writeFloatBE=v.writeFloatBE;a.writeDoubleLE=v.writeDoubleLE;a.writeDoubleBE=v.writeDoubleBE;a.fill=v.fill;a.inspect=v.inspect;a.toArrayBuffer=v.toArrayBuffer;return a};var K=/[^+\/0-9A-Za-z-_]/g},{"base64-js":44,ieee754:45,"is-array":46}],44:[function(f,m,g){(function(c){function f(b){b=b.charCodeAt(0);if(43===b||45===b)return 62;if(47===b||95===b)return 63;if(48>b)return-1;if(58>b)return b-48+52;if(91>b)return b-65;if(123>b)return b-97+26}var b="undefined"!==typeof Uint8Array?Uint8Array:
Array;c.toByteArray=function(c){function k(a){m[q++]=a}var a,h,d,g,m;if(0<c.length%4)throw Error("Invalid string. Length must be a multiple of 4");a=c.length;g="="===c.charAt(a-2)?2:"="===c.charAt(a-1)?1:0;m=new b(3*c.length/4-g);h=0<g?c.length-4:c.length;var q=0;for(a=0;a<h;a+=4)d=f(c.charAt(a))<<18|f(c.charAt(a+1))<<12|f(c.charAt(a+2))<<6|f(c.charAt(a+3)),k((d&16711680)>>16),k((d&65280)>>8),k(d&255);2===g?(d=f(c.charAt(a))<<2|f(c.charAt(a+1))>>4,k(d&255)):1===g&&(d=f(c.charAt(a))<<10|f(c.charAt(a+
1))<<4|f(c.charAt(a+2))>>2,k(d>>8&255),k(d&255));return m};c.fromByteArray=function(b){var c,a=b.length%3,h="",d,f;c=0;for(f=b.length-a;c<f;c+=3)d=(b[c]<<16)+(b[c+1]<<8)+b[c+2],d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>18&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>12&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>6&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d&
63),h+=d;switch(a){case 1:d=b[b.length-1];h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>2);h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d<<4&63);h+="==";break;case 2:d=(b[b.length-2]<<8)+b[b.length-1],h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>10),h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d>>4&63),h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d<<
2&63),h+="="}return h}})("undefined"===typeof g?this.base64js={}:g)},{}],45:[function(f,m,g){g.read=function(c,f,b,e,k){var a;a=8*k-e-1;var h=(1<<a)-1,d=h>>1,g=-7;k=b?k-1:0;var m=b?-1:1,q=c[f+k];k+=m;b=q&(1<<-g)-1;q>>=-g;for(g+=a;0<g;b=256*b+c[f+k],k+=m,g-=8);a=b&(1<<-g)-1;b>>=-g;for(g+=e;0<g;a=256*a+c[f+k],k+=m,g-=8);if(0===b)b=1-d;else{if(b===h)return a?NaN:Infinity*(q?-1:1);a+=Math.pow(2,e);b-=d}return(q?-1:1)*a*Math.pow(2,b-e)};g.write=function(c,f,b,e,k,a){var h,d=8*a-k-1,g=(1<<d)-1,m=g>>1,q=
23===k?Math.pow(2,-24)-Math.pow(2,-77):0;a=e?0:a-1;var x=e?1:-1,u=0>f||0===f&&0>1/f?1:0;f=Math.abs(f);isNaN(f)||Infinity===f?(f=isNaN(f)?1:0,e=g):(e=Math.floor(Math.log(f)/Math.LN2),1>f*(h=Math.pow(2,-e))&&(e--,h*=2),f=1<=e+m?f+q/h:f+q*Math.pow(2,1-m),2<=f*h&&(e++,h/=2),e+m>=g?(f=0,e=g):1<=e+m?(f=(f*h-1)*Math.pow(2,k),e+=m):(f=f*Math.pow(2,m-1)*Math.pow(2,k),e=0));for(;8<=k;c[b+a]=f&255,a+=x,f/=256,k-=8);e=e<<k|f;for(d+=k;0<d;c[b+a]=e&255,a+=x,e/=256,d-=8);c[b+a-x]|=128*u}},{}],46:[function(f,m,g){var c=
Object.prototype.toString;m.exports=Array.isArray||function(f){return!!f&&"[object Array]"==c.call(f)}},{}],47:[function(f,m,g){function c(){this._events=this._events||{};this._maxListeners=this._maxListeners||void 0}function l(b){return"function"===typeof b}function b(b){return"object"===typeof b&&null!==b}m.exports=c;c.EventEmitter=c;c.prototype._events=void 0;c.prototype._maxListeners=void 0;c.defaultMaxListeners=10;c.prototype.setMaxListeners=function(b){if("number"!==typeof b||0>b||isNaN(b))throw TypeError("n must be a positive number");
this._maxListeners=b;return this};c.prototype.emit=function(c){var f,a,h,d;this._events||(this._events={});if("error"===c&&(!this._events.error||b(this._events.error)&&!this._events.error.length)){f=arguments[1];if(f instanceof Error)throw f;throw TypeError('Uncaught, unspecified "error" event.');}a=this._events[c];if(void 0===a)return!1;if(l(a))switch(arguments.length){case 1:a.call(this);break;case 2:a.call(this,arguments[1]);break;case 3:a.call(this,arguments[1],arguments[2]);break;default:f=arguments.length;
h=Array(f-1);for(d=1;d<f;d++)h[d-1]=arguments[d];a.apply(this,h)}else if(b(a)){f=arguments.length;h=Array(f-1);for(d=1;d<f;d++)h[d-1]=arguments[d];a=a.slice();f=a.length;for(d=0;d<f;d++)a[d].apply(this,h)}return!0};c.prototype.addListener=function(e,f){var a;if(!l(f))throw TypeError("listener must be a function");this._events||(this._events={});this._events.newListener&&this.emit("newListener",e,l(f.listener)?f.listener:f);this._events[e]?b(this._events[e])?this._events[e].push(f):this._events[e]=
[this._events[e],f]:this._events[e]=f;b(this._events[e])&&!this._events[e].warned&&(a=void 0!==this._maxListeners?this._maxListeners:c.defaultMaxListeners)&&0<a&&this._events[e].length>a&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"===typeof console.trace&&console.trace());return this};c.prototype.on=c.prototype.addListener;c.prototype.once=
function(b,c){function a(){this.removeListener(b,a);h||(h=!0,c.apply(this,arguments))}if(!l(c))throw TypeError("listener must be a function");var h=!1;a.listener=c;this.on(b,a);return this};c.prototype.removeListener=function(c,f){var a,h,d;if(!l(f))throw TypeError("listener must be a function");if(!this._events||!this._events[c])return this;a=this._events[c];d=a.length;h=-1;if(a===f||l(a.listener)&&a.listener===f)delete this._events[c],this._events.removeListener&&this.emit("removeListener",c,f);
else if(b(a)){for(;0<d--;)if(a[d]===f||a[d].listener&&a[d].listener===f){h=d;break}if(0>h)return this;1===a.length?(a.length=0,delete this._events[c]):a.splice(h,1);this._events.removeListener&&this.emit("removeListener",c,f)}return this};c.prototype.removeAllListeners=function(b){var c;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[b]&&delete this._events[b],this;if(0===arguments.length){for(c in this._events)"removeListener"!==
c&&this.removeAllListeners(c);this.removeAllListeners("removeListener");this._events={};return this}c=this._events[b];if(l(c))this.removeListener(b,c);else for(;c.length;)this.removeListener(b,c[c.length-1]);delete this._events[b];return this};c.prototype.listeners=function(b){return this._events&&this._events[b]?l(this._events[b])?[this._events[b]]:this._events[b].slice():[]};c.listenerCount=function(b,c){return b._events&&b._events[c]?l(b._events[c])?1:b._events[c].length:0}},{}],48:[function(f,
m,g){m.exports="function"===typeof Object.create?function(c,f){c.super_=f;c.prototype=Object.create(f.prototype,{constructor:{value:c,enumerable:!1,writable:!0,configurable:!0}})}:function(c,f){c.super_=f;var b=function(){};b.prototype=f.prototype;c.prototype=new b;c.prototype.constructor=c}},{}],49:[function(f,m,g){m.exports=Array.isArray||function(c){return"[object Array]"==Object.prototype.toString.call(c)}},{}],50:[function(f,m,g){g.endianness=function(){return"LE"};g.hostname=function(){return"undefined"!==
typeof location?location.hostname:""};g.loadavg=function(){return[]};g.uptime=function(){return 0};g.freemem=function(){return Number.MAX_VALUE};g.totalmem=function(){return Number.MAX_VALUE};g.cpus=function(){return[]};g.type=function(){return"Browser"};g.release=function(){return"undefined"!==typeof navigator?navigator.appVersion:""};g.networkInterfaces=g.getNetworkInterfaces=function(){return{}};g.arch=function(){return"javascript"};g.platform=function(){return"browser"};g.tmpdir=g.tmpDir=function(){return"/tmp"};
g.EOL="\n"},{}],51:[function(f,m,g){function c(){a=!1;h.length?k=h.concat(k):d=-1;k.length&&l()}function l(){if(!a){var b=setTimeout(c);a=!0;for(var e=k.length;e;){h=k;for(k=[];++d<e;)h&&h[d].run();d=-1;e=k.length}h=null;a=!1;clearTimeout(b)}}function b(a,b){this.fun=a;this.array=b}function e(){}f=m.exports={};var k=[],a=!1,h,d=-1;f.nextTick=function(c){var d=Array(arguments.length-1);if(1<arguments.length)for(var e=1;e<arguments.length;e++)d[e-1]=arguments[e];k.push(new b(c,d));1!==k.length||a||
setTimeout(l,0)};b.prototype.run=function(){this.fun.apply(null,this.array)};f.title="browser";f.browser=!0;f.env={};f.argv=[];f.version="";f.versions={};f.on=e;f.addListener=e;f.once=e;f.off=e;f.removeListener=e;f.removeAllListeners=e;f.emit=e;f.binding=function(a){throw Error("process.binding is not supported");};f.cwd=function(){return"/"};f.chdir=function(a){throw Error("process.chdir is not supported");};f.umask=function(){return 0}},{}],52:[function(f,m,g){m.exports=f("./lib/_stream_duplex.js")},
{"./lib/_stream_duplex.js":53}],53:[function(f,m,g){(function(c){function g(c){if(!(this instanceof g))return new g(c);a.call(this,c);h.call(this,c);c&&!1===c.readable&&(this.readable=!1);c&&!1===c.writable&&(this.writable=!1);this.allowHalfOpen=!0;c&&!1===c.allowHalfOpen&&(this.allowHalfOpen=!1);this.once("end",b)}function b(){this.allowHalfOpen||this._writableState.ended||c.nextTick(this.end.bind(this))}m.exports=g;var e=Object.keys||function(a){var b=[],c;for(c in a)b.push(c);return b},k=f("core-util-is");
k.inherits=f("inherits");var a=f("./_stream_readable"),h=f("./_stream_writable");k.inherits(g,a);(function(a,b){for(var c=0,e=a.length;c<e;c++)b(a[c],c)})(e(h.prototype),function(a){g.prototype[a]||(g.prototype[a]=h.prototype[a])})}).call(this,f("_process"))},{"./_stream_readable":55,"./_stream_writable":57,_process:51,"core-util-is":58,inherits:48}],54:[function(f,m,g){function c(b){if(!(this instanceof c))return new c(b);l.call(this,b)}m.exports=c;var l=f("./_stream_transform");m=f("core-util-is");
m.inherits=f("inherits");m.inherits(c,l);c.prototype._transform=function(b,c,f){f(null,b)}},{"./_stream_transform":56,"core-util-is":58,inherits:48}],55:[function(f,m,g){(function(c){function g(a,b){var c=f("./_stream_duplex");a=a||{};var d=a.highWaterMark,e=a.objectMode?16:16384;this.highWaterMark=d||0===d?d:e;this.highWaterMark=~~this.highWaterMark;this.buffer=[];this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.reading=this.endEmitted=this.ended=!1;this.sync=!0;this.readableListening=
this.emittedReadable=this.needReadable=!1;this.objectMode=!!a.objectMode;b instanceof c&&(this.objectMode=this.objectMode||!!a.readableObjectMode);this.defaultEncoding=a.defaultEncoding||"utf8";this.ranOut=!1;this.awaitDrain=0;this.readingMore=!1;this.encoding=this.decoder=null;a.encoding&&(y||(y=f("string_decoder/").StringDecoder),this.decoder=new y(a.encoding),this.encoding=a.encoding)}function b(a){f("./_stream_duplex");if(!(this instanceof b))return new b(a);this._readableState=new g(a,this);
this.readable=!0;F.call(this)}function e(b,c,e,h,f){var k;k=e;var g=null;B.isBuffer(k)||B.isString(k)||B.isNullOrUndefined(k)||c.objectMode||(g=new TypeError("Invalid non-string/buffer chunk"));(k=g)?b.emit("error",k):B.isNullOrUndefined(e)?(c.reading=!1,c.ended||(c.decoder&&!c.ended&&(e=c.decoder.end())&&e.length&&(c.buffer.push(e),c.length+=c.objectMode?1:e.length),c.ended=!0,a(b))):c.objectMode||e&&0<e.length?c.ended&&!f?(e=Error("stream.push() after EOF"),b.emit("error",e)):c.endEmitted&&f?(e=
Error("stream.unshift() after end event"),b.emit("error",e)):(!c.decoder||f||h||(e=c.decoder.write(e)),f||(c.reading=!1),c.flowing&&0===c.length&&!c.sync?(b.emit("data",e),b.read(0)):(c.length+=c.objectMode?1:e.length,f?c.buffer.unshift(e):c.buffer.push(e),c.needReadable&&a(b)),d(b,c)):f||(c.reading=!1);return!c.ended&&(c.needReadable||c.length<c.highWaterMark||0===c.length)}function k(a,b){if(0===b.length&&b.ended)return 0;if(b.objectMode)return 0===a?0:1;if(isNaN(a)||B.isNull(a))return b.flowing&&
b.buffer.length?b.buffer[0].length:b.length;if(0>=a)return 0;if(a>b.highWaterMark){var c=a;if(8388608<=c)c=8388608;else{c--;for(var d=1;32>d;d<<=1)c|=c>>d;c++}b.highWaterMark=c}if(a>b.length){if(b.ended)return b.length;b.needReadable=!0;return 0}return a}function a(a){var b=a._readableState;b.needReadable=!1;b.emittedReadable||(z("emitReadable",b.flowing),b.emittedReadable=!0,b.sync?c.nextTick(function(){h(a)}):h(a))}function h(a){z("emit readable");a.emit("readable");q(a)}function d(a,b){b.readingMore||
(b.readingMore=!0,c.nextTick(function(){for(var c=b.length;!b.reading&&!b.flowing&&!b.ended&&b.length<b.highWaterMark&&(z("maybeReadMore read 0"),a.read(0),c!==b.length);)c=b.length;b.readingMore=!1}))}function t(a){return function(){var b=a._readableState;z("pipeOnDrain",b.awaitDrain);b.awaitDrain&&b.awaitDrain--;0===b.awaitDrain&&A.listenerCount(a,"data")&&(b.flowing=!0,q(a))}}function r(a,b){b.resumeScheduled||(b.resumeScheduled=!0,c.nextTick(function(){b.resumeScheduled=!1;a.emit("resume");q(a);
b.flowing&&!b.reading&&a.read(0)}))}function q(a){var b=a._readableState;z("flow",b.flowing);if(b.flowing){do var c=a.read();while(null!==c&&b.flowing)}}function x(a,b){var c=b.buffer,d=b.length,e=!!b.decoder,h=!!b.objectMode;if(0===c.length)return null;if(0===d)d=null;else if(h)d=c.shift();else if(!a||a>=d)d=e?c.join(""):w.concat(c,d),c.length=0;else if(a<c[0].length)h=c[0],d=h.slice(0,a),c[0]=h.slice(a);else if(a===c[0].length)d=c.shift();else for(var d=e?"":new w(a),f=0,k=0,g=c.length;k<g&&f<a;k++){var h=
c[0],l=Math.min(a-f,h.length);e?d+=h.slice(0,l):h.copy(d,f,0,l);l<h.length?c[0]=h.slice(l):c.shift();f+=l}return d}function u(a){var b=a._readableState;if(0<b.length)throw Error("endReadable called on non-empty stream");b.endEmitted||(b.ended=!0,c.nextTick(function(){b.endEmitted||0!==b.length||(b.endEmitted=!0,a.readable=!1,a.emit("end"))}))}function D(a,b){for(var c=0,d=a.length;c<d;c++)b(a[c],c)}m.exports=b;var E=f("isarray"),w=f("buffer").Buffer;b.ReadableState=g;var A=f("events").EventEmitter;
A.listenerCount||(A.listenerCount=function(a,b){return a.listeners(b).length});var F=f("stream"),B=f("core-util-is");B.inherits=f("inherits");var y,z=f("util"),z=z&&z.debuglog?z.debuglog("stream"):function(){};B.inherits(b,F);b.prototype.push=function(a,b){var c=this._readableState;B.isString(a)&&!c.objectMode&&(b=b||c.defaultEncoding,b!==c.encoding&&(a=new w(a,b),b=""));return e(this,c,a,b,!1)};b.prototype.unshift=function(a){return e(this,this._readableState,a,"",!0)};b.prototype.setEncoding=function(a){y||
(y=f("string_decoder/").StringDecoder);this._readableState.decoder=new y(a);this._readableState.encoding=a;return this};b.prototype.read=function(b){z("read",b);var c=this._readableState,d=b;if(!B.isNumber(b)||0<b)c.emittedReadable=!1;if(0===b&&c.needReadable&&(c.length>=c.highWaterMark||c.ended))return z("read: emitReadable",c.length,c.ended),0===c.length&&c.ended?u(this):a(this),null;b=k(b,c);if(0===b&&c.ended)return 0===c.length&&u(this),null;var e=c.needReadable;z("need readable",e);if(0===c.length||
c.length-b<c.highWaterMark)e=!0,z("length less than watermark",e);if(c.ended||c.reading)e=!1,z("reading or ended",e);e&&(z("do read"),c.reading=!0,c.sync=!0,0===c.length&&(c.needReadable=!0),this._read(c.highWaterMark),c.sync=!1);e&&!c.reading&&(b=k(d,c));e=0<b?x(b,c):null;B.isNull(e)&&(c.needReadable=!0,b=0);c.length-=b;0!==c.length||c.ended||(c.needReadable=!0);d!==b&&c.ended&&0===c.length&&u(this);B.isNull(e)||this.emit("data",e);return e};b.prototype._read=function(a){this.emit("error",Error("not implemented"))};
b.prototype.pipe=function(a,b){function d(a){z("onunpipe");a===y&&h()}function e(){z("onend");a.end()}function h(){z("cleanup");a.removeListener("close",g);a.removeListener("finish",l);a.removeListener("drain",B);a.removeListener("error",k);a.removeListener("unpipe",d);y.removeListener("end",e);y.removeListener("end",h);y.removeListener("data",f);!r.awaitDrain||a._writableState&&!a._writableState.needDrain||B()}function f(b){z("ondata");!1===a.write(b)&&(z("false write response, pause",y._readableState.awaitDrain),
y._readableState.awaitDrain++,y.pause())}function k(b){z("onerror",b);m();a.removeListener("error",k);0===A.listenerCount(a,"error")&&a.emit("error",b)}function g(){a.removeListener("finish",l);m()}function l(){z("onfinish");a.removeListener("close",g);m()}function m(){z("unpipe");y.unpipe(a)}var y=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=a;break;case 1:r.pipes=[r.pipes,a];break;default:r.pipes.push(a)}r.pipesCount+=1;z("pipe count=%d opts=%j",r.pipesCount,b);var u=b&&!1===b.end||
a===c.stdout||a===c.stderr?h:e;if(r.endEmitted)c.nextTick(u);else y.once("end",u);a.on("unpipe",d);var B=t(y);a.on("drain",B);y.on("data",f);if(a._events&&a._events.error)E(a._events.error)?a._events.error.unshift(k):a._events.error=[k,a._events.error];else a.on("error",k);a.once("close",g);a.once("finish",l);a.emit("pipe",y);r.flowing||(z("pipe resume"),y.resume());return a};b.prototype.unpipe=function(a){var b=this._readableState;if(0===b.pipesCount)return this;if(1===b.pipesCount){if(a&&a!==b.pipes)return this;
a||(a=b.pipes);b.pipes=null;b.pipesCount=0;b.flowing=!1;a&&a.emit("unpipe",this);return this}if(!a){a=b.pipes;var c=b.pipesCount;b.pipes=null;b.pipesCount=0;b.flowing=!1;for(var d=0;d<c;d++)a[d].emit("unpipe",this);return this}a:{for(var d=b.pipes,c=0,e=d.length;c<e;c++)if(d[c]===a){d=c;break a}d=-1}if(-1===d)return this;b.pipes.splice(d,1);--b.pipesCount;1===b.pipesCount&&(b.pipes=b.pipes[0]);a.emit("unpipe",this);return this};b.prototype.on=function(b,d){var e=F.prototype.on.call(this,b,d);"data"===
b&&!1!==this._readableState.flowing&&this.resume();if("readable"===b&&this.readable){var h=this._readableState;if(!h.readableListening)if(h.readableListening=!0,h.emittedReadable=!1,h.needReadable=!0,h.reading)h.length&&a(this,h);else{var f=this;c.nextTick(function(){z("readable nexttick read 0");f.read(0)})}}return e};b.prototype.addListener=b.prototype.on;b.prototype.resume=function(){var a=this._readableState;a.flowing||(z("resume"),a.flowing=!0,a.reading||(z("resume read 0"),this.read(0)),r(this,
a));return this};b.prototype.pause=function(){z("call pause flowing=%j",this._readableState.flowing);!1!==this._readableState.flowing&&(z("pause"),this._readableState.flowing=!1,this.emit("pause"));return this};b.prototype.wrap=function(a){var b=this._readableState,c=!1,d=this;a.on("end",function(){z("wrapped end");if(b.decoder&&!b.ended){var a=b.decoder.end();a&&a.length&&d.push(a)}d.push(null)});a.on("data",function(e){z("wrapped data");b.decoder&&(e=b.decoder.write(e));e&&(b.objectMode||e.length)&&
!d.push(e)&&(c=!0,a.pause())});for(var e in a)B.isFunction(a[e])&&B.isUndefined(this[e])&&(this[e]=function(b){return function(){return a[b].apply(a,arguments)}}(e));D(["error","close","destroy","pause","resume"],function(b){a.on(b,d.emit.bind(d,b))});d._read=function(b){z("wrapped _read",b);c&&(c=!1,a.resume())};return d};b._fromList=x}).call(this,f("_process"))},{"./_stream_duplex":53,_process:51,buffer:43,"core-util-is":58,events:47,inherits:48,isarray:49,stream:63,"string_decoder/":64,util:42}],
56:[function(f,m,g){function c(a,b){this.afterTransform=function(a,c){var e;e=b._transformState;e.transforming=!1;var f=e.writecb;f?(e.writechunk=null,e.writecb=null,k.isNullOrUndefined(c)||b.push(c),f&&f(a),e=b._readableState,e.reading=!1,(e.needReadable||e.length<e.highWaterMark)&&b._read(e.highWaterMark),e=void 0):e=b.emit("error",Error("no writecb in Transform class"));return e};this.transforming=this.needTransform=!1;this.writechunk=this.writecb=null}function l(a){if(!(this instanceof l))return new l(a);
e.call(this,a);this._transformState=new c(a,this);var h=this;this._readableState.needReadable=!0;this._readableState.sync=!1;this.once("prefinish",function(){k.isFunction(this._flush)?this._flush(function(a){b(h,a)}):b(h)})}function b(a,b){if(b)return a.emit("error",b);var c=a._transformState;if(a._writableState.length)throw Error("calling transform done when ws.length != 0");if(c.transforming)throw Error("calling transform done when still transforming");return a.push(null)}m.exports=l;var e=f("./_stream_duplex"),
k=f("core-util-is");k.inherits=f("inherits");k.inherits(l,e);l.prototype.push=function(a,b){this._transformState.needTransform=!1;return e.prototype.push.call(this,a,b)};l.prototype._transform=function(a,b,c){throw Error("not implemented");};l.prototype._write=function(a,b,c){var e=this._transformState;e.writecb=c;e.writechunk=a;e.writeencoding=b;e.transforming||(a=this._readableState,(e.needTransform||a.needReadable||a.length<a.highWaterMark)&&this._read(a.highWaterMark))};l.prototype._read=function(a){a=
this._transformState;k.isNull(a.writechunk)||!a.writecb||a.transforming?a.needTransform=!0:(a.transforming=!0,this._transform(a.writechunk,a.writeencoding,a.afterTransform))}},{"./_stream_duplex":53,"core-util-is":58,inherits:48}],57:[function(f,m,g){(function(c){function g(a,b,c){this.chunk=a;this.encoding=b;this.callback=c}function b(a,b){var c=f("./_stream_duplex");a=a||{};var d=a.highWaterMark,e=a.objectMode?16:16384;this.highWaterMark=d||0===d?d:e;this.objectMode=!!a.objectMode;b instanceof c&&
(this.objectMode=this.objectMode||!!a.writableObjectMode);this.highWaterMark=~~this.highWaterMark;this.finished=this.ended=this.ending=this.needDrain=!1;this.decodeStrings=!1!==a.decodeStrings;this.defaultEncoding=a.defaultEncoding||"utf8";this.length=0;this.writing=!1;this.corked=0;this.sync=!0;this.bufferProcessing=!1;this.onwrite=function(a){q(b,a)};this.writecb=null;this.writelen=0;this.buffer=[];this.pendingcb=0;this.errorEmitted=this.prefinished=!1}function e(a){var c=f("./_stream_duplex");
if(!(this instanceof e||this instanceof c))return new e(a);this._writableState=new b(a,this);this.writable=!0;A.call(this)}function k(a,b,d){var e=Error("write after end");a.emit("error",e);c.nextTick(function(){d(e)})}function a(a,b,d,e){var h=!0;if(!(w.isBuffer(d)||w.isString(d)||w.isNullOrUndefined(d)||b.objectMode)){var f=new TypeError("Invalid non-string/buffer chunk");a.emit("error",f);c.nextTick(function(){e(f)});h=!1}return h}function h(a,b,c,e,h){var f=e;!b.objectMode&&!1!==b.decodeStrings&&
w.isString(c)&&(c=new E(c,f));w.isBuffer(c)&&(e="buffer");f=b.objectMode?1:c.length;b.length+=f;var k=b.length<b.highWaterMark;k||(b.needDrain=!0);b.writing||b.corked?b.buffer.push(new g(c,e,h)):d(a,b,!1,f,c,e,h);return k}function d(a,b,c,d,e,h,f){b.writelen=d;b.writecb=f;b.writing=!0;b.sync=!0;c?a._writev(e,b.onwrite):a._write(e,h,b.onwrite);b.sync=!1}function t(a,b,d,e,h){d?c.nextTick(function(){b.pendingcb--;h(e)}):(b.pendingcb--,h(e));a._writableState.errorEmitted=!0;a.emit("error",e)}function r(a){a.writing=
!1;a.writecb=null;a.length-=a.writelen;a.writelen=0}function q(a,b){var d=a._writableState,e=d.sync,h=d.writecb;r(d);if(b)t(a,d,e,b,h);else{var f=d.ending&&0===d.length&&!d.finished&&!d.writing;f||d.corked||d.bufferProcessing||!d.buffer.length||u(a,d);e?c.nextTick(function(){x(a,d,f,h)}):x(a,d,f,h)}}function x(a,b,c,d){!c&&0===b.length&&b.needDrain&&(b.needDrain=!1,a.emit("drain"));b.pendingcb--;d();D(a,b)}function u(a,b){b.bufferProcessing=!0;if(a._writev&&1<b.buffer.length){for(var c=[],e=0;e<b.buffer.length;e++)c.push(b.buffer[e].callback);
b.pendingcb++;d(a,b,!0,b.length,b.buffer,"",function(a){for(var d=0;d<c.length;d++)b.pendingcb--,c[d](a)});b.buffer=[]}else{for(e=0;e<b.buffer.length;e++){var h=b.buffer[e],f=h.chunk;d(a,b,!1,b.objectMode?1:f.length,f,h.encoding,h.callback);if(b.writing){e++;break}}e<b.buffer.length?b.buffer=b.buffer.slice(e):b.buffer.length=0}b.bufferProcessing=!1}function D(a,b){var c=b.ending&&0===b.length&&!b.finished&&!b.writing;c&&(0===b.pendingcb?(b.prefinished||(b.prefinished=!0,a.emit("prefinish")),b.finished=
!0,a.emit("finish")):b.prefinished||(b.prefinished=!0,a.emit("prefinish")));return c}m.exports=e;var E=f("buffer").Buffer;e.WritableState=b;var w=f("core-util-is");w.inherits=f("inherits");var A=f("stream");w.inherits(e,A);e.prototype.pipe=function(){this.emit("error",Error("Cannot pipe. Not readable."))};e.prototype.write=function(b,c,d){var e=this._writableState,f=!1;w.isFunction(c)&&(d=c,c=null);w.isBuffer(b)?c="buffer":c||(c=e.defaultEncoding);w.isFunction(d)||(d=function(){});e.ended?k(this,
e,d):a(this,e,b,d)&&(e.pendingcb++,f=h(this,e,b,c,d));return f};e.prototype.cork=function(){this._writableState.corked++};e.prototype.uncork=function(){var a=this._writableState;a.corked&&(a.corked--,a.writing||a.corked||a.finished||a.bufferProcessing||!a.buffer.length||u(this,a))};e.prototype._write=function(a,b,c){c(Error("not implemented"))};e.prototype._writev=null;e.prototype.end=function(a,b,d){var e=this._writableState;w.isFunction(a)?(d=a,b=a=null):w.isFunction(b)&&(d=b,b=null);w.isNullOrUndefined(a)||
this.write(a,b);e.corked&&(e.corked=1,this.uncork());if(!e.ending&&!e.finished){a=d;e.ending=!0;D(this,e);if(a)if(e.finished)c.nextTick(a);else this.once("finish",a);e.ended=!0}}}).call(this,f("_process"))},{"./_stream_duplex":53,_process:51,buffer:43,"core-util-is":58,inherits:48,stream:63}],58:[function(f,m,g){(function(c){function f(b){return"object"===typeof b&&null!==b}g.isArray=function(b){return Array.isArray(b)};g.isBoolean=function(b){return"boolean"===typeof b};g.isNull=function(b){return null===
b};g.isNullOrUndefined=function(b){return null==b};g.isNumber=function(b){return"number"===typeof b};g.isString=function(b){return"string"===typeof b};g.isSymbol=function(b){return"symbol"===typeof b};g.isUndefined=function(b){return void 0===b};g.isRegExp=function(b){return f(b)&&"[object RegExp]"===Object.prototype.toString.call(b)};g.isObject=f;g.isDate=function(b){return f(b)&&"[object Date]"===Object.prototype.toString.call(b)};g.isError=function(b){return f(b)&&("[object Error]"===Object.prototype.toString.call(b)||
b instanceof Error)};g.isFunction=function(b){return"function"===typeof b};g.isPrimitive=function(b){return null===b||"boolean"===typeof b||"number"===typeof b||"string"===typeof b||"symbol"===typeof b||"undefined"===typeof b};g.isBuffer=function(b){return c.isBuffer(b)}}).call(this,f("buffer").Buffer)},{buffer:43}],59:[function(f,m,g){m.exports=f("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":54}],60:[function(f,m,g){g=m.exports=f("./lib/_stream_readable.js");g.Stream=f("stream");
g.Readable=g;g.Writable=f("./lib/_stream_writable.js");g.Duplex=f("./lib/_stream_duplex.js");g.Transform=f("./lib/_stream_transform.js");g.PassThrough=f("./lib/_stream_passthrough.js")},{"./lib/_stream_duplex.js":53,"./lib/_stream_passthrough.js":54,"./lib/_stream_readable.js":55,"./lib/_stream_transform.js":56,"./lib/_stream_writable.js":57,stream:63}],61:[function(f,m,g){m.exports=f("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":56}],62:[function(f,m,g){m.exports=f("./lib/_stream_writable.js")},
{"./lib/_stream_writable.js":57}],63:[function(f,m,g){function c(){l.call(this)}m.exports=c;var l=f("events").EventEmitter;f("inherits")(c,l);c.Readable=f("readable-stream/readable.js");c.Writable=f("readable-stream/writable.js");c.Duplex=f("readable-stream/duplex.js");c.Transform=f("readable-stream/transform.js");c.PassThrough=f("readable-stream/passthrough.js");c.Stream=c;c.prototype.pipe=function(b,c){function f(a){b.writable&&!1===b.write(a)&&q.pause&&q.pause()}function a(){q.readable&&q.resume&&
q.resume()}function h(){x||(x=!0,b.end())}function d(){x||(x=!0,"function"===typeof b.destroy&&b.destroy())}function g(a){m();if(0===l.listenerCount(this,"error"))throw a;}function m(){q.removeListener("data",f);b.removeListener("drain",a);q.removeListener("end",h);q.removeListener("close",d);q.removeListener("error",g);b.removeListener("error",g);q.removeListener("end",m);q.removeListener("close",m);b.removeListener("close",m)}var q=this;q.on("data",f);b.on("drain",a);b._isStdio||c&&!1===c.end||
(q.on("end",h),q.on("close",d));var x=!1;q.on("error",g);b.on("error",g);q.on("end",m);q.on("close",m);b.on("close",m);b.emit("pipe",q);return b}},{events:47,inherits:48,"readable-stream/duplex.js":52,"readable-stream/passthrough.js":59,"readable-stream/readable.js":60,"readable-stream/transform.js":61,"readable-stream/writable.js":62}],64:[function(f,m,g){function c(a){return a.toString(this.encoding)}function l(a){this.charLength=(this.charReceived=a.length%2)?2:0}function b(a){this.charLength=
(this.charReceived=a.length%3)?3:0}var e=f("buffer").Buffer,k=e.isEncoding||function(a){switch(a&&a.toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "binary":case "base64":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":case "raw":return!0;default:return!1}};f=g.StringDecoder=function(a){this.encoding=(a||"utf8").toLowerCase().replace(/[-_]/,"");if(a&&!k(a))throw Error("Unknown encoding: "+a);switch(this.encoding){case "utf8":this.surrogateSize=3;break;case "ucs2":case "utf16le":this.surrogateSize=
2;this.detectIncompleteChar=l;break;case "base64":this.surrogateSize=3;this.detectIncompleteChar=b;break;default:this.write=c;return}this.charBuffer=new e(6);this.charLength=this.charReceived=0};f.prototype.write=function(a){for(var b="";this.charLength;){b=a.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:a.length;a.copy(this.charBuffer,this.charReceived,0,b);this.charReceived+=b;if(this.charReceived<this.charLength)return"";a=a.slice(b,a.length);var b=this.charBuffer.slice(0,
this.charLength).toString(this.encoding),c=b.charCodeAt(b.length-1);if(55296<=c&&56319>=c)this.charLength+=this.surrogateSize,b="";else{this.charReceived=this.charLength=0;if(0===a.length)return b;break}}this.detectIncompleteChar(a);var e=a.length;this.charLength&&(a.copy(this.charBuffer,0,a.length-this.charReceived,e),e-=this.charReceived);b+=a.toString(this.encoding,0,e);e=b.length-1;c=b.charCodeAt(e);return 55296<=c&&56319>=c?(c=this.surrogateSize,this.charLength+=c,this.charReceived+=c,this.charBuffer.copy(this.charBuffer,
c,0,c),a.copy(this.charBuffer,0,0,c),b.substring(0,e)):b};f.prototype.detectIncompleteChar=function(a){for(var b=3<=a.length?3:a.length;0<b;b--){var c=a[a.length-b];if(1==b&&6==c>>5){this.charLength=2;break}if(2>=b&&14==c>>4){this.charLength=3;break}if(3>=b&&30==c>>3){this.charLength=4;break}}this.charReceived=b};f.prototype.end=function(a){var b="";a&&a.length&&(b=this.write(a));this.charReceived&&(a=this.encoding,b+=this.charBuffer.slice(0,this.charReceived).toString(a));return b}},{buffer:43}],
65:[function(f,m,g){m.exports=function(c){return c&&"object"===typeof c&&"function"===typeof c.copy&&"function"===typeof c.fill&&"function"===typeof c.readUInt8}},{}],66:[function(f,m,g){(function(c,l){function b(a,b){var c={seen:[],stylize:k};3<=arguments.length&&(c.depth=arguments[2]);4<=arguments.length&&(c.colors=arguments[3]);D(b)?c.showHidden=b:b&&g._extend(c,b);A(c.showHidden)&&(c.showHidden=!1);A(c.depth)&&(c.depth=2);A(c.colors)&&(c.colors=!1);A(c.customInspect)&&(c.customInspect=!0);c.colors&&
(c.stylize=e);return h(c,a,c.depth)}function e(a,c){var d=b.styles[c];return d?"\u001b["+b.colors[d][0]+"m"+a+"\u001b["+b.colors[d][1]+"m":a}function k(a,b){return a}function a(a){var b={};a.forEach(function(a,c){b[a]=!0});return b}function h(b,c,e){if(b.customInspect&&c&&n(c.inspect)&&c.inspect!==g.inspect&&(!c.constructor||c.constructor.prototype!==c)){var f=c.inspect(e,b);w(f)||(f=h(b,f,e));return f}if(f=d(b,c))return f;var k=Object.keys(c),l=a(k);b.showHidden&&(k=Object.getOwnPropertyNames(c));
if(z(c)&&(0<=k.indexOf("message")||0<=k.indexOf("description")))return m(c);if(0===k.length){if(n(c))return b.stylize("[Function"+(c.name?": "+c.name:"")+"]","special");if(F(c))return b.stylize(RegExp.prototype.toString.call(c),"regexp");if(y(c))return b.stylize(Date.prototype.toString.call(c),"date");if(z(c))return m(c)}var f="",G=!1,v=["{","}"];u(c)&&(G=!0,v=["[","]"]);n(c)&&(f=" [Function"+(c.name?": "+c.name:"")+"]");F(c)&&(f=" "+RegExp.prototype.toString.call(c));y(c)&&(f=" "+Date.prototype.toUTCString.call(c));
z(c)&&(f=" "+m(c));if(0===k.length&&(!G||0==c.length))return v[0]+f+v[1];if(0>e)return F(c)?b.stylize(RegExp.prototype.toString.call(c),"regexp"):b.stylize("[Object]","special");b.seen.push(c);k=G?r(b,c,e,l,k):k.map(function(a){return q(b,c,e,l,a,G)});b.seen.pop();return x(k,f,v)}function d(a,b){if(A(b))return a.stylize("undefined","undefined");if(w(b)){var c="'"+JSON.stringify(b).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return a.stylize(c,"string")}if(E(b))return a.stylize(""+
b,"number");if(D(b))return a.stylize(""+b,"boolean");if(null===b)return a.stylize("null","null")}function m(a){return"["+Error.prototype.toString.call(a)+"]"}function r(a,b,c,d,e){for(var h=[],f=0,k=b.length;f<k;++f)Object.prototype.hasOwnProperty.call(b,String(f))?h.push(q(a,b,c,d,String(f),!0)):h.push("");e.forEach(function(e){e.match(/^\d+$/)||h.push(q(a,b,c,d,e,!0))});return h}function q(a,b,c,d,e,f){var k,g;b=Object.getOwnPropertyDescriptor(b,e)||{value:b[e]};b.get?g=b.set?a.stylize("[Getter/Setter]",
"special"):a.stylize("[Getter]","special"):b.set&&(g=a.stylize("[Setter]","special"));Object.prototype.hasOwnProperty.call(d,e)||(k="["+e+"]");g||(0>a.seen.indexOf(b.value)?(g=null===c?h(a,b.value,null):h(a,b.value,c-1),-1<g.indexOf("\n")&&(g=f?g.split("\n").map(function(a){return" "+a}).join("\n").substr(2):"\n"+g.split("\n").map(function(a){return" "+a}).join("\n"))):g=a.stylize("[Circular]","special"));if(A(k)){if(f&&e.match(/^\d+$/))return g;k=JSON.stringify(""+e);k.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?
(k=k.substr(1,k.length-2),k=a.stylize(k,"name")):(k=k.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),k=a.stylize(k,"string"))}return k+": "+g}function x(a,b,c){var d=0;return 60<a.reduce(function(a,b){d++;0<=b.indexOf("\n")&&d++;return a+b.replace(/\u001b\[\d\d?m/g,"").length+1},0)?c[0]+(""===b?"":b+"\n ")+" "+a.join(",\n ")+" "+c[1]:c[0]+b+" "+a.join(", ")+" "+c[1]}function u(a){return Array.isArray(a)}function D(a){return"boolean"===typeof a}function E(a){return"number"===typeof a}
function w(a){return"string"===typeof a}function A(a){return void 0===a}function F(a){return B(a)&&"[object RegExp]"===Object.prototype.toString.call(a)}function B(a){return"object"===typeof a&&null!==a}function y(a){return B(a)&&"[object Date]"===Object.prototype.toString.call(a)}function z(a){return B(a)&&("[object Error]"===Object.prototype.toString.call(a)||a instanceof Error)}function n(a){return"function"===typeof a}function p(a){return 10>a?"0"+a.toString(10):a.toString(10)}function G(){var a=
new Date,b=[p(a.getHours()),p(a.getMinutes()),p(a.getSeconds())].join(":");return[a.getDate(),C[a.getMonth()],b].join(" ")}var J=/%[sdj%]/g;g.format=function(a){if(!w(a)){for(var c=[],d=0;d<arguments.length;d++)c.push(b(arguments[d]));return c.join(" ")}for(var d=1,e=arguments,h=e.length,c=String(a).replace(J,function(a){if("%%"===a)return"%";if(d>=h)return a;switch(a){case "%s":return String(e[d++]);case "%d":return Number(e[d++]);case "%j":try{return JSON.stringify(e[d++])}catch(b){return"[Circular]"}default:return a}}),
f=e[d];d<h;f=e[++d])c=null!==f&&B(f)?c+(" "+b(f)):c+(" "+f);return c};g.deprecate=function(a,b){if(A(l.process))return function(){return g.deprecate(a,b).apply(this,arguments)};if(!0===c.noDeprecation)return a;var d=!1;return function(){if(!d){if(c.throwDeprecation)throw Error(b);c.traceDeprecation?console.trace(b):console.error(b);d=!0}return a.apply(this,arguments)}};var v={},K;g.debuglog=function(a){A(K)&&(K=c.env.NODE_DEBUG||"");a=a.toUpperCase();if(!v[a])if((new RegExp("\\b"+a+"\\b","i")).test(K)){var b=
c.pid;v[a]=function(){var c=g.format.apply(g,arguments);console.error("%s %d: %s",a,b,c)}}else v[a]=function(){};return v[a]};g.inspect=b;b.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]};b.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"};g.isArray=u;g.isBoolean=D;g.isNull=
function(a){return null===a};g.isNullOrUndefined=function(a){return null==a};g.isNumber=E;g.isString=w;g.isSymbol=function(a){return"symbol"===typeof a};g.isUndefined=A;g.isRegExp=F;g.isObject=B;g.isDate=y;g.isError=z;g.isFunction=n;g.isPrimitive=function(a){return null===a||"boolean"===typeof a||"number"===typeof a||"string"===typeof a||"symbol"===typeof a||"undefined"===typeof a};g.isBuffer=f("./support/isBuffer");var C="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" ");g.log=function(){console.log("%s - %s",
G(),g.format.apply(g,arguments))};g.inherits=f("inherits");g._extend=function(a,b){if(!b||!B(b))return a;for(var c=Object.keys(b),d=c.length;d--;)a[c[d]]=b[c[d]];return a}}).call(this,f("_process"),"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{"./support/isBuffer":65,_process:51,inherits:48}],67:[function(f,m,g){(function(c,f){function b(a,b,c){if(Array.prototype.map)return Array.prototype.map.call(a,b,c);for(var d=Array(a.length),e=0,f=
a.length;e<f;e++)d[e]=b.call(c,a[e],e,a);return d}function e(a){for(var b=[],c=0;c<a.length;c++)a[c]&&b.push(a[c]);return b}function k(a){a=a.replace(/&/g,"&amp;");a=a.replace(/</g,"&lt;");a=a.replace(/>/g,"&gt;");return a=a.replace(/"/g,"&quot;")}function a(b,c,d){c=c||[];d=d||[];var e;for(e=0;e<c.length;e+=1)if(c[e]===b)return d[e];var f;if("[object Array]"===g.call(b)){c.push(b);f=Array(b.length);d.push(f);for(e=0;e<b.length;e+=1)f[e]=a(b[e],c,d);c.pop();d.pop()}else if("object"===typeof b&&null!==
b){c.push(b);f={};d.push(f);var h=[],k;for(k in b)h.push(k);h.sort();for(e=0;e<h.length;e+=1)k=h[e],f[k]=a(b[k],c,d);c.pop();d.pop()}else f=b;return f}function h(a,c,d,e){for(var f=0,h=a.length,k=0,g=0;f<h;f++){var l=a[f];if(l.removed)l.value=d.slice(g,g+l.count).join(""),g+=l.count,f&&a[f-1].added&&(l=a[f-1],a[f-1]=a[f],a[f]=l);else{if(!l.added&&e){var m=c.slice(k,k+l.count),m=b(m,function(a,b){var c=d[g+b];return c.length>a.length?c:a});l.value=m.join("")}else l.value=c.slice(k,k+l.count).join("");
k+=l.count;l.added||(g+=l.count)}}return a}function d(a){this.ignoreWhitespace=a}var g=Object.prototype.toString;d.prototype={diff:function(a,b,c){function d(a){return c?(setTimeout(function(){c(f,a)},0),!0):a}function e(){for(var c=-1*t;c<=t;c+=2){var G;G=r[c-1];var n=r[c+1],u=(n?n.newPos:0)-c;G&&(r[c-1]=f);var D=G&&G.newPos+1<g,u=n&&0<=u&&u<m;if(D||u){!D||u&&G.newPos<n.newPos?(G={newPos:n.newPos,components:n.components.slice(0)},k.pushComponent(G.components,f,!0)):(G.newPos++,k.pushComponent(G.components,
!0,f));u=k.extractCommon(G,b,a,c);if(G.newPos+1>=g&&u+1>=m)return d(h(G.components,b,a,k.useLongestToken));r[c]=G}else r[c]=f}t++}var k=this;if(b===a)return d([{value:b}]);if(!b)return d([{value:a,removed:!0}]);if(!a)return d([{value:b,added:!0}]);b=this.tokenize(b);a=this.tokenize(a);var g=b.length,m=a.length,t=1,u=g+m,r=[{newPos:-1,components:[]}],D=this.extractCommon(r[0],b,a,0);if(r[0].newPos+1>=g&&D+1>=m)return d([{value:b.join("")}]);if(c)(function M(){setTimeout(function(){if(t>u)return c();
e()||M()},0)})();else for(;t<=u;)if(D=e())return D},pushComponent:function(a,b,c){var d=a[a.length-1];d&&d.added===b&&d.removed===c?a[a.length-1]={count:d.count+1,added:b,removed:c}:a.push({count:1,added:b,removed:c})},extractCommon:function(a,b,c,d){var e=b.length,f=c.length,h=a.newPos;d=h-d;for(var k=0;h+1<e&&d+1<f&&this.equals(b[h+1],c[d+1]);)h++,d++,k++;k&&a.components.push({count:k});a.newPos=h;return d},equals:function(a,b){var c=/\S/;return a===b||this.ignoreWhitespace&&!c.test(a)&&!c.test(b)},
tokenize:function(a){return a.split("")}};var r=new d,q=new d(!0),x=new d;q.tokenize=x.tokenize=function(a){return e(a.split(/(\s+|\b)/))};var u=new d(!0);u.tokenize=function(a){return e(a.split(/([{}:;,]|\s+)/))};var D=new d,E=new d;E.ignoreTrim=!0;D.tokenize=E.tokenize=function(a){var b=[];a=a.split(/^/m);for(var c=0;c<a.length;c++){var d=a[c],e=a[c-1],e=e&&e[e.length-1];"\n"===d&&"\r"===e?b[b.length-1]=b[b.length-1].slice(0,-1)+"\r\n":(this.ignoreTrim&&(d=d.trim(),c<a.length-1&&(d+="\n")),b.push(d))}return b};
var w=new d;w.tokenize=function(a){var b=[];a=a.split(/(\n|\r\n)/);a[a.length-1]||a.pop();for(var c=0;c<a.length;c++){var d=a[c];c%2?b[b.length-1]+=d:b.push(d)}return b};var A=new d;A.tokenize=function(a){return e(a.split(/(\S.+?[.!?])(?=\s+|$)/))};var F=new d;F.useLongestToken=!0;F.tokenize=D.tokenize;F.equals=function(a,b){return D.equals(a.replace(/,([\r\n])/g,"$1"),b.replace(/,([\r\n])/g,"$1"))};var B={Diff:d,diffChars:function(a,b,c){return r.diff(a,b,c)},diffWords:function(a,b,c){return q.diff(a,
b,c)},diffWordsWithSpace:function(a,b,c){return x.diff(a,b,c)},diffLines:function(a,b,c){return D.diff(a,b,c)},diffTrimmedLines:function(a,b,c){return E.diff(a,b,c)},diffSentences:function(a,b,c){return A.diff(a,b,c)},diffCss:function(a,b,c){return u.diff(a,b,c)},diffJson:function(b,c,d){return F.diff("string"===typeof b?b:JSON.stringify(a(b),f," "),"string"===typeof c?c:JSON.stringify(a(c),f," "),d)},createTwoFilesPatch:function(a,c,d,e,f,h){function k(a){return b(a,function(a){return" "+a})}function g(a,
b,c){var d=m[m.length-2],e=b===m.length-2;b=b===m.length-3&&c.added!==d.added;/\n$/.test(c.value)||!e&&!b||a.push("\\ No newline at end of file")}var l=[];a==c&&l.push("Index: "+a);l.push("===================================================================");l.push("--- "+a+("undefined"===typeof f?"":"\t"+f));l.push("+++ "+c+("undefined"===typeof h?"":"\t"+h));var m=w.diff(d,e);m.push({value:"",lines:[]});c=a=0;d=[];f=e=1;for(h=0;h<m.length;h++){var t=m[h],u=t.lines||t.value.replace(/\n$/,"").split("\n");
t.lines=u;if(t.added||t.removed){if(!a){var r=m[h-1];a=e;c=f;r&&(d=k(r.lines.slice(-4)),a-=d.length,c-=d.length)}d.push.apply(d,b(u,function(a){return(t.added?"+":"-")+a}));g(d,h,t);t.added?f+=u.length:e+=u.length}else a&&(8>=u.length&&h<m.length-2?d.push.apply(d,k(u)):(r=Math.min(u.length,4),l.push("@@ -"+a+","+(e-a+r)+" +"+c+","+(f-c+r)+" @@"),l.push.apply(l,d),l.push.apply(l,k(u.slice(0,r))),4>=u.length&&g(l,h,t),c=a=0,d=[])),e+=u.length,f+=u.length}return l.join("\n")+"\n"},createPatch:function(a,
b,c,d,e){return B.createTwoFilesPatch(a,a,b,c,d,e)},applyPatch:function(a,b){for(var c=b.split("\n"),d=[],e=0,f=!1,h=!1;e<c.length&&!/^@@/.test(c[e]);)e++;for(;e<c.length;e++)if("@"===c[e][0]){var k=c[e].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);d.unshift({start:k[3],oldlength:+k[2],removed:[],newlength:k[4],added:[]})}else"+"===c[e][0]?d[0].added.push(c[e].substr(1)):"-"===c[e][0]?d[0].removed.push(c[e].substr(1)):" "===c[e][0]?(d[0].added.push(c[e].substr(1)),d[0].removed.push(c[e].substr(1))):
"\\"===c[e][0]&&("+"===c[e-1][0]?f=!0:"-"===c[e-1][0]&&(h=!0));c=a.split("\n");for(e=d.length-1;0<=e;e--){for(var k=d[e],g=0;g<k.oldlength;g++)if(c[k.start-1+g]!==k.removed[g])return!1;Array.prototype.splice.apply(c,[k.start-1,k.oldlength].concat(k.added))}if(f)for(;!c[c.length-1];)c.pop();else h&&c.push("");return c.join("\n")},convertChangesToXML:function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d.added?b.push("<ins>"):d.removed&&b.push("<del>");b.push(k(d.value));d.added?b.push("</ins>"):
d.removed&&b.push("</del>")}return b.join("")},convertChangesToDMP:function(a){for(var b=[],c,d,e=0;e<a.length;e++)c=a[e],d=c.added?1:c.removed?-1:0,b.push([d,c.value]);return b},canonicalize:a};"undefined"!==typeof m&&m.exports?m.exports=B:"function"===typeof define&&define.amd?define([],function(){return B}):"undefined"===typeof c.JsDiff&&(c.JsDiff=B)})(this)},{}],68:[function(f,m,g){var c=/[|\\{}()[\]^$+*?.]/g;m.exports=function(f){if("string"!==typeof f)throw new TypeError("Expected a string");
return f.replace(c,"\\$&")}},{}],69:[function(f,m,g){(function(c){function l(b){for(var d=c.env.PATH.split(":"),e,f=0,h=d.length;f<h;++f)if(e=k.join(d[f],b),a(e))return e}var b=f("child_process").exec,e=f("fs"),k=f("path"),a=e.existsSync||k.existsSync,e=f("os"),h=JSON.stringify,d;switch(e.type()){case "Darwin":d=l("terminal-notifier")?{type:"Darwin-NotificationCenter",pkg:"terminal-notifier",msg:"-message",title:"-title",subtitle:"-subtitle",priority:{cmd:"-execute",range:[]}}:{type:"Darwin-Growl",
pkg:"growlnotify",msg:"-m",sticky:"--sticky",priority:{cmd:"--priority",range:[-2,-1,0,1,2,"Very Low","Moderate","Normal","High","Emergency"]}};break;case "Linux":d={type:"Linux",pkg:"notify-send",msg:"",sticky:"-t 0",icon:"-i",priority:{cmd:"-u",range:["low","normal","critical"]}};break;case "Windows_NT":d={type:"Windows",pkg:"growlnotify",msg:"",sticky:"/s:true",title:"/t:",icon:"/i:",priority:{cmd:"/p:",range:[-2,-1,0,1,2]}}}g=m.exports=function(a,c,e){var f,g;c=c||{};e=e||function(){};if(!d)return e(Error("growl not supported on this platform"));
g=[d.pkg];if(f=c.image)switch(d.type){case "Darwin-Growl":var l,m=k.extname(f).substr(1);l=(l=(l=(l=l||"icns"==m&&"iconpath"||/^[A-Z]/.test(f)&&"appIcon")||/^png|gif|jpe?g$/.test(m)&&"image")||m&&(f=m)&&"icon")||"icon";g.push("--"+l,h(f));break;case "Linux":g.push(d.icon,h(f));c.sticky||g.push("--hint=int:transient:1");break;case "Windows":g.push(d.icon+h(f))}c.sticky&&g.push(d.sticky);c.priority&&(f=c.priority+"",d.priority.range.indexOf(f),~d.priority.range.indexOf(f)&&g.push(d.priority,c.priority));
c.name&&"Darwin-Growl"===d.type&&g.push("--name",c.name);switch(d.type){case "Darwin-Growl":g.push(d.msg);g.push(h(a));c.title&&g.push(h(c.title));break;case "Darwin-NotificationCenter":g.push(d.msg);g.push(h(a));c.title&&(g.push(d.title),g.push(h(c.title)));c.subtitle&&(g.push(d.subtitle),g.push(h(c.subtitle)));break;case "Darwin-Growl":g.push(d.msg);g.push(h(a));c.title&&g.push(h(c.title));break;case "Linux":c.title&&(g.push(h(c.title)),g.push(d.msg));g.push(h(a));break;case "Windows":g.push(h(a)),
c.title&&g.push(d.title+h(c.title))}b(g.join(" "),e)};g.version="1.4.1"}).call(this,f("_process"))},{_process:51,child_process:41,fs:41,os:50,path:41}],70:[function(f,m,g){(function(c){function g(f,a,h,d){"function"===typeof a?(h=a,a={}):a&&"object"===typeof a||(a={mode:a});var m=a.mode,r=a.fs||e;void 0===m&&(m=511&~c.umask());d||(d=null);var q=h||function(){};f=b.resolve(f);r.mkdir(f,m,function(c){if(!c)return d=d||f,q(null,d);switch(c.code){case "ENOENT":g(b.dirname(f),a,function(b,c){b?q(b,c):
g(f,a,q,c)});break;default:r.stat(f,function(a,b){a||!b.isDirectory()?q(c,d):q(null,d)})}})}var b=f("path"),e=f("fs");m.exports=g.mkdirp=g.mkdirP=g;g.sync=function a(f,d,g){d&&"object"===typeof d||(d={mode:d});var l=d.mode,m=d.fs||e;void 0===l&&(l=511&~c.umask());g||(g=null);f=b.resolve(f);try{m.mkdirSync(f,l),g=g||f}catch(u){switch(u.code){case "ENOENT":g=a(b.dirname(f),d,g);a(f,d,g);break;default:var x;try{x=m.statSync(f)}catch(D){throw u;}if(!x.isDirectory())throw u;}}return g}}).call(this,f("_process"))},
{_process:51,fs:41,path:41}],71:[function(f,m,g){(function(c,g){function b(){for(var c=(new a).getTime();r.length&&100>(new a).getTime()-c;)r.shift()();q=r.length?h(b,0):null}c.stdout=f("browser-stdout")();var e=f("../"),k=new e({reporter:"html"}),a=g.Date,h=g.setTimeout,d=[],m=g.onerror;c.removeListener=function(a,b){if("uncaughtException"==a){g.onerror=m?m:function(){};var c=e.utils.indexOf(d,b);-1!=c&&d.splice(c,1)}};c.on=function(a,b){"uncaughtException"==a&&(g.onerror=function(a,c,d){b(Error(a+
" ("+c+":"+d+")"));return!k.allowUncaught},d.push(b))};k.suite.removeAllListeners("pre-require");var r=[],q;e.Runner.immediately=function(a){r.push(a);q||(q=h(b,0))};k.throwError=function(a){e.utils.forEach(d,function(b){b(a)});throw a;};k.ui=function(a){e.prototype.ui.call(this,a);this.suite.emit("pre-require",g,null,this);return this};k.setup=function(a){"string"==typeof a&&(a={ui:a});for(var b in a)this[b](a[b]);return this};k.run=function(a){var b=k.options;k.globals("location");var c=e.utils.parseQuery(g.location.search||
"");c.grep&&k.grep(new RegExp(c.grep));c.fgrep&&k.grep(c.fgrep);c.invert&&k.invert();return e.prototype.run.call(k,function(c){var d=g.document;d&&d.getElementById("mocha")&&!0!==b.noHighlighting&&e.utils.highlightTags("code");a&&a(c)})};e.process=c;g.Mocha=e;g.mocha=k}).call(this,f("_process"),"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{"../":1,_process:51,"browser-stdout":40}]},{},[71]);(function(){function f(m){var g=f.modules[m];if(!g)throw Error('failed to require "'+m+'"');"exports"in g||"function"!==typeof g.definition||(g.client=g.component=!0,g.definition.call(this,g.exports={},g),delete g.definition);return g.exports}f.loader="component";f.helper={};f.helper.semVerSort=function(f,g){for(var c=f.version.split("."),l=g.version.split("."),b=0;b<c.length;++b){var e=parseInt(c[b],10),k=parseInt(l[b],10);if(e===k){e=c[b].substr((""+e).length);k=l[b].substr((""+k).length);if(""===
e&&""!==k)return 1;if(""!==e&&""===k)return-1;if(""!==e&&""!==k)return e>k?1:-1}else return e>k?1:-1}return 0};f.latest=function(m,g){function c(a){throw Error('failed to find latest module of "'+a+'"');}var l=/(.*)~(.*)@v?(\d+\.\d+\.\d+[^\/]*)$/;/(.*)~(.*)/.test(m)||c(m);for(var b=Object.keys(f.modules),e=[],k=[],a=0;a<b.length;a++){var h=b[a];if((new RegExp(m+"@")).test(h)){var d=h.substr(m.length+1);null!=l.exec(h)?e.push({version:d,name:h}):k.push({version:d,name:h})}}0===e.concat(k).length&&
c(m);if(0<e.length)return l=e.sort(f.helper.semVerSort).pop().name,!0===g?l:f(l);l=k.sort(function(a,b){return a.name>b.name})[0].name;return!0===g?l:f(l)};f.modules={};f.register=function(m,g){f.modules[m]={definition:g}};f.define=function(m,g){f.modules[m]={exports:g}};f.register("chaijs~assertion-error@1.0.0",function(f,g){function c(){function b(b,a){Object.keys(a).forEach(function(f){~c.indexOf(f)||(b[f]=a[f])})}var c=[].slice.call(arguments);return function(){for(var c=[].slice.call(arguments),
a=0,e={};a<c.length;a++)b(e,c[a]);return e}}function l(b,e,f){var a=c("name","message","stack","constructor","toJSON")(e||{});this.message=b||"Unspecified AssertionError";this.showDiff=!1;for(var h in a)this[h]=a[h];(f=f||arguments.callee)&&Error.captureStackTrace&&Error.captureStackTrace(this,f)}g.exports=l;l.prototype=Object.create(Error.prototype);l.prototype.name="AssertionError";l.prototype.constructor=l;l.prototype.toJSON=function(b){var e=c("constructor","toJSON","stack")({name:this.name},
this);!1!==b&&this.stack&&(e.stack=this.stack);return e}});f.register("chaijs~type-detect@0.1.1",function(f,g){function c(c){var f=Object.prototype.toString.call(c);return b[f]?b[f]:null===c?"null":void 0===c?"undefined":c===Object(c)?"object":typeof c}function l(){this.tests={}}f=g.exports=c;var b={"[object Array]":"array","[object RegExp]":"regexp","[object Function]":"function","[object Arguments]":"arguments","[object Date]":"date"};f.Library=l;l.prototype.of=c;l.prototype.define=function(b,c){if(1===
arguments.length)return this.tests[b];this.tests[b]=c;return this};l.prototype.test=function(b,f){if(f===c(b))return!0;var a=this.tests[f];if(a&&"regexp"===c(a))return a.test(b);if(a&&"function"===c(a))return a(b);throw new ReferenceError('Type test "'+f+'" not defined or invalid.');}});f.register("chaijs~deep-eql@0.1.3",function(m,g){function c(b,f,g){return l(b,f)?!0:"date"===a(b)?(g="date"!==a(f)?!1:l(b.getTime(),f.getTime()),g):"regexp"===a(b)?(g="regexp"!==a(f)?!1:l(b.toString(),f.toString()),
g):h.isBuffer(b)?(g=h.isBuffer(f)?e(b,f):!1,g):"arguments"===a(b)?("arguments"!==a(f)?g=!1:(b=[].slice.call(b),f=[].slice.call(f),g=c(b,f,g)),g):a(b)!==a(f)?!1:"object"!==a(b)&&"object"!==a(f)&&"array"!==a(b)&&"array"!==a(f)?l(b,f):k(b,f,g)}function l(a,b){return a===b?0!==a||1/a===1/b:a!==a&&b!==b}function b(a){var b=[],c;for(c in a)b.push(c);return b}function e(a,b){if(a.length!==b.length)return!1;for(var c=0,e=!0;c<a.length;c++)if(a[c]!==b[c]){e=!1;break}return e}function k(a,f,h){if(null===a||
void 0===a||null===f||void 0===f||a.prototype!==f.prototype)return!1;var g;if(h)for(g=0;g<h.length;g++){if(h[g][0]===a&&h[g][1]===f||h[g][0]===f&&h[g][1]===a)return!0}else h=[];try{var k=b(a),l=b(f)}catch(m){return!1}k.sort();l.sort();if(!e(k,l))return!1;h.push([a,f]);for(g=k.length-1;0<=g;g--)if(l=k[g],!c(a[l],f[l],h))return!1;return!0}var a=f("chaijs~type-detect@0.1.1"),h;try{h=f("buffer").Buffer}catch(d){h={isBuffer:function(){return!1}}}g.exports=c});f.register("chai",function(m,g){g.exports=
f("chai/lib/chai.js")});f.register("chai/lib/chai.js",function(m,g){var c=[];m=g.exports={};m.version="2.1.0";m.AssertionError=f("chaijs~assertion-error@1.0.0");var l=f("chai/lib/chai/utils/index.js");m.use=function(b){~c.indexOf(b)||(b(this,l),c.push(b));return this};m.util=l;var b=f("chai/lib/chai/config.js");m.config=b;b=f("chai/lib/chai/assertion.js");m.use(b);b=f("chai/lib/chai/core/assertions.js");m.use(b);b=f("chai/lib/chai/interface/expect.js");m.use(b);b=f("chai/lib/chai/interface/should.js");
m.use(b);b=f("chai/lib/chai/interface/assert.js");m.use(b)});f.register("chai/lib/chai/assertion.js",function(m,g){var c=f("chai/lib/chai/config.js");g.exports=function(f,b){function e(b,c,e){a(this,"ssfi",e||arguments.callee);a(this,"object",b);a(this,"message",c)}var g=f.AssertionError,a=b.flag;f.Assertion=e;Object.defineProperty(e,"includeStack",{get:function(){console.warn("Assertion.includeStack is deprecated, use chai.config.includeStack instead.");return c.includeStack},set:function(a){console.warn("Assertion.includeStack is deprecated, use chai.config.includeStack instead.");
c.includeStack=a}});Object.defineProperty(e,"showDiff",{get:function(){console.warn("Assertion.showDiff is deprecated, use chai.config.showDiff instead.");return c.showDiff},set:function(a){console.warn("Assertion.showDiff is deprecated, use chai.config.showDiff instead.");c.showDiff=a}});e.addProperty=function(a,c){b.addProperty(this.prototype,a,c)};e.addMethod=function(a,c){b.addMethod(this.prototype,a,c)};e.addChainableMethod=function(a,c,e){b.addChainableMethod(this.prototype,a,c,e)};e.overwriteProperty=
function(a,c){b.overwriteProperty(this.prototype,a,c)};e.overwriteMethod=function(a,c){b.overwriteMethod(this.prototype,a,c)};e.overwriteChainableMethod=function(a,c,e){b.overwriteChainableMethod(this.prototype,a,c,e)};e.prototype.assert=function(e,d,f,l,m,x){var u=b.test(this,arguments);!0!==x&&(x=!1);!0!==c.showDiff&&(x=!1);if(!u)throw d=b.getMessage(this,arguments),u=b.getActual(this,arguments),new g(d,{actual:u,expected:l,showDiff:x},c.includeStack?this.assert:a(this,"ssfi"));};Object.defineProperty(e.prototype,
"_obj",{get:function(){return a(this,"object")},set:function(b){a(this,"object",b)}})}});f.register("chai/lib/chai/config.js",function(f,g){g.exports={includeStack:!1,showDiff:!0,truncateThreshold:40}});f.register("chai/lib/chai/core/assertions.js",function(f,g){g.exports=function(c,f){function b(a,b){b&&p(this,"message",b);a=a.toLowerCase();var c=p(this,"object"),d=~["a","e","i","o","u"].indexOf(a.charAt(0))?"an ":"a ";this.assert(a===f.type(c),"expected #{this} to be "+d+a,"expected #{this} not to be "+
d+a)}function e(){p(this,"contains",!0)}function g(a,b){b&&p(this,"message",b);var c=p(this,"object"),d=!1;if("array"===f.type(c)&&"object"===f.type(a))for(var e in c){if(f.eql(c[e],a)){d=!0;break}}else if("object"===f.type(a)){if(!p(this,"negate")){for(var h in a)(new n(c)).property(h,a[h]);return}d={};for(h in a)d[h]=c[h];d=f.eql(d,a)}else d=c&&~c.indexOf(a);this.assert(d,"expected #{this} to include "+f.inspect(a),"expected #{this} to not include "+f.inspect(a))}function a(){var a=p(this,"object"),
a=Object.prototype.toString.call(a);this.assert("[object Arguments]"===a,"expected #{this} to be arguments but got "+a,"expected #{this} to not be arguments")}function h(a,b){b&&p(this,"message",b);var c=p(this,"object");if(p(this,"deep"))return this.eql(a);this.assert(a===c,"expected #{this} to equal #{exp}","expected #{this} to not equal #{exp}",a,this._obj,!0)}function d(a,b){b&&p(this,"message",b);this.assert(f.eql(a,p(this,"object")),"expected #{this} to deeply equal #{exp}","expected #{this} to not deeply equal #{exp}",
a,this._obj,!0)}function m(a,b){b&&p(this,"message",b);var c=p(this,"object");p(this,"doLength")?((new n(c,b)).to.have.property("length"),c=c.length,this.assert(c>a,"expected #{this} to have a length above #{exp} but got #{act}","expected #{this} to not have a length above #{exp}",a,c)):this.assert(c>a,"expected #{this} to be above "+a,"expected #{this} to be at most "+a)}function r(a,b){b&&p(this,"message",b);var c=p(this,"object");p(this,"doLength")?((new n(c,b)).to.have.property("length"),c=c.length,
this.assert(c>=a,"expected #{this} to have a length at least #{exp} but got #{act}","expected #{this} to have a length below #{exp}",a,c)):this.assert(c>=a,"expected #{this} to be at least "+a,"expected #{this} to be below "+a)}function q(a,b){b&&p(this,"message",b);var c=p(this,"object");p(this,"doLength")?((new n(c,b)).to.have.property("length"),c=c.length,this.assert(c<a,"expected #{this} to have a length below #{exp} but got #{act}","expected #{this} to not have a length below #{exp}",a,c)):this.assert(c<
a,"expected #{this} to be below "+a,"expected #{this} to be at least "+a)}function x(a,b){b&&p(this,"message",b);var c=p(this,"object");p(this,"doLength")?((new n(c,b)).to.have.property("length"),c=c.length,this.assert(c<=a,"expected #{this} to have a length at most #{exp} but got #{act}","expected #{this} to have a length above #{exp}",a,c)):this.assert(c<=a,"expected #{this} to be at most "+a,"expected #{this} to be above "+a)}function u(a,b){b&&p(this,"message",b);var c=f.getName(a);this.assert(p(this,
"object")instanceof a,"expected #{this} to be an instance of "+c,"expected #{this} to not be an instance of "+c)}function D(a,b){b&&p(this,"message",b);var c=p(this,"object");this.assert(c.hasOwnProperty(a),"expected #{this} to have own property "+f.inspect(a),"expected #{this} to not have own property "+f.inspect(a))}function E(a,b){b&&p(this,"message",b);var c=p(this,"object");(new n(c,b)).to.have.property("length");c=c.length;this.assert(c==a,"expected #{this} to have a length of #{exp} but got #{act}",
"expected #{this} to not have a length of #{act}",a,c)}function w(a){var b=p(this,"object"),c,d=!0;switch(f.type(a)){case "array":if(1<arguments.length)throw Error("keys must be given single argument of Array|Object|String, or multiple String arguments");break;case "object":if(1<arguments.length)throw Error("keys must be given single argument of Array|Object|String, or multiple String arguments");a=Object.keys(a);break;default:a=Array.prototype.slice.call(arguments)}if(!a.length)throw Error("keys required");
var e=Object.keys(b),b=a,h=a.length,g=p(this,"any"),k=p(this,"all");g||k||(k=!0);g&&(d=0<b.filter(function(a){return~e.indexOf(a)}).length);k&&(d=a.every(function(a){return~e.indexOf(a)}),p(this,"negate")||p(this,"contains")||(d=d&&a.length==e.length));if(1<h){a=a.map(function(a){return f.inspect(a)});var m=a.pop();k&&(c=a.join(", ")+", and "+m);g&&(c=a.join(", ")+", or "+m)}else c=f.inspect(a[0]);c=(1<h?"keys ":"key ")+c;c=(p(this,"contains")?"contain ":"have ")+c;this.assert(d,"expected #{this} to "+
c,"expected #{this} to not "+c,b.slice(0).sort(),e.sort(),!0)}function A(a,b,c){c&&p(this,"message",c);var d=p(this,"object");(new n(d,c)).is.a("function");var e=!1,h=null,g=null,k=null;0===arguments.length?a=b=null:a&&(a instanceof RegExp||"string"===typeof a)?(b=a,a=null):a&&a instanceof Error?(h=a,b=a=null):"function"===typeof a?(g=a.prototype.name||a.name,"Error"===g&&a!==Error&&(g=(new a).name)):a=null;try{d()}catch(m){if(h)return this.assert(m===h,"expected #{this} to throw #{exp} but #{act} was thrown",
"expected #{this} to not throw #{exp}",h instanceof Error?h.toString():h,m instanceof Error?m.toString():m),p(this,"object",m),this;if(a&&(this.assert(m instanceof a,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp} but #{act} was thrown",g,m instanceof Error?m.toString():m),!b))return p(this,"object",m),this;e="object"===f.type(m)&&"message"in m?m.message:""+m;if(null!=e&&b&&b instanceof RegExp)return this.assert(b.exec(e),"expected #{this} to throw error matching #{exp} but got #{act}",
"expected #{this} to throw error not matching #{exp}",b,e),p(this,"object",m),this;if(null!=e&&b&&"string"===typeof b)return this.assert(~e.indexOf(b),"expected #{this} to throw error including #{exp} but got #{act}","expected #{this} to throw error not including #{act}",b,e),p(this,"object",m),this;e=!0;k=m}d="";g=null!==g?g:h?"#{exp}":"an error";e&&(d=" but #{act} was thrown");this.assert(!0===e,"expected #{this} to throw "+g+d,"expected #{this} to not throw "+g+d,h instanceof Error?h.toString():
h,k instanceof Error?k.toString():k);p(this,"object",k)}function F(a,b,c){return a.every(function(a){return c?b.some(function(b){return c(a,b)}):-1!==b.indexOf(a)})}function B(a,b,c){c&&p(this,"message",c);var d=p(this,"object");(new n(a,c)).to.have.property(b);(new n(d)).is.a("function");c=a[b];d();this.assert(c!==a[b],"expected ."+b+" to change","expected ."+b+" to not change")}function y(a,b,c){c&&p(this,"message",c);var d=p(this,"object");(new n(a,c)).to.have.property(b);(new n(d)).is.a("function");
c=a[b];d();this.assert(0<a[b]-c,"expected ."+b+" to increase","expected ."+b+" to not increase")}function z(a,b,c){c&&p(this,"message",c);var d=p(this,"object");(new n(a,c)).to.have.property(b);(new n(d)).is.a("function");c=a[b];d();this.assert(0>a[b]-c,"expected ."+b+" to decrease","expected ."+b+" to not decrease")}var n=c.Assertion,p=f.flag;"to be been is and has have with that which at of same".split(" ").forEach(function(a){n.addProperty(a,function(){return this})});n.addProperty("not",function(){p(this,
"negate",!0)});n.addProperty("deep",function(){p(this,"deep",!0)});n.addProperty("any",function(){p(this,"any",!0);p(this,"all",!1)});n.addProperty("all",function(){p(this,"all",!0);p(this,"any",!1)});n.addChainableMethod("an",b);n.addChainableMethod("a",b);n.addChainableMethod("include",g,e);n.addChainableMethod("contain",g,e);n.addChainableMethod("contains",g,e);n.addChainableMethod("includes",g,e);n.addProperty("ok",function(){this.assert(p(this,"object"),"expected #{this} to be truthy","expected #{this} to be falsy")});
n.addProperty("true",function(){this.assert(!0===p(this,"object"),"expected #{this} to be true","expected #{this} to be false",this.negate?!1:!0)});n.addProperty("false",function(){this.assert(!1===p(this,"object"),"expected #{this} to be false","expected #{this} to be true",this.negate?!0:!1)});n.addProperty("null",function(){this.assert(null===p(this,"object"),"expected #{this} to be null","expected #{this} not to be null")});n.addProperty("undefined",function(){this.assert(void 0===p(this,"object"),
"expected #{this} to be undefined","expected #{this} not to be undefined")});n.addProperty("exist",function(){this.assert(null!=p(this,"object"),"expected #{this} to exist","expected #{this} to not exist")});n.addProperty("empty",function(){var a=p(this,"object"),b=a;Array.isArray(a)||"string"===typeof object?b=a.length:"object"===typeof a&&(b=Object.keys(a).length);this.assert(!b,"expected #{this} to be empty","expected #{this} not to be empty")});n.addProperty("arguments",a);n.addProperty("Arguments",
a);n.addMethod("equal",h);n.addMethod("equals",h);n.addMethod("eq",h);n.addMethod("eql",d);n.addMethod("eqls",d);n.addMethod("above",m);n.addMethod("gt",m);n.addMethod("greaterThan",m);n.addMethod("least",r);n.addMethod("gte",r);n.addMethod("below",q);n.addMethod("lt",q);n.addMethod("lessThan",q);n.addMethod("most",x);n.addMethod("lte",x);n.addMethod("within",function(a,b,c){c&&p(this,"message",c);var d=p(this,"object"),e=a+".."+b;p(this,"doLength")?((new n(d,c)).to.have.property("length"),c=d.length,
this.assert(c>=a&&c<=b,"expected #{this} to have a length within "+e,"expected #{this} to not have a length within "+e)):this.assert(d>=a&&d<=b,"expected #{this} to be within "+e,"expected #{this} to not be within "+e)});n.addMethod("instanceof",u);n.addMethod("instanceOf",u);n.addMethod("property",function(a,b,c){c&&p(this,"message",c);var d=!!p(this,"deep"),e=d?"deep property ":"property ",h=p(this,"negate"),g=p(this,"object"),k=d?f.getPathInfo(a,g):null,m=d?k.exists:f.hasProperty(a,g),d=d?k.value:
g[a];if(h&&void 0!==b){if(void 0===d)throw Error((null!=c?c+": ":"")+f.inspect(g)+" has no "+e+f.inspect(a));}else this.assert(m,"expected #{this} to have a "+e+f.inspect(a),"expected #{this} to not have "+e+f.inspect(a));void 0!==b&&this.assert(b===d,"expected #{this} to have a "+e+f.inspect(a)+" of #{exp}, but got #{act}","expected #{this} to not have a "+e+f.inspect(a)+" of #{act}",b,d);p(this,"object",d)});n.addMethod("ownProperty",D);n.addMethod("haveOwnProperty",D);n.addChainableMethod("length",
E,function(){p(this,"doLength",!0)});n.addMethod("lengthOf",E);n.addMethod("match",function(a,b){b&&p(this,"message",b);var c=p(this,"object");this.assert(a.exec(c),"expected #{this} to match "+a,"expected #{this} not to match "+a)});n.addMethod("string",function(a,b){b&&p(this,"message",b);var c=p(this,"object");(new n(c,b)).is.a("string");this.assert(~c.indexOf(a),"expected #{this} to contain "+f.inspect(a),"expected #{this} to not contain "+f.inspect(a))});n.addMethod("keys",w);n.addMethod("key",
w);n.addMethod("throw",A);n.addMethod("throws",A);n.addMethod("Throw",A);n.addMethod("respondTo",function(a,b){b&&p(this,"message",b);var c=p(this,"object"),d=p(this,"itself"),c="function"!==f.type(c)||d?c[a]:c.prototype[a];this.assert("function"===typeof c,"expected #{this} to respond to "+f.inspect(a),"expected #{this} to not respond to "+f.inspect(a))});n.addProperty("itself",function(){p(this,"itself",!0)});n.addMethod("satisfy",function(a,b){b&&p(this,"message",b);var c=p(this,"object"),c=a(c);
this.assert(c,"expected #{this} to satisfy "+f.objDisplay(a),"expected #{this} to not satisfy"+f.objDisplay(a),this.negate?!1:!0,c)});n.addMethod("closeTo",function(a,b,c){c&&p(this,"message",c);var d=p(this,"object");(new n(d,c)).is.a("number");if("number"!==f.type(a)||"number"!==f.type(b))throw Error("the arguments to closeTo must be numbers");this.assert(Math.abs(d-a)<=b,"expected #{this} to be close to "+a+" +/- "+b,"expected #{this} not to be close to "+a+" +/- "+b)});n.addMethod("members",function(a,
b){b&&p(this,"message",b);var c=p(this,"object");(new n(c)).to.be.an("array");(new n(a)).to.be.an("array");var d=p(this,"deep")?f.eql:void 0;if(p(this,"contains"))return this.assert(F(a,c,d),"expected #{this} to be a superset of #{act}","expected #{this} to not be a superset of #{act}",c,a);this.assert(F(c,a,d)&&F(a,c,d),"expected #{this} to have the same members as #{act}","expected #{this} to not have the same members as #{act}",c,a)});n.addChainableMethod("change",B);n.addChainableMethod("changes",
B);n.addChainableMethod("increase",y);n.addChainableMethod("increases",y);n.addChainableMethod("decrease",z);n.addChainableMethod("decreases",z)}});f.register("chai/lib/chai/interface/assert.js",function(f,g){g.exports=function(c,f){var b=c.Assertion,e=f.flag,g=c.assert=function(a,e){(new b(null,null,c.assert)).assert(a,e,"[ negation message unavailable ]")};g.fail=function(a,b,d,e){throw new c.AssertionError(d||"assert.fail()",{actual:a,expected:b,operator:e},g.fail);};g.ok=function(a,c){(new b(a,
c)).is.ok};g.notOk=function(a,c){(new b(a,c)).is.not.ok};g.equal=function(a,c,d){d=new b(a,d,g.equal);d.assert(c==e(d,"object"),"expected #{this} to equal #{exp}","expected #{this} to not equal #{act}",c,a)};g.notEqual=function(a,c,d){d=new b(a,d,g.notEqual);d.assert(c!=e(d,"object"),"expected #{this} to not equal #{exp}","expected #{this} to equal #{act}",c,a)};g.strictEqual=function(a,c,d){(new b(a,d)).to.equal(c)};g.notStrictEqual=function(a,c,d){(new b(a,d)).to.not.equal(c)};g.deepEqual=function(a,
c,d){(new b(a,d)).to.eql(c)};g.notDeepEqual=function(a,c,d){(new b(a,d)).to.not.eql(c)};g.isAbove=function(a,c,d){(new b(a,d)).to.be.above(c)};g.isBelow=function(a,c,d){(new b(a,d)).to.be.below(c)};g.isTrue=function(a,c){(new b(a,c)).is["true"]};g.isFalse=function(a,c){(new b(a,c)).is["false"]};g.isNull=function(a,c){(new b(a,c)).to.equal(null)};g.isNotNull=function(a,c){(new b(a,c)).to.not.equal(null)};g.isUndefined=function(a,c){(new b(a,c)).to.equal(void 0)};g.isDefined=function(a,c){(new b(a,
c)).to.not.equal(void 0)};g.isFunction=function(a,c){(new b(a,c)).to.be.a("function")};g.isNotFunction=function(a,c){(new b(a,c)).to.not.be.a("function")};g.isObject=function(a,c){(new b(a,c)).to.be.a("object")};g.isNotObject=function(a,c){(new b(a,c)).to.not.be.a("object")};g.isArray=function(a,c){(new b(a,c)).to.be.an("array")};g.isNotArray=function(a,c){(new b(a,c)).to.not.be.an("array")};g.isString=function(a,c){(new b(a,c)).to.be.a("string")};g.isNotString=function(a,c){(new b(a,c)).to.not.be.a("string")};
g.isNumber=function(a,c){(new b(a,c)).to.be.a("number")};g.isNotNumber=function(a,c){(new b(a,c)).to.not.be.a("number")};g.isBoolean=function(a,c){(new b(a,c)).to.be.a("boolean")};g.isNotBoolean=function(a,c){(new b(a,c)).to.not.be.a("boolean")};g.typeOf=function(a,c,d){(new b(a,d)).to.be.a(c)};g.notTypeOf=function(a,c,d){(new b(a,d)).to.not.be.a(c)};g.instanceOf=function(a,c,d){(new b(a,d)).to.be.instanceOf(c)};g.notInstanceOf=function(a,c,d){(new b(a,d)).to.not.be.instanceOf(c)};g.include=function(a,
c,d){(new b(a,d,g.include)).include(c)};g.notInclude=function(a,c,d){(new b(a,d,g.notInclude)).not.include(c)};g.match=function(a,c,d){(new b(a,d)).to.match(c)};g.notMatch=function(a,c,d){(new b(a,d)).to.not.match(c)};g.property=function(a,c,d){(new b(a,d)).to.have.property(c)};g.notProperty=function(a,c,d){(new b(a,d)).to.not.have.property(c)};g.deepProperty=function(a,c,d){(new b(a,d)).to.have.deep.property(c)};g.notDeepProperty=function(a,c,d){(new b(a,d)).to.not.have.deep.property(c)};g.propertyVal=
function(a,c,d,e){(new b(a,e)).to.have.property(c,d)};g.propertyNotVal=function(a,c,d,e){(new b(a,e)).to.not.have.property(c,d)};g.deepPropertyVal=function(a,c,d,e){(new b(a,e)).to.have.deep.property(c,d)};g.deepPropertyNotVal=function(a,c,d,e){(new b(a,e)).to.not.have.deep.property(c,d)};g.lengthOf=function(a,c,d){(new b(a,d)).to.have.length(c)};g.Throw=function(a,c,d,f){if("string"===typeof c||c instanceof RegExp)d=c,c=null;a=(new b(a,f)).to.Throw(c,d);return e(a,"object")};g.doesNotThrow=function(a,
c,d){"string"===typeof c&&(d=c,c=null);(new b(a,d)).to.not.Throw(c)};g.operator=function(a,c,d,g){if(!~"== === > >= < <= != !==".split(" ").indexOf(c))throw Error('Invalid operator "'+c+'"');g=new b(eval(a+c+d),g);g.assert(!0===e(g,"object"),"expected "+f.inspect(a)+" to be "+c+" "+f.inspect(d),"expected "+f.inspect(a)+" to not be "+c+" "+f.inspect(d))};g.closeTo=function(a,c,d,e){(new b(a,e)).to.be.closeTo(c,d)};g.sameMembers=function(a,c,d){(new b(a,d)).to.have.same.members(c)};g.sameDeepMembers=
function(a,c,d){(new b(a,d)).to.have.same.deep.members(c)};g.includeMembers=function(a,c,d){(new b(a,d)).to.include.members(c)};g.changes=function(a,c,d){(new b(a)).to.change(c,d)};g.doesNotChange=function(a,c,d){(new b(a)).to.not.change(c,d)};g.increases=function(a,c,d){(new b(a)).to.increase(c,d)};g.doesNotIncrease=function(a,c,d){(new b(a)).to.not.increase(c,d)};g.decreases=function(a,c,d){(new b(a)).to.decrease(c,d)};g.doesNotDecrease=function(a,c,d){(new b(a)).to.not.decrease(c,d)};g.ifError=
function(a,c){(new b(a,c)).to.not.be.ok};(function h(b,c){g[c]=g[b];return h})("Throw","throw")("Throw","throws")}});f.register("chai/lib/chai/interface/expect.js",function(f,g){g.exports=function(c,f){c.expect=function(b,e){return new c.Assertion(b,e)};c.expect.fail=function(b,e,f,a){throw new c.AssertionError(f||"expect.fail()",{actual:b,expected:e,operator:a},c.expect.fail);}}});f.register("chai/lib/chai/interface/should.js",function(f,g){g.exports=function(c,f){function b(){function b(){return this instanceof
String||this instanceof Number?new e(this.constructor(this),null,b):this instanceof Boolean?new e(1==this,null,b):new e(this,null,b)}Object.defineProperty(Object.prototype,"should",{set:function(a){Object.defineProperty(this,"should",{value:a,enumerable:!0,configurable:!0,writable:!0})},get:b,configurable:!0});var a={fail:function(b,d,e,f){throw new c.AssertionError(e||"should.fail()",{actual:b,expected:d,operator:f},a.fail);},equal:function(a,b,c){(new e(a,c)).to.equal(b)},Throw:function(a,b,c,f){(new e(a,
f)).to.Throw(b,c)},exist:function(a,b){(new e(a,b)).to.exist},not:{}};a.not.equal=function(a,b,c){(new e(a,c)).to.not.equal(b)};a.not.Throw=function(a,b,c,f){(new e(a,f)).to.not.Throw(b,c)};a.not.exist=function(a,b){(new e(a,b)).to.not.exist};a["throw"]=a.Throw;a.not["throw"]=a.not.Throw;return a}var e=c.Assertion;c.should=b;c.Should=b}});f.register("chai/lib/chai/utils/addChainableMethod.js",function(m,g){var c=f("chai/lib/chai/utils/transferFlags.js"),l=f("chai/lib/chai/utils/flag.js"),b=f("chai/lib/chai/config.js"),
e="__proto__"in Object,k=/^(?:length|name|arguments|caller)$/,a=Function.prototype.call,h=Function.prototype.apply;g.exports=function(d,f,g,m){"function"!==typeof m&&(m=function(){});var x={method:g,chainingBehavior:m};d.__methods||(d.__methods={});d.__methods[f]=x;Object.defineProperty(d,f,{get:function(){x.chainingBehavior.call(this);var f=function w(){l(this,"ssfi")&&!1===b.includeStack&&l(this,"ssfi",w);var a=x.method.apply(this,arguments);return void 0===a?this:a};if(e){var g=f.__proto__=Object.create(this);
g.call=a;g.apply=h}else Object.getOwnPropertyNames(d).forEach(function(a){if(!k.test(a)){var b=Object.getOwnPropertyDescriptor(d,a);Object.defineProperty(f,a,b)}});c(this,f);return f},configurable:!0})}});f.register("chai/lib/chai/utils/addMethod.js",function(m,g){var c=f("chai/lib/chai/config.js"),l=f("chai/lib/chai/utils/flag.js");g.exports=function(b,e,f){b[e]=function(){l(this,"ssfi")&&!1===c.includeStack&&l(this,"ssfi",b[e]);var a=f.apply(this,arguments);return void 0===a?this:a}}});f.register("chai/lib/chai/utils/addProperty.js",
function(f,g){g.exports=function(c,f,b){Object.defineProperty(c,f,{get:function(){var c=b.call(this);return void 0===c?this:c},configurable:!0})}});f.register("chai/lib/chai/utils/flag.js",function(f,g){g.exports=function(c,f,b){var e=c.__flags||(c.__flags=Object.create(null));if(3===arguments.length)e[f]=b;else return e[f]}});f.register("chai/lib/chai/utils/getActual.js",function(f,g){g.exports=function(c,f){return 4<f.length?f[4]:c._obj}});f.register("chai/lib/chai/utils/getEnumerableProperties.js",
function(f,g){g.exports=function(c){var f=[],b;for(b in c)f.push(b);return f}});f.register("chai/lib/chai/utils/getMessage.js",function(m,g){var c=f("chai/lib/chai/utils/flag.js"),l=f("chai/lib/chai/utils/getActual.js");f("chai/lib/chai/utils/inspect.js");var b=f("chai/lib/chai/utils/objDisplay.js");g.exports=function(e,f){var a=c(e,"negate"),g=c(e,"object"),d=f[3],m=l(e,f),a=a?f[2]:f[1],r=c(e,"message");"function"===typeof a&&(a=a());a=(a||"").replace(/#{this}/g,b(g)).replace(/#{act}/g,b(m)).replace(/#{exp}/g,
b(d));return r?r+": "+a:a}});f.register("chai/lib/chai/utils/getName.js",function(f,g){g.exports=function(c){return c.name?c.name:(c=/^\s?function ([^(]*)\(/.exec(c))&&c[1]?c[1]:""}});f.register("chai/lib/chai/utils/getPathValue.js",function(m,g){var c=f("chai/lib/chai/utils/getPathInfo.js");g.exports=function(f,b){return c(f,b).value}});f.register("chai/lib/chai/utils/getPathInfo.js",function(m,g){function c(b){return b.replace(/\[/g,".[").match(/(\\\.|[^.]+?)+/g).map(function(b){var a=/\[(\d+)\]$/.exec(b);
return a?{i:parseFloat(a[1])}:{p:b}})}function l(b,c,a){var f;a=void 0===a?b.length:a;for(var d=0;d<a;d++){var g=b[d];c?("undefined"!==typeof g.p?c=c[g.p]:"undefined"!==typeof g.i&&(c=c[g.i]),d==a-1&&(f=c)):f=void 0}return f}var b=f("chai/lib/chai/utils/hasProperty.js");g.exports=function(e,f){var a=c(e),g=a[a.length-1],a={parent:l(a,f,a.length-1),name:g.p||g.i,value:l(a,f)};a.exists=b(a.name,a.parent);return a}});f.register("chai/lib/chai/utils/hasProperty.js",function(m,g){var c=f("chai/lib/chai/utils/type.js"),
l={number:Number,string:String};g.exports=function(b,e){var f=c(e);if("null"===f||"undefined"===f)return!1;l[f]&&"object"!==typeof e&&(e=new l[f](e));return b in e}});f.register("chai/lib/chai/utils/getProperties.js",function(f,g){g.exports=function(c){function f(c){-1===b.indexOf(c)&&b.push(c)}var b=Object.getOwnPropertyNames(subject);for(c=Object.getPrototypeOf(subject);null!==c;)Object.getOwnPropertyNames(c).forEach(f),c=Object.getPrototypeOf(c);return b}});f.register("chai/lib/chai/utils/index.js",
function(m,g){m=g.exports={};m.test=f("chai/lib/chai/utils/test.js");m.type=f("chai/lib/chai/utils/type.js");m.getMessage=f("chai/lib/chai/utils/getMessage.js");m.getActual=f("chai/lib/chai/utils/getActual.js");m.inspect=f("chai/lib/chai/utils/inspect.js");m.objDisplay=f("chai/lib/chai/utils/objDisplay.js");m.flag=f("chai/lib/chai/utils/flag.js");m.transferFlags=f("chai/lib/chai/utils/transferFlags.js");m.eql=f("chaijs~deep-eql@0.1.3");m.getPathValue=f("chai/lib/chai/utils/getPathValue.js");m.getPathInfo=
f("chai/lib/chai/utils/getPathInfo.js");m.hasProperty=f("chai/lib/chai/utils/hasProperty.js");m.getName=f("chai/lib/chai/utils/getName.js");m.addProperty=f("chai/lib/chai/utils/addProperty.js");m.addMethod=f("chai/lib/chai/utils/addMethod.js");m.overwriteProperty=f("chai/lib/chai/utils/overwriteProperty.js");m.overwriteMethod=f("chai/lib/chai/utils/overwriteMethod.js");m.addChainableMethod=f("chai/lib/chai/utils/addChainableMethod.js");m.overwriteChainableMethod=f("chai/lib/chai/utils/overwriteChainableMethod.js")});
f.register("chai/lib/chai/utils/inspect.js",function(m,g){function c(f,g,E){if(g&&"function"===typeof g.inspect&&g.inspect!==m.inspect&&(!g.constructor||g.constructor.prototype!==g)){var w=g.inspect(E);"string"!==typeof w&&(w=c(f,w,E));return w}var A=l(f,g);if(A)return A;A="object"===typeof HTMLElement?g instanceof HTMLElement:g&&"object"===typeof g&&1===g.nodeType&&"string"===typeof g.nodeName;if(A){if("outerHTML"in g)return g.outerHTML;try{if(document.xmlVersion)return(new XMLSerializer).serializeToString(g);
w=document.createElementNS("http://www.w3.org/1999/xhtml","_");w.appendChild(g.cloneNode(!1));html=w.innerHTML.replace("><",">"+g.innerHTML+"<");w.innerHTML="";return html}catch(z){}}var F=x(g),A=f.showHidden?q(g):F;if(0===A.length||t(g)&&(1===A.length&&"stack"===A[0]||2===A.length&&"description"===A[0]&&"stack"===A[1])){if("function"===typeof g){var B=r(g);return f.stylize("[Function"+(B?": "+B:"")+"]","special")}if(h(g))return f.stylize(RegExp.prototype.toString.call(g),"regexp");if(d(g))return f.stylize(Date.prototype.toUTCString.call(g),
"date");if(t(g))return"["+Error.prototype.toString.call(g)+"]"}var B="",y=!1,w=["{","}"];a(g)&&(y=!0,w=["[","]"]);"function"===typeof g&&(B=r(g),B=" [Function"+(B?": "+B:"")+"]");h(g)&&(B=" "+RegExp.prototype.toString.call(g));d(g)&&(B=" "+Date.prototype.toUTCString.call(g));if(t(g))return"["+Error.prototype.toString.call(g)+"]";if(0===A.length&&(!y||0==g.length))return w[0]+B+w[1];if(0>E)return h(g)?f.stylize(RegExp.prototype.toString.call(g),"regexp"):f.stylize("[Object]","special");f.seen.push(g);
A=y?b(f,g,E,F,A):A.map(function(a){return e(f,g,E,F,a,y)});f.seen.pop();return k(A,B,w)}function l(a,b){switch(typeof b){case "undefined":return a.stylize("undefined","undefined");case "string":var c="'"+JSON.stringify(b).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return a.stylize(c,"string");case "number":return 0===b&&-Infinity===1/b?a.stylize("-0","number"):a.stylize(""+b,"number");case "boolean":return a.stylize(""+b,"boolean")}if(null===b)return a.stylize("null","null")}
function b(a,b,c,d,f){for(var g=[],h=0,k=b.length;h<k;++h)Object.prototype.hasOwnProperty.call(b,String(h))?g.push(e(a,b,c,d,String(h),!0)):g.push("");f.forEach(function(f){f.match(/^\d+$/)||g.push(e(a,b,c,d,f,!0))});return g}function e(a,b,d,e,f,g){var h,k;b.__lookupGetter__&&(b.__lookupGetter__(f)?k=b.__lookupSetter__(f)?a.stylize("[Getter/Setter]","special"):a.stylize("[Getter]","special"):b.__lookupSetter__(f)&&(k=a.stylize("[Setter]","special")));0>e.indexOf(f)&&(h="["+f+"]");k||(0>a.seen.indexOf(b[f])?
(k=null===d?c(a,b[f],null):c(a,b[f],d-1),-1<k.indexOf("\n")&&(k=g?k.split("\n").map(function(a){return" "+a}).join("\n").substr(2):"\n"+k.split("\n").map(function(a){return" "+a}).join("\n"))):k=a.stylize("[Circular]","special"));if("undefined"===typeof h){if(g&&f.match(/^\d+$/))return k;h=JSON.stringify(""+f);h.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(h=h.substr(1,h.length-2),h=a.stylize(h,"name")):(h=h.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),h=a.stylize(h,"string"))}return h+
": "+k}function k(a,b,c){var d=0;return 60<a.reduce(function(a,b){d++;0<=b.indexOf("\n")&&d++;return a+b.length+1},0)?c[0]+(""===b?"":b+"\n ")+" "+a.join(",\n ")+" "+c[1]:c[0]+b+" "+a.join(", ")+" "+c[1]}function a(a){return Array.isArray(a)||"object"===typeof a&&"[object Array]"===Object.prototype.toString.call(a)}function h(a){return"object"===typeof a&&"[object RegExp]"===Object.prototype.toString.call(a)}function d(a){return"object"===typeof a&&"[object Date]"===Object.prototype.toString.call(a)}
function t(a){return"object"===typeof a&&"[object Error]"===Object.prototype.toString.call(a)}var r=f("chai/lib/chai/utils/getName.js"),q=f("chai/lib/chai/utils/getProperties.js"),x=f("chai/lib/chai/utils/getEnumerableProperties.js");g.exports=function(a,b,d,e){return c({showHidden:b,seen:[],stylize:function(a){return a}},a,"undefined"===typeof d?2:d)}});f.register("chai/lib/chai/utils/objDisplay.js",function(m,g){var c=f("chai/lib/chai/utils/inspect.js"),l=f("chai/lib/chai/config.js");g.exports=
function(b){var e=c(b),f=Object.prototype.toString.call(b);if(l.truncateThreshold&&e.length>=l.truncateThreshold){if("[object Function]"===f)return b.name&&""!==b.name?"[Function: "+b.name+"]":"[Function]";if("[object Array]"===f)return"[ Array("+b.length+") ]";if("[object Object]"===f)return b=Object.keys(b),"{ Object ("+(2<b.length?b.splice(0,2).join(", ")+", ...":b.join(", "))+") }"}return e}});f.register("chai/lib/chai/utils/overwriteMethod.js",function(f,g){g.exports=function(c,f,b){var e=c[f],
g=function(){return this};e&&"function"===typeof e&&(g=e);c[f]=function(){var a=b(g).apply(this,arguments);return void 0===a?this:a}}});f.register("chai/lib/chai/utils/overwriteProperty.js",function(f,g){g.exports=function(c,f,b){var e=Object.getOwnPropertyDescriptor(c,f),g=function(){};e&&"function"===typeof e.get&&(g=e.get);Object.defineProperty(c,f,{get:function(){var a=b(g).call(this);return void 0===a?this:a},configurable:!0})}});f.register("chai/lib/chai/utils/overwriteChainableMethod.js",function(f,
g){g.exports=function(c,f,b,e){c=c.__methods[f];var g=c.chainingBehavior;c.chainingBehavior=function(){var a=e(g).call(this);return void 0===a?this:a};var a=c.method;c.method=function(){var c=b(a).apply(this,arguments);return void 0===c?this:c}}});f.register("chai/lib/chai/utils/test.js",function(m,g){var c=f("chai/lib/chai/utils/flag.js");g.exports=function(f,b){var e=c(f,"negate"),g=b[0];return e?!g:g}});f.register("chai/lib/chai/utils/transferFlags.js",function(f,g){g.exports=function(c,f,b){var e=
c.__flags||(c.__flags=Object.create(null));f.__flags||(f.__flags=Object.create(null));b=3===arguments.length?b:!0;for(var g in e)if(b||"object"!==g&&"ssfi"!==g&&"message"!=g)f.__flags[g]=e[g]}});f.register("chai/lib/chai/utils/type.js",function(f,g){var c={"[object Arguments]":"arguments","[object Array]":"array","[object Date]":"date","[object Function]":"function","[object Number]":"number","[object RegExp]":"regexp","[object String]":"string"};g.exports=function(f){var b=Object.prototype.toString.call(f);
return c[b]?c[b]:null===f?"null":void 0===f?"undefined":f===Object(f)?"object":typeof f}});"object"==typeof exports?module.exports=f("chai"):"function"==typeof define&&define.amd?define("chai",[],function(){return f("chai")}):(this||window).chai=f("chai")})();

View File

@ -0,0 +1,59 @@
var slice = Array.prototype.slice;
suite('AnimeClient methods exist', function () {
test("AnimeClient exists", function () {
expect(AnimeClient).to.be.ok;
});
['$', 'scrollToTop', 'showMessage', 'closestParent', 'url', 'throttle', 'on', 'ajax', 'get'].forEach((method) => {
test("AnimeClient." + method + ' exists.', function () {
expect(AnimeClient[method]).to.be.ok;
});
});
});
suite('AnimeClient.$', function () {
test('$ returns an array', function () {
var matched = AnimeClient.$('div');
expect(matched).to.be.an('array');
});
test('$ returns same element as "getElementById"', function () {
var actual = AnimeClient.$('#mocha')[0];
var expected = document.getElementById('mocha');
expect(actual).to.equal(expected);
});
test('$ returns same elements as "getElementsByClassName"', function () {
var actual = AnimeClient.$('.progress');
var expected = slice.apply(document.getElementsByClassName('progress'));
expect(actual).to.deep.equal(expected);
});
test('$ returns same elements as "getElementsByTagName"', function () {
var actual = AnimeClient.$('ul');
var expected = slice.apply(document.getElementsByTagName('ul'));
expect(actual).to.deep.equal(expected);
});
});
suite('AnimeClient.url', function () {
test('url method has expected result', function () {
let expected = `//${document.location.host}/path`;
expect(AnimeClient.url('/path')).to.equal(expected);
});
});
suite('AnimeClient.closestParent', function () {
test('".grandChild" closest "section" is "#parentTest"', function () {
let sel = AnimeClient.$('.grandChild')[0];
let expected = document.getElementById('parentTest');
expect(AnimeClient.closestParent(sel, 'section')).to.equal(expected);
});
test('".child" closest "article" is "#parentTest"', function () {
let sel = AnimeClient.$('.child')[0];
let expected = document.getElementById('parentTest');
expect(AnimeClient.closestParent(sel, 'section')).to.equal(expected);
});
});

100
public/test/tests/ajax.js Normal file
View File

@ -0,0 +1,100 @@
suite('AnimeClient.ajax', function () {
'use strict';
test('AnimeClient.get method', function (done) {
AnimeClient.get('ajax.php', function (res) {
expect(res).to.be.ok;
done();
});
});
test('GET', function (done) {
AnimeClient.ajax('ajax.php', {
success: function (res) {
expect(res).to.be.ok;
done();
},
error: function (err) {
expect.fail;
done();
}
});
});
test('POST', function (done) {
AnimeClient.ajax('ajax.php', {
type: 'POST',
success: function (res) {
expect(res).to.be.ok;
done();
},
error: function (err) {
expect.fail;
done();
}
});
});
test('PUT', function (done) {
AnimeClient.ajax('ajax.php', {
type: 'PUT',
success: function (res) {
expect(res).to.be.ok;
done();
},
error: function (err) {
expect.fail;
done();
}
});
});
test('DELETE', function (done) {
AnimeClient.ajax('ajax.php', {
type: 'DELETE',
success: function (res) {
expect(res).to.be.ok;
done();
},
error: function (err) {
expect.fail;
done();
}
});
});
test('POST with data', function (done) {
var expected = '{"foo":"data"}';
AnimeClient.ajax('ajax.php?data', {
data: {foo:'data'},
type: 'POST',
success: function (res) {
expect(res).to.be.equal(expected);
done();
},
error: function (err) {
expect.fail;
done();
}
});
});
test('PUT with data', function (done) {
var expected = '{"bar":"data"}';
AnimeClient.ajax('ajax.php?data', {
data: {bar:'data'},
type: 'POST',
success: function (res) {
expect(res).to.be.equal(expected);
done();
},
error: function (err) {
expect.fail;
done();
}
});
});
test('Bad request', function (done) {
AnimeClient.ajax('ajax.php?bad', {
error: function (status) {
expect(status).to.be.equal(401);
done();
}
});
});
});

View File

@ -382,11 +382,13 @@ class Controller {
* Output a JSON Response
*
* @param mixed $data
* @param int $code - the http status code
* @return void
*/
protected function outputJSON($data = [])
protected function outputJSON($data = [], $code = 200)
{
$view = new JsonView($this->container);
$view->setStatusCode($code);
$view->setOutput($data);
}

View File

@ -244,16 +244,36 @@ class Anime extends BaseController {
/**
* Update an anime item
*
* @return boolean|null
*/
public function update()
{
$this->outputJSON(
$this->model->update(
$this->request->post->get()
)
);
$response = $this->model->update($this->request->post->get());
$this->outputJSON($response['body'], $response['statusCode']);
}
/**
* Remove an anime from the list
*/
public function delete()
{
$response = $this->model->update($this->request->post->get());
$this->outputJSON($response['body'], $response['statusCode']);
}
/**
* View details of an anime
*
* @param string anime_id
* @return void
*/
public function details($anime_id)
{
$data = $this->model->get_anime($anime_id);
$this->outputHTML('anime/details', [
'title' => $data['title'],
'data' => $data,
]);
}
}
// End of AnimeController.php

View File

@ -12,6 +12,7 @@
*/
namespace Aviat\AnimeClient\Controller;
use Aviat\Ion\Json;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\AnimeClient\Controller;
use Aviat\AnimeClient\Config;
@ -91,6 +92,61 @@ class Manga extends Controller {
]);
}
/**
* Form to add an manga
*
* @return void
*/
public function add_form()
{
$raw_status_list = MangaReadingStatus::getConstList();
$statuses = [];
foreach ($raw_status_list as $status_item)
{
$statuses[$status_item] = (string)$this->string($status_item)
->underscored()
->humanize()
->titleize();
}
$this->set_session_redirect();
$this->outputHTML('manga/add', [
'title' => $this->config->get('whose_list') .
"'s Manga List &middot; Add",
'action_url' => $this->urlGenerator->url('manga/add'),
'status_list' => $statuses
]);
}
/**
* Add an manga to the list
*
* @return void
*/
public function add()
{
$data = $this->request->post->get();
if ( ! array_key_exists('id', $data))
{
$this->redirect("manga/add", 303);
}
$result = $this->model->add($data);
if ($result['statusCode'] >= 200 && $result['statusCode'] < 300)
{
$this->set_flash_message('Added new manga to list', 'success');
}
else
{
$this->set_flash_message('Failed to add new manga to list' . $result['body'], 'error');
}
$this->session_redirect();
}
/**
* Show the manga edit form
*
@ -113,6 +169,17 @@ class Manga extends Controller {
]);
}
/**
* Search for a manga to add to the list
*
* @return void
*/
public function search()
{
$query = $this->request->query->get('query');
$this->outputJSON($this->model->search($query));
}
/**
* Update an anime item via a form submission
*
@ -128,9 +195,9 @@ class Manga extends Controller {
$post_data = $transformer->untransform($post_data);
$full_result = $this->model->update($post_data);
$result = $full_result['body'];
$result = Json::decode((string)$full_result['body']);
if (array_key_exists('manga', $result))
if ($full_result['statusCode'] == 200)
{
$m =& $result['manga'][0];
$title = ( ! empty($m['english_title']))
@ -141,7 +208,7 @@ class Manga extends Controller {
}
else
{
$this->set_flash_message('Failed to update anime.', 'error');
$this->set_flash_message('Failed to update manga.', 'error');
}
$this->session_redirect();
@ -154,7 +221,8 @@ class Manga extends Controller {
*/
public function update()
{
$this->outputJSON($this->model->update($this->request->post->get()));
$result = $this->model->update($this->request->post->get());
$this->outputJSON($result['body'], $result['statusCode']);
}
}
// End of MangaController.php

View File

@ -104,7 +104,7 @@ class Dispatcher extends RoutingBase {
$logger->debug(print_r($route, TRUE));
}
if($route)
if ($route)
{
$parsed = $this->process_route($route);
$controller_name = $parsed['controller_name'];
@ -272,7 +272,7 @@ class Dispatcher extends RoutingBase {
'message' => 'Invalid HTTP Verb'
];
}
else if($failure->failedAccept())
else if ($failure->failedAccept())
{
$params = [
'http_code' => 406,

View File

@ -105,7 +105,7 @@ class MangaListTransformer extends AbstractTransformer {
'notes' => $item['notes'],
];
if ($item['new_rating'] !== $item['old_rating'])
if ($item['new_rating'] !== $item['old_rating'] && $item['new_rating'] !== "")
{
$map['rating'] = ($item['new_rating'] > 0)
? $item['new_rating'] / 2

View File

@ -178,5 +178,18 @@ class API extends BaseModel {
return FALSE;
}
/**
* Dummy function that should be abstract. Is not abstract because
* this class is used concretely for authorizing API calls
*
* @TODO Refactor, and make this abstract
* @param string $status
* @return array
*/
protected function _get_list_from_api($status)
{
return [];
}
}
// End of BaseApiModel.php

View File

@ -74,6 +74,33 @@ class Anime extends API {
];
}
/**
* Remove an anime from a list
*
* @param array $data
* @return array|false
*/
public function delete($data)
{
$auth = $this->container->get('auth');
if ( ! $auth->is_authenticated() || ! array_key_exists('id', $data))
{
return FALSE;
}
$id = $data['id'];
$data['auth_token'] = $auth->get_auth_token();
$response = $this->client->post("libraries/{$id}/remove", [
'form_params' => $data
]);
return [
'statusCode' => $response->getStatusCode(),
'body' => Json::decode($response->getBody(), TRUE)
];
}
/**
* Get the full set of anime lists
*

View File

@ -51,15 +51,15 @@ class Manga extends API {
protected $base_url = "https://hummingbird.me/";
/**
* Update the selected manga
* Make an authenticated manga API call
*
* @param array $data
* @param string $type - the HTTP verb
* @param string $url
* @param string|null $json
* @return array
*/
public function update($data)
protected function _manga_api_call($type, $url, $json = NULL)
{
$id = $data['id'];
$token = $this->container->get('auth')
->get_auth_token();
@ -73,17 +73,101 @@ class Manga extends API {
]);
$cookieJar->setCookie($cookie_data);
$result = $this->put("manga_library_entries/{$id}", [
'cookies' => $cookieJar,
'json' => ['manga_library_entry' => $data]
]);
$config = [
'cookies' => $cookieJar
];
if ( ! is_null($json))
{
$config['json'] = $json;
}
$result = $this->client->request(strtoupper($type), $url, $config);
return [
'statusCode' => $result->getStatusCode(),
'body' => Json::decode($result->getBody(), TRUE)
'body' => $result->getBody()
];
}
/**
* Add a manga to the list
*
* @param array $data
*/
public function add($data)
{
$object = [
'manga_library_entry' => [
'status' => $data['status'],
'manga_id' => $data['id']
]
];
return $this->_manga_api_call('post', 'manga_library_entries', $object);
}
/**
* Update the selected manga
*
* @param array $data
* @return array
*/
public function update($data)
{
$id = $data['id'];
return $this->_manga_api_call(
'put',
"manga_library_entries/{$id}",
['manga_library_entry' => $data]
);
}
/**
* Delete a manga entry
*
* @param array $data
* @return array
*/
public function delete($data)
{
$id = $data['id'];
return $this->_manga_api_call('delete', "manga_library_entries/{$id}");
}
/**
* Search for manga by name
*
* @param string $name
* @return array
*/
public function search($name)
{
$logger = $this->container->getLogger('default');
$config = [
'query' => [
'scope' => 'manga',
'depth' => 'full',
'query' => $name
]
];
$response = $this->get('search.json', $config);
if ($response->getStatusCode() != 200)
{
$logger->warning("Non 200 response for search api call");
$logger->warning($response->getBody());
throw new RuntimeException($response->getEffectiveUrl());
}
return Json::decode($response->getBody(), TRUE);
}
/**
* Get the full set of anime lists
*

View File

@ -39,6 +39,12 @@ class RoutingBase {
*/
protected $routes;
/**
* Route configuration options
* @var array
*/
protected $route_config;
/**
* Constructor
*
@ -48,8 +54,9 @@ class RoutingBase {
{
$this->container = $container;
$this->config = $container->get('config');
$this->base_routes = $this->config->get('routes');
$this->routes = $this->base_routes['routes'];
$base_routes = $this->config->get('routes');
$this->routes = $base_routes['routes'];
$this->route_config = $base_routes['route_config'];
}
/**
@ -60,7 +67,7 @@ class RoutingBase {
*/
public function __get($key)
{
$routing_config = $this->base_routes['route_config'];
$routing_config =& $this->route_config;
if (array_key_exists($key, $routing_config))
{

View File

@ -23,8 +23,8 @@ class Json {
* Encode data in json format
*
* @param mixed $data
* @param int $options=0
* @param int $depth=512
* @param int $options
* @param int $depth
* @return string
*/
public static function encode($data, $options = 0, $depth = 512)

View File

@ -65,6 +65,11 @@ class HttpView extends BaseView {
*/
protected function output()
{
$this->response->headers->set('Content-Security-Policy', "script-src 'self'");
$this->response->headers->set('X-Content-Type-Options', 'nosniff');
$this->response->headers->set('X-XSS-Protection', '1;mode=block');
$this->response->headers->set('X-Frame-Options', 'SAMEORIGIN');
$content =& $this->response->content;
$content->set($this->output);
$content->setType($this->contentType);

View File

@ -144,6 +144,10 @@ class MockBaseApiModel extends BaseApiModel {
use MockInjectionTrait;
protected $base_url = 'https://httpbin.org/';
protected function _get_list_from_api($status)
{
return [];
}
}
class TestAnimeModel extends AnimeModel {