diff --git a/.env.example b/.env.example
index b538ab1a0796..36f8816f87e1 100644
--- a/.env.example
+++ b/.env.example
@@ -56,6 +56,9 @@ GOOGLE_MAPS_ENABLED=true
# Create a cookie to stay logged in
#REMEMBER_ME_ENABLED=true
+# Immediately expire cookie on the browser closing
+#SESSION_EXPIRE_ON_CLOSE=false
+
# The app automatically logs the user out after this number of seconds
#AUTO_LOGOUT_SECONDS=28800
diff --git a/.env.travis b/.env.travis
index c644c4f63898..e7ea720c59f7 100644
--- a/.env.travis
+++ b/.env.travis
@@ -1,5 +1,5 @@
APP_ENV=development
-APP_DEBUG=true
+APP_DEBUG=false
APP_URL=http://ninja.dev
APP_KEY=SomeRandomStringSomeRandomString
APP_CIPHER=AES-256-CBC
diff --git a/.travis.yml b/.travis.yml
index b8f19fb9e6eb..4cd190407757 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -93,7 +93,8 @@ script:
#- php ./vendor/codeception/codeception/codecept run acceptance GoProCest.php
after_script:
- - php artisan ninja:check-data --no-interaction
+ - php artisan ninja:check-data --no-interaction --database='db-ninja-1'
+ - php artisan ninja:check-data --no-interaction --database='db-ninja-2'
- php artisan ninja:init-lookup --validate=true --database='db-ninja-1'
- php artisan ninja:init-lookup --validate=true --database='db-ninja-2'
- cat .env
diff --git a/app/Console/Commands/CalculatePayouts.php b/app/Console/Commands/CalculatePayouts.php
index 869783dc8ad3..673b1d89f869 100644
--- a/app/Console/Commands/CalculatePayouts.php
+++ b/app/Console/Commands/CalculatePayouts.php
@@ -74,7 +74,8 @@ class CalculatePayouts extends Command
$this->info("User: $user");
foreach ($client->payments as $payment) {
- $this->info("Date: $payment->payment_date, Amount: $payment->amount, Reference: $payment->transaction_reference");
+ $amount = $payment->getCompletedAmount();
+ $this->info("Date: $payment->payment_date, Amount: $amount, Reference: $payment->transaction_reference");
}
}
}
diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php
index 80d85501fa3f..f7f2407277d1 100644
--- a/app/Console/Commands/CreateTestData.php
+++ b/app/Console/Commands/CreateTestData.php
@@ -8,6 +8,8 @@ use App\Ninja\Repositories\ExpenseRepository;
use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Repositories\PaymentRepository;
use App\Ninja\Repositories\VendorRepository;
+use App\Ninja\Repositories\TaskRepository;
+use App\Ninja\Repositories\ProjectRepository;
use App\Models\Client;
use App\Models\TaxRate;
use App\Models\Project;
@@ -44,6 +46,7 @@ class CreateTestData extends Command
* @param PaymentRepository $paymentRepo
* @param VendorRepository $vendorRepo
* @param ExpenseRepository $expenseRepo
+ * @param TaskRepository $taskRepo
* @param AccountRepository $accountRepo
*/
public function __construct(
@@ -52,6 +55,8 @@ class CreateTestData extends Command
PaymentRepository $paymentRepo,
VendorRepository $vendorRepo,
ExpenseRepository $expenseRepo,
+ TaskRepository $taskRepo,
+ ProjectRepository $projectRepo,
AccountRepository $accountRepo)
{
parent::__construct();
@@ -63,6 +68,8 @@ class CreateTestData extends Command
$this->paymentRepo = $paymentRepo;
$this->vendorRepo = $vendorRepo;
$this->expenseRepo = $expenseRepo;
+ $this->taskRepo = $taskRepo;
+ $this->projectRepo = $projectRepo;
$this->accountRepo = $accountRepo;
}
@@ -125,17 +132,20 @@ class CreateTestData extends Command
$this->info('Client: ' . $client->name);
$this->createInvoices($client);
+ $this->createInvoices($client, true);
+ $this->createTasks($client);
}
}
/**
* @param $client
*/
- private function createInvoices($client)
+ private function createInvoices($client, $isQuote = false)
{
for ($i = 0; $i < $this->count; $i++) {
$data = [
'is_public' => true,
+ 'is_quote' => $isQuote,
'client_id' => $client->id,
'invoice_date_sql' => date_create()->modify(rand(-100, 100) . ' days')->format('Y-m-d'),
'due_date_sql' => date_create()->modify(rand(-100, 100) . ' days')->format('Y-m-d'),
@@ -150,7 +160,9 @@ class CreateTestData extends Command
$invoice = $this->invoiceRepo->save($data);
$this->info('Invoice: ' . $invoice->invoice_number);
- $this->createPayment($client, $invoice);
+ if (! $isQuote) {
+ $this->createPayment($client, $invoice);
+ }
}
}
@@ -172,6 +184,31 @@ class CreateTestData extends Command
$this->info('Payment: ' . $payment->amount);
}
+ private function createTasks($client)
+ {
+ $data = [
+ 'client_id' => $client->id,
+ 'name' => $this->faker->sentence(3),
+ ];
+ $project = $this->projectRepo->save($data);
+
+ for ($i = 0; $i < $this->count; $i++) {
+ $startTime = date_create()->modify(rand(-100, 100) . ' days')->format('U');
+ $endTime = $startTime + (60 * 60 * 2);
+ $timeLog = "[[{$startTime},{$endTime}]]";
+ $data = [
+ 'client_id' => $client->id,
+ 'project_id' => $project->id,
+ 'description' => $this->faker->text($this->faker->numberBetween(50, 300)),
+ 'time_log' => $timeLog,
+ ];
+
+ $this->taskRepo->save(false, $data);
+ }
+ }
+
+
+
private function createVendors()
{
for ($i = 0; $i < $this->count; $i++) {
@@ -206,7 +243,7 @@ class CreateTestData extends Command
$data = [
'vendor_id' => $vendor->id,
'amount' => $this->faker->randomFloat(2, 1, 10),
- 'expense_date' => null,
+ 'expense_date' => date_create()->modify(rand(-100, 100) . ' days')->format('Y-m-d'),
'public_notes' => '',
];
diff --git a/app/Console/Commands/SendRenewalInvoices.php b/app/Console/Commands/SendRenewalInvoices.php
index ca0a11568cb7..a054c2e18b2c 100644
--- a/app/Console/Commands/SendRenewalInvoices.php
+++ b/app/Console/Commands/SendRenewalInvoices.php
@@ -74,13 +74,6 @@ class SendRenewalInvoices extends Command
$plan['num_users'] = $company->num_users;
$plan['price'] = min($company->plan_price, Utils::getPlanPrice($plan));
- if ($company->pending_plan) {
- $plan['plan'] = $company->pending_plan;
- $plan['term'] = $company->pending_term;
- $plan['num_users'] = $company->pending_num_users;
- $plan['price'] = min($company->pending_plan_price, Utils::getPlanPrice($plan));
- }
-
if ($plan['plan'] == PLAN_FREE || ! $plan['plan'] || ! $plan['term'] || ! $plan['price']) {
continue;
}
diff --git a/app/Constants.php b/app/Constants.php
index 198ec32113e4..5868fee66527 100644
--- a/app/Constants.php
+++ b/app/Constants.php
@@ -309,7 +309,7 @@ if (! defined('APP_NAME')) {
define('NINJA_APP_URL', env('NINJA_APP_URL', 'https://app.invoiceninja.com'));
define('NINJA_DOCS_URL', env('NINJA_DOCS_URL', 'http://docs.invoiceninja.com/en/latest'));
define('NINJA_DATE', '2000-01-01');
- define('NINJA_VERSION', '3.7.2' . env('NINJA_VERSION_SUFFIX'));
+ define('NINJA_VERSION', '3.8.0' . env('NINJA_VERSION_SUFFIX'));
define('SOCIAL_LINK_FACEBOOK', env('SOCIAL_LINK_FACEBOOK', 'https://www.facebook.com/invoiceninja'));
define('SOCIAL_LINK_TWITTER', env('SOCIAL_LINK_TWITTER', 'https://twitter.com/invoiceninja'));
@@ -341,6 +341,8 @@ if (! defined('APP_NAME')) {
define('MSBOT_STATE_URL', 'https://state.botframework.com/v3');
define('INVOICEPLANE_IMPORT', 'https://github.com/turbo124/Plane2Ninja');
+ define('TIME_TRACKER_USER_AGENT', 'Time Tracker');
+
define('BOT_PLATFORM_WEB_APP', 'WebApp');
define('BOT_PLATFORM_SKYPE', 'Skype');
@@ -405,6 +407,7 @@ if (! defined('APP_NAME')) {
define('PAYMENT_TYPE_SWITCH', 23);
define('PAYMENT_TYPE_ALIPAY', 28);
define('PAYMENT_TYPE_SOFORT', 29);
+ define('PAYMENT_TYPE_SEPA', 30);
define('PAYMENT_METHOD_STATUS_NEW', 'new');
define('PAYMENT_METHOD_STATUS_VERIFICATION_FAILED', 'verification_failed');
@@ -418,6 +421,7 @@ if (! defined('APP_NAME')) {
define('GATEWAY_TYPE_CUSTOM', 6);
define('GATEWAY_TYPE_ALIPAY', 7);
define('GATEWAY_TYPE_SOFORT', 8);
+ define('GATEWAY_TYPE_SEPA', 9);
define('GATEWAY_TYPE_TOKEN', 'token');
define('TEMPLATE_INVOICE', 'invoice');
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index 23e7b5710b54..f03eb9e65fc7 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -431,9 +431,12 @@ class AccountController extends BaseController
*/
private function showBankAccounts()
{
+ $account = auth()->user()->account;
+
return View::make('accounts.banks', [
'title' => trans('texts.bank_accounts'),
'advanced' => ! Auth::user()->hasFeature(FEATURE_EXPENSES),
+ 'warnPaymentGateway' => ! $account->account_gateways->count(),
]);
}
diff --git a/app/Http/Controllers/AccountGatewayController.php b/app/Http/Controllers/AccountGatewayController.php
index 0ff3cee87201..8c1db8731dd8 100644
--- a/app/Http/Controllers/AccountGatewayController.php
+++ b/app/Http/Controllers/AccountGatewayController.php
@@ -254,7 +254,7 @@ class AccountGatewayController extends BaseController
if (! $value && in_array($field, ['testMode', 'developerMode', 'sandbox'])) {
// do nothing
} elseif ($gatewayId == GATEWAY_CUSTOM) {
- $config->$field = strip_tags($value);
+ $config->$field = Utils::isNinjaProd() ? strip_tags($value) : $value;
} else {
$config->$field = $value;
}
diff --git a/app/Http/Controllers/BaseAPIController.php b/app/Http/Controllers/BaseAPIController.php
index 190debf96139..47473467460d 100644
--- a/app/Http/Controllers/BaseAPIController.php
+++ b/app/Http/Controllers/BaseAPIController.php
@@ -74,10 +74,14 @@ class BaseAPIController extends Controller
$entity = $request->entity();
$action = $request->action;
- if (! in_array($action, ['archive', 'delete', 'restore'])) {
+ if (! in_array($action, ['archive', 'delete', 'restore', 'mark_sent'])) {
return $this->errorResponse("Action [$action] is not supported");
}
+ if ($action == 'mark_sent') {
+ $action = 'markSent';
+ }
+
$repo = Utils::toCamelCase($this->entityType) . 'Repo';
$this->$repo->$action($entity);
diff --git a/app/Http/Controllers/CalendarController.php b/app/Http/Controllers/CalendarController.php
new file mode 100644
index 000000000000..80abe6b2cd20
--- /dev/null
+++ b/app/Http/Controllers/CalendarController.php
@@ -0,0 +1,35 @@
+ auth()->user()->account,
+ ];
+
+ return view('calendar', $data);
+ }
+
+ public function loadEvents()
+ {
+ if (auth()->user()->account->hasFeature(FEATURE_REPORTS)) {
+ $events = dispatch(new GenerateCalendarEvents());
+ } else {
+ $events = [];
+ }
+
+ return response()->json($events);
+ }
+
+}
diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php
index 58d759b22388..7837c0980710 100644
--- a/app/Http/Controllers/DashboardController.php
+++ b/app/Http/Controllers/DashboardController.php
@@ -42,10 +42,14 @@ class DashboardController extends BaseController
$expenses = $dashboardRepo->expenses($account, $userId, $viewAll);
$tasks = $dashboardRepo->tasks($accountId, $userId, $viewAll);
- $showBlueVinePromo = $user->is_admin
- && env('BLUEVINE_PARTNER_UNIQUE_ID')
- && ! $account->company->bluevine_status
- && $account->created_at <= date('Y-m-d', strtotime('-1 month'));
+ $showBlueVinePromo = false;
+ if ($user->is_admin && env('BLUEVINE_PARTNER_UNIQUE_ID')) {
+ $showBlueVinePromo = ! $account->company->bluevine_status
+ && $account->created_at <= date('Y-m-d', strtotime('-1 month'));
+ if (request()->bluevine) {
+ $showBlueVinePromo = true;
+ }
+ }
$showWhiteLabelExpired = Utils::isSelfHost() && $account->company->hasExpiredPlan(PLAN_WHITE_LABEL);
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 716d96860b7e..9ad5e3efa679 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -126,6 +126,14 @@ class HomeController extends BaseController
return RESULT_SUCCESS;
}
+ /**
+ * @return mixed
+ */
+ public function loggedIn()
+ {
+ return RESULT_SUCCESS;
+ }
+
/**
* @return mixed
*/
diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php
index ef87f90749ad..45798d3f0fa9 100644
--- a/app/Http/Controllers/InvoiceController.php
+++ b/app/Http/Controllers/InvoiceController.php
@@ -172,7 +172,7 @@ class InvoiceController extends BaseController
$contact->email_error = $invitation->email_error;
$contact->invitation_link = $invitation->getLink('view', $hasPassword, $hasPassword);
$contact->invitation_viewed = $invitation->viewed_date && $invitation->viewed_date != '0000-00-00 00:00:00' ? $invitation->viewed_date : false;
- $contact->invitation_openend = $invitation->opened_date && $invitation->opened_date != '0000-00-00 00:00:00' ? $invitation->opened_date : false;
+ $contact->invitation_opened = $invitation->opened_date && $invitation->opened_date != '0000-00-00 00:00:00' ? $invitation->opened_date : false;
$contact->invitation_status = $contact->email_error ? false : $invitation->getStatus();
$contact->invitation_signature_svg = $invitation->signatureDiv();
}
diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php
index 62404903b91f..16dc60adad5a 100644
--- a/app/Http/Controllers/TaskController.php
+++ b/app/Http/Controllers/TaskController.php
@@ -232,17 +232,22 @@ class TaskController extends BaseController
$task = $this->taskRepo->save($publicId, $request->input());
- if ($publicId) {
- Session::flash('message', trans('texts.updated_task'));
- } else {
- Session::flash('message', trans('texts.created_task'));
- }
-
if (in_array($action, ['invoice', 'add_to_invoice'])) {
return self::bulk();
}
- return Redirect::to("tasks/{$task->public_id}/edit");
+ if (request()->wantsJson()) {
+ $task->time_log = json_decode($task->time_log);
+ return $task->load(['client.contacts', 'project'])->toJson();
+ } else {
+ if ($publicId) {
+ Session::flash('message', trans('texts.updated_task'));
+ } else {
+ Session::flash('message', trans('texts.created_task'));
+ }
+
+ return Redirect::to("tasks/{$task->public_id}/edit");
+ }
}
/**
@@ -303,10 +308,14 @@ class TaskController extends BaseController
} else {
$count = $this->taskService->bulk($ids, $action);
- $message = Utils::pluralize($action.'d_task', $count);
- Session::flash('message', $message);
+ if (request()->wantsJson()) {
+ return response()->json($count);
+ } else {
+ $message = Utils::pluralize($action.'d_task', $count);
+ Session::flash('message', $message);
- return $this->returnBulk($this->entityType, $action, $ids);
+ return $this->returnBulk($this->entityType, $action, $ids);
+ }
}
}
diff --git a/app/Http/Controllers/TimeTrackerController.php b/app/Http/Controllers/TimeTrackerController.php
new file mode 100644
index 000000000000..77cb951c304a
--- /dev/null
+++ b/app/Http/Controllers/TimeTrackerController.php
@@ -0,0 +1,32 @@
+user();
+ $account = $user->account;
+
+ if (! $account->hasFeature(FEATURE_TASKS)) {
+ return trans('texts.tasks_not_enabled');
+ }
+
+ $data = [
+ 'title' => trans('texts.time_tracker'),
+ 'tasks' => Task::scope()->with('project', 'client.contacts')->whereNull('invoice_id')->get(),
+ 'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
+ 'projects' => Project::scope()->with('client.contacts')->orderBy('name')->get(),
+ 'account' => $account,
+ ];
+
+ return view('tasks.time_tracker', $data);
+ }
+}
diff --git a/app/Http/Requests/TaskRequest.php b/app/Http/Requests/TaskRequest.php
index b5bd2cd3e311..1fb10a6d7051 100644
--- a/app/Http/Requests/TaskRequest.php
+++ b/app/Http/Requests/TaskRequest.php
@@ -13,11 +13,24 @@ class TaskRequest extends EntityRequest
{
$input = $this->all();
+ /*
+ // check if we're creating a new client
+ if ($this->client_id == '-1') {
+ $client = [
+ 'name' => trim($this->client_name),
+ ];
+ if (Client::validate($client) === true) {
+ $client = app('App\Ninja\Repositories\ClientRepository')->save($client);
+ $input['client_id'] = $this->client_id = $client->public_id;
+ }
+ }
+ */
+
// check if we're creating a new project
if ($this->project_id == '-1') {
$project = [
'name' => trim($this->project_name),
- 'client_id' => Client::getPrivateId($this->client),
+ 'client_id' => Client::getPrivateId($this->client_id ?: $this->client),
];
if (Project::validate($project) === true) {
$project = app('App\Ninja\Repositories\ProjectRepository')->save($project);
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 23b4950447b5..615fcac7a900 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -121,6 +121,7 @@ if (Utils::isTravis()) {
}
Route::group(['middleware' => ['lookup:user', 'auth:user']], function () {
+ Route::get('logged_in', 'HomeController@loggedIn');
Route::get('dashboard', 'DashboardController@index');
Route::get('dashboard_chart_data/{group_by}/{start_date}/{end_date}/{currency_id}/{include_expenses}', 'DashboardController@chartData');
Route::get('set_entity_filter/{entity_type}/{filter?}', 'AccountController@setEntityFilter');
@@ -147,6 +148,7 @@ Route::group(['middleware' => ['lookup:user', 'auth:user']], function () {
Route::post('clients/bulk', 'ClientController@bulk');
Route::get('clients/statement/{client_id}/{status_id?}/{start_date?}/{end_date?}', 'ClientController@statement');
+ Route::get('time_tracker', 'TimeTrackerController@index');
Route::resource('tasks', 'TaskController');
Route::get('api/tasks/{client_id?}', 'TaskController@getDatatable');
Route::get('tasks/create/{client_id?}/{project_id?}', 'TaskController@create');
@@ -248,6 +250,8 @@ Route::group(['middleware' => ['lookup:user', 'auth:user']], function () {
Route::get('reports', 'ReportController@showReports');
Route::post('reports', 'ReportController@showReports');
+ Route::get('calendar', 'CalendarController@showCalendar');
+ Route::get('calendar_events', 'CalendarController@loadEvents');
});
Route::group([
diff --git a/app/Jobs/GenerateCalendarEvents.php b/app/Jobs/GenerateCalendarEvents.php
new file mode 100644
index 000000000000..6d27b6190db7
--- /dev/null
+++ b/app/Jobs/GenerateCalendarEvents.php
@@ -0,0 +1,52 @@
+filter ?: [];
+
+ $data = [
+ ENTITY_INVOICE => Invoice::scope()->invoices(),
+ ENTITY_QUOTE => Invoice::scope()->quotes(),
+ ENTITY_TASK => Task::scope()->with(['project']),
+ ENTITY_PAYMENT => Payment::scope()->with(['invoice']),
+ ENTITY_EXPENSE => Expense::scope()->with(['expense_category']),
+ ];
+
+ foreach ($data as $type => $source) {
+ if (! count($filter) || in_array($type, $filter)) {
+ $source->where(function($query) use ($type) {
+ $start = date_create(request()->start);
+ $end = date_create(request()->end);
+ return $query->dateRange($start, $end);
+ });
+
+ foreach ($source->with(['account', 'client.contacts'])->get() as $entity) {
+ if ($entity->client && $entity->client->trashed()) {
+ continue;
+ }
+
+ $subColors = count($filter) == 1;
+ $events[] = $entity->present()->calendarEvent($subColors);
+ }
+ }
+ }
+
+ return $events;
+ }
+}
diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php
index ccf2bb162d55..3e43eab32dc5 100644
--- a/app/Libraries/Utils.php
+++ b/app/Libraries/Utils.php
@@ -1304,6 +1304,22 @@ class Utils
return $r;
}
+ public static function brewerColor($number) {
+ $colors = [
+ '#1c9f77',
+ '#d95d02',
+ '#716cb1',
+ '#e62a8b',
+ '#5fa213',
+ '#e6aa04',
+ '#a87821',
+ '#676767',
+ ];
+ $number = ($number-1) % count($colors);
+
+ return $colors[$number];
+ }
+
/**
* Replace language-specific characters by ASCII-equivalents.
* @param string $s
diff --git a/app/Models/Expense.php b/app/Models/Expense.php
index a76b59cae032..1dc81d2c381e 100644
--- a/app/Models/Expense.php
+++ b/app/Models/Expense.php
@@ -227,6 +227,16 @@ class Expense extends EntityModel
return $array;
}
+ /**
+ * @param $query
+ *
+ * @return mixed
+ */
+ public function scopeDateRange($query, $startDate, $endDate)
+ {
+ return $query->whereBetween('expense_date', [$startDate, $endDate]);
+ }
+
/**
* @param $query
* @param null $bankdId
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index 43df86c63c64..12efcb6a14dc 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -423,6 +423,20 @@ class Invoice extends EntityModel implements BalanceAffecting
->where('is_recurring', '=', true);
}
+ /**
+ * @param $query
+ *
+ * @return mixed
+ */
+ public function scopeDateRange($query, $startDate, $endDate)
+ {
+ return $query->where(function ($query) use ($startDate, $endDate) {
+ $query->whereBetween('invoice_date', [$startDate, $endDate]);
+ })->orWhere(function ($query) use ($startDate, $endDate) {
+ $query->whereBetween('due_date', [$startDate, $endDate]);
+ });
+ }
+
/**
* @param $query
*
diff --git a/app/Models/Payment.php b/app/Models/Payment.php
index 415f2664d1db..0fc6da08eda2 100644
--- a/app/Models/Payment.php
+++ b/app/Models/Payment.php
@@ -146,6 +146,16 @@ class Payment extends EntityModel
return $query;
}
+ /**
+ * @param $query
+ *
+ * @return mixed
+ */
+ public function scopeDateRange($query, $startDate, $endDate)
+ {
+ return $query->whereBetween('payment_date', [$startDate, $endDate]);
+ }
+
/**
* @return mixed
*/
diff --git a/app/Ninja/Datatables/ClientDatatable.php b/app/Ninja/Datatables/ClientDatatable.php
index ad20e15bc67e..b74eb5fc08ea 100644
--- a/app/Ninja/Datatables/ClientDatatable.php
+++ b/app/Ninja/Datatables/ClientDatatable.php
@@ -17,7 +17,8 @@ class ClientDatatable extends EntityDatatable
[
'name',
function ($model) {
- return link_to("clients/{$model->public_id}", $model->name ?: '')->toHtml();
+ $str = link_to("clients/{$model->public_id}", $model->name ?: '')->toHtml();
+ return $this->addNote($str, $model->private_notes);
},
],
[
diff --git a/app/Ninja/Datatables/EntityDatatable.php b/app/Ninja/Datatables/EntityDatatable.php
index 008b1f877d12..02fd80845756 100644
--- a/app/Ninja/Datatables/EntityDatatable.php
+++ b/app/Ninja/Datatables/EntityDatatable.php
@@ -90,4 +90,12 @@ class EntityDatatable
return $indices;
}
+
+ public function addNote($str, $note) {
+ if (! $note) {
+ return $str;
+ }
+
+ return $str . ' ';
+ }
}
diff --git a/app/Ninja/Datatables/ExpenseDatatable.php b/app/Ninja/Datatables/ExpenseDatatable.php
index c3c344e92099..620366c21ccc 100644
--- a/app/Ninja/Datatables/ExpenseDatatable.php
+++ b/app/Ninja/Datatables/ExpenseDatatable.php
@@ -52,7 +52,8 @@ class ExpenseDatatable extends EntityDatatable
return Utils::fromSqlDate($model->expense_date_sql);
}
- return link_to("expenses/{$model->public_id}/edit", Utils::fromSqlDate($model->expense_date_sql))->toHtml();
+ $str = link_to("expenses/{$model->public_id}/edit", Utils::fromSqlDate($model->expense_date_sql))->toHtml();
+ return $this->addNote($str, $model->private_notes);
},
],
[
diff --git a/app/Ninja/Datatables/InvoiceDatatable.php b/app/Ninja/Datatables/InvoiceDatatable.php
index 9e98b18d3889..0f5cf8047042 100644
--- a/app/Ninja/Datatables/InvoiceDatatable.php
+++ b/app/Ninja/Datatables/InvoiceDatatable.php
@@ -24,7 +24,8 @@ class InvoiceDatatable extends EntityDatatable
return $model->invoice_number;
}
- return link_to("{$entityType}s/{$model->public_id}/edit", $model->invoice_number, ['class' => Utils::getEntityRowClass($model)])->toHtml();
+ $str = link_to("{$entityType}s/{$model->public_id}/edit", $model->invoice_number, ['class' => Utils::getEntityRowClass($model)])->toHtml();
+ return $this->addNote($str, $model->private_notes);
},
],
[
diff --git a/app/Ninja/Datatables/PaymentDatatable.php b/app/Ninja/Datatables/PaymentDatatable.php
index 17d2605359a8..435b610f92c7 100644
--- a/app/Ninja/Datatables/PaymentDatatable.php
+++ b/app/Ninja/Datatables/PaymentDatatable.php
@@ -46,7 +46,8 @@ class PaymentDatatable extends EntityDatatable
[
'transaction_reference',
function ($model) {
- return $model->transaction_reference ? e($model->transaction_reference) : ''.trans('texts.manual_entry').'';
+ $str = $model->transaction_reference ? e($model->transaction_reference) : ''.trans('texts.manual_entry').'';
+ return $this->addNote($str, $model->private_notes);
},
],
[
diff --git a/app/Ninja/Datatables/RecurringExpenseDatatable.php b/app/Ninja/Datatables/RecurringExpenseDatatable.php
index 4ecafef47459..e8a1311595d2 100644
--- a/app/Ninja/Datatables/RecurringExpenseDatatable.php
+++ b/app/Ninja/Datatables/RecurringExpenseDatatable.php
@@ -57,6 +57,16 @@ class RecurringExpenseDatatable extends EntityDatatable
},
],
*/
+ [
+ 'frequency',
+ function ($model) {
+ $frequency = strtolower($model->frequency);
+ $frequency = preg_replace('/\s/', '_', $frequency);
+
+ $str = link_to("recurring_expenses/{$model->public_id}/edit", trans('texts.freq_'.$frequency))->toHtml();
+ return $this->addNote($str, $model->private_notes);
+ },
+ ],
[
'amount',
function ($model) {
@@ -91,15 +101,6 @@ class RecurringExpenseDatatable extends EntityDatatable
return $model->public_notes != null ? substr($model->public_notes, 0, 100) : '';
},
],
- [
- 'frequency',
- function ($model) {
- $frequency = strtolower($model->frequency);
- $frequency = preg_replace('/\s/', '_', $frequency);
-
- return link_to("recurring_expenses/{$model->public_id}/edit", trans('texts.freq_'.$frequency))->toHtml();
- },
- ],
];
}
diff --git a/app/Ninja/Datatables/VendorDatatable.php b/app/Ninja/Datatables/VendorDatatable.php
index 761d12ebccf9..df5415df01b2 100644
--- a/app/Ninja/Datatables/VendorDatatable.php
+++ b/app/Ninja/Datatables/VendorDatatable.php
@@ -17,7 +17,8 @@ class VendorDatatable extends EntityDatatable
[
'name',
function ($model) {
- return link_to("vendors/{$model->public_id}", $model->name ?: '')->toHtml();
+ $str = link_to("vendors/{$model->public_id}", $model->name ?: '')->toHtml();
+ return $this->addNote($str, $model->private_notes);
},
],
[
diff --git a/app/Ninja/PaymentDrivers/AuthorizeNetAIMPaymentDriver.php b/app/Ninja/PaymentDrivers/AuthorizeNetAIMPaymentDriver.php
index 9bec8c2426bb..b697af1bcc4a 100644
--- a/app/Ninja/PaymentDrivers/AuthorizeNetAIMPaymentDriver.php
+++ b/app/Ninja/PaymentDrivers/AuthorizeNetAIMPaymentDriver.php
@@ -5,4 +5,12 @@ namespace App\Ninja\PaymentDrivers;
class AuthorizeNetAIMPaymentDriver extends BasePaymentDriver
{
protected $transactionReferenceParam = 'refId';
+
+ protected function paymentDetails($paymentMethod = false)
+ {
+ $data = parent::paymentDetails();
+ $data['solutionId'] = $this->accountGateway->getConfigField('testMode') ? 'AAA100303' : 'AAA172036';
+
+ return $data;
+ }
}
diff --git a/app/Ninja/PaymentDrivers/PagSeguroPaymentDriver.php b/app/Ninja/PaymentDrivers/PagSeguroPaymentDriver.php
new file mode 100644
index 000000000000..a76bc927ebec
--- /dev/null
+++ b/app/Ninja/PaymentDrivers/PagSeguroPaymentDriver.php
@@ -0,0 +1,17 @@
+invoice()->invoice_number;
+
+ return $data;
+ }
+
+
+}
diff --git a/app/Ninja/PaymentDrivers/PagarmePaymentDriver.php b/app/Ninja/PaymentDrivers/PagarmePaymentDriver.php
new file mode 100644
index 000000000000..385a5ebfe289
--- /dev/null
+++ b/app/Ninja/PaymentDrivers/PagarmePaymentDriver.php
@@ -0,0 +1,8 @@
+{$label}";
}
+ public function statusColor()
+ {
+ $class = $this->entity->statusClass();
+
+ switch ($class) {
+ case 'success':
+ return '#5cb85c';
+ case 'warning':
+ return '#f0ad4e';
+ case 'primary':
+ return '#337ab7';
+ case 'info':
+ return '#5bc0de';
+ default:
+ return '#777';
+ }
+ }
+
/**
* @return mixed
*/
@@ -67,4 +86,17 @@ class EntityPresenter extends Presenter
return sprintf('%s: %s', trans('texts.' . $entityType), $entity->getDisplayName());
}
+
+ public function calendarEvent($subColors = false)
+ {
+ $entity = $this->entity;
+
+ $data = new stdClass();
+ $data->id = $entity->getEntityType() . ':' . $entity->public_id;
+ $data->allDay = true;
+ $data->url = $this->url();
+
+ return $data;
+ }
+
}
diff --git a/app/Ninja/Presenters/ExpensePresenter.php b/app/Ninja/Presenters/ExpensePresenter.php
index 100a0de8cded..fda0104bf3c7 100644
--- a/app/Ninja/Presenters/ExpensePresenter.php
+++ b/app/Ninja/Presenters/ExpensePresenter.php
@@ -48,4 +48,31 @@ class ExpensePresenter extends EntityPresenter
{
return $this->entity->expense_category ? $this->entity->expense_category->name : '';
}
+
+ public function calendarEvent($subColors = false)
+ {
+ $data = parent::calendarEvent();
+ $expense = $this->entity;
+
+ $data->title = trans('texts.expense') . ' ' . $this->amount() . ' | ' . $this->category();
+
+ $data->title = trans('texts.expense') . ' ' . $this->amount();
+ if ($category = $this->category()) {
+ $data->title .= ' | ' . $category;
+ }
+ if ($this->public_notes) {
+ $data->title .= ' | ' . $this->public_notes;
+ }
+
+
+ $data->start = $expense->expense_date;
+
+ if ($subColors && $expense->expense_category_id) {
+ $data->borderColor = $data->backgroundColor = Utils::brewerColor($expense->expense_category->public_id);
+ } else {
+ $data->borderColor = $data->backgroundColor = '#d95d02';
+ }
+
+ return $data;
+ }
}
diff --git a/app/Ninja/Presenters/InvoicePresenter.php b/app/Ninja/Presenters/InvoicePresenter.php
index 3ffd3430342e..5668b9d9553c 100644
--- a/app/Ninja/Presenters/InvoicePresenter.php
+++ b/app/Ninja/Presenters/InvoicePresenter.php
@@ -323,4 +323,22 @@ class InvoicePresenter extends EntityPresenter
return $link;
}
+
+ public function calendarEvent($subColors = false)
+ {
+ $data = parent::calendarEvent();
+ $invoice = $this->entity;
+ $entityType = $invoice->getEntityType();
+
+ $data->title = trans("texts.{$entityType}") . ' ' . $invoice->invoice_number . ' | ' . $this->amount() . ' | ' . $this->client();
+ $data->start = $invoice->due_date ?: $invoice->invoice_date;
+
+ if ($subColors) {
+ $data->borderColor = $data->backgroundColor = $invoice->present()->statusColor();
+ } else {
+ $data->borderColor = $data->backgroundColor = $invoice->isQuote() ? '#716cb1' : '#377eb8';
+ }
+
+ return $data;
+ }
}
diff --git a/app/Ninja/Presenters/PaymentPresenter.php b/app/Ninja/Presenters/PaymentPresenter.php
index a2c15c478ce5..97505a7c2186 100644
--- a/app/Ninja/Presenters/PaymentPresenter.php
+++ b/app/Ninja/Presenters/PaymentPresenter.php
@@ -45,4 +45,22 @@ class PaymentPresenter extends EntityPresenter
return trans('texts.payment_type_' . $this->entity->payment_type->name);
}
}
+
+ public function calendarEvent($subColors = false)
+ {
+ $data = parent::calendarEvent();
+ $payment = $this->entity;
+ $invoice = $payment->invoice;
+
+ $data->title = trans('texts.payment') . ' ' . $invoice->invoice_number . ' | ' . $this->completedAmount() . ' | ' . $this->client();
+ $data->start = $payment->payment_date;
+
+ if ($subColors) {
+ $data->borderColor = $data->backgroundColor = Utils::brewerColor($payment->payment_status_id);
+ } else {
+ $data->borderColor = $data->backgroundColor = '#5fa213';
+ }
+
+ return $data;
+ }
}
diff --git a/app/Ninja/Presenters/TaskPresenter.php b/app/Ninja/Presenters/TaskPresenter.php
index a69b2de55942..93aa7c3f6ff2 100644
--- a/app/Ninja/Presenters/TaskPresenter.php
+++ b/app/Ninja/Presenters/TaskPresenter.php
@@ -2,6 +2,8 @@
namespace App\Ninja\Presenters;
+use Utils;
+
/**
* Class TaskPresenter.
*/
@@ -70,4 +72,42 @@ class TaskPresenter extends EntityPresenter
return $str . implode("\n", $times);
}
+
+ public function calendarEvent($subColors = false)
+ {
+ $data = parent::calendarEvent();
+ $task = $this->entity;
+ $account = $task->account;
+ $date = $account->getDateTime();
+
+ $data->title = trans('texts.task');
+ if ($project = $this->project()) {
+ $data->title .= ' | ' . $project;
+ }
+ if ($description = $this->description()) {
+ $data->title .= ' | ' . $description;
+ }
+ $data->allDay = false;
+
+ if ($subColors && $task->project_id) {
+ $data->borderColor = $data->backgroundColor = Utils::brewerColor($task->project->public_id);
+ } else {
+ $data->borderColor = $data->backgroundColor = '#a87821';
+ }
+
+ $parts = json_decode($task->time_log) ?: [];
+ if (count($parts)) {
+ $first = $parts[0];
+ $start = $first[0];
+ $date->setTimestamp($start);
+ $data->start = $date->format('Y-m-d H:i:m');
+
+ $last = $parts[count($parts) - 1];
+ $end = count($last) == 2 ? $last[1] : $last[0];
+ $date->setTimestamp($end);
+ $data->end = $date->format('Y-m-d H:i:m');
+ }
+
+ return $data;
+ }
}
diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php
index 092493794f01..b4fde7c1d4e9 100644
--- a/app/Ninja/Repositories/AccountRepository.php
+++ b/app/Ninja/Repositories/AccountRepository.php
@@ -210,6 +210,7 @@ class AccountRepository
$features = array_merge($features, [
['dashboard', '/dashboard'],
['reports', '/reports'],
+ ['calendar', '/calendar'],
['customize_design', '/settings/customize_design'],
['new_tax_rate', '/tax_rates/create'],
['new_product', '/products/create'],
diff --git a/app/Ninja/Repositories/ClientRepository.php b/app/Ninja/Repositories/ClientRepository.php
index 8ee2e5a90375..316bc898458f 100644
--- a/app/Ninja/Repositories/ClientRepository.php
+++ b/app/Ninja/Repositories/ClientRepository.php
@@ -41,6 +41,7 @@ class ClientRepository extends BaseRepository
DB::raw("CONCAT(contacts.first_name, ' ', contacts.last_name) contact"),
'clients.public_id',
'clients.name',
+ 'clients.private_notes',
'contacts.first_name',
'contacts.last_name',
'clients.balance',
diff --git a/app/Ninja/Repositories/ExpenseRepository.php b/app/Ninja/Repositories/ExpenseRepository.php
index 867c0af93635..dfda1ee70a31 100644
--- a/app/Ninja/Repositories/ExpenseRepository.php
+++ b/app/Ninja/Repositories/ExpenseRepository.php
@@ -81,6 +81,7 @@ class ExpenseRepository extends BaseRepository
'expenses.user_id',
'expenses.tax_rate1',
'expenses.tax_rate2',
+ 'expenses.private_notes',
'expenses.payment_date',
'expense_categories.name as category',
'expense_categories.user_id as category_user_id',
diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php
index 0ec7491ea7a7..408d8cc73b8c 100644
--- a/app/Ninja/Repositories/InvoiceRepository.php
+++ b/app/Ninja/Repositories/InvoiceRepository.php
@@ -89,7 +89,8 @@ class InvoiceRepository extends BaseRepository
'invoices.partial',
'invoices.user_id',
'invoices.is_public',
- 'invoices.is_recurring'
+ 'invoices.is_recurring',
+ 'invoices.private_notes'
);
$this->applyFilters($query, $entityType, ENTITY_INVOICE);
diff --git a/app/Ninja/Repositories/PaymentRepository.php b/app/Ninja/Repositories/PaymentRepository.php
index 34d6555c8923..1cb48cb64819 100644
--- a/app/Ninja/Repositories/PaymentRepository.php
+++ b/app/Ninja/Repositories/PaymentRepository.php
@@ -63,6 +63,7 @@ class PaymentRepository extends BaseRepository
'payments.email',
'payments.routing_number',
'payments.bank_name',
+ 'payments.private_notes',
'invoices.is_deleted as invoice_is_deleted',
'gateways.name as gateway_name',
'gateways.id as gateway_id',
diff --git a/app/Ninja/Repositories/RecurringExpenseRepository.php b/app/Ninja/Repositories/RecurringExpenseRepository.php
index 9eb121ed2a4a..3b5050dfb602 100644
--- a/app/Ninja/Repositories/RecurringExpenseRepository.php
+++ b/app/Ninja/Repositories/RecurringExpenseRepository.php
@@ -60,6 +60,7 @@ class RecurringExpenseRepository extends BaseRepository
'recurring_expenses.user_id',
'recurring_expenses.tax_rate1',
'recurring_expenses.tax_rate2',
+ 'recurring_expenses.private_notes',
'frequencies.name as frequency',
'expense_categories.name as category',
'expense_categories.user_id as category_user_id',
diff --git a/app/Ninja/Repositories/TaskRepository.php b/app/Ninja/Repositories/TaskRepository.php
index a0b66d5bab46..327164741e30 100644
--- a/app/Ninja/Repositories/TaskRepository.php
+++ b/app/Ninja/Repositories/TaskRepository.php
@@ -117,7 +117,10 @@ class TaskRepository extends BaseRepository
if (isset($data['client'])) {
$task->client_id = $data['client'] ? Client::getPrivateId($data['client']) : null;
+ } elseif (isset($data['client_id'])) {
+ $task->client_id = $data['client_id'] ? Client::getPrivateId($data['client_id']) : null;
}
+
if (isset($data['project_id'])) {
$task->project_id = $data['project_id'] ? Project::getPrivateId($data['project_id']) : null;
}
@@ -134,10 +137,6 @@ class TaskRepository extends BaseRepository
$timeLog = [];
}
- if(isset($data['client_id'])) {
- $task->client_id = Client::getPrivateId($data['client_id']);
- }
-
array_multisort($timeLog);
if (isset($data['action'])) {
@@ -153,6 +152,8 @@ class TaskRepository extends BaseRepository
} elseif ($data['action'] == 'offline'){
$task->is_running = $data['is_running'] ? 1 : 0;
}
+ } elseif (isset($data['is_running'])) {
+ $task->is_running = $data['is_running'] ? 1 : 0;
}
$task->time_log = json_encode($timeLog);
diff --git a/app/Ninja/Repositories/VendorRepository.php b/app/Ninja/Repositories/VendorRepository.php
index 765e9b9f3cd4..fe44f61ea0ff 100644
--- a/app/Ninja/Repositories/VendorRepository.php
+++ b/app/Ninja/Repositories/VendorRepository.php
@@ -44,7 +44,8 @@ class VendorRepository extends BaseRepository
'vendor_contacts.email',
'vendors.deleted_at',
'vendors.is_deleted',
- 'vendors.user_id'
+ 'vendors.user_id',
+ 'vendors.private_notes'
);
$this->applyFilters($query, ENTITY_VENDOR);
diff --git a/bower.json b/bower.json
index d0fc82a59a34..118c4b884b93 100644
--- a/bower.json
+++ b/bower.json
@@ -35,7 +35,10 @@
"select2": "select2-dist#^4.0.3",
"mousetrap": "^1.6.0",
"tablesorter": "jquery.tablesorter#^2.28.4",
- "card": "^2.1.1"
+ "card": "^2.1.1",
+ "fullcalendar": "^3.5.1",
+ "toastr": "^2.1.3",
+ "jt.timepicker": "jquery-timepicker-jt#^1.11.12"
},
"resolutions": {
"jquery": "~1.11"
diff --git a/composer.json b/composer.json
index 7587d6b8d49e..d9a1b4575e2e 100644
--- a/composer.json
+++ b/composer.json
@@ -86,8 +86,10 @@
"webpatser/laravel-countries": "dev-master",
"websight/l5-google-cloud-storage": "dev-master",
"wepay/php-sdk": "^0.2",
- "wildbit/laravel-postmark-provider": "3.0"
- },
+ "wildbit/laravel-postmark-provider": "3.0",
+ "abdala/omnipay-pagseguro": "0.2",
+ "omnipay/authorizenet": "dev-solution-id as 2.5.0"
+ },
"require-dev": {
"codeception/c3": "~2.0",
"codeception/codeception": "2.3.3",
@@ -166,6 +168,10 @@
{
"type": "vcs",
"url": "https://github.com/hillelcoren/omnipay-gocardlessv2"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hillelcoren/omnipay-authorizenet"
}
]
}
diff --git a/composer.lock b/composer.lock
index a116a5721b0e..6281ae77205e 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,9 +4,59 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "a39a505121abab0985f7c0cb1734920c",
- "content-hash": "4067bb1f3c6d2b3397e3a005b642ddb6",
+ "hash": "17538bc11db205b06d6656224af6956a",
+ "content-hash": "eb01266703f4233d8fa703516a43bba8",
"packages": [
+ {
+ "name": "abdala/omnipay-pagseguro",
+ "version": "0.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/abdala/omnipay-pagseguro.git",
+ "reference": "da53d77eccc4c0c4e24d6df825cbae4e0944f9dc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/abdala/omnipay-pagseguro/zipball/da53d77eccc4c0c4e24d6df825cbae4e0944f9dc",
+ "reference": "da53d77eccc4c0c4e24d6df825cbae4e0944f9dc",
+ "shasum": ""
+ },
+ "require": {
+ "omnipay/common": "~2.0"
+ },
+ "require-dev": {
+ "omnipay/tests": "~2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Omnipay\\PagSeguro\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Abdala Cerqueira",
+ "email": "abdala.cerqueira@gmail.com"
+ }
+ ],
+ "description": "PagSeguro gateway for OmniPay",
+ "homepage": "https://github.com/abdala/omnipay-pagseguro",
+ "keywords": [
+ "PHPeste",
+ "Pagseguro",
+ "gateway",
+ "merchant",
+ "mp",
+ "omnipay",
+ "pay",
+ "payment"
+ ],
+ "time": "2017-02-03 14:11:08"
+ },
{
"name": "agmscode/omnipay-agms",
"version": "1.0.0",
@@ -69,12 +119,12 @@
"source": {
"type": "git",
"url": "https://github.com/xcaliber-tech/omnipay-skrill.git",
- "reference": "e8f3f76103e1f311b4d922c9b0b14689aa7938b4"
+ "reference": "f90a185b5e26fb5b4150d664f01ad8048b460bcf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/xcaliber-tech/omnipay-skrill/zipball/e8f3f76103e1f311b4d922c9b0b14689aa7938b4",
- "reference": "e8f3f76103e1f311b4d922c9b0b14689aa7938b4",
+ "url": "https://api.github.com/repos/xcaliber-tech/omnipay-skrill/zipball/f90a185b5e26fb5b4150d664f01ad8048b460bcf",
+ "reference": "f90a185b5e26fb5b4150d664f01ad8048b460bcf",
"shasum": ""
},
"require": {
@@ -115,7 +165,7 @@
"payment",
"skrill"
],
- "time": "2017-07-24 10:13:29"
+ "time": "2017-08-23 08:56:17"
},
{
"name": "anahkiasen/former",
@@ -330,19 +380,23 @@
},
{
"name": "aws/aws-sdk-php",
- "version": "3.33.3",
+ "version": "3.36.19",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
- "reference": "2820644f411fa261f126727c1c00de15227b9520"
+ "reference": "bed7567b2ed8e70fbf5e1ecf927100e91955b29a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2820644f411fa261f126727c1c00de15227b9520",
- "reference": "2820644f411fa261f126727c1c00de15227b9520",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/bed7567b2ed8e70fbf5e1ecf927100e91955b29a",
+ "reference": "bed7567b2ed8e70fbf5e1ecf927100e91955b29a",
"shasum": ""
},
"require": {
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-simplexml": "*",
+ "ext-spl": "*",
"guzzlehttp/guzzle": "^5.3.1|^6.2.1",
"guzzlehttp/promises": "~1.0",
"guzzlehttp/psr7": "^1.4.1",
@@ -355,11 +409,7 @@
"behat/behat": "~3.0",
"doctrine/cache": "~1.4",
"ext-dom": "*",
- "ext-json": "*",
"ext-openssl": "*",
- "ext-pcre": "*",
- "ext-simplexml": "*",
- "ext-spl": "*",
"nette/neon": "^2.3",
"phpunit/phpunit": "^4.8.35|^5.4.0",
"psr/cache": "^1.0"
@@ -406,7 +456,7 @@
"s3",
"sdk"
],
- "time": "2017-08-18 18:04:40"
+ "time": "2017-10-03 15:53:57"
},
{
"name": "barracudanetworks/archivestream-php",
@@ -679,16 +729,16 @@
},
{
"name": "braintree/braintree_php",
- "version": "3.24.0",
+ "version": "3.25.0",
"source": {
"type": "git",
"url": "https://github.com/braintree/braintree_php.git",
- "reference": "c0e856104f95a75c08db4af5b5ace8fe0e80e573"
+ "reference": "8c8785b8876d5b2f4b4f78c5768ad245a7c43feb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/braintree/braintree_php/zipball/c0e856104f95a75c08db4af5b5ace8fe0e80e573",
- "reference": "c0e856104f95a75c08db4af5b5ace8fe0e80e573",
+ "url": "https://api.github.com/repos/braintree/braintree_php/zipball/8c8785b8876d5b2f4b4f78c5768ad245a7c43feb",
+ "reference": "8c8785b8876d5b2f4b4f78c5768ad245a7c43feb",
"shasum": ""
},
"require": {
@@ -722,7 +772,7 @@
}
],
"description": "Braintree PHP Client Library",
- "time": "2017-08-10 16:54:00"
+ "time": "2017-08-25 19:38:09"
},
{
"name": "cardgate/omnipay-cardgate",
@@ -830,16 +880,16 @@
},
{
"name": "cerdic/css-tidy",
- "version": "v1.5.5",
+ "version": "v1.5.6",
"source": {
"type": "git",
"url": "https://github.com/Cerdic/CSSTidy.git",
- "reference": "b0c1bda3be5a35da44ba1ac28cc61c67d2ada465"
+ "reference": "d4443352da925610919f1b49c5f6bb68216b6b60"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Cerdic/CSSTidy/zipball/b0c1bda3be5a35da44ba1ac28cc61c67d2ada465",
- "reference": "b0c1bda3be5a35da44ba1ac28cc61c67d2ada465",
+ "url": "https://api.github.com/repos/Cerdic/CSSTidy/zipball/d4443352da925610919f1b49c5f6bb68216b6b60",
+ "reference": "d4443352da925610919f1b49c5f6bb68216b6b60",
"shasum": ""
},
"type": "library",
@@ -859,7 +909,7 @@
}
],
"description": "CSSTidy is a CSS minifier",
- "time": "2015-11-28 21:47:43"
+ "time": "2017-09-29 14:18:45"
},
{
"name": "chumper/datatable",
@@ -1269,12 +1319,12 @@
"source": {
"type": "git",
"url": "https://github.com/descubraomundo/omnipay-pagarme.git",
- "reference": "8571396139eb1fb1a7011450714a5e8d8d604d8c"
+ "reference": "99e92dffd1640bdaf736560e26ec244326a3dd4a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/descubraomundo/omnipay-pagarme/zipball/8571396139eb1fb1a7011450714a5e8d8d604d8c",
- "reference": "8571396139eb1fb1a7011450714a5e8d8d604d8c",
+ "url": "https://api.github.com/repos/descubraomundo/omnipay-pagarme/zipball/99e92dffd1640bdaf736560e26ec244326a3dd4a",
+ "reference": "99e92dffd1640bdaf736560e26ec244326a3dd4a",
"shasum": ""
},
"require": {
@@ -1311,7 +1361,7 @@
"pay",
"payment"
],
- "time": "2016-03-18 19:37:37"
+ "time": "2017-09-15 17:25:40"
},
{
"name": "digitickets/omnipay-barclays-epdq",
@@ -2266,16 +2316,16 @@
},
{
"name": "fotografde/omnipay-checkoutcom",
- "version": "2.0",
+ "version": "2.1.1",
"source": {
"type": "git",
"url": "https://github.com/fotografde/omnipay-checkoutcom.git",
- "reference": "b17eae9cd2e9786345c03ed48abec30befbf4edd"
+ "reference": "292de331d9f0cf185f7d58a77caef4d2d53d7935"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fotografde/omnipay-checkoutcom/zipball/b17eae9cd2e9786345c03ed48abec30befbf4edd",
- "reference": "b17eae9cd2e9786345c03ed48abec30befbf4edd",
+ "url": "https://api.github.com/repos/fotografde/omnipay-checkoutcom/zipball/292de331d9f0cf185f7d58a77caef4d2d53d7935",
+ "reference": "292de331d9f0cf185f7d58a77caef4d2d53d7935",
"shasum": ""
},
"require": {
@@ -2315,7 +2365,7 @@
"pay",
"payment"
],
- "time": "2015-08-06 09:26:34"
+ "time": "2017-09-12 15:25:57"
},
{
"name": "fruitcakestudio/omnipay-sisow",
@@ -2442,16 +2492,16 @@
},
{
"name": "gocardless/gocardless-pro",
- "version": "1.1.0",
+ "version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/gocardless/gocardless-pro-php.git",
- "reference": "48ae4c194e4735007de58b67176a9cb6548e83d5"
+ "reference": "d2d4adb7cde53722858f1e7e5508697fefdb5390"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/gocardless/gocardless-pro-php/zipball/48ae4c194e4735007de58b67176a9cb6548e83d5",
- "reference": "48ae4c194e4735007de58b67176a9cb6548e83d5",
+ "url": "https://api.github.com/repos/gocardless/gocardless-pro-php/zipball/d2d4adb7cde53722858f1e7e5508697fefdb5390",
+ "reference": "d2d4adb7cde53722858f1e7e5508697fefdb5390",
"shasum": ""
},
"require": {
@@ -2490,7 +2540,7 @@
"direct debit",
"gocardless"
],
- "time": "2017-05-19 13:01:53"
+ "time": "2017-09-18 15:08:13"
},
{
"name": "google/apiclient",
@@ -2553,16 +2603,16 @@
},
{
"name": "google/apiclient-services",
- "version": "v0.20",
+ "version": "v0.28",
"source": {
"type": "git",
"url": "https://github.com/google/google-api-php-client-services.git",
- "reference": "c1a6e6ac716c6563ca6c240120cde69fde49af4f"
+ "reference": "209421578d76762806087944cf514f1ede6cf7ad"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/google/google-api-php-client-services/zipball/c1a6e6ac716c6563ca6c240120cde69fde49af4f",
- "reference": "c1a6e6ac716c6563ca6c240120cde69fde49af4f",
+ "url": "https://api.github.com/repos/google/google-api-php-client-services/zipball/209421578d76762806087944cf514f1ede6cf7ad",
+ "reference": "209421578d76762806087944cf514f1ede6cf7ad",
"shasum": ""
},
"require": {
@@ -2586,7 +2636,7 @@
"keywords": [
"google"
],
- "time": "2017-08-20 00:20:36"
+ "time": "2017-09-30 00:22:48"
},
{
"name": "google/auth",
@@ -2638,20 +2688,22 @@
},
{
"name": "google/cloud",
- "version": "v0.36.0",
+ "version": "v0.39.2",
"source": {
"type": "git",
"url": "https://github.com/GoogleCloudPlatform/google-cloud-php.git",
- "reference": "eebf5291ab903647c7e8422f1b2361355db66b59"
+ "reference": "2ae1022a000624d3aaa98d9c184d0177363840c1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GoogleCloudPlatform/google-cloud-php/zipball/eebf5291ab903647c7e8422f1b2361355db66b59",
- "reference": "eebf5291ab903647c7e8422f1b2361355db66b59",
+ "url": "https://api.github.com/repos/GoogleCloudPlatform/google-cloud-php/zipball/2ae1022a000624d3aaa98d9c184d0177363840c1",
+ "reference": "2ae1022a000624d3aaa98d9c184d0177363840c1",
"shasum": ""
},
"require": {
"google/auth": "~0.9|^1.0",
+ "google/gax": "^0.23",
+ "google/proto-client": "^0.23",
"guzzlehttp/guzzle": "^5.3|^6.0",
"guzzlehttp/psr7": "^1.2",
"monolog/monolog": "~1",
@@ -2661,26 +2713,25 @@
"rize/uri-template": "~0.3"
},
"replace": {
- "google/cloud-bigquery": "0.2.2",
- "google/cloud-core": "1.8.0",
- "google/cloud-datastore": "1.0.0",
- "google/cloud-error-reporting": "0.4.1",
- "google/cloud-language": "0.4.0",
- "google/cloud-logging": "1.3.1",
- "google/cloud-monitoring": "0.4.1",
- "google/cloud-pubsub": "0.6.1",
- "google/cloud-spanner": "0.4.0",
- "google/cloud-speech": "0.6.1",
- "google/cloud-storage": "1.1.3",
- "google/cloud-trace": "0.3.1",
- "google/cloud-translate": "1.0.0",
- "google/cloud-videointelligence": "0.3.1",
- "google/cloud-vision": "0.4.0"
+ "google/cloud-bigquery": "0.2.4",
+ "google/cloud-core": "1.9.0",
+ "google/cloud-datastore": "1.0.1",
+ "google/cloud-dlp": "0.1.2",
+ "google/cloud-error-reporting": "0.4.3",
+ "google/cloud-language": "0.5.0",
+ "google/cloud-logging": "1.4.0",
+ "google/cloud-monitoring": "0.4.3",
+ "google/cloud-pubsub": "0.7.0",
+ "google/cloud-spanner": "0.6.0",
+ "google/cloud-speech": "0.7.0",
+ "google/cloud-storage": "1.1.5",
+ "google/cloud-trace": "0.3.2",
+ "google/cloud-translate": "1.0.1",
+ "google/cloud-videointelligence": "0.4.0",
+ "google/cloud-vision": "0.4.1"
},
"require-dev": {
"erusev/parsedown": "^1.6",
- "google/gax": "^0.21.0",
- "google/proto-client": "^0.21.0",
"league/json-guard": "^0.3",
"phpdocumentor/reflection": "^3.0",
"phpseclib/phpseclib": "^2",
@@ -2691,8 +2742,6 @@
"vierbergenlars/php-semver": "^3.0"
},
"suggest": {
- "google/gax": "Required to support gRPC",
- "google/proto-client": "Required to support gRPC",
"phpseclib/phpseclib": "May be used in place of OpenSSL for creating signed Cloud Storage URLs. Please require version ^2."
},
"bin": [
@@ -2704,7 +2753,10 @@
"id": "google-cloud",
"target": "git@github.com:jdpedrie-gcp/google-cloud-php.git",
"path": "src",
- "entry": "ServiceBuilder.php"
+ "entry": [
+ "Version.php",
+ "ServiceBuilder.php"
+ ]
}
},
"autoload": {
@@ -2753,7 +2805,173 @@
"translation",
"vision"
],
- "time": "2017-08-02 20:02:30"
+ "time": "2017-09-18 15:09:56"
+ },
+ {
+ "name": "google/gax",
+ "version": "0.23.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/googleapis/gax-php.git",
+ "reference": "e09f219ed50ea1f6162d1945156d2ea6af6cd1f9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/googleapis/gax-php/zipball/e09f219ed50ea1f6162d1945156d2ea6af6cd1f9",
+ "reference": "e09f219ed50ea1f6162d1945156d2ea6af6cd1f9",
+ "shasum": ""
+ },
+ "require": {
+ "google/auth": "~0.9|^1.0",
+ "google/protobuf": "^3.4",
+ "grpc/grpc": "^1.4",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.8.*",
+ "squizlabs/php_codesniffer": "2.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Google\\GAX\\": "src/",
+ "Google\\GAX\\UnitTests\\": "tests/",
+ "Google\\": "src/generated/Google/",
+ "GPBMetadata\\": "src/generated/GPBMetadata/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "Google API Extensions for PHP",
+ "homepage": "https://github.com/googleapis/gax-php",
+ "keywords": [
+ "google"
+ ],
+ "time": "2017-08-31 21:40:57"
+ },
+ {
+ "name": "google/proto-client",
+ "version": "0.23.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/googleapis/proto-client-php.git",
+ "reference": "b159f408b6acdba55bf727c3639d03bb0117fc27"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/googleapis/proto-client-php/zipball/b159f408b6acdba55bf727c3639d03bb0117fc27",
+ "reference": "b159f408b6acdba55bf727c3639d03bb0117fc27",
+ "shasum": ""
+ },
+ "require": {
+ "google/protobuf": "^3.3.2",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "google/gax": ">=0.20.0",
+ "phpunit/phpunit": "4.8.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Google\\": "src/Google/",
+ "GPBMetadata\\": "src/GPBMetadata/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "Generated proto and gRPC classes for Google Cloud Platform in PHP",
+ "homepage": "https://github.com/googleapis/proto-client-php",
+ "keywords": [
+ "google"
+ ],
+ "time": "2017-09-01 22:33:04"
+ },
+ {
+ "name": "google/protobuf",
+ "version": "v3.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/google/protobuf.git",
+ "reference": "b04e5cba356212e4e8c66c61bbe0c3a20537c5b9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/google/protobuf/zipball/b04e5cba356212e4e8c66c61bbe0c3a20537c5b9",
+ "reference": "b04e5cba356212e4e8c66c61bbe0c3a20537c5b9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": ">=4.8.0"
+ },
+ "suggest": {
+ "ext-bcmath": "Need to support JSON deserialization"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Google\\Protobuf\\": "php/src/Google/Protobuf",
+ "GPBMetadata\\Google\\Protobuf\\": "php/src/GPBMetadata/Google/Protobuf"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "proto library for PHP",
+ "homepage": "https://developers.google.com/protocol-buffers/",
+ "keywords": [
+ "proto"
+ ],
+ "time": "2017-09-14 19:24:28"
+ },
+ {
+ "name": "grpc/grpc",
+ "version": "1.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/grpc/grpc-php.git",
+ "reference": "8d190d91ddb9d980f685d9caf79bca62d7edc1e6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/grpc/grpc-php/zipball/8d190d91ddb9d980f685d9caf79bca62d7edc1e6",
+ "reference": "8d190d91ddb9d980f685d9caf79bca62d7edc1e6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "google/auth": "v0.9"
+ },
+ "suggest": {
+ "ext-protobuf": "For better performance, install the protobuf C extension.",
+ "google/protobuf": "To get started using grpc quickly, install the native protobuf library."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Grpc\\": "src/lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "description": "gRPC library for PHP",
+ "homepage": "https://grpc.io",
+ "keywords": [
+ "rpc"
+ ],
+ "time": "2017-09-11 20:50:39"
},
{
"name": "guzzle/guzzle",
@@ -3140,12 +3358,12 @@
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
- "reference": "4581c28cdcb6067dca2b27ea8b76842ca79ddf90"
+ "reference": "a54d1e9e6af2815c5ec24972d1d9209c677ce452"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Intervention/image/zipball/4581c28cdcb6067dca2b27ea8b76842ca79ddf90",
- "reference": "4581c28cdcb6067dca2b27ea8b76842ca79ddf90",
+ "url": "https://api.github.com/repos/Intervention/image/zipball/a54d1e9e6af2815c5ec24972d1d9209c677ce452",
+ "reference": "a54d1e9e6af2815c5ec24972d1d9209c677ce452",
"shasum": ""
},
"require": {
@@ -3202,7 +3420,7 @@
"thumbnail",
"watermark"
],
- "time": "2017-07-04 16:10:28"
+ "time": "2017-09-21 16:33:42"
},
{
"name": "ircmaxell/password-compat",
@@ -3376,16 +3594,16 @@
},
{
"name": "jaybizzle/crawler-detect",
- "version": "v1.2.51",
+ "version": "v1.2.52",
"source": {
"type": "git",
"url": "https://github.com/JayBizzle/Crawler-Detect.git",
- "reference": "be9074b1206ba7b5ac5662f900295edc088a9da8"
+ "reference": "bd6f1eef08645f1fe2fe79fb58d745e17670c3eb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/be9074b1206ba7b5ac5662f900295edc088a9da8",
- "reference": "be9074b1206ba7b5ac5662f900295edc088a9da8",
+ "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/bd6f1eef08645f1fe2fe79fb58d745e17670c3eb",
+ "reference": "bd6f1eef08645f1fe2fe79fb58d745e17670c3eb",
"shasum": ""
},
"require": {
@@ -3421,7 +3639,7 @@
"crawlerdetect",
"php crawler detect"
],
- "time": "2017-08-07 18:48:00"
+ "time": "2017-09-07 08:18:18"
},
{
"name": "jaybizzle/laravel-crawler-detect",
@@ -4439,23 +4657,23 @@
},
{
"name": "maatwebsite/excel",
- "version": "2.1.20",
+ "version": "2.1.23",
"source": {
"type": "git",
"url": "https://github.com/Maatwebsite/Laravel-Excel.git",
- "reference": "a8baf7de1030d261318f90fa5c273a47ef616b59"
+ "reference": "8682c955601b6de15a8c7d6e373b927cc8380627"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/a8baf7de1030d261318f90fa5c273a47ef616b59",
- "reference": "a8baf7de1030d261318f90fa5c273a47ef616b59",
+ "url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/8682c955601b6de15a8c7d6e373b927cc8380627",
+ "reference": "8682c955601b6de15a8c7d6e373b927cc8380627",
"shasum": ""
},
"require": {
- "illuminate/cache": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
- "illuminate/config": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
- "illuminate/filesystem": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
- "illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
+ "illuminate/cache": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
+ "illuminate/config": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
+ "illuminate/filesystem": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
+ "illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
"jeremeamia/superclosure": "^2.3",
"nesbot/carbon": "~1.0",
"php": ">=5.5",
@@ -4469,10 +4687,10 @@
"phpunit/phpunit": "~4.0"
},
"suggest": {
- "illuminate/http": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
- "illuminate/queue": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
- "illuminate/routing": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*",
- "illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*"
+ "illuminate/http": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
+ "illuminate/queue": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
+ "illuminate/routing": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
+ "illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*"
},
"type": "library",
"extra": {
@@ -4513,7 +4731,7 @@
"import",
"laravel"
],
- "time": "2017-07-26 18:04:04"
+ "time": "2017-09-19 19:36:48"
},
{
"name": "maximebf/debugbar",
@@ -5108,16 +5326,16 @@
},
{
"name": "nwidart/laravel-modules",
- "version": "1.27.1",
+ "version": "1.27.2",
"source": {
"type": "git",
"url": "https://github.com/nWidart/laravel-modules.git",
- "reference": "ca3a1b5bbd22d5e91c413fbf6a29e6ad18f58961"
+ "reference": "5f149198bd3d4cf9c9323a301d5b8b0aabc44591"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/ca3a1b5bbd22d5e91c413fbf6a29e6ad18f58961",
- "reference": "ca3a1b5bbd22d5e91c413fbf6a29e6ad18f58961",
+ "url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/5f149198bd3d4cf9c9323a301d5b8b0aabc44591",
+ "reference": "5f149198bd3d4cf9c9323a301d5b8b0aabc44591",
"shasum": ""
},
"require": {
@@ -5126,7 +5344,7 @@
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.4",
- "mockery/mockery": "~0.9",
+ "mockery/mockery": "~0.9.3",
"orchestra/testbench": "^3.1|^3.2|^3.3|^3.4",
"phpro/grumphp": "^0.11",
"phpunit/phpunit": "~5.7"
@@ -5170,7 +5388,7 @@
"nwidart",
"rad"
],
- "time": "2017-07-31 09:06:50"
+ "time": "2017-08-31 16:09:16"
},
{
"name": "omnipay/2checkout",
@@ -5233,16 +5451,16 @@
},
{
"name": "omnipay/authorizenet",
- "version": "2.5.0",
+ "version": "dev-solution-id",
"source": {
"type": "git",
- "url": "https://github.com/thephpleague/omnipay-authorizenet.git",
- "reference": "229bdb205384f2e3bf844cdf258927895b4858d5"
+ "url": "https://github.com/hillelcoren/omnipay-authorizenet.git",
+ "reference": "56e9f740c5f883208594861e1c3564f8ef686a95"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/omnipay-authorizenet/zipball/229bdb205384f2e3bf844cdf258927895b4858d5",
- "reference": "229bdb205384f2e3bf844cdf258927895b4858d5",
+ "url": "https://api.github.com/repos/hillelcoren/omnipay-authorizenet/zipball/56e9f740c5f883208594861e1c3564f8ef686a95",
+ "reference": "56e9f740c5f883208594861e1c3564f8ef686a95",
"shasum": ""
},
"require": {
@@ -5262,7 +5480,6 @@
"Omnipay\\AuthorizeNet\\": "src/"
}
},
- "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -5288,7 +5505,10 @@
"pay",
"payment"
],
- "time": "2017-03-07 14:00:14"
+ "support": {
+ "source": "https://github.com/hillelcoren/omnipay-authorizenet/tree/solution-id"
+ },
+ "time": "2017-10-04 09:53:32"
},
{
"name": "omnipay/bitpay",
@@ -6679,16 +6899,16 @@
},
{
"name": "omnipay/sagepay",
- "version": "2.4.0",
+ "version": "2.4.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-sagepay.git",
- "reference": "4ca4847935bc31dbcdd627e92377b5c3cf709e9b"
+ "reference": "8e14e235caf6530ee9afcbbb8cd6a54ad160a0f0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/omnipay-sagepay/zipball/4ca4847935bc31dbcdd627e92377b5c3cf709e9b",
- "reference": "4ca4847935bc31dbcdd627e92377b5c3cf709e9b",
+ "url": "https://api.github.com/repos/thephpleague/omnipay-sagepay/zipball/8e14e235caf6530ee9afcbbb8cd6a54ad160a0f0",
+ "reference": "8e14e235caf6530ee9afcbbb8cd6a54ad160a0f0",
"shasum": ""
},
"require": {
@@ -6734,7 +6954,7 @@
"sage pay",
"sagepay"
],
- "time": "2017-01-12 23:36:01"
+ "time": "2017-09-05 15:31:15"
},
{
"name": "omnipay/securepay",
@@ -7593,16 +7813,16 @@
},
{
"name": "ramsey/uuid",
- "version": "3.7.0",
+ "version": "3.7.1",
"source": {
"type": "git",
"url": "https://github.com/ramsey/uuid.git",
- "reference": "0ef23d1b10cf1bc576e9d865a7e9c47982c5715e"
+ "reference": "45cffe822057a09e05f7bd09ec5fb88eeecd2334"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ramsey/uuid/zipball/0ef23d1b10cf1bc576e9d865a7e9c47982c5715e",
- "reference": "0ef23d1b10cf1bc576e9d865a7e9c47982c5715e",
+ "url": "https://api.github.com/repos/ramsey/uuid/zipball/45cffe822057a09e05f7bd09ec5fb88eeecd2334",
+ "reference": "45cffe822057a09e05f7bd09ec5fb88eeecd2334",
"shasum": ""
},
"require": {
@@ -7671,7 +7891,7 @@
"identifier",
"uuid"
],
- "time": "2017-08-04 13:39:04"
+ "time": "2017-09-22 20:46:04"
},
{
"name": "rize/uri-template",
@@ -7822,16 +8042,16 @@
},
{
"name": "softcommerce/omnipay-paytrace",
- "version": "v1.1",
+ "version": "v1.2.1",
"source": {
"type": "git",
"url": "https://github.com/iddqdidkfa/omnipay-paytrace.git",
- "reference": "5783c84be9073bf9f804a7925bca0af4f912dcbd"
+ "reference": "82077923d14a1c8b45a89b6683343e0617d83956"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/iddqdidkfa/omnipay-paytrace/zipball/5783c84be9073bf9f804a7925bca0af4f912dcbd",
- "reference": "5783c84be9073bf9f804a7925bca0af4f912dcbd",
+ "url": "https://api.github.com/repos/iddqdidkfa/omnipay-paytrace/zipball/82077923d14a1c8b45a89b6683343e0617d83956",
+ "reference": "82077923d14a1c8b45a89b6683343e0617d83956",
"shasum": ""
},
"require": {
@@ -7870,7 +8090,7 @@
"payment",
"paytrace"
],
- "time": "2017-05-27 14:16:31"
+ "time": "2017-08-24 17:02:28"
},
{
"name": "swiftmailer/swiftmailer",
@@ -7928,20 +8148,20 @@
},
{
"name": "symfony/class-loader",
- "version": "v3.3.6",
+ "version": "v3.3.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/class-loader.git",
- "reference": "386a294d621576302e7cc36965d6ed53b8c73c4f"
+ "reference": "9c69968ce57924e9e93550895cd2b0477edf0e19"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/class-loader/zipball/386a294d621576302e7cc36965d6ed53b8c73c4f",
- "reference": "386a294d621576302e7cc36965d6ed53b8c73c4f",
+ "url": "https://api.github.com/repos/symfony/class-loader/zipball/9c69968ce57924e9e93550895cd2b0477edf0e19",
+ "reference": "9c69968ce57924e9e93550895cd2b0477edf0e19",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": "^5.5.9|>=7.0.8"
},
"require-dev": {
"symfony/finder": "~2.8|~3.0",
@@ -7980,7 +8200,7 @@
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
- "time": "2017-06-02 09:51:43"
+ "time": "2017-07-29 21:54:42"
},
{
"name": "symfony/config",
@@ -8100,20 +8320,20 @@
},
{
"name": "symfony/css-selector",
- "version": "v3.3.6",
+ "version": "v3.3.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "4d882dced7b995d5274293039370148e291808f2"
+ "reference": "c5f5263ed231f164c58368efbce959137c7d9488"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/4d882dced7b995d5274293039370148e291808f2",
- "reference": "4d882dced7b995d5274293039370148e291808f2",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/c5f5263ed231f164c58368efbce959137c7d9488",
+ "reference": "c5f5263ed231f164c58368efbce959137c7d9488",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
@@ -8149,7 +8369,7 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2017-05-01 15:01:29"
+ "time": "2017-07-29 21:54:42"
},
{
"name": "symfony/debug",
@@ -8273,7 +8493,7 @@
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.8.26",
+ "version": "v2.8.27",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
@@ -8333,20 +8553,20 @@
},
{
"name": "symfony/filesystem",
- "version": "v3.3.6",
+ "version": "v3.3.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "427987eb4eed764c3b6e38d52a0f87989e010676"
+ "reference": "b32a0e5f928d0fa3d1dd03c78d020777e50c10cb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/427987eb4eed764c3b6e38d52a0f87989e010676",
- "reference": "427987eb4eed764c3b6e38d52a0f87989e010676",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/b32a0e5f928d0fa3d1dd03c78d020777e50c10cb",
+ "reference": "b32a0e5f928d0fa3d1dd03c78d020777e50c10cb",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
@@ -8378,7 +8598,7 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2017-07-11 07:17:58"
+ "time": "2017-07-29 21:54:42"
},
{
"name": "symfony/finder",
@@ -8431,16 +8651,16 @@
},
{
"name": "symfony/http-foundation",
- "version": "v2.8.26",
+ "version": "v2.8.27",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "9ff3a0b3756ace2e3da7dded37e920ee776faa4e"
+ "reference": "fc4942ad82af83ac8301b68d0c9b1bbcc95a84c6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9ff3a0b3756ace2e3da7dded37e920ee776faa4e",
- "reference": "9ff3a0b3756ace2e3da7dded37e920ee776faa4e",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/fc4942ad82af83ac8301b68d0c9b1bbcc95a84c6",
+ "reference": "fc4942ad82af83ac8301b68d0c9b1bbcc95a84c6",
"shasum": ""
},
"require": {
@@ -8482,7 +8702,7 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2017-07-17 14:02:19"
+ "time": "2017-08-10 07:04:10"
},
{
"name": "symfony/http-kernel",
@@ -8568,20 +8788,20 @@
},
{
"name": "symfony/options-resolver",
- "version": "v3.3.6",
+ "version": "v3.3.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
- "reference": "ff48982d295bcac1fd861f934f041ebc73ae40f0"
+ "reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/options-resolver/zipball/ff48982d295bcac1fd861f934f041ebc73ae40f0",
- "reference": "ff48982d295bcac1fd861f934f041ebc73ae40f0",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/ee4e22978fe885b54ee5da8c7964f0a5301abfb6",
+ "reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
@@ -8618,7 +8838,7 @@
"configuration",
"options"
],
- "time": "2017-04-12 14:14:56"
+ "time": "2017-07-29 21:54:42"
},
{
"name": "symfony/polyfill-mbstring",
@@ -9154,20 +9374,20 @@
},
{
"name": "symfony/yaml",
- "version": "v3.3.6",
+ "version": "v3.3.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "ddc23324e6cfe066f3dd34a37ff494fa80b617ed"
+ "reference": "1d8c2a99c80862bdc3af94c1781bf70f86bccac0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/ddc23324e6cfe066f3dd34a37ff494fa80b617ed",
- "reference": "ddc23324e6cfe066f3dd34a37ff494fa80b617ed",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/1d8c2a99c80862bdc3af94c1781bf70f86bccac0",
+ "reference": "1d8c2a99c80862bdc3af94c1781bf70f86bccac0",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": "^5.5.9|>=7.0.8"
},
"require-dev": {
"symfony/console": "~2.8|~3.0"
@@ -9205,7 +9425,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2017-07-23 12:43:26"
+ "time": "2017-07-29 21:54:42"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -9459,16 +9679,16 @@
},
{
"name": "twig/twig",
- "version": "v1.34.4",
+ "version": "v1.35.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "f878bab48edb66ad9c6ed626bf817f60c6c096ee"
+ "reference": "daa657073e55b0a78cce8fdd22682fddecc6385f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/f878bab48edb66ad9c6ed626bf817f60c6c096ee",
- "reference": "f878bab48edb66ad9c6ed626bf817f60c6c096ee",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/daa657073e55b0a78cce8fdd22682fddecc6385f",
+ "reference": "daa657073e55b0a78cce8fdd22682fddecc6385f",
"shasum": ""
},
"require": {
@@ -9482,7 +9702,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.34-dev"
+ "dev-master": "1.35-dev"
}
},
"autoload": {
@@ -9520,7 +9740,7 @@
"keywords": [
"templating"
],
- "time": "2017-07-04 13:19:31"
+ "time": "2017-09-27 18:06:46"
},
{
"name": "vink/omnipay-komoju",
@@ -9626,12 +9846,12 @@
"source": {
"type": "git",
"url": "https://github.com/webpatser/laravel-countries.git",
- "reference": "bb5d5116d796a038bfb45f083998b25506d9a595"
+ "reference": "50e06eeb4e0473cd2d1471f59dbd4826908a9771"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webpatser/laravel-countries/zipball/bb5d5116d796a038bfb45f083998b25506d9a595",
- "reference": "bb5d5116d796a038bfb45f083998b25506d9a595",
+ "url": "https://api.github.com/repos/webpatser/laravel-countries/zipball/50e06eeb4e0473cd2d1471f59dbd4826908a9771",
+ "reference": "50e06eeb4e0473cd2d1471f59dbd4826908a9771",
"shasum": ""
},
"require": {
@@ -9670,7 +9890,7 @@
"iso_3166_3",
"laravel"
],
- "time": "2017-01-25 20:26:35"
+ "time": "2017-08-24 08:46:54"
},
{
"name": "websight/l5-google-cloud-storage",
@@ -10131,16 +10351,16 @@
},
{
"name": "zendframework/zend-validator",
- "version": "2.10.0",
+ "version": "2.10.1",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-validator.git",
- "reference": "07ef29e31353592e99eb32b2feb7248681ffb630"
+ "reference": "010084ddbd33299bf51ea6f0e07f8f4e8bd832a8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/07ef29e31353592e99eb32b2feb7248681ffb630",
- "reference": "07ef29e31353592e99eb32b2feb7248681ffb630",
+ "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/010084ddbd33299bf51ea6f0e07f8f4e8bd832a8",
+ "reference": "010084ddbd33299bf51ea6f0e07f8f4e8bd832a8",
"shasum": ""
},
"require": {
@@ -10198,7 +10418,7 @@
"validator",
"zf2"
],
- "time": "2017-08-14 20:36:46"
+ "time": "2017-08-22 14:19:23"
},
{
"name": "zendframework/zendservice-apple-apns",
@@ -10657,16 +10877,16 @@
},
{
"name": "phpdocumentor/reflection-common",
- "version": "1.0",
+ "version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
- "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
"shasum": ""
},
"require": {
@@ -10707,26 +10927,26 @@
"reflection",
"static analysis"
],
- "time": "2015-12-27 11:43:31"
+ "time": "2017-09-11 18:02:19"
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "3.2.2",
+ "version": "4.1.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157"
+ "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/4aada1f93c72c35e22fb1383b47fee43b8f1d157",
- "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2d3d238c433cf69caeb4842e97a3223a116f94b2",
+ "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2",
"shasum": ""
},
"require": {
- "php": ">=5.5",
+ "php": "^7.0",
"phpdocumentor/reflection-common": "^1.0@dev",
- "phpdocumentor/type-resolver": "^0.3.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
"webmozart/assert": "^1.0"
},
"require-dev": {
@@ -10752,20 +10972,20 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2017-08-08 06:39:58"
+ "time": "2017-08-30 18:51:59"
},
{
"name": "phpdocumentor/type-resolver",
- "version": "0.3.0",
+ "version": "0.4.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "fb3933512008d8162b3cdf9e18dba9309b7c3773"
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/fb3933512008d8162b3cdf9e18dba9309b7c3773",
- "reference": "fb3933512008d8162b3cdf9e18dba9309b7c3773",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
"shasum": ""
},
"require": {
@@ -10799,7 +11019,7 @@
"email": "me@mikevanriel.com"
}
],
- "time": "2017-06-03 08:32:36"
+ "time": "2017-07-14 14:27:02"
},
{
"name": "phpspec/php-diff",
@@ -10915,22 +11135,22 @@
},
{
"name": "phpspec/prophecy",
- "version": "v1.7.0",
+ "version": "v1.7.2",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
+ "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
- "reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6",
+ "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
"sebastian/comparator": "^1.1|^2.0",
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
},
@@ -10941,7 +11161,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.6.x-dev"
+ "dev-master": "1.7.x-dev"
}
},
"autoload": {
@@ -10974,7 +11194,7 @@
"spy",
"stub"
],
- "time": "2017-03-02 20:05:34"
+ "time": "2017-09-04 11:05:03"
},
{
"name": "phpunit/php-code-coverage",
@@ -11771,20 +11991,20 @@
},
{
"name": "symfony/browser-kit",
- "version": "v3.3.6",
+ "version": "v3.3.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
- "reference": "8079a6b3668ef15cdbf73a4c7d31081abb8bb5f0"
+ "reference": "aee7120b058c268363e606ff5fe8271da849a1b5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/browser-kit/zipball/8079a6b3668ef15cdbf73a4c7d31081abb8bb5f0",
- "reference": "8079a6b3668ef15cdbf73a4c7d31081abb8bb5f0",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/aee7120b058c268363e606ff5fe8271da849a1b5",
+ "reference": "aee7120b058c268363e606ff5fe8271da849a1b5",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
+ "php": "^5.5.9|>=7.0.8",
"symfony/dom-crawler": "~2.8|~3.0"
},
"require-dev": {
@@ -11824,24 +12044,24 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
- "time": "2017-07-12 13:03:20"
+ "time": "2017-07-29 21:54:42"
},
{
"name": "symfony/dom-crawler",
- "version": "v3.3.6",
+ "version": "v3.3.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "fc2c588ce376e9fe04a7b8c79e3ec62fe32d95b1"
+ "reference": "6b511d7329b203a620f09a2288818d27dcc915ae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/fc2c588ce376e9fe04a7b8c79e3ec62fe32d95b1",
- "reference": "fc2c588ce376e9fe04a7b8c79e3ec62fe32d95b1",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/6b511d7329b203a620f09a2288818d27dcc915ae",
+ "reference": "6b511d7329b203a620f09a2288818d27dcc915ae",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
+ "php": "^5.5.9|>=7.0.8",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
@@ -11880,7 +12100,7 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2017-05-25 23:10:31"
+ "time": "2017-09-11 15:55:22"
},
{
"name": "webmozart/assert",
@@ -11933,7 +12153,14 @@
"time": "2016-11-23 20:04:58"
}
],
- "aliases": [],
+ "aliases": [
+ {
+ "alias": "2.5.0",
+ "alias_normalized": "2.5.0.0",
+ "version": "dev-solution-id",
+ "package": "omnipay/authorizenet"
+ }
+ ],
"minimum-stability": "stable",
"stability-flags": {
"dwolla/omnipay-dwolla": 20,
@@ -11961,7 +12188,8 @@
"omnipay/stripe": 20,
"simshaun/recurr": 20,
"webpatser/laravel-countries": 20,
- "websight/l5-google-cloud-storage": 20
+ "websight/l5-google-cloud-storage": 20,
+ "omnipay/authorizenet": 20
},
"prefer-stable": false,
"prefer-lowest": false,
diff --git a/config/ninja.php b/config/ninja.php
index 3b428f9f3724..979d0c64c3f7 100644
--- a/config/ninja.php
+++ b/config/ninja.php
@@ -2,6 +2,9 @@
return [
+ // Marketing links
+ 'time_tracker_web_url' => env('TIME_TRACKER_WEB_URL'),
+
// Hosted plan coupons
'coupon_50_off' => env('COUPON_50_OFF', false),
'coupon_75_off' => env('COUPON_75_OFF', false),
diff --git a/config/session.php b/config/session.php
index beb02c87d793..be4edb889810 100644
--- a/config/session.php
+++ b/config/session.php
@@ -31,7 +31,7 @@ return [
'lifetime' => env('SESSION_LIFETIME', (60 * 8)),
- 'expire_on_close' => true,
+ 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', true),
/*
|--------------------------------------------------------------------------
diff --git a/database/seeds/GatewayTypesSeeder.php b/database/seeds/GatewayTypesSeeder.php
index 6ec180a9001f..22c9702111ad 100644
--- a/database/seeds/GatewayTypesSeeder.php
+++ b/database/seeds/GatewayTypesSeeder.php
@@ -17,6 +17,7 @@ class GatewayTypesSeeder extends Seeder
['alias' => 'custom', 'name' => 'Custom'],
['alias' => 'alipay', 'name' => 'Alipay'],
['alias' => 'sofort', 'name' => 'Sofort'],
+ ['alias' => 'sepa', 'name' => 'SEPA'],
];
foreach ($gateway_types as $gateway_type) {
diff --git a/database/seeds/PaymentLibrariesSeeder.php b/database/seeds/PaymentLibrariesSeeder.php
index 664c9bb4d998..30745b7e5620 100644
--- a/database/seeds/PaymentLibrariesSeeder.php
+++ b/database/seeds/PaymentLibrariesSeeder.php
@@ -73,6 +73,7 @@ class PaymentLibrariesSeeder extends Seeder
['name' => 'Custom', 'provider' => 'Custom', 'is_offsite' => true, 'sort_order' => 9],
['name' => 'FirstData Payeezy', 'provider' => 'FirstData_Payeezy'],
['name' => 'GoCardless', 'provider' => 'GoCardlessV2\Redirect', 'sort_order' => 8, 'is_offsite' => true],
+ ['name' => 'PagSeguro', 'provider' => 'PagSeguro'],
];
foreach ($gateways as $gateway) {
diff --git a/database/seeds/PaymentTypesSeeder.php b/database/seeds/PaymentTypesSeeder.php
index afd679f3f493..0e56db05b7d1 100644
--- a/database/seeds/PaymentTypesSeeder.php
+++ b/database/seeds/PaymentTypesSeeder.php
@@ -38,6 +38,7 @@ class PaymentTypesSeeder extends Seeder
['name' => 'Money Order'],
['name' => 'Alipay', 'gateway_type_id' => GATEWAY_TYPE_ALIPAY],
['name' => 'Sofort', 'gateway_type_id' => GATEWAY_TYPE_SOFORT],
+ ['name' => 'SEPA', 'gateway_type_id' => GATEWAY_TYPE_SEPA],
];
foreach ($paymentTypes as $paymentType) {
diff --git a/database/setup.sql b/database/setup.sql
index be4a9f6d9908..ef109b13a0a2 100644
--- a/database/setup.sql
+++ b/database/setup.sql
@@ -790,7 +790,7 @@ CREATE TABLE `countries` (
LOCK TABLES `countries` WRITE;
/*!40000 ALTER TABLE `countries` DISABLE KEYS */;
-INSERT INTO `countries` VALUES (4,'Kabul','Afghan','004','afghani','AFN','pul','Islamic Republic of Afghanistan','AF','AFG','Afghanistan','142','034',0,0,0,NULL,NULL),(8,'Tirana','Albanian','008','lek','ALL','(qindar (pl. qindarka))','Republic of Albania','AL','ALB','Albania','150','039',0,0,0,NULL,NULL),(10,'Antartica','of Antartica','010','','','','Antarctica','AQ','ATA','Antarctica','','',0,0,0,NULL,NULL),(12,'Algiers','Algerian','012','Algerian dinar','DZD','centime','People’s Democratic Republic of Algeria','DZ','DZA','Algeria','002','015',0,0,0,NULL,NULL),(16,'Pago Pago','American Samoan','016','US dollar','USD','cent','Territory of American','AS','ASM','American Samoa','009','061',0,0,0,NULL,NULL),(20,'Andorra la Vella','Andorran','020','euro','EUR','cent','Principality of Andorra','AD','AND','Andorra','150','039',0,0,0,NULL,NULL),(24,'Luanda','Angolan','024','kwanza','AOA','cêntimo','Republic of Angola','AO','AGO','Angola','002','017',0,0,0,NULL,NULL),(28,'St John’s','of Antigua and Barbuda','028','East Caribbean dollar','XCD','cent','Antigua and Barbuda','AG','ATG','Antigua and Barbuda','019','029',0,0,0,NULL,NULL),(31,'Baku','Azerbaijani','031','Azerbaijani manat','AZN','kepik (inv.)','Republic of Azerbaijan','AZ','AZE','Azerbaijan','142','145',0,0,0,NULL,NULL),(32,'Buenos Aires','Argentinian','032','Argentine peso','ARS','centavo','Argentine Republic','AR','ARG','Argentina','019','005',0,1,0,NULL,NULL),(36,'Canberra','Australian','036','Australian dollar','AUD','cent','Commonwealth of Australia','AU','AUS','Australia','009','053',0,0,0,NULL,NULL),(40,'Vienna','Austrian','040','euro','EUR','cent','Republic of Austria','AT','AUT','Austria','150','155',1,1,1,NULL,NULL),(44,'Nassau','Bahamian','044','Bahamian dollar','BSD','cent','Commonwealth of the Bahamas','BS','BHS','Bahamas','019','029',0,0,0,NULL,NULL),(48,'Manama','Bahraini','048','Bahraini dinar','BHD','fils (inv.)','Kingdom of Bahrain','BH','BHR','Bahrain','142','145',0,0,0,NULL,NULL),(50,'Dhaka','Bangladeshi','050','taka (inv.)','BDT','poisha (inv.)','People’s Republic of Bangladesh','BD','BGD','Bangladesh','142','034',0,0,0,NULL,NULL),(51,'Yerevan','Armenian','051','dram (inv.)','AMD','luma','Republic of Armenia','AM','ARM','Armenia','142','145',0,0,0,NULL,NULL),(52,'Bridgetown','Barbadian','052','Barbados dollar','BBD','cent','Barbados','BB','BRB','Barbados','019','029',0,0,0,NULL,NULL),(56,'Brussels','Belgian','056','euro','EUR','cent','Kingdom of Belgium','BE','BEL','Belgium','150','155',1,1,0,NULL,NULL),(60,'Hamilton','Bermudian','060','Bermuda dollar','BMD','cent','Bermuda','BM','BMU','Bermuda','019','021',0,0,0,NULL,NULL),(64,'Thimphu','Bhutanese','064','ngultrum (inv.)','BTN','chhetrum (inv.)','Kingdom of Bhutan','BT','BTN','Bhutan','142','034',0,0,0,NULL,NULL),(68,'Sucre (BO1)','Bolivian','068','boliviano','BOB','centavo','Plurinational State of Bolivia','BO','BOL','Bolivia, Plurinational State of','019','005',0,0,0,NULL,NULL),(70,'Sarajevo','of Bosnia and Herzegovina','070','convertible mark','BAM','fening','Bosnia and Herzegovina','BA','BIH','Bosnia and Herzegovina','150','039',0,0,0,NULL,NULL),(72,'Gaborone','Botswanan','072','pula (inv.)','BWP','thebe (inv.)','Republic of Botswana','BW','BWA','Botswana','002','018',0,0,0,NULL,NULL),(74,'Bouvet island','of Bouvet island','074','','','','Bouvet Island','BV','BVT','Bouvet Island','','',0,0,0,NULL,NULL),(76,'Brasilia','Brazilian','076','real (pl. reais)','BRL','centavo','Federative Republic of Brazil','BR','BRA','Brazil','019','005',0,0,0,NULL,NULL),(84,'Belmopan','Belizean','084','Belize dollar','BZD','cent','Belize','BZ','BLZ','Belize','019','013',0,0,0,NULL,NULL),(86,'Diego Garcia','Changosian','086','US dollar','USD','cent','British Indian Ocean Territory','IO','IOT','British Indian Ocean Territory','','',0,0,0,NULL,NULL),(90,'Honiara','Solomon Islander','090','Solomon Islands dollar','SBD','cent','Solomon Islands','SB','SLB','Solomon Islands','009','054',0,0,0,NULL,NULL),(92,'Road Town','British Virgin Islander;','092','US dollar','USD','cent','British Virgin Islands','VG','VGB','Virgin Islands, British','019','029',0,0,0,NULL,NULL),(96,'Bandar Seri Begawan','Bruneian','096','Brunei dollar','BND','sen (inv.)','Brunei Darussalam','BN','BRN','Brunei Darussalam','142','035',0,0,0,NULL,NULL),(100,'Sofia','Bulgarian','100','lev (pl. leva)','BGN','stotinka','Republic of Bulgaria','BG','BGR','Bulgaria','150','151',1,0,1,NULL,NULL),(104,'Yangon','Burmese','104','kyat','MMK','pya','Union of Myanmar/','MM','MMR','Myanmar','142','035',0,0,0,NULL,NULL),(108,'Bujumbura','Burundian','108','Burundi franc','BIF','centime','Republic of Burundi','BI','BDI','Burundi','002','014',0,0,0,NULL,NULL),(112,'Minsk','Belarusian','112','Belarusian rouble','BYR','kopek','Republic of Belarus','BY','BLR','Belarus','150','151',0,0,0,NULL,NULL),(116,'Phnom Penh','Cambodian','116','riel','KHR','sen (inv.)','Kingdom of Cambodia','KH','KHM','Cambodia','142','035',0,0,0,NULL,NULL),(120,'Yaoundé','Cameroonian','120','CFA franc (BEAC)','XAF','centime','Republic of Cameroon','CM','CMR','Cameroon','002','017',0,0,0,NULL,NULL),(124,'Ottawa','Canadian','124','Canadian dollar','CAD','cent','Canada','CA','CAN','Canada','019','021',0,0,0,NULL,NULL),(132,'Praia','Cape Verdean','132','Cape Verde escudo','CVE','centavo','Republic of Cape Verde','CV','CPV','Cape Verde','002','011',0,0,0,NULL,NULL),(136,'George Town','Caymanian','136','Cayman Islands dollar','KYD','cent','Cayman Islands','KY','CYM','Cayman Islands','019','029',0,0,0,NULL,NULL),(140,'Bangui','Central African','140','CFA franc (BEAC)','XAF','centime','Central African Republic','CF','CAF','Central African Republic','002','017',0,0,0,NULL,NULL),(144,'Colombo','Sri Lankan','144','Sri Lankan rupee','LKR','cent','Democratic Socialist Republic of Sri Lanka','LK','LKA','Sri Lanka','142','034',0,0,0,NULL,NULL),(148,'N’Djamena','Chadian','148','CFA franc (BEAC)','XAF','centime','Republic of Chad','TD','TCD','Chad','002','017',0,0,0,NULL,NULL),(152,'Santiago','Chilean','152','Chilean peso','CLP','centavo','Republic of Chile','CL','CHL','Chile','019','005',0,0,0,NULL,NULL),(156,'Beijing','Chinese','156','renminbi-yuan (inv.)','CNY','jiao (10)','People’s Republic of China','CN','CHN','China','142','030',0,0,0,NULL,NULL),(158,'Taipei','Taiwanese','158','new Taiwan dollar','TWD','fen (inv.)','Republic of China, Taiwan (TW1)','TW','TWN','Taiwan, Province of China','142','030',0,0,0,NULL,NULL),(162,'Flying Fish Cove','Christmas Islander','162','Australian dollar','AUD','cent','Christmas Island Territory','CX','CXR','Christmas Island','','',0,0,0,NULL,NULL),(166,'Bantam','Cocos Islander','166','Australian dollar','AUD','cent','Territory of Cocos (Keeling) Islands','CC','CCK','Cocos (Keeling) Islands','','',0,0,0,NULL,NULL),(170,'Santa Fe de Bogotá','Colombian','170','Colombian peso','COP','centavo','Republic of Colombia','CO','COL','Colombia','019','005',0,0,0,NULL,NULL),(174,'Moroni','Comorian','174','Comorian franc','KMF','','Union of the Comoros','KM','COM','Comoros','002','014',0,0,0,NULL,NULL),(175,'Mamoudzou','Mahorais','175','euro','EUR','cent','Departmental Collectivity of Mayotte','YT','MYT','Mayotte','002','014',0,0,0,NULL,NULL),(178,'Brazzaville','Congolese','178','CFA franc (BEAC)','XAF','centime','Republic of the Congo','CG','COG','Congo','002','017',0,0,0,NULL,NULL),(180,'Kinshasa','Congolese','180','Congolese franc','CDF','centime','Democratic Republic of the Congo','CD','COD','Congo, the Democratic Republic of the','002','017',0,0,0,NULL,NULL),(184,'Avarua','Cook Islander','184','New Zealand dollar','NZD','cent','Cook Islands','CK','COK','Cook Islands','009','061',0,0,0,NULL,NULL),(188,'San José','Costa Rican','188','Costa Rican colón (pl. colones)','CRC','céntimo','Republic of Costa Rica','CR','CRI','Costa Rica','019','013',0,0,0,NULL,NULL),(191,'Zagreb','Croatian','191','kuna (inv.)','HRK','lipa (inv.)','Republic of Croatia','HR','HRV','Croatia','150','039',1,0,1,NULL,NULL),(192,'Havana','Cuban','192','Cuban peso','CUP','centavo','Republic of Cuba','CU','CUB','Cuba','019','029',0,0,0,NULL,NULL),(196,'Nicosia','Cypriot','196','euro','EUR','cent','Republic of Cyprus','CY','CYP','Cyprus','142','145',1,0,0,NULL,NULL),(203,'Prague','Czech','203','Czech koruna (pl. koruny)','CZK','halér','Czech Republic','CZ','CZE','Czech Republic','150','151',1,0,1,NULL,NULL),(204,'Porto Novo (BJ1)','Beninese','204','CFA franc (BCEAO)','XOF','centime','Republic of Benin','BJ','BEN','Benin','002','011',0,0,0,NULL,NULL),(208,'Copenhagen','Danish','208','Danish krone','DKK','øre (inv.)','Kingdom of Denmark','DK','DNK','Denmark','150','154',1,1,0,NULL,NULL),(212,'Roseau','Dominican','212','East Caribbean dollar','XCD','cent','Commonwealth of Dominica','DM','DMA','Dominica','019','029',0,0,0,NULL,NULL),(214,'Santo Domingo','Dominican','214','Dominican peso','DOP','centavo','Dominican Republic','DO','DOM','Dominican Republic','019','029',0,0,0,NULL,NULL),(218,'Quito','Ecuadorian','218','US dollar','USD','cent','Republic of Ecuador','EC','ECU','Ecuador','019','005',0,0,0,NULL,NULL),(222,'San Salvador','Salvadoran','222','Salvadorian colón (pl. colones)','SVC','centavo','Republic of El Salvador','SV','SLV','El Salvador','019','013',0,0,0,NULL,NULL),(226,'Malabo','Equatorial Guinean','226','CFA franc (BEAC)','XAF','centime','Republic of Equatorial Guinea','GQ','GNQ','Equatorial Guinea','002','017',0,0,0,NULL,NULL),(231,'Addis Ababa','Ethiopian','231','birr (inv.)','ETB','cent','Federal Democratic Republic of Ethiopia','ET','ETH','Ethiopia','002','014',0,0,0,NULL,NULL),(232,'Asmara','Eritrean','232','nakfa','ERN','cent','State of Eritrea','ER','ERI','Eritrea','002','014',0,0,0,NULL,NULL),(233,'Tallinn','Estonian','233','euro','EUR','cent','Republic of Estonia','EE','EST','Estonia','150','154',1,0,1,NULL,NULL),(234,'Tórshavn','Faeroese','234','Danish krone','DKK','øre (inv.)','Faeroe Islands','FO','FRO','Faroe Islands','150','154',0,0,0,NULL,NULL),(238,'Stanley','Falkland Islander','238','Falkland Islands pound','FKP','new penny','Falkland Islands','FK','FLK','Falkland Islands (Malvinas)','019','005',0,0,0,NULL,NULL),(239,'King Edward Point (Grytviken)','of South Georgia and the South Sandwich Islands','239','','','','South Georgia and the South Sandwich Islands','GS','SGS','South Georgia and the South Sandwich Islands','','',0,0,0,NULL,NULL),(242,'Suva','Fijian','242','Fiji dollar','FJD','cent','Republic of Fiji','FJ','FJI','Fiji','009','054',0,0,0,NULL,NULL),(246,'Helsinki','Finnish','246','euro','EUR','cent','Republic of Finland','FI','FIN','Finland','150','154',1,1,1,NULL,NULL),(248,'Mariehamn','Åland Islander','248','euro','EUR','cent','Åland Islands','AX','ALA','Åland Islands','150','154',0,0,0,NULL,NULL),(250,'Paris','French','250','euro','EUR','cent','French Republic','FR','FRA','France','150','155',1,1,1,NULL,NULL),(254,'Cayenne','Guianese','254','euro','EUR','cent','French Guiana','GF','GUF','French Guiana','019','005',0,0,0,NULL,NULL),(258,'Papeete','Polynesian','258','CFP franc','XPF','centime','French Polynesia','PF','PYF','French Polynesia','009','061',0,0,0,NULL,NULL),(260,'Port-aux-Francais','of French Southern and Antarctic Lands','260','euro','EUR','cent','French Southern and Antarctic Lands','TF','ATF','French Southern Territories','','',0,0,0,NULL,NULL),(262,'Djibouti','Djiboutian','262','Djibouti franc','DJF','','Republic of Djibouti','DJ','DJI','Djibouti','002','014',0,0,0,NULL,NULL),(266,'Libreville','Gabonese','266','CFA franc (BEAC)','XAF','centime','Gabonese Republic','GA','GAB','Gabon','002','017',0,0,0,NULL,NULL),(268,'Tbilisi','Georgian','268','lari','GEL','tetri (inv.)','Georgia','GE','GEO','Georgia','142','145',0,0,0,NULL,NULL),(270,'Banjul','Gambian','270','dalasi (inv.)','GMD','butut','Republic of the Gambia','GM','GMB','Gambia','002','011',0,0,0,NULL,NULL),(275,NULL,'Palestinian','275',NULL,NULL,NULL,NULL,'PS','PSE','Palestinian Territory, Occupied','142','145',0,0,0,NULL,NULL),(276,'Berlin','German','276','euro','EUR','cent','Federal Republic of Germany','DE','DEU','Germany','150','155',1,1,1,NULL,NULL),(288,'Accra','Ghanaian','288','Ghana cedi','GHS','pesewa','Republic of Ghana','GH','GHA','Ghana','002','011',0,0,0,NULL,NULL),(292,'Gibraltar','Gibraltarian','292','Gibraltar pound','GIP','penny','Gibraltar','GI','GIB','Gibraltar','150','039',0,0,0,NULL,NULL),(296,'Tarawa','Kiribatian','296','Australian dollar','AUD','cent','Republic of Kiribati','KI','KIR','Kiribati','009','057',0,0,0,NULL,NULL),(300,'Athens','Greek','300','euro','EUR','cent','Hellenic Republic','GR','GRC','Greece','150','039',1,0,1,NULL,NULL),(304,'Nuuk','Greenlander','304','Danish krone','DKK','øre (inv.)','Greenland','GL','GRL','Greenland','019','021',0,1,0,NULL,NULL),(308,'St George’s','Grenadian','308','East Caribbean dollar','XCD','cent','Grenada','GD','GRD','Grenada','019','029',0,0,0,NULL,NULL),(312,'Basse Terre','Guadeloupean','312','euro','EUR ','cent','Guadeloupe','GP','GLP','Guadeloupe','019','029',0,0,0,NULL,NULL),(316,'Agaña (Hagåtña)','Guamanian','316','US dollar','USD','cent','Territory of Guam','GU','GUM','Guam','009','057',0,0,0,NULL,NULL),(320,'Guatemala City','Guatemalan','320','quetzal (pl. quetzales)','GTQ','centavo','Republic of Guatemala','GT','GTM','Guatemala','019','013',0,0,0,NULL,NULL),(324,'Conakry','Guinean','324','Guinean franc','GNF','','Republic of Guinea','GN','GIN','Guinea','002','011',0,0,0,NULL,NULL),(328,'Georgetown','Guyanese','328','Guyana dollar','GYD','cent','Cooperative Republic of Guyana','GY','GUY','Guyana','019','005',0,0,0,NULL,NULL),(332,'Port-au-Prince','Haitian','332','gourde','HTG','centime','Republic of Haiti','HT','HTI','Haiti','019','029',0,0,0,NULL,NULL),(334,'Territory of Heard Island and McDonald Islands','of Territory of Heard Island and McDonald Islands','334','','','','Territory of Heard Island and McDonald Islands','HM','HMD','Heard Island and McDonald Islands','','',0,0,0,NULL,NULL),(336,'Vatican City','of the Holy See/of the Vatican','336','euro','EUR','cent','the Holy See/ Vatican City State','VA','VAT','Holy See (Vatican City State)','150','039',0,0,0,NULL,NULL),(340,'Tegucigalpa','Honduran','340','lempira','HNL','centavo','Republic of Honduras','HN','HND','Honduras','019','013',0,0,0,NULL,NULL),(344,'(HK3)','Hong Kong Chinese','344','Hong Kong dollar','HKD','cent','Hong Kong Special Administrative Region of the People’s Republic of China (HK2)','HK','HKG','Hong Kong','142','030',0,0,0,NULL,NULL),(348,'Budapest','Hungarian','348','forint (inv.)','HUF','(fillér (inv.))','Republic of Hungary','HU','HUN','Hungary','150','151',1,0,1,NULL,NULL),(352,'Reykjavik','Icelander','352','króna (pl. krónur)','ISK','','Republic of Iceland','IS','ISL','Iceland','150','154',1,1,1,NULL,NULL),(356,'New Delhi','Indian','356','Indian rupee','INR','paisa','Republic of India','IN','IND','India','142','034',0,0,0,NULL,NULL),(360,'Jakarta','Indonesian','360','Indonesian rupiah (inv.)','IDR','sen (inv.)','Republic of Indonesia','ID','IDN','Indonesia','142','035',0,0,0,NULL,NULL),(364,'Tehran','Iranian','364','Iranian rial','IRR','(dinar) (IR1)','Islamic Republic of Iran','IR','IRN','Iran, Islamic Republic of','142','034',0,0,0,NULL,NULL),(368,'Baghdad','Iraqi','368','Iraqi dinar','IQD','fils (inv.)','Republic of Iraq','IQ','IRQ','Iraq','142','145',0,0,0,NULL,NULL),(372,'Dublin','Irish','372','euro','EUR','cent','Ireland (IE1)','IE','IRL','Ireland','150','154',1,0,0,',','.'),(376,'(IL1)','Israeli','376','shekel','ILS','agora','State of Israel','IL','ISR','Israel','142','145',0,1,0,NULL,NULL),(380,'Rome','Italian','380','euro','EUR','cent','Italian Republic','IT','ITA','Italy','150','039',1,1,1,NULL,NULL),(384,'Yamoussoukro (CI1)','Ivorian','384','CFA franc (BCEAO)','XOF','centime','Republic of Côte d’Ivoire','CI','CIV','Côte d\'Ivoire','002','011',0,0,0,NULL,NULL),(388,'Kingston','Jamaican','388','Jamaica dollar','JMD','cent','Jamaica','JM','JAM','Jamaica','019','029',0,0,0,NULL,NULL),(392,'Tokyo','Japanese','392','yen (inv.)','JPY','(sen (inv.)) (JP1)','Japan','JP','JPN','Japan','142','030',0,1,1,NULL,NULL),(398,'Astana','Kazakh','398','tenge (inv.)','KZT','tiyn','Republic of Kazakhstan','KZ','KAZ','Kazakhstan','142','143',0,0,0,NULL,NULL),(400,'Amman','Jordanian','400','Jordanian dinar','JOD','100 qirsh','Hashemite Kingdom of Jordan','JO','JOR','Jordan','142','145',0,0,0,NULL,NULL),(404,'Nairobi','Kenyan','404','Kenyan shilling','KES','cent','Republic of Kenya','KE','KEN','Kenya','002','014',0,0,0,NULL,NULL),(408,'Pyongyang','North Korean','408','North Korean won (inv.)','KPW','chun (inv.)','Democratic People’s Republic of Korea','KP','PRK','Korea, Democratic People\'s Republic of','142','030',0,0,0,NULL,NULL),(410,'Seoul','South Korean','410','South Korean won (inv.)','KRW','(chun (inv.))','Republic of Korea','KR','KOR','Korea, Republic of','142','030',0,0,0,NULL,NULL),(414,'Kuwait City','Kuwaiti','414','Kuwaiti dinar','KWD','fils (inv.)','State of Kuwait','KW','KWT','Kuwait','142','145',0,0,0,NULL,NULL),(417,'Bishkek','Kyrgyz','417','som','KGS','tyiyn','Kyrgyz Republic','KG','KGZ','Kyrgyzstan','142','143',0,0,0,NULL,NULL),(418,'Vientiane','Lao','418','kip (inv.)','LAK','(at (inv.))','Lao People’s Democratic Republic','LA','LAO','Lao People\'s Democratic Republic','142','035',0,0,0,NULL,NULL),(422,'Beirut','Lebanese','422','Lebanese pound','LBP','(piastre)','Lebanese Republic','LB','LBN','Lebanon','142','145',0,0,0,NULL,NULL),(426,'Maseru','Basotho','426','loti (pl. maloti)','LSL','sente','Kingdom of Lesotho','LS','LSO','Lesotho','002','018',0,0,0,NULL,NULL),(428,'Riga','Latvian','428','euro','EUR','cent','Republic of Latvia','LV','LVA','Latvia','150','154',1,0,0,NULL,NULL),(430,'Monrovia','Liberian','430','Liberian dollar','LRD','cent','Republic of Liberia','LR','LBR','Liberia','002','011',0,0,0,NULL,NULL),(434,'Tripoli','Libyan','434','Libyan dinar','LYD','dirham','Socialist People’s Libyan Arab Jamahiriya','LY','LBY','Libya','002','015',0,0,0,NULL,NULL),(438,'Vaduz','Liechtensteiner','438','Swiss franc','CHF','centime','Principality of Liechtenstein','LI','LIE','Liechtenstein','150','155',1,0,0,NULL,NULL),(440,'Vilnius','Lithuanian','440','euro','EUR','cent','Republic of Lithuania','LT','LTU','Lithuania','150','154',1,0,1,NULL,NULL),(442,'Luxembourg','Luxembourger','442','euro','EUR','cent','Grand Duchy of Luxembourg','LU','LUX','Luxembourg','150','155',1,1,0,NULL,NULL),(446,'Macao (MO3)','Macanese','446','pataca','MOP','avo','Macao Special Administrative Region of the People’s Republic of China (MO2)','MO','MAC','Macao','142','030',0,0,0,NULL,NULL),(450,'Antananarivo','Malagasy','450','ariary','MGA','iraimbilanja (inv.)','Republic of Madagascar','MG','MDG','Madagascar','002','014',0,0,0,NULL,NULL),(454,'Lilongwe','Malawian','454','Malawian kwacha (inv.)','MWK','tambala (inv.)','Republic of Malawi','MW','MWI','Malawi','002','014',0,0,0,NULL,NULL),(458,'Kuala Lumpur (MY1)','Malaysian','458','ringgit (inv.)','MYR','sen (inv.)','Malaysia','MY','MYS','Malaysia','142','035',0,1,0,NULL,NULL),(462,'Malé','Maldivian','462','rufiyaa','MVR','laari (inv.)','Republic of Maldives','MV','MDV','Maldives','142','034',0,0,0,NULL,NULL),(466,'Bamako','Malian','466','CFA franc (BCEAO)','XOF','centime','Republic of Mali','ML','MLI','Mali','002','011',0,0,0,NULL,NULL),(470,'Valletta','Maltese','470','euro','EUR','cent','Republic of Malta','MT','MLT','Malta','150','039',1,0,0,NULL,NULL),(474,'Fort-de-France','Martinican','474','euro','EUR','cent','Martinique','MQ','MTQ','Martinique','019','029',0,0,0,NULL,NULL),(478,'Nouakchott','Mauritanian','478','ouguiya','MRO','khoum','Islamic Republic of Mauritania','MR','MRT','Mauritania','002','011',0,0,0,NULL,NULL),(480,'Port Louis','Mauritian','480','Mauritian rupee','MUR','cent','Republic of Mauritius','MU','MUS','Mauritius','002','014',0,0,0,NULL,NULL),(484,'Mexico City','Mexican','484','Mexican peso','MXN','centavo','United Mexican States','MX','MEX','Mexico','019','013',0,1,0,NULL,NULL),(492,'Monaco','Monegasque','492','euro','EUR','cent','Principality of Monaco','MC','MCO','Monaco','150','155',0,0,0,NULL,NULL),(496,'Ulan Bator','Mongolian','496','tugrik','MNT','möngö (inv.)','Mongolia','MN','MNG','Mongolia','142','030',0,0,0,NULL,NULL),(498,'Chisinau','Moldovan','498','Moldovan leu (pl. lei)','MDL','ban','Republic of Moldova','MD','MDA','Moldova, Republic of','150','151',0,0,0,NULL,NULL),(499,'Podgorica','Montenegrin','499','euro','EUR','cent','Montenegro','ME','MNE','Montenegro','150','039',0,0,0,NULL,NULL),(500,'Plymouth (MS2)','Montserratian','500','East Caribbean dollar','XCD','cent','Montserrat','MS','MSR','Montserrat','019','029',0,0,0,NULL,NULL),(504,'Rabat','Moroccan','504','Moroccan dirham','MAD','centime','Kingdom of Morocco','MA','MAR','Morocco','002','015',0,0,0,NULL,NULL),(508,'Maputo','Mozambican','508','metical','MZN','centavo','Republic of Mozambique','MZ','MOZ','Mozambique','002','014',0,0,0,NULL,NULL),(512,'Muscat','Omani','512','Omani rial','OMR','baiza','Sultanate of Oman','OM','OMN','Oman','142','145',0,0,0,NULL,NULL),(516,'Windhoek','Namibian','516','Namibian dollar','NAD','cent','Republic of Namibia','NA','NAM','Namibia','002','018',0,0,0,NULL,NULL),(520,'Yaren','Nauruan','520','Australian dollar','AUD','cent','Republic of Nauru','NR','NRU','Nauru','009','057',0,0,0,NULL,NULL),(524,'Kathmandu','Nepalese','524','Nepalese rupee','NPR','paisa (inv.)','Nepal','NP','NPL','Nepal','142','034',0,0,0,NULL,NULL),(528,'Amsterdam (NL2)','Dutch','528','euro','EUR','cent','Kingdom of the Netherlands','NL','NLD','Netherlands','150','155',1,1,0,NULL,NULL),(531,'Willemstad','Curaçaoan','531','Netherlands Antillean guilder (CW1)','ANG','cent','Curaçao','CW','CUW','Curaçao','019','029',0,0,0,NULL,NULL),(533,'Oranjestad','Aruban','533','Aruban guilder','AWG','cent','Aruba','AW','ABW','Aruba','019','029',0,0,0,NULL,NULL),(534,'Philipsburg','Sint Maartener','534','Netherlands Antillean guilder (SX1)','ANG','cent','Sint Maarten','SX','SXM','Sint Maarten (Dutch part)','019','029',0,0,0,NULL,NULL),(535,NULL,'of Bonaire, Sint Eustatius and Saba','535','US dollar','USD','cent',NULL,'BQ','BES','Bonaire, Sint Eustatius and Saba','019','029',0,0,0,NULL,NULL),(540,'Nouméa','New Caledonian','540','CFP franc','XPF','centime','New Caledonia','NC','NCL','New Caledonia','009','054',0,0,0,NULL,NULL),(548,'Port Vila','Vanuatuan','548','vatu (inv.)','VUV','','Republic of Vanuatu','VU','VUT','Vanuatu','009','054',0,0,0,NULL,NULL),(554,'Wellington','New Zealander','554','New Zealand dollar','NZD','cent','New Zealand','NZ','NZL','New Zealand','009','053',0,0,0,NULL,NULL),(558,'Managua','Nicaraguan','558','córdoba oro','NIO','centavo','Republic of Nicaragua','NI','NIC','Nicaragua','019','013',0,0,0,NULL,NULL),(562,'Niamey','Nigerien','562','CFA franc (BCEAO)','XOF','centime','Republic of Niger','NE','NER','Niger','002','011',0,0,0,NULL,NULL),(566,'Abuja','Nigerian','566','naira (inv.)','NGN','kobo (inv.)','Federal Republic of Nigeria','NG','NGA','Nigeria','002','011',0,0,0,NULL,NULL),(570,'Alofi','Niuean','570','New Zealand dollar','NZD','cent','Niue','NU','NIU','Niue','009','061',0,0,0,NULL,NULL),(574,'Kingston','Norfolk Islander','574','Australian dollar','AUD','cent','Territory of Norfolk Island','NF','NFK','Norfolk Island','009','053',0,0,0,NULL,NULL),(578,'Oslo','Norwegian','578','Norwegian krone (pl. kroner)','NOK','øre (inv.)','Kingdom of Norway','NO','NOR','Norway','150','154',1,0,0,NULL,NULL),(580,'Saipan','Northern Mariana Islander','580','US dollar','USD','cent','Commonwealth of the Northern Mariana Islands','MP','MNP','Northern Mariana Islands','009','057',0,0,0,NULL,NULL),(581,'United States Minor Outlying Islands','of United States Minor Outlying Islands','581','US dollar','USD','cent','United States Minor Outlying Islands','UM','UMI','United States Minor Outlying Islands','','',0,0,0,NULL,NULL),(583,'Palikir','Micronesian','583','US dollar','USD','cent','Federated States of Micronesia','FM','FSM','Micronesia, Federated States of','009','057',0,0,0,NULL,NULL),(584,'Majuro','Marshallese','584','US dollar','USD','cent','Republic of the Marshall Islands','MH','MHL','Marshall Islands','009','057',0,0,0,NULL,NULL),(585,'Melekeok','Palauan','585','US dollar','USD','cent','Republic of Palau','PW','PLW','Palau','009','057',0,0,0,NULL,NULL),(586,'Islamabad','Pakistani','586','Pakistani rupee','PKR','paisa','Islamic Republic of Pakistan','PK','PAK','Pakistan','142','034',0,0,0,NULL,NULL),(591,'Panama City','Panamanian','591','balboa','PAB','centésimo','Republic of Panama','PA','PAN','Panama','019','013',0,0,0,NULL,NULL),(598,'Port Moresby','Papua New Guinean','598','kina (inv.)','PGK','toea (inv.)','Independent State of Papua New Guinea','PG','PNG','Papua New Guinea','009','054',0,0,0,NULL,NULL),(600,'Asunción','Paraguayan','600','guaraní','PYG','céntimo','Republic of Paraguay','PY','PRY','Paraguay','019','005',0,0,0,NULL,NULL),(604,'Lima','Peruvian','604','new sol','PEN','céntimo','Republic of Peru','PE','PER','Peru','019','005',0,0,0,NULL,NULL),(608,'Manila','Filipino','608','Philippine peso','PHP','centavo','Republic of the Philippines','PH','PHL','Philippines','142','035',0,0,0,NULL,NULL),(612,'Adamstown','Pitcairner','612','New Zealand dollar','NZD','cent','Pitcairn Islands','PN','PCN','Pitcairn','009','061',0,0,0,NULL,NULL),(616,'Warsaw','Polish','616','zloty','PLN','grosz (pl. groszy)','Republic of Poland','PL','POL','Poland','150','151',1,1,1,NULL,NULL),(620,'Lisbon','Portuguese','620','euro','EUR','cent','Portuguese Republic','PT','PRT','Portugal','150','039',1,1,1,NULL,NULL),(624,'Bissau','Guinea-Bissau national','624','CFA franc (BCEAO)','XOF','centime','Republic of Guinea-Bissau','GW','GNB','Guinea-Bissau','002','011',0,0,0,NULL,NULL),(626,'Dili','East Timorese','626','US dollar','USD','cent','Democratic Republic of East Timor','TL','TLS','Timor-Leste','142','035',0,0,0,NULL,NULL),(630,'San Juan','Puerto Rican','630','US dollar','USD','cent','Commonwealth of Puerto Rico','PR','PRI','Puerto Rico','019','029',0,0,0,NULL,NULL),(634,'Doha','Qatari','634','Qatari riyal','QAR','dirham','State of Qatar','QA','QAT','Qatar','142','145',0,0,0,NULL,NULL),(638,'Saint-Denis','Reunionese','638','euro','EUR','cent','Réunion','RE','REU','Réunion','002','014',0,0,0,NULL,NULL),(642,'Bucharest','Romanian','642','Romanian leu (pl. lei)','RON','ban (pl. bani)','Romania','RO','ROU','Romania','150','151',1,0,1,NULL,NULL),(643,'Moscow','Russian','643','Russian rouble','RUB','kopek','Russian Federation','RU','RUS','Russian Federation','150','151',0,0,0,NULL,NULL),(646,'Kigali','Rwandan; Rwandese','646','Rwandese franc','RWF','centime','Republic of Rwanda','RW','RWA','Rwanda','002','014',0,0,0,NULL,NULL),(652,'Gustavia','of Saint Barthélemy','652','euro','EUR','cent','Collectivity of Saint Barthélemy','BL','BLM','Saint Barthélemy','019','029',0,0,0,NULL,NULL),(654,'Jamestown','Saint Helenian','654','Saint Helena pound','SHP','penny','Saint Helena, Ascension and Tristan da Cunha','SH','SHN','Saint Helena, Ascension and Tristan da Cunha','002','011',0,0,0,NULL,NULL),(659,'Basseterre','Kittsian; Nevisian','659','East Caribbean dollar','XCD','cent','Federation of Saint Kitts and Nevis','KN','KNA','Saint Kitts and Nevis','019','029',0,0,0,NULL,NULL),(660,'The Valley','Anguillan','660','East Caribbean dollar','XCD','cent','Anguilla','AI','AIA','Anguilla','019','029',0,0,0,NULL,NULL),(662,'Castries','Saint Lucian','662','East Caribbean dollar','XCD','cent','Saint Lucia','LC','LCA','Saint Lucia','019','029',0,0,0,NULL,NULL),(663,'Marigot','of Saint Martin','663','euro','EUR','cent','Collectivity of Saint Martin','MF','MAF','Saint Martin (French part)','019','029',0,0,0,NULL,NULL),(666,'Saint-Pierre','St-Pierrais; Miquelonnais','666','euro','EUR','cent','Territorial Collectivity of Saint Pierre and Miquelon','PM','SPM','Saint Pierre and Miquelon','019','021',0,0,0,NULL,NULL),(670,'Kingstown','Vincentian','670','East Caribbean dollar','XCD','cent','Saint Vincent and the Grenadines','VC','VCT','Saint Vincent and the Grenadines','019','029',0,0,0,NULL,NULL),(674,'San Marino','San Marinese','674','euro','EUR ','cent','Republic of San Marino','SM','SMR','San Marino','150','039',0,0,0,NULL,NULL),(678,'São Tomé','São Toméan','678','dobra','STD','centavo','Democratic Republic of São Tomé and Príncipe','ST','STP','Sao Tome and Principe','002','017',0,0,0,NULL,NULL),(682,'Riyadh','Saudi Arabian','682','riyal','SAR','halala','Kingdom of Saudi Arabia','SA','SAU','Saudi Arabia','142','145',0,0,0,NULL,NULL),(686,'Dakar','Senegalese','686','CFA franc (BCEAO)','XOF','centime','Republic of Senegal','SN','SEN','Senegal','002','011',0,0,0,NULL,NULL),(688,'Belgrade','Serb','688','Serbian dinar','RSD','para (inv.)','Republic of Serbia','RS','SRB','Serbia','150','039',0,0,0,NULL,NULL),(690,'Victoria','Seychellois','690','Seychelles rupee','SCR','cent','Republic of Seychelles','SC','SYC','Seychelles','002','014',0,0,0,NULL,NULL),(694,'Freetown','Sierra Leonean','694','leone','SLL','cent','Republic of Sierra Leone','SL','SLE','Sierra Leone','002','011',0,0,0,NULL,NULL),(702,'Singapore','Singaporean','702','Singapore dollar','SGD','cent','Republic of Singapore','SG','SGP','Singapore','142','035',0,0,0,NULL,NULL),(703,'Bratislava','Slovak','703','euro','EUR','cent','Slovak Republic','SK','SVK','Slovakia','150','151',1,0,1,NULL,NULL),(704,'Hanoi','Vietnamese','704','dong','VND','(10 hào','Socialist Republic of Vietnam','VN','VNM','Viet Nam','142','035',0,0,0,NULL,NULL),(705,'Ljubljana','Slovene','705','euro','EUR','cent','Republic of Slovenia','SI','SVN','Slovenia','150','039',1,0,1,NULL,NULL),(706,'Mogadishu','Somali','706','Somali shilling','SOS','cent','Somali Republic','SO','SOM','Somalia','002','014',0,0,0,NULL,NULL),(710,'Pretoria (ZA1)','South African','710','rand','ZAR','cent','Republic of South Africa','ZA','ZAF','South Africa','002','018',0,0,0,NULL,NULL),(716,'Harare','Zimbabwean','716','Zimbabwe dollar (ZW1)','ZWL','cent','Republic of Zimbabwe','ZW','ZWE','Zimbabwe','002','014',0,0,0,NULL,NULL),(724,'Madrid','Spaniard','724','euro','EUR','cent','Kingdom of Spain','ES','ESP','Spain','150','039',1,1,1,NULL,NULL),(728,'Juba','South Sudanese','728','South Sudanese pound','SSP','piaster','Republic of South Sudan','SS','SSD','South Sudan','002','015',0,0,0,NULL,NULL),(729,'Khartoum','Sudanese','729','Sudanese pound','SDG','piastre','Republic of the Sudan','SD','SDN','Sudan','002','015',0,0,0,NULL,NULL),(732,'Al aaiun','Sahrawi','732','Moroccan dirham','MAD','centime','Western Sahara','EH','ESH','Western Sahara','002','015',0,0,0,NULL,NULL),(740,'Paramaribo','Surinamese','740','Surinamese dollar','SRD','cent','Republic of Suriname','SR','SUR','Suriname','019','005',0,0,0,NULL,NULL),(744,'Longyearbyen','of Svalbard','744','Norwegian krone (pl. kroner)','NOK','øre (inv.)','Svalbard and Jan Mayen','SJ','SJM','Svalbard and Jan Mayen','150','154',0,0,0,NULL,NULL),(748,'Mbabane','Swazi','748','lilangeni','SZL','cent','Kingdom of Swaziland','SZ','SWZ','Swaziland','002','018',0,0,0,NULL,NULL),(752,'Stockholm','Swedish','752','krona (pl. kronor)','SEK','öre (inv.)','Kingdom of Sweden','SE','SWE','Sweden','150','154',1,1,1,NULL,NULL),(756,'Berne','Swiss','756','Swiss franc','CHF','centime','Swiss Confederation','CH','CHE','Switzerland','150','155',1,1,0,NULL,NULL),(760,'Damascus','Syrian','760','Syrian pound','SYP','piastre','Syrian Arab Republic','SY','SYR','Syrian Arab Republic','142','145',0,0,0,NULL,NULL),(762,'Dushanbe','Tajik','762','somoni','TJS','diram','Republic of Tajikistan','TJ','TJK','Tajikistan','142','143',0,0,0,NULL,NULL),(764,'Bangkok','Thai','764','baht (inv.)','THB','satang (inv.)','Kingdom of Thailand','TH','THA','Thailand','142','035',0,0,0,NULL,NULL),(768,'Lomé','Togolese','768','CFA franc (BCEAO)','XOF','centime','Togolese Republic','TG','TGO','Togo','002','011',0,0,0,NULL,NULL),(772,'(TK2)','Tokelauan','772','New Zealand dollar','NZD','cent','Tokelau','TK','TKL','Tokelau','009','061',0,0,0,NULL,NULL),(776,'Nuku’alofa','Tongan','776','pa’anga (inv.)','TOP','seniti (inv.)','Kingdom of Tonga','TO','TON','Tonga','009','061',0,0,0,NULL,NULL),(780,'Port of Spain','Trinidadian; Tobagonian','780','Trinidad and Tobago dollar','TTD','cent','Republic of Trinidad and Tobago','TT','TTO','Trinidad and Tobago','019','029',0,0,0,NULL,NULL),(784,'Abu Dhabi','Emirian','784','UAE dirham','AED','fils (inv.)','United Arab Emirates','AE','ARE','United Arab Emirates','142','145',0,0,0,NULL,NULL),(788,'Tunis','Tunisian','788','Tunisian dinar','TND','millime','Republic of Tunisia','TN','TUN','Tunisia','002','015',0,0,0,NULL,NULL),(792,'Ankara','Turk','792','Turkish lira (inv.)','TRY','kurus (inv.)','Republic of Turkey','TR','TUR','Turkey','142','145',0,0,0,NULL,NULL),(795,'Ashgabat','Turkmen','795','Turkmen manat (inv.)','TMT','tenge (inv.)','Turkmenistan','TM','TKM','Turkmenistan','142','143',0,0,0,NULL,NULL),(796,'Cockburn Town','Turks and Caicos Islander','796','US dollar','USD','cent','Turks and Caicos Islands','TC','TCA','Turks and Caicos Islands','019','029',0,0,0,NULL,NULL),(798,'Funafuti','Tuvaluan','798','Australian dollar','AUD','cent','Tuvalu','TV','TUV','Tuvalu','009','061',0,0,0,NULL,NULL),(800,'Kampala','Ugandan','800','Uganda shilling','UGX','cent','Republic of Uganda','UG','UGA','Uganda','002','014',0,0,0,NULL,NULL),(804,'Kiev','Ukrainian','804','hryvnia','UAH','kopiyka','Ukraine','UA','UKR','Ukraine','150','151',0,0,0,NULL,NULL),(807,'Skopje','of the former Yugoslav Republic of Macedonia','807','denar (pl. denars)','MKD','deni (inv.)','the former Yugoslav Republic of Macedonia','MK','MKD','Macedonia, the former Yugoslav Republic of','150','039',0,0,0,NULL,NULL),(818,'Cairo','Egyptian','818','Egyptian pound','EGP','piastre','Arab Republic of Egypt','EG','EGY','Egypt','002','015',0,0,0,NULL,NULL),(826,'London','British','826','pound sterling','GBP','penny (pl. pence)','United Kingdom of Great Britain and Northern Ireland','GB','GBR','United Kingdom','150','154',1,0,0,NULL,NULL),(831,'St Peter Port','of Guernsey','831','Guernsey pound (GG2)','GGP (GG2)','penny (pl. pence)','Bailiwick of Guernsey','GG','GGY','Guernsey','150','154',0,0,0,NULL,NULL),(832,'St Helier','of Jersey','832','Jersey pound (JE2)','JEP (JE2)','penny (pl. pence)','Bailiwick of Jersey','JE','JEY','Jersey','150','154',0,0,0,NULL,NULL),(833,'Douglas','Manxman; Manxwoman','833','Manx pound (IM2)','IMP (IM2)','penny (pl. pence)','Isle of Man','IM','IMN','Isle of Man','150','154',0,0,0,NULL,NULL),(834,'Dodoma (TZ1)','Tanzanian','834','Tanzanian shilling','TZS','cent','United Republic of Tanzania','TZ','TZA','Tanzania, United Republic of','002','014',0,0,0,NULL,NULL),(840,'Washington DC','American','840','US dollar','USD','cent','United States of America','US','USA','United States','019','021',0,0,0,',','.'),(850,'Charlotte Amalie','US Virgin Islander','850','US dollar','USD','cent','United States Virgin Islands','VI','VIR','Virgin Islands, U.S.','019','029',0,0,0,NULL,NULL),(854,'Ouagadougou','Burkinabe','854','CFA franc (BCEAO)','XOF','centime','Burkina Faso','BF','BFA','Burkina Faso','002','011',0,0,0,NULL,NULL),(858,'Montevideo','Uruguayan','858','Uruguayan peso','UYU','centésimo','Eastern Republic of Uruguay','UY','URY','Uruguay','019','005',0,1,0,NULL,NULL),(860,'Tashkent','Uzbek','860','sum (inv.)','UZS','tiyin (inv.)','Republic of Uzbekistan','UZ','UZB','Uzbekistan','142','143',0,0,0,NULL,NULL),(862,'Caracas','Venezuelan','862','bolívar fuerte (pl. bolívares fuertes)','VEF','céntimo','Bolivarian Republic of Venezuela','VE','VEN','Venezuela, Bolivarian Republic of','019','005',0,0,0,NULL,NULL),(876,'Mata-Utu','Wallisian; Futunan; Wallis and Futuna Islander','876','CFP franc','XPF','centime','Wallis and Futuna','WF','WLF','Wallis and Futuna','009','061',0,0,0,NULL,NULL),(882,'Apia','Samoan','882','tala (inv.)','WST','sene (inv.)','Independent State of Samoa','WS','WSM','Samoa','009','061',0,0,0,NULL,NULL),(887,'San’a','Yemenite','887','Yemeni rial','YER','fils (inv.)','Republic of Yemen','YE','YEM','Yemen','142','145',0,0,0,NULL,NULL),(894,'Lusaka','Zambian','894','Zambian kwacha (inv.)','ZMW','ngwee (inv.)','Republic of Zambia','ZM','ZMB','Zambia','002','014',0,0,0,NULL,NULL);
+INSERT INTO `countries` VALUES (4,'Kabul','Afghan','004','afghani','AFN','pul','Islamic Republic of Afghanistan','AF','AFG','Afghanistan','142','034',0,0,0,NULL,NULL),(8,'Tirana','Albanian','008','lek','ALL','(qindar (pl. qindarka))','Republic of Albania','AL','ALB','Albania','150','039',0,0,0,NULL,NULL),(10,'Antartica','of Antartica','010','','','','Antarctica','AQ','ATA','Antarctica','','',0,0,0,NULL,NULL),(12,'Algiers','Algerian','012','Algerian dinar','DZD','centime','People’s Democratic Republic of Algeria','DZ','DZA','Algeria','002','015',0,0,0,NULL,NULL),(16,'Pago Pago','American Samoan','016','US dollar','USD','cent','Territory of American','AS','ASM','American Samoa','009','061',0,0,0,NULL,NULL),(20,'Andorra la Vella','Andorran','020','euro','EUR','cent','Principality of Andorra','AD','AND','Andorra','150','039',0,0,0,NULL,NULL),(24,'Luanda','Angolan','024','kwanza','AOA','cêntimo','Republic of Angola','AO','AGO','Angola','002','017',0,0,0,NULL,NULL),(28,'St John’s','of Antigua and Barbuda','028','East Caribbean dollar','XCD','cent','Antigua and Barbuda','AG','ATG','Antigua and Barbuda','019','029',0,0,0,NULL,NULL),(31,'Baku','Azerbaijani','031','Azerbaijani manat','AZN','kepik (inv.)','Republic of Azerbaijan','AZ','AZE','Azerbaijan','142','145',0,0,0,NULL,NULL),(32,'Buenos Aires','Argentinian','032','Argentine peso','ARS','centavo','Argentine Republic','AR','ARG','Argentina','019','005',0,1,0,NULL,NULL),(36,'Canberra','Australian','036','Australian dollar','AUD','cent','Commonwealth of Australia','AU','AUS','Australia','009','053',0,0,0,NULL,NULL),(40,'Vienna','Austrian','040','euro','EUR','cent','Republic of Austria','AT','AUT','Austria','150','155',1,1,1,NULL,NULL),(44,'Nassau','Bahamian','044','Bahamian dollar','BSD','cent','Commonwealth of the Bahamas','BS','BHS','Bahamas','019','029',0,0,0,NULL,NULL),(48,'Manama','Bahraini','048','Bahraini dinar','BHD','fils (inv.)','Kingdom of Bahrain','BH','BHR','Bahrain','142','145',0,0,0,NULL,NULL),(50,'Dhaka','Bangladeshi','050','taka (inv.)','BDT','poisha (inv.)','People’s Republic of Bangladesh','BD','BGD','Bangladesh','142','034',0,0,0,NULL,NULL),(51,'Yerevan','Armenian','051','dram (inv.)','AMD','luma','Republic of Armenia','AM','ARM','Armenia','142','145',0,0,0,NULL,NULL),(52,'Bridgetown','Barbadian','052','Barbados dollar','BBD','cent','Barbados','BB','BRB','Barbados','019','029',0,0,0,NULL,NULL),(56,'Brussels','Belgian','056','euro','EUR','cent','Kingdom of Belgium','BE','BEL','Belgium','150','155',1,1,0,NULL,NULL),(60,'Hamilton','Bermudian','060','Bermuda dollar','BMD','cent','Bermuda','BM','BMU','Bermuda','019','021',0,0,0,NULL,NULL),(64,'Thimphu','Bhutanese','064','ngultrum (inv.)','BTN','chhetrum (inv.)','Kingdom of Bhutan','BT','BTN','Bhutan','142','034',0,0,0,NULL,NULL),(68,'Sucre (BO1)','Bolivian','068','boliviano','BOB','centavo','Plurinational State of Bolivia','BO','BOL','Bolivia, Plurinational State of','019','005',0,0,0,NULL,NULL),(70,'Sarajevo','of Bosnia and Herzegovina','070','convertible mark','BAM','fening','Bosnia and Herzegovina','BA','BIH','Bosnia and Herzegovina','150','039',0,0,0,NULL,NULL),(72,'Gaborone','Botswanan','072','pula (inv.)','BWP','thebe (inv.)','Republic of Botswana','BW','BWA','Botswana','002','018',0,0,0,NULL,NULL),(74,'Bouvet island','of Bouvet island','074','','','','Bouvet Island','BV','BVT','Bouvet Island','','',0,0,0,NULL,NULL),(76,'Brasilia','Brazilian','076','real (pl. reais)','BRL','centavo','Federative Republic of Brazil','BR','BRA','Brazil','019','005',0,0,0,NULL,NULL),(84,'Belmopan','Belizean','084','Belize dollar','BZD','cent','Belize','BZ','BLZ','Belize','019','013',0,0,0,NULL,NULL),(86,'Diego Garcia','Changosian','086','US dollar','USD','cent','British Indian Ocean Territory','IO','IOT','British Indian Ocean Territory','','',0,0,0,NULL,NULL),(90,'Honiara','Solomon Islander','090','Solomon Islands dollar','SBD','cent','Solomon Islands','SB','SLB','Solomon Islands','009','054',0,0,0,NULL,NULL),(92,'Road Town','British Virgin Islander;','092','US dollar','USD','cent','British Virgin Islands','VG','VGB','Virgin Islands, British','019','029',0,0,0,NULL,NULL),(96,'Bandar Seri Begawan','Bruneian','096','Brunei dollar','BND','sen (inv.)','Brunei Darussalam','BN','BRN','Brunei Darussalam','142','035',0,0,0,NULL,NULL),(100,'Sofia','Bulgarian','100','lev (pl. leva)','BGN','stotinka','Republic of Bulgaria','BG','BGR','Bulgaria','150','151',1,0,1,NULL,NULL),(104,'Yangon','Burmese','104','kyat','MMK','pya','Union of Myanmar/','MM','MMR','Myanmar','142','035',0,0,0,NULL,NULL),(108,'Bujumbura','Burundian','108','Burundi franc','BIF','centime','Republic of Burundi','BI','BDI','Burundi','002','014',0,0,0,NULL,NULL),(112,'Minsk','Belarusian','112','Belarusian rouble','BYR','kopek','Republic of Belarus','BY','BLR','Belarus','150','151',0,0,0,NULL,NULL),(116,'Phnom Penh','Cambodian','116','riel','KHR','sen (inv.)','Kingdom of Cambodia','KH','KHM','Cambodia','142','035',0,0,0,NULL,NULL),(120,'Yaoundé','Cameroonian','120','CFA franc (BEAC)','XAF','centime','Republic of Cameroon','CM','CMR','Cameroon','002','017',0,0,0,NULL,NULL),(124,'Ottawa','Canadian','124','Canadian dollar','CAD','cent','Canada','CA','CAN','Canada','019','021',0,0,0,NULL,NULL),(132,'Praia','Cape Verdean','132','Cape Verde escudo','CVE','centavo','Republic of Cape Verde','CV','CPV','Cape Verde','002','011',0,0,0,NULL,NULL),(136,'George Town','Caymanian','136','Cayman Islands dollar','KYD','cent','Cayman Islands','KY','CYM','Cayman Islands','019','029',0,0,0,NULL,NULL),(140,'Bangui','Central African','140','CFA franc (BEAC)','XAF','centime','Central African Republic','CF','CAF','Central African Republic','002','017',0,0,0,NULL,NULL),(144,'Colombo','Sri Lankan','144','Sri Lankan rupee','LKR','cent','Democratic Socialist Republic of Sri Lanka','LK','LKA','Sri Lanka','142','034',0,0,0,NULL,NULL),(148,'N’Djamena','Chadian','148','CFA franc (BEAC)','XAF','centime','Republic of Chad','TD','TCD','Chad','002','017',0,0,0,NULL,NULL),(152,'Santiago','Chilean','152','Chilean peso','CLP','centavo','Republic of Chile','CL','CHL','Chile','019','005',0,0,0,NULL,NULL),(156,'Beijing','Chinese','156','renminbi-yuan (inv.)','CNY','jiao (10)','People’s Republic of China','CN','CHN','China','142','030',0,0,0,NULL,NULL),(158,'Taipei','Taiwanese','158','new Taiwan dollar','TWD','fen (inv.)','Republic of China, Taiwan (TW1)','TW','TWN','Taiwan, Province of China','142','030',0,0,0,NULL,NULL),(162,'Flying Fish Cove','Christmas Islander','162','Australian dollar','AUD','cent','Christmas Island Territory','CX','CXR','Christmas Island','','',0,0,0,NULL,NULL),(166,'Bantam','Cocos Islander','166','Australian dollar','AUD','cent','Territory of Cocos (Keeling) Islands','CC','CCK','Cocos (Keeling) Islands','','',0,0,0,NULL,NULL),(170,'Santa Fe de Bogotá','Colombian','170','Colombian peso','COP','centavo','Republic of Colombia','CO','COL','Colombia','019','005',0,0,0,NULL,NULL),(174,'Moroni','Comorian','174','Comorian franc','KMF','','Union of the Comoros','KM','COM','Comoros','002','014',0,0,0,NULL,NULL),(175,'Mamoudzou','Mahorais','175','euro','EUR','cent','Departmental Collectivity of Mayotte','YT','MYT','Mayotte','002','014',0,0,0,NULL,NULL),(178,'Brazzaville','Congolese','178','CFA franc (BEAC)','XAF','centime','Republic of the Congo','CG','COG','Congo','002','017',0,0,0,NULL,NULL),(180,'Kinshasa','Congolese','180','Congolese franc','CDF','centime','Democratic Republic of the Congo','CD','COD','Congo, the Democratic Republic of the','002','017',0,0,0,NULL,NULL),(184,'Avarua','Cook Islander','184','New Zealand dollar','NZD','cent','Cook Islands','CK','COK','Cook Islands','009','061',0,0,0,NULL,NULL),(188,'San José','Costa Rican','188','Costa Rican colón (pl. colones)','CRC','céntimo','Republic of Costa Rica','CR','CRI','Costa Rica','019','013',0,0,0,NULL,NULL),(191,'Zagreb','Croatian','191','kuna (inv.)','HRK','lipa (inv.)','Republic of Croatia','HR','HRV','Croatia','150','039',1,0,1,NULL,NULL),(192,'Havana','Cuban','192','Cuban peso','CUP','centavo','Republic of Cuba','CU','CUB','Cuba','019','029',0,0,0,NULL,NULL),(196,'Nicosia','Cypriot','196','euro','EUR','cent','Republic of Cyprus','CY','CYP','Cyprus','142','145',1,0,0,NULL,NULL),(203,'Prague','Czech','203','Czech koruna (pl. koruny)','CZK','halér','Czech Republic','CZ','CZE','Czech Republic','150','151',1,0,1,NULL,NULL),(204,'Porto Novo (BJ1)','Beninese','204','CFA franc (BCEAO)','XOF','centime','Republic of Benin','BJ','BEN','Benin','002','011',0,0,0,NULL,NULL),(208,'Copenhagen','Danish','208','Danish krone','DKK','øre (inv.)','Kingdom of Denmark','DK','DNK','Denmark','150','154',1,1,0,NULL,NULL),(212,'Roseau','Dominican','212','East Caribbean dollar','XCD','cent','Commonwealth of Dominica','DM','DMA','Dominica','019','029',0,0,0,NULL,NULL),(214,'Santo Domingo','Dominican','214','Dominican peso','DOP','centavo','Dominican Republic','DO','DOM','Dominican Republic','019','029',0,0,0,NULL,NULL),(218,'Quito','Ecuadorian','218','US dollar','USD','cent','Republic of Ecuador','EC','ECU','Ecuador','019','005',0,0,0,NULL,NULL),(222,'San Salvador','Salvadoran','222','Salvadorian colón (pl. colones)','SVC','centavo','Republic of El Salvador','SV','SLV','El Salvador','019','013',0,0,0,NULL,NULL),(226,'Malabo','Equatorial Guinean','226','CFA franc (BEAC)','XAF','centime','Republic of Equatorial Guinea','GQ','GNQ','Equatorial Guinea','002','017',0,0,0,NULL,NULL),(231,'Addis Ababa','Ethiopian','231','birr (inv.)','ETB','cent','Federal Democratic Republic of Ethiopia','ET','ETH','Ethiopia','002','014',0,0,0,NULL,NULL),(232,'Asmara','Eritrean','232','nakfa','ERN','cent','State of Eritrea','ER','ERI','Eritrea','002','014',0,0,0,NULL,NULL),(233,'Tallinn','Estonian','233','euro','EUR','cent','Republic of Estonia','EE','EST','Estonia','150','154',1,0,1,NULL,NULL),(234,'Tórshavn','Faeroese','234','Danish krone','DKK','øre (inv.)','Faeroe Islands','FO','FRO','Faroe Islands','150','154',0,0,0,NULL,NULL),(238,'Stanley','Falkland Islander','238','Falkland Islands pound','FKP','new penny','Falkland Islands','FK','FLK','Falkland Islands (Malvinas)','019','005',0,0,0,NULL,NULL),(239,'King Edward Point (Grytviken)','of South Georgia and the South Sandwich Islands','239','','','','South Georgia and the South Sandwich Islands','GS','SGS','South Georgia and the South Sandwich Islands','','',0,0,0,NULL,NULL),(242,'Suva','Fijian','242','Fiji dollar','FJD','cent','Republic of Fiji','FJ','FJI','Fiji','009','054',0,0,0,NULL,NULL),(246,'Helsinki','Finnish','246','euro','EUR','cent','Republic of Finland','FI','FIN','Finland','150','154',1,1,1,NULL,NULL),(248,'Mariehamn','Åland Islander','248','euro','EUR','cent','Åland Islands','AX','ALA','Åland Islands','150','154',0,0,0,NULL,NULL),(250,'Paris','French','250','euro','EUR','cent','French Republic','FR','FRA','France','150','155',1,1,1,NULL,NULL),(254,'Cayenne','Guianese','254','euro','EUR','cent','French Guiana','GF','GUF','French Guiana','019','005',0,0,0,NULL,NULL),(258,'Papeete','Polynesian','258','CFP franc','XPF','centime','French Polynesia','PF','PYF','French Polynesia','009','061',0,0,0,NULL,NULL),(260,'Port-aux-Francais','of French Southern and Antarctic Lands','260','euro','EUR','cent','French Southern and Antarctic Lands','TF','ATF','French Southern Territories','','',0,0,0,NULL,NULL),(262,'Djibouti','Djiboutian','262','Djibouti franc','DJF','','Republic of Djibouti','DJ','DJI','Djibouti','002','014',0,0,0,NULL,NULL),(266,'Libreville','Gabonese','266','CFA franc (BEAC)','XAF','centime','Gabonese Republic','GA','GAB','Gabon','002','017',0,0,0,NULL,NULL),(268,'Tbilisi','Georgian','268','lari','GEL','tetri (inv.)','Georgia','GE','GEO','Georgia','142','145',0,0,0,NULL,NULL),(270,'Banjul','Gambian','270','dalasi (inv.)','GMD','butut','Republic of the Gambia','GM','GMB','Gambia','002','011',0,0,0,NULL,NULL),(275,NULL,'Palestinian','275',NULL,NULL,NULL,NULL,'PS','PSE','Palestinian Territory, Occupied','142','145',0,0,0,NULL,NULL),(276,'Berlin','German','276','euro','EUR','cent','Federal Republic of Germany','DE','DEU','Germany','150','155',1,1,1,NULL,NULL),(288,'Accra','Ghanaian','288','Ghana cedi','GHS','pesewa','Republic of Ghana','GH','GHA','Ghana','002','011',0,0,0,NULL,NULL),(292,'Gibraltar','Gibraltarian','292','Gibraltar pound','GIP','penny','Gibraltar','GI','GIB','Gibraltar','150','039',0,0,0,NULL,NULL),(296,'Tarawa','Kiribatian','296','Australian dollar','AUD','cent','Republic of Kiribati','KI','KIR','Kiribati','009','057',0,0,0,NULL,NULL),(300,'Athens','Greek','300','euro','EUR','cent','Hellenic Republic','GR','GRC','Greece','150','039',1,0,1,NULL,NULL),(304,'Nuuk','Greenlander','304','Danish krone','DKK','øre (inv.)','Greenland','GL','GRL','Greenland','019','021',0,1,0,NULL,NULL),(308,'St George’s','Grenadian','308','East Caribbean dollar','XCD','cent','Grenada','GD','GRD','Grenada','019','029',0,0,0,NULL,NULL),(312,'Basse Terre','Guadeloupean','312','euro','EUR ','cent','Guadeloupe','GP','GLP','Guadeloupe','019','029',0,0,0,NULL,NULL),(316,'Agaña (Hagåtña)','Guamanian','316','US dollar','USD','cent','Territory of Guam','GU','GUM','Guam','009','057',0,0,0,NULL,NULL),(320,'Guatemala City','Guatemalan','320','quetzal (pl. quetzales)','GTQ','centavo','Republic of Guatemala','GT','GTM','Guatemala','019','013',0,0,0,NULL,NULL),(324,'Conakry','Guinean','324','Guinean franc','GNF','','Republic of Guinea','GN','GIN','Guinea','002','011',0,0,0,NULL,NULL),(328,'Georgetown','Guyanese','328','Guyana dollar','GYD','cent','Cooperative Republic of Guyana','GY','GUY','Guyana','019','005',0,0,0,NULL,NULL),(332,'Port-au-Prince','Haitian','332','gourde','HTG','centime','Republic of Haiti','HT','HTI','Haiti','019','029',0,0,0,NULL,NULL),(334,'Territory of Heard Island and McDonald Islands','of Territory of Heard Island and McDonald Islands','334','','','','Territory of Heard Island and McDonald Islands','HM','HMD','Heard Island and McDonald Islands','','',0,0,0,NULL,NULL),(336,'Vatican City','of the Holy See/of the Vatican','336','euro','EUR','cent','the Holy See/ Vatican City State','VA','VAT','Holy See (Vatican City State)','150','039',0,0,0,NULL,NULL),(340,'Tegucigalpa','Honduran','340','lempira','HNL','centavo','Republic of Honduras','HN','HND','Honduras','019','013',0,0,0,NULL,NULL),(344,'(HK3)','Hong Kong Chinese','344','Hong Kong dollar','HKD','cent','Hong Kong Special Administrative Region of the People’s Republic of China (HK2)','HK','HKG','Hong Kong','142','030',0,0,0,NULL,NULL),(348,'Budapest','Hungarian','348','forint (inv.)','HUF','(fillér (inv.))','Republic of Hungary','HU','HUN','Hungary','150','151',1,0,1,NULL,NULL),(352,'Reykjavik','Icelander','352','króna (pl. krónur)','ISK','','Republic of Iceland','IS','ISL','Iceland','150','154',0,1,1,NULL,NULL),(356,'New Delhi','Indian','356','Indian rupee','INR','paisa','Republic of India','IN','IND','India','142','034',0,0,0,NULL,NULL),(360,'Jakarta','Indonesian','360','Indonesian rupiah (inv.)','IDR','sen (inv.)','Republic of Indonesia','ID','IDN','Indonesia','142','035',0,0,0,NULL,NULL),(364,'Tehran','Iranian','364','Iranian rial','IRR','(dinar) (IR1)','Islamic Republic of Iran','IR','IRN','Iran, Islamic Republic of','142','034',0,0,0,NULL,NULL),(368,'Baghdad','Iraqi','368','Iraqi dinar','IQD','fils (inv.)','Republic of Iraq','IQ','IRQ','Iraq','142','145',0,0,0,NULL,NULL),(372,'Dublin','Irish','372','euro','EUR','cent','Ireland (IE1)','IE','IRL','Ireland','150','154',1,0,0,',','.'),(376,'(IL1)','Israeli','376','shekel','ILS','agora','State of Israel','IL','ISR','Israel','142','145',0,1,0,NULL,NULL),(380,'Rome','Italian','380','euro','EUR','cent','Italian Republic','IT','ITA','Italy','150','039',1,1,1,NULL,NULL),(384,'Yamoussoukro (CI1)','Ivorian','384','CFA franc (BCEAO)','XOF','centime','Republic of Côte d’Ivoire','CI','CIV','Côte d\'Ivoire','002','011',0,0,0,NULL,NULL),(388,'Kingston','Jamaican','388','Jamaica dollar','JMD','cent','Jamaica','JM','JAM','Jamaica','019','029',0,0,0,NULL,NULL),(392,'Tokyo','Japanese','392','yen (inv.)','JPY','(sen (inv.)) (JP1)','Japan','JP','JPN','Japan','142','030',0,1,1,NULL,NULL),(398,'Astana','Kazakh','398','tenge (inv.)','KZT','tiyn','Republic of Kazakhstan','KZ','KAZ','Kazakhstan','142','143',0,0,0,NULL,NULL),(400,'Amman','Jordanian','400','Jordanian dinar','JOD','100 qirsh','Hashemite Kingdom of Jordan','JO','JOR','Jordan','142','145',0,0,0,NULL,NULL),(404,'Nairobi','Kenyan','404','Kenyan shilling','KES','cent','Republic of Kenya','KE','KEN','Kenya','002','014',0,0,0,NULL,NULL),(408,'Pyongyang','North Korean','408','North Korean won (inv.)','KPW','chun (inv.)','Democratic People’s Republic of Korea','KP','PRK','Korea, Democratic People\'s Republic of','142','030',0,0,0,NULL,NULL),(410,'Seoul','South Korean','410','South Korean won (inv.)','KRW','(chun (inv.))','Republic of Korea','KR','KOR','Korea, Republic of','142','030',0,0,0,NULL,NULL),(414,'Kuwait City','Kuwaiti','414','Kuwaiti dinar','KWD','fils (inv.)','State of Kuwait','KW','KWT','Kuwait','142','145',0,0,0,NULL,NULL),(417,'Bishkek','Kyrgyz','417','som','KGS','tyiyn','Kyrgyz Republic','KG','KGZ','Kyrgyzstan','142','143',0,0,0,NULL,NULL),(418,'Vientiane','Lao','418','kip (inv.)','LAK','(at (inv.))','Lao People’s Democratic Republic','LA','LAO','Lao People\'s Democratic Republic','142','035',0,0,0,NULL,NULL),(422,'Beirut','Lebanese','422','Lebanese pound','LBP','(piastre)','Lebanese Republic','LB','LBN','Lebanon','142','145',0,0,0,NULL,NULL),(426,'Maseru','Basotho','426','loti (pl. maloti)','LSL','sente','Kingdom of Lesotho','LS','LSO','Lesotho','002','018',0,0,0,NULL,NULL),(428,'Riga','Latvian','428','euro','EUR','cent','Republic of Latvia','LV','LVA','Latvia','150','154',1,0,0,NULL,NULL),(430,'Monrovia','Liberian','430','Liberian dollar','LRD','cent','Republic of Liberia','LR','LBR','Liberia','002','011',0,0,0,NULL,NULL),(434,'Tripoli','Libyan','434','Libyan dinar','LYD','dirham','Socialist People’s Libyan Arab Jamahiriya','LY','LBY','Libya','002','015',0,0,0,NULL,NULL),(438,'Vaduz','Liechtensteiner','438','Swiss franc','CHF','centime','Principality of Liechtenstein','LI','LIE','Liechtenstein','150','155',0,0,0,NULL,NULL),(440,'Vilnius','Lithuanian','440','euro','EUR','cent','Republic of Lithuania','LT','LTU','Lithuania','150','154',1,0,1,NULL,NULL),(442,'Luxembourg','Luxembourger','442','euro','EUR','cent','Grand Duchy of Luxembourg','LU','LUX','Luxembourg','150','155',1,1,0,NULL,NULL),(446,'Macao (MO3)','Macanese','446','pataca','MOP','avo','Macao Special Administrative Region of the People’s Republic of China (MO2)','MO','MAC','Macao','142','030',0,0,0,NULL,NULL),(450,'Antananarivo','Malagasy','450','ariary','MGA','iraimbilanja (inv.)','Republic of Madagascar','MG','MDG','Madagascar','002','014',0,0,0,NULL,NULL),(454,'Lilongwe','Malawian','454','Malawian kwacha (inv.)','MWK','tambala (inv.)','Republic of Malawi','MW','MWI','Malawi','002','014',0,0,0,NULL,NULL),(458,'Kuala Lumpur (MY1)','Malaysian','458','ringgit (inv.)','MYR','sen (inv.)','Malaysia','MY','MYS','Malaysia','142','035',0,1,0,NULL,NULL),(462,'Malé','Maldivian','462','rufiyaa','MVR','laari (inv.)','Republic of Maldives','MV','MDV','Maldives','142','034',0,0,0,NULL,NULL),(466,'Bamako','Malian','466','CFA franc (BCEAO)','XOF','centime','Republic of Mali','ML','MLI','Mali','002','011',0,0,0,NULL,NULL),(470,'Valletta','Maltese','470','euro','EUR','cent','Republic of Malta','MT','MLT','Malta','150','039',1,0,0,NULL,NULL),(474,'Fort-de-France','Martinican','474','euro','EUR','cent','Martinique','MQ','MTQ','Martinique','019','029',0,0,0,NULL,NULL),(478,'Nouakchott','Mauritanian','478','ouguiya','MRO','khoum','Islamic Republic of Mauritania','MR','MRT','Mauritania','002','011',0,0,0,NULL,NULL),(480,'Port Louis','Mauritian','480','Mauritian rupee','MUR','cent','Republic of Mauritius','MU','MUS','Mauritius','002','014',0,0,0,NULL,NULL),(484,'Mexico City','Mexican','484','Mexican peso','MXN','centavo','United Mexican States','MX','MEX','Mexico','019','013',0,1,0,NULL,NULL),(492,'Monaco','Monegasque','492','euro','EUR','cent','Principality of Monaco','MC','MCO','Monaco','150','155',0,0,0,NULL,NULL),(496,'Ulan Bator','Mongolian','496','tugrik','MNT','möngö (inv.)','Mongolia','MN','MNG','Mongolia','142','030',0,0,0,NULL,NULL),(498,'Chisinau','Moldovan','498','Moldovan leu (pl. lei)','MDL','ban','Republic of Moldova','MD','MDA','Moldova, Republic of','150','151',0,0,0,NULL,NULL),(499,'Podgorica','Montenegrin','499','euro','EUR','cent','Montenegro','ME','MNE','Montenegro','150','039',0,0,0,NULL,NULL),(500,'Plymouth (MS2)','Montserratian','500','East Caribbean dollar','XCD','cent','Montserrat','MS','MSR','Montserrat','019','029',0,0,0,NULL,NULL),(504,'Rabat','Moroccan','504','Moroccan dirham','MAD','centime','Kingdom of Morocco','MA','MAR','Morocco','002','015',0,0,0,NULL,NULL),(508,'Maputo','Mozambican','508','metical','MZN','centavo','Republic of Mozambique','MZ','MOZ','Mozambique','002','014',0,0,0,NULL,NULL),(512,'Muscat','Omani','512','Omani rial','OMR','baiza','Sultanate of Oman','OM','OMN','Oman','142','145',0,0,0,NULL,NULL),(516,'Windhoek','Namibian','516','Namibian dollar','NAD','cent','Republic of Namibia','NA','NAM','Namibia','002','018',0,0,0,NULL,NULL),(520,'Yaren','Nauruan','520','Australian dollar','AUD','cent','Republic of Nauru','NR','NRU','Nauru','009','057',0,0,0,NULL,NULL),(524,'Kathmandu','Nepalese','524','Nepalese rupee','NPR','paisa (inv.)','Nepal','NP','NPL','Nepal','142','034',0,0,0,NULL,NULL),(528,'Amsterdam (NL2)','Dutch','528','euro','EUR','cent','Kingdom of the Netherlands','NL','NLD','Netherlands','150','155',1,1,0,NULL,NULL),(531,'Willemstad','Curaçaoan','531','Netherlands Antillean guilder (CW1)','ANG','cent','Curaçao','CW','CUW','Curaçao','019','029',0,0,0,NULL,NULL),(533,'Oranjestad','Aruban','533','Aruban guilder','AWG','cent','Aruba','AW','ABW','Aruba','019','029',0,0,0,NULL,NULL),(534,'Philipsburg','Sint Maartener','534','Netherlands Antillean guilder (SX1)','ANG','cent','Sint Maarten','SX','SXM','Sint Maarten (Dutch part)','019','029',0,0,0,NULL,NULL),(535,NULL,'of Bonaire, Sint Eustatius and Saba','535','US dollar','USD','cent',NULL,'BQ','BES','Bonaire, Sint Eustatius and Saba','019','029',0,0,0,NULL,NULL),(540,'Nouméa','New Caledonian','540','CFP franc','XPF','centime','New Caledonia','NC','NCL','New Caledonia','009','054',0,0,0,NULL,NULL),(548,'Port Vila','Vanuatuan','548','vatu (inv.)','VUV','','Republic of Vanuatu','VU','VUT','Vanuatu','009','054',0,0,0,NULL,NULL),(554,'Wellington','New Zealander','554','New Zealand dollar','NZD','cent','New Zealand','NZ','NZL','New Zealand','009','053',0,0,0,NULL,NULL),(558,'Managua','Nicaraguan','558','córdoba oro','NIO','centavo','Republic of Nicaragua','NI','NIC','Nicaragua','019','013',0,0,0,NULL,NULL),(562,'Niamey','Nigerien','562','CFA franc (BCEAO)','XOF','centime','Republic of Niger','NE','NER','Niger','002','011',0,0,0,NULL,NULL),(566,'Abuja','Nigerian','566','naira (inv.)','NGN','kobo (inv.)','Federal Republic of Nigeria','NG','NGA','Nigeria','002','011',0,0,0,NULL,NULL),(570,'Alofi','Niuean','570','New Zealand dollar','NZD','cent','Niue','NU','NIU','Niue','009','061',0,0,0,NULL,NULL),(574,'Kingston','Norfolk Islander','574','Australian dollar','AUD','cent','Territory of Norfolk Island','NF','NFK','Norfolk Island','009','053',0,0,0,NULL,NULL),(578,'Oslo','Norwegian','578','Norwegian krone (pl. kroner)','NOK','øre (inv.)','Kingdom of Norway','NO','NOR','Norway','150','154',0,0,0,NULL,NULL),(580,'Saipan','Northern Mariana Islander','580','US dollar','USD','cent','Commonwealth of the Northern Mariana Islands','MP','MNP','Northern Mariana Islands','009','057',0,0,0,NULL,NULL),(581,'United States Minor Outlying Islands','of United States Minor Outlying Islands','581','US dollar','USD','cent','United States Minor Outlying Islands','UM','UMI','United States Minor Outlying Islands','','',0,0,0,NULL,NULL),(583,'Palikir','Micronesian','583','US dollar','USD','cent','Federated States of Micronesia','FM','FSM','Micronesia, Federated States of','009','057',0,0,0,NULL,NULL),(584,'Majuro','Marshallese','584','US dollar','USD','cent','Republic of the Marshall Islands','MH','MHL','Marshall Islands','009','057',0,0,0,NULL,NULL),(585,'Melekeok','Palauan','585','US dollar','USD','cent','Republic of Palau','PW','PLW','Palau','009','057',0,0,0,NULL,NULL),(586,'Islamabad','Pakistani','586','Pakistani rupee','PKR','paisa','Islamic Republic of Pakistan','PK','PAK','Pakistan','142','034',0,0,0,NULL,NULL),(591,'Panama City','Panamanian','591','balboa','PAB','centésimo','Republic of Panama','PA','PAN','Panama','019','013',0,0,0,NULL,NULL),(598,'Port Moresby','Papua New Guinean','598','kina (inv.)','PGK','toea (inv.)','Independent State of Papua New Guinea','PG','PNG','Papua New Guinea','009','054',0,0,0,NULL,NULL),(600,'Asunción','Paraguayan','600','guaraní','PYG','céntimo','Republic of Paraguay','PY','PRY','Paraguay','019','005',0,0,0,NULL,NULL),(604,'Lima','Peruvian','604','new sol','PEN','céntimo','Republic of Peru','PE','PER','Peru','019','005',0,0,0,NULL,NULL),(608,'Manila','Filipino','608','Philippine peso','PHP','centavo','Republic of the Philippines','PH','PHL','Philippines','142','035',0,0,0,NULL,NULL),(612,'Adamstown','Pitcairner','612','New Zealand dollar','NZD','cent','Pitcairn Islands','PN','PCN','Pitcairn','009','061',0,0,0,NULL,NULL),(616,'Warsaw','Polish','616','zloty','PLN','grosz (pl. groszy)','Republic of Poland','PL','POL','Poland','150','151',1,1,1,NULL,NULL),(620,'Lisbon','Portuguese','620','euro','EUR','cent','Portuguese Republic','PT','PRT','Portugal','150','039',1,1,1,NULL,NULL),(624,'Bissau','Guinea-Bissau national','624','CFA franc (BCEAO)','XOF','centime','Republic of Guinea-Bissau','GW','GNB','Guinea-Bissau','002','011',0,0,0,NULL,NULL),(626,'Dili','East Timorese','626','US dollar','USD','cent','Democratic Republic of East Timor','TL','TLS','Timor-Leste','142','035',0,0,0,NULL,NULL),(630,'San Juan','Puerto Rican','630','US dollar','USD','cent','Commonwealth of Puerto Rico','PR','PRI','Puerto Rico','019','029',0,0,0,NULL,NULL),(634,'Doha','Qatari','634','Qatari riyal','QAR','dirham','State of Qatar','QA','QAT','Qatar','142','145',0,0,0,NULL,NULL),(638,'Saint-Denis','Reunionese','638','euro','EUR','cent','Réunion','RE','REU','Réunion','002','014',0,0,0,NULL,NULL),(642,'Bucharest','Romanian','642','Romanian leu (pl. lei)','RON','ban (pl. bani)','Romania','RO','ROU','Romania','150','151',1,0,1,NULL,NULL),(643,'Moscow','Russian','643','Russian rouble','RUB','kopek','Russian Federation','RU','RUS','Russian Federation','150','151',0,0,0,NULL,NULL),(646,'Kigali','Rwandan; Rwandese','646','Rwandese franc','RWF','centime','Republic of Rwanda','RW','RWA','Rwanda','002','014',0,0,0,NULL,NULL),(652,'Gustavia','of Saint Barthélemy','652','euro','EUR','cent','Collectivity of Saint Barthélemy','BL','BLM','Saint Barthélemy','019','029',0,0,0,NULL,NULL),(654,'Jamestown','Saint Helenian','654','Saint Helena pound','SHP','penny','Saint Helena, Ascension and Tristan da Cunha','SH','SHN','Saint Helena, Ascension and Tristan da Cunha','002','011',0,0,0,NULL,NULL),(659,'Basseterre','Kittsian; Nevisian','659','East Caribbean dollar','XCD','cent','Federation of Saint Kitts and Nevis','KN','KNA','Saint Kitts and Nevis','019','029',0,0,0,NULL,NULL),(660,'The Valley','Anguillan','660','East Caribbean dollar','XCD','cent','Anguilla','AI','AIA','Anguilla','019','029',0,0,0,NULL,NULL),(662,'Castries','Saint Lucian','662','East Caribbean dollar','XCD','cent','Saint Lucia','LC','LCA','Saint Lucia','019','029',0,0,0,NULL,NULL),(663,'Marigot','of Saint Martin','663','euro','EUR','cent','Collectivity of Saint Martin','MF','MAF','Saint Martin (French part)','019','029',0,0,0,NULL,NULL),(666,'Saint-Pierre','St-Pierrais; Miquelonnais','666','euro','EUR','cent','Territorial Collectivity of Saint Pierre and Miquelon','PM','SPM','Saint Pierre and Miquelon','019','021',0,0,0,NULL,NULL),(670,'Kingstown','Vincentian','670','East Caribbean dollar','XCD','cent','Saint Vincent and the Grenadines','VC','VCT','Saint Vincent and the Grenadines','019','029',0,0,0,NULL,NULL),(674,'San Marino','San Marinese','674','euro','EUR ','cent','Republic of San Marino','SM','SMR','San Marino','150','039',0,0,0,NULL,NULL),(678,'São Tomé','São Toméan','678','dobra','STD','centavo','Democratic Republic of São Tomé and Príncipe','ST','STP','Sao Tome and Principe','002','017',0,0,0,NULL,NULL),(682,'Riyadh','Saudi Arabian','682','riyal','SAR','halala','Kingdom of Saudi Arabia','SA','SAU','Saudi Arabia','142','145',0,0,0,NULL,NULL),(686,'Dakar','Senegalese','686','CFA franc (BCEAO)','XOF','centime','Republic of Senegal','SN','SEN','Senegal','002','011',0,0,0,NULL,NULL),(688,'Belgrade','Serb','688','Serbian dinar','RSD','para (inv.)','Republic of Serbia','RS','SRB','Serbia','150','039',0,0,0,NULL,NULL),(690,'Victoria','Seychellois','690','Seychelles rupee','SCR','cent','Republic of Seychelles','SC','SYC','Seychelles','002','014',0,0,0,NULL,NULL),(694,'Freetown','Sierra Leonean','694','leone','SLL','cent','Republic of Sierra Leone','SL','SLE','Sierra Leone','002','011',0,0,0,NULL,NULL),(702,'Singapore','Singaporean','702','Singapore dollar','SGD','cent','Republic of Singapore','SG','SGP','Singapore','142','035',0,0,0,NULL,NULL),(703,'Bratislava','Slovak','703','euro','EUR','cent','Slovak Republic','SK','SVK','Slovakia','150','151',1,0,1,NULL,NULL),(704,'Hanoi','Vietnamese','704','dong','VND','(10 hào','Socialist Republic of Vietnam','VN','VNM','Viet Nam','142','035',0,0,0,NULL,NULL),(705,'Ljubljana','Slovene','705','euro','EUR','cent','Republic of Slovenia','SI','SVN','Slovenia','150','039',1,0,1,NULL,NULL),(706,'Mogadishu','Somali','706','Somali shilling','SOS','cent','Somali Republic','SO','SOM','Somalia','002','014',0,0,0,NULL,NULL),(710,'Pretoria (ZA1)','South African','710','rand','ZAR','cent','Republic of South Africa','ZA','ZAF','South Africa','002','018',0,0,0,NULL,NULL),(716,'Harare','Zimbabwean','716','Zimbabwe dollar (ZW1)','ZWL','cent','Republic of Zimbabwe','ZW','ZWE','Zimbabwe','002','014',0,0,0,NULL,NULL),(724,'Madrid','Spaniard','724','euro','EUR','cent','Kingdom of Spain','ES','ESP','Spain','150','039',1,1,1,NULL,NULL),(728,'Juba','South Sudanese','728','South Sudanese pound','SSP','piaster','Republic of South Sudan','SS','SSD','South Sudan','002','015',0,0,0,NULL,NULL),(729,'Khartoum','Sudanese','729','Sudanese pound','SDG','piastre','Republic of the Sudan','SD','SDN','Sudan','002','015',0,0,0,NULL,NULL),(732,'Al aaiun','Sahrawi','732','Moroccan dirham','MAD','centime','Western Sahara','EH','ESH','Western Sahara','002','015',0,0,0,NULL,NULL),(740,'Paramaribo','Surinamese','740','Surinamese dollar','SRD','cent','Republic of Suriname','SR','SUR','Suriname','019','005',0,0,0,NULL,NULL),(744,'Longyearbyen','of Svalbard','744','Norwegian krone (pl. kroner)','NOK','øre (inv.)','Svalbard and Jan Mayen','SJ','SJM','Svalbard and Jan Mayen','150','154',0,0,0,NULL,NULL),(748,'Mbabane','Swazi','748','lilangeni','SZL','cent','Kingdom of Swaziland','SZ','SWZ','Swaziland','002','018',0,0,0,NULL,NULL),(752,'Stockholm','Swedish','752','krona (pl. kronor)','SEK','öre (inv.)','Kingdom of Sweden','SE','SWE','Sweden','150','154',1,1,1,NULL,NULL),(756,'Berne','Swiss','756','Swiss franc','CHF','centime','Swiss Confederation','CH','CHE','Switzerland','150','155',0,1,0,NULL,NULL),(760,'Damascus','Syrian','760','Syrian pound','SYP','piastre','Syrian Arab Republic','SY','SYR','Syrian Arab Republic','142','145',0,0,0,NULL,NULL),(762,'Dushanbe','Tajik','762','somoni','TJS','diram','Republic of Tajikistan','TJ','TJK','Tajikistan','142','143',0,0,0,NULL,NULL),(764,'Bangkok','Thai','764','baht (inv.)','THB','satang (inv.)','Kingdom of Thailand','TH','THA','Thailand','142','035',0,0,0,NULL,NULL),(768,'Lomé','Togolese','768','CFA franc (BCEAO)','XOF','centime','Togolese Republic','TG','TGO','Togo','002','011',0,0,0,NULL,NULL),(772,'(TK2)','Tokelauan','772','New Zealand dollar','NZD','cent','Tokelau','TK','TKL','Tokelau','009','061',0,0,0,NULL,NULL),(776,'Nuku’alofa','Tongan','776','pa’anga (inv.)','TOP','seniti (inv.)','Kingdom of Tonga','TO','TON','Tonga','009','061',0,0,0,NULL,NULL),(780,'Port of Spain','Trinidadian; Tobagonian','780','Trinidad and Tobago dollar','TTD','cent','Republic of Trinidad and Tobago','TT','TTO','Trinidad and Tobago','019','029',0,0,0,NULL,NULL),(784,'Abu Dhabi','Emirian','784','UAE dirham','AED','fils (inv.)','United Arab Emirates','AE','ARE','United Arab Emirates','142','145',0,0,0,NULL,NULL),(788,'Tunis','Tunisian','788','Tunisian dinar','TND','millime','Republic of Tunisia','TN','TUN','Tunisia','002','015',0,0,0,NULL,NULL),(792,'Ankara','Turk','792','Turkish lira (inv.)','TRY','kurus (inv.)','Republic of Turkey','TR','TUR','Turkey','142','145',0,0,0,NULL,NULL),(795,'Ashgabat','Turkmen','795','Turkmen manat (inv.)','TMT','tenge (inv.)','Turkmenistan','TM','TKM','Turkmenistan','142','143',0,0,0,NULL,NULL),(796,'Cockburn Town','Turks and Caicos Islander','796','US dollar','USD','cent','Turks and Caicos Islands','TC','TCA','Turks and Caicos Islands','019','029',0,0,0,NULL,NULL),(798,'Funafuti','Tuvaluan','798','Australian dollar','AUD','cent','Tuvalu','TV','TUV','Tuvalu','009','061',0,0,0,NULL,NULL),(800,'Kampala','Ugandan','800','Uganda shilling','UGX','cent','Republic of Uganda','UG','UGA','Uganda','002','014',0,0,0,NULL,NULL),(804,'Kiev','Ukrainian','804','hryvnia','UAH','kopiyka','Ukraine','UA','UKR','Ukraine','150','151',0,0,0,NULL,NULL),(807,'Skopje','of the former Yugoslav Republic of Macedonia','807','denar (pl. denars)','MKD','deni (inv.)','the former Yugoslav Republic of Macedonia','MK','MKD','Macedonia, the former Yugoslav Republic of','150','039',0,0,0,NULL,NULL),(818,'Cairo','Egyptian','818','Egyptian pound','EGP','piastre','Arab Republic of Egypt','EG','EGY','Egypt','002','015',0,0,0,NULL,NULL),(826,'London','British','826','pound sterling','GBP','penny (pl. pence)','United Kingdom of Great Britain and Northern Ireland','GB','GBR','United Kingdom','150','154',1,0,0,NULL,NULL),(831,'St Peter Port','of Guernsey','831','Guernsey pound (GG2)','GGP (GG2)','penny (pl. pence)','Bailiwick of Guernsey','GG','GGY','Guernsey','150','154',0,0,0,NULL,NULL),(832,'St Helier','of Jersey','832','Jersey pound (JE2)','JEP (JE2)','penny (pl. pence)','Bailiwick of Jersey','JE','JEY','Jersey','150','154',0,0,0,NULL,NULL),(833,'Douglas','Manxman; Manxwoman','833','Manx pound (IM2)','IMP (IM2)','penny (pl. pence)','Isle of Man','IM','IMN','Isle of Man','150','154',0,0,0,NULL,NULL),(834,'Dodoma (TZ1)','Tanzanian','834','Tanzanian shilling','TZS','cent','United Republic of Tanzania','TZ','TZA','Tanzania, United Republic of','002','014',0,0,0,NULL,NULL),(840,'Washington DC','American','840','US dollar','USD','cent','United States of America','US','USA','United States','019','021',0,0,0,',','.'),(850,'Charlotte Amalie','US Virgin Islander','850','US dollar','USD','cent','United States Virgin Islands','VI','VIR','Virgin Islands, U.S.','019','029',0,0,0,NULL,NULL),(854,'Ouagadougou','Burkinabe','854','CFA franc (BCEAO)','XOF','centime','Burkina Faso','BF','BFA','Burkina Faso','002','011',0,0,0,NULL,NULL),(858,'Montevideo','Uruguayan','858','Uruguayan peso','UYU','centésimo','Eastern Republic of Uruguay','UY','URY','Uruguay','019','005',0,1,0,NULL,NULL),(860,'Tashkent','Uzbek','860','sum (inv.)','UZS','tiyin (inv.)','Republic of Uzbekistan','UZ','UZB','Uzbekistan','142','143',0,0,0,NULL,NULL),(862,'Caracas','Venezuelan','862','bolívar fuerte (pl. bolívares fuertes)','VEF','céntimo','Bolivarian Republic of Venezuela','VE','VEN','Venezuela, Bolivarian Republic of','019','005',0,0,0,NULL,NULL),(876,'Mata-Utu','Wallisian; Futunan; Wallis and Futuna Islander','876','CFP franc','XPF','centime','Wallis and Futuna','WF','WLF','Wallis and Futuna','009','061',0,0,0,NULL,NULL),(882,'Apia','Samoan','882','tala (inv.)','WST','sene (inv.)','Independent State of Samoa','WS','WSM','Samoa','009','061',0,0,0,NULL,NULL),(887,'San’a','Yemenite','887','Yemeni rial','YER','fils (inv.)','Republic of Yemen','YE','YEM','Yemen','142','145',0,0,0,NULL,NULL),(894,'Lusaka','Zambian','894','Zambian kwacha (inv.)','ZMW','ngwee (inv.)','Republic of Zambia','ZM','ZMB','Zambia','002','014',0,0,0,NULL,NULL);
/*!40000 ALTER TABLE `countries` ENABLE KEYS */;
UNLOCK TABLES;
@@ -855,7 +855,7 @@ CREATE TABLE `currencies` (
`code` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`swap_currency_symbol` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=68 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -864,7 +864,7 @@ CREATE TABLE `currencies` (
LOCK TABLES `currencies` WRITE;
/*!40000 ALTER TABLE `currencies` DISABLE KEYS */;
-INSERT INTO `currencies` VALUES (1,'US Dollar','$','2',',','.','USD',0),(2,'British Pound','£','2',',','.','GBP',0),(3,'Euro','€','2','.',',','EUR',0),(4,'South African Rand','R','2','.',',','ZAR',0),(5,'Danish Krone','kr','2','.',',','DKK',1),(6,'Israeli Shekel','NIS ','2',',','.','ILS',0),(7,'Swedish Krona','kr','2','.',',','SEK',1),(8,'Kenyan Shilling','KSh ','2',',','.','KES',0),(9,'Canadian Dollar','C$','2',',','.','CAD',0),(10,'Philippine Peso','P ','2',',','.','PHP',0),(11,'Indian Rupee','Rs. ','2',',','.','INR',0),(12,'Australian Dollar','$','2',',','.','AUD',0),(13,'Singapore Dollar','','2',',','.','SGD',0),(14,'Norske Kroner','kr','2','.',',','NOK',1),(15,'New Zealand Dollar','$','2',',','.','NZD',0),(16,'Vietnamese Dong','','0','.',',','VND',0),(17,'Swiss Franc','','2','\'','.','CHF',0),(18,'Guatemalan Quetzal','Q','2',',','.','GTQ',0),(19,'Malaysian Ringgit','RM','2',',','.','MYR',0),(20,'Brazilian Real','R$','2','.',',','BRL',0),(21,'Thai Baht','','2',',','.','THB',0),(22,'Nigerian Naira','','2',',','.','NGN',0),(23,'Argentine Peso','$','2','.',',','ARS',0),(24,'Bangladeshi Taka','Tk','2',',','.','BDT',0),(25,'United Arab Emirates Dirham','DH ','2',',','.','AED',0),(26,'Hong Kong Dollar','','2',',','.','HKD',0),(27,'Indonesian Rupiah','Rp','2',',','.','IDR',0),(28,'Mexican Peso','$','2',',','.','MXN',0),(29,'Egyptian Pound','E£','2',',','.','EGP',0),(30,'Colombian Peso','$','2','.',',','COP',0),(31,'West African Franc','CFA ','2',',','.','XOF',0),(32,'Chinese Renminbi','RMB ','2',',','.','CNY',0),(33,'Rwandan Franc','RF ','2',',','.','RWF',0),(34,'Tanzanian Shilling','TSh ','2',',','.','TZS',0),(35,'Netherlands Antillean Guilder','','2','.',',','ANG',0),(36,'Trinidad and Tobago Dollar','TT$','2',',','.','TTD',0),(37,'East Caribbean Dollar','EC$','2',',','.','XCD',0),(38,'Ghanaian Cedi','','2',',','.','GHS',0),(39,'Bulgarian Lev','','2',' ','.','BGN',0),(40,'Aruban Florin','Afl. ','2',' ','.','AWG',0),(41,'Turkish Lira','TL ','2','.',',','TRY',0),(42,'Romanian New Leu','','2',',','.','RON',0),(43,'Croatian Kuna','kn','2','.',',','HRK',0),(44,'Saudi Riyal','','2',',','.','SAR',0),(45,'Japanese Yen','¥','0',',','.','JPY',0),(46,'Maldivian Rufiyaa','','2',',','.','MVR',0),(47,'Costa Rican Colón','','2',',','.','CRC',0),(48,'Pakistani Rupee','Rs ','0',',','.','PKR',0),(49,'Polish Zloty','zł','2',' ',',','PLN',1),(50,'Sri Lankan Rupee','LKR','2',',','.','LKR',1),(51,'Czech Koruna','Kč','2',' ',',','CZK',1),(52,'Uruguayan Peso','$','2','.',',','UYU',0),(53,'Namibian Dollar','$','2',',','.','NAD',0),(54,'Tunisian Dinar','','2',',','.','TND',0),(55,'Russian Ruble','','2',',','.','RUB',0),(56,'Mozambican Metical','MT','2','.',',','MZN',1),(57,'Omani Rial','','2',',','.','OMR',0),(58,'Ukrainian Hryvnia','','2',',','.','UAH',0),(59,'Macanese Pataca','MOP$','2',',','.','MOP',0),(60,'Taiwan New Dollar','NT$','2',',','.','TWD',0),(61,'Dominican Peso','RD$','2',',','.','DOP',0),(62,'Chilean Peso','$','0','.',',','CLP',0),(63,'Icelandic Króna','kr','2','.',',','ISK',1),(64,'Papua New Guinean Kina','K','2',',','.','PGK',0),(65,'Jordanian Dinar','','2',',','.','JOD',0),(66,'Myanmar Kyat','K','2',',','.','MMK',0),(67,'Peruvian Sol','S/ ','2',',','.','PEN',0);
+INSERT INTO `currencies` VALUES (1,'US Dollar','$','2',',','.','USD',0),(2,'British Pound','£','2',',','.','GBP',0),(3,'Euro','€','2','.',',','EUR',0),(4,'South African Rand','R','2','.',',','ZAR',0),(5,'Danish Krone','kr','2','.',',','DKK',1),(6,'Israeli Shekel','NIS ','2',',','.','ILS',0),(7,'Swedish Krona','kr','2','.',',','SEK',1),(8,'Kenyan Shilling','KSh ','2',',','.','KES',0),(9,'Canadian Dollar','C$','2',',','.','CAD',0),(10,'Philippine Peso','P ','2',',','.','PHP',0),(11,'Indian Rupee','Rs. ','2',',','.','INR',0),(12,'Australian Dollar','$','2',',','.','AUD',0),(13,'Singapore Dollar','','2',',','.','SGD',0),(14,'Norske Kroner','kr','2','.',',','NOK',1),(15,'New Zealand Dollar','$','2',',','.','NZD',0),(16,'Vietnamese Dong','','0','.',',','VND',0),(17,'Swiss Franc','','2','\'','.','CHF',0),(18,'Guatemalan Quetzal','Q','2',',','.','GTQ',0),(19,'Malaysian Ringgit','RM','2',',','.','MYR',0),(20,'Brazilian Real','R$','2','.',',','BRL',0),(21,'Thai Baht','','2',',','.','THB',0),(22,'Nigerian Naira','','2',',','.','NGN',0),(23,'Argentine Peso','$','2','.',',','ARS',0),(24,'Bangladeshi Taka','Tk','2',',','.','BDT',0),(25,'United Arab Emirates Dirham','DH ','2',',','.','AED',0),(26,'Hong Kong Dollar','','2',',','.','HKD',0),(27,'Indonesian Rupiah','Rp','2',',','.','IDR',0),(28,'Mexican Peso','$','2',',','.','MXN',0),(29,'Egyptian Pound','E£','2',',','.','EGP',0),(30,'Colombian Peso','$','2','.',',','COP',0),(31,'West African Franc','CFA ','2',',','.','XOF',0),(32,'Chinese Renminbi','RMB ','2',',','.','CNY',0),(33,'Rwandan Franc','RF ','2',',','.','RWF',0),(34,'Tanzanian Shilling','TSh ','2',',','.','TZS',0),(35,'Netherlands Antillean Guilder','','2','.',',','ANG',0),(36,'Trinidad and Tobago Dollar','TT$','2',',','.','TTD',0),(37,'East Caribbean Dollar','EC$','2',',','.','XCD',0),(38,'Ghanaian Cedi','','2',',','.','GHS',0),(39,'Bulgarian Lev','','2',' ','.','BGN',0),(40,'Aruban Florin','Afl. ','2',' ','.','AWG',0),(41,'Turkish Lira','TL ','2','.',',','TRY',0),(42,'Romanian New Leu','','2',',','.','RON',0),(43,'Croatian Kuna','kn','2','.',',','HRK',0),(44,'Saudi Riyal','','2',',','.','SAR',0),(45,'Japanese Yen','¥','0',',','.','JPY',0),(46,'Maldivian Rufiyaa','','2',',','.','MVR',0),(47,'Costa Rican Colón','','2',',','.','CRC',0),(48,'Pakistani Rupee','Rs ','0',',','.','PKR',0),(49,'Polish Zloty','zł','2',' ',',','PLN',1),(50,'Sri Lankan Rupee','LKR','2',',','.','LKR',1),(51,'Czech Koruna','Kč','2',' ',',','CZK',1),(52,'Uruguayan Peso','$','2','.',',','UYU',0),(53,'Namibian Dollar','$','2',',','.','NAD',0),(54,'Tunisian Dinar','','2',',','.','TND',0),(55,'Russian Ruble','','2',',','.','RUB',0),(56,'Mozambican Metical','MT','2','.',',','MZN',1),(57,'Omani Rial','','2',',','.','OMR',0),(58,'Ukrainian Hryvnia','','2',',','.','UAH',0),(59,'Macanese Pataca','MOP$','2',',','.','MOP',0),(60,'Taiwan New Dollar','NT$','2',',','.','TWD',0),(61,'Dominican Peso','RD$','2',',','.','DOP',0),(62,'Chilean Peso','$','0','.',',','CLP',0),(63,'Icelandic Króna','kr','2','.',',','ISK',1),(64,'Papua New Guinean Kina','K','2',',','.','PGK',0),(65,'Jordanian Dinar','','2',',','.','JOD',0),(66,'Myanmar Kyat','K','2',',','.','MMK',0),(67,'Peruvian Sol','S/ ','2',',','.','PEN',0),(68,'Botswana Pula','P','2',',','.','BWP',0);
/*!40000 ALTER TABLE `currencies` ENABLE KEYS */;
UNLOCK TABLES;
@@ -1187,7 +1187,7 @@ CREATE TABLE `gateway_types` (
`alias` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -1196,7 +1196,7 @@ CREATE TABLE `gateway_types` (
LOCK TABLES `gateway_types` WRITE;
/*!40000 ALTER TABLE `gateway_types` DISABLE KEYS */;
-INSERT INTO `gateway_types` VALUES (1,'credit_card','Credit Card'),(2,'bank_transfer','Bank Transfer'),(3,'paypal','PayPal'),(4,'bitcoin','Bitcoin'),(5,'dwolla','Dwolla'),(6,'custom','Custom'),(7,'alipay','Alipay'),(8,'sofort','Sofort');
+INSERT INTO `gateway_types` VALUES (1,'credit_card','Credit Card'),(2,'bank_transfer','Bank Transfer'),(3,'paypal','PayPal'),(4,'bitcoin','Bitcoin'),(5,'dwolla','Dwolla'),(6,'custom','Custom'),(7,'alipay','Alipay'),(8,'sofort','Sofort'),(9,'sepa','SEPA');
/*!40000 ALTER TABLE `gateway_types` ENABLE KEYS */;
UNLOCK TABLES;
@@ -1223,7 +1223,7 @@ CREATE TABLE `gateways` (
PRIMARY KEY (`id`),
KEY `gateways_payment_library_id_foreign` (`payment_library_id`),
CONSTRAINT `gateways_payment_library_id_foreign` FOREIGN KEY (`payment_library_id`) REFERENCES `payment_libraries` (`id`) ON DELETE CASCADE
-) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -1232,7 +1232,7 @@ CREATE TABLE `gateways` (
LOCK TABLES `gateways` WRITE;
/*!40000 ALTER TABLE `gateways` DISABLE KEYS */;
-INSERT INTO `gateways` VALUES (1,'2017-09-10 03:46:49','2017-09-10 03:46:49','Authorize.Net AIM','AuthorizeNet_AIM',1,1,4,0,NULL,0,0),(2,'2017-09-10 03:46:49','2017-09-10 03:46:49','Authorize.Net SIM','AuthorizeNet_SIM',1,2,10000,0,NULL,0,0),(3,'2017-09-10 03:46:49','2017-09-10 03:46:49','CardSave','CardSave',1,1,10000,0,NULL,0,0),(4,'2017-09-10 03:46:49','2017-09-10 03:46:49','Eway Rapid','Eway_RapidShared',1,1,10000,0,NULL,1,0),(5,'2017-09-10 03:46:49','2017-09-10 03:46:49','FirstData Connect','FirstData_Connect',1,1,10000,0,NULL,0,0),(6,'2017-09-10 03:46:49','2017-09-10 03:46:49','GoCardless','GoCardless',1,2,10000,0,NULL,1,0),(7,'2017-09-10 03:46:49','2017-09-10 03:46:49','Migs ThreeParty','Migs_ThreeParty',1,1,10000,0,NULL,0,0),(8,'2017-09-10 03:46:49','2017-09-10 03:46:49','Migs TwoParty','Migs_TwoParty',1,1,10000,0,NULL,0,0),(9,'2017-09-10 03:46:49','2017-09-10 03:46:49','Mollie','Mollie',1,1,7,0,NULL,1,0),(10,'2017-09-10 03:46:49','2017-09-10 03:46:49','MultiSafepay','MultiSafepay',1,1,10000,0,NULL,0,0),(11,'2017-09-10 03:46:49','2017-09-10 03:46:49','Netaxept','Netaxept',1,1,10000,0,NULL,0,0),(12,'2017-09-10 03:46:49','2017-09-10 03:46:49','NetBanx','NetBanx',1,1,10000,0,NULL,0,0),(13,'2017-09-10 03:46:49','2017-09-10 03:46:49','PayFast','PayFast',1,1,10000,0,NULL,1,0),(14,'2017-09-10 03:46:49','2017-09-10 03:46:49','Payflow Pro','Payflow_Pro',1,1,10000,0,NULL,0,0),(15,'2017-09-10 03:46:49','2017-09-10 03:46:49','PaymentExpress PxPay','PaymentExpress_PxPay',1,1,10000,0,NULL,0,0),(16,'2017-09-10 03:46:49','2017-09-10 03:46:49','PaymentExpress PxPost','PaymentExpress_PxPost',1,1,10000,0,NULL,0,0),(17,'2017-09-10 03:46:49','2017-09-10 03:46:49','PayPal Express','PayPal_Express',1,1,3,0,NULL,1,0),(18,'2017-09-10 03:46:49','2017-09-10 03:46:49','PayPal Pro','PayPal_Pro',1,1,10000,0,NULL,0,0),(19,'2017-09-10 03:46:49','2017-09-10 03:46:49','Pin','Pin',1,1,10000,0,NULL,0,0),(20,'2017-09-10 03:46:49','2017-09-10 03:46:49','SagePay Direct','SagePay_Direct',1,1,10000,0,NULL,0,0),(21,'2017-09-10 03:46:49','2017-09-10 03:46:49','SagePay Server','SagePay_Server',1,1,10000,0,NULL,0,0),(22,'2017-09-10 03:46:49','2017-09-10 03:46:49','SecurePay DirectPost','SecurePay_DirectPost',1,1,10000,0,NULL,0,0),(23,'2017-09-10 03:46:50','2017-09-10 03:46:50','Stripe','Stripe',1,1,1,0,NULL,0,0),(24,'2017-09-10 03:46:50','2017-09-10 03:46:50','TargetPay Direct eBanking','TargetPay_Directebanking',1,1,10000,0,NULL,0,0),(25,'2017-09-10 03:46:50','2017-09-10 03:46:50','TargetPay Ideal','TargetPay_Ideal',1,1,10000,0,NULL,0,0),(26,'2017-09-10 03:46:50','2017-09-10 03:46:50','TargetPay Mr Cash','TargetPay_Mrcash',1,1,10000,0,NULL,0,0),(27,'2017-09-10 03:46:50','2017-09-10 03:46:50','TwoCheckout','TwoCheckout',1,1,10000,0,NULL,1,0),(28,'2017-09-10 03:46:50','2017-09-10 03:46:50','WorldPay','WorldPay',1,1,10000,0,NULL,0,0),(29,'2017-09-10 03:46:50','2017-09-10 03:46:50','BeanStream','BeanStream',1,2,10000,0,NULL,0,0),(30,'2017-09-10 03:46:50','2017-09-10 03:46:50','Psigate','Psigate',1,2,10000,0,NULL,0,0),(31,'2017-09-10 03:46:50','2017-09-10 03:46:50','moolah','AuthorizeNet_AIM',1,1,10000,0,NULL,0,0),(32,'2017-09-10 03:46:50','2017-09-10 03:46:50','Alipay','Alipay_Express',1,1,10000,0,NULL,0,0),(33,'2017-09-10 03:46:50','2017-09-10 03:46:50','Buckaroo','Buckaroo_CreditCard',1,1,10000,0,NULL,0,0),(34,'2017-09-10 03:46:50','2017-09-10 03:46:50','Coinbase','Coinbase',1,1,10000,0,NULL,0,0),(35,'2017-09-10 03:46:50','2017-09-10 03:46:50','DataCash','DataCash',1,1,10000,0,NULL,0,0),(36,'2017-09-10 03:46:50','2017-09-10 03:46:50','Neteller','Neteller',1,2,10000,0,NULL,0,0),(37,'2017-09-10 03:46:50','2017-09-10 03:46:50','Pacnet','Pacnet',1,1,10000,0,NULL,0,0),(38,'2017-09-10 03:46:50','2017-09-10 03:46:50','PaymentSense','PaymentSense',1,2,10000,0,NULL,0,0),(39,'2017-09-10 03:46:50','2017-09-10 03:46:50','Realex','Realex_Remote',1,1,10000,0,NULL,0,0),(40,'2017-09-10 03:46:50','2017-09-10 03:46:50','Sisow','Sisow',1,1,10000,0,NULL,0,0),(41,'2017-09-10 03:46:50','2017-09-10 03:46:50','Skrill','Skrill',1,1,10000,0,NULL,1,0),(42,'2017-09-10 03:46:50','2017-09-10 03:46:50','BitPay','BitPay',1,1,6,0,NULL,1,0),(43,'2017-09-10 03:46:50','2017-09-10 03:46:50','Dwolla','Dwolla',1,1,5,0,NULL,1,0),(44,'2017-09-10 03:46:50','2017-09-10 03:46:50','AGMS','Agms',1,1,10000,0,NULL,0,0),(45,'2017-09-10 03:46:50','2017-09-10 03:46:50','Barclays','BarclaysEpdq\\Essential',1,1,10000,0,NULL,0,0),(46,'2017-09-10 03:46:50','2017-09-10 03:46:50','Cardgate','Cardgate',1,1,10000,0,NULL,0,0),(47,'2017-09-10 03:46:50','2017-09-10 03:46:50','Checkout.com','CheckoutCom',1,1,10000,0,NULL,0,0),(48,'2017-09-10 03:46:50','2017-09-10 03:46:50','Creditcall','Creditcall',1,1,10000,0,NULL,0,0),(49,'2017-09-10 03:46:50','2017-09-10 03:46:50','Cybersource','Cybersource',1,1,10000,0,NULL,0,0),(50,'2017-09-10 03:46:50','2017-09-10 03:46:50','ecoPayz','Ecopayz',1,1,10000,0,NULL,0,0),(51,'2017-09-10 03:46:50','2017-09-10 03:46:50','Fasapay','Fasapay',1,1,10000,0,NULL,0,0),(52,'2017-09-10 03:46:50','2017-09-10 03:46:50','Komoju','Komoju',1,1,10000,0,NULL,0,0),(53,'2017-09-10 03:46:50','2017-09-10 03:46:50','Multicards','Multicards',1,1,10000,0,NULL,0,0),(54,'2017-09-10 03:46:50','2017-09-10 03:46:50','Pagar.Me','Pagarme',1,2,10000,0,NULL,0,0),(55,'2017-09-10 03:46:50','2017-09-10 03:46:50','Paysafecard','Paysafecard',1,1,10000,0,NULL,0,0),(56,'2017-09-10 03:46:50','2017-09-10 03:46:50','Paytrace','Paytrace_CreditCard',1,1,10000,0,NULL,0,0),(57,'2017-09-10 03:46:50','2017-09-10 03:46:50','Secure Trading','SecureTrading',1,1,10000,0,NULL,0,0),(58,'2017-09-10 03:46:50','2017-09-10 03:46:50','SecPay','SecPay',1,1,10000,0,NULL,0,0),(59,'2017-09-10 03:46:50','2017-09-10 03:46:50','WeChat Express','WeChat_Express',1,2,10000,0,NULL,0,0),(60,'2017-09-10 03:46:50','2017-09-10 03:46:50','WePay','WePay',1,1,10000,0,NULL,0,0),(61,'2017-09-10 03:46:50','2017-09-10 03:46:50','Braintree','Braintree',1,1,2,0,NULL,0,0),(62,'2017-09-10 03:46:50','2017-09-10 03:46:50','Custom','Custom',1,1,9,0,NULL,1,0),(63,'2017-09-10 03:46:50','2017-09-10 03:46:50','FirstData Payeezy','FirstData_Payeezy',1,1,10000,0,NULL,0,0),(64,'2017-09-10 03:46:50','2017-09-10 03:46:50','GoCardless','GoCardlessV2\\Redirect',1,1,8,0,NULL,1,0);
+INSERT INTO `gateways` VALUES (1,'2017-10-15 08:07:04','2017-10-15 08:07:04','Authorize.Net AIM','AuthorizeNet_AIM',1,1,4,0,NULL,0,0),(2,'2017-10-15 08:07:04','2017-10-15 08:07:04','Authorize.Net SIM','AuthorizeNet_SIM',1,2,10000,0,NULL,0,0),(3,'2017-10-15 08:07:04','2017-10-15 08:07:04','CardSave','CardSave',1,1,10000,0,NULL,0,0),(4,'2017-10-15 08:07:04','2017-10-15 08:07:04','Eway Rapid','Eway_RapidShared',1,1,10000,0,NULL,1,0),(5,'2017-10-15 08:07:04','2017-10-15 08:07:04','FirstData Connect','FirstData_Connect',1,1,10000,0,NULL,0,0),(6,'2017-10-15 08:07:04','2017-10-15 08:07:04','GoCardless','GoCardless',1,2,10000,0,NULL,1,0),(7,'2017-10-15 08:07:04','2017-10-15 08:07:04','Migs ThreeParty','Migs_ThreeParty',1,1,10000,0,NULL,0,0),(8,'2017-10-15 08:07:04','2017-10-15 08:07:04','Migs TwoParty','Migs_TwoParty',1,1,10000,0,NULL,0,0),(9,'2017-10-15 08:07:04','2017-10-15 08:07:04','Mollie','Mollie',1,1,7,0,NULL,1,0),(10,'2017-10-15 08:07:04','2017-10-15 08:07:04','MultiSafepay','MultiSafepay',1,1,10000,0,NULL,0,0),(11,'2017-10-15 08:07:04','2017-10-15 08:07:04','Netaxept','Netaxept',1,1,10000,0,NULL,0,0),(12,'2017-10-15 08:07:04','2017-10-15 08:07:04','NetBanx','NetBanx',1,1,10000,0,NULL,0,0),(13,'2017-10-15 08:07:04','2017-10-15 08:07:04','PayFast','PayFast',1,1,10000,0,NULL,1,0),(14,'2017-10-15 08:07:04','2017-10-15 08:07:04','Payflow Pro','Payflow_Pro',1,1,10000,0,NULL,0,0),(15,'2017-10-15 08:07:04','2017-10-15 08:07:04','PaymentExpress PxPay','PaymentExpress_PxPay',1,1,10000,0,NULL,0,0),(16,'2017-10-15 08:07:04','2017-10-15 08:07:04','PaymentExpress PxPost','PaymentExpress_PxPost',1,1,10000,0,NULL,0,0),(17,'2017-10-15 08:07:04','2017-10-15 08:07:04','PayPal Express','PayPal_Express',1,1,3,0,NULL,1,0),(18,'2017-10-15 08:07:04','2017-10-15 08:07:04','PayPal Pro','PayPal_Pro',1,1,10000,0,NULL,0,0),(19,'2017-10-15 08:07:04','2017-10-15 08:07:04','Pin','Pin',1,1,10000,0,NULL,0,0),(20,'2017-10-15 08:07:04','2017-10-15 08:07:04','SagePay Direct','SagePay_Direct',1,1,10000,0,NULL,0,0),(21,'2017-10-15 08:07:04','2017-10-15 08:07:04','SagePay Server','SagePay_Server',1,1,10000,0,NULL,0,0),(22,'2017-10-15 08:07:04','2017-10-15 08:07:04','SecurePay DirectPost','SecurePay_DirectPost',1,1,10000,0,NULL,0,0),(23,'2017-10-15 08:07:04','2017-10-15 08:07:04','Stripe','Stripe',1,1,1,0,NULL,0,0),(24,'2017-10-15 08:07:04','2017-10-15 08:07:04','TargetPay Direct eBanking','TargetPay_Directebanking',1,1,10000,0,NULL,0,0),(25,'2017-10-15 08:07:04','2017-10-15 08:07:04','TargetPay Ideal','TargetPay_Ideal',1,1,10000,0,NULL,0,0),(26,'2017-10-15 08:07:04','2017-10-15 08:07:04','TargetPay Mr Cash','TargetPay_Mrcash',1,1,10000,0,NULL,0,0),(27,'2017-10-15 08:07:04','2017-10-15 08:07:04','TwoCheckout','TwoCheckout',1,1,10000,0,NULL,1,0),(28,'2017-10-15 08:07:04','2017-10-15 08:07:04','WorldPay','WorldPay',1,1,10000,0,NULL,0,0),(29,'2017-10-15 08:07:04','2017-10-15 08:07:04','BeanStream','BeanStream',1,2,10000,0,NULL,0,0),(30,'2017-10-15 08:07:04','2017-10-15 08:07:04','Psigate','Psigate',1,2,10000,0,NULL,0,0),(31,'2017-10-15 08:07:04','2017-10-15 08:07:04','moolah','AuthorizeNet_AIM',1,1,10000,0,NULL,0,0),(32,'2017-10-15 08:07:04','2017-10-15 08:07:04','Alipay','Alipay_Express',1,1,10000,0,NULL,0,0),(33,'2017-10-15 08:07:04','2017-10-15 08:07:04','Buckaroo','Buckaroo_CreditCard',1,1,10000,0,NULL,0,0),(34,'2017-10-15 08:07:04','2017-10-15 08:07:04','Coinbase','Coinbase',1,1,10000,0,NULL,0,0),(35,'2017-10-15 08:07:04','2017-10-15 08:07:04','DataCash','DataCash',1,1,10000,0,NULL,0,0),(36,'2017-10-15 08:07:04','2017-10-15 08:07:04','Neteller','Neteller',1,2,10000,0,NULL,0,0),(37,'2017-10-15 08:07:04','2017-10-15 08:07:04','Pacnet','Pacnet',1,1,10000,0,NULL,0,0),(38,'2017-10-15 08:07:04','2017-10-15 08:07:04','PaymentSense','PaymentSense',1,2,10000,0,NULL,0,0),(39,'2017-10-15 08:07:04','2017-10-15 08:07:04','Realex','Realex_Remote',1,1,10000,0,NULL,0,0),(40,'2017-10-15 08:07:04','2017-10-15 08:07:04','Sisow','Sisow',1,1,10000,0,NULL,0,0),(41,'2017-10-15 08:07:04','2017-10-15 08:07:04','Skrill','Skrill',1,1,10000,0,NULL,1,0),(42,'2017-10-15 08:07:05','2017-10-15 08:07:05','BitPay','BitPay',1,1,6,0,NULL,1,0),(43,'2017-10-15 08:07:05','2017-10-15 08:07:05','Dwolla','Dwolla',1,1,5,0,NULL,1,0),(44,'2017-10-15 08:07:05','2017-10-15 08:07:05','AGMS','Agms',1,1,10000,0,NULL,0,0),(45,'2017-10-15 08:07:05','2017-10-15 08:07:05','Barclays','BarclaysEpdq\\Essential',1,1,10000,0,NULL,0,0),(46,'2017-10-15 08:07:05','2017-10-15 08:07:05','Cardgate','Cardgate',1,1,10000,0,NULL,0,0),(47,'2017-10-15 08:07:05','2017-10-15 08:07:05','Checkout.com','CheckoutCom',1,1,10000,0,NULL,0,0),(48,'2017-10-15 08:07:05','2017-10-15 08:07:05','Creditcall','Creditcall',1,1,10000,0,NULL,0,0),(49,'2017-10-15 08:07:05','2017-10-15 08:07:05','Cybersource','Cybersource',1,1,10000,0,NULL,0,0),(50,'2017-10-15 08:07:05','2017-10-15 08:07:05','ecoPayz','Ecopayz',1,1,10000,0,NULL,0,0),(51,'2017-10-15 08:07:05','2017-10-15 08:07:05','Fasapay','Fasapay',1,1,10000,0,NULL,0,0),(52,'2017-10-15 08:07:05','2017-10-15 08:07:05','Komoju','Komoju',1,1,10000,0,NULL,0,0),(53,'2017-10-15 08:07:05','2017-10-15 08:07:05','Multicards','Multicards',1,1,10000,0,NULL,0,0),(54,'2017-10-15 08:07:05','2017-10-15 08:07:05','Pagar.Me','Pagarme',1,2,10000,0,NULL,0,0),(55,'2017-10-15 08:07:05','2017-10-15 08:07:05','Paysafecard','Paysafecard',1,1,10000,0,NULL,0,0),(56,'2017-10-15 08:07:05','2017-10-15 08:07:05','Paytrace','Paytrace_CreditCard',1,1,10000,0,NULL,0,0),(57,'2017-10-15 08:07:05','2017-10-15 08:07:05','Secure Trading','SecureTrading',1,1,10000,0,NULL,0,0),(58,'2017-10-15 08:07:05','2017-10-15 08:07:05','SecPay','SecPay',1,1,10000,0,NULL,0,0),(59,'2017-10-15 08:07:05','2017-10-15 08:07:05','WeChat Express','WeChat_Express',1,2,10000,0,NULL,0,0),(60,'2017-10-15 08:07:05','2017-10-15 08:07:05','WePay','WePay',1,1,10000,0,NULL,0,0),(61,'2017-10-15 08:07:05','2017-10-15 08:07:05','Braintree','Braintree',1,1,2,0,NULL,0,0),(62,'2017-10-15 08:07:05','2017-10-15 08:07:05','Custom','Custom',1,1,9,0,NULL,1,0),(63,'2017-10-15 08:07:05','2017-10-15 08:07:05','FirstData Payeezy','FirstData_Payeezy',1,1,10000,0,NULL,0,0),(64,'2017-10-15 08:07:05','2017-10-15 08:07:05','GoCardless','GoCardlessV2\\Redirect',1,1,8,0,NULL,1,0),(65,'2017-10-15 08:07:05','2017-10-15 08:07:05','PagSeguro','PagSeguro',1,1,10000,0,NULL,0,0);
/*!40000 ALTER TABLE `gateways` ENABLE KEYS */;
UNLOCK TABLES;
@@ -1824,7 +1824,7 @@ CREATE TABLE `payment_libraries` (
LOCK TABLES `payment_libraries` WRITE;
/*!40000 ALTER TABLE `payment_libraries` DISABLE KEYS */;
-INSERT INTO `payment_libraries` VALUES (1,'2017-09-10 03:46:48','2017-09-10 03:46:48','Omnipay',1),(2,'2017-09-10 03:46:48','2017-09-10 03:46:48','PHP-Payments [Deprecated]',1);
+INSERT INTO `payment_libraries` VALUES (1,'2017-10-15 08:07:03','2017-10-15 08:07:03','Omnipay',1),(2,'2017-10-15 08:07:03','2017-10-15 08:07:03','PHP-Payments [Deprecated]',1);
/*!40000 ALTER TABLE `payment_libraries` ENABLE KEYS */;
UNLOCK TABLES;
@@ -1934,7 +1934,7 @@ CREATE TABLE `payment_terms` (
LOCK TABLES `payment_terms` WRITE;
/*!40000 ALTER TABLE `payment_terms` DISABLE KEYS */;
-INSERT INTO `payment_terms` VALUES (1,7,'Net 7','2017-09-10 03:46:48','2017-09-10 03:46:48',NULL,0,0,1),(2,10,'Net 10','2017-09-10 03:46:48','2017-09-10 03:46:48',NULL,0,0,2),(3,14,'Net 14','2017-09-10 03:46:48','2017-09-10 03:46:48',NULL,0,0,3),(4,15,'Net 15','2017-09-10 03:46:48','2017-09-10 03:46:48',NULL,0,0,4),(5,30,'Net 30','2017-09-10 03:46:48','2017-09-10 03:46:48',NULL,0,0,5),(6,60,'Net 60','2017-09-10 03:46:48','2017-09-10 03:46:48',NULL,0,0,6),(7,90,'Net 90','2017-09-10 03:46:48','2017-09-10 03:46:48',NULL,0,0,7),(8,-1,'Net 0','2017-09-10 03:46:51','2017-09-10 03:46:51',NULL,0,0,0);
+INSERT INTO `payment_terms` VALUES (1,7,'Net 7','2017-10-15 08:07:03','2017-10-15 08:07:03',NULL,0,0,1),(2,10,'Net 10','2017-10-15 08:07:03','2017-10-15 08:07:03',NULL,0,0,2),(3,14,'Net 14','2017-10-15 08:07:03','2017-10-15 08:07:03',NULL,0,0,3),(4,15,'Net 15','2017-10-15 08:07:03','2017-10-15 08:07:03',NULL,0,0,4),(5,30,'Net 30','2017-10-15 08:07:03','2017-10-15 08:07:03',NULL,0,0,5),(6,60,'Net 60','2017-10-15 08:07:03','2017-10-15 08:07:03',NULL,0,0,6),(7,90,'Net 90','2017-10-15 08:07:03','2017-10-15 08:07:03',NULL,0,0,7),(8,-1,'Net 0','2017-10-15 08:07:06','2017-10-15 08:07:06',NULL,0,0,0);
/*!40000 ALTER TABLE `payment_terms` ENABLE KEYS */;
UNLOCK TABLES;
@@ -1952,7 +1952,7 @@ CREATE TABLE `payment_types` (
PRIMARY KEY (`id`),
KEY `payment_types_gateway_type_id_foreign` (`gateway_type_id`),
CONSTRAINT `payment_types_gateway_type_id_foreign` FOREIGN KEY (`gateway_type_id`) REFERENCES `gateway_types` (`id`) ON DELETE CASCADE
-) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -1961,7 +1961,7 @@ CREATE TABLE `payment_types` (
LOCK TABLES `payment_types` WRITE;
/*!40000 ALTER TABLE `payment_types` DISABLE KEYS */;
-INSERT INTO `payment_types` VALUES (1,'Apply Credit',NULL),(2,'Bank Transfer',2),(3,'Cash',NULL),(4,'Debit',1),(5,'ACH',2),(6,'Visa Card',1),(7,'MasterCard',1),(8,'American Express',1),(9,'Discover Card',1),(10,'Diners Card',1),(11,'EuroCard',1),(12,'Nova',1),(13,'Credit Card Other',1),(14,'PayPal',3),(15,'Google Wallet',NULL),(16,'Check',NULL),(17,'Carte Blanche',1),(18,'UnionPay',1),(19,'JCB',1),(20,'Laser',1),(21,'Maestro',1),(22,'Solo',1),(23,'Switch',1),(24,'iZettle',1),(25,'Swish',2),(26,'Venmo',NULL),(27,'Money Order',NULL),(28,'Alipay',7),(29,'Sofort',8);
+INSERT INTO `payment_types` VALUES (1,'Apply Credit',NULL),(2,'Bank Transfer',2),(3,'Cash',NULL),(4,'Debit',1),(5,'ACH',2),(6,'Visa Card',1),(7,'MasterCard',1),(8,'American Express',1),(9,'Discover Card',1),(10,'Diners Card',1),(11,'EuroCard',1),(12,'Nova',1),(13,'Credit Card Other',1),(14,'PayPal',3),(15,'Google Wallet',NULL),(16,'Check',NULL),(17,'Carte Blanche',1),(18,'UnionPay',1),(19,'JCB',1),(20,'Laser',1),(21,'Maestro',1),(22,'Solo',1),(23,'Switch',1),(24,'iZettle',1),(25,'Swish',2),(26,'Venmo',NULL),(27,'Money Order',NULL),(28,'Alipay',7),(29,'Sofort',8),(30,'SEPA',9);
/*!40000 ALTER TABLE `payment_types` ENABLE KEYS */;
UNLOCK TABLES;
@@ -2592,4 +2592,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2017-09-10 9:46:52
+-- Dump completed on 2017-10-15 14:07:07
diff --git a/docs/api.rst b/docs/api.rst
index 95b8dfdcae99..b67bb606619a 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -115,6 +115,8 @@ You can archive, delete or restore an entity by setting ``action`` in the reques
curl -X PUT ninja.dev/api/v1/invoices/1?action=archive \
-H "X-Ninja-Token: TOKEN"
+.. TIP:: For invoices use `mark_sent` to manually mark the invoice as sent
+
Emailing Invoices
"""""""""""""""""
diff --git a/docs/conf.py b/docs/conf.py
index 9843be98f94c..543e5590bca2 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -57,9 +57,9 @@ author = u'Invoice Ninja'
# built documents.
#
# The short X.Y version.
-version = u'3.7'
+version = u'3.8'
# The full version, including alpha/beta/rc tags.
-release = u'3.7.2'
+release = u'3.8.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/configure.rst b/docs/configure.rst
index c36d1d851859..8c4f8dff21a3 100644
--- a/docs/configure.rst
+++ b/docs/configure.rst
@@ -101,6 +101,15 @@ You need to create a `Google Maps API `_ and then running:
+
+.. code-block:: shell
+
+ nativefier --name "Invoice Ninja" --user-agent "Time Tracker" https://example.com/time_tracker
+
Voice Commands
""""""""""""""
diff --git a/docs/install.rst b/docs/install.rst
index 95ab08932e36..6cd6b3e5487b 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -64,7 +64,7 @@ You’ll need to create a new database along with a user to access it. Most host
Step 4: Configure the web server
""""""""""""""""""""""""""""""""
-Please see these guides for detailed information on configuring Apache or Nginx.
+See the guides listed above for detailed information on configuring Apache or Nginx.
Once you can access the site the initial setup screen will enable you to configure the database and email settings as well as create the initial admin user.
diff --git a/docs/invoices.rst b/docs/invoices.rst
index d44f29254604..54475c65ea76 100644
--- a/docs/invoices.rst
+++ b/docs/invoices.rst
@@ -3,9 +3,9 @@ Invoices
Well, it’s time to bill, and the Invoices function of Invoice Ninja lets you get the job done fast and with perfect accuracy.
-With a bustling freelance business, you’re going to be sending out a lot of invoices. Creating an invoice is simple with the New Invoice page. Once you’ve entered the client, job and rates information, you’ll see a preview of your invoice, and you’ll have a range of actions at your fingertips – from saving a draft, to sending the invoice to the client via email, to printing a PDF hard copy.
+With a bustling freelance business, you’re going to be sending out a lot of invoices. Creating an invoice is simple with the New Invoice page. Once you’ve entered the client, job and rates information, you’ll see a live PDF preview of your invoice, and you’ll have a range of actions at your fingertips – from saving a draft, to sending the invoice to the client via email, to printing a PDF hard copy.
-List Invoices
+Invoices List page
"""""""""""""
With numerous invoices to keep track of, the Invoices list page is your go-to guide for the entire history and status of all your invoices – including those that have been paid, those sent but unpaid, and those still in the drafting and editing stage.
@@ -20,22 +20,24 @@ The life of an invoice in the Invoice Ninja system is made up of a number of sta
- **Viewed**: The client has opened the invoice email and viewed the invoice.
- **Partial**: The invoice has been partially paid.
- **Paid**: Congratulations! The client has paid the full invoice amount.
+- **Unpaid**: The invoice remains unpaid.
+- **Overdue**: The invoice has passed its due date.
In order to understand exactly how the Invoices list page works, we’ll take you through it step by step.
-To view your Invoices list page, click the Invoices tab on the main taskbar. This will open the Invoices list page.
+To view your Invoices list page, click the Invoices tab on the main sidebar. This will open the Invoices list page.
-The Invoices list page displays a table of all your invoices, at every stage, from the moment you create a new invoice, to the moment you archive or delete an invoice.
+The Invoices list page displays a table of all your active invoices, at every stage, from the moment you create a new invoice, to the moment you archive or delete an invoice.
Let's explore the invoices list according to the tabs on the main header bar of the table from left to right:
- **Invoice #**: The number of the invoice
-- **Client**: The client name
-- **Invoice Date**: The date the invoice was issued
-- **Invoice Total**: The total amount of the invoice
-- **Balance Due**: The amount owed by the client (after credits and other adjustments are calculated)
+- **Client Name**: The name of the client
+- **Date**: The date the invoice was issued
+- **Amount**: The total amount of the invoice
+- **Balance**: The amount owed by the client (after credits and other adjustments are calculated)
- **Due Date**: The date the payment is due
-- **Status**: The current status of the invoice (Gray = Draft, Blue = Sent, XX = Viewed, XX = Partial, Green = Paid)
+- **Status**: The current status of the invoice (Draft, Sent, Viewed, Partial, Paid, Unpaid, Overdue)
- **Action**: The Action button provides a range of possible actions, depending upon the status of the invoice.
To view the actions, hover your mouse over the Action area of the relevant invoice entry and a gray Select button will appear. Click on the arrow at the right side of the button to open a drop-down list. For invoices with “Draft” status, the drop-down list presents the following action items:
@@ -43,14 +45,40 @@ To view the actions, hover your mouse over the Action area of the relevant invoi
- **Edit Invoice**: Edit the invoice information on the Edit Invoice page.
- **Clone Invoice**: Duplicate the invoice. Then you can make minor adjustments. This is a fast way to create a new invoice that is identical or similar to this invoice.
- **View History**: You'll be redirected to the Invoices / History page, where you can view a history of all the actions taken from the time the invoice was created. The Invoices / History page displays a copy of the latest version of the invoice and a drop-down list of all actions and the corresponding version of the invoice. Select the version you wish to view. Click on the blue Edit Invoice button at the top right of the page to edit the invoice.
-- **Mark Sent**: When you have sent the invoice to your customer, mark as Sent. This will update the invoice status in the Invoices list, so you can keep track.
+- **Mark Sent**: When you mark an invoice as sent, only then is the invoice viewable to the client in the client portal, and the client balance is updated to reflect the invoice amount.
+- **Mark Paid**: Manually mark the invoice as paid. You may want to do this if you are not entering the payment directly into the system.
- **Enter Payment**: Enter the payment relevant to this invoice. You'll be redirected to the Payments / Create page.
- **Archive Invoice**: Click here to archive the invoice. It will be archived and removed from the Invoices list page.
- **Delete Invoice**: Click here to delete the invoice. It will be deleted and removed from the Invoices list page.
-.. TIP:: For invoices with “Viewed”, “Sent”, “Partial” or “Paid” status, only the relevant and applicable options from the above list will show in the Action drop-down list.
+.. TIP:: For invoices with a status other than "Draft", only the relevant and applicable options from the above list will show in the Action drop-down list.
+
+.. TIP:: To sort the invoices list according to any of the columns, click on the column tab of your choice. A small arrow will appear. If the arrow is pointing up, data is sorted from lowest to highest value. If the arrow is pointing down, data is sorted from highest to lowest value. Click to change the arrow direction.
+
+Filtering Invoices
+^^^^^^^^^^^^^^^^^^
+
+You can easily filter your invoices list according to any state or status - Archived, Deleted, Draft, Viewed, Partial, Paid, Unpaid, Overdue. Go to the Filter field, located at the top left of the Invoices list page. Click inside the field. A drop down menu will open, displaying all the filter options. Click on the filter option or multiple options you want. The list will refresh automatically to display your chosen filters.
+
+.. TIP:: The default filter is Active, so all your current active invoices will be displayed in the list, no matter the status. Remove the Active filter by clicking on the X.
+
+Bulk Actions
+^^^^^^^^^^^^
+
+If you need to perform an action for a number of invoices, you can do it in one click with the bulk action feature. To use the bulk action feature, mark the relevant invoices in their checkbox at the far left of the invoices list. Once you've marked the invoices, click on the arrow of the gray Archive button, which is located at the top left of the invoices list. A drop down menu will open, featuring the following options:
+
+- **Download Invoice**: Download PDF versions of the marked invoices.
+- **Email Invoice**: Send invoices by email to the client(s).
+- **Mark Sent**: Mark invoices as sent. Only then are these invoices viewable to the client in the client portal, and the client's total balance updated with the amounts of these invoices.
+- **Mark Paid**: Mark invoices as paid.
+- **Archive Invoice**: Archive invoices.
+- **Delete Invoice**: Delete invoices.
+
+Select the relevant option. The action will be taken automatically and instantly for all the invoices you checked.
+
+.. TIP:: The number of invoices marked for bulk action will show on the Archive button. It is updated automatically when you check each invoice. This will help you keep track.
+
-.. TIP:: To sort the invoices list according to any of the columns, click on the orange column tab of your choice. A small arrow will appear. If the arrow is pointing up, data is sorted from lowest to highest value. If the arrow is pointing down, data is sorted from highest to lowest value. Click to change the arrow direction.
Create Invoice
""""""""""""""
@@ -59,7 +87,7 @@ Here, we’re going to focus on how to create a new invoice.
**Let’s Begin**
-To create a new invoice, go to the Invoices tab on the main taskbar, open the drop-down menu, and click on New Invoice. This will open the Invoices / Create page.
+To create a new invoice, go to the Invoices tab on the main sidebar, and click on the + sign. This will open the Invoices / Create page.
When you open the Invoices / Create page, the Invoice Ninja system will automatically create a new, empty invoice for you to complete. Note that each new invoice you create will be automatically numbered in chronological order. This will ensure your records are kept logical and organized. (You have the option to change the invoice number manually. We'll discuss that a little later.)
@@ -68,71 +96,83 @@ The top section of the invoice contains a range of important information specifi
- **Client**: Click on the arrow at the right end of the Client field. Select the relevant client from the client list. TIP: You can create a new client while creating a new invoice. Simply click on the Create new client link, situated below the Client field on the Invoices / Create page. A pop-up window will open, enabling you to complete the new client’s details. Then continue creating the invoice for this new client.
- **Invoice Date**: The date of creation of the invoice. Click the calendar icon to select the relevant date.
- **Due Date**: The date the invoice payment is due. Click the calendar icon to select the relevant date.
-- **Partial**: In the event that you need to bill the client for a partial amount of the total amount due, enter the amount in the Partial field. This will be automatically applied to the invoice.
+- **Partial/Deposit**: In the event that you need to bill the client for a partial amount of the total amount due, enter the amount in the Partial/Deposit field. This will be automatically applied to the invoice.
- **Invoice #**: The invoice number is assigned automatically when you create a new invoice, in order of chronology. TIP: You can manually override the default invoice number by entering a different number in the Invoice # field.
- **PO #**: The purchase order number. Enter the purchase order number for easy reference.
- **Discount**: If you wish to apply a discount to the invoice, you can choose one of two methods: a monetary amount, or a percentage of the total amount due. To choose a method, click on the arrow at the right side of the box next to the Discount field. Select Percent or Amount from the drop-down list. Then enter the relevant figure. For example, to apply a 20% discount, enter the number 20, and select “Percent” from the drop-down list. To apply a $50 discount, enter the number 50, and select “Amount” from the drop-down list.
-- **Taxes**: Manage the various tax rates that apply by clicking on the Manage rates link. The Tax Rates pop-up window will open. To apply a tax rate, enter the name of the tax in the Name field, and the percentage amount in the Rate field. For example, to apply a VAT of 17%, enter VAT in the Name field, and 17 in the Rate field. TIP: If you need to apply multiple taxes, add another Name and Rate to the new row. A new row will open automatically as soon as you begin typing in the current row.
+.. TIP: The currency of the invoice will be set according to the default currency specified for this client when you created the client.
-The Tax Rates pop-up box offers various settings for presentation of taxes on the invoice. Check the boxes of the settings you wish to apply.
+Now that we’ve completed the general invoice information, it’s time to finish creating your invoice by specifying the job/s you’re billing for, the amounts due for each job/line item, taxes, discounts and final balance due. Let's explore the various columns of the invoice, from left to right along the header bar:
-- **Enable specifying an invoice tax**: Check this box to apply the tax rate for the entire invoice. It will appear on the invoice above the Balance Due field.
-- **Enable specifying line item taxes**: Check this box to apply various tax rates to specific items of the same invoice. This setting enables you to apply different taxes to the different line items.
-- **Display line item taxes inline**: Check this box to include a Tax column on the invoice, so your customer can view the tax amounts that apply to each line item.
-
-After selecting the desired tax settings, you’ll need to choose a tax rate for the invoice, or for each line item. To select a tax rate, click on the arrow at the right side of each Tax field that appears on the invoice. A drop-down list will open, featuring all the tax rates you created. Choose the relevant tax rate from the list. It will automatically apply and the figures in the invoice will adjust accordingly.
-
-.. TIP:: The currency of the invoice will be according to the default currency specified for this client when you created the client.
-
-Now that we’ve completed the general invoice information, it’s time to finish creating your invoice by specifying the job/s you’re billing for, the amounts due for each job/line item, taxes, discounts and final balance due. Let's explore the various columns of the invoice, from left to right along the orange header bar:
-
-- **Item**: This is the name of the item you are billing for. You can either enter the details manually, or by selecting one of the set items created by you at the Product Settings stage. To select a set item, click on the arrow at the right side of the item bar and choose the relevant item from the drop-down list. To enter the item manually, click inside the field and enter the item. Here are some examples of an item: 1 hour programming services OR 5 pages translation OR 1 hour consulting.
+- **Item**: This is the name of the item you are billing for. You can either enter the details manually, or by selecting one of the set items created by you in the Product Library. To select an item from your product library, click on the arrow at the right side of the item bar and choose the relevant item from the drop-down list. To enter the item manually, click inside the field and enter the item. Here are some examples of an item: 1 hour programming services OR 5 pages translation OR 1 hour consulting.
- **Description**: Add more information about the item. This will help the customer better understand the job completed, and is also useful for your own reference.
-- **Unit Cost**: The amount you charge per unit of items. For example, let's say your item is "1 hour consulting", and you charge $80 for an hour of consulting – that is, for 1 item unit. Then you'll enter 80 in the Unit Cost field. Note: If you have selected a set item, the unit cost that you pre-defined at the Product Settings stage will apply by default. You can manually override the default unit cost by clicking in the Unit Cost field and changing the value.
+- **Unit Cost**: The amount you charge per unit of items. For example, let's say your item is "1 hour consulting", and you charge $80 for an hour of consulting – that is, for 1 item unit. Then you'll enter 80 in the Unit Cost field.
+
+.. Note:: If you have selected a set item from the Product Library, the description and unit cost that you pre-defined in the Product Library will apply by default. You can manually override the default unit cost or description by clicking in field and changing the data.
+
- **Quantity**: The number of units being charged. Continuing the above example, let's say you need to charge for 3 hours of consulting, enter the number 3 in the Quantity field.
-- **Tax**: This field will only appear if you selected "Enable specifying line item taxes." To apply tax to the line item, click on the arrow at the right side of the Tax field and select the relevant tax from the drop-down list.
+- **Tax**: Note: This field will only appear if you selected "Enable specifying line item taxes" in the Settings > Tax Rates section of your account. To apply tax to the line item, click on the arrow at the right side of the Tax field and select the relevant tax from the drop-down list.
- **Line Total**: This is the amount due for the particular line item. Once you have entered the Unit Cost and Quantity, this figure will be calculated automatically. If you change either value at any time during creation of the invoice, the Line Total will adjust accordingly.
-.. TIP:: You can enter as many line items as you need in the invoice. As soon as you enter any data in a line item, a fresh, blank line item will open in the row below.
+.. TIP: You can enter as many line items as you need in the invoice. As soon as you enter any data in a line item, a fresh, blank line item will open in the row below.
Beneath and to the right of the line item section, you'll find the Balance Due section. It's made up of a number of figures, all leading to the golden number – the final, total Balance Due.
- **Subtotal**: This is the amount due before other figures are taken into calculation, such as Tax, Partial payments, Credits, etc.
-- **Tax**: The tax rate for the invoice. Here you can select the appropriate tax rate for the entire invoice by clicking the arrow at the right side of the Tax field and selecting the relevant tax from the drop-down list. Note: If you selected "Enable specifying line item taxes" in the Manage rates pop-up box, then the tax applied to each line item will appear here, listed individually.
+- **Tax**: The tax rate for the invoice. Note: To apply a tax rate to the entire invoice, you must enable it first. Go to Settings > Tax Rates, and check the box for "Enable specifying an invoice tax". Select the appropriate tax rate for the entire invoice by clicking the arrow at the right side of the Tax field and selecting the relevant tax from the drop-down list.
- **Paid to Date**: The amount paid to date, including partial payments and credits.
-- **Balance Due**: The final balance owed to you by your customer, after taxes, partial payments and credits have been deducted from the charged amount.
+- **Balance Due**: The final balance owed to you, after taxes, partial payments and credits have been deducted from the charged amount.
-Directly to the left of the Balance Due section, you'll see a text box with three tabs to choose from:
+Directly to the left of the Balance Due section, you'll see a text box with a number of tabs to choose from:
-- **Note to Client**: Want to write a personal or explanatory note to the client? Enter it here.
-- **Invoice Terms**: Want to set terms to the invoice? Enter them here. The terms will appear on the invoice. If you want to make these the default terms for all invoices, check the Save as default terms box. Then these terms will automatically appear on each invoice you create. Need to change the default terms? Click Reset Terms, and the text box will clear. You can enter new terms or leave blank.
-- **Invoice Footer**: Want to enter information to appear as a footer on the invoice? Enter it here. The text will appear at the bottom of the invoice. If you want to make this the default footer for all invoices, check the Save as default footer box. Then this footer will automatically appear on each invoice you create. Need to change the default footer? Click Reset footer, and the text box will clear. You can enter a new footer or leave blank.
+- **Public Notes**: Want to write a personal or explanatory note to the client? Enter it here.
+- **Private Notes**: Want to include some notes or comments for your eyes only? Enter them here, and only you can see them.
+- Terms: Want to set terms to the invoice? Enter them here. The terms will appear on the invoice. If you want to make these the default terms for all invoices, check the Save as default terms box. Then these terms will automatically appear on each invoice you create.
+- **Footer**: Want to enter information to appear as a footer on the invoice? Enter it here. The text will appear at the bottom of the invoice. If you want to make this the default footer for all invoices, check the Save as default footer box. Then this footer will automatically appear on each invoice you create.
+- **Documents**: If you have an Enterprise account, you can attach 3rd party documents to send with your invoice. Click to upload files from your computer, or use the drag and drop feature to attach them. You can attach any type of file as long as it doesn't exceed 10 MB in size. Note: You must enable this feature in order to attach 3rd party documents. To enable, go to Advanced Settings > Email Settings and check Enable for Attach PDFs and Attach Documents.
.. TIP:: The Invoices page is rich in clickable links, providing you with a shortcut to relevant pages you may wish to view. For example, all invoice numbers are clickable, taking you directly to the specific invoice page, and all client names are clickable, taking you directly to the specific client summary page.
Invoice Preview
^^^^^^^^^^^^^^^
-Did you know that all this time you've been creating the new invoice, a preview of the invoice appears below, and it changes in real time according to the data you've entered?
+Did you know that all this time you've been creating the new invoice, a live PDF preview of the invoice appears below, and it changes in real time according to the data you've entered?
Scroll down below the invoice data fields to check out the invoice preview.
But before we get there you'll see a row of colorful buttons, giving you a range of options:
- **Blue button – Download PDF**: Download the invoice as a PDF file. You can then print or save to your PC or mobile device.
-- **Green button – Save Invoice**: Save the last version of the invoice. The data is saved in your Invoice Ninja account. You can return to the invoice at any time to continue working on it.
-- **Orange button – Email Invoice**: Email the invoice directly via the Invoice Ninja system to the email address specified for the client.
-- **Gray button – More Actions**
+- **Gray button – Save Draft**: Save the latest version of the invoice. The data is saved in your Invoice Ninja account. You can return to the invoice at any time to continue working on it. Note: An invoice in the Draft stage is not viewable to the client in the client portal, and the amount on the invoice is not reflected in the client's invoicing balance.
+- **Green button – Mark Sent**: If you mark the invoice as sent, then the invoice will be viewable to your client in the client portal. The amount on the invoice will also be calculated in the client's balance data.
+- **Orange button - Email Invoice**: Email the invoice directly via the Invoice Ninja system to the email address specified for the client.
+- **Gray button – More Actions**: Click on More Actions to open the following action list:
-Click on More Actions to open the following action list:
-
-- **Clone**: Invoice Duplicate the current invoice. Then you can make minor adjustments. This is a fast way to create a new invoice that is identical or similar to a previous invoice.
+- **Clone Invoice**: Duplicate the current invoice. Then you can make minor adjustments. This is a fast way to create a new invoice that is identical or similar to a previous invoice.
- **View History**: You'll be redirected to the Invoices / History page, where you can view a history of all the actions taken from the time the invoice was created. The Invoices / History page displays a copy of the latest version of the invoice and a drop-down list of all actions and the corresponding version of the invoice. Select the version you wish to view. Click on the blue Edit Invoice button at the top right of the page to go back to the invoice page.
-- **Mark Sent**: When you have sent the invoice to your customer, mark as Sent. This will update the invoice status in the Invoices list, so you can keep track.
+- **Mark Paid**: The invoice status is changed to Paid.
- **Enter Payment**: Enter the payment relevant to this invoice. You'll be redirected to the Payments / Create page.
- **Archive Invoice**: Want to archive the invoice? Click here. The invoice will be archived and removed from the Invoices list page.
- **Delete Invoice**: Want to delete the invoice? Click here. The invoice will be deleted and removed from the Invoices list page.
-.. TIP:: At the left of these colorful buttons, you'll see a field with an arrow that opens a drop-down menu. This field provides you with template options for the invoice design. Click on the arrow to select the desired template. When selected, the invoice preview will change to reflect the new template.
+.. TIP: At the left of these colorful buttons, you'll see a field with an arrow that opens a drop-down menu. This field provides you with template options for the invoice design. Click on the arrow to select the desired template. When selected, the live PDF invoice preview will change to reflect the new template.
-.. IMPORTANT:: Remember to click the green Save Invoice button every time you finish working on an invoice. If you don't click Save, you will lose the changes made. (But don't worry – if you forget to click Save, a dialog box with a reminder to save will open when you try to leave the page.)
+.. IMPORTANT: Remember to click the gray Save Draft button every time you finish working on an invoice. If you don't click Save, you will lose the changes made. (But don't worry – if you forget to click Save, a dialog box with a reminder to save will open when you try to leave the page.)
+
+Email Invoice preview
+^^^^^^^^^^^^^^^^^^^^^
+
+When you are ready to send an invoice to the client, click the orange Email Invoice button. Before the invoice email is sent, a pop-up box will open, displaying a preview of the email. Here, you can customize the email template, including the text, data fields, and formatting. You can also view the sent history of the email.
+
+Customizing the Invoice Email Template
+''''''''''''''''''''''''''''''''''''''
+
+To customize the email template, click the Customize tab. Add text or edit the default text, and use the formatting toolbar below to adjust the layout. Once you've finished customizing, click the Preview tab to see how the email looks.
+Note: The email contains variables that automatically insert the relevant data to the email, so you don't need to type it in. Examples include the client's name and invoice balance. To see a full list of the variables you can insert and how to write them, click the question mark icon at the right end of the email subject line header.
+
+.. TIP:: You can customize any type of email template from the Email Invoice box, including Initial Email, First Reminder, Second Reminder and Third Reminder emails. Go to Email Template and click to open the drop-down menu. Select the relevant template you want to work on.
+
+Viewing the Email History
+'''''''''''''''''''''''''
+
+To view a history of when the email invoice was last sent, click the History tab. A list of all instances the email was sent will be shown here, according to date.
diff --git a/docs/mobile_apps.rst b/docs/mobile_apps.rst
index 37b4dbe509fc..8a005c3d50a5 100644
--- a/docs/mobile_apps.rst
+++ b/docs/mobile_apps.rst
@@ -3,6 +3,8 @@ Mobile Applications
The Invoice Ninja iPhone and Android applications allows a user to connect to their self-hosted Invoice Ninja web application.
+.. TIP:: If you're unable to access the Android app store you can download the APK here: https://download.invoiceninja.com/apk
+
Connecting your to your self-hosted invoice ninja installation requires a couple of easy steps.
Web App configuration
diff --git a/gulpfile.js b/gulpfile.js
index e3f133634544..bb841eed0951 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -50,6 +50,7 @@ elixir(function(mix) {
bowerDir + '/dropzone/dist/dropzone.css',
bowerDir + '/spectrum/spectrum.css',
bowerDir + '/sweetalert2/dist/sweetalert2.css',
+ bowerDir + '/toastr/toastr.css',
'bootstrap-combobox.css',
'typeahead.js-bootstrap.css',
'style.css',
@@ -66,6 +67,10 @@ elixir(function(mix) {
bowerDir + '/bootstrap-daterangepicker/daterangepicker.css'
], 'public/css/daterangepicker.css');
+ mix.styles([
+ bowerDir + '/jt.timepicker/jquery.timepicker.css'
+ ], 'public/css/jquery.timepicker.css');
+
mix.styles([
bowerDir + '/select2/dist/css/select2.css'
], 'public/css/select2.css');
@@ -76,6 +81,10 @@ elixir(function(mix) {
bowerDir + '/tablesorter/dist/css/widget.grouping.min.css'
], 'public/css/tablesorter.css');
+ mix.styles([
+ bowerDir + '/fullcalendar/dist/fullcalendar.css'
+ ], 'public/css/fullcalendar.css');
+
/**
* JS configuration
@@ -94,6 +103,15 @@ elixir(function(mix) {
bowerDir + '/bootstrap-daterangepicker/daterangepicker.js'
], 'public/js/daterangepicker.min.js');
+ mix.scripts([
+ bowerDir + '/jt.timepicker/jquery.timepicker.js'
+ ], 'public/js/jquery.timepicker.js');
+
+ mix.scripts([
+ bowerDir + '/fullcalendar/dist/fullcalendar.js',
+ bowerDir + '/fullcalendar/dist/locale-all.js',
+ ], 'public/js/fullcalendar.min.js');
+
mix.scripts([
bowerDir + '/card/dist/card.js',
], 'public/js/card.min.js');
@@ -141,12 +159,12 @@ elixir(function(mix) {
bowerDir + '/spectrum/spectrum.js',
bowerDir + '/moment/moment.js',
bowerDir + '/moment-timezone/builds/moment-timezone-with-data.js',
- //bowerDir + '/stacktrace-js/dist/stacktrace-with-polyfills.min.js',
+ bowerDir + '/stacktrace-js/stacktrace.js',
bowerDir + '/es6-promise/es6-promise.auto.js',
bowerDir + '/sweetalert2/dist/sweetalert2.js',
- //bowerDir + '/sweetalert/dist/sweetalert-dev.js',
bowerDir + '/nouislider/distribute/nouislider.js',
bowerDir + '/mousetrap/mousetrap.js',
+ bowerDir + '/toastr/toastr.js',
bowerDir + '/fuse.js/src/fuse.js',
'bootstrap-combobox.js',
'script.js',
diff --git a/public/built.js b/public/built.js
index 3b60e30bee9b..445b4b184b20 100644
--- a/public/built.js
+++ b/public/built.js
@@ -1,19 +1,19 @@
-function generatePDF(t,e,n,i){if(t&&e){if(!n)return refreshTimer&&clearTimeout(refreshTimer),void(refreshTimer=setTimeout(function(){generatePDF(t,e,!0,i)},500));refreshTimer=null,t=calculateAmounts(t);var o=GetPdfMake(t,e,i);return i&&o.getDataUrl(i),o}}function copyObject(t){return!!t&&JSON.parse(JSON.stringify(t))}function processVariables(t){if(!t)return"";for(var e=["MONTH","QUARTER","YEAR"],n=0;n1?c=r.split("+")[1]:r.split("-").length>1&&(c=parseInt(r.split("-")[1])*-1),t=t.replace(r,getDatePart(i,c))}}return t}function getDatePart(t,e){return e=parseInt(e),e||(e=0),"MONTH"==t?getMonth(e):"QUARTER"==t?getQuarter(e):"YEAR"==t?getYear(e):void 0}function getMonth(t){var e=new Date,n=["January","February","March","April","May","June","July","August","September","October","November","December"],i=e.getMonth();return i=parseInt(i)+t,i%=12,i<0&&(i+=12),n[i]}function getYear(t){var e=new Date,n=e.getFullYear();return parseInt(n)+t}function getQuarter(t){var e=new Date,n=Math.floor((e.getMonth()+3)/3);return n+=t,n%=4,0==n&&(n=4),"Q"+n}function isStorageSupported(){try{return"localStorage"in window&&null!==window.localStorage}catch(t){return!1}}function isValidEmailAddress(t){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);return e.test(t)}function enableHoverClick(t,e,n){}function setAsLink(t,e){e?(t.css("text-decoration","underline"),t.css("cursor","pointer")):(t.css("text-decoration","none"),t.css("cursor","text"))}function setComboboxValue(t,e,n){t.find("input").val(e),t.find("input.form-control").val(n),e&&n?(t.find("select").combobox("setSelected"),t.find(".combobox-container").addClass("combobox-selected")):t.find(".combobox-container").removeClass("combobox-selected")}function convertDataURIToBinary(t){var e=t.indexOf(BASE64_MARKER)+BASE64_MARKER.length,n=t.substring(e);return base64DecToArr(n)}function comboboxHighlighter(t){var e=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),n=t.replace(new RegExp(" ","g"),"\n");return n=stripHtmlTags(n),n=n.replace(new RegExp("("+e+")","ig"),function(t,n){return n?""+n+"":e}),n.replace(new RegExp("\n","g")," ")}function inIframe(){try{return window.self!==window.top}catch(t){return!0}}function comboboxMatcher(t){return~stripHtmlTags(t).toLowerCase().indexOf(this.query.toLowerCase())}function stripHtmlTags(t){var e=document.createElement("div");return e.innerHTML=t,e.textContent||e.innerText||""}function getContactDisplayName(t){return t.first_name||t.last_name?$.trim((t.first_name||"")+" "+(t.last_name||"")):t.email}function getContactDisplayNameWithEmail(t){var e="";return(t.first_name||t.last_name)&&(e+=$.trim((t.first_name||"")+" "+(t.last_name||""))),t.email&&(e&&(e+=" - "),e+=t.email),$.trim(e)}function getClientDisplayName(t){var e=!!t.contacts&&t.contacts[0];return t.name?t.name:e?getContactDisplayName(e):""}function populateInvoiceComboboxes(t,e){for(var n={},i={},o={},a=$("select#client"),s=0;s1?t+=", ":n64&&t<91?t-65:t>96&&t<123?t-71:t>47&&t<58?t+4:43===t?62:47===t?63:0}function base64DecToArr(t,e){for(var n,i,o=t.replace(/[^A-Za-z0-9\+\/]/g,""),a=o.length,s=e?Math.ceil((3*a+1>>2)/e)*e:3*a+1>>2,r=new Uint8Array(s),c=0,l=0,u=0;u>>(16>>>n&24)&255;c=0}return r}function uint6ToB64(t){return t<26?t+65:t<52?t+71:t<62?t-4:62===t?43:63===t?47:65}function base64EncArr(t){for(var e=2,n="",i=t.length,o=0,a=0;a0&&4*a/3%76===0&&(n+="\r\n"),o|=t[a]<<(16>>>e&24),2!==e&&t.length-a!==1||(n+=String.fromCharCode(uint6ToB64(o>>>18&63),uint6ToB64(o>>>12&63),uint6ToB64(o>>>6&63),uint6ToB64(63&o)),o=0);return n.substr(0,n.length-2+e)+(2===e?"":1===e?"=":"==")}function UTF8ArrToStr(t){for(var e,n="",i=t.length,o=0;o251&&e<254&&o+5247&&e<252&&o+4239&&e<248&&o+3223&&e<240&&o+2191&&e<224&&o+1>>6),e[s++]=128+(63&n)):n<65536?(e[s++]=224+(n>>>12),e[s++]=128+(n>>>6&63),e[s++]=128+(63&n)):n<2097152?(e[s++]=240+(n>>>18),e[s++]=128+(n>>>12&63),e[s++]=128+(n>>>6&63),e[s++]=128+(63&n)):n<67108864?(e[s++]=248+(n>>>24),e[s++]=128+(n>>>18&63),e[s++]=128+(n>>>12&63),e[s++]=128+(n>>>6&63),e[s++]=128+(63&n)):(e[s++]=252+n/1073741824,e[s++]=128+(n>>>24&63),e[s++]=128+(n>>>18&63),e[s++]=128+(n>>>12&63),e[s++]=128+(n>>>6&63),e[s++]=128+(63&n));return e}function hexToR(t){return parseInt(cutHex(t).substring(0,2),16)}function hexToG(t){return parseInt(cutHex(t).substring(2,4),16)}function hexToB(t){return parseInt(cutHex(t).substring(4,6),16)}function cutHex(t){return"#"==t.charAt(0)?t.substring(1,7):t}function setDocHexColor(t,e){var n=hexToR(e),i=hexToG(e),o=hexToB(e);return t.setTextColor(n,i,o)}function setDocHexFill(t,e){var n=hexToR(e),i=hexToG(e),o=hexToB(e);return t.setFillColor(n,i,o)}function setDocHexDraw(t,e){var n=hexToR(e),i=hexToG(e),o=hexToB(e);return t.setDrawColor(n,i,o)}function toggleDatePicker(t){$("#"+t).datepicker("show")}function getPrecision(t){return roundToPrecision(t,3)!=t?4:roundToPrecision(t,2)!=t?3:2}function roundSignificant(t){var e=getPrecision(t),n=roundToPrecision(t,e);return isNaN(n)?0:n}function roundToTwo(t,e){var n=roundToPrecision(t,2);return e?n.toFixed(2):n||0}function roundToFour(t,e){var n=roundToPrecision(t,4);return e?n.toFixed(4):n||0}function roundToPrecision(t,e){var n=t<0;return n&&(t*=-1),t=+(Math.round(t+"e+"+e)+"e-"+e),n&&(t*=-1),t}function truncate(t,e){return t&&t.length>e?t.substr(0,e-1)+"...":t}function endsWith(t,e){return t.indexOf(e,t.length-e.length)!==-1}function secondsToTime(t){t=Math.round(t);var e=Math.floor(t/3600),n=t%3600,i=Math.floor(n/60),o=n%60,a=Math.ceil(o),s={h:e,m:i,s:a};return s}function twoDigits(t){return t<10?"0"+t:t}function toSnakeCase(t){return t?t.replace(/([A-Z])/g,function(t){return"_"+t.toLowerCase()}):""}function snakeToCamel(t){return t.replace(/_([a-z])/g,function(t){return t[1].toUpperCase()})}function getDescendantProp(t,e){for(var n=e.split(".");n.length&&(t=t[n.shift()]););return t}function doubleDollarSign(t){return t?t.replace?t.replace(/\$/g,"$$$"):t:""}function truncate(t,e){return t.length>e?t.substring(0,e)+"...":t}function actionListHandler(){$("tbody tr .tr-action").closest("tr").mouseover(function(){$(this).closest("tr").find(".tr-action").show(),$(this).closest("tr").find(".tr-status").hide()}).mouseout(function(){$dropdown=$(this).closest("tr").find(".tr-action"),$dropdown.hasClass("open")||($dropdown.hide(),$(this).closest("tr").find(".tr-status").show())})}function loadImages(t){$(t+" img").each(function(t,e){var n=$(e).attr("data-src");$(e).attr("src",n),$(e).attr("data-src",n)})}function prettyJson(t){return"string"!=typeof t&&(t=JSON.stringify(t,void 0,2)),t=t.replace(/&/g,"&").replace(//g,">"),t.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,function(t){var e="number";return/^"/.test(t)?e=/:$/.test(t)?"key":"string":/true|false/.test(t)?e="boolean":/null/.test(t)&&(e="null"),t=snakeToCamel(t),''+t+""})}function searchData(t,e,n){return function(i,o){var a;if(n){var s={keys:[e]},r=new Fuse(t,s);a=r.search(i)}else a=[],substrRegex=new RegExp(escapeRegExp(i),"i"),$.each(t,function(t,n){substrRegex.test(n[e])&&a.push(n)});o(a)}}function escapeRegExp(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function firstJSONError(t){for(var e in t)if(t.hasOwnProperty(e)){var n=t[e];for(var i in n)if(n.hasOwnProperty(i))return n[i]}return!1}function pad(t,e,n){return n=n||"0",t+="",t.length>=e?t:new Array(e-t.length+1).join(n)+t}function GetPdfMake(t,e,n){function i(e,n){if("string"==typeof n){if(0===n.indexOf("$firstAndLast")){var i=n.split(":");return function(t,e){return 0===t||t===e.table.body.length?parseFloat(i[1]):0}}if(0===n.indexOf("$none"))return function(t,e){return 0};if(0===n.indexOf("$notFirstAndLastColumn")){var i=n.split(":");return function(t,e){return 0===t||t===e.table.widths.length?0:parseFloat(i[1])}}if(0===n.indexOf("$notFirst")){var i=n.split(":");return function(t,e){return 0===t?0:parseFloat(i[1])}}if(0===n.indexOf("$amount")){var i=n.split(":");return function(t,e){return parseFloat(i[1])}}if(0===n.indexOf("$primaryColor")){var i=n.split(":");return NINJA.primaryColor||i[1]}if(0===n.indexOf("$secondaryColor")){var i=n.split(":");return NINJA.secondaryColor||i[1]}}if(t.features.customize_invoice_design){if("header"===e)return function(e,i){return 1===e||"1"==t.account.all_pages_header?t.features.remove_created_by?NINJA.updatePageCount(JSON.parse(JSON.stringify(n)),e,i):n:""};if("footer"===e)return function(e,i){return e===i||"1"==t.account.all_pages_footer?t.features.remove_created_by?NINJA.updatePageCount(JSON.parse(JSON.stringify(n)),e,i):n:""}}return"text"===e&&(n=NINJA.parseMarkdownText(n,!0)),n}function o(t){window.ninjaFontVfs[t.folder]&&(folder="fonts/"+t.folder,pdfMake.fonts[t.name]={normal:folder+"/"+t.normal,italics:folder+"/"+t.italics,bold:folder+"/"+t.bold,bolditalics:folder+"/"+t.bolditalics})}var a=!1;if(t.hasSecondTable){for(var s=JSON.parse(e),r=0;r0&&e-1 in t))}function i(t,e,n){if(ot.isFunction(e))return ot.grep(t,function(t,i){return!!e.call(t,i,t)!==n});if(e.nodeType)return ot.grep(t,function(t){return t===e!==n});if("string"==typeof e){if(dt.test(e))return ot.filter(e,t,n);e=ot.filter(e,t)}return ot.grep(t,function(t){return ot.inArray(t,e)>=0!==n})}function o(t,e){do t=t[e];while(t&&1!==t.nodeType);return t}function a(t){var e=yt[t]={};return ot.each(t.match(Mt)||[],function(t,n){e[n]=!0}),e}function s(){ft.addEventListener?(ft.removeEventListener("DOMContentLoaded",r,!1),t.removeEventListener("load",r,!1)):(ft.detachEvent("onreadystatechange",r),t.detachEvent("onload",r))}function r(){(ft.addEventListener||"load"===event.type||"complete"===ft.readyState)&&(s(),ot.ready())}function c(t,e,n){if(void 0===n&&1===t.nodeType){var i="data-"+e.replace(wt,"-$1").toLowerCase();if(n=t.getAttribute(i),"string"==typeof n){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:Tt.test(n)?ot.parseJSON(n):n)}catch(o){}ot.data(t,e,n)}else n=void 0}return n}function l(t){var e;for(e in t)if(("data"!==e||!ot.isEmptyObject(t[e]))&&"toJSON"!==e)return!1;return!0}function u(t,e,n,i){if(ot.acceptData(t)){var o,a,s=ot.expando,r=t.nodeType,c=r?ot.cache:t,l=r?t[s]:t[s]&&s;if(l&&c[l]&&(i||c[l].data)||void 0!==n||"string"!=typeof e)return l||(l=r?t[s]=Y.pop()||ot.guid++:s),c[l]||(c[l]=r?{}:{toJSON:ot.noop}),"object"!=typeof e&&"function"!=typeof e||(i?c[l]=ot.extend(c[l],e):c[l].data=ot.extend(c[l].data,e)),a=c[l],i||(a.data||(a.data={}),a=a.data),void 0!==n&&(a[ot.camelCase(e)]=n),"string"==typeof e?(o=a[e],null==o&&(o=a[ot.camelCase(e)])):o=a,o}}function h(t,e,n){if(ot.acceptData(t)){var i,o,a=t.nodeType,s=a?ot.cache:t,r=a?t[ot.expando]:ot.expando;if(s[r]){if(e&&(i=n?s[r]:s[r].data)){ot.isArray(e)?e=e.concat(ot.map(e,ot.camelCase)):e in i?e=[e]:(e=ot.camelCase(e),e=e in i?[e]:e.split(" ")),o=e.length;for(;o--;)delete i[e[o]];if(n?!l(i):!ot.isEmptyObject(i))return}(n||(delete s[r].data,l(s[r])))&&(a?ot.cleanData([t],!0):nt.deleteExpando||s!=s.window?delete s[r]:s[r]=null)}}}function d(){return!0}function p(){return!1}function f(){try{return ft.activeElement}catch(t){}}function m(t){var e=Et.split("|"),n=t.createDocumentFragment();if(n.createElement)for(;e.length;)n.createElement(e.pop());return n}function g(t,e){var n,i,o=0,a=typeof t.getElementsByTagName!==zt?t.getElementsByTagName(e||"*"):typeof t.querySelectorAll!==zt?t.querySelectorAll(e||"*"):void 0;if(!a)for(a=[],n=t.childNodes||t;null!=(i=n[o]);o++)!e||ot.nodeName(i,e)?a.push(i):ot.merge(a,g(i,e));return void 0===e||e&&ot.nodeName(t,e)?ot.merge([t],a):a}function b(t){xt.test(t.type)&&(t.defaultChecked=t.checked)}function v(t,e){return ot.nodeName(t,"table")&&ot.nodeName(11!==e.nodeType?e:e.firstChild,"tr")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}function M(t){return t.type=(null!==ot.find.attr(t,"type"))+"/"+t.type,t}function y(t){var e=Vt.exec(t.type);return e?t.type=e[1]:t.removeAttribute("type"),t}function A(t,e){for(var n,i=0;null!=(n=t[i]);i++)ot._data(n,"globalEval",!e||ot._data(e[i],"globalEval"))}function _(t,e){if(1===e.nodeType&&ot.hasData(t)){var n,i,o,a=ot._data(t),s=ot._data(e,a),r=a.events;if(r){delete s.handle,s.events={};for(n in r)for(i=0,o=r[n].length;i")).appendTo(e.documentElement),e=(Qt[0].contentWindow||Qt[0].contentDocument).document,e.write(),e.close(),n=T(t,e),Qt.detach()),Zt[t]=n),n}function C(t,e){return{get:function(){var n=t();if(null!=n)return n?void delete this.get:(this.get=e).apply(this,arguments)}}}function O(t,e){if(e in t)return e;for(var n=e.charAt(0).toUpperCase()+e.slice(1),i=e,o=de.length;o--;)if(e=de[o]+n,e in t)return e;return i}function N(t,e){for(var n,i,o,a=[],s=0,r=t.length;s=0&&n=0},isEmptyObject:function(t){var e;for(e in t)return!1;return!0},isPlainObject:function(t){var e;if(!t||"object"!==ot.type(t)||t.nodeType||ot.isWindow(t))return!1;try{if(t.constructor&&!et.call(t,"constructor")&&!et.call(t.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}if(nt.ownLast)for(e in t)return et.call(t,e);for(e in t);return void 0===e||et.call(t,e)},type:function(t){return null==t?t+"":"object"==typeof t||"function"==typeof t?Z[tt.call(t)]||"object":typeof t},globalEval:function(e){e&&ot.trim(e)&&(t.execScript||function(e){t.eval.call(t,e)})(e)},camelCase:function(t){return t.replace(st,"ms-").replace(rt,ct)},nodeName:function(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()},each:function(t,e,i){var o,a=0,s=t.length,r=n(t);if(i){if(r)for(;a_.cacheLength&&delete t[e.shift()],t[n+" "]=i}var e=[];return t}function i(t){return t[P]=!0,t}function o(t){var e=D.createElement("div");try{return!!t(e)}catch(n){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function a(t,e){for(var n=t.split("|"),i=t.length;i--;)_.attrHandle[n[i]]=e}function s(t,e){var n=e&&t,i=n&&1===t.nodeType&&1===e.nodeType&&(~e.sourceIndex||V)-(~t.sourceIndex||V);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===e)return-1;return t?1:-1}function r(t){return function(e){var n=e.nodeName.toLowerCase();return"input"===n&&e.type===t}}function c(t){return function(e){var n=e.nodeName.toLowerCase();return("input"===n||"button"===n)&&e.type===t}}function l(t){return i(function(e){return e=+e,i(function(n,i){for(var o,a=t([],n.length,e),s=a.length;s--;)n[o=a[s]]&&(n[o]=!(i[o]=n[o]))})})}function u(t){return t&&"undefined"!=typeof t.getElementsByTagName&&t}function h(){}function d(t){for(var e=0,n=t.length,i="";e1?function(e,n,i){for(var o=t.length;o--;)if(!t[o](e,n,i))return!1;return!0}:t[0]}function m(t,n,i){for(var o=0,a=n.length;o-1&&(i[l]=!(s[l]=h))}}else M=g(M===s?M.splice(f,M.length):M),a?a(null,s,M,c):Q.apply(s,M)})}function v(t){for(var e,n,i,o=t.length,a=_.relative[t[0].type],s=a||_.relative[" "],r=a?1:0,c=p(function(t){return t===e},s,!0),l=p(function(t){return tt(e,t)>-1},s,!0),u=[function(t,n,i){var o=!a&&(i||n!==N)||((e=n).nodeType?c(t,n,i):l(t,n,i));return e=null,o}];r1&&f(u),r>1&&d(t.slice(0,r-1).concat({value:" "===t[r-2].type?"*":""})).replace(ct,"$1"),n,r0,a=t.length>0,s=function(i,s,r,c,l){var u,h,d,p=0,f="0",m=i&&[],b=[],v=N,M=i||a&&_.find.TAG("*",l),y=R+=null==v?1:Math.random()||.1,A=M.length;for(l&&(N=s!==D&&s);f!==A&&null!=(u=M[f]);f++){if(a&&u){for(h=0;d=t[h++];)if(d(u,s,r)){c.push(u);break}l&&(R=y)}o&&((u=!d&&u)&&p--,i&&m.push(u))}if(p+=f,o&&f!==p){for(h=0;d=n[h++];)d(m,b,s,r);if(i){if(p>0)for(;f--;)m[f]||b[f]||(b[f]=K.call(c));b=g(b)}Q.apply(c,b),l&&!i&&b.length>0&&p+n.length>1&&e.uniqueSort(c)}return l&&(R=y,N=v),m};return o?i(s):s}var y,A,_,z,T,w,C,O,N,S,x,L,D,k,q,W,E,B,I,P="sizzle"+1*new Date,X=t.document,R=0,F=0,H=n(),j=n(),U=n(),$=function(t,e){return t===e&&(x=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],K=J.pop,G=J.push,Q=J.push,Z=J.slice,tt=function(t,e){for(var n=0,i=t.length;n+~]|"+nt+")"+nt+"*"),ht=new RegExp("="+nt+"*([^\\]'\"]*?)"+nt+"*\\]","g"),dt=new RegExp(st),pt=new RegExp("^"+ot+"$"),ft={ID:new RegExp("^#("+it+")"),CLASS:new RegExp("^\\.("+it+")"),TAG:new RegExp("^("+it.replace("w","w*")+")"),ATTR:new RegExp("^"+at),PSEUDO:new RegExp("^"+st),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+nt+"*(even|odd|(([+-]|)(\\d*)n|)"+nt+"*(?:([+-]|)"+nt+"*(\\d+)|))"+nt+"*\\)|)","i"),bool:new RegExp("^(?:"+et+")$","i"),needsContext:new RegExp("^"+nt+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+nt+"*((?:-\\d)?\\d*)"+nt+"*\\)|)(?=[^-]|$)","i")},mt=/^(?:input|select|textarea|button)$/i,gt=/^h\d$/i,bt=/^[^{]+\{\s*\[native \w/,vt=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Mt=/[+~]/,yt=/'|\\/g,At=new RegExp("\\\\([\\da-f]{1,6}"+nt+"?|("+nt+")|.)","ig"),_t=function(t,e,n){var i="0x"+e-65536;return i!==i||n?e:i<0?String.fromCharCode(i+65536):String.fromCharCode(i>>10|55296,1023&i|56320)},zt=function(){L()};try{Q.apply(J=Z.call(X.childNodes),X.childNodes),J[X.childNodes.length].nodeType}catch(Tt){Q={apply:J.length?function(t,e){G.apply(t,Z.call(e))}:function(t,e){for(var n=t.length,i=0;t[n++]=e[i++];);t.length=n-1}}}A=e.support={},T=e.isXML=function(t){var e=t&&(t.ownerDocument||t).documentElement;return!!e&&"HTML"!==e.nodeName},L=e.setDocument=function(t){var e,n,i=t?t.ownerDocument||t:X;return i!==D&&9===i.nodeType&&i.documentElement?(D=i,k=i.documentElement,n=i.defaultView,n&&n!==n.top&&(n.addEventListener?n.addEventListener("unload",zt,!1):n.attachEvent&&n.attachEvent("onunload",zt)),q=!T(i),A.attributes=o(function(t){return t.className="i",!t.getAttribute("className")}),A.getElementsByTagName=o(function(t){return t.appendChild(i.createComment("")),!t.getElementsByTagName("*").length}),A.getElementsByClassName=bt.test(i.getElementsByClassName),A.getById=o(function(t){return k.appendChild(t).id=P,!i.getElementsByName||!i.getElementsByName(P).length}),A.getById?(_.find.ID=function(t,e){if("undefined"!=typeof e.getElementById&&q){var n=e.getElementById(t);return n&&n.parentNode?[n]:[]}},_.filter.ID=function(t){var e=t.replace(At,_t);return function(t){return t.getAttribute("id")===e}}):(delete _.find.ID,_.filter.ID=function(t){var e=t.replace(At,_t);return function(t){var n="undefined"!=typeof t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}}),_.find.TAG=A.getElementsByTagName?function(t,e){return"undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t):A.qsa?e.querySelectorAll(t):void 0}:function(t,e){var n,i=[],o=0,a=e.getElementsByTagName(t);if("*"===t){for(;n=a[o++];)1===n.nodeType&&i.push(n);return i}return a},_.find.CLASS=A.getElementsByClassName&&function(t,e){if(q)return e.getElementsByClassName(t)},E=[],W=[],(A.qsa=bt.test(i.querySelectorAll))&&(o(function(t){k.appendChild(t).innerHTML="",t.querySelectorAll("[msallowcapture^='']").length&&W.push("[*^$]="+nt+"*(?:''|\"\")"),t.querySelectorAll("[selected]").length||W.push("\\["+nt+"*(?:value|"+et+")"),t.querySelectorAll("[id~="+P+"-]").length||W.push("~="),t.querySelectorAll(":checked").length||W.push(":checked"),t.querySelectorAll("a#"+P+"+*").length||W.push(".#.+[+~]")}),o(function(t){var e=i.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&W.push("name"+nt+"*[*^$|!~]?="),t.querySelectorAll(":enabled").length||W.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),W.push(",.*:")})),(A.matchesSelector=bt.test(B=k.matches||k.webkitMatchesSelector||k.mozMatchesSelector||k.oMatchesSelector||k.msMatchesSelector))&&o(function(t){A.disconnectedMatch=B.call(t,"div"),B.call(t,"[s!='']:x"),E.push("!=",st)}),W=W.length&&new RegExp(W.join("|")),E=E.length&&new RegExp(E.join("|")),e=bt.test(k.compareDocumentPosition),I=e||bt.test(k.contains)?function(t,e){var n=9===t.nodeType?t.documentElement:t,i=e&&e.parentNode;return t===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):t.compareDocumentPosition&&16&t.compareDocumentPosition(i)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},$=e?function(t,e){if(t===e)return x=!0,0;var n=!t.compareDocumentPosition-!e.compareDocumentPosition;return n?n:(n=(t.ownerDocument||t)===(e.ownerDocument||e)?t.compareDocumentPosition(e):1,1&n||!A.sortDetached&&e.compareDocumentPosition(t)===n?t===i||t.ownerDocument===X&&I(X,t)?-1:e===i||e.ownerDocument===X&&I(X,e)?1:S?tt(S,t)-tt(S,e):0:4&n?-1:1)}:function(t,e){if(t===e)return x=!0,0;var n,o=0,a=t.parentNode,r=e.parentNode,c=[t],l=[e];if(!a||!r)return t===i?-1:e===i?1:a?-1:r?1:S?tt(S,t)-tt(S,e):0;if(a===r)return s(t,e);for(n=t;n=n.parentNode;)c.unshift(n);for(n=e;n=n.parentNode;)l.unshift(n);for(;c[o]===l[o];)o++;return o?s(c[o],l[o]):c[o]===X?-1:l[o]===X?1:0},i):D},e.matches=function(t,n){return e(t,null,null,n)},e.matchesSelector=function(t,n){if((t.ownerDocument||t)!==D&&L(t),n=n.replace(ht,"='$1']"),A.matchesSelector&&q&&(!E||!E.test(n))&&(!W||!W.test(n)))try{var i=B.call(t,n);if(i||A.disconnectedMatch||t.document&&11!==t.document.nodeType)return i}catch(o){}return e(n,D,null,[t]).length>0},e.contains=function(t,e){return(t.ownerDocument||t)!==D&&L(t),I(t,e)},e.attr=function(t,e){(t.ownerDocument||t)!==D&&L(t);var n=_.attrHandle[e.toLowerCase()],i=n&&Y.call(_.attrHandle,e.toLowerCase())?n(t,e,!q):void 0;return void 0!==i?i:A.attributes||!q?t.getAttribute(e):(i=t.getAttributeNode(e))&&i.specified?i.value:null},e.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},e.uniqueSort=function(t){var e,n=[],i=0,o=0;if(x=!A.detectDuplicates,S=!A.sortStable&&t.slice(0),t.sort($),x){for(;e=t[o++];)e===t[o]&&(i=n.push(o));for(;i--;)t.splice(n[i],1)}return S=null,t},z=e.getText=function(t){var e,n="",i=0,o=t.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)n+=z(t)}else if(3===o||4===o)return t.nodeValue}else for(;e=t[i++];)n+=z(e);return n},_=e.selectors={cacheLength:50,createPseudo:i,match:ft,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(At,_t),t[3]=(t[3]||t[4]||t[5]||"").replace(At,_t),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||e.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&e.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return ft.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&dt.test(n)&&(e=w(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(At,_t).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=H[t+" "];return e||(e=new RegExp("(^|"+nt+")"+t+"("+nt+"|$)"))&&H(t,function(t){return e.test("string"==typeof t.className&&t.className||"undefined"!=typeof t.getAttribute&&t.getAttribute("class")||"")})},ATTR:function(t,n,i){return function(o){var a=e.attr(o,t);return null==a?"!="===n:!n||(a+="","="===n?a===i:"!="===n?a!==i:"^="===n?i&&0===a.indexOf(i):"*="===n?i&&a.indexOf(i)>-1:"$="===n?i&&a.slice(-i.length)===i:"~="===n?(" "+a.replace(rt," ")+" ").indexOf(i)>-1:"|="===n&&(a===i||a.slice(0,i.length+1)===i+"-"))}},CHILD:function(t,e,n,i,o){var a="nth"!==t.slice(0,3),s="last"!==t.slice(-4),r="of-type"===e;return 1===i&&0===o?function(t){return!!t.parentNode}:function(e,n,c){var l,u,h,d,p,f,m=a!==s?"nextSibling":"previousSibling",g=e.parentNode,b=r&&e.nodeName.toLowerCase(),v=!c&&!r;if(g){if(a){for(;m;){for(h=e;h=h[m];)if(r?h.nodeName.toLowerCase()===b:1===h.nodeType)return!1;f=m="only"===t&&!f&&"nextSibling"}return!0}if(f=[s?g.firstChild:g.lastChild],s&&v){for(u=g[P]||(g[P]={}),l=u[t]||[],p=l[0]===R&&l[1],d=l[0]===R&&l[2],h=p&&g.childNodes[p];h=++p&&h&&h[m]||(d=p=0)||f.pop();)if(1===h.nodeType&&++d&&h===e){u[t]=[R,p,d];break}}else if(v&&(l=(e[P]||(e[P]={}))[t])&&l[0]===R)d=l[1];else for(;(h=++p&&h&&h[m]||(d=p=0)||f.pop())&&((r?h.nodeName.toLowerCase()!==b:1!==h.nodeType)||!++d||(v&&((h[P]||(h[P]={}))[t]=[R,d]),h!==e)););return d-=o,d===i||d%i===0&&d/i>=0}}},PSEUDO:function(t,n){var o,a=_.pseudos[t]||_.setFilters[t.toLowerCase()]||e.error("unsupported pseudo: "+t);return a[P]?a(n):a.length>1?(o=[t,t,"",n],_.setFilters.hasOwnProperty(t.toLowerCase())?i(function(t,e){for(var i,o=a(t,n),s=o.length;s--;)i=tt(t,o[s]),t[i]=!(e[i]=o[s])}):function(t){return a(t,0,o)}):a}},pseudos:{not:i(function(t){var e=[],n=[],o=C(t.replace(ct,"$1"));return o[P]?i(function(t,e,n,i){for(var a,s=o(t,null,i,[]),r=t.length;r--;)(a=s[r])&&(t[r]=!(e[r]=a))}):function(t,i,a){return e[0]=t,o(e,null,a,n),e[0]=null,!n.pop()}}),has:i(function(t){return function(n){return e(t,n).length>0}}),contains:i(function(t){return t=t.replace(At,_t),function(e){return(e.textContent||e.innerText||z(e)).indexOf(t)>-1}}),lang:i(function(t){return pt.test(t||"")||e.error("unsupported lang: "+t),t=t.replace(At,_t).toLowerCase(),function(e){var n;do if(n=q?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return n=n.toLowerCase(),n===t||0===n.indexOf(t+"-");while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var n=t.location&&t.location.hash;return n&&n.slice(1)===e.id},root:function(t){return t===k},focus:function(t){return t===D.activeElement&&(!D.hasFocus||D.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:function(t){return t.disabled===!1},disabled:function(t){return t.disabled===!0},checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,t.selected===!0},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!_.pseudos.empty(t)},header:function(t){return gt.test(t.nodeName)},input:function(t){return mt.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:l(function(){return[0]}),last:l(function(t,e){return[e-1]}),eq:l(function(t,e,n){return[n<0?n+e:n]}),even:l(function(t,e){for(var n=0;n=0;)t.push(i);return t}),gt:l(function(t,e,n){for(var i=n<0?n+e:n;++i2&&"ID"===(s=a[0]).type&&A.getById&&9===e.nodeType&&q&&_.relative[a[1].type]){if(e=(_.find.ID(s.matches[0].replace(At,_t),e)||[])[0],!e)return n;l&&(e=e.parentNode),t=t.slice(a.shift().value.length)}for(o=ft.needsContext.test(t)?0:a.length;o--&&(s=a[o],!_.relative[r=s.type]);)if((c=_.find[r])&&(i=c(s.matches[0].replace(At,_t),Mt.test(a[0].type)&&u(e.parentNode)||e))){if(a.splice(o,1),t=i.length&&d(a),!t)return Q.apply(n,i),n;break}}return(l||C(t,h))(i,e,!q,n,Mt.test(t)&&u(e.parentNode)||e),n},A.sortStable=P.split("").sort($).join("")===P,A.detectDuplicates=!!x,L(),A.sortDetached=o(function(t){return 1&t.compareDocumentPosition(D.createElement("div"))}),o(function(t){return t.innerHTML="","#"===t.firstChild.getAttribute("href")})||a("type|href|height|width",function(t,e,n){if(!n)return t.getAttribute(e,"type"===e.toLowerCase()?1:2)}),A.attributes&&o(function(t){return t.innerHTML="",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")})||a("value",function(t,e,n){if(!n&&"input"===t.nodeName.toLowerCase())return t.defaultValue}),o(function(t){return null==t.getAttribute("disabled")})||a(et,function(t,e,n){var i;if(!n)return t[e]===!0?e.toLowerCase():(i=t.getAttributeNode(e))&&i.specified?i.value:null}),e}(t);ot.find=lt,ot.expr=lt.selectors,ot.expr[":"]=ot.expr.pseudos,ot.unique=lt.uniqueSort,ot.text=lt.getText,ot.isXMLDoc=lt.isXML,ot.contains=lt.contains;var ut=ot.expr.match.needsContext,ht=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,dt=/^.[^:#\[\.,]*$/;ot.filter=function(t,e,n){var i=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===i.nodeType?ot.find.matchesSelector(i,t)?[i]:[]:ot.find.matches(t,ot.grep(e,function(t){return 1===t.nodeType}))},ot.fn.extend({find:function(t){var e,n=[],i=this,o=i.length;if("string"!=typeof t)return this.pushStack(ot(t).filter(function(){for(e=0;e1?ot.unique(n):n),n.selector=this.selector?this.selector+" "+t:t,n},filter:function(t){return this.pushStack(i(this,t||[],!1))},not:function(t){return this.pushStack(i(this,t||[],!0))},is:function(t){return!!i(this,"string"==typeof t&&ut.test(t)?ot(t):t||[],!1).length}});var pt,ft=t.document,mt=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,gt=ot.fn.init=function(t,e){var n,i;if(!t)return this;if("string"==typeof t){if(n="<"===t.charAt(0)&&">"===t.charAt(t.length-1)&&t.length>=3?[null,t,null]:mt.exec(t),!n||!n[1]&&e)return!e||e.jquery?(e||pt).find(t):this.constructor(e).find(t);if(n[1]){if(e=e instanceof ot?e[0]:e,ot.merge(this,ot.parseHTML(n[1],e&&e.nodeType?e.ownerDocument||e:ft,!0)),ht.test(n[1])&&ot.isPlainObject(e))for(n in e)ot.isFunction(this[n])?this[n](e[n]):this.attr(n,e[n]);return this}if(i=ft.getElementById(n[2]),i&&i.parentNode){if(i.id!==n[2])return pt.find(t);this.length=1,this[0]=i}return this.context=ft,this.selector=t,this}return t.nodeType?(this.context=this[0]=t,this.length=1,this):ot.isFunction(t)?"undefined"!=typeof pt.ready?pt.ready(t):t(ot):(void 0!==t.selector&&(this.selector=t.selector,this.context=t.context),ot.makeArray(t,this))};gt.prototype=ot.fn,pt=ot(ft);var bt=/^(?:parents|prev(?:Until|All))/,vt={children:!0,contents:!0,next:!0,prev:!0};ot.extend({dir:function(t,e,n){for(var i=[],o=t[e];o&&9!==o.nodeType&&(void 0===n||1!==o.nodeType||!ot(o).is(n));)1===o.nodeType&&i.push(o),o=o[e];return i},sibling:function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n}}),ot.fn.extend({has:function(t){var e,n=ot(t,this),i=n.length;return this.filter(function(){for(e=0;e-1:1===n.nodeType&&ot.find.matchesSelector(n,t))){a.push(n);break}return this.pushStack(a.length>1?ot.unique(a):a)},index:function(t){return t?"string"==typeof t?ot.inArray(this[0],ot(t)):ot.inArray(t.jquery?t[0]:t,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(ot.unique(ot.merge(this.get(),ot(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),ot.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return ot.dir(t,"parentNode")},parentsUntil:function(t,e,n){return ot.dir(t,"parentNode",n)},next:function(t){return o(t,"nextSibling")},prev:function(t){return o(t,"previousSibling")},nextAll:function(t){return ot.dir(t,"nextSibling")},prevAll:function(t){return ot.dir(t,"previousSibling")},nextUntil:function(t,e,n){return ot.dir(t,"nextSibling",n)},prevUntil:function(t,e,n){return ot.dir(t,"previousSibling",n)},siblings:function(t){return ot.sibling((t.parentNode||{}).firstChild,t)},children:function(t){return ot.sibling(t.firstChild)},contents:function(t){return ot.nodeName(t,"iframe")?t.contentDocument||t.contentWindow.document:ot.merge([],t.childNodes)}},function(t,e){ot.fn[t]=function(n,i){var o=ot.map(this,e,n);return"Until"!==t.slice(-5)&&(i=n),i&&"string"==typeof i&&(o=ot.filter(i,o)),this.length>1&&(vt[t]||(o=ot.unique(o)),bt.test(t)&&(o=o.reverse())),this.pushStack(o)}});var Mt=/\S+/g,yt={};ot.Callbacks=function(t){t="string"==typeof t?yt[t]||a(t):ot.extend({},t);var e,n,i,o,s,r,c=[],l=!t.once&&[],u=function(a){for(n=t.memory&&a,i=!0,s=r||0,r=0,o=c.length,e=!0;c&&s-1;)c.splice(i,1),e&&(i<=o&&o--,i<=s&&s--)}),this},has:function(t){return t?ot.inArray(t,c)>-1:!(!c||!c.length)},empty:function(){return c=[],o=0,this},disable:function(){return c=l=n=void 0,this},disabled:function(){return!c},lock:function(){return l=void 0,n||h.disable(),this},locked:function(){return!l},fireWith:function(t,n){return!c||i&&!l||(n=n||[],n=[t,n.slice?n.slice():n],e?l.push(n):u(n)),this},fire:function(){return h.fireWith(this,arguments),this},fired:function(){return!!i}};return h},ot.extend({Deferred:function(t){var e=[["resolve","done",ot.Callbacks("once memory"),"resolved"],["reject","fail",ot.Callbacks("once memory"),"rejected"],["notify","progress",ot.Callbacks("memory")]],n="pending",i={state:function(){return n},always:function(){return o.done(arguments).fail(arguments),this},then:function(){var t=arguments;return ot.Deferred(function(n){ot.each(e,function(e,a){var s=ot.isFunction(t[e])&&t[e];o[a[1]](function(){var t=s&&s.apply(this,arguments);t&&ot.isFunction(t.promise)?t.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a[0]+"With"](this===i?n.promise():this,s?[t]:arguments)})}),t=null}).promise()},promise:function(t){return null!=t?ot.extend(t,i):i}},o={};return i.pipe=i.then,ot.each(e,function(t,a){var s=a[2],r=a[3];i[a[1]]=s.add,r&&s.add(function(){n=r},e[1^t][2].disable,e[2][2].lock),o[a[0]]=function(){return o[a[0]+"With"](this===o?i:this,arguments),this},o[a[0]+"With"]=s.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(t){var e,n,i,o=0,a=J.call(arguments),s=a.length,r=1!==s||t&&ot.isFunction(t.promise)?s:0,c=1===r?t:ot.Deferred(),l=function(t,n,i){return function(o){n[t]=this,i[t]=arguments.length>1?J.call(arguments):o,i===e?c.notifyWith(n,i):--r||c.resolveWith(n,i)}};if(s>1)for(e=new Array(s),n=new Array(s),i=new Array(s);o0||(At.resolveWith(ft,[ot]),ot.fn.triggerHandler&&(ot(ft).triggerHandler("ready"),ot(ft).off("ready")))}}}),ot.ready.promise=function(e){if(!At)if(At=ot.Deferred(),"complete"===ft.readyState)setTimeout(ot.ready);else if(ft.addEventListener)ft.addEventListener("DOMContentLoaded",r,!1),t.addEventListener("load",r,!1);else{ft.attachEvent("onreadystatechange",r),t.attachEvent("onload",r);var n=!1;try{n=null==t.frameElement&&ft.documentElement}catch(i){}n&&n.doScroll&&!function o(){if(!ot.isReady){try{n.doScroll("left")}catch(t){return setTimeout(o,50)}s(),ot.ready()}}()}return At.promise(e)};var _t,zt="undefined";for(_t in ot(nt))break;nt.ownLast="0"!==_t,nt.inlineBlockNeedsLayout=!1,ot(function(){var t,e,n,i;n=ft.getElementsByTagName("body")[0],n&&n.style&&(e=ft.createElement("div"),i=ft.createElement("div"),i.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(i).appendChild(e),typeof e.style.zoom!==zt&&(e.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",nt.inlineBlockNeedsLayout=t=3===e.offsetWidth,t&&(n.style.zoom=1)),n.removeChild(i))}),function(){var t=ft.createElement("div");if(null==nt.deleteExpando){nt.deleteExpando=!0;try{delete t.test}catch(e){nt.deleteExpando=!1}}t=null}(),ot.acceptData=function(t){var e=ot.noData[(t.nodeName+" ").toLowerCase()],n=+t.nodeType||1;return(1===n||9===n)&&(!e||e!==!0&&t.getAttribute("classid")===e)};var Tt=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,wt=/([A-Z])/g;ot.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(t){return t=t.nodeType?ot.cache[t[ot.expando]]:t[ot.expando],!!t&&!l(t)},data:function(t,e,n){return u(t,e,n)},removeData:function(t,e){return h(t,e)},_data:function(t,e,n){return u(t,e,n,!0)},_removeData:function(t,e){return h(t,e,!0)}}),ot.fn.extend({data:function(t,e){var n,i,o,a=this[0],s=a&&a.attributes;if(void 0===t){if(this.length&&(o=ot.data(a),1===a.nodeType&&!ot._data(a,"parsedAttrs"))){for(n=s.length;n--;)s[n]&&(i=s[n].name,0===i.indexOf("data-")&&(i=ot.camelCase(i.slice(5)),c(a,i,o[i])));ot._data(a,"parsedAttrs",!0)}return o}return"object"==typeof t?this.each(function(){ot.data(this,t)}):arguments.length>1?this.each(function(){ot.data(this,t,e)}):a?c(a,t,ot.data(a,t)):void 0},removeData:function(t){return this.each(function(){ot.removeData(this,t)})}}),ot.extend({queue:function(t,e,n){var i;if(t)return e=(e||"fx")+"queue",i=ot._data(t,e),n&&(!i||ot.isArray(n)?i=ot._data(t,e,ot.makeArray(n)):i.push(n)),i||[]},dequeue:function(t,e){e=e||"fx";var n=ot.queue(t,e),i=n.length,o=n.shift(),a=ot._queueHooks(t,e),s=function(){ot.dequeue(t,e)};"inprogress"===o&&(o=n.shift(),i--),o&&("fx"===e&&n.unshift("inprogress"),delete a.stop,o.call(t,s,a)),!i&&a&&a.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return ot._data(t,n)||ot._data(t,n,{empty:ot.Callbacks("once memory").add(function(){ot._removeData(t,e+"queue"),ot._removeData(t,n)})})}}),ot.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length
OKCancel×',p=document.getElementsByClassName(l.container);p.length?s=p[0]:(s=document.createElement("div"),s.className=l.container,s.innerHTML=d);var f,m=function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},g=function(t,e){t=String(t).replace(/[^0-9a-f]/gi,""),t.length<6&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]),e=e||0;for(var n="#",i=0;i<3;i++){var o=parseInt(t.substr(2*i,2),16);o=Math.round(Math.min(Math.max(0,o+o*e),255)).toString(16),n+=("00"+o).substr(o.length)}return n},b={previousWindowKeyDown:null,previousActiveElement:null,previousBodyPadding:null},v=function(){if("undefined"!=typeof document&&!document.getElementsByClassName(l.container).length){document.body.appendChild(s);var t=y(),e=k(t,l.input),n=k(t,l.file),i=t.querySelector("."+l.range+" input"),o=k(t,l.select),r=t.querySelector("."+l.checkbox+" input"),c=k(t,l.textarea);return e.oninput=function(){a.resetValidationError()},e.onkeydown=function(t){setTimeout(function(){13===t.keyCode&&(t.stopPropagation(),a.clickConfirm())},0)},n.onchange=function(){a.resetValidationError()},i.oninput=function(){a.resetValidationError(),i.previousSibling.value=i.value},i.onchange=function(){a.resetValidationError(),i.previousSibling.value=i.value},o.onchange=function(){a.resetValidationError()},r.onchange=function(){a.resetValidationError()},c.oninput=function(){a.resetValidationError()},t}},M=function(t){return s.querySelector("."+t)},y=function(){return document.body.querySelector("."+l.modal)||v()},A=function(){var t=y();return t.querySelectorAll("."+l.icon)},_=function(){return M(l.spacer)},z=function(){return M(l.progresssteps)},T=function(){return M(l.validationerror)},w=function(){return M(l.confirm)},C=function(){return M(l.cancel)},O=function(){return M(l.close)},N=function(t){var e=[w(),C()];return t&&e.reverse(),e.concat(Array.prototype.slice.call(y().querySelectorAll("button:not([class^="+r+"]), input:not([type=hidden]), textarea, select")))},S=function(t,e){return t.classList.contains(e)},x=function(t){if(t.focus(),"file"!==t.type){var e=t.value;t.value="",t.value=e}},L=function(t,e){if(t&&e){var n=e.split(/\s+/);n.forEach(function(e){t.classList.add(e)})}},D=function(t,e){if(t&&e){var n=e.split(/\s+/);n.forEach(function(e){t.classList.remove(e)})}},k=function(t,e){for(var n=0;n");var d;if(t.text||t.html){if("object"==typeof t.html)if(o.innerHTML="",0 in t.html)for(d=0;d in t.html;d++)o.appendChild(t.html[d].cloneNode(!0));else o.appendChild(t.html.cloneNode(!0));else o.innerHTML=t.html||t.text.split("\n").join(" ");q(o)}else W(o);t.showCloseButton?q(c):W(c),e.className=l.modal,t.customClass&&L(e,t.customClass);var p=z(),f=parseInt(null===t.currentProgressStep?a.getQueueStep():t.currentProgressStep,10);t.progressSteps.length?(q(p),E(p),f>=t.progressSteps.length,t.progressSteps.forEach(function(e,n){var i=document.createElement("li");if(L(i,l.progresscircle),i.innerHTML=e,n===f&&L(i,l.activeprogressstep),p.appendChild(i),n!==t.progressSteps.length-1){var o=document.createElement("li");L(o,l.progressline),o.style.width=t.progressStepsDistance,p.appendChild(o)}})):W(p);var m=A();for(d=0;d1?e[1].length:0}function c(t,e){t.classList?t.classList.add(e):t.className+=" "+e}function l(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," ")}function u(t,e){return t.classList?t.classList.contains(e):new RegExp("\\b"+e+"\\b").test(t.className)}function h(){var t=void 0!==window.pageXOffset,e="CSS1Compat"===(document.compatMode||""),n=t?window.pageXOffset:e?document.documentElement.scrollLeft:document.body.scrollLeft,i=t?window.pageYOffset:e?document.documentElement.scrollTop:document.body.scrollTop;return{x:n,y:i}}function d(){return window.navigator.pointerEnabled?{start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled?{start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}:{start:"mousedown touchstart",move:"mousemove touchmove",end:"mouseup touchend"}}function p(t,e){return 100/(e-t)}function f(t,e){return 100*e/(t[1]-t[0])}function m(t,e){return f(t,t[0]<0?e+Math.abs(t[0]):e-t[0])}function g(t,e){return e*(t[1]-t[0])/100+t[0]}function b(t,e){for(var n=1;t>=e[n];)n+=1;return n}function v(t,e,n){if(n>=t.slice(-1)[0])return 100;var i,o,a,s,r=b(n,t);return i=t[r-1],o=t[r],a=e[r-1],s=e[r],a+m([i,o],n)/p(a,s)}function M(t,e,n){if(n>=100)return t.slice(-1)[0];var i,o,a,s,r=b(n,e);return i=t[r-1],o=t[r],a=e[r-1],s=e[r],g([i,o],(n-a)*p(a,s))}function y(t,n,i,o){if(100===o)return o;var a,s,r=b(o,t);return i?(a=t[r-1],s=t[r],o-a>(s-a)/2?s:a):n[r-1]?t[r-1]+e(o-t[r-1],n[r-1]):o}function A(t,e,n){var o;if("number"==typeof e&&(e=[e]),"[object Array]"!==Object.prototype.toString.call(e))throw new Error("noUiSlider: 'range' contains invalid value.");if(o="min"===t?0:"max"===t?100:parseFloat(t),!i(o)||!i(e[0]))throw new Error("noUiSlider: 'range' value isn't numeric.");n.xPct.push(o),n.xVal.push(e[0]),o?n.xSteps.push(!isNaN(e[1])&&e[1]):isNaN(e[1])||(n.xSteps[0]=e[1])}function _(t,e,n){return!e||void(n.xSteps[t]=f([n.xVal[t],n.xVal[t+1]],e)/p(n.xPct[t],n.xPct[t+1]))}function z(t,e,n,i){this.xPct=[],this.xVal=[],this.xSteps=[i||!1],this.xNumSteps=[!1],this.snap=e,this.direction=n;var o,a=[];for(o in t)t.hasOwnProperty(o)&&a.push([t[o],o]);for(a.length&&"object"==typeof a[0][0]?a.sort(function(t,e){return t[0][0]-e[0][0]}):a.sort(function(t,e){return t[0]-e[0]}),o=0;o2)throw new Error("noUiSlider: 'start' option is incorrect.");t.handles=e.length,t.start=e}function O(t,e){if(t.snap=e,"boolean"!=typeof e)throw new Error("noUiSlider: 'snap' option must be a boolean.")}function N(t,e){if(t.animate=e,"boolean"!=typeof e)throw new Error("noUiSlider: 'animate' option must be a boolean.")}function S(t,e){if(t.animationDuration=e,"number"!=typeof e)throw new Error("noUiSlider: 'animationDuration' option must be a number.")}function x(t,e){if("lower"===e&&1===t.handles)t.connect=1;else if("upper"===e&&1===t.handles)t.connect=2;else if(e===!0&&2===t.handles)t.connect=3;else{if(e!==!1)throw new Error("noUiSlider: 'connect' option doesn't match handle count.");t.connect=0}}function L(t,e){switch(e){case"horizontal":t.ort=0;break;case"vertical":t.ort=1;break;default:throw new Error("noUiSlider: 'orientation' option is invalid.")}}function D(t,e){if(!i(e))throw new Error("noUiSlider: 'margin' option must be numeric.");if(0!==e&&(t.margin=t.spectrum.getMargin(e),!t.margin))throw new Error("noUiSlider: 'margin' option is only supported on linear sliders.")}function k(t,e){if(!i(e))throw new Error("noUiSlider: 'limit' option must be numeric.");if(t.limit=t.spectrum.getMargin(e),!t.limit)throw new Error("noUiSlider: 'limit' option is only supported on linear sliders.")}function q(t,e){switch(e){case"ltr":t.dir=0;break;case"rtl":t.dir=1,t.connect=[0,2,1,3][t.connect];break;default:throw new Error("noUiSlider: 'direction' option was not recognized.")}}function W(t,e){if("string"!=typeof e)throw new Error("noUiSlider: 'behaviour' must be a string containing options.");var n=e.indexOf("tap")>=0,i=e.indexOf("drag")>=0,o=e.indexOf("fixed")>=0,a=e.indexOf("snap")>=0,s=e.indexOf("hover")>=0;if(i&&!t.connect)throw new Error("noUiSlider: 'drag' behaviour must be used with 'connect': true.");t.events={tap:n||a,drag:i,fixed:o,snap:a,hover:s}}function E(t,e){var n;if(e!==!1)if(e===!0)for(t.tooltips=[],n=0;n100&&(i-=o-100),[a(i),a(o)]):[i,o]}function m(t,e){t.preventDefault();var n,i,o=0===t.type.indexOf("touch"),a=0===t.type.indexOf("mouse"),s=0===t.type.indexOf("pointer"),r=t;return 0===t.type.indexOf("MSPointer")&&(s=!0),o&&(n=t.changedTouches[0].pageX,i=t.changedTouches[0].pageY),e=e||h(),(a||s)&&(n=t.clientX+e.x,i=t.clientY+e.y),r.pageOffset=e,r.points=[n,i],r.cursor=a||s,r}function g(t,e){var n=document.createElement("div"),o=document.createElement("div"),a=[i.cssClasses.handleLower,i.cssClasses.handleUpper];return t&&a.reverse(),c(o,i.cssClasses.handle),c(o,a[e]),c(n,i.cssClasses.origin),n.appendChild(o),n}function b(t,e,n){switch(t){case 1:c(e,i.cssClasses.connect),c(n[0],i.cssClasses.background);break;case 3:c(n[1],i.cssClasses.background);case 2:c(n[0],i.cssClasses.connect);case 0:c(e,i.cssClasses.background)}}function v(t,e,n){var i,o=[];for(i=0;i-1?1:"steps"===n?2:0,!a&&l&&(g=0),c===A&&u||(s[p.toFixed(5)]=[c,g]),h=p}}),Z.direction=a,s}function T(t,e,n){function o(t,e){var n=e===i.cssClasses.value,o=n?d:p,a=n?u:h;return e+" "+o[i.ort]+" "+a[t]}function a(t,e,n){return'class="'+o(n[1],e)+'" style="'+i.style+": "+t+'%"'}function s(t,o){Z.direction&&(t=100-t),o[1]=o[1]&&e?e(o[0],o[1]):o[1],l+="",o[1]&&(l+="
OKCancel×',p=document.getElementsByClassName(l.container);p.length?s=p[0]:(s=document.createElement("div"),s.className=l.container,s.innerHTML=d);var f,m=function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},g=function(t,e){t=String(t).replace(/[^0-9a-f]/gi,""),t.length<6&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]),e=e||0;for(var n="#",i=0;i<3;i++){var o=parseInt(t.substr(2*i,2),16);o=Math.round(Math.min(Math.max(0,o+o*e),255)).toString(16),n+=("00"+o).substr(o.length)}return n},b={previousWindowKeyDown:null,previousActiveElement:null,previousBodyPadding:null},v=function(){if("undefined"!=typeof document&&!document.getElementsByClassName(l.container).length){document.body.appendChild(s);var t=y(),e=k(t,l.input),n=k(t,l.file),i=t.querySelector("."+l.range+" input"),o=k(t,l.select),r=t.querySelector("."+l.checkbox+" input"),c=k(t,l.textarea);return e.oninput=function(){a.resetValidationError()},e.onkeydown=function(t){setTimeout(function(){13===t.keyCode&&(t.stopPropagation(),a.clickConfirm())},0)},n.onchange=function(){a.resetValidationError()},i.oninput=function(){a.resetValidationError(),i.previousSibling.value=i.value},i.onchange=function(){a.resetValidationError(),i.previousSibling.value=i.value},o.onchange=function(){a.resetValidationError()},r.onchange=function(){a.resetValidationError()},c.oninput=function(){a.resetValidationError()},t}},M=function(t){return s.querySelector("."+t)},y=function(){return document.body.querySelector("."+l.modal)||v()},A=function(){var t=y();return t.querySelectorAll("."+l.icon)},_=function(){return M(l.spacer)},z=function(){return M(l.progresssteps)},T=function(){return M(l.validationerror)},w=function(){return M(l.confirm)},C=function(){return M(l.cancel)},O=function(){return M(l.close)},N=function(t){var e=[w(),C()];return t&&e.reverse(),e.concat(Array.prototype.slice.call(y().querySelectorAll("button:not([class^="+r+"]), input:not([type=hidden]), textarea, select")))},S=function(t,e){return t.classList.contains(e)},x=function(t){if(t.focus(),"file"!==t.type){var e=t.value;t.value="",t.value=e}},L=function(t,e){if(t&&e){var n=e.split(/\s+/);n.forEach(function(e){t.classList.add(e)})}},D=function(t,e){if(t&&e){var n=e.split(/\s+/);n.forEach(function(e){t.classList.remove(e)})}},k=function(t,e){for(var n=0;n");var d;if(t.text||t.html){if("object"==typeof t.html)if(o.innerHTML="",0 in t.html)for(d=0;d in t.html;d++)o.appendChild(t.html[d].cloneNode(!0));else o.appendChild(t.html.cloneNode(!0));else o.innerHTML=t.html||t.text.split("\n").join(" ");q(o)}else W(o);t.showCloseButton?q(c):W(c),e.className=l.modal,t.customClass&&L(e,t.customClass);var p=z(),f=parseInt(null===t.currentProgressStep?a.getQueueStep():t.currentProgressStep,10);t.progressSteps.length?(q(p),E(p),f>=t.progressSteps.length,t.progressSteps.forEach(function(e,n){var i=document.createElement("li");if(L(i,l.progresscircle),i.innerHTML=e,n===f&&L(i,l.activeprogressstep),p.appendChild(i),n!==t.progressSteps.length-1){var o=document.createElement("li");L(o,l.progressline),o.style.width=t.progressStepsDistance,p.appendChild(o)}})):W(p);var m=A();for(d=0;d1?e[1].length:0}function c(t,e){t.classList?t.classList.add(e):t.className+=" "+e}function l(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," ")}function u(t,e){return t.classList?t.classList.contains(e):new RegExp("\\b"+e+"\\b").test(t.className)}function h(){var t=void 0!==window.pageXOffset,e="CSS1Compat"===(document.compatMode||""),n=t?window.pageXOffset:e?document.documentElement.scrollLeft:document.body.scrollLeft,i=t?window.pageYOffset:e?document.documentElement.scrollTop:document.body.scrollTop;return{x:n,y:i}}function d(){return window.navigator.pointerEnabled?{start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled?{start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}:{start:"mousedown touchstart",move:"mousemove touchmove",end:"mouseup touchend"}}function p(t,e){return 100/(e-t)}function f(t,e){return 100*e/(t[1]-t[0])}function m(t,e){return f(t,t[0]<0?e+Math.abs(t[0]):e-t[0])}function g(t,e){return e*(t[1]-t[0])/100+t[0]}function b(t,e){for(var n=1;t>=e[n];)n+=1;return n}function v(t,e,n){if(n>=t.slice(-1)[0])return 100;var i,o,a,s,r=b(n,t);return i=t[r-1],o=t[r],a=e[r-1],s=e[r],a+m([i,o],n)/p(a,s)}function M(t,e,n){if(n>=100)return t.slice(-1)[0];var i,o,a,s,r=b(n,e);return i=t[r-1],o=t[r],a=e[r-1],s=e[r],g([i,o],(n-a)*p(a,s))}function y(t,n,i,o){if(100===o)return o;var a,s,r=b(o,t);return i?(a=t[r-1],s=t[r],o-a>(s-a)/2?s:a):n[r-1]?t[r-1]+e(o-t[r-1],n[r-1]):o}function A(t,e,n){var o;if("number"==typeof e&&(e=[e]),"[object Array]"!==Object.prototype.toString.call(e))throw new Error("noUiSlider: 'range' contains invalid value.");if(o="min"===t?0:"max"===t?100:parseFloat(t),!i(o)||!i(e[0]))throw new Error("noUiSlider: 'range' value isn't numeric.");n.xPct.push(o),n.xVal.push(e[0]),o?n.xSteps.push(!isNaN(e[1])&&e[1]):isNaN(e[1])||(n.xSteps[0]=e[1])}function _(t,e,n){return!e||void(n.xSteps[t]=f([n.xVal[t],n.xVal[t+1]],e)/p(n.xPct[t],n.xPct[t+1]))}function z(t,e,n,i){this.xPct=[],this.xVal=[],this.xSteps=[i||!1],this.xNumSteps=[!1],this.snap=e,this.direction=n;var o,a=[];for(o in t)t.hasOwnProperty(o)&&a.push([t[o],o]);for(a.length&&"object"==typeof a[0][0]?a.sort(function(t,e){return t[0][0]-e[0][0]}):a.sort(function(t,e){return t[0]-e[0]}),o=0;o2)throw new Error("noUiSlider: 'start' option is incorrect.");t.handles=e.length,t.start=e}function O(t,e){if(t.snap=e,"boolean"!=typeof e)throw new Error("noUiSlider: 'snap' option must be a boolean.")}function N(t,e){if(t.animate=e,"boolean"!=typeof e)throw new Error("noUiSlider: 'animate' option must be a boolean.")}function S(t,e){if(t.animationDuration=e,"number"!=typeof e)throw new Error("noUiSlider: 'animationDuration' option must be a number.")}function x(t,e){if("lower"===e&&1===t.handles)t.connect=1;else if("upper"===e&&1===t.handles)t.connect=2;else if(e===!0&&2===t.handles)t.connect=3;else{if(e!==!1)throw new Error("noUiSlider: 'connect' option doesn't match handle count.");t.connect=0}}function L(t,e){switch(e){case"horizontal":t.ort=0;break;case"vertical":t.ort=1;break;default:throw new Error("noUiSlider: 'orientation' option is invalid.")}}function D(t,e){if(!i(e))throw new Error("noUiSlider: 'margin' option must be numeric.");if(0!==e&&(t.margin=t.spectrum.getMargin(e),!t.margin))throw new Error("noUiSlider: 'margin' option is only supported on linear sliders.")}function k(t,e){if(!i(e))throw new Error("noUiSlider: 'limit' option must be numeric.");if(t.limit=t.spectrum.getMargin(e),!t.limit)throw new Error("noUiSlider: 'limit' option is only supported on linear sliders.")}function q(t,e){switch(e){case"ltr":t.dir=0;break;case"rtl":t.dir=1,t.connect=[0,2,1,3][t.connect];break;default:throw new Error("noUiSlider: 'direction' option was not recognized.")}}function W(t,e){if("string"!=typeof e)throw new Error("noUiSlider: 'behaviour' must be a string containing options.");var n=e.indexOf("tap")>=0,i=e.indexOf("drag")>=0,o=e.indexOf("fixed")>=0,a=e.indexOf("snap")>=0,s=e.indexOf("hover")>=0;if(i&&!t.connect)throw new Error("noUiSlider: 'drag' behaviour must be used with 'connect': true.");t.events={tap:n||a,drag:i,fixed:o,snap:a,hover:s}}function E(t,e){var n;if(e!==!1)if(e===!0)for(t.tooltips=[],n=0;n100&&(i-=o-100),[a(i),a(o)]):[i,o]}function m(t,e){t.preventDefault();var n,i,o=0===t.type.indexOf("touch"),a=0===t.type.indexOf("mouse"),s=0===t.type.indexOf("pointer"),r=t;return 0===t.type.indexOf("MSPointer")&&(s=!0),o&&(n=t.changedTouches[0].pageX,i=t.changedTouches[0].pageY),e=e||h(),(a||s)&&(n=t.clientX+e.x,i=t.clientY+e.y),r.pageOffset=e,r.points=[n,i],r.cursor=a||s,r}function g(t,e){var n=document.createElement("div"),o=document.createElement("div"),a=[i.cssClasses.handleLower,i.cssClasses.handleUpper];return t&&a.reverse(),c(o,i.cssClasses.handle),c(o,a[e]),c(n,i.cssClasses.origin),n.appendChild(o),n}function b(t,e,n){switch(t){case 1:c(e,i.cssClasses.connect),c(n[0],i.cssClasses.background);break;case 3:c(n[1],i.cssClasses.background);case 2:c(n[0],i.cssClasses.connect);case 0:c(e,i.cssClasses.background)}}function v(t,e,n){var i,o=[];for(i=0;i-1?1:"steps"===n?2:0,!a&&l&&(g=0),c===A&&u||(s[p.toFixed(5)]=[c,g]),h=p}}),Z.direction=a,s}function T(t,e,n){function o(t,e){var n=e===i.cssClasses.value,o=n?d:p,a=n?u:h;return e+" "+o[i.ort]+" "+a[t]}function a(t,e,n){return'class="'+o(n[1],e)+'" style="'+i.style+": "+t+'%"'}function s(t,o){Z.direction&&(t=100-t),o[1]=o[1]&&e?e(o[0],o[1]):o[1],l+="",o[1]&&(l+="
'\n );\n var els = $('a', nPaging);\n $(els[0]).bind( 'click.DT', { action: \"previous\" }, fnClickHandler );\n $(els[1]).bind( 'click.DT', { action: \"next\" }, fnClickHandler );\n },\n\n \"fnUpdate\": function ( oSettings, fnDraw ) {\n var iListLength = 5;\n var oPaging = oSettings.oInstance.fnPagingInfo();\n var an = oSettings.aanFeatures.p;\n var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);\n\n if ( oPaging.iTotalPages < iListLength) {\n iStart = 1;\n iEnd = oPaging.iTotalPages;\n }\n else if ( oPaging.iPage <= iHalf ) {\n iStart = 1;\n iEnd = iListLength;\n } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {\n iStart = oPaging.iTotalPages - iListLength + 1;\n iEnd = oPaging.iTotalPages;\n } else {\n iStart = oPaging.iPage - iHalf + 1;\n iEnd = iStart + iListLength - 1;\n }\n\n for ( i=0, ien=an.length ; i'+j+'')\n .insertBefore( $('li:last', an[i])[0] )\n .bind('click', function (e) {\n e.preventDefault();\n oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;\n fnDraw( oSettings );\n } );\n }\n\n // Add / remove disabled classes from the static elements\n if ( oPaging.iPage === 0 ) {\n $('li:first', an[i]).addClass('disabled');\n } else {\n $('li:first', an[i]).removeClass('disabled');\n }\n\n if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {\n $('li:last', an[i]).addClass('disabled');\n } else {\n $('li:last', an[i]).removeClass('disabled');\n }\n }\n }\n }\n } );\n}\n\n/*\n * TableTools Bootstrap compatibility\n * Required TableTools 2.1+\n */\nif ( $.fn.DataTable.TableTools ) {\n // Set the classes that TableTools uses to something suitable for Bootstrap\n $.extend( true, $.fn.DataTable.TableTools.classes, {\n \"container\": \"DTTT btn-group\",\n \"buttons\": {\n \"normal\": \"btn\",\n \"disabled\": \"disabled\"\n },\n \"collection\": {\n \"container\": \"DTTT_dropdown dropdown-menu\",\n \"buttons\": {\n \"normal\": \"\",\n \"disabled\": \"disabled\"\n }\n },\n \"print\": {\n \"info\": \"DTTT_print_info modal\"\n },\n \"select\": {\n \"row\": \"active\"\n }\n } );\n\n // Have the collection use a bootstrap compatible dropdown\n $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {\n \"collection\": {\n \"container\": \"ul\",\n \"button\": \"li\",\n \"liner\": \"a\"\n }\n } );\n}\n\n\nfunction isStorageSupported() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n}\n\nfunction isValidEmailAddress(emailAddress) {\n var pattern = new RegExp(/^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$/i);\n return pattern.test(emailAddress);\n};\n\nfunction enableHoverClick($combobox, $entityId, url) {\n /*\n $combobox.mouseleave(function() {\n $combobox.css('text-decoration','none');\n }).on('mouseenter', function(e) {\n setAsLink($combobox, $combobox.closest('.combobox-container').hasClass('combobox-selected'));\n }).on('focusout mouseleave', function(e) {\n setAsLink($combobox, false);\n }).on('click', function() {\n var clientId = $entityId.val();\n if ($(combobox).closest('.combobox-container').hasClass('combobox-selected')) {\n if (parseInt(clientId) > 0) {\n window.open(url + '/' + clientId, '_blank');\n } else {\n $('#myModal').modal('show');\n }\n };\n });\n */\n}\n\nfunction setAsLink($input, enable) {\n if (enable) {\n $input.css('text-decoration','underline');\n $input.css('cursor','pointer');\n } else {\n $input.css('text-decoration','none');\n $input.css('cursor','text');\n }\n}\n\nfunction setComboboxValue($combobox, id, name) {\n $combobox.find('input').val(id);\n $combobox.find('input.form-control').val(name);\n if (id && name) {\n $combobox.find('select').combobox('setSelected');\n $combobox.find('.combobox-container').addClass('combobox-selected');\n } else {\n $combobox.find('.combobox-container').removeClass('combobox-selected');\n }\n}\n\n\nvar BASE64_MARKER = ';base64,';\nfunction convertDataURIToBinary(dataURI) {\n var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;\n var base64 = dataURI.substring(base64Index);\n return base64DecToArr(base64);\n}\n\nif (window.ko) {\n ko.bindingHandlers.dropdown = {\n init: function (element, valueAccessor, allBindingsAccessor) {\n var options = allBindingsAccessor().dropdownOptions|| {};\n var value = ko.utils.unwrapObservable(valueAccessor());\n var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;\n if (id) $(element).val(id);\n //console.log(\"combo-init: %s\", id);\n $(element).combobox(options);\n\n /*\n ko.utils.registerEventHandler(element, \"change\", function () {\n console.log(\"change: %s\", $(element).val());\n //var\n valueAccessor($(element).val());\n //$(element).combobox('refresh');\n });\n */\n },\n update: function (element, valueAccessor) {\n var value = ko.utils.unwrapObservable(valueAccessor());\n var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;\n //console.log(\"combo-update: %s\", id);\n if (id) {\n $(element).val(id);\n $(element).combobox('refresh');\n } else {\n $(element).combobox('clearTarget');\n $(element).combobox('clearElement');\n }\n }\n };\n\n ko.bindingHandlers.combobox = {\n init: function (element, valueAccessor, allBindingsAccessor) {\n var options = allBindingsAccessor().dropdownOptions|| {};\n var value = ko.utils.unwrapObservable(valueAccessor());\n var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;\n if (id) $(element).val(id);\n $(element).combobox(options);\n\n ko.utils.registerEventHandler(element, \"change\", function () {\n var value = valueAccessor();\n value($(element).val());\n });\n },\n update: function (element, valueAccessor) {\n var value = ko.utils.unwrapObservable(valueAccessor());\n var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;\n if (id) {\n $(element).val(id);\n $(element).combobox('refresh');\n } else {\n $(element).combobox('clearTarget');\n $(element).combobox('clearElement');\n }\n }\n };\n\n ko.bindingHandlers.datePicker = {\n init: function (element, valueAccessor, allBindingsAccessor) {\n var value = ko.utils.unwrapObservable(valueAccessor());\n if (value) $(element).datepicker('update', value);\n $(element).change(function() {\n var value = valueAccessor();\n value($(element).val());\n })\n },\n update: function (element, valueAccessor) {\n var value = ko.utils.unwrapObservable(valueAccessor());\n if (value) $(element).datepicker('update', value);\n }\n };\n\n ko.bindingHandlers.placeholder = {\n init: function (element, valueAccessor, allBindingsAccessor) {\n var underlyingObservable = valueAccessor();\n ko.applyBindingsToNode(element, { attr: { placeholder: underlyingObservable } } );\n }\n };\n\n ko.bindingHandlers.tooltip = {\n init: function(element, valueAccessor) {\n var local = ko.utils.unwrapObservable(valueAccessor()),\n options = {};\n\n ko.utils.extend(options, ko.bindingHandlers.tooltip.options);\n ko.utils.extend(options, local);\n\n $(element).tooltip(options);\n\n ko.utils.domNodeDisposal.addDisposeCallback(element, function() {\n $(element).tooltip(\"destroy\");\n });\n },\n options: {\n placement: \"bottom\",\n trigger: \"hover\"\n }\n };\n\n ko.bindingHandlers.typeahead = {\n init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {\n var $element = $(element);\n var allBindings = allBindingsAccessor();\n\n $element.typeahead({\n highlight: true,\n minLength: 0,\n },\n {\n name: 'data',\n display: allBindings.key,\n limit: 50,\n source: searchData(allBindings.items, allBindings.key)\n }).on('typeahead:change', function(element, datum, name) {\n var value = valueAccessor();\n value(datum);\n });\n },\n\n update: function (element, valueAccessor) {\n var value = ko.utils.unwrapObservable(valueAccessor());\n if (value) {\n $(element).typeahead('val', value);\n }\n }\n };\n}\n\nfunction comboboxHighlighter(item) {\n var query = this.query.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&');\n var result = item.replace(new RegExp(' ', 'g'), \"\\n\");\n result = stripHtmlTags(result);\n result = result.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {\n return match ? '' + match + '' : query;\n });\n return result.replace(new RegExp(\"\\n\", 'g'), ' ');\n}\n\n// https://stackoverflow.com/a/326076/497368\nfunction inIframe () {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n\nfunction comboboxMatcher(item) {\n return ~stripHtmlTags(item).toLowerCase().indexOf(this.query.toLowerCase());\n}\n\nfunction stripHtmlTags(text) {\n // http://stackoverflow.com/a/5002618/497368\n var div = document.createElement(\"div\");\n div.innerHTML = text;\n return div.textContent || div.innerText || '';\n}\n\nfunction getContactDisplayName(contact)\n{\n if (contact.first_name || contact.last_name) {\n return $.trim((contact.first_name || '') + ' ' + (contact.last_name || ''));\n } else {\n return contact.email;\n }\n}\n\nfunction getContactDisplayNameWithEmail(contact)\n{\n var str = '';\n\n if (contact.first_name || contact.last_name) {\n str += $.trim((contact.first_name || '') + ' ' + (contact.last_name || ''));\n }\n\n if (contact.email) {\n if (str) {\n str += ' - ';\n }\n\n str += contact.email;\n }\n\n return $.trim(str);\n}\n\nfunction getClientDisplayName(client)\n{\n var contact = client.contacts ? client.contacts[0] : false;\n if (client.name) {\n return client.name;\n } else if (contact) {\n return getContactDisplayName(contact);\n }\n return '';\n}\n\nfunction populateInvoiceComboboxes(clientId, invoiceId) {\n var clientMap = {};\n var invoiceMap = {};\n var invoicesForClientMap = {};\n var $clientSelect = $('select#client');\n\n for (var i=0; i 1) {\n concatStr += ', ';\n } else if (i < data.length -1) {\n concatStr += ' ';\n }\n }\n return data.length ? concatStr : \"\";\n}\n\nfunction calculateAmounts(invoice) {\n var total = 0;\n var hasTaxes = false;\n var taxes = {};\n invoice.has_product_key = false;\n\n // Bold designs currently breaks w/o the product column\n if (invoice.invoice_design_id == 2) {\n invoice.has_product_key = true;\n }\n\n var hasStandard = false;\n var hasTask = false;\n\n // sum line item\n for (var i=0; i 64 && nChr < 91 ?\n nChr - 65\n : nChr > 96 && nChr < 123 ?\n nChr - 71\n : nChr > 47 && nChr < 58 ?\n nChr + 4\n : nChr === 43 ?\n 62\n : nChr === 47 ?\n 63\n :\n 0;\n\n}\n\nfunction base64DecToArr (sBase64, nBlocksSize) {\n\n var\n sB64Enc = sBase64.replace(/[^A-Za-z0-9\\+\\/]/g, \"\"), nInLen = sB64Enc.length,\n nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);\n\n for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {\n nMod4 = nInIdx & 3;\n nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;\n if (nMod4 === 3 || nInLen - nInIdx === 1) {\n for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {\n taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;\n }\n nUint24 = 0;\n\n }\n }\n\n return taBytes;\n}\n\n/* Base64 string to array encoding */\n\nfunction uint6ToB64 (nUint6) {\n\n return nUint6 < 26 ?\n nUint6 + 65\n : nUint6 < 52 ?\n nUint6 + 71\n : nUint6 < 62 ?\n nUint6 - 4\n : nUint6 === 62 ?\n 43\n : nUint6 === 63 ?\n 47\n :\n 65;\n\n}\n\nfunction base64EncArr (aBytes) {\n\n var nMod3 = 2, sB64Enc = \"\";\n\n for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {\n nMod3 = nIdx % 3;\n if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += \"\\r\\n\"; }\n nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);\n if (nMod3 === 2 || aBytes.length - nIdx === 1) {\n sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));\n nUint24 = 0;\n }\n }\n\n return sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + (nMod3 === 2 ? '' : nMod3 === 1 ? '=' : '==');\n\n}\n\n/* UTF-8 array to DOMString and vice versa */\n\nfunction UTF8ArrToStr (aBytes) {\n\n var sView = \"\";\n\n for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) {\n nPart = aBytes[nIdx];\n sView += String.fromCharCode(\n nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */\n /* (nPart - 252 << 32) is not possible in ECMAScript! So...: */\n (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128\n : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */\n (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128\n : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */\n (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128\n : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */\n (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128\n : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */\n (nPart - 192 << 6) + aBytes[++nIdx] - 128\n : /* nPart < 127 ? */ /* one byte */\n nPart\n );\n }\n\n return sView;\n\n}\n\nfunction strToUTF8Arr (sDOMStr) {\n\n var aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0;\n\n /* mapping... */\n\n for (var nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) {\n nChr = sDOMStr.charCodeAt(nMapIdx);\n nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6;\n }\n\n aBytes = new Uint8Array(nArrLen);\n\n /* transcription... */\n\n for (var nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) {\n nChr = sDOMStr.charCodeAt(nChrIdx);\n if (nChr < 128) {\n /* one byte */\n aBytes[nIdx++] = nChr;\n } else if (nChr < 0x800) {\n /* two bytes */\n aBytes[nIdx++] = 192 + (nChr >>> 6);\n aBytes[nIdx++] = 128 + (nChr & 63);\n } else if (nChr < 0x10000) {\n /* three bytes */\n aBytes[nIdx++] = 224 + (nChr >>> 12);\n aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);\n aBytes[nIdx++] = 128 + (nChr & 63);\n } else if (nChr < 0x200000) {\n /* four bytes */\n aBytes[nIdx++] = 240 + (nChr >>> 18);\n aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);\n aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);\n aBytes[nIdx++] = 128 + (nChr & 63);\n } else if (nChr < 0x4000000) {\n /* five bytes */\n aBytes[nIdx++] = 248 + (nChr >>> 24);\n aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);\n aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);\n aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);\n aBytes[nIdx++] = 128 + (nChr & 63);\n } else /* if (nChr <= 0x7fffffff) */ {\n /* six bytes */\n aBytes[nIdx++] = 252 + /* (nChr >>> 32) is not possible in ECMAScript! So...: */ (nChr / 1073741824);\n aBytes[nIdx++] = 128 + (nChr >>> 24 & 63);\n aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);\n aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);\n aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);\n aBytes[nIdx++] = 128 + (nChr & 63);\n }\n }\n\n return aBytes;\n\n}\n\n\n\nfunction hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}\nfunction hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}\nfunction hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}\nfunction cutHex(h) {return (h.charAt(0)==\"#\") ? h.substring(1,7):h}\nfunction setDocHexColor(doc, hex) {\n var r = hexToR(hex);\n var g = hexToG(hex);\n var b = hexToB(hex);\n return doc.setTextColor(r, g, b);\n}\nfunction setDocHexFill(doc, hex) {\n var r = hexToR(hex);\n var g = hexToG(hex);\n var b = hexToB(hex);\n return doc.setFillColor(r, g, b);\n}\nfunction setDocHexDraw(doc, hex) {\n var r = hexToR(hex);\n var g = hexToG(hex);\n var b = hexToB(hex);\n return doc.setDrawColor(r, g, b);\n}\n\nfunction toggleDatePicker(field) {\n $('#'+field).datepicker('show');\n}\n\nfunction getPrecision(number) {\n if (roundToPrecision(number, 3) != number) {\n return 4;\n } else if (roundToPrecision(number, 2) != number) {\n return 3;\n } else {\n return 2;\n }\n}\n\nfunction roundSignificant(number) {\n var precision = getPrecision(number);\n var value = roundToPrecision(number, precision);\n return isNaN(value) ? 0 : value;\n}\n\nfunction roundToTwo(number, toString) {\n var val = roundToPrecision(number, 2);\n return toString ? val.toFixed(2) : (val || 0);\n}\n\nfunction roundToFour(number, toString) {\n var val = roundToPrecision(number, 4);\n return toString ? val.toFixed(4) : (val || 0);\n}\n\n// https://stackoverflow.com/a/18358056/497368\nfunction roundToPrecision(number, precision) {\n // prevent negative numbers from rounding to 0\n var isNegative = number < 0;\n if (isNegative) {\n number = number * -1;\n }\n number = +(Math.round(number + \"e+\"+ precision) + \"e-\" + precision);\n if (isNegative) {\n number = number * -1;\n }\n return number;\n}\n\nfunction truncate(str, length) {\n return (str && str.length > length) ? (str.substr(0, length-1) + '...') : str;\n}\n\n// http://stackoverflow.com/questions/280634/endswith-in-javascript\nfunction endsWith(str, suffix) {\n return str.indexOf(suffix, str.length - suffix.length) !== -1;\n}\n\n// http://codeaid.net/javascript/convert-seconds-to-hours-minutes-and-seconds-%28javascript%29\nfunction secondsToTime(secs)\n{\n secs = Math.round(secs);\n var hours = Math.floor(secs / (60 * 60));\n\n var divisor_for_minutes = secs % (60 * 60);\n var minutes = Math.floor(divisor_for_minutes / 60);\n\n var divisor_for_seconds = divisor_for_minutes % 60;\n var seconds = Math.ceil(divisor_for_seconds);\n\n var obj = {\n \"h\": hours,\n \"m\": minutes,\n \"s\": seconds\n };\n return obj;\n}\n\nfunction twoDigits(value) {\n if (value < 10) {\n return '0' + value;\n }\n return value;\n}\n\nfunction toSnakeCase(str) {\n if (!str) return '';\n return str.replace(/([A-Z])/g, function($1){return \"_\"+$1.toLowerCase();});\n}\n\n// https://coderwall.com/p/iprsng/convert-snake-case-to-camelcase\nfunction snakeToCamel(s){\n return s.replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); });\n}\n\nfunction getDescendantProp(obj, desc) {\n var arr = desc.split(\".\");\n while(arr.length && (obj = obj[arr.shift()]));\n return obj;\n}\n\nfunction doubleDollarSign(str) {\n if (!str) return '';\n if (!str.replace) return str;\n return str.replace(/\\$/g, '\\$\\$\\$');\n}\n\nfunction truncate(string, length){\n if (string.length > length) {\n return string.substring(0, length) + '...';\n } else {\n return string;\n }\n};\n\n// Show/hide the 'Select' option in the datalists\nfunction actionListHandler() {\n $('tbody tr .tr-action').closest('tr').mouseover(function() {\n $(this).closest('tr').find('.tr-action').show();\n $(this).closest('tr').find('.tr-status').hide();\n }).mouseout(function() {\n $dropdown = $(this).closest('tr').find('.tr-action');\n if (!$dropdown.hasClass('open')) {\n $dropdown.hide();\n $(this).closest('tr').find('.tr-status').show();\n }\n });\n}\n\nfunction loadImages(selector) {\n $(selector + ' img').each(function(index, item) {\n var src = $(item).attr('data-src');\n $(item).attr('src', src);\n $(item).attr('data-src', src);\n });\n}\n\n// http://stackoverflow.com/questions/4810841/how-can-i-pretty-print-json-using-javascript\nfunction prettyJson(json) {\n if (typeof json != 'string') {\n json = JSON.stringify(json, undefined, 2);\n }\n json = json.replace(/&/g, '&').replace(//g, '>');\n return json.replace(/(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g, function (match) {\n var cls = 'number';\n if (/^\"/.test(match)) {\n if (/:$/.test(match)) {\n cls = 'key';\n } else {\n cls = 'string';\n }\n } else if (/true|false/.test(match)) {\n cls = 'boolean';\n } else if (/null/.test(match)) {\n cls = 'null';\n }\n match = snakeToCamel(match);\n return '' + match + '';\n });\n}\n\nfunction searchData(data, key, fuzzy) {\n return function findMatches(q, cb) {\n var matches, substringRegex;\n if (fuzzy) {\n var options = {\n keys: [key],\n }\n var fuse = new Fuse(data, options);\n matches = fuse.search(q);\n } else {\n matches = [];\n substrRegex = new RegExp(escapeRegExp(q), 'i');\n $.each(data, function(i, obj) {\n if (substrRegex.test(obj[key])) {\n matches.push(obj);\n }\n });\n }\n cb(matches);\n }\n};\n\nfunction escapeRegExp(str) {\n return str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\");\n}\n\nfunction firstJSONError(json) {\n for (var key in json) {\n if ( ! json.hasOwnProperty(key)) {\n continue;\n }\n var item = json[key];\n for (var subKey in item) {\n if ( ! item.hasOwnProperty(subKey)) {\n continue;\n }\n return item[subKey];\n }\n }\n return false;\n}\n\n// http://stackoverflow.com/questions/10073699/pad-a-number-with-leading-zeros-in-javascript\nfunction pad(n, width, z) {\n z = z || '0';\n n = n + '';\n return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;\n}\n","var NINJA = NINJA || {};\n\nNINJA.TEMPLATES = {\n CLEAN: \"1\",\n BOLD:\"2\",\n MODERN: \"3\",\n NORMAL:\"4\",\n BUSINESS:\"5\",\n CREATIVE:\"6\",\n ELEGANT:\"7\",\n HIPSTER:\"8\",\n PLAYFUL:\"9\",\n PHOTO:\"10\"\n};\n\nfunction GetPdfMake(invoice, javascript, callback) {\n\n // check if we need to add a second table for tasks\n var itemsTable = false;\n if (invoice.hasSecondTable) {\n var json = JSON.parse(javascript);\n for (var i=0; i= 0) {\n var regExp = new RegExp('\"\\\\$'+key+'\",', 'g');\n val = json[key];\n } else {\n var regExp = new RegExp('\"\\\\$'+key+'\"', 'g');\n var val = JSON.stringify(json[key]);\n val = doubleDollarSign(val);\n }\n javascript = javascript.replace(regExp, val);\n }\n\n // search/replace labels\n var regExp = new RegExp('\"\\\\$\\\\\\w*?Label(UC)?(:)?(\\\\\\?)?\"', 'g');\n var matches = javascript.match(regExp);\n\n if (matches) {\n for (var i=0; i 0 && field == 'balance_due') {\n field = 'partial_due';\n } else if (invoice.is_quote) {\n if (field == 'due_date') {\n field = 'valid_until';\n } else {\n field = field.replace('invoice', 'quote');\n }\n }\n if (invoice.is_statement) {\n if (field == 'your_invoice') {\n field = 'your_statement';\n } else if (field == 'invoice_issued_to') {\n field = 'statement_issued_to';\n } else if (field == 'invoice_to') {\n field = 'statement_to';\n }\n } else if (invoice.balance_amount < 0) {\n if (field == 'your_invoice') {\n field = 'your_credit';\n } else if (field == 'invoice_issued_to') {\n field = 'credit_issued_to';\n } else if (field == 'invoice_to') {\n field = 'credit_to';\n }\n }\n\n var label = invoiceLabels[field];\n if (match.indexOf('UC') >= 0) {\n label = label.toUpperCase();\n }\n if (match.indexOf(':') >= 0) {\n label = label + ':';\n }\n } else {\n label = ' ';\n }\n javascript = javascript.replace(match, '\"'+label+'\"');\n }\n }\n\n // search/replace values\n var regExp = new RegExp('\"\\\\$[a-z][\\\\\\w\\\\\\.]*?[Value]?\"', 'g');\n var matches = javascript.match(regExp);\n\n if (matches) {\n for (var i=0; i= 0) {\n continue;\n }\n\n // legacy style had 'Value' at the end\n if (endsWith(match, 'Value\"')) {\n field = match.substring(2, match.indexOf('Value'));\n } else {\n field = match.substring(2, match.length - 1);\n }\n field = toSnakeCase(field);\n\n var value = getDescendantProp(invoice, field) || ' ';\n value = doubleDollarSign(value);\n value = value.replace(/\\n/g, \"\\\\n\").replace(/\\r/g, \"\\\\r\");\n javascript = javascript.replace(match, '\"'+value+'\"');\n }\n }\n\n return javascript;\n}\n\n\nNINJA.notesAndTerms = function(invoice)\n{\n var data = [];\n\n if (invoice.public_notes) {\n data.push({stack:[{text: invoice.is_recurring ? processVariables(invoice.public_notes) : invoice.public_notes, style: ['notes']}]});\n data.push({text:' '});\n }\n\n if (invoice.terms) {\n data.push({text:invoiceLabels.terms, style: ['termsLabel']});\n data.push({stack:[{text: invoice.is_recurring ? processVariables(invoice.terms) : invoice.terms, style: ['terms']}]});\n }\n\n return NINJA.prepareDataList(data, 'notesAndTerms');\n}\n\nNINJA.statementColumns = function(invoice)\n{\n return [\"22%\", \"22%\", \"22%\", \"17%\", \"17%\"];\n}\n\nNINJA.statementLines = function(invoice)\n{\n var grid = [[]];\n grid[0].push({text: invoiceLabels.invoice_number, style: ['tableHeader', 'itemTableHeader']});\n grid[0].push({text: invoiceLabels.invoice_date, style: ['tableHeader', 'invoiceDateTableHeader']});\n grid[0].push({text: invoiceLabels.due_date, style: ['tableHeader', 'dueDateTableHeader']});\n grid[0].push({text: invoiceLabels.total, style: ['tableHeader', 'totalTableHeader']});\n grid[0].push({text: invoiceLabels.balance, style: ['tableHeader', 'balanceTableHeader']});\n\n for (var i = 0; i < invoice.invoice_items.length; i++) {\n var item = invoice.invoice_items[i];\n var row = [];\n var rowStyle = (i % 2 == 0) ? 'odd' : 'even';\n grid.push([\n {text: item.invoice_number, style:['invoiceNumber', 'productKey', rowStyle]},\n {text: item.invoice_date && item.invoice_date != '0000-00-00' ? moment(item.invoice_date).format(invoice.date_format) : ' ', style:['invoiceDate', rowStyle]},\n {text: item.due_date && item.due_date != '0000-00-00' ? moment(item.due_date).format(invoice.date_format) : ' ', style:['dueDate', rowStyle]},\n {text: formatMoneyInvoice(item.amount, invoice), style:['subtotals', rowStyle]},\n {text: formatMoneyInvoice(item.balance, invoice), style:['lineTotal', rowStyle]},\n ]);\n }\n\n return NINJA.prepareDataTable(grid, 'invoiceItems');\n}\n\nNINJA.invoiceColumns = function(invoice)\n{\n var account = invoice.account;\n var columns = [];\n\n if (invoice.has_product_key) {\n columns.push(\"15%\");\n }\n\n columns.push(\"*\")\n\n if (invoice.features.invoice_settings && account.custom_invoice_item_label1) {\n columns.push(\"10%\");\n }\n if (invoice.features.invoice_settings && account.custom_invoice_item_label2) {\n columns.push(\"10%\");\n }\n\n var count = 3;\n if (account.hide_quantity == '1') {\n count -= 2;\n }\n if (account.show_item_taxes == '1') {\n count++;\n }\n for (var i=0; i= 0 ? (account.custom_invoice_label1 || invoiceLabels.surcharge) : invoiceLabels.discount;\n\n var customValue2 = NINJA.parseFloat(invoice.custom_value2);\n var customValue2Label = customValue2 >= 0 ? (account.custom_invoice_label2 || invoiceLabels.surcharge) : invoiceLabels.discount;\n\n if (customValue1 && invoice.custom_taxes1 == '1') {\n data.push([{text: customValue1Label, style: ['subtotalsLabel', 'customTax1Label']}, {text: formatMoneyInvoice(invoice.custom_value1, invoice), style: ['subtotals', 'customTax1']}]);\n }\n if (customValue2 && invoice.custom_taxes2 == '1') {\n data.push([{text: customValue2Label, style: ['subtotalsLabel', 'customTax2Label']}, {text: formatMoneyInvoice(invoice.custom_value2, invoice), style: ['subtotals', 'customTax2']}]);\n }\n\n for (var key in invoice.item_taxes) {\n if (invoice.item_taxes.hasOwnProperty(key)) {\n var taxRate = invoice.item_taxes[key];\n var taxStr = taxRate.name + ' ' + (taxRate.rate*1).toString() + '%';\n data.push([{text: taxStr, style: ['subtotalsLabel', 'taxLabel']}, {text: formatMoneyInvoice(taxRate.amount, invoice), style: ['subtotals', 'tax']}]);\n }\n }\n\n if (parseFloat(invoice.tax_rate1 || 0) != 0) {\n var taxStr = invoice.tax_name1 + ' ' + (invoice.tax_rate1*1).toString() + '%';\n data.push([{text: taxStr, style: ['subtotalsLabel', 'tax1Label']}, {text: formatMoneyInvoice(invoice.tax_amount1, invoice), style: ['subtotals', 'tax1']}]);\n }\n if (parseFloat(invoice.tax_rate2 || 0) != 0) {\n var taxStr = invoice.tax_name2 + ' ' + (invoice.tax_rate2*1).toString() + '%';\n data.push([{text: taxStr, style: ['subtotalsLabel', 'tax2Label']}, {text: formatMoneyInvoice(invoice.tax_amount2, invoice), style: ['subtotals', 'tax2']}]);\n }\n\n if (customValue1 && invoice.custom_taxes1 != '1') {\n data.push([{text: customValue1Label, style: ['subtotalsLabel', 'custom1Label']}, {text: formatMoneyInvoice(invoice.custom_value1, invoice), style: ['subtotals', 'custom1']}]);\n }\n if (customValue2 && invoice.custom_taxes2 != '1') {\n data.push([{text: customValue2Label, style: ['subtotalsLabel', 'custom2Label']}, {text: formatMoneyInvoice(invoice.custom_value2, invoice), style: ['subtotals', 'custom2']}]);\n }\n\n var paid = invoice.amount - invoice.balance;\n if (!invoice.is_quote && invoice.balance_amount >= 0 && (invoice.account.hide_paid_to_date != '1' || paid)) {\n data.push([{text:invoiceLabels.paid_to_date, style: ['subtotalsLabel', 'paidToDateLabel']}, {text:formatMoneyInvoice(paid, invoice), style: ['subtotals', 'paidToDate']}]);\n }\n\n var isPartial = NINJA.parseFloat(invoice.partial);\n\n if (!hideBalance || isPartial) {\n data.push([\n { text: invoice.is_quote || invoice.balance_amount < 0 ? invoiceLabels.total : invoiceLabels.balance_due, style: ['subtotalsLabel', isPartial ? '' : 'subtotalsBalanceDueLabel'] },\n { text: formatMoneyInvoice(invoice.total_amount, invoice), style: ['subtotals', isPartial ? '' : 'subtotalsBalanceDue'] }\n ]);\n }\n\n if (!hideBalance) {\n if (isPartial) {\n data.push([\n { text: invoiceLabels.partial_due, style: ['subtotalsLabel', 'subtotalsBalanceDueLabel'] },\n { text: formatMoneyInvoice(invoice.balance_amount, invoice), style: ['subtotals', 'subtotalsBalanceDue'] }\n ]);\n }\n }\n\n return NINJA.prepareDataPairs(data, 'subtotals');\n}\n\nNINJA.subtotalsBalance = function(invoice) {\n var isPartial = NINJA.parseFloat(invoice.partial);\n return [[\n {text: isPartial ? invoiceLabels.partial_due : (invoice.is_quote || invoice.balance_amount < 0 ? invoiceLabels.total : invoiceLabels.balance_due), style:['subtotalsLabel', 'subtotalsBalanceDueLabel']},\n {text: formatMoneyInvoice(invoice.balance_amount, invoice), style:['subtotals', 'subtotalsBalanceDue']}\n ]];\n}\n\nNINJA.accountDetails = function(invoice) {\n var account = invoice.account;\n if (invoice.features.invoice_settings && account.invoice_fields) {\n var fields = JSON.parse(account.invoice_fields).account_fields1;\n } else {\n var fields = [\n 'account.company_name',\n 'account.id_number',\n 'account.vat_number',\n 'account.website',\n 'account.email',\n 'account.phone',\n ];\n }\n\n var data = [];\n\n for (var i=0; i < fields.length; i++) {\n var field = fields[i];\n var value = NINJA.renderField(invoice, field);\n if (value) {\n data.push(value);\n }\n }\n\n return NINJA.prepareDataList(data, 'accountDetails');\n}\n\nNINJA.accountAddress = function(invoice) {\n var account = invoice.account;\n if (invoice.features.invoice_settings && account.invoice_fields) {\n var fields = JSON.parse(account.invoice_fields).account_fields2;\n } else {\n var fields = [\n 'account.address1',\n 'account.address2',\n 'account.city_state_postal',\n 'account.country',\n 'account.custom_value1',\n 'account.custom_value2',\n ]\n }\n\n var data = [];\n\n for (var i=0; i < fields.length; i++) {\n var field = fields[i];\n var value = NINJA.renderField(invoice, field);\n if (value) {\n data.push(value);\n }\n }\n\n return NINJA.prepareDataList(data, 'accountAddress');\n}\n\nNINJA.invoiceDetails = function(invoice) {\n\n var account = invoice.account;\n if (invoice.features.invoice_settings && account.invoice_fields) {\n var fields = JSON.parse(account.invoice_fields).invoice_fields;\n } else {\n var fields = [\n 'invoice.invoice_number',\n 'invoice.po_number',\n 'invoice.invoice_date',\n 'invoice.due_date',\n 'invoice.balance_due',\n 'invoice.partial_due',\n 'invoice.custom_text_value1',\n 'invoice.custom_text_value2',\n ];\n }\n var data = [];\n\n for (var i=0; i < fields.length; i++) {\n var field = fields[i];\n var value = NINJA.renderField(invoice, field, true);\n if (value) {\n data.push(value);\n }\n }\n\n return NINJA.prepareDataPairs(data, 'invoiceDetails');\n}\n\n\nNINJA.renderField = function(invoice, field, twoColumn) {\n var client = invoice.client;\n if (!client) {\n return false;\n }\n var account = invoice.account;\n var contact = client.contacts[0];\n var clientName = client.name || (contact.first_name || contact.last_name ? (contact.first_name + ' ' + contact.last_name) : contact.email);\n\n var label = false;\n var value = false;\n\n if (field == 'client.client_name') {\n value = clientName || ' ';\n } else if (field == 'client.contact_name') {\n value = (contact.first_name || contact.last_name) ? contact.first_name + ' ' + contact.last_name : false;\n } else if (field == 'client.id_number') {\n value = client.id_number;\n if (invoiceLabels.id_number_orig) {\n label = invoiceLabels.id_number;\n }\n } else if (field == 'client.vat_number') {\n value = client.vat_number;\n if (invoiceLabels.vat_number_orig) {\n label = invoiceLabels.vat_number;\n }\n } else if (field == 'client.address1') {\n value = client.address1;\n } else if (field == 'client.address2') {\n value = client.address2;\n } else if (field == 'client.city_state_postal') {\n var cityStatePostal = '';\n if (client.city || client.state || client.postal_code) {\n var swap = client.country && client.country.swap_postal_code;\n cityStatePostal = formatAddress(client.city, client.state, client.postal_code, swap);\n }\n value = cityStatePostal;\n } else if (field == 'client.postal_city_state') {\n var postalCityState = '';\n if (client.city || client.state || client.postal_code) {\n postalCityState = formatAddress(client.city, client.state, client.postal_code, true);\n }\n value = postalCityState;\n } else if (field == 'client.country') {\n value = client.country ? client.country.name : '';\n } else if (field == 'client.email') {\n value = contact.email == clientName ? '' : contact.email;\n } else if (field == 'client.phone') {\n value = contact.phone;\n } else if (field == 'client.custom_value1') {\n if (account.custom_client_label1 && client.custom_value1) {\n label = account.custom_client_label1;\n value = client.custom_value1;\n }\n } else if (field == 'client.custom_value2') {\n if (account.custom_client_label2 && client.custom_value2) {\n label = account.custom_client_label2;\n value = client.custom_value2;\n }\n } else if (field == 'contact.custom_value1') {\n if (account.custom_contact_label1 && contact.custom_value1) {\n label = account.custom_contact_label1;\n value = contact.custom_value1;\n }\n } else if (field == 'contact.custom_value2') {\n if (account.custom_contact_label2 && contact.custom_value2) {\n label = account.custom_contact_label2;\n value = contact.custom_value2;\n }\n } else if (field == 'account.company_name') {\n value = account.name;\n } else if (field == 'account.id_number') {\n value = account.id_number;\n if (invoiceLabels.id_number_orig) {\n label = invoiceLabels.id_number;\n }\n } else if (field == 'account.vat_number') {\n value = account.vat_number;\n if (invoiceLabels.vat_number_orig) {\n label = invoiceLabels.vat_number;\n }\n } else if (field == 'account.website') {\n value = account.website;\n } else if (field == 'account.email') {\n value = account.work_email;\n } else if (field == 'account.phone') {\n value = account.work_phone;\n } else if (field == 'account.address1') {\n value = account.address1;\n } else if (field == 'account.address2') {\n value = account.address2;\n } else if (field == 'account.city_state_postal') {\n var cityStatePostal = '';\n if (account.city || account.state || account.postal_code) {\n var swap = account.country && account.country.swap_postal_code;\n cityStatePostal = formatAddress(account.city, account.state, account.postal_code, swap);\n }\n value = cityStatePostal;\n } else if (field == 'account.postal_city_state') {\n var postalCityState = '';\n if (account.city || account.state || account.postal_code) {\n postalCityState = formatAddress(account.city, account.state, account.postal_code, true);\n }\n value = postalCityState;\n } else if (field == 'account.country') {\n value = account.country ? account.country.name : false;\n } else if (field == 'account.custom_value1') {\n if (invoice.account.custom_label1 && invoice.account.custom_value1) {\n label = invoice.account.custom_label1;\n value = invoice.account.custom_value1;\n }\n } else if (field == 'account.custom_value2') {\n if (invoice.account.custom_label2 && invoice.account.custom_value2) {\n label = invoice.account.custom_label2;\n value = invoice.account.custom_value2;\n }\n } else if (field == 'invoice.invoice_number') {\n if (! invoice.is_statement) {\n label = invoice.is_quote ? invoiceLabels.quote_number : invoice.balance_amount < 0 ? invoiceLabels.credit_number : invoiceLabels.invoice_number;\n value = invoice.invoice_number;\n }\n } else if (field == 'invoice.po_number') {\n value = invoice.po_number;\n } else if (field == 'invoice.invoice_date') {\n label = invoice.is_statement ? invoiceLabels.statement_date : invoice.is_quote ? invoiceLabels.quote_date : invoice.balance_amount < 0 ? invoiceLabels.credit_date : invoiceLabels.invoice_date;\n value = invoice.invoice_date;\n } else if (field == 'invoice.due_date') {\n label = invoice.is_quote ? invoiceLabels.valid_until : invoiceLabels.due_date;\n value = invoice.is_recurring ? false : invoice.due_date;\n } else if (field == 'invoice.custom_text_value1') {\n if (invoice.custom_text_value1 && account.custom_invoice_text_label1) {\n label = invoice.account.custom_invoice_text_label1;\n value = invoice.is_recurring ? processVariables(invoice.custom_text_value1) : invoice.custom_text_value1;\n }\n } else if (field == 'invoice.custom_text_value2') {\n if (invoice.custom_text_value2 && account.custom_invoice_text_label2) {\n label = invoice.account.custom_invoice_text_label2;\n value = invoice.is_recurring ? processVariables(invoice.custom_text_value2) : invoice.custom_text_value2;\n }\n } else if (field == 'invoice.balance_due') {\n label = invoice.is_quote || invoice.balance_amount < 0 ? invoiceLabels.total : invoiceLabels.balance_due;\n value = formatMoneyInvoice(invoice.total_amount, invoice);\n } else if (field == invoice.partial_due) {\n if (NINJA.parseFloat(invoice.partial)) {\n label = invoiceLabels.partial_due;\n value = formatMoneyInvoice(invoice.balance_amount, invoice);\n }\n } else if (field == 'invoice.invoice_total') {\n if (invoice.is_statement || invoice.is_quote || invoice.balance_amount < 0) {\n // hide field\n } else {\n value = formatMoneyInvoice(invoice.amount, invoice);\n }\n } else if (field == 'invoice.outstanding') {\n if (invoice.is_statement || invoice.is_quote) {\n // hide field\n } else {\n value = formatMoneyInvoice(client.balance, invoice);\n }\n } else if (field == '.blank') {\n value = ' ';\n }\n\n if (value) {\n var shortField = false;\n var parts = field.split('.');\n if (parts.length >= 2) {\n var shortField = parts[1];\n }\n var style = snakeToCamel(shortField == 'company_name' ? 'account_name' : shortField); // backwards compatibility\n if (twoColumn) {\n // try to automatically determine the label\n if (! label && label != 'Blank') {\n if (invoiceLabels[shortField]) {\n label = invoiceLabels[shortField];\n }\n }\n return [{text: label, style: [style + 'Label']}, {text: value, style: [style]}];\n } else {\n // if the label is set prepend it to the value\n if (label) {\n value = label + ': ' + value;\n }\n return {text:value, style: [style]};\n }\n } else {\n return false;\n }\n}\n\nNINJA.clientDetails = function(invoice) {\n var account = invoice.account;\n if (invoice.features.invoice_settings && account.invoice_fields) {\n var fields = JSON.parse(account.invoice_fields).client_fields;\n } else {\n var fields = [\n 'client.client_name',\n 'client.id_number',\n 'client.vat_number',\n 'client.address1',\n 'client.address2',\n 'client.city_state_postal',\n 'client.country',\n 'client.email',\n 'client.custom_value1',\n 'client.custom_value2',\n 'contact.custom_value1',\n 'contact.custom_value2',\n ];\n }\n var data = [];\n\n for (var i=0; i < fields.length; i++) {\n var field = fields[i];\n var value = NINJA.renderField(invoice, field);\n if (value) {\n data.push(value);\n }\n }\n\n return NINJA.prepareDataList(data, 'clientDetails');\n}\n\nNINJA.getPrimaryColor = function(defaultColor) {\n return NINJA.primaryColor ? NINJA.primaryColor : defaultColor;\n}\n\nNINJA.getSecondaryColor = function(defaultColor) {\n return NINJA.primaryColor ? NINJA.secondaryColor : defaultColor;\n}\n\n// remove blanks and add section style to all elements\nNINJA.prepareDataList = function(oldData, section) {\n var newData = [];\n if (! oldData.length) {\n oldData.push({text:' '});\n }\n for (var i=0; i 1 ? parts : val;\n}\n\n/*\nNINJA.parseMarkdownStack = function(val)\n{\n if (val.length == 1) {\n var item = val[0];\n var line = item.hasOwnProperty('text') ? item.text : item;\n\n if (typeof line === 'string') {\n line = [line];\n }\n\n var regExp = '^\\\\\\* (.*[\\r\\n|\\n|\\r]?)';\n var formatter = function(data) {\n return {\"ul\": [data.text]};\n }\n\n val = NINJA.parseRegExp(line, regExp, formatter, false);\n }\n\n return val;\n}\n*/\n\nNINJA.parseRegExp = function(val, regExpStr, formatter, groupText)\n{\n var regExp = new RegExp(regExpStr, 'gm');\n var parts = [];\n\n for (var i=0; i 1 ? parts : val;\n}\n\nNINJA.parseRegExpLine = function(line, regExp, formatter, groupText)\n{\n var parts = [];\n var lastIndex = -1;\n\n while (match = regExp.exec(line)) {\n if (match.index > lastIndex) {\n parts.push(line.substring(lastIndex, match.index));\n }\n var data = {};\n data.text = match[1];\n data = formatter(data);\n parts.push(data);\n lastIndex = match.index + match[0].length;\n }\n\n if (parts.length) {\n if (lastIndex < line.length) {\n parts.push(line.substring(lastIndex));\n }\n return parts;\n }\n\n return line;\n}\n","/*!\n * Bootstrap v3.3.1 (http://getbootstrap.com)\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\nif (typeof jQuery === 'undefined') {\n throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n var version = $.fn.jquery.split(' ')[0].split('.')\n if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {\n throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher')\n }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.1\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n // ============================================================\n\n function transitionEnd() {\n var el = document.createElement('bootstrap')\n\n var transEndEventNames = {\n WebkitTransition : 'webkitTransitionEnd',\n MozTransition : 'transitionend',\n OTransition : 'oTransitionEnd otransitionend',\n transition : 'transitionend'\n }\n\n for (var name in transEndEventNames) {\n if (el.style[name] !== undefined) {\n return { end: transEndEventNames[name] }\n }\n }\n\n return false // explicit for ie8 ( ._.)\n }\n\n // http://blog.alexmaccaw.com/css-transitions\n $.fn.emulateTransitionEnd = function (duration) {\n var called = false\n var $el = this\n $(this).one('bsTransitionEnd', function () { called = true })\n var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n setTimeout(callback, duration)\n return this\n }\n\n $(function () {\n $.support.transition = transitionEnd()\n\n if (!$.support.transition) return\n\n $.event.special.bsTransitionEnd = {\n bindType: $.support.transition.end,\n delegateType: $.support.transition.end,\n handle: function (e) {\n if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n }\n }\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.1\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // ALERT CLASS DEFINITION\n // ======================\n\n var dismiss = '[data-dismiss=\"alert\"]'\n var Alert = function (el) {\n $(el).on('click', dismiss, this.close)\n }\n\n Alert.VERSION = '3.3.1'\n\n Alert.TRANSITION_DURATION = 150\n\n Alert.prototype.close = function (e) {\n var $this = $(this)\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = $(selector)\n\n if (e) e.preventDefault()\n\n if (!$parent.length) {\n $parent = $this.closest('.alert')\n }\n\n $parent.trigger(e = $.Event('close.bs.alert'))\n\n if (e.isDefaultPrevented()) return\n\n $parent.removeClass('in')\n\n function removeElement() {\n // detach from parent, fire event then clean up data\n $parent.detach().trigger('closed.bs.alert').remove()\n }\n\n $.support.transition && $parent.hasClass('fade') ?\n $parent\n .one('bsTransitionEnd', removeElement)\n .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n removeElement()\n }\n\n\n // ALERT PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.alert')\n\n if (!data) $this.data('bs.alert', (data = new Alert(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.alert\n\n $.fn.alert = Plugin\n $.fn.alert.Constructor = Alert\n\n\n // ALERT NO CONFLICT\n // =================\n\n $.fn.alert.noConflict = function () {\n $.fn.alert = old\n return this\n }\n\n\n // ALERT DATA-API\n // ==============\n\n $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.1\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // BUTTON PUBLIC CLASS DEFINITION\n // ==============================\n\n var Button = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Button.DEFAULTS, options)\n this.isLoading = false\n }\n\n Button.VERSION = '3.3.1'\n\n Button.DEFAULTS = {\n loadingText: 'loading...'\n }\n\n Button.prototype.setState = function (state) {\n var d = 'disabled'\n var $el = this.$element\n var val = $el.is('input') ? 'val' : 'html'\n var data = $el.data()\n\n state = state + 'Text'\n\n if (data.resetText == null) $el.data('resetText', $el[val]())\n\n // push to event loop to allow forms to submit\n setTimeout($.proxy(function () {\n $el[val](data[state] == null ? this.options[state] : data[state])\n\n if (state == 'loadingText') {\n this.isLoading = true\n $el.addClass(d).attr(d, d)\n } else if (this.isLoading) {\n this.isLoading = false\n $el.removeClass(d).removeAttr(d)\n }\n }, this), 0)\n }\n\n Button.prototype.toggle = function () {\n var changed = true\n var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n if ($parent.length) {\n var $input = this.$element.find('input')\n if ($input.prop('type') == 'radio') {\n if ($input.prop('checked') && this.$element.hasClass('active')) changed = false\n else $parent.find('.active').removeClass('active')\n }\n if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')\n } else {\n this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n }\n\n if (changed) this.$element.toggleClass('active')\n }\n\n\n // BUTTON PLUGIN DEFINITION\n // ========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.button')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n if (option == 'toggle') data.toggle()\n else if (option) data.setState(option)\n })\n }\n\n var old = $.fn.button\n\n $.fn.button = Plugin\n $.fn.button.Constructor = Button\n\n\n // BUTTON NO CONFLICT\n // ==================\n\n $.fn.button.noConflict = function () {\n $.fn.button = old\n return this\n }\n\n\n // BUTTON DATA-API\n // ===============\n\n $(document)\n .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n var $btn = $(e.target)\n if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n Plugin.call($btn, 'toggle')\n e.preventDefault()\n })\n .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.1\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // CAROUSEL CLASS DEFINITION\n // =========================\n\n var Carousel = function (element, options) {\n this.$element = $(element)\n this.$indicators = this.$element.find('.carousel-indicators')\n this.options = options\n this.paused =\n this.sliding =\n this.interval =\n this.$active =\n this.$items = null\n\n this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n }\n\n Carousel.VERSION = '3.3.1'\n\n Carousel.TRANSITION_DURATION = 600\n\n Carousel.DEFAULTS = {\n interval: 5000,\n pause: 'hover',\n wrap: true,\n keyboard: true\n }\n\n Carousel.prototype.keydown = function (e) {\n if (/input|textarea/i.test(e.target.tagName)) return\n switch (e.which) {\n case 37: this.prev(); break\n case 39: this.next(); break\n default: return\n }\n\n e.preventDefault()\n }\n\n Carousel.prototype.cycle = function (e) {\n e || (this.paused = false)\n\n this.interval && clearInterval(this.interval)\n\n this.options.interval\n && !this.paused\n && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n return this\n }\n\n Carousel.prototype.getItemIndex = function (item) {\n this.$items = item.parent().children('.item')\n return this.$items.index(item || this.$active)\n }\n\n Carousel.prototype.getItemForDirection = function (direction, active) {\n var delta = direction == 'prev' ? -1 : 1\n var activeIndex = this.getItemIndex(active)\n var itemIndex = (activeIndex + delta) % this.$items.length\n return this.$items.eq(itemIndex)\n }\n\n Carousel.prototype.to = function (pos) {\n var that = this\n var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n if (pos > (this.$items.length - 1) || pos < 0) return\n\n if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n if (activeIndex == pos) return this.pause().cycle()\n\n return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n }\n\n Carousel.prototype.pause = function (e) {\n e || (this.paused = true)\n\n if (this.$element.find('.next, .prev').length && $.support.transition) {\n this.$element.trigger($.support.transition.end)\n this.cycle(true)\n }\n\n this.interval = clearInterval(this.interval)\n\n return this\n }\n\n Carousel.prototype.next = function () {\n if (this.sliding) return\n return this.slide('next')\n }\n\n Carousel.prototype.prev = function () {\n if (this.sliding) return\n return this.slide('prev')\n }\n\n Carousel.prototype.slide = function (type, next) {\n var $active = this.$element.find('.item.active')\n var $next = next || this.getItemForDirection(type, $active)\n var isCycling = this.interval\n var direction = type == 'next' ? 'left' : 'right'\n var fallback = type == 'next' ? 'first' : 'last'\n var that = this\n\n if (!$next.length) {\n if (!this.options.wrap) return\n $next = this.$element.find('.item')[fallback]()\n }\n\n if ($next.hasClass('active')) return (this.sliding = false)\n\n var relatedTarget = $next[0]\n var slideEvent = $.Event('slide.bs.carousel', {\n relatedTarget: relatedTarget,\n direction: direction\n })\n this.$element.trigger(slideEvent)\n if (slideEvent.isDefaultPrevented()) return\n\n this.sliding = true\n\n isCycling && this.pause()\n\n if (this.$indicators.length) {\n this.$indicators.find('.active').removeClass('active')\n var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n $nextIndicator && $nextIndicator.addClass('active')\n }\n\n var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n if ($.support.transition && this.$element.hasClass('slide')) {\n $next.addClass(type)\n $next[0].offsetWidth // force reflow\n $active.addClass(direction)\n $next.addClass(direction)\n $active\n .one('bsTransitionEnd', function () {\n $next.removeClass([type, direction].join(' ')).addClass('active')\n $active.removeClass(['active', direction].join(' '))\n that.sliding = false\n setTimeout(function () {\n that.$element.trigger(slidEvent)\n }, 0)\n })\n .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n } else {\n $active.removeClass('active')\n $next.addClass('active')\n this.sliding = false\n this.$element.trigger(slidEvent)\n }\n\n isCycling && this.cycle()\n\n return this\n }\n\n\n // CAROUSEL PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.carousel')\n var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n var action = typeof option == 'string' ? option : options.slide\n\n if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n if (typeof option == 'number') data.to(option)\n else if (action) data[action]()\n else if (options.interval) data.pause().cycle()\n })\n }\n\n var old = $.fn.carousel\n\n $.fn.carousel = Plugin\n $.fn.carousel.Constructor = Carousel\n\n\n // CAROUSEL NO CONFLICT\n // ====================\n\n $.fn.carousel.noConflict = function () {\n $.fn.carousel = old\n return this\n }\n\n\n // CAROUSEL DATA-API\n // =================\n\n var clickHandler = function (e) {\n var href\n var $this = $(this)\n var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n if (!$target.hasClass('carousel')) return\n var options = $.extend({}, $target.data(), $this.data())\n var slideIndex = $this.attr('data-slide-to')\n if (slideIndex) options.interval = false\n\n Plugin.call($target, options)\n\n if (slideIndex) {\n $target.data('bs.carousel').to(slideIndex)\n }\n\n e.preventDefault()\n }\n\n $(document)\n .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n $(window).on('load', function () {\n $('[data-ride=\"carousel\"]').each(function () {\n var $carousel = $(this)\n Plugin.call($carousel, $carousel.data())\n })\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.1\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // COLLAPSE PUBLIC CLASS DEFINITION\n // ================================\n\n var Collapse = function (element, options) {\n this.$element = $(element)\n this.options = $.extend({}, Collapse.DEFAULTS, options)\n this.$trigger = $(this.options.trigger).filter('[href=\"#' + element.id + '\"], [data-target=\"#' + element.id + '\"]')\n this.transitioning = null\n\n if (this.options.parent) {\n this.$parent = this.getParent()\n } else {\n this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n }\n\n if (this.options.toggle) this.toggle()\n }\n\n Collapse.VERSION = '3.3.1'\n\n Collapse.TRANSITION_DURATION = 350\n\n Collapse.DEFAULTS = {\n toggle: true,\n trigger: '[data-toggle=\"collapse\"]'\n }\n\n Collapse.prototype.dimension = function () {\n var hasWidth = this.$element.hasClass('width')\n return hasWidth ? 'width' : 'height'\n }\n\n Collapse.prototype.show = function () {\n if (this.transitioning || this.$element.hasClass('in')) return\n\n var activesData\n var actives = this.$parent && this.$parent.find('> .panel').children('.in, .collapsing')\n\n if (actives && actives.length) {\n activesData = actives.data('bs.collapse')\n if (activesData && activesData.transitioning) return\n }\n\n var startEvent = $.Event('show.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n if (actives && actives.length) {\n Plugin.call(actives, 'hide')\n activesData || actives.data('bs.collapse', null)\n }\n\n var dimension = this.dimension()\n\n this.$element\n .removeClass('collapse')\n .addClass('collapsing')[dimension](0)\n .attr('aria-expanded', true)\n\n this.$trigger\n .removeClass('collapsed')\n .attr('aria-expanded', true)\n\n this.transitioning = 1\n\n var complete = function () {\n this.$element\n .removeClass('collapsing')\n .addClass('collapse in')[dimension]('')\n this.transitioning = 0\n this.$element\n .trigger('shown.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n this.$element\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n }\n\n Collapse.prototype.hide = function () {\n if (this.transitioning || !this.$element.hasClass('in')) return\n\n var startEvent = $.Event('hide.bs.collapse')\n this.$element.trigger(startEvent)\n if (startEvent.isDefaultPrevented()) return\n\n var dimension = this.dimension()\n\n this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n this.$element\n .addClass('collapsing')\n .removeClass('collapse in')\n .attr('aria-expanded', false)\n\n this.$trigger\n .addClass('collapsed')\n .attr('aria-expanded', false)\n\n this.transitioning = 1\n\n var complete = function () {\n this.transitioning = 0\n this.$element\n .removeClass('collapsing')\n .addClass('collapse')\n .trigger('hidden.bs.collapse')\n }\n\n if (!$.support.transition) return complete.call(this)\n\n this.$element\n [dimension](0)\n .one('bsTransitionEnd', $.proxy(complete, this))\n .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n }\n\n Collapse.prototype.toggle = function () {\n this[this.$element.hasClass('in') ? 'hide' : 'show']()\n }\n\n Collapse.prototype.getParent = function () {\n return $(this.options.parent)\n .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n .each($.proxy(function (i, element) {\n var $element = $(element)\n this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n }, this))\n .end()\n }\n\n Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n var isOpen = $element.hasClass('in')\n\n $element.attr('aria-expanded', isOpen)\n $trigger\n .toggleClass('collapsed', !isOpen)\n .attr('aria-expanded', isOpen)\n }\n\n function getTargetFromTrigger($trigger) {\n var href\n var target = $trigger.attr('data-target')\n || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n return $(target)\n }\n\n\n // COLLAPSE PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.collapse')\n var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data && options.toggle && option == 'show') options.toggle = false\n if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.collapse\n\n $.fn.collapse = Plugin\n $.fn.collapse.Constructor = Collapse\n\n\n // COLLAPSE NO CONFLICT\n // ====================\n\n $.fn.collapse.noConflict = function () {\n $.fn.collapse = old\n return this\n }\n\n\n // COLLAPSE DATA-API\n // =================\n\n $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n var $this = $(this)\n\n if (!$this.attr('data-target')) e.preventDefault()\n\n var $target = getTargetFromTrigger($this)\n var data = $target.data('bs.collapse')\n var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })\n\n Plugin.call($target, option)\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.1\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // DROPDOWN CLASS DEFINITION\n // =========================\n\n var backdrop = '.dropdown-backdrop'\n var toggle = '[data-toggle=\"dropdown\"]'\n var Dropdown = function (element) {\n $(element).on('click.bs.dropdown', this.toggle)\n }\n\n Dropdown.VERSION = '3.3.1'\n\n Dropdown.prototype.toggle = function (e) {\n var $this = $(this)\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n clearMenus()\n\n if (!isActive) {\n if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n // if mobile we use a backdrop because click events don't delegate\n $('
').insertAfter($(this)).on('click', clearMenus)\n }\n\n var relatedTarget = { relatedTarget: this }\n $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this\n .trigger('focus')\n .attr('aria-expanded', 'true')\n\n $parent\n .toggleClass('open')\n .trigger('shown.bs.dropdown', relatedTarget)\n }\n\n return false\n }\n\n Dropdown.prototype.keydown = function (e) {\n if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n var $this = $(this)\n\n e.preventDefault()\n e.stopPropagation()\n\n if ($this.is('.disabled, :disabled')) return\n\n var $parent = getParent($this)\n var isActive = $parent.hasClass('open')\n\n if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {\n if (e.which == 27) $parent.find(toggle).trigger('focus')\n return $this.trigger('click')\n }\n\n var desc = ' li:not(.divider):visible a'\n var $items = $parent.find('[role=\"menu\"]' + desc + ', [role=\"listbox\"]' + desc)\n\n if (!$items.length) return\n\n var index = $items.index(e.target)\n\n if (e.which == 38 && index > 0) index-- // up\n if (e.which == 40 && index < $items.length - 1) index++ // down\n if (!~index) index = 0\n\n $items.eq(index).trigger('focus')\n }\n\n function clearMenus(e) {\n if (e && e.which === 3) return\n $(backdrop).remove()\n $(toggle).each(function () {\n var $this = $(this)\n var $parent = getParent($this)\n var relatedTarget = { relatedTarget: this }\n\n if (!$parent.hasClass('open')) return\n\n $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n if (e.isDefaultPrevented()) return\n\n $this.attr('aria-expanded', 'false')\n $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)\n })\n }\n\n function getParent($this) {\n var selector = $this.attr('data-target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n var $parent = selector && $(selector)\n\n return $parent && $parent.length ? $parent : $this.parent()\n }\n\n\n // DROPDOWN PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.dropdown')\n\n if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n if (typeof option == 'string') data[option].call($this)\n })\n }\n\n var old = $.fn.dropdown\n\n $.fn.dropdown = Plugin\n $.fn.dropdown.Constructor = Dropdown\n\n\n // DROPDOWN NO CONFLICT\n // ====================\n\n $.fn.dropdown.noConflict = function () {\n $.fn.dropdown = old\n return this\n }\n\n\n // APPLY TO STANDARD DROPDOWN ELEMENTS\n // ===================================\n\n $(document)\n .on('click.bs.dropdown.data-api', clearMenus)\n .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n .on('keydown.bs.dropdown.data-api', '[role=\"menu\"]', Dropdown.prototype.keydown)\n .on('keydown.bs.dropdown.data-api', '[role=\"listbox\"]', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.1\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // MODAL CLASS DEFINITION\n // ======================\n\n var Modal = function (element, options) {\n this.options = options\n this.$body = $(document.body)\n this.$element = $(element)\n this.$backdrop =\n this.isShown = null\n this.scrollbarWidth = 0\n\n if (this.options.remote) {\n this.$element\n .find('.modal-content')\n .load(this.options.remote, $.proxy(function () {\n this.$element.trigger('loaded.bs.modal')\n }, this))\n }\n }\n\n Modal.VERSION = '3.3.1'\n\n Modal.TRANSITION_DURATION = 300\n Modal.BACKDROP_TRANSITION_DURATION = 150\n\n Modal.DEFAULTS = {\n backdrop: true,\n keyboard: true,\n show: true\n }\n\n Modal.prototype.toggle = function (_relatedTarget) {\n return this.isShown ? this.hide() : this.show(_relatedTarget)\n }\n\n Modal.prototype.show = function (_relatedTarget) {\n var that = this\n var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n this.$element.trigger(e)\n\n if (this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = true\n\n this.checkScrollbar()\n this.setScrollbar()\n this.$body.addClass('modal-open')\n\n this.escape()\n this.resize()\n\n this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n this.backdrop(function () {\n var transition = $.support.transition && that.$element.hasClass('fade')\n\n if (!that.$element.parent().length) {\n that.$element.appendTo(that.$body) // don't move modals dom position\n }\n\n that.$element\n .show()\n .scrollTop(0)\n\n if (that.options.backdrop) that.adjustBackdrop()\n that.adjustDialog()\n\n if (transition) {\n that.$element[0].offsetWidth // force reflow\n }\n\n that.$element\n .addClass('in')\n .attr('aria-hidden', false)\n\n that.enforceFocus()\n\n var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n transition ?\n that.$element.find('.modal-dialog') // wait for modal to slide in\n .one('bsTransitionEnd', function () {\n that.$element.trigger('focus').trigger(e)\n })\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n that.$element.trigger('focus').trigger(e)\n })\n }\n\n Modal.prototype.hide = function (e) {\n if (e) e.preventDefault()\n\n e = $.Event('hide.bs.modal')\n\n this.$element.trigger(e)\n\n if (!this.isShown || e.isDefaultPrevented()) return\n\n this.isShown = false\n\n this.escape()\n this.resize()\n\n $(document).off('focusin.bs.modal')\n\n this.$element\n .removeClass('in')\n .attr('aria-hidden', true)\n .off('click.dismiss.bs.modal')\n\n $.support.transition && this.$element.hasClass('fade') ?\n this.$element\n .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n this.hideModal()\n }\n\n Modal.prototype.enforceFocus = function () {\n $(document)\n .off('focusin.bs.modal') // guard against infinite focus loop\n .on('focusin.bs.modal', $.proxy(function (e) {\n if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n this.$element.trigger('focus')\n }\n }, this))\n }\n\n Modal.prototype.escape = function () {\n if (this.isShown && this.options.keyboard) {\n this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n e.which == 27 && this.hide()\n }, this))\n } else if (!this.isShown) {\n this.$element.off('keydown.dismiss.bs.modal')\n }\n }\n\n Modal.prototype.resize = function () {\n if (this.isShown) {\n $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n } else {\n $(window).off('resize.bs.modal')\n }\n }\n\n Modal.prototype.hideModal = function () {\n var that = this\n this.$element.hide()\n this.backdrop(function () {\n that.$body.removeClass('modal-open')\n that.resetAdjustments()\n that.resetScrollbar()\n that.$element.trigger('hidden.bs.modal')\n })\n }\n\n Modal.prototype.removeBackdrop = function () {\n this.$backdrop && this.$backdrop.remove()\n this.$backdrop = null\n }\n\n Modal.prototype.backdrop = function (callback) {\n var that = this\n var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n if (this.isShown && this.options.backdrop) {\n var doAnimate = $.support.transition && animate\n\n this.$backdrop = $('')\n .prependTo(this.$element)\n .on('click.dismiss.bs.modal', $.proxy(function (e) {\n if (e.target !== e.currentTarget) return\n this.options.backdrop == 'static'\n ? this.$element[0].focus.call(this.$element[0])\n : this.hide.call(this)\n }, this))\n\n if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n this.$backdrop.addClass('in')\n\n if (!callback) return\n\n doAnimate ?\n this.$backdrop\n .one('bsTransitionEnd', callback)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callback()\n\n } else if (!this.isShown && this.$backdrop) {\n this.$backdrop.removeClass('in')\n\n var callbackRemove = function () {\n that.removeBackdrop()\n callback && callback()\n }\n $.support.transition && this.$element.hasClass('fade') ?\n this.$backdrop\n .one('bsTransitionEnd', callbackRemove)\n .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n callbackRemove()\n\n } else if (callback) {\n callback()\n }\n }\n\n // these following methods are used to handle overflowing modals\n\n Modal.prototype.handleUpdate = function () {\n if (this.options.backdrop) this.adjustBackdrop()\n this.adjustDialog()\n }\n\n Modal.prototype.adjustBackdrop = function () {\n this.$backdrop\n .css('height', 0)\n .css('height', this.$element[0].scrollHeight)\n }\n\n Modal.prototype.adjustDialog = function () {\n var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n this.$element.css({\n paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n })\n }\n\n Modal.prototype.resetAdjustments = function () {\n this.$element.css({\n paddingLeft: '',\n paddingRight: ''\n })\n }\n\n Modal.prototype.checkScrollbar = function () {\n this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight\n this.scrollbarWidth = this.measureScrollbar()\n }\n\n Modal.prototype.setScrollbar = function () {\n var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n }\n\n Modal.prototype.resetScrollbar = function () {\n this.$body.css('padding-right', '')\n }\n\n Modal.prototype.measureScrollbar = function () { // thx walsh\n var scrollDiv = document.createElement('div')\n scrollDiv.className = 'modal-scrollbar-measure'\n this.$body.append(scrollDiv)\n var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n this.$body[0].removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n\n // MODAL PLUGIN DEFINITION\n // =======================\n\n function Plugin(option, _relatedTarget) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.modal')\n var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n if (typeof option == 'string') data[option](_relatedTarget)\n else if (options.show) data.show(_relatedTarget)\n })\n }\n\n var old = $.fn.modal\n\n $.fn.modal = Plugin\n $.fn.modal.Constructor = Modal\n\n\n // MODAL NO CONFLICT\n // =================\n\n $.fn.modal.noConflict = function () {\n $.fn.modal = old\n return this\n }\n\n\n // MODAL DATA-API\n // ==============\n\n $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n var $this = $(this)\n var href = $this.attr('href')\n var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n if ($this.is('a')) e.preventDefault()\n\n $target.one('show.bs.modal', function (showEvent) {\n if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n $target.one('hidden.bs.modal', function () {\n $this.is(':visible') && $this.trigger('focus')\n })\n })\n Plugin.call($target, option, this)\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.1\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TOOLTIP PUBLIC CLASS DEFINITION\n // ===============================\n\n var Tooltip = function (element, options) {\n this.type =\n this.options =\n this.enabled =\n this.timeout =\n this.hoverState =\n this.$element = null\n\n this.init('tooltip', element, options)\n }\n\n Tooltip.VERSION = '3.3.1'\n\n Tooltip.TRANSITION_DURATION = 150\n\n Tooltip.DEFAULTS = {\n animation: true,\n placement: 'top',\n selector: false,\n template: '
',\n trigger: 'hover focus',\n title: '',\n delay: 0,\n html: false,\n container: false,\n viewport: {\n selector: 'body',\n padding: 0\n }\n }\n\n Tooltip.prototype.init = function (type, element, options) {\n this.enabled = true\n this.type = type\n this.$element = $(element)\n this.options = this.getOptions(options)\n this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)\n\n var triggers = this.options.trigger.split(' ')\n\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i]\n\n if (trigger == 'click') {\n this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n } else if (trigger != 'manual') {\n var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'\n var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n }\n }\n\n this.options.selector ?\n (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n this.fixTitle()\n }\n\n Tooltip.prototype.getDefaults = function () {\n return Tooltip.DEFAULTS\n }\n\n Tooltip.prototype.getOptions = function (options) {\n options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n if (options.delay && typeof options.delay == 'number') {\n options.delay = {\n show: options.delay,\n hide: options.delay\n }\n }\n\n return options\n }\n\n Tooltip.prototype.getDelegateOptions = function () {\n var options = {}\n var defaults = this.getDefaults()\n\n this._options && $.each(this._options, function (key, value) {\n if (defaults[key] != value) options[key] = value\n })\n\n return options\n }\n\n Tooltip.prototype.enter = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (self && self.$tip && self.$tip.is(':visible')) {\n self.hoverState = 'in'\n return\n }\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'in'\n\n if (!self.options.delay || !self.options.delay.show) return self.show()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'in') self.show()\n }, self.options.delay.show)\n }\n\n Tooltip.prototype.leave = function (obj) {\n var self = obj instanceof this.constructor ?\n obj : $(obj.currentTarget).data('bs.' + this.type)\n\n if (!self) {\n self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n $(obj.currentTarget).data('bs.' + this.type, self)\n }\n\n clearTimeout(self.timeout)\n\n self.hoverState = 'out'\n\n if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n self.timeout = setTimeout(function () {\n if (self.hoverState == 'out') self.hide()\n }, self.options.delay.hide)\n }\n\n Tooltip.prototype.show = function () {\n var e = $.Event('show.bs.' + this.type)\n\n if (this.hasContent() && this.enabled) {\n this.$element.trigger(e)\n\n var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n if (e.isDefaultPrevented() || !inDom) return\n var that = this\n\n var $tip = this.tip()\n\n var tipId = this.getUID(this.type)\n\n this.setContent()\n $tip.attr('id', tipId)\n this.$element.attr('aria-describedby', tipId)\n\n if (this.options.animation) $tip.addClass('fade')\n\n var placement = typeof this.options.placement == 'function' ?\n this.options.placement.call(this, $tip[0], this.$element[0]) :\n this.options.placement\n\n var autoToken = /\\s?auto?\\s?/i\n var autoPlace = autoToken.test(placement)\n if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n $tip\n .detach()\n .css({ top: 0, left: 0, display: 'block' })\n .addClass(placement)\n .data('bs.' + this.type, this)\n\n this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n\n var pos = this.getPosition()\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (autoPlace) {\n var orgPlacement = placement\n var $container = this.options.container ? $(this.options.container) : this.$element.parent()\n var containerDim = this.getPosition($container)\n\n placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :\n placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :\n placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :\n placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :\n placement\n\n $tip\n .removeClass(orgPlacement)\n .addClass(placement)\n }\n\n var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n this.applyPlacement(calculatedOffset, placement)\n\n var complete = function () {\n var prevHoverState = that.hoverState\n that.$element.trigger('shown.bs.' + that.type)\n that.hoverState = null\n\n if (prevHoverState == 'out') that.leave(that)\n }\n\n $.support.transition && this.$tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n }\n }\n\n Tooltip.prototype.applyPlacement = function (offset, placement) {\n var $tip = this.tip()\n var width = $tip[0].offsetWidth\n var height = $tip[0].offsetHeight\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt($tip.css('margin-top'), 10)\n var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0\n if (isNaN(marginLeft)) marginLeft = 0\n\n offset.top = offset.top + marginTop\n offset.left = offset.left + marginLeft\n\n // $.fn.offset doesn't round pixel values\n // so we use setOffset directly with our own function B-0\n $.offset.setOffset($tip[0], $.extend({\n using: function (props) {\n $tip.css({\n top: Math.round(props.top),\n left: Math.round(props.left)\n })\n }\n }, offset), 0)\n\n $tip.addClass('in')\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = $tip[0].offsetWidth\n var actualHeight = $tip[0].offsetHeight\n\n if (placement == 'top' && actualHeight != height) {\n offset.top = offset.top + height - actualHeight\n }\n\n var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n if (delta.left) offset.left += delta.left\n else offset.top += delta.top\n\n var isVertical = /top|bottom/.test(placement)\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n $tip.offset(offset)\n this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n }\n\n Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {\n this.arrow()\n .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '')\n }\n\n Tooltip.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n\n $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n $tip.removeClass('fade in top bottom left right')\n }\n\n Tooltip.prototype.hide = function (callback) {\n var that = this\n var $tip = this.tip()\n var e = $.Event('hide.bs.' + this.type)\n\n function complete() {\n if (that.hoverState != 'in') $tip.detach()\n that.$element\n .removeAttr('aria-describedby')\n .trigger('hidden.bs.' + that.type)\n callback && callback()\n }\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n $tip.removeClass('in')\n\n $.support.transition && this.$tip.hasClass('fade') ?\n $tip\n .one('bsTransitionEnd', complete)\n .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n complete()\n\n this.hoverState = null\n\n return this\n }\n\n Tooltip.prototype.fixTitle = function () {\n var $e = this.$element\n if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {\n $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n }\n }\n\n Tooltip.prototype.hasContent = function () {\n return this.getTitle()\n }\n\n Tooltip.prototype.getPosition = function ($element) {\n $element = $element || this.$element\n\n var el = $element[0]\n var isBody = el.tagName == 'BODY'\n\n var elRect = el.getBoundingClientRect()\n if (elRect.width == null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n }\n var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()\n var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n return $.extend({}, elRect, scroll, outerDims, elOffset)\n }\n\n Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n }\n\n Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n var delta = { top: 0, left: 0 }\n if (!this.$viewport) return delta\n\n var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n var viewportDimensions = this.getPosition(this.$viewport)\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll\n var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n }\n } else {\n var leftEdgeOffset = pos.left - viewportPadding\n var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset\n } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n }\n }\n\n return delta\n }\n\n Tooltip.prototype.getTitle = function () {\n var title\n var $e = this.$element\n var o = this.options\n\n title = $e.attr('data-original-title')\n || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)\n\n return title\n }\n\n Tooltip.prototype.getUID = function (prefix) {\n do prefix += ~~(Math.random() * 1000000)\n while (document.getElementById(prefix))\n return prefix\n }\n\n Tooltip.prototype.tip = function () {\n return (this.$tip = this.$tip || $(this.options.template))\n }\n\n Tooltip.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n }\n\n Tooltip.prototype.enable = function () {\n this.enabled = true\n }\n\n Tooltip.prototype.disable = function () {\n this.enabled = false\n }\n\n Tooltip.prototype.toggleEnabled = function () {\n this.enabled = !this.enabled\n }\n\n Tooltip.prototype.toggle = function (e) {\n var self = this\n if (e) {\n self = $(e.currentTarget).data('bs.' + this.type)\n if (!self) {\n self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n $(e.currentTarget).data('bs.' + this.type, self)\n }\n }\n\n self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n }\n\n Tooltip.prototype.destroy = function () {\n var that = this\n clearTimeout(this.timeout)\n this.hide(function () {\n that.$element.off('.' + that.type).removeData('bs.' + that.type)\n })\n }\n\n\n // TOOLTIP PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tooltip')\n var options = typeof option == 'object' && option\n var selector = options && options.selector\n\n if (!data && option == 'destroy') return\n if (selector) {\n if (!data) $this.data('bs.tooltip', (data = {}))\n if (!data[selector]) data[selector] = new Tooltip(this, options)\n } else {\n if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n }\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tooltip\n\n $.fn.tooltip = Plugin\n $.fn.tooltip.Constructor = Tooltip\n\n\n // TOOLTIP NO CONFLICT\n // ===================\n\n $.fn.tooltip.noConflict = function () {\n $.fn.tooltip = old\n return this\n }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.1\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // POPOVER PUBLIC CLASS DEFINITION\n // ===============================\n\n var Popover = function (element, options) {\n this.init('popover', element, options)\n }\n\n if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n Popover.VERSION = '3.3.1'\n\n Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n placement: 'right',\n trigger: 'click',\n content: '',\n template: '
'\n })\n\n\n // NOTE: POPOVER EXTENDS tooltip.js\n // ================================\n\n Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n Popover.prototype.constructor = Popover\n\n Popover.prototype.getDefaults = function () {\n return Popover.DEFAULTS\n }\n\n Popover.prototype.setContent = function () {\n var $tip = this.tip()\n var title = this.getTitle()\n var content = this.getContent()\n\n $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n ](content)\n\n $tip.removeClass('fade top bottom left right in')\n\n // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n // this manually by checking the contents.\n if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n }\n\n Popover.prototype.hasContent = function () {\n return this.getTitle() || this.getContent()\n }\n\n Popover.prototype.getContent = function () {\n var $e = this.$element\n var o = this.options\n\n return $e.attr('data-content')\n || (typeof o.content == 'function' ?\n o.content.call($e[0]) :\n o.content)\n }\n\n Popover.prototype.arrow = function () {\n return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n }\n\n Popover.prototype.tip = function () {\n if (!this.$tip) this.$tip = $(this.options.template)\n return this.$tip\n }\n\n\n // POPOVER PLUGIN DEFINITION\n // =========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.popover')\n var options = typeof option == 'object' && option\n var selector = options && options.selector\n\n if (!data && option == 'destroy') return\n if (selector) {\n if (!data) $this.data('bs.popover', (data = {}))\n if (!data[selector]) data[selector] = new Popover(this, options)\n } else {\n if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n }\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.popover\n\n $.fn.popover = Plugin\n $.fn.popover.Constructor = Popover\n\n\n // POPOVER NO CONFLICT\n // ===================\n\n $.fn.popover.noConflict = function () {\n $.fn.popover = old\n return this\n }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.1\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // SCROLLSPY CLASS DEFINITION\n // ==========================\n\n function ScrollSpy(element, options) {\n var process = $.proxy(this.process, this)\n\n this.$body = $('body')\n this.$scrollElement = $(element).is('body') ? $(window) : $(element)\n this.options = $.extend({}, ScrollSpy.DEFAULTS, options)\n this.selector = (this.options.target || '') + ' .nav li > a'\n this.offsets = []\n this.targets = []\n this.activeTarget = null\n this.scrollHeight = 0\n\n this.$scrollElement.on('scroll.bs.scrollspy', process)\n this.refresh()\n this.process()\n }\n\n ScrollSpy.VERSION = '3.3.1'\n\n ScrollSpy.DEFAULTS = {\n offset: 10\n }\n\n ScrollSpy.prototype.getScrollHeight = function () {\n return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n }\n\n ScrollSpy.prototype.refresh = function () {\n var offsetMethod = 'offset'\n var offsetBase = 0\n\n if (!$.isWindow(this.$scrollElement[0])) {\n offsetMethod = 'position'\n offsetBase = this.$scrollElement.scrollTop()\n }\n\n this.offsets = []\n this.targets = []\n this.scrollHeight = this.getScrollHeight()\n\n var self = this\n\n this.$body\n .find(this.selector)\n .map(function () {\n var $el = $(this)\n var href = $el.data('target') || $el.attr('href')\n var $href = /^#./.test(href) && $(href)\n\n return ($href\n && $href.length\n && $href.is(':visible')\n && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n })\n .sort(function (a, b) { return a[0] - b[0] })\n .each(function () {\n self.offsets.push(this[0])\n self.targets.push(this[1])\n })\n }\n\n ScrollSpy.prototype.process = function () {\n var scrollTop = this.$scrollElement.scrollTop() + this.options.offset\n var scrollHeight = this.getScrollHeight()\n var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()\n var offsets = this.offsets\n var targets = this.targets\n var activeTarget = this.activeTarget\n var i\n\n if (this.scrollHeight != scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n }\n\n if (activeTarget && scrollTop < offsets[0]) {\n this.activeTarget = null\n return this.clear()\n }\n\n for (i = offsets.length; i--;) {\n activeTarget != targets[i]\n && scrollTop >= offsets[i]\n && (!offsets[i + 1] || scrollTop <= offsets[i + 1])\n && this.activate(targets[i])\n }\n }\n\n ScrollSpy.prototype.activate = function (target) {\n this.activeTarget = target\n\n this.clear()\n\n var selector = this.selector +\n '[data-target=\"' + target + '\"],' +\n this.selector + '[href=\"' + target + '\"]'\n\n var active = $(selector)\n .parents('li')\n .addClass('active')\n\n if (active.parent('.dropdown-menu').length) {\n active = active\n .closest('li.dropdown')\n .addClass('active')\n }\n\n active.trigger('activate.bs.scrollspy')\n }\n\n ScrollSpy.prototype.clear = function () {\n $(this.selector)\n .parentsUntil(this.options.target, '.active')\n .removeClass('active')\n }\n\n\n // SCROLLSPY PLUGIN DEFINITION\n // ===========================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.scrollspy')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.scrollspy\n\n $.fn.scrollspy = Plugin\n $.fn.scrollspy.Constructor = ScrollSpy\n\n\n // SCROLLSPY NO CONFLICT\n // =====================\n\n $.fn.scrollspy.noConflict = function () {\n $.fn.scrollspy = old\n return this\n }\n\n\n // SCROLLSPY DATA-API\n // ==================\n\n $(window).on('load.bs.scrollspy.data-api', function () {\n $('[data-spy=\"scroll\"]').each(function () {\n var $spy = $(this)\n Plugin.call($spy, $spy.data())\n })\n })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.1\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // TAB CLASS DEFINITION\n // ====================\n\n var Tab = function (element) {\n this.element = $(element)\n }\n\n Tab.VERSION = '3.3.1'\n\n Tab.TRANSITION_DURATION = 150\n\n Tab.prototype.show = function () {\n var $this = this.element\n var $ul = $this.closest('ul:not(.dropdown-menu)')\n var selector = $this.data('target')\n\n if (!selector) {\n selector = $this.attr('href')\n selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n }\n\n if ($this.parent('li').hasClass('active')) return\n\n var $previous = $ul.find('.active:last a')\n var hideEvent = $.Event('hide.bs.tab', {\n relatedTarget: $this[0]\n })\n var showEvent = $.Event('show.bs.tab', {\n relatedTarget: $previous[0]\n })\n\n $previous.trigger(hideEvent)\n $this.trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n var $target = $(selector)\n\n this.activate($this.closest('li'), $ul)\n this.activate($target, $target.parent(), function () {\n $previous.trigger({\n type: 'hidden.bs.tab',\n relatedTarget: $this[0]\n })\n $this.trigger({\n type: 'shown.bs.tab',\n relatedTarget: $previous[0]\n })\n })\n }\n\n Tab.prototype.activate = function (element, container, callback) {\n var $active = container.find('> .active')\n var transition = callback\n && $.support.transition\n && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)\n\n function next() {\n $active\n .removeClass('active')\n .find('> .dropdown-menu > .active')\n .removeClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', false)\n\n element\n .addClass('active')\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n\n if (transition) {\n element[0].offsetWidth // reflow for transition\n element.addClass('in')\n } else {\n element.removeClass('fade')\n }\n\n if (element.parent('.dropdown-menu')) {\n element\n .closest('li.dropdown')\n .addClass('active')\n .end()\n .find('[data-toggle=\"tab\"]')\n .attr('aria-expanded', true)\n }\n\n callback && callback()\n }\n\n $active.length && transition ?\n $active\n .one('bsTransitionEnd', next)\n .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n next()\n\n $active.removeClass('in')\n }\n\n\n // TAB PLUGIN DEFINITION\n // =====================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.tab')\n\n if (!data) $this.data('bs.tab', (data = new Tab(this)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.tab\n\n $.fn.tab = Plugin\n $.fn.tab.Constructor = Tab\n\n\n // TAB NO CONFLICT\n // ===============\n\n $.fn.tab.noConflict = function () {\n $.fn.tab = old\n return this\n }\n\n\n // TAB DATA-API\n // ============\n\n var clickHandler = function (e) {\n e.preventDefault()\n Plugin.call($(this), 'show')\n }\n\n $(document)\n .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.1\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n 'use strict';\n\n // AFFIX CLASS DEFINITION\n // ======================\n\n var Affix = function (element, options) {\n this.options = $.extend({}, Affix.DEFAULTS, options)\n\n this.$target = $(this.options.target)\n .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))\n\n this.$element = $(element)\n this.affixed =\n this.unpin =\n this.pinnedOffset = null\n\n this.checkPosition()\n }\n\n Affix.VERSION = '3.3.1'\n\n Affix.RESET = 'affix affix-top affix-bottom'\n\n Affix.DEFAULTS = {\n offset: 0,\n target: window\n }\n\n Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n var targetHeight = this.$target.height()\n\n if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n if (this.affixed == 'bottom') {\n if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n }\n\n var initializing = this.affixed == null\n var colliderTop = initializing ? scrollTop : position.top\n var colliderHeight = initializing ? targetHeight : height\n\n if (offsetTop != null && colliderTop <= offsetTop) return 'top'\n if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n return false\n }\n\n Affix.prototype.getPinnedOffset = function () {\n if (this.pinnedOffset) return this.pinnedOffset\n this.$element.removeClass(Affix.RESET).addClass('affix')\n var scrollTop = this.$target.scrollTop()\n var position = this.$element.offset()\n return (this.pinnedOffset = position.top - scrollTop)\n }\n\n Affix.prototype.checkPositionWithEventLoop = function () {\n setTimeout($.proxy(this.checkPosition, this), 1)\n }\n\n Affix.prototype.checkPosition = function () {\n if (!this.$element.is(':visible')) return\n\n var height = this.$element.height()\n var offset = this.options.offset\n var offsetTop = offset.top\n var offsetBottom = offset.bottom\n var scrollHeight = $('body').height()\n\n if (typeof offset != 'object') offsetBottom = offsetTop = offset\n if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)\n if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n if (this.affixed != affix) {\n if (this.unpin != null) this.$element.css('top', '')\n\n var affixType = 'affix' + (affix ? '-' + affix : '')\n var e = $.Event(affixType + '.bs.affix')\n\n this.$element.trigger(e)\n\n if (e.isDefaultPrevented()) return\n\n this.affixed = affix\n this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n this.$element\n .removeClass(Affix.RESET)\n .addClass(affixType)\n .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n }\n\n if (affix == 'bottom') {\n this.$element.offset({\n top: scrollHeight - height - offsetBottom\n })\n }\n }\n\n\n // AFFIX PLUGIN DEFINITION\n // =======================\n\n function Plugin(option) {\n return this.each(function () {\n var $this = $(this)\n var data = $this.data('bs.affix')\n var options = typeof option == 'object' && option\n\n if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n if (typeof option == 'string') data[option]()\n })\n }\n\n var old = $.fn.affix\n\n $.fn.affix = Plugin\n $.fn.affix.Constructor = Affix\n\n\n // AFFIX NO CONFLICT\n // =================\n\n $.fn.affix.noConflict = function () {\n $.fn.affix = old\n return this\n }\n\n\n // AFFIX DATA-API\n // ==============\n\n $(window).on('load', function () {\n $('[data-spy=\"affix\"]').each(function () {\n var $spy = $(this)\n var data = $spy.data()\n\n data.offset = data.offset || {}\n\n if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n if (data.offsetTop != null) data.offset.top = data.offsetTop\n\n Plugin.call($spy, data)\n })\n })\n\n}(jQuery);\n","/*!\n * jQuery JavaScript Library v1.11.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:19Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.3\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"\" +\n\t\t\t\t\"\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t// but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: ) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n * selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n * selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"
a\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG