diff --git a/dist/fonts/OpenSans-Light.eot b/dist/fonts/OpenSans-Light.eot new file mode 100644 index 0000000..725db50 Binary files /dev/null and b/dist/fonts/OpenSans-Light.eot differ diff --git a/dist/fonts/OpenSans-Light.svg b/dist/fonts/OpenSans-Light.svg new file mode 100644 index 0000000..b6daf10 --- /dev/null +++ b/dist/fonts/OpenSans-Light.svg @@ -0,0 +1,581 @@ + + + + +Created by FontForge 20110222 at Thu May 12 12:49:24 2011 + By www-data +Digitized data copyright (c) 2010-2011, Google Corporation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dist/fonts/OpenSans-Light.ttf b/dist/fonts/OpenSans-Light.ttf new file mode 100644 index 0000000..3d29b04 Binary files /dev/null and b/dist/fonts/OpenSans-Light.ttf differ diff --git a/dist/fonts/taiga.eot b/dist/fonts/taiga.eot index 39b73c7..f8cdfc9 100644 Binary files a/dist/fonts/taiga.eot and b/dist/fonts/taiga.eot differ diff --git a/dist/fonts/taiga.svg b/dist/fonts/taiga.svg index 018e647..435c7a9 100644 --- a/dist/fonts/taiga.svg +++ b/dist/fonts/taiga.svg @@ -30,16 +30,13 @@ - - - @@ -49,7 +46,6 @@ - @@ -59,4 +55,9 @@ + + + + + diff --git a/dist/fonts/taiga.ttf b/dist/fonts/taiga.ttf index 6b27df5..67c906c 100644 Binary files a/dist/fonts/taiga.ttf and b/dist/fonts/taiga.ttf differ diff --git a/dist/fonts/taiga.woff b/dist/fonts/taiga.woff index 48f74d8..5c346f3 100644 Binary files a/dist/fonts/taiga.woff and b/dist/fonts/taiga.woff differ diff --git a/dist/images/github-help.png b/dist/images/github-help.png deleted file mode 100644 index 795fd9f..0000000 Binary files a/dist/images/github-help.png and /dev/null differ diff --git a/dist/images/logo-color.png b/dist/images/logo-color.png new file mode 100644 index 0000000..74b8c04 Binary files /dev/null and b/dist/images/logo-color.png differ diff --git a/dist/images/menu-vert.png b/dist/images/menu-vert.png new file mode 100644 index 0000000..81db59e Binary files /dev/null and b/dist/images/menu-vert.png differ diff --git a/dist/images/quote.png b/dist/images/quote.png new file mode 100644 index 0000000..dd6d973 Binary files /dev/null and b/dist/images/quote.png differ diff --git a/dist/index.html b/dist/index.html index 52f0232..a755bc7 100644 --- a/dist/index.html +++ b/dist/index.html @@ -2,92 +2,21 @@ - Taiga - - + + + Taiga + + + -
-
-

-
-
-
-
-
-
-

-

-
-
-
-
- - -

{{ template.description }}

-
-
-
-
-
-
-
-

-

-
-
-
-
- -
-
- -
-
-
- -
- -
-
-
-
-
-
-
- -
-
-
-
-
-
- - -
-
-

-

-
-
-
-
-
-

-

-
-
-
-
-

-

-
-
+
- -

- - - +
+
+

+

+
+
+
+
+
+

+

+
+
+
+
+

+

+
+
+ + + \ No newline at end of file diff --git a/dist/js/app-loader.js b/dist/js/app-loader.js index d164025..9421cb6 100644 --- a/dist/js/app-loader.js +++ b/dist/js/app-loader.js @@ -1,7 +1,7 @@ (function() { var promise, version; - version = 1432563821968; + version = 1434623906290; window.taigaConfig = { "api": "http://localhost:8000/api/v1/", diff --git a/dist/js/app.js b/dist/js/app.js index 7060caa..fb00579 100644 --- a/dist/js/app.js +++ b/dist/js/app.js @@ -46,50 +46,81 @@ taiga.sessionId = taiga.generateUniqueSessionIdentifier(); - configure = function($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider, tgLoaderProvider, $compileProvider, $translateProvider) { - var authHttpIntercept, defaultHeaders, preferedLangCode, userInfo, versionCheckHttpIntercept; + configure = function($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider, $compileProvider, $translateProvider) { + var authHttpIntercept, defaultHeaders, loaderIntercept, originalWhen, preferedLangCode, userInfo, versionCheckHttpIntercept; + originalWhen = $routeProvider.when; + $routeProvider.when = function(path, route) { + route.resolve || (route.resolve = {}); + angular.extend(route.resolve, { + languageLoad: [ + "$q", "$translate", function($q, $translate) { + var deferred; + deferred = $q.defer(); + $translate().then(function() { + return deferred.resolve(); + }); + return deferred.promise; + } + ] + }); + return originalWhen.call($routeProvider, path, route); + }; $routeProvider.when("/", { - templateUrl: "project/projects.html", - resolve: { - loader: tgLoaderProvider.add() - } + templateUrl: "home/home.html", + access: { + requiresLogin: true + }, + title: "HOME.PAGE_TITLE", + description: "HOME.PAGE_DESCRIPTION", + loader: true + }); + $routeProvider.when("/projects/", { + templateUrl: "projects/listing/projects-listing.html", + access: { + requiresLogin: true + }, + title: "PROJECTS.PAGE_TITLE", + description: "PROJECTS.PAGE_DESCRIPTION", + loader: true, + controller: "ProjectsListing", + controllerAs: "vm" }); $routeProvider.when("/project/:pslug/", { - templateUrl: "project/project.html" + templateUrl: "projects/project/project.html", + loader: true, + controller: "Project", + controllerAs: "vm", + section: "project-timeline" }); $routeProvider.when("/project/:pslug/search", { templateUrl: "search/search.html", - reloadOnSearch: false + reloadOnSearch: false, + section: "search" }); $routeProvider.when("/project/:pslug/backlog", { templateUrl: "backlog/backlog.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "backlog" }); $routeProvider.when("/project/:pslug/kanban", { templateUrl: "kanban/kanban.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "kanban" }); $routeProvider.when("/project/:pslug/taskboard/:sslug", { templateUrl: "taskboard/taskboard.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "backlog" }); $routeProvider.when("/project/:pslug/us/:usref", { templateUrl: "us/us-detail.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "backlog-kanban" }); $routeProvider.when("/project/:pslug/task/:taskref", { templateUrl: "task/task-detail.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "backlog-kanban" }); $routeProvider.when("/project/:pslug/wiki", { redirectTo: function(params) { @@ -98,92 +129,102 @@ }); $routeProvider.when("/project/:pslug/wiki/:slug", { templateUrl: "wiki/wiki.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "wiki" }); $routeProvider.when("/project/:pslug/team", { templateUrl: "team/team.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "team" }); $routeProvider.when("/project/:pslug/issues", { templateUrl: "issue/issues.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "issues" }); $routeProvider.when("/project/:pslug/issue/:issueref", { templateUrl: "issue/issues-detail.html", - resolve: { - loader: tgLoaderProvider.add() - } + loader: true, + section: "issues" }); $routeProvider.when("/project/:pslug/admin/project-profile/details", { - templateUrl: "admin/admin-project-profile.html" + templateUrl: "admin/admin-project-profile.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-profile/default-values", { - templateUrl: "admin/admin-project-default-values.html" + templateUrl: "admin/admin-project-default-values.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-profile/modules", { - templateUrl: "admin/admin-project-modules.html" + templateUrl: "admin/admin-project-modules.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-profile/export", { - templateUrl: "admin/admin-project-export.html" + templateUrl: "admin/admin-project-export.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-profile/reports", { - templateUrl: "admin/admin-project-reports.html" + templateUrl: "admin/admin-project-reports.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-values/status", { - templateUrl: "admin/admin-project-values-status.html" + templateUrl: "admin/admin-project-values-status.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-values/points", { - templateUrl: "admin/admin-project-values-points.html" + templateUrl: "admin/admin-project-values-points.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-values/priorities", { - templateUrl: "admin/admin-project-values-priorities.html" + templateUrl: "admin/admin-project-values-priorities.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-values/severities", { - templateUrl: "admin/admin-project-values-severities.html" + templateUrl: "admin/admin-project-values-severities.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-values/types", { - templateUrl: "admin/admin-project-values-types.html" + templateUrl: "admin/admin-project-values-types.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/project-values/custom-fields", { - templateUrl: "admin/admin-project-values-custom-fields.html" + templateUrl: "admin/admin-project-values-custom-fields.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/memberships", { - templateUrl: "admin/admin-memberships.html" + templateUrl: "admin/admin-memberships.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/roles", { - templateUrl: "admin/admin-roles.html" + templateUrl: "admin/admin-roles.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/third-parties/webhooks", { - templateUrl: "admin/admin-third-parties-webhooks.html" + templateUrl: "admin/admin-third-parties-webhooks.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/third-parties/github", { - templateUrl: "admin/admin-third-parties-github.html" + templateUrl: "admin/admin-third-parties-github.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/third-parties/gitlab", { - templateUrl: "admin/admin-third-parties-gitlab.html" + templateUrl: "admin/admin-third-parties-gitlab.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/third-parties/bitbucket", { - templateUrl: "admin/admin-third-parties-bitbucket.html" + templateUrl: "admin/admin-third-parties-bitbucket.html", + section: "admin" }); $routeProvider.when("/project/:pslug/admin/contrib/:plugin", { templateUrl: "contrib/main.html" }); - $routeProvider.when("/project/:pslug/user-settings/user-profile", { + $routeProvider.when("/user-settings/user-profile", { templateUrl: "user/user-profile.html" }); - $routeProvider.when("/project/:pslug/user-settings/user-change-password", { + $routeProvider.when("/user-settings/user-change-password", { templateUrl: "user/user-change-password.html" }); - $routeProvider.when("/project/:pslug/user-settings/user-avatar", { - templateUrl: "user/user-avatar.html" - }); - $routeProvider.when("/project/:pslug/user-settings/mail-notifications", { + $routeProvider.when("/user-settings/mail-notifications", { templateUrl: "user/mail-notifications.html" }); $routeProvider.when("/change-email/:email_token", { @@ -192,23 +233,50 @@ $routeProvider.when("/cancel-account/:cancel_token", { templateUrl: "user/cancel-account.html" }); + $routeProvider.when("/profile", { + templateUrl: "profile/profile.html", + loader: true, + access: { + requiresLogin: true + }, + controller: "Profile", + controllerAs: "vm" + }); + $routeProvider.when("/profile/:slug", { + templateUrl: "profile/profile.html", + loader: true, + controller: "Profile", + controllerAs: "vm" + }); $routeProvider.when("/login", { - templateUrl: "auth/login.html" + templateUrl: "auth/login.html", + title: "LOGIN.PAGE_TITLE", + description: "LOGIN.PAGE_DESCRIPTION" }); $routeProvider.when("/register", { - templateUrl: "auth/register.html" + templateUrl: "auth/register.html", + title: "REGISTER.PAGE_TITLE", + description: "REGISTER.PAGE_DESCRIPTION" }); $routeProvider.when("/forgot-password", { - templateUrl: "auth/forgot-password.html" + templateUrl: "auth/forgot-password.html", + title: "FORGOT_PASSWORD.PAGE_TITLE", + description: "FORGOT_PASSWORD.PAGE_DESCRIPTION" }); $routeProvider.when("/change-password", { - templateUrl: "auth/change-password-from-recovery.html" + templateUrl: "auth/change-password-from-recovery.html", + title: "CHANGE_PASSWORD.PAGE_TITLE", + description: "CHANGE_PASSWORD.PAGE_TITLE" }); $routeProvider.when("/change-password/:token", { - templateUrl: "auth/change-password-from-recovery.html" + templateUrl: "auth/change-password-from-recovery.html", + title: "CHANGE_PASSWORD.PAGE_TITLE", + description: "CHANGE_PASSWORD.PAGE_TITLE" }); $routeProvider.when("/invitation/:token", { - templateUrl: "auth/invitation.html" + templateUrl: "auth/invitation.html", + title: "INVITATION.PAGE_TITLE", + description: "INVITATION.PAGE_DESCRIPTION" }); $routeProvider.when("/error", { templateUrl: "error/error.html" @@ -238,6 +306,7 @@ $httpProvider.defaults.headers.get = { "X-Session-Id": taiga.sessionId }; + $httpProvider.useApplyAsync(true); $tgEventsProvider.setSessionId(taiga.sessionId); authHttpIntercept = function($q, $location, $navUrls, $lightboxService) { var httpResponseError; @@ -259,6 +328,28 @@ }; $provide.factory("authHttpIntercept", ["$q", "$location", "$tgNavUrls", "lightboxService", authHttpIntercept]); $httpProvider.interceptors.push("authHttpIntercept"); + loaderIntercept = function($q, loaderService) { + return { + request: function(config) { + loaderService.logRequest(); + return config; + }, + requestError: function(rejection) { + loaderService.logResponse(); + return $q.reject(rejection); + }, + responseError: function(rejection) { + loaderService.logResponse(); + return $q.reject(rejection); + }, + response: function(response) { + loaderService.logResponse(); + return response; + } + }; + }; + $provide.factory("loaderIntercept", ["$q", "tgLoader", loaderIntercept]); + $httpProvider.interceptors.push("loaderIntercept"); versionCheckHttpIntercept = function($q) { var httpResponseError; httpResponseError = function(response) { @@ -340,8 +431,8 @@ return checksley.updateMessages('default', messages); }; - init = function($log, $config, $rootscope, $auth, $events, $analytics, $translate) { - var user; + init = function($log, $rootscope, $auth, $events, $analytics, $translate, $location, $navUrls, appMetaService, projectService, loaderService) { + var un, user; $log.debug("Initialize application"); $rootscope.contribPlugins = this.taigaContribPlugins; $rootscope.adminPlugins = _.where(this.taigaContribPlugins, { @@ -352,22 +443,53 @@ lang = ctx.language; return i18nInit(lang, $translate); }); + Promise.setScheduler(function(cb) { + return $rootscope.$evalAsync(cb); + }); if ($auth.isAuthenticated()) { $events.setupConnection(); user = $auth.getUser(); } - return $analytics.initialize(); + $analytics.initialize(); + un = $rootscope.$on('$routeChangeStart', function(event, next) { + if (next.loader) { + loaderService.start(true); + } + return un(); + }); + return $rootscope.$on('$routeChangeSuccess', function(event, next) { + var description, title; + if (next.loader) { + loaderService.start(true); + } + if (next.access && next.access.requiresLogin) { + if (!$auth.isAuthenticated()) { + $location.path($navUrls.resolve("login")); + } + } + projectService.setSection(next.section); + if (next.params.pslug) { + projectService.setProject(next.params.pslug); + } else { + projectService.cleanProject(); + } + if (next.title || next.description) { + title = $translate.instant(next.title || ""); + description = $translate.instant(next.description || ""); + return appMetaService.setAll(title, description); + } + }); }; - modules = ["taigaBase", "taigaCommon", "taigaResources", "taigaAuth", "taigaEvents", "taigaRelatedTasks", "taigaBacklog", "taigaTaskboard", "taigaKanban", "taigaIssues", "taigaUserStories", "taigaTasks", "taigaTeam", "taigaWiki", "taigaSearch", "taigaAdmin", "taigaNavMenu", "taigaProject", "taigaUserSettings", "taigaFeedback", "taigaPlugins", "taigaIntegrations", "taigaComponents", "templates", "ngRoute", "ngAnimate", "pascalprecht.translate"].concat(_.map(this.taigaContribPlugins, function(plugin) { + modules = ["taigaBase", "taigaCommon", "taigaResources", "taigaResources2", "taigaAuth", "taigaEvents", "taigaHome", "taigaNavigationBar", "taigaProjects", "taigaRelatedTasks", "taigaBacklog", "taigaTaskboard", "taigaKanban", "taigaIssues", "taigaUserStories", "taigaTasks", "taigaTeam", "taigaWiki", "taigaSearch", "taigaAdmin", "taigaProject", "taigaUserSettings", "taigaFeedback", "taigaPlugins", "taigaIntegrations", "taigaComponents", "taigaProfile", "taigaHome", "taigaUserTimeline", "templates", "ngRoute", "ngAnimate", "pascalprecht.translate", "infinite-scroll", "tgRepeat"].concat(_.map(this.taigaContribPlugins, function(plugin) { return plugin.module; })); module = angular.module("taiga", modules); - module.config(["$routeProvider", "$locationProvider", "$httpProvider", "$provide", "$tgEventsProvider", "tgLoaderProvider", "$compileProvider", "$translateProvider", configure]); + module.config(["$routeProvider", "$locationProvider", "$httpProvider", "$provide", "$tgEventsProvider", "$compileProvider", "$translateProvider", configure]); - module.run(["$log", "$tgConfig", "$rootScope", "$tgAuth", "$tgEvents", "$tgAnalytics", "$translate", init]); + module.run(["$log", "$rootScope", "$tgAuth", "$tgEvents", "$tgAnalytics", "$translate", "$tgLocation", "$tgNavUrls", "tgAppMetaService", "tgProjectService", "tgLoader", init]); }).call(this); @@ -473,7 +595,7 @@ */ (function() { - var bindMethods, bindOnce, cancelTimeout, debounce, debounceLeading, groupBy, joinStr, mixOf, nl2br, scopeDefer, sizeFormat, slugify, startswith, taiga, timeout, toString, toggleText, trim, unslugify, + var bindMethods, bindOnce, cancelTimeout, debounce, debounceLeading, defineImmutableProperty, groupBy, joinStr, mixOf, nl2br, replaceTags, scopeDefer, sizeFormat, slugify, startswith, stripTags, taiga, timeout, toString, toggleText, trim, truncate, unslugify, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, slice = [].slice, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, @@ -632,6 +754,23 @@ return _.str.startsWith(str1, str2); }; + truncate = function(str, maxLength, suffix) { + var out; + if (suffix == null) { + suffix = "..."; + } + if ((typeof str !== "string") && !(str instanceof String)) { + return str; + } + out = str.slice(0); + if (out.length > maxLength) { + out = out.substring(0, maxLength + 1); + out = out.substring(0, Math.min(out.length, out.lastIndexOf(" "))); + out = out + suffix; + } + return out; + }; + sizeFormat = function(input, precision) { var number, size, units; if (precision == null) { @@ -652,6 +791,45 @@ return size + " " + units[number]; }; + stripTags = function(str, exception) { + var pattern; + if (exception) { + pattern = new RegExp('<(?!' + exception + '\s*\/?)[^>]+>', 'gi'); + return String(str).replace(pattern, ''); + } else { + return String(str).replace(/<\/?[^>]+>/g, ''); + } + }; + + replaceTags = function(str, tags, replace) { + var pattern; + pattern = new RegExp('<(' + tags + ')>', 'gi'); + str = str.replace(pattern, '<' + replace + '>'); + pattern = new RegExp('<\/(' + tags + ')>', 'gi'); + str = str.replace(pattern, ''); + return str; + }; + + defineImmutableProperty = (function(_this) { + return function(obj, name, fn) { + return Object.defineProperty(obj, name, { + get: function() { + var fn_result; + if (!_.isFunction(fn)) { + throw "defineImmutableProperty third param must be a function"; + } + fn_result = fn(); + if (fn_result && _.isObject(fn_result)) { + if (fn_result.size === void 0) { + throw "defineImmutableProperty must return immutable data"; + } + } + return fn_result; + } + }); + }; + })(this); + taiga = this.taiga; taiga.nl2br = nl2br; @@ -682,6 +860,8 @@ taiga.joinStr = joinStr; + taiga.truncate = truncate; + taiga.debounce = debounce; taiga.debounceLeading = debounceLeading; @@ -690,6 +870,12 @@ taiga.sizeFormat = sizeFormat; + taiga.stripTags = stripTags; + + taiga.replaceTags = replaceTags; + + taiga.defineImmutableProperty = defineImmutableProperty; + }).call(this); @@ -915,9 +1101,10 @@ AuthService = (function(superClass) { extend(AuthService, superClass); - AuthService.$inject = ["$rootScope", "$tgStorage", "$tgModel", "$tgResources", "$tgHttp", "$tgUrls", "$tgConfig", "$translate"]; + AuthService.$inject = ["$rootScope", "$tgStorage", "$tgModel", "$tgResources", "$tgHttp", "$tgUrls", "$tgConfig", "$translate", "tgCurrentUserService"]; - function AuthService(rootscope, storage, model, rs, http, urls, config, translate) { + function AuthService(rootscope, storage, model, rs, http, urls, config, translate, currentUserService) { + var userModel; this.rootscope = rootscope; this.storage = storage; this.model = model; @@ -926,12 +1113,25 @@ this.urls = urls; this.config = config; this.translate = translate; + this.currentUserService = currentUserService; AuthService.__super__.constructor.call(this); + userModel = this.getUser(); + this.setUserdata(userModel); } + AuthService.prototype.setUserdata = function(userModel) { + if (userModel) { + this.userData = Immutable.fromJS(userModel.getAttrs()); + return this.currentUserService.setUser(this.userData); + } else { + return this.userData = null; + } + }; + AuthService.prototype._setLocales = function() { var lang; lang = this.rootscope.user.lang || this.config.get("defaultLanguage") || "en"; + this.translate.preferredLanguage(lang); return this.translate.use(lang); }; @@ -954,6 +1154,7 @@ this.rootscope.auth = user; this.storage.set("userInfo", user.getAttrs()); this.rootscope.user = user; + this.setUserdata(user); return this._setLocales(); }; @@ -1001,7 +1202,8 @@ AuthService.prototype.logout = function() { this.removeToken(); - return this.clear(); + this.clear(); + return this.currentUserService.removeUser(); }; AuthService.prototype.register = function(data, type, existing) { @@ -1128,7 +1330,11 @@ return promise.then(onSuccess, onError); }; })(this)); - return $el.on("submit", "form", submit); + $el.on("submit", "form", submit); + window.prerenderReady = true; + return $scope.$on("$destroy", function() { + return $el.off(); + }); }; return { link: link @@ -1156,9 +1362,11 @@ }; onErrorSubmit = function(response) { var text; - if (response.data._error_message != null) { - text = $translate.instant("LOGIN_FORM.ERROR_GENERIC") + " " + response.data._error_message; - $confirm.notify("light-error", text + " " + response.data._error_message); + if (response.data._error_message) { + text = $translate.instant("COMMON.GENERIC_ERROR", { + error: response.data._error_message + }); + $confirm.notify("light-error", text); } return form.setErrors(response.data); }; @@ -1173,7 +1381,11 @@ return promise.then(onSuccessSubmit, onErrorSubmit); }; })(this)); - return $el.on("submit", "form", submit); + $el.on("submit", "form", submit); + $scope.$on("$destroy", function() { + return $el.off(); + }); + return window.prerenderReady = true; }; return { link: link @@ -1210,7 +1422,11 @@ return promise.then(onSuccessSubmit, onErrorSubmit); }; })(this)); - return $el.on("submit", "form", submit); + $el.on("submit", "form", submit); + $scope.$on("$destroy", function() { + return $el.off(); + }); + return window.prerenderReady = true; }; return { link: link @@ -1255,7 +1471,10 @@ return promise.then(onSuccessSubmit, onErrorSubmit); }; })(this)); - return $el.on("submit", "form", submit); + $el.on("submit", "form", submit); + return $scope.$on("$destroy", function() { + return $el.off(); + }); }; return { link: link @@ -1316,7 +1535,9 @@ $scope.dataRegister = { token: token }; - registerForm = $el.find("form.register-form").checksley(); + registerForm = $el.find("form.register-form").checksley({ + onlyOneErrorElement: true + }); onSuccessSubmitRegister = function(response) { $analytics.trackEvent("auth", "invitationAccept", "invitation accept with new user", 1); $location.path($navUrls.resolve("project", { @@ -1326,8 +1547,13 @@ }; onErrorSubmitRegister = function(response) { var text; - text = $translate.instant("LOGIN_FORM.ERROR_AUTH_INCORRECT"); - return $confirm.notify("light-error", text); + if (response.data._error_message) { + text = $translate.instant("COMMON.GENERIC_ERROR", { + error: response.data._error_message + }); + $confirm.notify("light-error", text); + } + return registerForm.setErrors(response.data); }; submitRegister = debounce(2000, (function(_this) { return function(event) { @@ -1340,7 +1566,10 @@ }; })(this)); $el.on("submit", "form.register-form", submitRegister); - return $el.on("click", ".button-register", submitRegister); + $el.on("click", ".button-register", submitRegister); + return $scope.$on("$destroy", function() { + return $el.off(); + }); }; return { link: link @@ -1357,15 +1586,19 @@ $scope.data.email_token = $params.email_token; form = $el.find("form").checksley(); onSuccessSubmit = function(response) { - return $repo.queryOne("users", $auth.getUser().id).then((function(_this) { - return function(data) { - var text; - $auth.setUser(data); - $location.path($navUrls.resolve("home")); - text = $translate.instant("CHANGE_EMAIL_FORM.SUCCESS"); - return $confirm.success(text); - }; - })(this)); + var text; + if ($auth.isAuthenticated()) { + $repo.queryOne("users", $auth.getUser().id).then((function(_this) { + return function(data) { + $auth.setUser(data); + return $location.path($navUrls.resolve("home")); + }; + })(this)); + } else { + $location.path($navUrls.resolve("login")); + } + text = $translate.instant("CHANGE_EMAIL_FORM.SUCCESS"); + return $confirm.success(text); }; onErrorSubmit = function(response) { var text; @@ -1386,10 +1619,13 @@ event.preventDefault(); return submit(); }); - return $el.on("click", "a.button-change-email", function(event) { + $el.on("click", "a.button-change-email", function(event) { event.preventDefault(); return submit(); }); + return $scope.$on("$destroy", function() { + return $el.off(); + }); }; return { link: link @@ -1430,7 +1666,10 @@ return promise.then(onSuccessSubmit, onErrorSubmit); }; })(this)); - return $el.on("submit", "form", submit); + $el.on("submit", "form", submit); + return $scope.$on("$destroy", function() { + return $el.off(); + }); }; return { link: link @@ -1519,6 +1758,7 @@ urls = { "home": "/", + "projects": "/projects", "error": "/error", "not-found": "/not-found", "permission-denied": "/permission-denied", @@ -1530,7 +1770,8 @@ "register": "/register", "invitation": "/invitation/:token", "create-project": "/create-project", - "profile": "/:user", + "profile": "/profile", + "user-profile": "/profile/:username", "project": "/project/:project", "project-backlog": "/project/:project/backlog", "project-taskboard": "/project/:project/taskboard/:sprint", @@ -1562,10 +1803,10 @@ "project-admin-third-parties-gitlab": "/project/:project/admin/third-parties/gitlab", "project-admin-third-parties-bitbucket": "/project/:project/admin/third-parties/bitbucket", "project-admin-contrib": "/project/:project/admin/contrib/:plugin", - "user-settings-user-profile": "/project/:project/user-settings/user-profile", - "user-settings-user-change-password": "/project/:project/user-settings/user-change-password", - "user-settings-user-avatar": "/project/:project/user-settings/user-avatar", - "user-settings-mail-notifications": "/project/:project/user-settings/mail-notifications" + "user-settings-user-profile": "/user-settings/user-profile", + "user-settings-user-change-password": "/user-settings/user-change-password", + "user-settings-user-avatar": "/user-settings/user-avatar", + "user-settings-mail-notifications": "/user-settings/mail-notifications" }; init = function($log, $navurls) { @@ -1600,7 +1841,7 @@ */ (function() { - var AnimationFrame, AppTitle, CheckPermissionDirective, ClassPermissionDirective, LimitLineLengthDirective, ProjectUrl, Qqueue, SelectedText, Template, ToggleCommentDirective, module, taiga, + var AnimationFrame, CheckPermissionDirective, ClassPermissionDirective, LimitLineLengthDirective, ProjectUrl, Qqueue, SelectedText, Template, ToggleCommentDirective, module, taiga, slice = [].slice; taiga = this.taiga; @@ -1741,18 +1982,6 @@ module.directive("tgToggleComment", ToggleCommentDirective); - AppTitle = function() { - var set; - set = function(text) { - return $("title").text(text); - }; - return { - set: set - }; - }; - - module.factory("$appTitle", AppTitle); - ProjectUrl = function($navurls) { var get; get = function(project) { @@ -2113,10 +2342,10 @@ module = angular.module("taigaFeedback", []); - FeedbackDirective = function($lightboxService, $repo, $confirm, $loading) { - var link; + FeedbackDirective = function($lightboxService, $repo, $confirm, $loading, feedbackService) { + var directive, link; link = function($scope, $el, $attrs) { - var form, submit, submitButton; + var form, openLightbox, submit, submitButton; form = $el.find("form").checksley(); submit = debounce(2000, (function(_this) { return function(event) { @@ -2140,23 +2369,25 @@ })(this)); submitButton = $el.find(".submit-button"); $el.on("submit", "form", submit); - $scope.$on("feedback:show", function() { - $scope.$apply(function() { - return $scope.feedback = {}; - }); + openLightbox = function() { + $scope.feedback = {}; $lightboxService.open($el); return $el.find("textarea").focus(); - }); - return $scope.$on("$destroy", function() { + }; + $scope.$on("$destroy", function() { return $el.off(); }); + return openLightbox(); }; - return { - link: link + directive = { + link: link, + templateUrl: "common/lightbox-feedback.html", + scope: {} }; + return directive; }; - module.directive("tgLbFeedback", ["lightboxService", "$tgRepo", "$tgConfirm", "$tgLoading", FeedbackDirective]); + module.directive("tgLbFeedback", ["lightboxService", "$tgRepo", "$tgConfirm", "$tgLoading", "tgFeedbackService", FeedbackDirective]); }).call(this); @@ -2248,336 +2479,6 @@ }).call(this); -/* - * Copyright (C) 2014 Andrey Antukh - * Copyright (C) 2014 Jesús Espino Garcia - * Copyright (C) 2014 David Barragán Merino -# - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. -# - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. -# - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . -# - * File: modules/nav.coffee - */ - -(function() { - var ProjectMenuDirective, ProjectsNavigationController, ProjectsNavigationDirective, bindOnce, groupBy, module, taiga, timeout, - extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - hasProp = {}.hasOwnProperty; - - taiga = this.taiga; - - groupBy = this.taiga.groupBy; - - bindOnce = this.taiga.bindOnce; - - timeout = this.taiga.timeout; - - module = angular.module("taigaNavMenu", []); - - ProjectsNavigationController = (function(superClass) { - extend(ProjectsNavigationController, superClass); - - ProjectsNavigationController.$inject = ["$scope", "$rootScope", "$tgResources", "$tgNavUrls", "$projectUrl"]; - - function ProjectsNavigationController(scope, rootscope, rs, navurls, projectUrl) { - var promise; - this.scope = scope; - this.rootscope = rootscope; - this.rs = rs; - this.navurls = navurls; - this.projectUrl = projectUrl; - promise = this.loadInitialData(); - promise.then(null, function() { - return console.log("FAIL"); - }); - this.scope.$on("projects:reload", (function(_this) { - return function() { - return _this.loadInitialData(); - }; - })(this)); - this.scope.$on("project:loaded", (function(_this) { - return function(ctx, project) { - return _this.loadInitialData(); - }; - })(this)); - } - - ProjectsNavigationController.prototype.loadInitialData = function() { - var ref; - return this.rs.projects.listByMember((ref = this.rootscope.user) != null ? ref.id : void 0).then((function(_this) { - return function(projects) { - var i, len, project; - for (i = 0, len = projects.length; i < len; i++) { - project = projects[i]; - project.url = _this.projectUrl.get(project); - } - _this.scope.projects = projects; - _this.scope.filteredProjects = projects; - _this.scope.filterText = ""; - return projects; - }; - })(this)); - }; - - ProjectsNavigationController.prototype.newProject = function() { - return this.scope.$apply((function(_this) { - return function() { - return _this.rootscope.$broadcast("projects:create"); - }; - })(this)); - }; - - ProjectsNavigationController.prototype.filterProjects = function(text) { - this.scope.filteredProjects = _.filter(this.scope.projects, function(project) { - return project.name.toLowerCase().indexOf(text) > -1; - }); - this.scope.filterText = text; - return this.rootscope.$broadcast("projects:filtered"); - }; - - return ProjectsNavigationController; - - })(taiga.Controller); - - module.controller("ProjectsNavigationController", ProjectsNavigationController); - - ProjectsNavigationDirective = function($rootscope, animationFrame, $timeout, tgLoader, $location, $compile, $template) { - var baseTemplate, hideMenu, link, loadingStart, overlay, projectsTemplate; - baseTemplate = $template.get("project/project-navigation-base.html", true); - projectsTemplate = $template.get("project/project-navigation-list.html", true); - overlay = $(".projects-nav-overlay"); - loadingStart = 0; - hideMenu = function() { - var difftime, timeoutValue; - if (overlay.is(':visible')) { - difftime = new Date().getTime() - loadingStart; - timeoutValue = 0; - if (difftime < 1000) { - timeoutValue = 1000 - timeoutValue; - } - return timeout(timeoutValue, function() { - overlay.one('transitionend', function() { - $(document.body).removeClass("loading-project open-projects-nav closed-projects-nav").css("overflow-x", "visible"); - return overlay.hide(); - }); - $(document.body).addClass("closed-projects-nav"); - return tgLoader.disablePreventLoading(); - }); - } - }; - link = function($scope, $el, $attrs, $ctrls) { - var $ctrl, render, renderProjects; - $ctrl = $ctrls[0]; - $rootscope.$on("project:loaded", hideMenu); - renderProjects = function(projects) { - var html; - html = projectsTemplate({ - projects: projects - }); - $el.find(".projects-list").html(html); - return $scope.$emit("regenerate:project-pagination"); - }; - render = function(projects) { - $el.html($compile(baseTemplate())($scope)); - return renderProjects(projects); - }; - overlay.on('click', function() { - return hideMenu(); - }); - $(document).on('keydown', (function(_this) { - return function(e) { - var code; - code = e.keyCode ? e.keyCode : e.which; - if (code === 27) { - return hideMenu(); - } - }; - })(this)); - $scope.$on("nav:projects-list:open", function() { - if (!$(document.body).hasClass("open-projects-nav")) { - animationFrame.add((function(_this) { - return function() { - return overlay.show(); - }; - })(this)); - } - return animationFrame.add((function(_this) { - return function() { - return $(document.body).css("overflow-x", "hidden"); - }; - })(this), (function(_this) { - return function() { - return $(document.body).toggleClass("open-projects-nav"); - }; - })(this)); - }); - $el.on("click", ".projects-list > li > a", function(event) { - var currentUrl, nextUrl, target; - target = angular.element(event.currentTarget); - nextUrl = target.prop("href"); - currentUrl = $location.absUrl(); - if (nextUrl === currentUrl) { - hideMenu(); - return; - } - $(document.body).addClass('loading-project'); - tgLoader.preventLoading(); - return loadingStart = new Date().getTime(); - }); - $el.on("click", ".create-project-button", function(event) { - event.preventDefault(); - return $ctrl.newProject(); - }); - $el.on("keyup", ".search-project", function(event) { - var target; - target = angular.element(event.currentTarget); - return $ctrl.filterProjects(target.val()); - }); - $scope.$on("projects:filtered", function() { - return renderProjects($scope.filteredProjects); - }); - return $scope.$watch("projects", function(projects) { - if (projects != null) { - return render(projects); - } - }); - }; - return { - require: ["tgProjectsNav"], - controller: ProjectsNavigationController, - link: link - }; - }; - - module.directive("tgProjectsNav", ["$rootScope", "animationFrame", "$timeout", "tgLoader", "$tgLocation", "$compile", "$tgTemplate", ProjectsNavigationDirective]); - - ProjectMenuDirective = function($log, $compile, $auth, $rootscope, $tgAuth, $location, $navUrls, $config, $template) { - var getSectionName, link, mainTemplate, menuEntriesTemplate, renderMainMenu, renderMenuEntries, videoConferenceUrl; - menuEntriesTemplate = $template.get("project/project-menu.html", true); - mainTemplate = _.template("
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n taiga[beta]\n
\n
"); - getSectionName = function($el, sectionName, project) { - var oldSectionName, ref; - oldSectionName = (ref = $el.find("a.active").parent().attr("id")) != null ? ref.replace("nav-", "") : void 0; - if (sectionName === "backlog-kanban") { - if (oldSectionName === "backlog" || oldSectionName === "kanban") { - sectionName = oldSectionName; - } else if (project.is_backlog_activated && !project.is_kanban_activated) { - sectionName = "backlog"; - } else if (!project.is_backlog_activated && project.is_kanban_activated) { - sectionName = "kanban"; - } - } - return sectionName; - }; - renderMainMenu = function($el) { - var html; - html = mainTemplate({}); - return $el.html(html); - }; - renderMenuEntries = function($el, targetScope, project) { - var container, ctx, dom, sectionName; - if (project == null) { - project = {}; - } - container = $el.find(".menu-container"); - sectionName = getSectionName($el, targetScope.section, project); - ctx = { - user: $auth.getUser(), - project: project, - feedbackEnabled: $config.get("feedbackEnabled") - }; - dom = $compile(menuEntriesTemplate(ctx))(targetScope); - dom.find("a.active").removeClass("active"); - dom.find("#nav-" + sectionName + " > a").addClass("active"); - return container.replaceWith(dom); - }; - videoConferenceUrl = function(project) { - var baseUrl, url, urlFixer; - urlFixer = function(url) { - return url; - }; - if (project.videoconferences === "appear-in") { - baseUrl = "https://appear.in/"; - } else if (project.videoconferences === "talky") { - baseUrl = "https://talky.io/"; - } else if (project.videoconferences === "jitsi") { - baseUrl = "https://meet.jit.si/"; - urlFixer = function(url) { - return url.replace(/ /g, "").replace(/-/g, ""); - }; - } else { - return ""; - } - if (project.videoconferences_salt) { - url = project.slug + "-" + project.videoconferences_salt; - } else { - url = "" + project.slug; - } - url = urlFixer(url); - return baseUrl + url; - }; - link = function($scope, $el, $attrs, $ctrl) { - var project; - renderMainMenu($el); - project = null; - $el.on("click", ".logo", function(event) { - var target; - event.preventDefault(); - target = angular.element(event.currentTarget); - return $rootscope.$broadcast("nav:projects-list:open"); - }); - $el.on("click", ".user-settings .avatar", function(event) { - event.preventDefault(); - return $el.find(".user-settings .popover").popover().open(); - }); - $el.on("click", ".logout", function(event) { - event.preventDefault(); - $auth.logout(); - return $scope.$apply(function() { - return $location.path($navUrls.resolve("login")); - }); - }); - $el.on("click", "#nav-search > a", function(event) { - event.preventDefault(); - return $rootscope.$broadcast("search-box:show", project); - }); - $el.on("click", ".feedback", function(event) { - event.preventDefault(); - return $rootscope.$broadcast("feedback:show"); - }); - $scope.$on("projects:loaded", function(listener) { - $el.addClass("hidden"); - return listener.stopPropagation(); - }); - return $scope.$on("project:loaded", function(ctx, newProject) { - project = newProject; - if ($el.hasClass("hidden")) { - $el.removeClass("hidden"); - } - project.videoconferenceUrl = videoConferenceUrl(project); - return renderMenuEntries($el, ctx.targetScope, project); - }); - }; - return { - link: link - }; - }; - - module.directive("tgProjectMenu", ["$log", "$compile", "$tgAuth", "$rootScope", "$tgAuth", "$tgLocation", "$tgNavUrls", "$tgConfig", "$tgTemplate", ProjectMenuDirective]); - -}).call(this); - - /* * Copyright (C) 2014 Andrey Antukh * Copyright (C) 2014 Jesús Espino Garcia @@ -2993,11 +2894,15 @@ "auth-register": "/auth/register", "invitations": "/invitations", "users": "/users", + "by_username": "/users/by_username", "users-password-recovery": "/users/password_recovery", "users-change-password-from-recovery": "/users/change_password_from_recovery", "users-change-password": "/users/change_password", "users-change-email": "/users/change_email", "users-cancel-account": "/users/cancel", + "contacts": "/users/%s/contacts", + "stats": "/users/%s/stats", + "permissions": "/permissions", "notify-policies": "/notify-policies", "user-storage": "/user-storage", "memberships": "/memberships", @@ -3008,6 +2913,7 @@ "projects": "/projects", "project-templates": "/project-templates", "project-modules": "/projects/%s/modules", + "bulk-update-projects-order": "/projects/bulk_update_order", "userstory-statuses": "/userstory-statuses", "points": "/points", "task-statuses": "/task-statuses", @@ -3050,6 +2956,9 @@ "userstories-csv": "/userstories/csv?uuid=%s", "tasks-csv": "/tasks/csv?uuid=%s", "issues-csv": "/issues/csv?uuid=%s", + "timeline-profile": "/timeline/profile", + "timeline-user": "/timeline/user", + "timeline-project": "/timeline/project", "search": "/search", "exporter": "/exporter", "importer": "/importer/load_dump", @@ -3080,7 +2989,7 @@ module.run(["$log", "$tgUrls", initUrls]); - module.run(["$log", "$tgResources", "$tgProjectsResourcesProvider", "$tgCustomAttributesResourcesProvider", "$tgCustomAttributesValuesResourcesProvider", "$tgMembershipsResourcesProvider", "$tgNotifyPoliciesResourcesProvider", "$tgInvitationsResourcesProvider", "$tgRolesResourcesProvider", "$tgUserSettingsResourcesProvider", "$tgSprintsResourcesProvider", "$tgUserstoriesResourcesProvider", "$tgTasksResourcesProvider", "$tgIssuesResourcesProvider", "$tgWikiResourcesProvider", "$tgSearchResourcesProvider", "$tgAttachmentsResourcesProvider", "$tgMdRenderResourcesProvider", "$tgHistoryResourcesProvider", "$tgKanbanResourcesProvider", "$tgModulesResourcesProvider", "$tgWebhooksResourcesProvider", "$tgWebhookLogsResourcesProvider", "$tgLocalesResourcesProvider", initResources]); + module.run(["$log", "$tgResources", "$tgProjectsResourcesProvider", "$tgCustomAttributesResourcesProvider", "$tgCustomAttributesValuesResourcesProvider", "$tgMembershipsResourcesProvider", "$tgNotifyPoliciesResourcesProvider", "$tgInvitationsResourcesProvider", "$tgRolesResourcesProvider", "$tgUserSettingsResourcesProvider", "$tgSprintsResourcesProvider", "$tgUserstoriesResourcesProvider", "$tgTasksResourcesProvider", "$tgIssuesResourcesProvider", "$tgWikiResourcesProvider", "$tgSearchResourcesProvider", "$tgAttachmentsResourcesProvider", "$tgMdRenderResourcesProvider", "$tgHistoryResourcesProvider", "$tgKanbanResourcesProvider", "$tgModulesResourcesProvider", "$tgWebhooksResourcesProvider", "$tgWebhookLogsResourcesProvider", "$tgLocalesResourcesProvider", "$tgUsersResourcesProvider", initResources]); }).call(this); @@ -3130,9 +3039,9 @@ SearchController = (function(superClass) { extend(SearchController, superClass); - SearchController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "$q", "$tgLocation", "$appTitle", "$tgNavUrls", "tgLoader"]; + SearchController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "$q", "$tgLocation", "tgAppMetaService", "$tgNavUrls", "$translate"]; - function SearchController(scope1, repo, rs, params, q, location, appTitle, navUrls, tgLoader) { + function SearchController(scope1, repo, rs, params, q, location, appMetaService, navUrls, translate) { var loadSearchData, promise; this.scope = scope1; this.repo = repo; @@ -3140,14 +3049,22 @@ this.params = params; this.q = q; this.location = location; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.navUrls = navUrls; - this.tgLoader = tgLoader; + this.translate = translate; this.scope.sectionName = "Search"; promise = this.loadInitialData(); promise.then((function(_this) { return function() { - return _this.appTitle.set("Search"); + var description, title; + title = _this.translate.instant("SEARCH.PAGE_TITLE", { + projectName: _this.scope.project.name + }); + description = _this.translate.instant("SEARCH.PAGE_DESCRIPTION", { + projectName: _this.scope.project.name, + projectDescription: _this.scope.project.description + }); + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); @@ -3159,9 +3076,7 @@ })(this)); this.scope.$watch("searchTerm", (function(_this) { return function(term) { - if (!term) { - return _this.tgLoader.pageLoaded(); - } else { + if (term) { return loadSearchData(term); } }; @@ -3211,11 +3126,6 @@ return data; }; })(this)); - promise["finally"]((function(_this) { - return function() { - return _this.tgLoader.pageLoaded(); - }; - })(this)); return promise; }; @@ -3234,10 +3144,10 @@ module.controller("SearchController", SearchController); - SearchBoxDirective = function($lightboxService, $navurls, $location, $route) { + SearchBoxDirective = function(projectService, $lightboxService, $navurls, $location, $route) { var link; link = function($scope, $el, $attrs) { - var project, submit; + var openLightbox, project, submit; project = null; submit = debounce(2000, (function(_this) { return function(event) { @@ -3249,29 +3159,34 @@ } text = $el.find("#search-text").val(); url = $navurls.resolve("project-search", { - project: project.slug + project: project.get("slug") }); - $lightboxService.close($el); return $scope.$apply(function() { + $lightboxService.close($el); $location.path(url); $location.search("text", text).path(url); return $route.reload(); }); }; })(this)); - $scope.$on("search-box:show", function(ctx, newProject) { - project = newProject; - $lightboxService.open($el); - return $el.find("#search-text").val(""); - }); - return $el.on("submit", "form", submit); + openLightbox = function() { + project = projectService.project; + return $lightboxService.open($el).then(function() { + return $el.find("#search-text").focus(); + }); + }; + $el.on("submit", "form", submit); + return openLightbox(); }; return { + templateUrl: "search/lightbox-search.html", link: link }; }; - module.directive("tgSearchBox", ["lightboxService", "$tgNavUrls", "$tgLocation", "$route", SearchBoxDirective]); + SearchBoxDirective.$inject = ["tgProjectService", "lightboxService", "$tgNavUrls", "$tgLocation", "$route"]; + + module.directive("tgSearchBox", SearchBoxDirective); SearchDirective = function($log, $compile, $templatecache, $routeparams, $location) { var link, linkTable; @@ -3280,19 +3195,21 @@ tabsDom = $el.find("section.search-filter"); lastSeatchResults = null; getActiveSection = function(data) { - var maxVal, name, selectedSectionData, selectedSectionName, value; + var i, len, maxVal, name, ref, selectedSectionData, selectedSectionName, value; maxVal = 0; selectedSectionName = null; selectedSectionData = null; - for (name in data) { - value = data[name]; - if (name === "count") { - continue; - } - if (value.length > maxVal) { - maxVal = value.length; - selectedSectionName = name; - selectedSectionData = value; + if (data) { + ref = ["userstories", "issues", "tasks", "wikipages"]; + for (i = 0, len = ref.length; i < len; i++) { + name = ref[i]; + value = data[name]; + if (value.length > maxVal) { + maxVal = value.length; + selectedSectionName = name; + selectedSectionData = value; + break; + } } } if (maxVal === 0) { @@ -4041,6 +3958,8 @@ if (attachment.is_deprecated) { $el.addClass("deprecated"); return $el.find("input:checkbox").prop('checked', true); + } else { + return $el.removeClass("deprecated"); } }; saveAttachment = function() { @@ -4124,6 +4043,28 @@ }).call(this); +(function() { + var CompileHtmlDirective; + + CompileHtmlDirective = function($compile) { + var link; + link = function(scope, element, attrs) { + return scope.$watch(attrs.tgCompileHtml, function(newValue, oldValue) { + element.html(newValue); + return $compile(element.contents())(scope); + }); + }; + return { + link: link + }; + }; + + CompileHtmlDirective.$inject = ["$compile"]; + + angular.module("taigaCommon").directive("tgCompileHtml", CompileHtmlDirective); + +}).call(this); + /* * Copyright (C) 2014 Andrey Antukh @@ -4332,7 +4273,7 @@ return $scope.usersById[watcherId]; }); renderWatchers(watchers); - return $rootscope.$broadcast("history:reload"); + return $rootscope.$broadcast("object:updated"); }); return promise.then(null, function() { return $model.$modelValue.revert(); @@ -4353,7 +4294,7 @@ return $scope.usersById[watcherId]; }); renderWatchers(watchers); - return $rootscope.$broadcast("history:reload"); + return $rootscope.$broadcast("object:updated"); }); return promise.then(null, function() { item.revert(); @@ -4451,7 +4392,7 @@ $loading.finish($el); $confirm.notify("success"); renderAssignedTo($model.$modelValue); - return $rootscope.$broadcast("history:reload"); + return $rootscope.$broadcast("object:updated"); }); promise.then(null, function() { $model.$modelValue.revert(); @@ -4617,6 +4558,10 @@ template = $template.get("common/components/editable-subject.html"); link = function($scope, $el, $attrs, $model) { var isEditable, save; + $scope.$on("object:updated", function() { + $el.find('.edit-subject').hide(); + return $el.find('.view-subject').show(); + }); isEditable = function() { return $scope.project.my_permissions.indexOf($attrs.requiredPerm) !== -1; }; @@ -4628,7 +4573,7 @@ promise = $repo.save($model.$modelValue); promise.then(function() { $confirm.notify("success"); - $rootscope.$broadcast("history:reload"); + $rootscope.$broadcast("object:updated"); $el.find('.edit-subject').hide(); return $el.find('.view-subject').show(); }); @@ -4649,8 +4594,9 @@ $el.find('.view-subject').hide(); return $el.find('input').focus(); }); - $el.on("click", ".save", function() { + $el.on("click", ".save", function(e) { var subject; + e.preventDefault(); subject = $scope.item.subject; return save(subject); }); @@ -4703,6 +4649,10 @@ var isEditable, save; $el.find('.edit-description').hide(); $el.find('.view-description .edit').hide(); + $scope.$on("object:updated", function() { + $el.find('.edit-description').hide(); + return $el.find('.view-description').show(); + }); isEditable = function() { return $scope.project.my_permissions.indexOf($attrs.requiredPerm) !== -1; }; @@ -4714,7 +4664,7 @@ promise = $repo.save($model.$modelValue); promise.then(function() { $confirm.notify("success"); - $rootscope.$broadcast("history:reload"); + $rootscope.$broadcast("object:updated"); $el.find('.edit-description').hide(); return $el.find('.view-description').show(); }); @@ -4975,14 +4925,7 @@ var link; link = function($scope, $el, $attrs) { $attrs.$observe("i18nSectionName", function(i18nSectionName) { - var trans; - trans = $translate(i18nSectionName); - trans.then(function(sectionName) { - return $scope.sectionName = sectionName; - }); - return trans["catch"](function(sectionName) { - return $scope.sectionName = sectionName; - }); + return $scope.sectionName = $translate.instant(i18nSectionName); }); return $scope.$on("$destroy", function() { return $el.off(); @@ -5643,7 +5586,7 @@ estimationProcess = $tgEstimationsService.create($el, us, $scope.project); estimationProcess.onSelectedPointForRole = function(roleId, pointId) { return this.save(roleId, pointId).then(function() { - return $rootScope.$broadcast("history:reload"); + return $rootScope.$broadcast("object:updated"); }); }; estimationProcess.render = function() { @@ -6263,7 +6206,7 @@ deleteCommentUser: comment.delete_comment_user.name, deleteComment: comment.comment_html, activityId: comment.id, - canRestoreComment: comment.delete_comment_user.pk === $scope.user.id || $scope.project.my_permissions.indexOf("modify_project") > -1 + canRestoreComment: $scope.user && (comment.delete_comment_user.pk === $scope.user.id || $scope.project.my_permissions.indexOf("modify_project") > -1) }); html = $compile(html)($scope); return html[0].outerHTML; @@ -6360,10 +6303,10 @@ })(this)); $scope.$watch("comments", renderComments); $scope.$watch("history", renderActivity); - $scope.$on("history:reload", function() { + $scope.$on("object:updated", function() { return $ctrl.loadHistory(type, objectId); }); - $el.on("click", ".add-comment a.button-green", debounce(2000, function(event) { + $el.on("click", ".add-comment input.button-green", debounce(2000, function(event) { var target; event.preventDefault(); target = angular.element(event.currentTarget); @@ -6583,10 +6526,12 @@ lightboxContent = $el.children().not(".close"); lightboxContent.hide(); $el.css('display', 'flex'); - $el.find('input,textarea').first().focus(); this.animationFrame.add((function(_this) { return function() { - return $el.addClass("open"); + $el.addClass("open"); + return _this.animationFrame.add(function() { + return $el.find('input,textarea').first().focus(); + }); }; })(this)); this.animationFrame.add((function(_this) { @@ -6609,7 +6554,7 @@ }; LightboxService.prototype.close = function($el) { - var docEl; + var docEl, scope; docEl = angular.element(document); docEl.off(".lightbox"); docEl.off(".keyboard-navigation"); @@ -6619,7 +6564,12 @@ return $el.removeClass("open").removeClass('close'); }; })(this)); - return $el.addClass('close'); + $el.addClass('close'); + if ($el.hasClass("remove-on-close")) { + scope = $el.data("scope"); + scope.$destroy(); + return $el.remove(); + } }; LightboxService.prototype.closeAll = function() { @@ -6726,17 +6676,16 @@ BlockLightboxDirective = function($rootscope, $tgrepo, $confirm, lightboxService, $loading, $qqueue, $translate) { var link; link = function($scope, $el, $attrs, $model) { - var block, unblock; - $translate($attrs.title).then(function(title) { - return $el.find("h2.title").text(title); - }); + var block, title, unblock; + title = $translate.instant($attrs.title); + $el.find("h2.title").text(title); unblock = $qqueue.bindAdd((function(_this) { return function(item, finishCallback) { var promise; promise = $tgrepo.save(item); promise.then(function() { $confirm.notify("success"); - $rootscope.$broadcast("history:reload"); + $rootscope.$broadcast("object:updated"); $model.$setViewValue(item); return finishCallback(); }); @@ -6759,7 +6708,7 @@ promise = $tgrepo.save($model.$modelValue); promise.then(function() { $confirm.notify("success"); - return $rootscope.$broadcast("history:reload"); + return $rootscope.$broadcast("object:updated"); }); promise.then(null, function() { $confirm.notify("error"); @@ -7039,8 +6988,7 @@ }; html = usersTemplate(ctx); html = $compile(html)($scope); - $el.find("div.watchers").html(html); - return lightboxKeyboardNavigationService.init($el); + return $el.find("div.watchers").html(html); }; closeLightbox = function() { lightboxKeyboardNavigationService.stop(); @@ -7053,7 +7001,8 @@ selectedUser = $scope.usersById[assignedToId]; render(selectedUser); return lightboxService.open($el).then(function() { - return $el.find('input').focus(); + $el.find('input').focus(); + return lightboxKeyboardNavigationService.init($el); }); }); $scope.$watch("usersSearch", function(searchingText) { @@ -7134,8 +7083,7 @@ showMore: users.length > 5 }; html = usersTemplate(ctx); - $el.find("div.watchers").html(html); - return lightboxKeyboardNavigationService.init($el); + return $el.find("div.watchers").html(html); }; closeLightbox = function() { lightboxKeyboardNavigationService.stop(); @@ -7146,10 +7094,10 @@ selectedItem = item; users = getFilteredUsers(); render(users); - lightboxService.open($el).then(function() { - return $el.find("input").focus(); + return lightboxService.open($el).then(function() { + $el.find("input").focus(); + return lightboxKeyboardNavigationService.init($el); }); - return lightboxKeyboardNavigationService.init($el); }); $scope.$watch("usersSearch", function(searchingText) { var users; @@ -7233,16 +7181,10 @@ $(document.body).addClass("loader-active"); return $el.addClass("active"); }); - tgLoader.onEnd(function() { + return tgLoader.onEnd(function() { $(document.body).removeClass("loader-active"); return $el.removeClass("active"); }); - $rootscope.$on("$routeChangeSuccess", function(e) { - return tgLoader.startCurrentPageLoader(); - }); - return $rootscope.$on("$locationChangeSuccess", function(e) { - return tgLoader.reset(); - }); }; return { link: link @@ -7251,78 +7193,91 @@ module.directive("tgLoader", ["tgLoader", "$rootScope", LoaderDirective]); - Loader = function() { - var config, defaultConfig, forceDisabled; - forceDisabled = false; - defaultConfig = { - enabled: false, + Loader = function($rootscope) { + var autoClose, config, lastResponseDate, open, pageLoaded, requestCount, start, startLoadTime; + config = { minTime: 300 }; - config = _.merge({}, defaultConfig); - this.add = function() { - return function() { - if (!forceDisabled) { - return config.enabled = true; - } - }; - }; - this.$get = [ - "$rootScope", function($rootscope) { - var pageLoaded, reset, start, startLoadTime; - startLoadTime = 0; - reset = function() { - return config = _.merge({}, defaultConfig); - }; - pageLoaded = function(force) { - var diff, endTime, timeoutValue; - if (force == null) { - force = false; - } - if (startLoadTime) { - timeoutValue = 0; - if (!force) { - endTime = new Date().getTime(); - diff = endTime - startLoadTime; - if (diff < config.minTime) { - timeoutValue = config.minTime - diff; - } - } - return timeout(timeoutValue, function() { - return $rootscope.$broadcast("loader:end"); - }); - } - }; - start = function() { - startLoadTime = new Date().getTime(); - return $rootscope.$broadcast("loader:start"); - }; - return { - reset: reset, - pageLoaded: pageLoaded, - start: start, - startCurrentPageLoader: function() { - if (config.enabled) { - return start(); - } - }, - onStart: function(fn) { - return $rootscope.$on("loader:start", fn); - }, - onEnd: function(fn) { - return $rootscope.$on("loader:end", fn); - }, - preventLoading: function() { - return forceDisabled = true; - }, - disablePreventLoading: function() { - return forceDisabled = false; - } - }; + open = false; + startLoadTime = 0; + requestCount = 0; + lastResponseDate = 0; + pageLoaded = function(force) { + var diff, endTime, timeoutValue; + if (force == null) { + force = false; } - ]; + if (startLoadTime) { + timeoutValue = 0; + if (!force) { + endTime = new Date().getTime(); + diff = endTime - startLoadTime; + if (diff < config.minTime) { + timeoutValue = config.minTime - diff; + } + } + timeout(timeoutValue, function() { + $rootscope.$broadcast("loader:end"); + open = false; + return window.prerenderReady = true; + }); + } + startLoadTime = 0; + requestCount = 0; + return lastResponseDate = 0; + }; + autoClose = function() { + var intervalAuto, maxAuto, timeoutAuto; + maxAuto = 5000; + timeoutAuto = setTimeout((function() { + pageLoaded(); + return clearInterval(intervalAuto); + }), maxAuto); + return intervalAuto = setInterval((function() { + if (lastResponseDate && requestCount === 0) { + pageLoaded(); + clearInterval(intervalAuto); + return clearTimeout(timeoutAuto); + } + }), 50); + }; + start = function() { + startLoadTime = new Date().getTime(); + $rootscope.$broadcast("loader:start"); + return open = true; + }; + return { + pageLoaded: pageLoaded, + start: function(auto) { + if (auto == null) { + auto = false; + } + if (!open) { + start(); + if (auto) { + return autoClose(); + } + } + }, + onStart: function(fn) { + return $rootscope.$on("loader:start", fn); + }, + onEnd: function(fn) { + return $rootscope.$on("loader:end", fn); + }, + logRequest: function() { + return requestCount++; + }, + logResponse: function() { + requestCount--; + return lastResponseDate = new Date().getTime(); + } + }; }; - module.provider("tgLoader", [Loader]); + Loader.$inject = ["$rootScope"]; + + module.factory("tgLoader", Loader); }).call(this); @@ -8043,7 +7998,7 @@ model.tags = tags; $model.$setViewValue(model); onSuccess = function() { - return $rootScope.$broadcast("history:reload"); + return $rootScope.$broadcast("object:updated"); }; onError = function() { $confirm.notify("error"); @@ -8065,7 +8020,7 @@ model.tags = tags; $model.$setViewValue(model); onSuccess = function() { - return $rootScope.$broadcast("history:reload"); + return $rootScope.$broadcast("object:updated"); }; onError = function() { $confirm.notify("error"); @@ -8969,9 +8924,9 @@ BacklogController = (function(superClass) { extend(BacklogController, superClass); - BacklogController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$appTitle", "$tgNavUrls", "$tgEvents", "$tgAnalytics", "tgLoader", "$translate"]; + BacklogController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "tgAppMetaService", "$tgNavUrls", "$tgEvents", "$tgAnalytics", "$translate"]; - function BacklogController(scope, rootscope, repo, confirm, rs, params1, q, location, appTitle, navUrls, events, analytics, tgLoader, translate) { + function BacklogController(scope, rootscope, repo, confirm, rs, params1, q, location, appMetaService, navUrls, events, analytics, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -8981,7 +8936,7 @@ this.params = params1; this.q = q; this.location = location; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.navUrls = navUrls; this.events = events; this.analytics = analytics; @@ -8994,7 +8949,15 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - _this.appTitle.set("Backlog - " + _this.scope.project.name); + var description, title; + title = _this.translate.instant("BACKLOG.PAGE_TITLE", { + projectName: _this.scope.project.name + }); + description = _this.translate.instant("BACKLOG.PAGE_DESCRIPTION", { + projectName: _this.scope.project.name, + projectDescription: _this.scope.project.description + }); + _this.appMetaService.setAll(title, description); if (_this.rs.userstories.getShowTags(_this.scope.projectId)) { _this.showTags = true; return _this.scope.$broadcast("showTags", _this.showTags); @@ -9002,7 +8965,6 @@ }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); } BacklogController.prototype.initializeEventHandlers = function() { @@ -9662,7 +9624,7 @@ return $scope.$watch("stats", reloadDoomLine); }; linkToolbar = function($scope, $el, $attrs, $ctrl) { - var moveToCurrentSprint; + var checkSelected, lastChecked, moveToCurrentSprint, shiftPressed; moveToCurrentSprint = function(selectedUss) { var extraPoints, totalExtraPoints, ussCurrent; ussCurrent = _($scope.userstories); @@ -9681,9 +9643,11 @@ return $ctrl.loadProjectStats(); }); }; - $el.on("change", ".backlog-table-body .user-stories input:checkbox", function(event) { - var moveToCurrentSprintDom, selectedUsDom, target; - target = angular.element(event.currentTarget); + shiftPressed = false; + lastChecked = null; + checkSelected = function(target) { + var moveToCurrentSprintDom, selectedUsDom; + lastChecked = target.closest(".us-item-row"); moveToCurrentSprintDom = $el.find("#move-to-current-sprint"); selectedUsDom = $el.find(".backlog-table-body .user-stories input:checkbox:checked"); if (selectedUsDom.length > 0 && $scope.sprints.length > 0) { @@ -9692,6 +9656,36 @@ moveToCurrentSprintDom.hide(); } return target.closest('.us-item-row').toggleClass('ui-multisortable-multiple'); + }; + $(window).on("keydown.shift-pressed keyup.shift-pressed", function(event) { + shiftPressed = !!event.shiftKey; + return true; + }); + $el.on("change", ".backlog-table-body .user-stories input:checkbox", function(event) { + var current, elements, nextAll, prevAll, target; + if (lastChecked && shiftPressed) { + elements = []; + current = $(event.currentTarget).closest(".us-item-row"); + nextAll = lastChecked.nextAll(); + prevAll = lastChecked.prevAll(); + if (_.some(nextAll, function(next) { + return next === current[0]; + })) { + elements = lastChecked.nextUntil(current); + } else if (_.some(prevAll, function(prev) { + return prev === current[0]; + })) { + elements = lastChecked.prevUntil(current); + } + _.map(elements, function(elm) { + var input; + input = $(elm).find("input:checkbox"); + input.prop('checked', true); + return checkSelected(input); + }); + } + target = angular.element(event.currentTarget); + return checkSelected(target); }); $el.on("click", "#move-to-current-sprint", (function(_this) { return function(event) { @@ -9771,7 +9765,8 @@ return showHideTags($ctrl); }); return $scope.$on("$destroy", function() { - return $el.off(); + $el.off(); + return $(window).off(".shift-pressed"); }); }; return { @@ -10236,16 +10231,17 @@ items: ".us-item-row", cancel: ".popover", connectWith: ".sprint", - containment: ".wrapper", dropOnEmpty: true, placeholder: "row us-item-row us-item-drag sortable-placeholder", scroll: true, + disableHorizontalScroll: true, tolerance: "pointer", revert: false, - cursorAt: { - right: 15 + start: function() { + return $(document.body).addClass("drag-active"); }, stop: function() { + $(document.body).removeClass("drag-active"); if ($el.hasClass("active-filters")) { $el.sortable("cancel"); return filterError(); @@ -10341,7 +10337,10 @@ scroll: true, dropOnEmpty: true, items: ".sprint-table .milestone-us-item-row", - connectWith: ".sprint,.backlog-table-body,.empty-backlog" + disableHorizontalScroll: true, + connectWith: ".sprint,.backlog-table-body,.empty-backlog", + placeholder: "row us-item-row sortable-placeholder", + forcePlaceholderSize: true }); $el.on("multiplesortreceive", function(event, ui) { var index, items, us; @@ -10954,9 +10953,9 @@ TaskboardController = (function(superClass) { extend(TaskboardController, superClass); - TaskboardController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$appTitle", "$tgLocation", "$tgNavUrls", "$tgEvents", "$tgAnalytics", "tgLoader", "$translate"]; + TaskboardController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "tgAppMetaService", "$tgLocation", "$tgNavUrls", "$tgEvents", "$tgAnalytics", "$translate"]; - function TaskboardController(scope, rootscope, repo, confirm, rs1, params1, q, appTitle, location, navUrls, events, analytics, tgLoader, translate) { + function TaskboardController(scope, rootscope, repo, confirm, rs1, params1, q, appMetaService, location, navUrls, events, analytics, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -10965,7 +10964,7 @@ this.rs = rs1; this.params = params1; this.q = q; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.location = location; this.navUrls = navUrls; this.events = events; @@ -10977,13 +10976,33 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - return _this.appTitle.set("Taskboard - " + _this.scope.project.name); + return _this._setMeta(); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); } + TaskboardController.prototype._setMeta = function() { + var description, prettyDate, title; + prettyDate = this.translate.instant("BACKLOG.SPRINTS.DATE"); + title = this.translate.instant("TASKBOARD.PAGE_TITLE", { + projectName: this.scope.project.name, + sprintName: this.scope.sprint.name + }); + description = this.translate.instant("TASKBOARD.PAGE_DESCRIPTION", { + projectName: this.scope.project.name, + sprintName: this.scope.sprint.name, + startDate: moment(this.scope.sprint.estimated_start).format(prettyDate), + endDate: moment(this.scope.sprint.estimated_finish).format(prettyDate), + completedPercentage: this.scope.stats.completedPercentage || "0", + completedPoints: this.scope.stats.completedPointsSum || "--", + totalPoints: this.scope.stats.totalPointsSum || "--", + openTasks: this.scope.stats.openTasks || "--", + totalTasks: this.scope.stats.total_tasks || "--" + }); + return this.appMetaService.setAll(title, description); + }; + TaskboardController.prototype.initializeEventHandlers = function() { this.scope.$on("taskform:bulk:success", (function(_this) { return function() { @@ -11625,9 +11644,9 @@ KanbanController = (function(superClass) { extend(KanbanController, superClass); - KanbanController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$appTitle", "$tgNavUrls", "$tgEvents", "$tgAnalytics", "tgLoader", "$translate"]; + KanbanController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "tgAppMetaService", "$tgNavUrls", "$tgEvents", "$tgAnalytics", "$translate"]; - function KanbanController(scope, rootscope, repo, confirm, rs1, params1, q, location, appTitle, navUrls, events, analytics, tgLoader, translate) { + function KanbanController(scope, rootscope, repo, confirm, rs1, params1, q, location, appMetaService, navUrls, events, analytics, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -11637,7 +11656,7 @@ this.params = params1; this.q = q; this.location = location; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.navUrls = navUrls; this.events = events; this.analytics = analytics; @@ -11649,11 +11668,18 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - return _this.appTitle.set("Kanban - " + _this.scope.project.name); + var description, title; + title = _this.translate.instant("KANBAN.PAGE_TITLE", { + projectName: _this.scope.project.name + }); + description = _this.translate.instant("KANBAN.PAGE_DESCRIPTION", { + projectName: _this.scope.project.name, + projectDescription: _this.scope.project.description + }); + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); } KanbanController.prototype.initializeEventHandlers = function() { @@ -12358,9 +12384,9 @@ IssueDetailController = (function(superClass) { extend(IssueDetailController, superClass); - IssueDetailController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$log", "$appTitle", "$tgAnalytics", "$tgNavUrls", "$translate", "tgLoader"]; + IssueDetailController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$log", "tgAppMetaService", "$tgAnalytics", "$tgNavUrls", "$translate"]; - function IssueDetailController(scope, rootscope, repo, confirm, rs, params, q, location, log, appTitle, analytics, navUrls, translate, tgLoader) { + function IssueDetailController(scope, rootscope, repo, confirm, rs, params, q, location, log, appMetaService, analytics, navUrls, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -12371,7 +12397,7 @@ this.q = q; this.location = location; this.log = log; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.analytics = analytics; this.navUrls = navUrls; this.translate = translate; @@ -12381,41 +12407,57 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - _this.appTitle.set(_this.scope.issue.subject + " - " + _this.scope.project.name); + _this._setMeta(); return _this.initializeOnDeleteGoToUrl(); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); } + IssueDetailController.prototype._setMeta = function() { + var description, ref, ref1, ref2, ref3, title; + title = this.translate.instant("ISSUE.PAGE_TITLE", { + issueRef: "#" + this.scope.issue.ref, + issueSubject: this.scope.issue.subject, + projectName: this.scope.project.name + }); + description = this.translate.instant("ISSUE.PAGE_DESCRIPTION", { + issueStatus: ((ref = this.scope.statusById[this.scope.issue.status]) != null ? ref.name : void 0) || "--", + issueType: ((ref1 = this.scope.typeById[this.scope.issue.type]) != null ? ref1.name : void 0) || "--", + issueSeverity: ((ref2 = this.scope.severityById[this.scope.issue.severity]) != null ? ref2.name : void 0) || "--", + issuePriority: ((ref3 = this.scope.priorityById[this.scope.issue.priority]) != null ? ref3.name : void 0) || "--", + issueDescription: angular.element(this.scope.issue.description_html || "").text() + }); + return this.appMetaService.setAll(title, description); + }; + IssueDetailController.prototype.initializeEventHandlers = function() { this.scope.$on("attachment:create", (function(_this) { return function() { - _this.rootscope.$broadcast("history:reload"); + _this.rootscope.$broadcast("object:updated"); return _this.analytics.trackEvent("attachment", "create", "create attachment on issue", 1); }; })(this)); this.scope.$on("attachment:edit", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); this.scope.$on("attachment:delete", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); this.scope.$on("promote-issue-to-us:success", (function(_this) { return function() { _this.analytics.trackEvent("issue", "promoteToUserstory", "promote issue to userstory", 1); - _this.rootscope.$broadcast("history:reload"); + _this.rootscope.$broadcast("object:updated"); return _this.loadIssue(); }; })(this)); return this.scope.$on("custom-attributes-values:edit", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); }; @@ -12567,7 +12609,7 @@ onSuccess = function() { $confirm.notify("success"); $model.$setViewValue(issue); - $rootScope.$broadcast("history:reload"); + $rootScope.$broadcast("object:updated"); return $loading.finish($el.find(".level-name")); }; onError = function() { @@ -12646,7 +12688,7 @@ onSuccess = function() { $confirm.notify("success"); $model.$setViewValue(issue); - $rootScope.$broadcast("history:reload"); + $rootScope.$broadcast("object:updated"); return $loading.finish($el.find(".level-name")); }; onError = function() { @@ -12726,7 +12768,7 @@ onSuccess = function() { $confirm.notify("success"); $model.$setViewValue(issue); - $rootScope.$broadcast("history:reload"); + $rootScope.$broadcast("object:updated"); return $loading.finish($el.find(".level-name")); }; onError = function() { @@ -12806,7 +12848,7 @@ onSuccess = function() { $confirm.notify("success"); $model.$setViewValue(issue); - $rootScope.$broadcast("history:reload"); + $rootScope.$broadcast("object:updated"); return $loading.finish($el.find(".level-name")); }; onError = function() { @@ -13100,9 +13142,9 @@ IssuesController = (function(superClass) { extend(IssuesController, superClass); - IssuesController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$tgUrls", "$routeParams", "$q", "$tgLocation", "$appTitle", "$tgNavUrls", "$tgEvents", "$tgAnalytics", "tgLoader", "$translate"]; + IssuesController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$tgUrls", "$routeParams", "$q", "$tgLocation", "tgAppMetaService", "$tgNavUrls", "$tgEvents", "$tgAnalytics", "$translate"]; - function IssuesController(scope, rootscope, repo, confirm, rs, urls, params, q, location, appTitle, navUrls, events, analytics, tgLoader, translate) { + function IssuesController(scope, rootscope, repo, confirm, rs, urls, params, q, location, appMetaService, navUrls, events, analytics, translate) { var filters, promise; this.scope = scope; this.rootscope = rootscope; @@ -13113,13 +13155,13 @@ this.params = params; this.q = q; this.location = location; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.navUrls = navUrls; this.events = events; this.analytics = analytics; this.translate = translate; this.loadIssues = bind(this.loadIssues, this); - this.scope.sectionName = this.translate.instant("ISSUES.LIST_SECTION_NAME"); + this.scope.sectionName = "Issues"; this.scope.filters = {}; if (_.isEmpty(this.location.search())) { filters = this.rs.issues.getFilters(this.params.pslug); @@ -13131,11 +13173,18 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - return _this.appTitle.set("Issues - " + _this.scope.project.name); + var description, title; + title = _this.translate.instant("ISSUES.PAGE_TITLE", { + projectName: _this.scope.project.name + }); + description = _this.translate.instant("ISSUES.PAGE_DESCRIPTION", { + projectName: _this.scope.project.name, + projectDescription: _this.scope.project.description + }); + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); this.scope.$on("issueform:new:success", (function(_this) { return function() { _this.analytics.trackEvent("issue", "create", "create issue on issues list", 1); @@ -13601,7 +13650,7 @@ module.directive("tgIssues", ["$log", "$tgLocation", "$tgTemplate", "$compile", IssuesDirective]); - IssuesFiltersDirective = function($log, $location, $rs, $confirm, $loading, $template, $translate, $compile) { + IssuesFiltersDirective = function($log, $location, $rs, $confirm, $loading, $template, $translate, $compile, $auth) { var link, template, templateSelected; template = $template.get("issue/issues-filters.html", true); templateSelected = $template.get("issue/issues-filters-selected.html", true); @@ -13649,7 +13698,7 @@ }); html = $compile(html)($scope); $el.find(".filters-applied").html(html); - if (selectedFilters.length > 0) { + if ($auth.isAuthenticated() && selectedFilters.length > 0) { return $el.find(".save-filters").show(); } else { return $el.find(".save-filters").hide(); @@ -13859,7 +13908,7 @@ }; }; - module.directive("tgIssuesFilters", ["$log", "$tgLocation", "$tgResources", "$tgConfirm", "$tgLoading", "$tgTemplate", "$translate", "$compile", IssuesFiltersDirective]); + module.directive("tgIssuesFilters", ["$log", "$tgLocation", "$tgResources", "$tgConfirm", "$tgLoading", "$tgTemplate", "$translate", "$compile", "$tgAuth", IssuesFiltersDirective]); IssueStatusInlineEditionDirective = function($repo, $template, $rootscope) { @@ -13914,7 +13963,8 @@ return $scope.$apply(function() { var k, len1, ref1; $repo.save(issue).then(function() { - var el, filtering, i, k, l, len1, len2, len3, m, ref1, ref2, ref3, results; + var k, len1, ref1; + $ctrl.loadIssues(); ref1 = $scope.filters.statuses; for (k = 0, len1 = ref1.length; k < len1; k++) { filter = ref1[k]; @@ -13922,32 +13972,7 @@ filter.count++; } } - $rootscope.$broadcast("filters:issueupdate", $scope.filters); - filtering = false; - ref2 = $scope.filters.statuses; - for (l = 0, len2 = ref2.length; l < len2; l++) { - filter = ref2[l]; - if (filter.selected === true) { - filtering = true; - if (filter.id === issue.status) { - return; - } - } - } - if (!filtering) { - return; - } - ref3 = $scope.issues; - results = []; - for (i = m = 0, len3 = ref3.length; m < len3; i = ++m) { - el = ref3[i]; - if (el && el.id === issue.id) { - results.push($scope.issues.splice(i, 1)); - } else { - results.push(void 0); - } - } - return results; + return $rootscope.$broadcast("filters:issueupdate", $scope.filters); }); ref1 = $scope.filters.statuses; for (k = 0, len1 = ref1.length; k < len1; k++) { @@ -14083,9 +14108,9 @@ UserStoryDetailController = (function(superClass) { extend(UserStoryDetailController, superClass); - UserStoryDetailController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$log", "$appTitle", "$tgNavUrls", "$tgAnalytics", "$translate", "tgLoader"]; + UserStoryDetailController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$log", "tgAppMetaService", "$tgNavUrls", "$tgAnalytics", "$translate"]; - function UserStoryDetailController(scope, rootscope, repo, confirm, rs, params, q, location, log, appTitle, navUrls, analytics, translate, tgLoader) { + function UserStoryDetailController(scope, rootscope, repo, confirm, rs, params, q, location, log, appMetaService, navUrls, analytics, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -14096,7 +14121,7 @@ this.q = q; this.location = location; this.log = log; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.navUrls = navUrls; this.analytics = analytics; this.translate = translate; @@ -14106,14 +14131,38 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - _this.appTitle.set(_this.scope.us.subject + " - " + _this.scope.project.name); + _this._setMeta(); return _this.initializeOnDeleteGoToUrl(); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); } + UserStoryDetailController.prototype._setMeta = function() { + var closedTasks, description, progressPercentage, ref, title, totalTasks; + totalTasks = this.scope.tasks.length; + closedTasks = _.filter(this.scope.tasks, (function(_this) { + return function(t) { + return _this.scope.taskStatusById[t.status].is_closed; + }; + })(this)).length; + progressPercentage = totalTasks > 0 ? Math.round(100 * closedTasks / totalTasks) : 0; + title = this.translate.instant("US.PAGE_TITLE", { + userStoryRef: "#" + this.scope.us.ref, + userStorySubject: this.scope.us.subject, + projectName: this.scope.project.name + }); + description = this.translate.instant("US.PAGE_DESCRIPTION", { + userStoryStatus: ((ref = this.scope.statusById[this.scope.us.status]) != null ? ref.name : void 0) || "--", + userStoryPoints: this.scope.us.total_points, + userStoryDescription: angular.element(this.scope.us.description_html || "").text(), + userStoryClosedTasks: closedTasks, + userStoryTotalTasks: totalTasks, + userStoryProgressPercentage: progressPercentage + }); + return this.appMetaService.setAll(title, description); + }; + UserStoryDetailController.prototype.initializeEventHandlers = function() { this.scope.$on("related-tasks:update", (function(_this) { return function() { @@ -14124,22 +14173,22 @@ this.scope.$on("attachment:create", (function(_this) { return function() { _this.analytics.trackEvent("attachment", "create", "create attachment on userstory", 1); - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); this.scope.$on("attachment:edit", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); this.scope.$on("attachment:delete", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); return this.scope.$on("custom-attributes-values:edit", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); }; @@ -14379,7 +14428,7 @@ $model.$setViewValue(us); onSuccess = function() { $confirm.notify("success"); - $rootScope.$broadcast("history:reload"); + $rootScope.$broadcast("object:updated"); return $loading.finish($el.find(".level-name")); }; onError = function() { @@ -14461,7 +14510,7 @@ promise = $tgrepo.save($model.$modelValue); promise.then(function() { $loading.finish($el.find("label")); - return $rootscope.$broadcast("history:reload"); + return $rootscope.$broadcast("object:updated"); }); return promise.then(null, function() { $loading.finish($el.find("label")); @@ -14528,7 +14577,7 @@ promise = $tgrepo.save($model.$modelValue); promise.then(function() { $loading.finish($el.find("label")); - return $rootscope.$broadcast("history:reload"); + return $rootscope.$broadcast("object:updated"); }); return promise.then(null, function() { $loading.finish($el.find("label")); @@ -14604,9 +14653,9 @@ TaskDetailController = (function(superClass) { extend(TaskDetailController, superClass); - TaskDetailController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$log", "$appTitle", "$tgNavUrls", "$tgAnalytics", "$translate", "tgLoader"]; + TaskDetailController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$log", "tgAppMetaService", "$tgNavUrls", "$tgAnalytics", "$translate"]; - function TaskDetailController(scope, rootscope, repo, confirm, rs, params, q, location, log, appTitle, navUrls, analytics, translate, tgLoader) { + function TaskDetailController(scope, rootscope, repo, confirm, rs, params, q, location, log, appMetaService, navUrls, analytics, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -14617,7 +14666,7 @@ this.q = q; this.location = location; this.log = log; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.navUrls = navUrls; this.analytics = analytics; this.translate = translate; @@ -14627,34 +14676,47 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - _this.appTitle.set(_this.scope.task.subject + " - " + _this.scope.project.name); + _this._setMeta(); return _this.initializeOnDeleteGoToUrl(); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); } + TaskDetailController.prototype._setMeta = function() { + var description, ref, title; + title = this.translate.instant("TASK.PAGE_TITLE", { + taskRef: "#" + this.scope.task.ref, + taskSubject: this.scope.task.subject, + projectName: this.scope.project.name + }); + description = this.translate.instant("TASK.PAGE_DESCRIPTION", { + taskStatus: ((ref = this.scope.statusById[this.scope.task.status]) != null ? ref.name : void 0) || "--", + taskDescription: angular.element(this.scope.task.description_html || "").text() + }); + return this.appMetaService.setAll(title, description); + }; + TaskDetailController.prototype.initializeEventHandlers = function() { this.scope.$on("attachment:create", (function(_this) { return function() { _this.analytics.trackEvent("attachment", "create", "create attachment on task", 1); - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); this.scope.$on("attachment:edit", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); this.scope.$on("attachment:delete", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); return this.scope.$on("custom-attributes-values:edit", (function(_this) { return function() { - return _this.rootscope.$broadcast("history:reload"); + return _this.rootscope.$broadcast("object:updated"); }; })(this)); }; @@ -14827,7 +14889,7 @@ $model.$setViewValue(task); onSuccess = function() { $confirm.notify("success"); - $rootScope.$broadcast("history:reload"); + $rootScope.$broadcast("object:updated"); return $loading.finish($el.find(".level-name")); }; onError = function() { @@ -14908,7 +14970,7 @@ promise = $tgrepo.save(task); promise.then(function() { $confirm.notify("success"); - return $rootscope.$broadcast("history:reload"); + return $rootscope.$broadcast("object:updated"); }); promise.then(null, function() { task.revert(); @@ -14984,9 +15046,9 @@ TeamController = (function(superClass) { extend(TeamController, superClass); - TeamController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgResources", "$routeParams", "$q", "$location", "$tgNavUrls", "$appTitle", "$tgAuth", "tgLoader", "$translate"]; + TeamController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgResources", "$routeParams", "$q", "$location", "$tgNavUrls", "tgAppMetaService", "$tgAuth", "$translate", "tgProjectService"]; - function TeamController(scope, rootscope, repo, rs, params, q, location, navUrls, appTitle, auth, tgLoader, translate) { + function TeamController(scope, rootscope, repo, rs, params, q, location, navUrls, appMetaService, auth, translate, projectService) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -14996,22 +15058,26 @@ this.q = q; this.location = location; this.navUrls = navUrls; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.auth = auth; this.translate = translate; + this.projectService = projectService; this.scope.sectionName = "TEAM.SECTION_NAME"; promise = this.loadInitialData(); promise.then((function(_this) { return function() { - var text; - text = _this.translate.instant("TEAM.APP_TITLE", { - "projectName": _this.scope.project.name + var description, title; + title = _this.translate.instant("TEAM.PAGE_TITLE", { + projectName: _this.scope.project.name }); - return _this.appTitle.set(text); + description = _this.translate.instant("TEAM.PAGE_DESCRIPTION", { + projectName: _this.scope.project.name, + projectDescription: _this.scope.project.description + }); + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); } TeamController.prototype.setRole = function(role) { @@ -15023,35 +15089,46 @@ }; TeamController.prototype.loadMembers = function() { - return this.rs.memberships.list(this.scope.projectId, {}, false).then((function(_this) { - return function(data) { - var currentUser, i, len, membership, ref; - currentUser = _this.auth.getUser(); - if ((currentUser != null) && (currentUser.photo == null)) { - currentUser.photo = "/images/unnamed.png"; - } - _this.scope.currentUser = _.find(data, function(membership) { - return (currentUser != null) && membership.user === currentUser.id; - }); - _this.scope.totals = {}; - _.forEach(data, function(membership) { - return _this.scope.totals[membership.user] = 0; - }); - _this.scope.memberships = _.filter(data, function(membership) { - if (membership.user && ((currentUser == null) || membership.user !== currentUser.id) && membership.is_user_active) { - return membership; - } - }); - ref = _this.scope.memberships; - for (i = 0, len = ref.length; i < len; i++) { - membership = ref[i]; - if (membership.photo == null) { - membership.photo = "/images/unnamed.png"; - } - } - return data; + var currentUser, i, len, membership, memberships, ref, results; + currentUser = this.auth.getUser(); + if ((currentUser != null) && (currentUser.photo == null)) { + currentUser.photo = "/images/unnamed.png"; + } + memberships = this.projectService.project.toJS().memberships; + this.scope.currentUser = _.find(memberships, (function(_this) { + return function(membership) { + return (currentUser != null) && membership.user === currentUser.id; }; })(this)); + this.scope.totals = {}; + _.forEach(memberships, (function(_this) { + return function(membership) { + return _this.scope.totals[membership.user] = 0; + }; + })(this)); + this.scope.memberships = _.filter(memberships, (function(_this) { + return function(membership) { + if (membership.user && ((currentUser == null) || membership.user !== currentUser.id)) { + return membership; + } + }; + })(this)); + this.scope.memberships = _.filter(memberships, (function(_this) { + return function(membership) { + return membership.is_active; + }; + })(this)); + ref = this.scope.memberships; + results = []; + for (i = 0, len = ref.length; i < len; i++) { + membership = ref[i]; + if (membership.photo == null) { + results.push(membership.photo = "/images/unnamed.png"); + } else { + results.push(void 0); + } + } + return results; }; TeamController.prototype.loadProject = function() { @@ -15121,9 +15198,8 @@ return promise.then((function(_this) { return function(project) { _this.fillUsersAndRoles(project.users, project.roles); - return _this.loadMembers().then(function() { - return _this.loadMemberStats(); - }); + _this.loadMembers(); + return _this.loadMemberStats(); }; })(this)); }; @@ -15281,9 +15357,9 @@ WikiDetailController = (function(superClass) { extend(WikiDetailController, superClass); - WikiDetailController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgModel", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$filter", "$log", "$appTitle", "$tgNavUrls", "$tgAnalytics", "tgLoader", "$translate"]; + WikiDetailController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgModel", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$filter", "$log", "tgAppMetaService", "$tgNavUrls", "$tgAnalytics", "$translate"]; - function WikiDetailController(scope, rootscope, repo, model, confirm, rs, params, q, location, filter, log, appTitle, navUrls, analytics, tgLoader, translate) { + function WikiDetailController(scope, rootscope, repo, model, confirm, rs, params, q, location, filter, log, appMetaService, navUrls, analytics, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -15296,7 +15372,7 @@ this.location = location; this.filter = filter; this.log = log; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.navUrls = navUrls; this.analytics = analytics; this.translate = translate; @@ -15306,13 +15382,26 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - return _this.appTitle.set("Wiki - " + _this.scope.project.name); + return _this._setMeta(); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); } + WikiDetailController.prototype._setMeta = function() { + var description, title; + title = this.translate.instant("WIKI.PAGE_TITLE", { + wikiPageName: this.scope.wiki.slug, + projectName: unslugify(this.scope.wiki.slug) + }); + description = this.translate.instant("WIKI.PAGE_DESCRIPTION", { + wikiPageContent: angular.element(this.scope.wiki.html || "").text(), + totalEditions: this.scope.wiki.editions || 0, + lastModifiedDate: moment(this.scope.wiki.modified_date).format(this.translate.instant("WIKI.DATETIME")) + }); + return this.appMetaService.setAll(title, description); + }; + WikiDetailController.prototype.loadProject = function() { return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { @@ -15372,7 +15461,7 @@ return promise.then((function(_this) { return function(project) { _this.fillUsersAndRoles(project.users, project.roles); - return _this.q.all([_this.loadWikiLinks(), _this.loadWiki()]); + return _this.q.all([_this.loadWikiLinks(), _this.loadWiki()]).then(function() {}); }; })(this)); }; @@ -15565,7 +15654,7 @@ } if (isEditable()) { $el.addClass('editable'); - if (wikiPage.id == null) { + if ((wikiPage.id == null) || $.trim(wikiPage.content).length === 0) { return switchToEditMode(); } } else { @@ -15944,9 +16033,9 @@ MembershipsController = (function(superClass) { extend(MembershipsController, superClass); - MembershipsController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "$tgAnalytics", "$appTitle"]; + MembershipsController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "$tgAnalytics", "tgAppMetaService", "$translate"]; - function MembershipsController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, analytics, appTitle) { + function MembershipsController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, analytics, appMetaService, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -15958,14 +16047,20 @@ this.location = location; this.navUrls = navUrls; this.analytics = analytics; - this.appTitle = appTitle; + this.appMetaService = appMetaService; + this.translate = translate; bindMethods(this); this.scope.project = {}; this.scope.filters = {}; promise = this.loadInitialData(); promise.then((function(_this) { return function() { - return _this.appTitle.set("Membership - " + _this.scope.project.name); + var description, title; + title = _this.translate.instant("ADMIN.MEMBERSHIPS.PAGE_TITLE", { + projectName: _this.scope.project.name + }); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); @@ -15978,11 +16073,12 @@ } MembershipsController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { if (!project.i_am_owner) { _this.location.path(_this.navUrls.resolve("permission-denied")); } + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.$emit('project:loaded', project); return project; @@ -16008,27 +16104,14 @@ MembershipsController.prototype.loadInitialData = function() { var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)).then((function(_this) { - return function() { - return _this.loadUsersAndRoles(); - }; - })(this)).then((function(_this) { + promise = this.loadProject(); + promise.then((function(_this) { return function() { + _this.loadUsersAndRoles(); return _this.loadMembers(); }; })(this)); + return promise; }; MembershipsController.prototype.getUrlFilters = function() { @@ -16461,9 +16544,9 @@ ProjectProfileController = (function(superClass) { extend(ProjectProfileController, superClass); - ProjectProfileController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "$appTitle", "$translate"]; + ProjectProfileController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "tgAppMetaService", "$translate"]; - function ProjectProfileController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, appTitle1, translate) { + function ProjectProfileController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, appMetaService, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -16474,41 +16557,44 @@ this.q = q; this.location = location; this.navUrls = navUrls; - this.appTitle = appTitle1; + this.appMetaService = appMetaService; this.translate = translate; this.scope.project = {}; promise = this.loadInitialData(); promise.then((function(_this) { return function() { - var appTitle, sectionName; + var description, sectionName, title; sectionName = _this.translate.instant(_this.scope.sectionName); - appTitle = _this.translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", { + title = _this.translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", { sectionName: sectionName, projectName: _this.scope.project.name }); - return _this.appTitle.set(appTitle); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); this.scope.$on("project:loaded", (function(_this) { return function() { - var appTitle, sectionName; + var description, sectionName, title; sectionName = _this.translate.instant(_this.scope.sectionName); - appTitle = _this.translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", { + title = _this.translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", { sectionName: sectionName, projectName: _this.scope.project.name }); - return _this.appTitle.set(appTitle); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); } ProjectProfileController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { if (!project.i_am_owner) { _this.location.path(_this.navUrls.resolve("permission-denied")); } + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.pointsList = _.sortBy(project.points, "order"); _this.scope.usStatusList = _.sortBy(project.us_statuses, "order"); @@ -16523,33 +16609,10 @@ })(this)); }; - ProjectProfileController.prototype.loadTagsColors = function() { - return this.rs.projects.tagsColors(this.scope.projectId).then((function(_this) { - return function(tags_colors) { - return _this.scope.project.tags_colors = tags_colors; - }; - })(this)); - }; - - ProjectProfileController.prototype.loadProjectProfile = function() { - return this.q.all([this.loadProject(), this.loadTagsColors()]); - }; - ProjectProfileController.prototype.loadInitialData = function() { var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProjectProfile(); - }; - })(this)); + promise = this.loadProject(); + return promise; }; ProjectProfileController.prototype.openDeleteLightbox = function() { @@ -16562,10 +16625,11 @@ module.controller("ProjectProfileController", ProjectProfileController); - ProjectProfileDirective = function($repo, $confirm, $loading, $navurls, $location) { + ProjectProfileDirective = function($repo, $confirm, $loading, $navurls, $location, projectService) { var link; link = function($scope, $el, $attrs) { - var form, submit, submitButton; + var $ctrl, form, submit, submitButton; + $ctrl = $el.controller(); form = $el.find("form").checksley({ "onlyOneErrorElement": true }); @@ -16586,7 +16650,8 @@ project: $scope.project.slug }); $location.path(newUrl); - return $scope.$emit("project:loaded", $scope.project); + $ctrl.loadInitialData(); + return projectService.fetchProject(); }); return promise.then(null, function(data) { $loading.finish(submitButton); @@ -16605,7 +16670,7 @@ }; }; - module.directive("tgProjectProfile", ["$tgRepo", "$tgConfirm", "$tgLoading", "$tgNavUrls", "$tgLocation", ProjectProfileDirective]); + module.directive("tgProjectProfile", ["$tgRepo", "$tgConfirm", "$tgLoading", "$tgNavUrls", "$tgLocation", "tgProjectService", ProjectProfileDirective]); ProjectDefaultValuesDirective = function($repo, $confirm, $loading) { var link; @@ -16649,7 +16714,7 @@ module.directive("tgProjectDefaultValues", ["$tgRepo", "$tgConfirm", "$tgLoading", ProjectDefaultValuesDirective]); - ProjectModulesDirective = function($repo, $confirm, $loading) { + ProjectModulesDirective = function($repo, $confirm, $loading, projectService) { var link; link = function($scope, $el, $attrs) { var form, submit; @@ -16666,7 +16731,8 @@ promise.then(function() { $loading.finish(target); $confirm.notify("success"); - return $scope.$emit("project:loaded", $scope.project); + $scope.$emit("project:loaded", $scope.project); + return projectService.fetchProject(); }); return promise.then(null, function(data) { $loading.finish(target); @@ -16704,7 +16770,7 @@ }; }; - module.directive("tgProjectModules", ["$tgRepo", "$tgConfirm", "$tgLoading", ProjectModulesDirective]); + module.directive("tgProjectModules", ["$tgRepo", "$tgConfirm", "$tgLoading", "tgProjectService", ProjectModulesDirective]); ProjectExportDirective = function($window, $rs, $confirm, $translate) { var link; @@ -17034,9 +17100,9 @@ ProjectValuesSectionController = (function(superClass) { extend(ProjectValuesSectionController, superClass); - ProjectValuesSectionController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "$appTitle", "$translate"]; + ProjectValuesSectionController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "tgAppMetaService", "$translate"]; - function ProjectValuesSectionController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, appTitle, translate) { + function ProjectValuesSectionController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, appMetaService, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -17047,30 +17113,32 @@ this.q = q; this.location = location; this.navUrls = navUrls; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.translate = translate; this.scope.project = {}; promise = this.loadInitialData(); promise.then((function(_this) { return function() { - var sectionName, title; + var description, sectionName, title; sectionName = _this.translate.instant(_this.scope.sectionName); - title = _this.translate.instant("ADMIN.PROJECT_VALUES.APP_TITLE", { + title = _this.translate.instant("ADMIN.PROJECT_VALUES.PAGE_TITLE", { "sectionName": sectionName, "projectName": _this.scope.project.name }); - return _this.appTitle.set(title); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); } ProjectValuesSectionController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { if (!project.i_am_owner) { _this.location.path(_this.navUrls.resolve("permission-denied")); } + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.$emit('project:loaded', project); return project; @@ -17080,19 +17148,8 @@ ProjectValuesSectionController.prototype.loadInitialData = function() { var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)); + promise = this.loadProject(); + return promise; }; return ProjectValuesSectionController; @@ -17146,9 +17203,8 @@ module.controller("ProjectValuesController", ProjectValuesController); - ProjectValuesDirective = function($log, $repo, $confirm, $location, animationFrame, translate, $rootscope) { + ProjectValuesDirective = function($log, $repo, $confirm, $location, animationFrame, $translate, $rootscope) { var link, linkDragAndDrop, linkValue; - this.translate = translate; linkDragAndDrop = function($scope, $el, $attrs) { var itemEl, newParentScope, oldParentScope, tdom; oldParentScope = null; @@ -17186,7 +17242,7 @@ }; }; initializeTextTranslations = function() { - return $scope.addNewElementText = this.translate.instant("ADMIN.PROJECT_VALUES_" + (objName.toUpperCase()) + ".ACTION_ADD"); + return $scope.addNewElementText = $translate.instant("ADMIN.PROJECT_VALUES_" + (objName.toUpperCase()) + ".ACTION_ADD"); }; initializeNewValue(); initializeTextTranslations(); @@ -17319,7 +17375,7 @@ return cancel(target); }); return $el.on("click", ".delete-value", function(event) { - var choices, formEl, subtitle, target, value; + var choices, formEl, subtitle, target, text, title, value; event.preventDefault(); target = angular.element(event.currentTarget); formEl = target.parents("form"); @@ -17334,7 +17390,9 @@ if (_.keys(choices).length === 0) { return $confirm.error("ADMIN.PROJECT_VALUES.ERROR_DELETE_ALL"); } - return $confirm.askChoice("PROJECT.TITLE_ACTION_DELETE_VALUE", subtitle, choices, "ADMIN.PROJECT_VALUES.REPLACEMENT").then(function(response) { + title = $translate.instant("ADMIN.COMMON.TITLE_ACTION_DELETE_VALUE"); + text = $translate.instant("ADMIN.PROJECT_VALUES.REPLACEMENT"); + return $confirm.askChoice(title, subtitle, choices, text).then(function(response) { var onError, onSucces; onSucces = function() { return $ctrl.loadValues()["finally"](function() { @@ -17420,9 +17478,9 @@ ProjectCustomAttributesController = (function(superClass) { extend(ProjectCustomAttributesController, superClass); - ProjectCustomAttributesController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "$appTitle"]; + ProjectCustomAttributesController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "tgAppMetaService", "$translate"]; - function ProjectCustomAttributesController(scope, rootscope, repo, rs, params, q, location, navUrls, appTitle) { + function ProjectCustomAttributesController(scope, rootscope, repo, rs, params, q, location, navUrls, appMetaService, translate) { this.scope = scope; this.rootscope = rootscope; this.repo = repo; @@ -17431,7 +17489,8 @@ this.q = q; this.location = location; this.navUrls = navUrls; - this.appTitle = appTitle; + this.appMetaService = appMetaService; + this.translate = translate; this.moveCustomAttributes = bind(this.moveCustomAttributes, this); this.deleteCustomAttribute = bind(this.deleteCustomAttribute, this); this.saveCustomAttribute = bind(this.saveCustomAttribute, this); @@ -17440,8 +17499,15 @@ this.scope.project = {}; this.rootscope.$on("project:loaded", (function(_this) { return function() { + var description, sectionName, title; _this.loadCustomAttributes(); - return _this.appTitle.set("Project Custom Attributes - " + _this.scope.sectionName + " - " + _this.scope.project.name); + sectionName = _this.translate.instant(_this.scope.sectionName); + title = _this.translate.instant("ADMIN.CUSTOM_ATTRIBUTES.PAGE_TITLE", { + "sectionName": sectionName, + "projectName": _this.scope.project.name + }); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); } @@ -17486,7 +17552,7 @@ module.controller("ProjectCustomAttributesController", ProjectCustomAttributesController); - ProjectCustomAttributesDirective = function($log, $confirm, animationFrame) { + ProjectCustomAttributesDirective = function($log, $confirm, animationFrame, $translate) { var link; link = function($scope, $el, $attrs) { var $ctrl, cancelCreate, cancelUpdate, create, deleteCustomAttribute, hideAddButton, hideCancelButton, hideCreateForm, hideEditForm, resetNewAttr, revertChangesInCustomAttribute, showAddButton, showCancelButton, showCreateForm, showEditForm, sortableEl, update; @@ -17670,10 +17736,12 @@ } }); deleteCustomAttribute = function(formEl) { - var attr, message; + var attr, message, text, title; attr = formEl.scope().attr; message = attr.name; - return $confirm.ask("COMMON.CUSTOM_ATTRIBUTES.DELETE", "COMMON.CUSTOM_ATTRIBUTES.CONFIRM_DELETE", message).then(function(finish) { + title = $translate.instant("COMMON.CUSTOM_ATTRIBUTES.DELETE"); + text = $translate.instant("COMMON.CUSTOM_ATTRIBUTES.CONFIRM_DELETE"); + return $confirm.ask(title, text, message).then(function(finish) { var onError, onSucces; onSucces = function() { return $ctrl.loadCustomAttributes()["finally"](function() { @@ -17700,7 +17768,7 @@ }; }; - module.directive("tgProjectCustomAttributes", ["$log", "$tgConfirm", "animationFrame", ProjectCustomAttributesDirective]); + module.directive("tgProjectCustomAttributes", ["$log", "$tgConfirm", "animationFrame", "$translate", ProjectCustomAttributesDirective]); }).call(this); @@ -17747,9 +17815,9 @@ RolesController = (function(superClass) { extend(RolesController, superClass); - RolesController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "$appTitle", "$translate"]; + RolesController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "tgAppMetaService", "$translate"]; - function RolesController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, appTitle, translate) { + function RolesController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, appMetaService, translate) { var promise; this.scope = scope; this.rootscope = rootscope; @@ -17760,7 +17828,7 @@ this.q = q; this.location = location; this.navUrls = navUrls; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.translate = translate; bindMethods(this); this.scope.sectionName = "ADMIN.MENU.PERMISSIONS"; @@ -17769,22 +17837,24 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - var title; - title = _this.translate.instant("ADMIN.ROLES.SECTION_NAME", { + var description, title; + title = _this.translate.instant("ADMIN.ROLES.PAGE_TITLE", { projectName: _this.scope.project.name }); - return _this.appTitle.set(title); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); } RolesController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { if (!project.i_am_owner) { _this.location.path(_this.navUrls.resolve("permission-denied")); } + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.$emit('project:loaded', project); _this.scope.anyComputableRole = _.some(_.map(project.roles, function(point) { @@ -17795,24 +17865,20 @@ })(this)); }; - RolesController.prototype.loadExternalUserRole = function(roles) { - var public_permission; - roles = roles.map(function(role) { - role.external_user = false; - return role; - }); - public_permission = { - "name": this.translate.instant("ADMIN.ROLES.EXTERNAL_USER"), - "permissions": this.scope.project.public_permissions, - "external_user": true - }; - roles.push(public_permission); - return roles; - }; - RolesController.prototype.loadRoles = function() { - return this.rs.roles.list(this.scope.projectId).then(this.loadExternalUserRole).then((function(_this) { + return this.rs.roles.list(this.scope.projectId).then((function(_this) { return function(roles) { + var public_permission; + roles = roles.map(function(role) { + role.external_user = false; + return role; + }); + public_permission = { + "name": _this.translate.instant("ADMIN.ROLES.EXTERNAL_USER"), + "permissions": _this.scope.project.public_permissions, + "external_user": true + }; + roles.push(public_permission); _this.scope.roles = roles; _this.scope.role = _this.scope.roles[0]; return roles; @@ -17822,27 +17888,13 @@ RolesController.prototype.loadInitialData = function() { var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)).then((function(_this) { - return function() { - return _this.loadUsersAndRoles(); - }; - })(this)).then((function(_this) { + promise = this.loadProject(); + promise.then((function(_this) { return function() { return _this.loadRoles(); }; })(this)); + return promise; }; RolesController.prototype.setRole = function(role) { @@ -18006,7 +18058,9 @@ $el.find(".new").addClass("hidden"); $el.find(".new").val(''); onSuccess = function(role) { - $scope.roles.push(role); + var insertPosition; + insertPosition = $scope.roles.length - 1; + $scope.roles.splice(insertPosition, 0, role); $ctrl.setRole(role); $el.find(".add-button").show(); return $ctrl.loadProject(); @@ -18302,9 +18356,9 @@ WebhooksController = (function(superClass) { extend(WebhooksController, superClass); - WebhooksController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "$tgLocation", "$tgNavUrls", "$appTitle", "$translate"]; + WebhooksController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "$tgLocation", "$tgNavUrls", "tgAppMetaService", "$translate"]; - function WebhooksController(scope, repo, rs, params, location, navUrls, appTitle, translate) { + function WebhooksController(scope, repo, rs, params, location, navUrls, appMetaService, translate) { var promise; this.scope = scope; this.repo = repo; @@ -18312,7 +18366,7 @@ this.params = params; this.location = location; this.navUrls = navUrls; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.translate = translate; bindMethods(this); this.scope.sectionName = "ADMIN.WEBHOOKS.SECTION_NAME"; @@ -18320,11 +18374,12 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - var text; - text = _this.translate.instant("ADMIN.WEBHOOKS.APP_TITLE", { - "projectName": _this.scope.project.name + var description, title; + title = _this.translate.instant("ADMIN.WEBHOOKS.PAGE_TITLE", { + projectName: _this.scope.project.name }); - return _this.appTitle.set(text); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); @@ -18340,11 +18395,12 @@ }; WebhooksController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { if (!project.i_am_owner) { _this.location.path(_this.navUrls.resolve("permission-denied")); } + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.$emit('project:loaded', project); return project; @@ -18354,23 +18410,13 @@ WebhooksController.prototype.loadInitialData = function() { var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)).then((function(_this) { + promise = this.loadProject(); + promise.then((function(_this) { return function() { return _this.loadWebhooks(); }; })(this)); + return promise; }; return WebhooksController; @@ -18622,15 +18668,15 @@ GithubController = (function(superClass) { extend(GithubController, superClass); - GithubController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "$appTitle", "$translate"]; + GithubController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "tgAppMetaService", "$translate"]; - function GithubController(scope, repo, rs, params, appTitle, translate) { + function GithubController(scope, repo, rs, params, appMetaService, translate) { var promise; this.scope = scope; this.repo = repo; this.rs = rs; this.params = params; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.translate = translate; bindMethods(this); this.scope.sectionName = this.translate.instant("ADMIN.GITHUB.SECTION_NAME"); @@ -18638,11 +18684,12 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - var title; - title = _this.translate.instant("ADMIN.GITHUB.APP_TITLE", { + var description, title; + title = _this.translate.instant("ADMIN.GITHUB.PAGE_TITLE", { projectName: _this.scope.project.name }); - return _this.appTitle.set(title); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); @@ -18657,8 +18704,9 @@ }; GithubController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.$emit('project:loaded', project); return project; @@ -18668,23 +18716,13 @@ GithubController.prototype.loadInitialData = function() { var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)).then((function(_this) { + promise = this.loadProject(); + promise.then((function(_this) { return function() { return _this.loadModules(); }; })(this)); + return promise; }; return GithubController; @@ -18696,15 +18734,15 @@ GitlabController = (function(superClass) { extend(GitlabController, superClass); - GitlabController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "$appTitle", "$translate"]; + GitlabController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "tgAppMetaService", "$translate"]; - function GitlabController(scope, repo, rs, params, appTitle, translate) { + function GitlabController(scope, repo, rs, params, appMetaService, translate) { var promise; this.scope = scope; this.repo = repo; this.rs = rs; this.params = params; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.translate = translate; bindMethods(this); this.scope.sectionName = this.translate.instant("ADMIN.GITLAB.SECTION_NAME"); @@ -18712,11 +18750,12 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - var title; - title = _this.translate.instant("ADMIN.GITLAB.APP_TITLE", { + var description, title; + title = _this.translate.instant("ADMIN.GITLAB.PAGE_TITLE", { projectName: _this.scope.project.name }); - return _this.appTitle.set(title); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); @@ -18736,8 +18775,9 @@ }; GitlabController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.$emit('project:loaded', project); return project; @@ -18747,23 +18787,13 @@ GitlabController.prototype.loadInitialData = function() { var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)).then((function(_this) { + promise = this.loadProject(); + promise.then((function(_this) { return function() { return _this.loadModules(); }; })(this)); + return promise; }; return GitlabController; @@ -18775,15 +18805,15 @@ BitbucketController = (function(superClass) { extend(BitbucketController, superClass); - BitbucketController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "$appTitle", "$translate"]; + BitbucketController.$inject = ["$scope", "$tgRepo", "$tgResources", "$routeParams", "tgAppMetaService", "$translate"]; - function BitbucketController(scope, repo, rs, params, appTitle, translate) { + function BitbucketController(scope, repo, rs, params, appMetaService, translate) { var promise; this.scope = scope; this.repo = repo; this.rs = rs; this.params = params; - this.appTitle = appTitle; + this.appMetaService = appMetaService; this.translate = translate; bindMethods(this); this.scope.sectionName = this.translate.instant("ADMIN.BITBUCKET.SECTION_NAME"); @@ -18791,11 +18821,12 @@ promise = this.loadInitialData(); promise.then((function(_this) { return function() { - var title; - title = _this.translate.instant("ADMIN.BITBUCKET.APP_TITLE", { + var description, title; + title = _this.translate.instant("ADMIN.BITBUCKET.PAGE_TITLE", { projectName: _this.scope.project.name }); - return _this.appTitle.set(title); + description = _this.scope.project.description; + return _this.appMetaService.setAll(title, description); }; })(this)); promise.then(null, this.onInitialDataError.bind(this)); @@ -18815,8 +18846,9 @@ }; BitbucketController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.$emit('project:loaded', project); return project; @@ -18826,23 +18858,13 @@ BitbucketController.prototype.loadInitialData = function() { var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)).then((function(_this) { + promise = this.loadProject(); + promise.then((function(_this) { return function() { return _this.loadModules(); }; })(this)); + return promise; }; return BitbucketController; @@ -19042,10 +19064,10 @@ module = angular.module("taigaProject"); - CreateProject = function($rootscope, $repo, $confirm, $location, $navurls, $rs, $projectUrl, $loading, lightboxService, $cacheFactory, $translate) { - var link; + CreateProject = function($rootscope, $repo, $confirm, $location, $navurls, $rs, $projectUrl, $loading, lightboxService, $cacheFactory, $translate, currentUserService) { + var directive, link; link = function($scope, $el, attrs) { - var form, onErrorSubmit, onSuccessSubmit, submit, submitButton; + var form, onErrorSubmit, onSuccessSubmit, openLightbox, submit, submitButton; $scope.data = {}; $scope.templates = []; form = $el.find("form").checksley({ @@ -19057,7 +19079,8 @@ $rootscope.$broadcast("projects:reload"); $confirm.notify("success", $translate.instant("COMMON.SAVE")); $location.url($projectUrl.get(response)); - return lightboxService.close($el); + lightboxService.close($el); + return currentUserService._loadProjects(); }; onErrorSubmit = function(response) { var error_field, error_step, i, len, ref, selectors; @@ -19086,7 +19109,7 @@ return promise.then(onSuccessSubmit, onErrorSubmit); }; })(this); - $scope.$on("projects:create", function() { + openLightbox = function() { $scope.data = { total_story_points: 100, total_milestones: 5 @@ -19111,7 +19134,7 @@ return timeout(600, function() { return $el.find(".progress-bar").addClass('step1'); }); - }); + }; $el.on("click", ".button-next", function(event) { var current, field, i, len, next, ref, step, valid; event.preventDefault(); @@ -19145,19 +19168,26 @@ }); submitButton = $el.find(".submit-button"); $el.on("submit", "form", submit); - return $el.on("click", ".close", function(event) { + $el.on("click", ".close", function(event) { event.preventDefault(); return lightboxService.close($el); }); + $scope.$on("$destroy", function() { + return $el.off(); + }); + return openLightbox(); }; - return { - link: link + directive = { + link: link, + templateUrl: "project/wizard-create-project.html", + scope: {} }; + return directive; }; - module.directive("tgLbCreateProject", ["$rootScope", "$tgRepo", "$tgConfirm", "$location", "$tgNavUrls", "$tgResources", "$projectUrl", "$tgLoading", "lightboxService", "$cacheFactory", "$translate", CreateProject]); + module.directive("tgLbCreateProject", ["$rootScope", "$tgRepo", "$tgConfirm", "$location", "$tgNavUrls", "$tgResources", "$projectUrl", "$tgLoading", "lightboxService", "$cacheFactory", "$translate", "tgCurrentUserService", CreateProject]); - DeleteProjectDirective = function($repo, $rootscope, $auth, $location, $navUrls, $confirm, lightboxService, tgLoader) { + DeleteProjectDirective = function($repo, $rootscope, $auth, $location, $navUrls, $confirm, lightboxService, tgLoader, currentUserService) { var link; link = function($scope, $el, $attrs) { var projectToDelete, submit; @@ -19178,7 +19208,8 @@ tgLoader.pageLoaded(); $rootscope.$broadcast("projects:reload"); $location.path($navUrls.resolve("home")); - return $confirm.notify("success"); + $confirm.notify("success"); + return currentUserService._loadProjects(); }); return promise.then(null, function() { $confirm.notify("error"); @@ -19199,331 +19230,7 @@ }; }; - module.directive("tgLbDeleteProject", ["$tgRepo", "$rootScope", "$tgAuth", "$tgLocation", "$tgNavUrls", "$tgConfirm", "lightboxService", "tgLoader", DeleteProjectDirective]); - -}).call(this); - - -/* - * Copyright (C) 2014 Andrey Antukh - * Copyright (C) 2014 Jesús Espino Garcia - * Copyright (C) 2014 David Barragán Merino -# - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. -# - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. -# - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . -# - * File: modules/common/attachments.coffee - */ - -(function() { - var ProjectController, ProjectsController, ProjectsListDirective, ProjectsPaginationDirective, bindOnce, module, taiga, - extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - hasProp = {}.hasOwnProperty; - - taiga = this.taiga; - - module = angular.module("taigaProject"); - - bindOnce = this.taiga.bindOnce; - - ProjectsController = (function(superClass) { - extend(ProjectsController, superClass); - - ProjectsController.$inject = ["$scope", "$q", "$tgResources", "$rootScope", "$tgNavUrls", "$tgAuth", "$tgLocation", "$appTitle", "$projectUrl", "tgLoader"]; - - function ProjectsController(scope, q, rs, rootscope, navUrls, auth, location, appTitle, projectUrl, tgLoader) { - var promise; - this.scope = scope; - this.q = q; - this.rs = rs; - this.rootscope = rootscope; - this.navUrls = navUrls; - this.auth = auth; - this.location = location; - this.appTitle = appTitle; - this.projectUrl = projectUrl; - this.appTitle.set("Projects"); - if (!this.auth.isAuthenticated()) { - this.location.path(this.navUrls.resolve("login")); - } - this.user = this.auth.getUser(); - this.projects = []; - promise = this.loadInitialData(); - promise.then((function(_this) { - return function() { - return _this.scope.$emit("projects:loaded", _this.projects); - }; - })(this)); - promise.then(null, this.onInitialDataError.bind(this)); - promise["finally"](tgLoader.pageLoaded); - } - - ProjectsController.prototype.loadInitialData = function() { - var ref; - return this.rs.projects.listByMember((ref = this.rootscope.user) != null ? ref.id : void 0).then((function(_this) { - return function(projects) { - var i, len, project; - _this.projects = { - 'recents': projects.slice(0, 8), - 'all': projects - }; - for (i = 0, len = projects.length; i < len; i++) { - project = projects[i]; - project.url = _this.projectUrl.get(project); - } - return projects; - }; - })(this)); - }; - - ProjectsController.prototype.newProject = function() { - return this.rootscope.$broadcast("projects:create"); - }; - - ProjectsController.prototype.logout = function() { - this.auth.logout(); - return this.location.path(this.navUrls.resolve("login")); - }; - - return ProjectsController; - - })(taiga.Controller); - - module.controller("ProjectsController", ProjectsController); - - ProjectController = (function(superClass) { - extend(ProjectController, superClass); - - ProjectController.$inject = ["$scope", "$tgResources", "$tgRepo", "$routeParams", "$q", "$rootScope", "$appTitle", "$tgLocation", "$tgNavUrls"]; - - function ProjectController(scope, rs, repo, params, q, rootscope, appTitle, location, navUrls) { - var promise; - this.scope = scope; - this.rs = rs; - this.repo = repo; - this.params = params; - this.q = q; - this.rootscope = rootscope; - this.appTitle = appTitle; - this.location = location; - this.navUrls = navUrls; - promise = this.loadInitialData(); - promise.then((function(_this) { - return function() { - _this.appTitle.set(_this.scope.project.name); - return _this.scope.$emit("regenerate:project-pagination"); - }; - })(this)); - promise.then(null, this.onInitialDataError.bind(this)); - } - - ProjectController.prototype.loadInitialData = function() { - var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadPageData(); - }; - })(this)).then((function(_this) { - return function() { - return _this.scope.$emit("project:loaded", _this.scope.project); - }; - })(this)); - }; - - ProjectController.prototype.loadPageData = function() { - return this.q.all([this.loadProjectStats(), this.loadProject()]); - }; - - ProjectController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { - return function(project) { - _this.scope.project = project; - return project; - }; - })(this)); - }; - - ProjectController.prototype.loadProjectStats = function() { - return this.rs.projects.stats(this.scope.projectId).then((function(_this) { - return function(stats) { - _this.scope.stats = stats; - return stats; - }; - })(this)); - }; - - return ProjectController; - - })(taiga.Controller); - - module.controller("ProjectController", ProjectController); - - ProjectsPaginationDirective = function($timeout) { - var link; - link = function($scope, $el, $attrs) { - var checkButtonVisibility, container, containerSize, hasNextPage, hasPagination, hasPrevPage, hide, nextBtn, nextPage, pageSize, prevBtn, prevPage, remove, render, visible; - prevBtn = $el.find(".v-pagination-previous"); - nextBtn = $el.find(".v-pagination-next"); - container = $el.find("ul"); - pageSize = 0; - containerSize = 0; - render = function() { - pageSize = $el.find(".v-pagination-list").height(); - if (container.find("li").length) { - if (hasPagination()) { - if (hasNextPage()) { - visible(nextBtn); - } else { - hide(nextBtn); - } - if (hasPrevPage()) { - return visible(prevBtn); - } else { - return hide(prevBtn); - } - } else { - return remove(); - } - } else { - return remove(); - } - }; - hasPagination = function() { - containerSize = container.height(); - return containerSize > pageSize; - }; - hasPrevPage = function(top) { - if (top == null) { - top = -parseInt(container.css('top'), 10) || 0; - } - return top !== 0; - }; - hasNextPage = function(top) { - containerSize = container.height(); - if (!top) { - top = -parseInt(container.css('top'), 10) || 0; - } - return containerSize > pageSize && top + pageSize < containerSize; - }; - nextPage = function(callback) { - var lastLi, maxTop, newTop, top; - top = parseInt(container.css('top'), 10); - newTop = top - pageSize; - lastLi = $el.find(".v-pagination-list li:last-child"); - maxTop = -((lastLi.position().top + lastLi.outerHeight()) - pageSize); - if (newTop < maxTop) { - newTop = maxTop; - } - container.animate({ - "top": newTop - }, callback); - return newTop; - }; - prevPage = function(callback) { - var newTop, top; - top = parseInt(container.css('top'), 10); - newTop = top + pageSize; - if (newTop > 0) { - newTop = 0; - } - container.animate({ - "top": newTop - }, callback); - return newTop; - }; - visible = function(element) { - return element.css('visibility', 'visible'); - }; - hide = function(element) { - return element.css('visibility', 'hidden'); - }; - checkButtonVisibility = function() {}; - remove = function() { - container.css('top', 0); - hide(prevBtn); - return hide(nextBtn); - }; - $el.on("click", ".v-pagination-previous", function(event) { - var newTop; - event.preventDefault(); - if (container.is(':animated')) { - return; - } - visible(nextBtn); - newTop = prevPage(); - if (!hasPrevPage(newTop)) { - return hide(prevBtn); - } - }); - $el.on("click", ".v-pagination-next", function(event) { - var newTop; - event.preventDefault(); - if (container.is(':animated')) { - return; - } - visible(prevBtn); - newTop = -nextPage(); - if (!hasNextPage(newTop)) { - return hide(nextBtn); - } - }); - $scope.$on("regenerate:project-pagination", function() { - remove(); - return render(); - }); - $(window).on("resize.projects-pagination", render); - return $scope.$on("$destroy", function() { - return $(window).off("resize.projects-pagination"); - }); - }; - return { - link: link - }; - }; - - module.directive("tgProjectsPagination", ['$timeout', ProjectsPaginationDirective]); - - ProjectsListDirective = function($compile, $template) { - var link, template; - template = $template.get('project/project-list.html', true); - link = function($scope, $el, $attrs, $ctrls) { - var render; - render = function(projects) { - $el.html($compile(template({ - projects: projects - }))($scope)); - return $scope.$emit("regenerate:project-pagination"); - }; - return $scope.$on("projects:loaded", function(ctx, projects) { - if (projects.all != null) { - return render(projects.all); - } - }); - }; - return { - link: link - }; - }; - - module.directive("tgProjectsList", ["$compile", "$tgTemplate", ProjectsListDirective]); + module.directive("tgLbDeleteProject", ["$tgRepo", "$rootScope", "$tgAuth", "$tgLocation", "$tgNavUrls", "$tgConfirm", "lightboxService", "tgLoader", "tgCurrentUserService", DeleteProjectDirective]); }).call(this); @@ -19770,9 +19477,9 @@ ContribController = (function(superClass) { extend(ContribController, superClass); - ContribController.$inject = ["$rootScope", "$scope", "$routeParams", "$tgRepo", "$tgResources", "$tgConfirm", "$appTitle"]; + ContribController.$inject = ["$rootScope", "$scope", "$routeParams", "$tgRepo", "$tgResources", "$tgConfirm"]; - function ContribController(rootScope, scope, params, repo, rs, confirm, appTitle) { + function ContribController(rootScope, scope, params, repo, rs, confirm) { var promise; this.rootScope = rootScope; this.scope = scope; @@ -19780,7 +19487,6 @@ this.repo = repo; this.rs = rs; this.confirm = confirm; - this.appTitle = appTitle; this.scope.adminPlugins = _.where(this.rootScope.contribPlugins, { "type": "admin" }); @@ -19790,11 +19496,6 @@ this.scope.pluginTemplate = "contrib/" + this.scope.currentPlugin.slug; this.scope.projectSlug = this.params.pslug; promise = this.loadInitialData(); - promise.then((function(_this) { - return function() { - return _this.appTitle.set(_this.scope.project.name); - }; - })(this)); promise.then(null, (function(_this) { return function() { return _this.confirm.notify("error"); @@ -19803,8 +19504,9 @@ } ContribController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { + return this.rs.projects.getBySlug(this.params.pslug).then((function(_this) { return function(project) { + _this.scope.projectId = project.id; _this.scope.project = project; _this.scope.$emit('project:loaded', project); _this.scope.$broadcast('project:loaded', project); @@ -19814,20 +19516,7 @@ }; ContribController.prototype.loadInitialData = function() { - var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)); + return this.loadProject(); }; return ContribController; @@ -19927,24 +19616,27 @@ HttpService = (function(superClass) { extend(HttpService, superClass); - HttpService.$inject = ["$http", "$q", "$tgStorage", "$rootScope"]; + HttpService.$inject = ["$http", "$q", "$tgStorage", "$rootScope", "$cacheFactory", "$translate"]; - function HttpService(http, q, storage, rootScope) { + function HttpService(http, q, storage, rootScope, cacheFactory, translate) { this.http = http; this.q = q; this.storage = storage; this.rootScope = rootScope; + this.cacheFactory = cacheFactory; + this.translate = translate; HttpService.__super__.constructor.call(this); + this.cache = this.cacheFactory("httpget"); } HttpService.prototype.headers = function() { - var headers, lang, ref, token; + var headers, lang, token; headers = {}; token = this.storage.get('token'); if (token) { headers["Authorization"] = "Bearer " + token; } - lang = (ref = this.rootScope.user) != null ? ref.lang : void 0; + lang = this.translate.preferredLanguage(); if (lang) { headers["Accept-Language"] = lang; } @@ -19967,7 +19659,12 @@ if (params) { options.params = params; } - return this.request(options); + options.cache = this.cache; + return this.request(options)["finally"]((function(_this) { + return function(data) { + return _this.cache.removeAll(); + }; + })(this)); }; HttpService.prototype.post = function(url, data, params, options) { @@ -20073,7 +19770,7 @@ }; $location.isInCurrentRouteParams = function(name, value) { var params; - params = _.merge($route.current.params, $location.search()); + params = $location.search() || {}; return params[name] === value; }; return $location; @@ -20444,6 +20141,9 @@ target.attr("href", fullUrl); } return $el.on("click", function(event) { + if (event.metaKey || event.ctrlKey) { + return; + } event.preventDefault(); target = $(event.currentTarget); if (target.hasClass('noclick')) { @@ -20776,6 +20476,32 @@ })(this)); }; + RepositoryService.prototype.queryOnePaginatedRaw = function(name, id, params, options) { + var httpOptions, url; + if (options == null) { + options = {}; + } + url = this.urls.resolve(name); + if (id) { + url = url + "/" + id; + } + httpOptions = _.merge({ + headers: {} + }, options); + return this.http.get(url, params, httpOptions).then((function(_this) { + return function(data) { + var headers, result; + headers = data.headers(); + result = {}; + result.data = data.data; + result.count = parseInt(headers["x-pagination-count"], 10); + result.current = parseInt(headers["x-pagination-current"] || 1, 10); + result.paginatedBy = parseInt(headers["x-paginated-by"], 10); + return result; + }; + })(this)); + }; + RepositoryService.prototype.resolve = function(options) { var cache, params; params = {}; @@ -21382,6 +21108,9 @@ params.ref = ref; return $repo.queryOne("issues", "by_ref", params); }; + service.listInAllProjects = function(filters) { + return $repo.queryMany("issues", filters); + }; service.list = function(projectId, filters, options) { var params; params = { @@ -21874,7 +21603,8 @@ service.listByMember = function(memberId) { var params; params = { - "member": memberId + "member": memberId, + "order_by": "memberships__user_order" }; return $repo.queryMany("projects", params); }; @@ -21898,6 +21628,11 @@ service.stats = function(projectId) { return $repo.queryOneRaw("projects", projectId + "/stats"); }; + service.bulkUpdateOrder = function(bulkData) { + var url; + url = $urls.resolve("bulk-update-projects-order"); + return $http.post(url, bulkData); + }; service.regenerate_userstories_csv_uuid = function(projectId) { var url; url = ($urls.resolve("projects")) + "/" + projectId + "/regenerate_userstories_csv_uuid"; @@ -22244,6 +21979,9 @@ params.ref = ref; return $repo.queryOne("tasks", "by_ref", params); }; + service.listInAllProjects = function(filters) { + return $repo.queryMany("tasks", filters); + }; service.list = function(projectId, sprintId, userStoryId) { var params; if (sprintId == null) { @@ -22423,6 +22161,65 @@ }).call(this); +/* + * Copyright (C) 2014 Andrey Antukh + * Copyright (C) 2014 Jesús Espino Garcia + * Copyright (C) 2014 David Barragán Merino +# + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. +# + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. +# + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +# + * File: modules/resources/user.coffee + */ + +(function() { + var module, resourceProvider, sizeFormat, taiga; + + taiga = this.taiga; + + sizeFormat = this.taiga.sizeFormat; + + resourceProvider = function($http, $urls) { + var service; + service = {}; + service.contacts = function(userId, options) { + var httpOptions, url; + if (options == null) { + options = {}; + } + url = $urls.resolve("contacts", userId); + httpOptions = { + headers: {} + }; + if (!options.enablePagination) { + httpOptions.headers["x-disable-pagination"] = "1"; + } + return $http.get(url, {}, httpOptions).then(function(result) { + return result.data; + }); + }; + return function(instance) { + return instance.users = service; + }; + }; + + module = angular.module("taigaResources"); + + module.factory("$tgUsersResourcesProvider", ["$tgHttp", "$tgUrls", "$q", resourceProvider]); + +}).call(this); + + /* * Copyright (C) 2014 Andrey Antukh * Copyright (C) 2014 Jesús Espino Garcia @@ -22468,6 +22265,9 @@ params.ref = ref; return $repo.queryOne("userstories", "by_ref", params); }; + service.listInAllProjects = function(filters) { + return $repo.queryMany("userstories", filters); + }; service.listUnassigned = function(projectId, filters) { var params; params = { @@ -22716,7 +22516,6 @@ UserChangePasswordController.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "$tgAuth", "$translate"]; function UserChangePasswordController(scope, rootscope, repo, confirm, rs, params, q, location, navUrls, auth, translate) { - var promise; this.scope = scope; this.rootscope = rootscope; this.repo = repo; @@ -22729,39 +22528,9 @@ this.auth = auth; this.translate = translate; this.scope.sectionName = this.translate.instant("CHANGE_PASSWORD.SECTION_NAME"); - this.scope.project = {}; this.scope.user = this.auth.getUser(); - promise = this.loadInitialData(); - promise.then(null, this.onInitialDataError.bind(this)); } - UserChangePasswordController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { - return function(project) { - _this.scope.project = project; - _this.scope.$emit('project:loaded', project); - return project; - }; - })(this)); - }; - - UserChangePasswordController.prototype.loadInitialData = function() { - var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)); - }; - return UserChangePasswordController; })(mixOf(taiga.Controller, taiga.PageMixin)); @@ -22924,7 +22693,7 @@ UserSettingsController.$inject = ["$scope", "$rootScope", "$tgConfig", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$tgLocation", "$tgNavUrls", "$tgAuth", "$translate"]; function UserSettingsController(scope, rootscope, config, repo, confirm, rs, params, q, location, navUrls, auth, translate) { - var maxFileSize, promise; + var maxFileSize, promise, text; this.scope = scope; this.rootscope = rootscope; this.config = config; @@ -22940,32 +22709,23 @@ this.scope.sectionName = "USER_SETTINGS.MENU.SECTION_TITLE"; this.scope.project = {}; this.scope.user = this.auth.getUser(); + if (!this.scope.user) { + this.location.path(this.navUrls.resolve("permission-denied")); + this.location.replace(); + } this.scope.lang = this.getLan(); maxFileSize = this.config.get("maxUploadFileSize", null); if (maxFileSize) { - this.translate("USER_SETTINGS.AVATAR_MAX_SIZE", { + text = this.translate.instant("USER_SETTINGS.AVATAR_MAX_SIZE", { "maxFileSize": sizeFormat(maxFileSize) - }).then((function(_this) { - return function(text) { - return _this.scope.maxFileSizeMsg = text; - }; - })(this)); + }); + this.scope.maxFileSizeMsg = text; } promise = this.loadInitialData(); promise.then(null, this.onInitialDataError.bind(this)); } - UserSettingsController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { - return function(project) { - _this.scope.project = project; - _this.scope.$emit('project:loaded', project); - return project; - }; - })(this)); - }; - - UserSettingsController.prototype.loadLocales = function() { + UserSettingsController.prototype.loadInitialData = function() { return this.rs.locales.list().then((function(_this) { return function(locales) { _this.scope.locales = locales; @@ -22974,25 +22734,6 @@ })(this)); }; - UserSettingsController.prototype.loadInitialData = function() { - var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return this.q.all([ - promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)), this.loadLocales() - ]); - }; - UserSettingsController.prototype.openDeleteLightbox = function() { return this.rootscope.$broadcast("deletelightbox:new", this.scope.user); }; @@ -23217,23 +22958,12 @@ this.navUrls = navUrls; this.auth = auth; this.scope.sectionName = "USER_SETTINGS.NOTIFICATIONS.SECTION_NAME"; - this.scope.project = {}; this.scope.user = this.auth.getUser(); promise = this.loadInitialData(); promise.then(null, this.onInitialDataError.bind(this)); } - UserNotificationsController.prototype.loadProject = function() { - return this.rs.projects.get(this.scope.projectId).then((function(_this) { - return function(project) { - _this.scope.project = project; - _this.scope.$emit('project:loaded', project); - return project; - }; - })(this)); - }; - - UserNotificationsController.prototype.loadNotifyPolicies = function() { + UserNotificationsController.prototype.loadInitialData = function() { return this.rs.notifyPolicies.list().then((function(_this) { return function(notifyPolicies) { _this.scope.notifyPolicies = notifyPolicies; @@ -23242,27 +22972,6 @@ })(this)); }; - UserNotificationsController.prototype.loadInitialData = function() { - var promise; - promise = this.repo.resolve({ - pslug: this.params.pslug - }).then((function(_this) { - return function(data) { - _this.scope.projectId = data.project; - return data; - }; - })(this)); - return promise.then((function(_this) { - return function() { - return _this.loadProject(); - }; - })(this)).then((function(_this) { - return function() { - return _this.loadNotifyPolicies(); - }; - })(this)); - }; - return UserNotificationsController; })(mixOf(taiga.Controller, taiga.PageMixin)); @@ -23352,6 +23061,2563 @@ }).call(this); +(function() { + var module; + + module = angular.module("taigaHome", []); + +}).call(this); + +(function() { + angular.module("taigaNavigationBar", []); + +}).call(this); + +(function() { + var module; + + module = angular.module("taigaProfile", []); + +}).call(this); + +(function() { + angular.module("taigaProjects", []); + +}).call(this); + +(function() { + angular.module("taigaResources2", []); + +}).call(this); + +(function() { + angular.module("taigaUserTimeline", []); + +}).call(this); + +(function() { + var ProjectMenuController; + + ProjectMenuController = (function() { + ProjectMenuController.$inject = ["tgProjectService", "tgLightboxFactory"]; + + function ProjectMenuController(projectService, lightboxFactory) { + this.projectService = projectService; + this.lightboxFactory = lightboxFactory; + this.project = null; + this.menu = Immutable.Map(); + } + + ProjectMenuController.prototype.show = function() { + this.project = this.projectService.project; + this.active = this._getActiveSection(); + this._setVideoConference(); + return this._setMenuPermissions(); + }; + + ProjectMenuController.prototype.hide = function() { + this.project = null; + return this.menu = {}; + }; + + ProjectMenuController.prototype.search = function() { + return this.lightboxFactory.create("tg-search-box", { + "class": "lightbox lightbox-search" + }); + }; + + ProjectMenuController.prototype._setVideoConference = function() { + var videoconferenceUrl; + videoconferenceUrl = this._videoConferenceUrl(); + if (videoconferenceUrl) { + return this.project = this.project.set("videoconferenceUrl", videoconferenceUrl); + } + }; + + ProjectMenuController.prototype._setMenuPermissions = function() { + this.menu = Immutable.Map({ + backlog: false, + kanban: false, + issues: false, + wiki: false + }); + if (this.project.get("is_backlog_activated") && this.project.get("my_permissions").indexOf("view_us") !== -1) { + this.menu = this.menu.set("backlog", true); + } + if (this.project.get("is_kanban_activated") && this.project.get("my_permissions").indexOf("view_us") !== -1) { + this.menu = this.menu.set("kanban", true); + } + if (this.project.get("is_issues_activated") && this.project.get("my_permissions").indexOf("view_issues") !== -1) { + this.menu = this.menu.set("issues", true); + } + if (this.project.get("is_wiki_activated") && this.project.get("my_permissions").indexOf("view_wiki_pages") !== -1) { + return this.menu = this.menu.set("wiki", true); + } + }; + + ProjectMenuController.prototype._getActiveSection = function() { + var indexBacklog, indexKanban, oldSectionName, sectionName, sectionsBreadcrumb; + sectionName = this.projectService.section; + sectionsBreadcrumb = this.projectService.sectionsBreadcrumb; + indexBacklog = sectionsBreadcrumb.lastIndexOf("backlog"); + indexKanban = sectionsBreadcrumb.lastIndexOf("kanban"); + if (indexBacklog !== -1 || indexKanban !== -1) { + if (indexKanban === -1 || indexBacklog < indexKanban) { + oldSectionName = "backlog"; + } else { + oldSectionName = "kanban"; + } + } + if (sectionName === "backlog-kanban") { + if (oldSectionName === "backlog" || oldSectionName === "kanban") { + sectionName = oldSectionName; + } else if (this.project.get("is_backlog_activated") && !this.project.get("is_kanban_activated")) { + sectionName = "backlog"; + } else if (!this.project.get("is_backlog_activated") && this.project.get("is_kanban_activated")) { + sectionName = "kanban"; + } + } + return sectionName; + }; + + ProjectMenuController.prototype._videoConferenceUrl = function() { + var baseUrl, url; + if (this.project.get("videoconferences") === "appear-in") { + baseUrl = "https://appear.in/"; + } else if (this.project.get("videoconferences") === "talky") { + baseUrl = "https://talky.io/"; + } else if (this.project.get("videoconferences") === "jitsi") { + baseUrl = "https://meet.jit.si/"; + } else { + return ""; + } + if (this.project.get("videoconferences_salt")) { + url = this.project.get("slug") + "-" + this.project.get("videoconferences_salt"); + } else { + url = this.project.get("slug"); + } + return baseUrl + url; + }; + + return ProjectMenuController; + + })(); + + angular.module("taigaComponents").controller("ProjectMenu", ProjectMenuController); + +}).call(this); + +(function() { + var ProjectMenuDirective, taiga; + + taiga = this.taiga; + + ProjectMenuDirective = function(projectService, lightboxFactory) { + var link; + link = function(scope, el, attrs, ctrl) { + var projectChange; + projectChange = function() { + if (projectService.project) { + return ctrl.show(); + } else { + return ctrl.hide(); + } + }; + return scope.$watch((function() { + return projectService.project; + }), projectChange); + }; + return { + scope: {}, + controller: "ProjectMenu", + controllerAs: "vm", + templateUrl: "components/project-menu/project-menu.html", + link: link + }; + }; + + ProjectMenuDirective.$inject = ["tgProjectService", "tgLightboxFactory"]; + + angular.module("taigaComponents").directive("tgProjectMenu", ProjectMenuDirective); + +}).call(this); + +(function() { + var FeedbackService, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + FeedbackService = (function(superClass) { + extend(FeedbackService, superClass); + + FeedbackService.$inject = ["tgLightboxFactory"]; + + function FeedbackService(lightboxFactory) { + this.lightboxFactory = lightboxFactory; + } + + FeedbackService.prototype.sendFeedback = function() { + return this.lightboxFactory.create("tg-lb-feedback", { + "class": "lightbox lightbox-feedback lightbox-generic-form" + }); + }; + + return FeedbackService; + + })(taiga.Service); + + angular.module("taigaFeedback").service("tgFeedbackService", FeedbackService); + +}).call(this); + +(function() { + var DutyDirective; + + DutyDirective = function(navurls, $translate) { + var link; + link = function(scope, el, attrs, ctrl) { + scope.vm = {}; + scope.vm.duty = scope.duty; + return scope.vm.getDutyType = function() { + if (scope.vm.duty) { + if (scope.vm.duty.get('_name') === "userstories") { + return $translate.instant("COMMON.USER_STORY"); + } + if (scope.vm.duty.get('_name') === "tasks") { + return $translate.instant("COMMON.TASK"); + } + if (scope.vm.duty.get('_name') === "issues") { + return $translate.instant("COMMON.ISSUE"); + } + } + }; + }; + return { + templateUrl: "home/duties/duty.html", + scope: { + "duty": "=tgDuty" + }, + link: link + }; + }; + + DutyDirective.$inject = ["$tgNavUrls", "$translate"]; + + angular.module("taigaHome").directive("tgDuty", DutyDirective); + +}).call(this); + +(function() { + var HomeService, groupBy, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + groupBy = this.taiga.groupBy; + + HomeService = (function(superClass) { + extend(HomeService, superClass); + + HomeService.$inject = ["$tgNavUrls", "tgResources", "tgProjectsService"]; + + function HomeService(navurls, rs, projectsService) { + this.navurls = navurls; + this.rs = rs; + this.projectsService = projectsService; + } + + HomeService.prototype._attachProjectInfoToWorkInProgress = function(workInProgress, projectsById) { + var _attachProjectInfoToDuty, _duties, assignedTo, watching; + _attachProjectInfoToDuty = (function(_this) { + return function(duty, objType) { + var ctx, project, url; + project = projectsById.get(String(duty.get('project'))); + ctx = { + project: project.get('slug'), + ref: duty.get('ref') + }; + url = _this.navurls.resolve("project-" + objType + "-detail", ctx); + duty = duty.set('url', url); + duty = duty.set('projectName', project.get('name')); + duty = duty.set("_name", objType); + return duty; + }; + })(this); + assignedTo = workInProgress.get("assignedTo"); + if (assignedTo.get("userStories")) { + _duties = assignedTo.get("userStories").map(function(duty) { + return _attachProjectInfoToDuty(duty, "userstories"); + }); + assignedTo = assignedTo.set("userStories", _duties); + } + if (assignedTo.get("tasks")) { + _duties = assignedTo.get("tasks").map(function(duty) { + return _attachProjectInfoToDuty(duty, "tasks"); + }); + assignedTo = assignedTo.set("tasks", _duties); + } + if (assignedTo.get("issues")) { + _duties = assignedTo.get("issues").map(function(duty) { + return _attachProjectInfoToDuty(duty, "issues"); + }); + assignedTo = assignedTo.set("issues", _duties); + } + watching = workInProgress.get("watching"); + if (watching.get("userStories")) { + _duties = watching.get("userStories").map(function(duty) { + return _attachProjectInfoToDuty(duty, "userstories"); + }); + watching = watching.set("userStories", _duties); + } + if (watching.get("tasks")) { + _duties = watching.get("tasks").map(function(duty) { + return _attachProjectInfoToDuty(duty, "tasks"); + }); + watching = watching.set("tasks", _duties); + } + if (watching.get("issues")) { + _duties = watching.get("issues").map(function(duty) { + return _attachProjectInfoToDuty(duty, "issues"); + }); + watching = watching.set("issues", _duties); + } + workInProgress = workInProgress.set("assignedTo", assignedTo); + return workInProgress = workInProgress.set("watching", watching); + }; + + HomeService.prototype.getWorkInProgress = function(userId) { + var assignedIssuesPromise, assignedTasksPromise, assignedTo, assignedUserStoriesPromise, params, params_us, projectsById, projectsPromise, watching, watchingIssuesPromise, watchingTasksPromise, watchingUserStoriesPromise, workInProgress; + projectsById = Immutable.Map(); + projectsPromise = this.projectsService.getProjectsByUserId(userId).then(function(projects) { + return projectsById = Immutable.fromJS(groupBy(projects.toJS(), function(p) { + return p.id; + })); + }); + assignedTo = Immutable.Map(); + params = { + status__is_closed: false, + assigned_to: userId + }; + params_us = { + is_closed: false, + assigned_to: userId + }; + assignedUserStoriesPromise = this.rs.userstories.listInAllProjects(params_us).then(function(userstories) { + return assignedTo = assignedTo.set("userStories", userstories); + }); + assignedTasksPromise = this.rs.tasks.listInAllProjects(params).then(function(tasks) { + return assignedTo = assignedTo.set("tasks", tasks); + }); + assignedIssuesPromise = this.rs.issues.listInAllProjects(params).then(function(issues) { + return assignedTo = assignedTo.set("issues", issues); + }); + params = { + status__is_closed: false, + watchers: userId + }; + params_us = { + is_closed: false, + watchers: userId + }; + watching = Immutable.Map(); + watchingUserStoriesPromise = this.rs.userstories.listInAllProjects(params_us).then(function(userstories) { + return watching = watching.set("userStories", userstories); + }); + watchingTasksPromise = this.rs.tasks.listInAllProjects(params).then(function(tasks) { + return watching = watching.set("tasks", tasks); + }); + watchingIssuesPromise = this.rs.issues.listInAllProjects(params).then(function(issues) { + return watching = watching.set("issues", issues); + }); + workInProgress = Immutable.Map(); + return Promise.all([projectsPromise, assignedUserStoriesPromise, assignedTasksPromise, assignedIssuesPromise, watchingUserStoriesPromise, watchingTasksPromise, watchingIssuesPromise]).then((function(_this) { + return function() { + workInProgress = workInProgress.set("assignedTo", assignedTo); + workInProgress = workInProgress.set("watching", watching); + workInProgress = _this._attachProjectInfoToWorkInProgress(workInProgress, projectsById); + return workInProgress; + }; + })(this)); + }; + + return HomeService; + + })(taiga.Service); + + angular.module("taigaHome").service("tgHomeService", HomeService); + +}).call(this); + +(function() { + var HomeProjectListDirective; + + HomeProjectListDirective = function(currentUserService, projectsService) { + var directive, link; + link = function(scope, el, attrs, ctrl) { + scope.vm = {}; + taiga.defineImmutableProperty(scope.vm, "projects", function() { + return currentUserService.projects.get("recents"); + }); + return scope.vm.newProject = function() { + return projectsService.newProject(); + }; + }; + directive = { + templateUrl: "home/projects/home-project-list.html", + scope: {}, + link: link + }; + return directive; + }; + + HomeProjectListDirective.$inject = ["tgCurrentUserService", "tgProjectsService"]; + + angular.module("taigaHome").directive("tgHomeProjectList", HomeProjectListDirective); + +}).call(this); + +(function() { + var WorkingOnController; + + WorkingOnController = (function() { + WorkingOnController.$inject = ["tgHomeService"]; + + function WorkingOnController(homeService) { + this.homeService = homeService; + this.assignedTo = Immutable.Map(); + this.watching = Immutable.Map(); + } + + WorkingOnController.prototype._setAssignedTo = function(workInProgress) { + var issues, tasks, userStories; + userStories = workInProgress.get("assignedTo").get("userStories"); + tasks = workInProgress.get("assignedTo").get("tasks"); + issues = workInProgress.get("assignedTo").get("issues"); + this.assignedTo = userStories.concat(tasks).concat(issues); + if (this.assignedTo.size > 0) { + return this.assignedTo = this.assignedTo.sortBy(function(elem) { + return elem.get("modified_date"); + }).reverse(); + } + }; + + WorkingOnController.prototype._setWatching = function(workInProgress) { + var issues, tasks, userStories; + userStories = workInProgress.get("watching").get("userStories"); + tasks = workInProgress.get("watching").get("tasks"); + issues = workInProgress.get("watching").get("issues"); + this.watching = userStories.concat(tasks).concat(issues); + if (this.watching.size > 0) { + return this.watching = this.watching.sortBy(function(elem) { + return elem.get("modified_date"); + }).reverse(); + } + }; + + WorkingOnController.prototype.getWorkInProgress = function(userId) { + return this.homeService.getWorkInProgress(userId).then((function(_this) { + return function(workInProgress) { + _this._setAssignedTo(workInProgress); + return _this._setWatching(workInProgress); + }; + })(this)); + }; + + return WorkingOnController; + + })(); + + angular.module("taigaHome").controller("WorkingOn", WorkingOnController); + +}).call(this); + +(function() { + var WorkingOnDirective; + + WorkingOnDirective = function(homeService, currentUserService) { + var link; + link = function(scope, el, attrs, ctrl) { + var userId; + userId = currentUserService.getUser().get("id"); + return ctrl.getWorkInProgress(userId); + }; + return { + controller: "WorkingOn", + controllerAs: "vm", + templateUrl: "home/working-on/working-on.html", + scope: {}, + link: link + }; + }; + + WorkingOnDirective.$inject = ["tgHomeService", "tgCurrentUserService"]; + + angular.module("taigaHome").directive("tgWorkingOn", WorkingOnDirective); + +}).call(this); + +(function() { + var DropdownProjectListDirective; + + DropdownProjectListDirective = function(currentUserService, projectsService) { + var directive, link; + link = function(scope, el, attrs, ctrl) { + scope.vm = {}; + taiga.defineImmutableProperty(scope.vm, "projects", function() { + return currentUserService.projects.get("recents"); + }); + return scope.vm.newProject = function() { + return projectsService.newProject(); + }; + }; + directive = { + templateUrl: "navigation-bar/dropdown-project-list/dropdown-project-list.html", + scope: {}, + link: link + }; + return directive; + }; + + DropdownProjectListDirective.$inject = ["tgCurrentUserService", "tgProjectsService"]; + + angular.module("taigaNavigationBar").directive("tgDropdownProjectList", DropdownProjectListDirective); + +}).call(this); + +(function() { + var DropdownUserDirective; + + DropdownUserDirective = function(authService, configService, locationService, navUrlsService, feedbackService) { + var directive, link; + link = function(scope, el, attrs, ctrl) { + scope.vm = {}; + scope.vm.isFeedbackEnabled = configService.get("feedbackEnabled"); + taiga.defineImmutableProperty(scope.vm, "user", function() { + return authService.userData; + }); + scope.vm.logout = function() { + authService.logout(); + return locationService.path(navUrlsService.resolve("login")); + }; + return scope.vm.sendFeedback = function() { + return feedbackService.sendFeedback(); + }; + }; + directive = { + templateUrl: "navigation-bar/dropdown-user/dropdown-user.html", + scope: {}, + link: link + }; + return directive; + }; + + DropdownUserDirective.$inject = ["$tgAuth", "$tgConfig", "$tgLocation", "$tgNavUrls", "tgFeedbackService"]; + + angular.module("taigaNavigationBar").directive("tgDropdownUser", DropdownUserDirective); + +}).call(this); + +(function() { + var NavigationBarDirective; + + NavigationBarDirective = function(currentUserService, $location) { + var directive, link; + link = function(scope, el, attrs, ctrl) { + scope.vm = {}; + scope.$on("$routeChangeSuccess", function() { + if ($location.path() === "/") { + return scope.vm.active = true; + } else { + return scope.vm.active = false; + } + }); + taiga.defineImmutableProperty(scope.vm, "projects", function() { + return currentUserService.projects.get("recents"); + }); + return taiga.defineImmutableProperty(scope.vm, "isAuthenticated", function() { + return currentUserService.isAuthenticated(); + }); + }; + directive = { + templateUrl: "navigation-bar/navigation-bar.html", + scope: {}, + link: link + }; + return directive; + }; + + NavigationBarDirective.$inject = ["tgCurrentUserService", "$location"]; + + angular.module("taigaNavigationBar").directive("tgNavigationBar", NavigationBarDirective); + +}).call(this); + +(function() { + var ProfileBarController; + + ProfileBarController = (function() { + ProfileBarController.$inject = ["tgUserService"]; + + function ProfileBarController(userService) { + this.userService = userService; + this.loadStats(); + } + + ProfileBarController.prototype.loadStats = function() { + return this.userService.getStats(this.user.get("id")).then((function(_this) { + return function(stats) { + return _this.stats = stats; + }; + })(this)); + }; + + return ProfileBarController; + + })(); + + angular.module("taigaProfile").controller("ProfileBar", ProfileBarController); + +}).call(this); + +(function() { + var ProfileBarDirective; + + ProfileBarDirective = function() { + return { + templateUrl: "profile/profile-bar/profile-bar.html", + controller: "ProfileBar", + controllerAs: "vm", + scope: { + user: "=user", + isCurrentUser: "=iscurrentuser" + }, + bindToController: true + }; + }; + + angular.module("taigaProfile").directive("tgProfileBar", ProfileBarDirective); + +}).call(this); + +(function() { + var ProfileContactsController; + + ProfileContactsController = (function() { + ProfileContactsController.$inject = ["tgUserService", "tgCurrentUserService"]; + + function ProfileContactsController(userService, currentUserService) { + this.userService = userService; + this.currentUserService = currentUserService; + } + + ProfileContactsController.prototype.loadContacts = function() { + this.currentUser = this.currentUserService.getUser(); + this.isCurrentUser = false; + if (this.currentUser.get("id") === this.user.get("id")) { + this.isCurrentUser = true; + } + return this.userService.getContacts(this.user.get("id")).then((function(_this) { + return function(contacts) { + return _this.contacts = contacts; + }; + })(this)); + }; + + return ProfileContactsController; + + })(); + + angular.module("taigaProfile").controller("ProfileContacts", ProfileContactsController); + +}).call(this); + +(function() { + var ProfileContactsDirective; + + ProfileContactsDirective = function() { + var link; + link = function(scope, elm, attrs, ctrl) { + return ctrl.loadContacts(); + }; + return { + templateUrl: "profile/profile-contacts/profile-contacts.html", + scope: { + user: "=" + }, + controllerAs: "vm", + controller: "ProfileContacts", + link: link, + bindToController: true + }; + }; + + angular.module("taigaProfile").directive("tgProfileContacts", ProfileContactsDirective); + +}).call(this); + +(function() { + var ProfileHints; + + ProfileHints = (function() { + ProfileHints.prototype.HINTS = [ + { + url: "https://taiga.io/support/import-export-projects/" + }, { + url: "https://taiga.io/support/custom-fields/" + }, {}, {} + ]; + + function ProfileHints(translate) { + var hintKey; + this.translate = translate; + hintKey = Math.floor(Math.random() * this.HINTS.length) + 1; + this.hint = this.HINTS[hintKey - 1]; + this.hint.linkText = this.hint.linkText || 'HINTS.LINK'; + this.hint.title = this.translate.instant("HINTS.HINT" + hintKey + "_TITLE"); + this.hint.text = this.translate.instant("HINTS.HINT" + hintKey + "_TEXT"); + } + + return ProfileHints; + + })(); + + ProfileHints.$inject = ["$translate"]; + + angular.module("taigaProfile").controller("ProfileHints", ProfileHints); + +}).call(this); + +(function() { + var ProfileHints; + + ProfileHints = function($translate) { + return { + scope: {}, + controller: "ProfileHints", + controllerAs: "vm", + templateUrl: "profile/profile-hints/profile-hints.html" + }; + }; + + ProfileHints.$inject = ["$translate"]; + + angular.module("taigaProfile").directive("tgProfileHints", ProfileHints); + +}).call(this); + +(function() { + var ProfileProjectsController; + + ProfileProjectsController = (function() { + ProfileProjectsController.$inject = ["tgProjectsService", "tgUserService"]; + + function ProfileProjectsController(projectsService, userService) { + this.projectsService = projectsService; + this.userService = userService; + } + + ProfileProjectsController.prototype.loadProjects = function() { + return this.projectsService.getProjectsByUserId(this.user.get("id")).then((function(_this) { + return function(projects) { + return _this.userService.attachUserContactsToProjects(_this.user.get("id"), projects); + }; + })(this)).then((function(_this) { + return function(projects) { + return _this.projects = projects; + }; + })(this)); + }; + + return ProfileProjectsController; + + })(); + + angular.module("taigaProfile").controller("ProfileProjects", ProfileProjectsController); + +}).call(this); + +(function() { + var ProfileProjectsDirective; + + ProfileProjectsDirective = function() { + var link; + link = function(scope, elm, attr, ctrl) { + return ctrl.loadProjects(); + }; + return { + templateUrl: "profile/profile-projects/profile-projects.html", + scope: { + user: "=" + }, + link: link, + bindToController: true, + controllerAs: "vm", + controller: "ProfileProjects" + }; + }; + + angular.module("taigaProfile").directive("tgProfileProjects", ProfileProjectsDirective); + +}).call(this); + +(function() { + var ProfileTabDirective; + + ProfileTabDirective = function() { + var link; + link = function(scope, element, attrs, ctrl, transclude) { + scope.tab = {}; + attrs.$observe("tabTitle", function(title) { + return scope.tab.title = title; + }); + scope.tab.name = attrs.tgProfileTab; + scope.tab.icon = attrs.tabIcon; + scope.tab.active = !!attrs.tabActive; + if (scope.$eval(attrs.tabDisabled) !== true) { + return ctrl.addTab(scope.tab); + } + }; + return { + templateUrl: "profile/profile-tab/profile-tab.html", + scope: {}, + require: "^tgProfileTabs", + link: link, + transclude: true + }; + }; + + angular.module("taigaProfile").directive("tgProfileTab", ProfileTabDirective); + +}).call(this); + +(function() { + var ProfileTabsController; + + ProfileTabsController = (function() { + function ProfileTabsController() { + this.tabs = []; + } + + ProfileTabsController.prototype.addTab = function(tab) { + return this.tabs.push(tab); + }; + + ProfileTabsController.prototype.toggleTab = function(tab) { + _.map(this.tabs, function(tab) { + return tab.active = false; + }); + return tab.active = true; + }; + + return ProfileTabsController; + + })(); + + angular.module("taigaProfile").controller("ProfileTabs", ProfileTabsController); + +}).call(this); + +(function() { + var ProfileTabsDirective; + + ProfileTabsDirective = function() { + return { + scope: {}, + controller: "ProfileTabs", + controllerAs: "vm", + templateUrl: "profile/profile-tabs/profile-tabs.html", + transclude: true + }; + }; + + angular.module("taigaProfile").directive("tgProfileTabs", ProfileTabsDirective); + +}).call(this); + +(function() { + var ProfileController; + + ProfileController = (function() { + ProfileController.$inject = ["tgAppMetaService", "tgCurrentUserService", "$routeParams", "tgUserService", "tgXhrErrorService", "$translate"]; + + function ProfileController(appMetaService, currentUserService, routeParams, userService, xhrError, translate) { + this.appMetaService = appMetaService; + this.currentUserService = currentUserService; + this.routeParams = routeParams; + this.userService = userService; + this.xhrError = xhrError; + this.translate = translate; + this.isCurrentUser = false; + if (this.routeParams.slug) { + this.userService.getUserByUserName(this.routeParams.slug).then((function(_this) { + return function(user) { + if (!user.get('is_active')) { + return _this.xhrError.notFound(); + } else { + _this.user = user; + _this.isCurrentUser = false; + _this._setMeta(_this.user); + return user; + } + }; + })(this))["catch"]((function(_this) { + return function(xhr) { + return _this.xhrError.response(xhr); + }; + })(this)); + } else { + this.user = this.currentUserService.getUser(); + this.isCurrentUser = true; + this._setMeta(this.user); + } + } + + ProfileController.prototype._setMeta = function(user) { + var ctx, description, title; + ctx = { + userFullName: user.get("full_name_display"), + userUsername: user.get("username") + }; + title = this.translate.instant("USER.PROFILE.PAGE_TITLE", ctx); + description = user.get("bio"); + return this.appMetaService.setAll(title, description); + }; + + return ProfileController; + + })(); + + angular.module("taigaProfile").controller("Profile", ProfileController); + +}).call(this); + +(function() { + var SortProjectsDirective; + + SortProjectsDirective = function(currentUserService) { + var directive, link; + link = function(scope, el, attrs, ctrl) { + var itemEl; + itemEl = null; + el.sortable({ + dropOnEmpty: true, + revert: 200, + axis: "y", + opacity: .95, + placeholder: 'placeholder', + cancel: '.project-name' + }); + return el.on("sortstop", function(event, ui) { + var i, index, len, project, sortData, sorted_project_ids, value; + itemEl = ui.item; + project = itemEl.scope().project; + index = itemEl.index(); + sorted_project_ids = _.map(scope.projects.toJS(), function(p) { + return p.id; + }); + sorted_project_ids = _.without(sorted_project_ids, project.get("id")); + sorted_project_ids.splice(index, 0, project.get('id')); + sortData = []; + for (index = i = 0, len = sorted_project_ids.length; i < len; index = ++i) { + value = sorted_project_ids[index]; + sortData.push({ + "project_id": value, + "order": index + }); + } + return currentUserService.bulkUpdateProjectsOrder(sortData); + }); + }; + directive = { + scope: { + projects: "=tgSortProjects" + }, + link: link + }; + return directive; + }; + + angular.module("taigaProjects").directive("tgSortProjects", ["tgCurrentUserService", SortProjectsDirective]); + +}).call(this); + +(function() { + var ProjectsListingController; + + ProjectsListingController = (function() { + ProjectsListingController.$inject = ["tgCurrentUserService", "tgProjectsService"]; + + function ProjectsListingController(currentUserService, projectsService) { + this.currentUserService = currentUserService; + this.projectsService = projectsService; + taiga.defineImmutableProperty(this, "projects", (function(_this) { + return function() { + return _this.currentUserService.projects.get("all"); + }; + })(this)); + } + + ProjectsListingController.prototype.newProject = function() { + return this.projectsService.newProject(); + }; + + return ProjectsListingController; + + })(); + + angular.module("taigaProjects").controller("ProjectsListing", ProjectsListingController); + +}).call(this); + +(function() { + var ProjectController; + + ProjectController = (function() { + ProjectController.$inject = ["tgProjectsService", "$routeParams", "tgAppMetaService", "$tgAuth", "tgXhrErrorService", "$translate"]; + + function ProjectController(projectsService, routeParams, appMetaService, auth, xhrError, translate) { + var projectSlug; + this.projectsService = projectsService; + this.routeParams = routeParams; + this.appMetaService = appMetaService; + this.auth = auth; + this.xhrError = xhrError; + this.translate = translate; + projectSlug = this.routeParams.pslug; + this.user = this.auth.userData; + this.projectsService.getProjectBySlug(projectSlug).then((function(_this) { + return function(project) { + _this.project = project; + return _this._setMeta(_this.project); + }; + })(this))["catch"]((function(_this) { + return function(xhr) { + return _this.xhrError.response(xhr); + }; + })(this)); + } + + ProjectController.prototype._setMeta = function(project) { + var ctx, description, title; + ctx = { + projectName: project.get("name") + }; + title = this.translate.instant("PROJECT.PAGE_TITLE", ctx); + description = project.get("description"); + return this.appMetaService.setAll(title, description); + }; + + return ProjectController; + + })(); + + angular.module("taigaProjects").controller("Project", ProjectController); + +}).call(this); + +(function() { + var ProjectsService, groupBy, taiga, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + taiga = this.taiga; + + groupBy = this.taiga.groupBy; + + ProjectsService = (function(superClass) { + extend(ProjectsService, superClass); + + ProjectsService.$inject = ["tgResources", "$projectUrl", "tgLightboxFactory"]; + + function ProjectsService(rs, projectUrl, lightboxFactory) { + this.rs = rs; + this.projectUrl = projectUrl; + this.lightboxFactory = lightboxFactory; + } + + ProjectsService.prototype.getProjectBySlug = function(projectSlug) { + return this.rs.projects.getProjectBySlug(projectSlug).then((function(_this) { + return function(project) { + return _this._decorate(project); + }; + })(this)); + }; + + ProjectsService.prototype.getProjectStats = function(projectId) { + return this.rs.projects.getProjectStats(projectId); + }; + + ProjectsService.prototype.getProjectsByUserId = function(userId) { + return this.rs.projects.getProjectsByUserId(userId).then((function(_this) { + return function(projects) { + return projects.map(_this._decorate.bind(_this)); + }; + })(this)); + }; + + ProjectsService.prototype._decorate = function(project) { + var colorized_tags, tags, url; + url = this.projectUrl.get(project.toJS()); + project = project.set("url", url); + colorized_tags = []; + if (project.get("tags")) { + tags = project.get("tags").sort(); + colorized_tags = tags.map(function(tag) { + var color; + color = project.get("tags_colors").get(tag); + return Immutable.fromJS({ + name: tag, + color: color + }); + }); + project = project.set("colorized_tags", colorized_tags); + } + return project; + }; + + ProjectsService.prototype.newProject = function() { + return this.lightboxFactory.create("tg-lb-create-project", { + "class": "wizard-create-project" + }); + }; + + ProjectsService.prototype.bulkUpdateProjectsOrder = function(sortData) { + return this.rs.projects.bulkUpdateOrder(sortData); + }; + + return ProjectsService; + + })(taiga.Service); + + angular.module("taigaProjects").service("tgProjectsService", ProjectsService); + +}).call(this); + +(function() { + var Resource, module; + + Resource = function(urlsService, http) { + var service; + service = {}; + service.listInAllProjects = function(params) { + var httpOptions, url; + url = urlsService.resolve("issues"); + httpOptions = { + headers: { + "x-disable-pagination": "1" + } + }; + return http.get(url, params, httpOptions).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + return function() { + return { + "issues": service + }; + }; + }; + + Resource.$inject = ["$tgUrls", "$tgHttp"]; + + module = angular.module("taigaResources2"); + + module.factory("tgIssuesResource", Resource); + +}).call(this); + +(function() { + var Resource, module, pagination; + + pagination = function() {}; + + Resource = function(urlsService, http, paginateResponseService) { + var service; + service = {}; + service.getProjectBySlug = function(projectSlug) { + var url; + url = urlsService.resolve("projects"); + url = url + "/by_slug?slug=" + projectSlug; + return http.get(url).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + service.getProjectsByUserId = function(userId) { + var params, url; + url = urlsService.resolve("projects"); + params = { + "member": userId, + "order_by": "memberships__user_order" + }; + return http.get(url, params).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + service.getProjectStats = function(projectId) { + var url; + url = urlsService.resolve("projects"); + url = url + "/" + projectId; + return http.get(url).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + service.bulkUpdateOrder = function(bulkData) { + var url; + url = urlsService.resolve("bulk-update-projects-order"); + return http.post(url, bulkData); + }; + service.getTimeline = function(projectId, page) { + var params, url; + params = { + page: page + }; + url = urlsService.resolve("timeline-project"); + url = url + "/" + projectId; + return http.get(url, params).then(function(result) { + result = Immutable.fromJS(result); + return paginateResponseService(result); + }); + }; + return function() { + return { + "projects": service + }; + }; + }; + + Resource.$inject = ["$tgUrls", "$tgHttp", "tgPaginateResponseService"]; + + module = angular.module("taigaResources2"); + + module.factory("tgProjectsResources", Resource); + +}).call(this); + +(function() { + var Resources, services; + + services = ["tgProjectsResources", "tgUsersResources", "tgUserstoriesResource", "tgTasksResource", "tgIssuesResource"]; + + Resources = function($injector) { + var i, j, len, len1, ref, service, serviceFn, serviceName, serviceProperty; + for (i = 0, len = services.length; i < len; i++) { + serviceName = services[i]; + serviceFn = $injector.get(serviceName); + service = $injector.invoke(serviceFn); + ref = Object.keys(service); + for (j = 0, len1 = ref.length; j < len1; j++) { + serviceProperty = ref[j]; + if (this[serviceProperty]) { + console.warm("repeated resource " + serviceProperty); + } + this[serviceProperty] = service[serviceProperty]; + } + } + return this; + }; + + Resources.$inject = ["$injector"]; + + angular.module("taigaResources2").service("tgResources", Resources); + +}).call(this); + +(function() { + var Resource, module; + + Resource = function(urlsService, http) { + var service; + service = {}; + service.listInAllProjects = function(params) { + var httpOptions, url; + url = urlsService.resolve("tasks"); + httpOptions = { + headers: { + "x-disable-pagination": "1" + } + }; + return http.get(url, params, httpOptions).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + return function() { + return { + "tasks": service + }; + }; + }; + + Resource.$inject = ["$tgUrls", "$tgHttp"]; + + module = angular.module("taigaResources2"); + + module.factory("tgTasksResource", Resource); + +}).call(this); + +(function() { + var Resource, module; + + Resource = function(urlsService, http, paginateResponseService) { + var service; + service = {}; + service.getUserByUsername = function(username) { + var httpOptions, params, url; + url = urlsService.resolve("by_username"); + httpOptions = { + headers: { + "x-disable-pagination": "1" + } + }; + params = { + username: username + }; + return http.get(url, params, httpOptions).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + service.getStats = function(userId) { + var httpOptions, url; + url = urlsService.resolve("stats", userId); + httpOptions = { + headers: { + "x-disable-pagination": "1" + } + }; + return http.get(url, {}, httpOptions).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + service.getContacts = function(userId) { + var httpOptions, url; + url = urlsService.resolve("contacts", userId); + httpOptions = { + headers: { + "x-disable-pagination": "1" + } + }; + return http.get(url, {}, httpOptions).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + service.getProfileTimeline = function(userId, page) { + var params, url; + params = { + page: page + }; + url = urlsService.resolve("timeline-profile"); + url = url + "/" + userId; + return http.get(url, params).then(function(result) { + result = Immutable.fromJS(result); + return paginateResponseService(result); + }); + }; + service.getUserTimeline = function(userId, page) { + var params, url; + params = { + page: page + }; + url = urlsService.resolve("timeline-user"); + url = url + "/" + userId; + return http.get(url, params).then(function(result) { + result = Immutable.fromJS(result); + return paginateResponseService(result); + }); + }; + return function() { + return { + "users": service + }; + }; + }; + + Resource.$inject = ["$tgUrls", "$tgHttp", "tgPaginateResponseService"]; + + module = angular.module("taigaResources2"); + + module.factory("tgUsersResources", Resource); + +}).call(this); + +(function() { + var Resource, module; + + Resource = function(urlsService, http) { + var service; + service = {}; + service.listInAllProjects = function(params) { + var httpOptions, url; + url = urlsService.resolve("userstories"); + httpOptions = { + headers: { + "x-disable-pagination": "1" + } + }; + return http.get(url, params, httpOptions).then(function(result) { + return Immutable.fromJS(result.data); + }); + }; + return function() { + return { + "userstories": service + }; + }; + }; + + Resource.$inject = ["$tgUrls", "$tgHttp"]; + + module = angular.module("taigaResources2"); + + module.factory("tgUserstoriesResource", Resource); + +}).call(this); + +(function() { + var AppMetaService, taiga, truncate, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + taiga = this.taiga; + + truncate = taiga.truncate; + + AppMetaService = (function(superClass) { + extend(AppMetaService, superClass); + + function AppMetaService() { + return AppMetaService.__super__.constructor.apply(this, arguments); + } + + return AppMetaService; + + })(taiga.Service = function() { + return { + _set: function(key, value) { + var meta; + if (!key) { + return; + } + if (key === "title") { + meta = $("title"); + if (meta.length === 0) { + meta = $(""); + $("head").append(meta); + } + return meta.text(value || ""); + } else if (key.indexOf("og:") === 0) { + meta = $("meta[property='" + key + "']"); + if (meta.length === 0) { + meta = $(""); + $("head").append(meta); + } + return meta.attr("content", value || ""); + } else { + meta = $("meta[name='" + key + "']"); + if (meta.length === 0) { + meta = $(""); + $("head").append(meta); + } + return meta.attr("content", value || ""); + } + }, + setTitle: function(title) { + return this._set('title', title); + }, + setDescription: function(description) { + return this._set("description", truncate(description, 250)); + }, + setTwitterMetas: function(title, description) { + this._set("twitter:card", "summary"); + this._set("twitter:site", "@taigaio"); + this._set("twitter:title", title); + this._set("twitter:description", truncate(description, 300)); + return this._set("twitter:image", window.location.origin + "/images/logo-color.png"); + }, + setOpenGraphMetas: function(title, description) { + this._set("og:type", "object"); + this._set("og:site_name", "Taiga - Love your projects"); + this._set("og:title", title); + this._set("og:description", truncate(description, 300)); + this._set("og:image", window.location.origin + "/images/logo-color.png"); + return this._set("og:url", window.location.href); + }, + setAll: function(title, description) { + this.setTitle(title); + this.setDescription(description); + this.setTwitterMetas(title, description); + return this.setOpenGraphMetas(title, description); + } + }; + }); + + angular.module("taigaCommon").service("tgAppMetaService", AppMetaService); + +}).call(this); + +(function() { + var CurrentUserService, groupBy, taiga; + + taiga = this.taiga; + + groupBy = this.taiga.groupBy; + + CurrentUserService = (function() { + CurrentUserService.$inject = ["tgProjectsService", "$tgStorage"]; + + function CurrentUserService(projectsService, storageService) { + this.projectsService = projectsService; + this.storageService = storageService; + this._user = null; + this._projects = Immutable.Map(); + this._projectsById = Immutable.Map(); + taiga.defineImmutableProperty(this, "projects", (function(_this) { + return function() { + return _this._projects; + }; + })(this)); + taiga.defineImmutableProperty(this, "projectsById", (function(_this) { + return function() { + return _this._projectsById; + }; + })(this)); + } + + CurrentUserService.prototype.isAuthenticated = function() { + if (this.getUser() !== null) { + return true; + } + return false; + }; + + CurrentUserService.prototype.getUser = function() { + var userData; + if (!this._user) { + userData = this.storageService.get("userInfo"); + if (userData) { + userData = Immutable.fromJS(userData); + this.setUser(userData); + } + } + return this._user; + }; + + CurrentUserService.prototype.removeUser = function() { + this._user = null; + this._projects = Immutable.Map(); + return this._projectsById = Immutable.Map(); + }; + + CurrentUserService.prototype.setUser = function(user) { + this._user = user; + return this._loadUserInfo(); + }; + + CurrentUserService.prototype.bulkUpdateProjectsOrder = function(sortData) { + return this.projectsService.bulkUpdateProjectsOrder(sortData).then((function(_this) { + return function() { + return _this._loadProjects(); + }; + })(this)); + }; + + CurrentUserService.prototype._loadProjects = function() { + return this.projectsService.getProjectsByUserId(this._user.get("id")).then((function(_this) { + return function(projects) { + _this._projects = _this._projects.set("all", projects); + _this._projects = _this._projects.set("recents", projects.slice(0, 10)); + _this._projectsById = Immutable.fromJS(groupBy(projects.toJS(), function(p) { + return p.id; + })); + return _this.projects; + }; + })(this)); + }; + + CurrentUserService.prototype._loadUserInfo = function() { + return this._loadProjects(); + }; + + return CurrentUserService; + + })(); + + angular.module("taigaCommon").service("tgCurrentUserService", CurrentUserService); + +}).call(this); + +(function() { + var LightboxFactory; + + LightboxFactory = (function() { + LightboxFactory.$inject = ["$rootScope", "$compile"]; + + function LightboxFactory(rootScope, compile) { + this.rootScope = rootScope; + this.compile = compile; + } + + LightboxFactory.prototype.create = function(name, attrs) { + var elm, html, scope; + scope = this.rootScope.$new(); + elm = $("
").attr(name, true).attr("tg-bind-scope", true); + if (attrs) { + elm.attr(attrs); + } + elm.addClass("remove-on-close"); + html = this.compile(elm)(scope); + $(document.body).append(html); + }; + + return LightboxFactory; + + })(); + + angular.module("taigaCommon").service("tgLightboxFactory", LightboxFactory); + +}).call(this); + +(function() { + var PaginateResponse; + + PaginateResponse = function() { + return function(result) { + var paginateResponse; + paginateResponse = Immutable.Map({ + "data": result.get("data"), + "next": !!result.get("headers")("x-pagination-next"), + "prev": !!result.get("headers")("x-pagination-prev"), + "current": result.get("headers")("x-pagination-current"), + "count": result.get("headers")("x-pagination-count") + }); + return paginateResponse; + }; + }; + + angular.module("taigaCommon").factory("tgPaginateResponseService", PaginateResponse); + +}).call(this); + +(function() { + var ProjectService, taiga; + + taiga = this.taiga; + + ProjectService = (function() { + ProjectService.$inject = ["tgProjectsService"]; + + function ProjectService(projectsService) { + this.projectsService = projectsService; + this._project = null; + this._section = null; + this._sectionsBreadcrumb = Immutable.List(); + taiga.defineImmutableProperty(this, "project", (function(_this) { + return function() { + return _this._project; + }; + })(this)); + taiga.defineImmutableProperty(this, "section", (function(_this) { + return function() { + return _this._section; + }; + })(this)); + taiga.defineImmutableProperty(this, "sectionsBreadcrumb", (function(_this) { + return function() { + return _this._sectionsBreadcrumb; + }; + })(this)); + } + + ProjectService.prototype.setSection = function(section) { + this._section = section; + if (section) { + return this._sectionsBreadcrumb = this._sectionsBreadcrumb.push(this._section); + } else { + return this._sectionsBreadcrumb = Immutable.List(); + } + }; + + ProjectService.prototype.setProject = function(pslug) { + if (this._pslug !== pslug) { + this._pslug = pslug; + return this.fetchProject(); + } + }; + + ProjectService.prototype.cleanProject = function() { + this._pslug = null; + this._project = null; + this._section = null; + return this._sectionsBreadcrumb = Immutable.List(); + }; + + ProjectService.prototype.fetchProject = function() { + return this.projectsService.getProjectBySlug(this._pslug).then((function(_this) { + return function(project) { + return _this._project = project; + }; + })(this)); + }; + + return ProjectService; + + })(); + + angular.module("taigaCommon").service("tgProjectService", ProjectService); + +}).call(this); + +(function() { + var ScopeEvent; + + ScopeEvent = (function() { + function ScopeEvent() {} + + ScopeEvent.prototype.scopes = {}; + + ScopeEvent.prototype._searchDuplicatedScopes = function(id) { + return _.find(Object.keys(this.scopes), (function(_this) { + return function(key) { + return _this.scopes[key].$id === id; + }; + })(this)); + }; + + ScopeEvent.prototype._create = function(name, scope) { + var duplicatedScopeName; + duplicatedScopeName = this._searchDuplicatedScopes(scope.$id); + if (duplicatedScopeName) { + throw new Error("scopeEvent: this scope is already register with the name \"" + duplicatedScopeName + "\""); + } + if (this.scopes[name]) { + throw new Error("scopeEvent: \"" + name + "\" already in use"); + } else { + scope._tgEmitter = new EventEmitter2(); + scope.$on("$destroy", (function(_this) { + return function() { + scope._tgEmitter.removeAllListeners(); + return delete _this.scopes[name]; + }; + })(this)); + return this.scopes[name] = scope; + } + }; + + ScopeEvent.prototype.emitter = function(name, scope) { + if (scope) { + scope = this._create(name, scope); + } else if (this.scopes[name]) { + scope = this.scopes[name]; + } else { + throw new Error("scopeEvent: \"" + name + "\" scope doesn't exist'"); + } + return scope._tgEmitter; + }; + + return ScopeEvent; + + })(); + + angular.module("taigaCommon").service("tgScopeEvent", ScopeEvent); + +}).call(this); + +(function() { + var UserService, taiga, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + taiga = this.taiga; + + UserService = (function(superClass) { + extend(UserService, superClass); + + UserService.$inject = ["tgResources"]; + + function UserService(rs) { + this.rs = rs; + } + + UserService.prototype.getUserByUserName = function(username) { + return this.rs.users.getUserByUsername(username); + }; + + UserService.prototype.getContacts = function(userId) { + return this.rs.users.getContacts(userId); + }; + + UserService.prototype.getStats = function(userId) { + return this.rs.users.getStats(userId); + }; + + UserService.prototype.attachUserContactsToProjects = function(userId, projects) { + return this.getContacts(userId).then(function(contacts) { + projects = projects.map(function(project) { + var contactsFiltered; + contactsFiltered = contacts.filter(function(contact) { + var contactId; + contactId = contact.get("id"); + return project.get('members').indexOf(contactId) !== -1; + }); + project = project.set("contacts", contactsFiltered); + return project; + }); + return projects; + }); + }; + + return UserService; + + })(taiga.Service); + + angular.module("taigaCommon").service("tgUserService", UserService); + +}).call(this); + +(function() { + var xhrError, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + xhrError = (function(superClass) { + extend(xhrError, superClass); + + xhrError.$inject = ["$q", "$location", "$tgNavUrls"]; + + function xhrError(q, location, navUrls) { + this.q = q; + this.location = location; + this.navUrls = navUrls; + } + + xhrError.prototype.notFound = function() { + this.location.path(this.navUrls.resolve("not-found")); + return this.location.replace(); + }; + + xhrError.prototype.permissionDenied = function() { + this.location.path(this.navUrls.resolve("permission-denied")); + return this.location.replace(); + }; + + xhrError.prototype.response = function(xhr) { + if (xhr) { + if (xhr.status === 404) { + this.notFound(); + } else if (xhr.status === 403) { + this.permissionDenied(); + } + } + return this.q.reject(xhr); + }; + + return xhrError; + + })(taiga.Service); + + angular.module("taigaCommon").service("tgXhrErrorService", xhrError); + +}).call(this); + +(function() { + var UserTimelineAttachmentDirective; + + UserTimelineAttachmentDirective = function(template, $compile) { + var isImage, link, validFileExtensions; + validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"]; + isImage = function(url) { + url = url.toLowerCase(); + return _.some(validFileExtensions, function(extension) { + return url.indexOf(extension, url - extension.length) !== -1; + }); + }; + link = function(scope, el) { + var is_image, templateHtml; + is_image = isImage(scope.attachment.url); + if (is_image) { + templateHtml = template.get("user-timeline/user-timeline-attachment/user-timeline-attachment-image.html"); + } else { + templateHtml = template.get("user-timeline/user-timeline-attachment/user-timeline-attachment.html"); + } + el.html(templateHtml); + $compile(el.contents())(scope); + return el.find("img").error(function() { + return this.remove(); + }); + }; + return { + link: link, + scope: { + attachment: "=tgUserTimelineAttachment" + } + }; + }; + + UserTimelineAttachmentDirective.$inject = ["$tgTemplate", "$compile"]; + + angular.module("taigaUserTimeline").directive("tgUserTimelineAttachment", UserTimelineAttachmentDirective); + +}).call(this); + +(function() { + var UserTimelineItemTitle, unslugify; + + unslugify = this.taiga.unslugify; + + UserTimelineItemTitle = (function() { + UserTimelineItemTitle.$inject = ["$translate"]; + + UserTimelineItemTitle.prototype._fieldTranslationKey = { + 'status': 'COMMON.FIELDS.STATUS', + 'subject': 'COMMON.FIELDS.SUBJECT', + 'description_diff': 'COMMON.FIELDS.DESCRIPTION', + 'points': 'COMMON.FIELDS.POINTS', + 'assigned_to': 'COMMON.FIELDS.ASSIGNED_TO', + 'severity': 'ISSUES.FIELDS.SEVERITY', + 'priority': 'ISSUES.FIELDS.PRIORITY', + 'type': 'ISSUES.FIELDS.TYPE', + 'is_iocaine': 'TASK.FIELDS.IS_IOCAINE' + }; + + function UserTimelineItemTitle(translate) { + this.translate = translate; + } + + UserTimelineItemTitle.prototype._translateTitleParams = function(param, timeline, event) { + var event_us, field_name, obj, text, title_attr, url, user; + if (param === "username") { + user = timeline.data.user; + title_attr = this.translate.instant('COMMON.SEE_USER_PROFILE', { + username: user.username + }); + url = 'user-profile:username=vm.activity.user.username'; + return this._getLink(url, user.name, title_attr); + } else if (param === 'field_name') { + field_name = Object.keys(timeline.data.values_diff)[0]; + return this.translate.instant(this._fieldTranslationKey[field_name]); + } else if (param === 'project_name') { + url = 'project:project=vm.activity.project.slug'; + return this._getLink(url, timeline.data.project.name); + } else if (param === 'sprint_name') { + url = 'project-taskboard:project=vm.activity.project.slug,sprint=vm.activity.sprint.slug'; + return this._getLink(url, timeline.data.milestone.name); + } else if (param === 'us_name') { + obj = this._getTimelineObj(timeline, event).userstory; + event_us = { + obj: 'parent_userstory' + }; + url = this._getDetailObjUrl(event_us); + text = '#' + obj.ref + ' ' + obj.subject; + return this._getLink(url, text); + } else if (param === 'obj_name') { + obj = this._getTimelineObj(timeline, event); + url = this._getDetailObjUrl(event); + if (event.obj === 'wikipage') { + text = unslugify(obj.slug); + } else if (event.obj === 'milestone') { + text = obj.name; + } else { + text = '#' + obj.ref + ' ' + obj.subject; + } + return this._getLink(url, text); + } + }; + + UserTimelineItemTitle.prototype._getTimelineObj = function(timeline, event) { + return timeline.data[event.obj]; + }; + + UserTimelineItemTitle.prototype._getDetailObjUrl = function(event) { + var url; + url = { + "issue": ["project-issues-detail", ":project=vm.activity.project.slug,ref=vm.activity.obj.ref"], + "wikipage": ["project-wiki-page", ":project=vm.activity.project.slug,slug=vm.activity.obj.slug"], + "task": ["project-tasks-detail", ":project=vm.activity.project.slug,ref=vm.activity.obj.ref"], + "userstory": ["project-userstories-detail", ":project=vm.activity.project.slug,ref=vm.activity.obj.ref"], + "parent_userstory": ["project-userstories-detail", ":project=vm.activity.project.slug,ref=vm.activity.obj.userstory.ref"], + "milestone": ["project-taskboard", ":project=vm.activity.project.slug,sprint=vm.activity.obj.slug"] + }; + return url[event.obj][0] + url[event.obj][1]; + }; + + UserTimelineItemTitle.prototype._getLink = function(url, text, title) { + title = title || text; + return $('').attr('tg-nav', url).text(text).attr('title', title).prop('outerHTML'); + }; + + UserTimelineItemTitle.prototype._getParams = function(timeline, event, timeline_type) { + var params; + params = {}; + timeline_type.translate_params.forEach((function(_this) { + return function(param) { + return params[param] = _this._translateTitleParams(param, timeline, event); + }; + })(this)); + return params; + }; + + UserTimelineItemTitle.prototype.getTitle = function(timeline, event, type) { + return this.translate.instant(type.key, this._getParams(timeline, event, type)); + }; + + return UserTimelineItemTitle; + + })(); + + angular.module("taigaUserTimeline").service("tgUserTimelineItemTitle", UserTimelineItemTitle); + +}).call(this); + +(function() { + var UserTimelineType, timelineType; + + timelineType = function(timeline, event) { + var field_name, types; + types = [ + { + check: function(timeline, event) { + return event.obj === 'membership'; + }, + key: 'TIMELINE.NEW_MEMBER', + translate_params: ['project_name'], + member: function(timeline) { + return { + user: timeline.data.user, + role: timeline.data.role + }; + } + }, { + check: function(timeline, event) { + return event.obj === 'project' && event.type === 'create'; + }, + key: 'TIMELINE.NEW_PROJECT', + translate_params: ['username', 'project_name'], + description: function(timeline) { + return timeline.data.project.description; + } + }, { + check: function(timeline, event) { + return event.type === 'change' && timeline.data.values_diff.attachments; + }, + key: 'TIMELINE.UPLOAD_ATTACHMENT', + translate_params: ['username', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'userstory' && event.type === 'create'; + }, + key: 'TIMELINE.US_CREATED', + translate_params: ['username', 'project_name', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'issue' && event.type === 'create'; + }, + key: 'TIMELINE.ISSUE_CREATED', + translate_params: ['username', 'project_name', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'wikipage' && event.type === 'create'; + }, + key: 'TIMELINE.WIKI_CREATED', + translate_params: ['username', 'project_name', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'task' && event.type === 'create' && !timeline.data.task.userstory; + }, + key: 'TIMELINE.TASK_CREATED', + translate_params: ['username', 'project_name', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'task' && event.type === 'create' && timeline.data.task.userstory; + }, + key: 'TIMELINE.TASK_CREATED_WITH_US', + translate_params: ['username', 'project_name', 'obj_name', 'us_name'] + }, { + check: function(timeline, event) { + return event.obj === 'milestone' && event.type === 'create'; + }, + key: 'TIMELINE.MILESTONE_CREATED', + translate_params: ['username', 'project_name', 'obj_name'] + }, { + check: function(timeline, event) { + return timeline.data.comment && event.obj === 'userstory'; + }, + key: 'TIMELINE.NEW_COMMENT_US', + translate_params: ['username', 'obj_name'], + description: function(timeline) { + return $(timeline.data.comment_html).text(); + } + }, { + check: function(timeline, event) { + return timeline.data.comment && event.obj === 'issue'; + }, + key: 'TIMELINE.NEW_COMMENT_ISSUE', + translate_params: ['username', 'obj_name'], + description: function(timeline) { + return $(timeline.data.comment_html).text(); + } + }, { + check: function(timeline, event) { + return timeline.data.comment && event.obj === 'task'; + }, + key: 'TIMELINE.NEW_COMMENT_TASK', + translate_params: ['username', 'obj_name'], + description: function(timeline) { + return $(timeline.data.comment_html).text(); + } + }, { + check: function(timeline, event, field_name) { + if (field_name === 'milestone' && event.type === 'change') { + return timeline.data.values_diff.milestone[0] === null; + } + return false; + }, + key: 'TIMELINE.US_ADDED_MILESTONE', + translate_params: ['username', 'obj_name', 'sprint_name'] + }, { + check: function(timeline, event, field_name) { + if (field_name === 'milestone' && event.type === 'change') { + return timeline.data.values_diff.milestone[1] === null; + } + return false; + }, + key: 'TIMELINE.US_REMOVED_FROM_MILESTONE', + translate_params: ['username', 'obj_name'] + }, { + check: function(timeline, event) { + if (event.type === 'change' && timeline.data.values_diff.is_blocked) { + return timeline.data.values_diff.is_blocked[1] === true; + } + return false; + }, + key: 'TIMELINE.BLOCKED', + translate_params: ['username', 'obj_name'], + description: function(timeline) { + if (timeline.data.values_diff.blocked_note_html) { + return $(timeline.data.values_diff.blocked_note_html[1]).text(); + } else { + return false; + } + } + }, { + check: function(timeline, event) { + if (event.type === 'change' && timeline.data.values_diff.is_blocked) { + return timeline.data.values_diff.is_blocked[1] === false; + } + return false; + }, + key: 'TIMELINE.UNBLOCKED', + translate_params: ['username', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'milestone' && event.type === 'change'; + }, + key: 'TIMELINE.MILESTONE_UPDATED', + translate_params: ['username', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'wikipage' && event.type === 'change'; + }, + key: 'TIMELINE.WIKI_UPDATED', + translate_params: ['username', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'userstory' && event.type === 'change'; + }, + key: 'TIMELINE.US_UPDATED', + translate_params: ['username', 'field_name', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'issue' && event.type === 'change'; + }, + key: 'TIMELINE.ISSUE_UPDATED', + translate_params: ['username', 'field_name', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'task' && event.type === 'change' && !timeline.data.task.userstory; + }, + key: 'TIMELINE.TASK_UPDATED', + translate_params: ['username', 'field_name', 'obj_name'] + }, { + check: function(timeline, event) { + return event.obj === 'task' && event.type === 'change' && timeline.data.task.userstory; + }, + key: 'TIMELINE.TASK_UPDATED_WITH_US', + translate_params: ['username', 'field_name', 'obj_name', 'us_name'] + }, { + check: function(timeline, event) { + return event.obj === 'user' && event.type === 'create'; + }, + key: 'TIMELINE.NEW_USER', + translate_params: ['username'] + } + ]; + if (timeline.data.values_diff) { + field_name = Object.keys(timeline.data.values_diff)[0]; + } + return _.find(types, function(obj) { + return obj.check(timeline, event, field_name); + }); + }; + + UserTimelineType = (function() { + function UserTimelineType() {} + + UserTimelineType.prototype.getType = function(timeline, event) { + return timelineType(timeline, event); + }; + + return UserTimelineType; + + })(); + + angular.module("taigaUserTimeline").service("tgUserTimelineItemType", UserTimelineType); + +}).call(this); + +(function() { + var UserTimelineItemController; + + UserTimelineItemController = (function() { + UserTimelineItemController.$inject = ["tgUserTimelineItemType", "tgUserTimelineItemTitle"]; + + function UserTimelineItemController(userTimelineItemType, userTimelineItemTitle) { + var event, ref, timeline, type; + this.userTimelineItemType = userTimelineItemType; + this.userTimelineItemTitle = userTimelineItemTitle; + timeline = this.timeline.toJS(); + event = this.parseEventType(timeline.event_type); + type = this.userTimelineItemType.getType(timeline, event); + this.activity = {}; + this.activity.user = timeline.data.user; + this.activity.project = timeline.data.project; + this.activity.sprint = timeline.data.milestone; + this.activity.title = this.userTimelineItemTitle.getTitle(timeline, event, type); + this.activity.created_formated = moment(timeline.created).fromNow(); + this.activity.obj = this.getObject(timeline, event); + if (type.description) { + this.activity.description = type.description(timeline); + } + if (type.member) { + this.activity.member = type.member(timeline); + } + if ((ref = timeline.data.values_diff) != null ? ref.attachments : void 0) { + this.activity.attachments = timeline.data.values_diff.attachments["new"]; + } + } + + UserTimelineItemController.prototype.parseEventType = function(event_type) { + event_type = event_type.split("."); + return { + section: event_type[0], + obj: event_type[1], + type: event_type[2] + }; + }; + + UserTimelineItemController.prototype.getObject = function(timeline, event) { + if (timeline.data[event.obj]) { + return timeline.data[event.obj]; + } + }; + + return UserTimelineItemController; + + })(); + + angular.module("taigaUserTimeline").controller("UserTimelineItem", UserTimelineItemController); + +}).call(this); + +(function() { + var UserTimelineItemDirective; + + UserTimelineItemDirective = function() { + return { + controllerAs: "vm", + controller: "UserTimelineItem", + bindToController: true, + templateUrl: "user-timeline/user-timeline-item/user-timeline-item.html", + scope: { + timeline: "=tgUserTimelineItem" + } + }; + }; + + angular.module("taigaUserTimeline").directive("tgUserTimelineItem", UserTimelineItemDirective); + +}).call(this); + +(function() { + var UserTimelinePaginationSequence; + + UserTimelinePaginationSequence = function() { + return function(config) { + var getContent, items, next, page; + page = 1; + items = Immutable.List(); + config.minItems = config.minItems || 20; + next = function() { + items = Immutable.List(); + return getContent(); + }; + getContent = function() { + return config.fetch(page).then(function(response) { + var data; + page++; + data = response.get("data"); + if (config.filter) { + data = config.filter(response.get("data")); + } + items = items.concat(data); + if (items.size < config.minItems && response.get("next")) { + return getContent(); + } + return Immutable.Map({ + items: items, + next: response.get("next") + }); + }); + }; + return { + next: function() { + return next(); + } + }; + }; + }; + + angular.module("taigaUserTimeline").factory("tgUserTimelinePaginationSequenceService", UserTimelinePaginationSequence); + +}).call(this); + + +/* + * Copyright (C) 2014 Andrey Antukh + * Copyright (C) 2014 Jesús Espino Garcia + * Copyright (C) 2014 David Barragán Merino +# + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. +# + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. +# + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +# + * File: modules/profile/profile-timeline/profile-timeline.controller.coffee + */ + +(function() { + var UserTimelineController, mixOf, taiga, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + taiga = this.taiga; + + mixOf = this.taiga.mixOf; + + UserTimelineController = (function(superClass) { + extend(UserTimelineController, superClass); + + UserTimelineController.$inject = ["tgUserTimelineService"]; + + function UserTimelineController(userTimelineService) { + this.userTimelineService = userTimelineService; + this.timelineList = Immutable.List(); + this.scrollDisabled = false; + this.timeline = null; + if (this.projectId) { + this.timeline = this.userTimelineService.getProjectTimeline(this.projectId); + } else if (this.currentUser) { + this.timeline = this.userTimelineService.getProfileTimeline(this.user.get("id")); + } else { + this.timeline = this.userTimelineService.getUserTimeline(this.user.get("id")); + } + } + + UserTimelineController.prototype.loadTimeline = function() { + this.scrollDisabled = true; + return this.timeline.next().then((function(_this) { + return function(response) { + _this.timelineList = _this.timelineList.concat(response.get("items")); + if (response.get("next")) { + _this.scrollDisabled = false; + } + return _this.timelineList; + }; + })(this)); + }; + + return UserTimelineController; + + })(mixOf(taiga.Controller, taiga.PageMixin, taiga.FiltersMixin)); + + angular.module("taigaUserTimeline").controller("UserTimeline", UserTimelineController); + +}).call(this); + +(function() { + var UserTimelineDirective; + + UserTimelineDirective = function() { + return { + templateUrl: "user-timeline/user-timeline/user-timeline.html", + controller: "UserTimeline", + controllerAs: "vm", + scope: { + projectId: "=projectid", + user: "=", + currentUser: "=" + }, + bindToController: true + }; + }; + + angular.module("taigaProfile").directive("tgUserTimeline", UserTimelineDirective); + +}).call(this); + +(function() { + var UserTimelineService, taiga, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + taiga = this.taiga; + + UserTimelineService = (function(superClass) { + extend(UserTimelineService, superClass); + + UserTimelineService.$inject = ["tgResources", "tgUserTimelinePaginationSequenceService"]; + + function UserTimelineService(rs, userTimelinePaginationSequenceService) { + this.rs = rs; + this.userTimelinePaginationSequenceService = userTimelinePaginationSequenceService; + } + + UserTimelineService.prototype._invalid = [ + { + check: function(timeline) { + var values, values_diff; + values_diff = timeline.get("data").get("values_diff"); + if (values_diff) { + values = Object.keys(values_diff.toJS()); + } + if (values && values.length) { + if (_.every(values, (function(_this) { + return function(value) { + return _this._valid_fields.indexOf(value) === -1; + }; + })(this))) { + return true; + } else if (values[0] === 'attachments' && values_diff.get('attachments').get('new').size === 0) { + return true; + } + } + return false; + } + }, { + check: function(timeline) { + var event; + event = timeline.get('event_type').split("."); + return event[2] === 'delete'; + } + }, { + check: function(timeline) { + var event; + event = timeline.get('event_type').split("."); + return event[1] === 'project' && event[2] === 'change'; + } + }, { + check: function(timeline) { + return !!timeline.get("data").get("comment_deleted"); + } + }, { + check: function(timeline) { + var event; + event = timeline.get('event_type').split("."); + if (event[1] === "task" && event[2] === "change") { + return timeline.get("data").get("values_diff").get("milestone"); + } + return false; + } + } + ]; + + UserTimelineService.prototype._valid_fields = ['status', 'subject', 'description_diff', 'assigned_to', 'points', 'severity', 'priority', 'type', 'attachments', 'milestone', 'is_blocked', 'is_iocaine', 'content_diff', 'name', 'estimated_finish', 'estimated_start']; + + UserTimelineService.prototype._isInValidTimeline = function(timeline) { + return _.some(this._invalid, (function(_this) { + return function(invalid) { + return invalid.check.call(_this, timeline); + }; + })(this)); + }; + + UserTimelineService.prototype.getProfileTimeline = function(userId, page) { + var config; + config = {}; + config.fetch = (function(_this) { + return function(page) { + return _this.rs.users.getProfileTimeline(userId, page); + }; + })(this); + config.filter = (function(_this) { + return function(items) { + return items.filterNot(function(item) { + return _this._isInValidTimeline(item); + }); + }; + })(this); + return this.userTimelinePaginationSequenceService(config); + }; + + UserTimelineService.prototype.getUserTimeline = function(userId) { + var config; + config = {}; + config.fetch = (function(_this) { + return function(page) { + return _this.rs.users.getUserTimeline(userId, page); + }; + })(this); + config.filter = (function(_this) { + return function(items) { + return items.filterNot(function(item) { + return _this._isInValidTimeline(item); + }); + }; + })(this); + return this.userTimelinePaginationSequenceService(config); + }; + + UserTimelineService.prototype.getProjectTimeline = function(projectId) { + var config; + config = {}; + config.fetch = (function(_this) { + return function(page) { + return _this.rs.projects.getTimeline(projectId, page); + }; + })(this); + config.filter = (function(_this) { + return function(items) { + return items.filterNot(function(item) { + return _this._isInValidTimeline(item); + }); + }; + })(this); + return this.userTimelinePaginationSequenceService(config); + }; + + return UserTimelineService; + + })(taiga.Service); + + angular.module("taigaUserTimeline").service("tgUserTimelineService", UserTimelineService); + +}).call(this); + /* * Copyright (C) 2014 Andrey Antukh diff --git a/dist/js/libs.js b/dist/js/libs.js index 245bfb5..ed539a4 100644 --- a/dist/js/libs.js +++ b/dist/js/libs.js @@ -1,40 +1,43 @@ -function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length*chrsz))}function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length*chrsz))}function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length*chrsz))}function hex_hmac_sha1(key,data){return binb2hex(core_hmac_sha1(key,data))}function b64_hmac_sha1(key,data){return binb2b64(core_hmac_sha1(key,data))}function str_hmac_sha1(key,data){return binb2str(core_hmac_sha1(key,data))}function sha1_vm_test(){return"a9993e364706816aba3e25717850c26c9cd0d89d"==hex_sha1("abc")}function core_sha1(x,len){x[len>>5]|=128<<24-len%32,x[(len+64>>9<<4)+15]=len;for(var w=Array(80),a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776,i=0;ij;j++){w[j]=16>j?x[i+j]:rol(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);var t=safe_add(safe_add(rol(a,5),sha1_ft(j,b,c,d)),safe_add(safe_add(e,w[j]),sha1_kt(j)));e=d,d=c,c=rol(b,30),b=a,a=t}a=safe_add(a,olda),b=safe_add(b,oldb),c=safe_add(c,oldc),d=safe_add(d,oldd),e=safe_add(e,olde)}return Array(a,b,c,d,e)}function sha1_ft(t,b,c,d){return 20>t?b&c|~b&d:40>t?b^c^d:60>t?b&c|b&d|c&d:b^c^d}function sha1_kt(t){return 20>t?1518500249:40>t?1859775393:60>t?-1894007588:-899497514}function core_hmac_sha1(key,data){var bkey=str2binb(key);bkey.length>16&&(bkey=core_sha1(bkey,key.length*chrsz));for(var ipad=Array(16),opad=Array(16),i=0;16>i;i++)ipad[i]=909522486^bkey[i],opad[i]=1549556828^bkey[i];var hash=core_sha1(ipad.concat(str2binb(data)),512+data.length*chrsz);return core_sha1(opad.concat(hash),672)}function safe_add(x,y){var lsw=(65535&x)+(65535&y),msw=(x>>16)+(y>>16)+(lsw>>16);return msw<<16|65535&lsw}function rol(num,cnt){return num<>>32-cnt}function str2binb(str){for(var bin=Array(),mask=(1<>5]|=(str.charCodeAt(i/chrsz)&mask)<<32-chrsz-i%32;return bin}function binb2str(bin){for(var str="",mask=(1<>5]>>>32-chrsz-i%32&mask);return str}function binb2hex(binarray){for(var hex_tab=hexcase?"0123456789ABCDEF":"0123456789abcdef",str="",i=0;i<4*binarray.length;i++)str+=hex_tab.charAt(binarray[i>>2]>>8*(3-i%4)+4&15)+hex_tab.charAt(binarray[i>>2]>>8*(3-i%4)&15);return str}function binb2b64(binarray){for(var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",str="",i=0;i<4*binarray.length;i+=3)for(var triplet=(binarray[i>>2]>>8*(3-i%4)&255)<<16|(binarray[i+1>>2]>>8*(3-(i+1)%4)&255)<<8|binarray[i+2>>2]>>8*(3-(i+2)%4)&255,j=0;4>j;j++)str+=8*i+6*j>32*binarray.length?b64pad:tab.charAt(triplet>>6*(3-j)&63);return str}!function(global,factory){"object"==typeof module&&"object"==typeof module.exports?module.exports=global.document?factory(global,!0):function(w){if(!w.document)throw new Error("jQuery requires a window with a document");return factory(w)}:factory(global)}("undefined"!=typeof window?window:this,function(window,noGlobal){function isArraylike(obj){var length="length"in obj&&obj.length,type=jQuery.type(obj);return"function"===type||jQuery.isWindow(obj)?!1:1===obj.nodeType&&length?!0:"array"===type||0===length||"number"==typeof length&&length>0&&length-1 in obj}function winnow(elements,qualifier,not){if(jQuery.isFunction(qualifier))return jQuery.grep(elements,function(elem,i){return!!qualifier.call(elem,i,elem)!==not});if(qualifier.nodeType)return jQuery.grep(elements,function(elem){return elem===qualifier!==not});if("string"==typeof qualifier){if(risSimple.test(qualifier))return jQuery.filter(qualifier,elements,not);qualifier=jQuery.filter(qualifier,elements)}return jQuery.grep(elements,function(elem){return indexOf.call(qualifier,elem)>=0!==not})}function sibling(cur,dir){for(;(cur=cur[dir])&&1!==cur.nodeType;);return cur}function createOptions(options){var object=optionsCache[options]={};return jQuery.each(options.match(rnotwhite)||[],function(_,flag){object[flag]=!0}),object}function completed(){document.removeEventListener("DOMContentLoaded",completed,!1),window.removeEventListener("load",completed,!1),jQuery.ready()}function Data(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=jQuery.expando+Data.uid++}function dataAttr(elem,key,data){var name;if(void 0===data&&1===elem.nodeType)if(name="data-"+key.replace(rmultiDash,"-$1").toLowerCase(),data=elem.getAttribute(name),"string"==typeof data){try{data="true"===data?!0:"false"===data?!1:"null"===data?null:+data+""===data?+data:rbrace.test(data)?jQuery.parseJSON(data):data}catch(e){}data_user.set(elem,key,data)}else data=void 0;return data}function returnTrue(){return!0}function returnFalse(){return!1}function safeActiveElement(){try{return document.activeElement}catch(err){}}function manipulationTarget(elem,content){return jQuery.nodeName(elem,"table")&&jQuery.nodeName(11!==content.nodeType?content:content.firstChild,"tr")?elem.getElementsByTagName("tbody")[0]||elem.appendChild(elem.ownerDocument.createElement("tbody")):elem}function disableScript(elem){return elem.type=(null!==elem.getAttribute("type"))+"/"+elem.type,elem}function restoreScript(elem){var match=rscriptTypeMasked.exec(elem.type);return match?elem.type=match[1]:elem.removeAttribute("type"),elem}function setGlobalEval(elems,refElements){for(var i=0,l=elems.length;l>i;i++)data_priv.set(elems[i],"globalEval",!refElements||data_priv.get(refElements[i],"globalEval"))}function cloneCopyEvent(src,dest){var i,l,type,pdataOld,pdataCur,udataOld,udataCur,events;if(1===dest.nodeType){if(data_priv.hasData(src)&&(pdataOld=data_priv.access(src),pdataCur=data_priv.set(dest,pdataOld),events=pdataOld.events)){delete pdataCur.handle,pdataCur.events={};for(type in events)for(i=0,l=events[type].length;l>i;i++)jQuery.event.add(dest,type,events[type][i])}data_user.hasData(src)&&(udataOld=data_user.access(src),udataCur=jQuery.extend({},udataOld),data_user.set(dest,udataCur))}}function getAll(context,tag){var ret=context.getElementsByTagName?context.getElementsByTagName(tag||"*"):context.querySelectorAll?context.querySelectorAll(tag||"*"):[];return void 0===tag||tag&&jQuery.nodeName(context,tag)?jQuery.merge([context],ret):ret}function fixInput(src,dest){var nodeName=dest.nodeName.toLowerCase();"input"===nodeName&&rcheckableType.test(src.type)?dest.checked=src.checked:("input"===nodeName||"textarea"===nodeName)&&(dest.defaultValue=src.defaultValue)}function actualDisplay(name,doc){var style,elem=jQuery(doc.createElement(name)).appendTo(doc.body),display=window.getDefaultComputedStyle&&(style=window.getDefaultComputedStyle(elem[0]))?style.display:jQuery.css(elem[0],"display");return elem.detach(),display}function defaultDisplay(nodeName){var doc=document,display=elemdisplay[nodeName];return display||(display=actualDisplay(nodeName,doc),"none"!==display&&display||(iframe=(iframe||jQuery("'),"after"==options.previewPosition?iFrame.insertAfter(footer):iFrame.insertBefore(header),previewWindow=iFrame[iFrame.length-1].contentWindow||frame[iFrame.length-1]):altKey===!0&&(iFrame?iFrame.remove():previewWindow.close(),previewWindow=iFrame=!1),options.previewAutoRefresh||refreshPreview(),options.previewInWindow&&previewWindow.focus()}function refreshPreview(){renderPreview()}function renderPreview(){if(options.previewHandler&&"function"==typeof options.previewHandler)options.previewHandler($$.val());else if(options.previewParser&&"function"==typeof options.previewParser){var data=options.previewParser($$.val());writeInPreview(localize(data,1))}else""!==options.previewParserPath?$.ajax({type:"POST",dataType:"text",global:!1,url:options.previewParserPath,data:options.previewParserVar+"="+encodeURIComponent($$.val()),success:function(data){writeInPreview(localize(data,1))}}):template||$.ajax({url:options.previewTemplatePath,dataType:"text",global:!1,success:function(data){writeInPreview(localize(data,1).replace(//g,$$.val()))}});return!1}function writeInPreview(data){if(options.previewInElement)$(options.previewInElement).html(data);else if(previewWindow&&previewWindow.document){try{sp=previewWindow.document.documentElement.scrollTop}catch(e){sp=0}previewWindow.document.open(),previewWindow.document.write(data),previewWindow.document.close(),previewWindow.document.documentElement.scrollTop=sp}}function keyPressed(e){if(shiftKey=e.shiftKey,altKey=e.altKey,ctrlKey=e.altKey&&e.ctrlKey?!1:e.ctrlKey||e.metaKey,"keydown"===e.type){if(ctrlKey===!0&&(li=$('a[accesskey="'+(13==e.keyCode?"\\n":String.fromCharCode(e.keyCode))+'"]',header).parent("li"),0!==li.length))return ctrlKey=!1,setTimeout(function(){li.triggerHandler("mouseup")},1),!1;if(13===e.keyCode||10===e.keyCode)return ctrlKey===!0?(ctrlKey=!1,markup(options.onCtrlEnter),options.onCtrlEnter.keepDefault):shiftKey===!0?(shiftKey=!1,markup(options.onShiftEnter),options.onShiftEnter.keepDefault):(markup(options.onEnter),options.onEnter.keepDefault);if(9===e.keyCode)return 1==shiftKey||1==ctrlKey||1==altKey?!1:-1!==caretOffset?(get(),caretOffset=$$.val().length-caretOffset,set(caretOffset,0),caretOffset=-1,!1):(markup(options.onTab),options.onTab.keepDefault)}}function remove(){$$.unbind(".markItUp").removeClass("markItUpEditor"),$$.parent("div").parent("div.markItUp").parent("div").replaceWith($$),$$.data("markItUp",null)}var $$,textarea,levels,scrollPosition,caretPosition,caretOffset,clicked,hash,header,footer,previewWindow,template,iFrame,abort;if($$=$(this),textarea=this,levels=[],abort=!1,scrollPosition=caretPosition=0,caretOffset=-1,options.previewParserPath=localize(options.previewParserPath),options.previewTemplatePath=localize(options.previewTemplatePath),method)switch(method){case"remove":remove();break;case"insert":markup(params);break;default:$.error("Method "+method+" does not exist on jQuery.markItUp")}else init()})},$.fn.markItUpRemove=function(){return this.each(function(){$(this).markItUp("remove")})},$.markItUp=function(settings){var options={target:!1};return $.extend(options,settings),options.target?$(options.target).each(function(){$(this).focus(),$(this).trigger("insertion",[options])}):void $("textarea").trigger("insertion",[options])}}(jQuery),!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}),!function(e){"undefined"!=typeof module&&module.exports?module.exports=e:e(jQuery,window,document)}(function(e){!function(t){var o="function"==typeof define&&define.amd,a="undefined"!=typeof module&&module.exports,n="https:"==document.location.protocol?"https:":"http:",i="cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.12/jquery.mousewheel.min.js";o||(a?require("jquery-mousewheel")(e):e.event.special.mousewheel||e("head").append(decodeURI("%3Cscript src="+n+"//"+i+"%3E%3C/script%3E"))),t()}(function(){var t,o="mCustomScrollbar",a="mCS",n=".mCustomScrollbar",i={setTop:0,setLeft:0,axis:"y",scrollbarPosition:"inside",scrollInertia:950,autoDraggerLength:!0,alwaysShowScrollbar:0,snapOffset:0,mouseWheel:{enable:!0,scrollAmount:"auto",axis:"y",deltaFactor:"auto",disableOver:["select","option","keygen","datalist","textarea"]},scrollButtons:{scrollType:"stepless",scrollAmount:"auto"},keyboard:{enable:!0,scrollType:"stepless",scrollAmount:"auto"},contentTouchScroll:25,advanced:{autoScrollOnFocus:"input,textarea,select,button,datalist,keygen,a[tabindex],area,object,[contenteditable='true']",updateOnContentResize:!0,updateOnImageLoad:!0},theme:"light",callbacks:{onTotalScrollOffset:0,onTotalScrollBackOffset:0,alwaysTriggerOffsets:!0}},r=0,l={},s=window.attachEvent&&!window.addEventListener?1:0,c=!1,d=["mCSB_dragger_onDrag","mCSB_scrollTools_onDrag","mCS_img_loaded","mCS_disabled","mCS_destroyed","mCS_no_scrollbar","mCS-autoHide","mCS-dir-rtl","mCS_no_scrollbar_y","mCS_no_scrollbar_x","mCS_y_hidden","mCS_x_hidden","mCSB_draggerContainer","mCSB_buttonUp","mCSB_buttonDown","mCSB_buttonLeft","mCSB_buttonRight"],u={init:function(t){var t=e.extend(!0,{},i,t),o=f.call(this);if(t.live){var s=t.liveSelector||this.selector||n,c=e(s);if("off"===t.live)return void m(s);l[s]=setTimeout(function(){c.mCustomScrollbar(t),"once"===t.live&&c.length&&m(s)},500)}else m(s);return t.setWidth=t.set_width?t.set_width:t.setWidth,t.setHeight=t.set_height?t.set_height:t.setHeight,t.axis=t.horizontalScroll?"x":p(t.axis),t.scrollInertia=t.scrollInertia>0&&t.scrollInertia<17?17:t.scrollInertia,"object"!=typeof t.mouseWheel&&1==t.mouseWheel&&(t.mouseWheel={enable:!0,scrollAmount:"auto",axis:"y",preventDefault:!1,deltaFactor:"auto",normalizeDelta:!1,invert:!1}),t.mouseWheel.scrollAmount=t.mouseWheelPixels?t.mouseWheelPixels:t.mouseWheel.scrollAmount,t.mouseWheel.normalizeDelta=t.advanced.normalizeMouseWheelDelta?t.advanced.normalizeMouseWheelDelta:t.mouseWheel.normalizeDelta,t.scrollButtons.scrollType=g(t.scrollButtons.scrollType),h(t),e(o).each(function(){var o=e(this);if(!o.data(a)){o.data(a,{idx:++r,opt:t,scrollRatio:{y:null,x:null},overflowed:null,contentReset:{y:null,x:null},bindEvents:!1,tweenRunning:!1,sequential:{},langDir:o.css("direction"),cbOffsets:null,trigger:null});var n=o.data(a),i=n.opt,l=o.data("mcs-axis"),s=o.data("mcs-scrollbar-position"),c=o.data("mcs-theme");l&&(i.axis=l),s&&(i.scrollbarPosition=s),c&&(i.theme=c,h(i)),v.call(this),e("#mCSB_"+n.idx+"_container img:not(."+d[2]+")").addClass(d[2]),u.update.call(null,o)}})},update:function(t,o){var n=t||f.call(this);return e(n).each(function(){var t=e(this);if(t.data(a)){var n=t.data(a),i=n.opt,r=e("#mCSB_"+n.idx+"_container"),l=[e("#mCSB_"+n.idx+"_dragger_vertical"),e("#mCSB_"+n.idx+"_dragger_horizontal")];if(!r.length)return;n.tweenRunning&&V(t),t.hasClass(d[3])&&t.removeClass(d[3]),t.hasClass(d[4])&&t.removeClass(d[4]),S.call(this),_.call(this),"y"===i.axis||i.advanced.autoExpandHorizontalScroll||r.css("width",x(r.children())),n.overflowed=B.call(this),O.call(this),i.autoDraggerLength&&b.call(this),C.call(this),k.call(this);var s=[Math.abs(r[0].offsetTop),Math.abs(r[0].offsetLeft)];"x"!==i.axis&&(n.overflowed[0]?l[0].height()>l[0].parent().height()?T.call(this):(Q(t,s[0].toString(),{dir:"y",dur:0,overwrite:"none"}),n.contentReset.y=null):(T.call(this),"y"===i.axis?M.call(this):"yx"===i.axis&&n.overflowed[1]&&Q(t,s[1].toString(),{dir:"x",dur:0,overwrite:"none"}))),"y"!==i.axis&&(n.overflowed[1]?l[1].width()>l[1].parent().width()?T.call(this):(Q(t,s[1].toString(),{dir:"x",dur:0,overwrite:"none"}),n.contentReset.x=null):(T.call(this),"x"===i.axis?M.call(this):"yx"===i.axis&&n.overflowed[0]&&Q(t,s[0].toString(),{dir:"y",dur:0,overwrite:"none"}))),o&&n&&(2===o&&i.callbacks.onImageLoad&&"function"==typeof i.callbacks.onImageLoad?i.callbacks.onImageLoad.call(this):3===o&&i.callbacks.onSelectorChange&&"function"==typeof i.callbacks.onSelectorChange?i.callbacks.onSelectorChange.call(this):i.callbacks.onUpdate&&"function"==typeof i.callbacks.onUpdate&&i.callbacks.onUpdate.call(this)),X.call(this)}})},scrollTo:function(t,o){if("undefined"!=typeof t&&null!=t){var n=f.call(this);return e(n).each(function(){var n=e(this);if(n.data(a)){var i=n.data(a),r=i.opt,l={trigger:"external",scrollInertia:r.scrollInertia,scrollEasing:"mcsEaseInOut",moveDragger:!1,timeout:60,callbacks:!0,onStart:!0,onUpdate:!0,onComplete:!0},s=e.extend(!0,{},l,o),c=Y.call(this,t),d=s.scrollInertia>0&&s.scrollInertia<17?17:s.scrollInertia;c[0]=j.call(this,c[0],"y"),c[1]=j.call(this,c[1],"x"),s.moveDragger&&(c[0]*=i.scrollRatio.y,c[1]*=i.scrollRatio.x),s.dur=d,setTimeout(function(){null!==c[0]&&"undefined"!=typeof c[0]&&"x"!==r.axis&&i.overflowed[0]&&(s.dir="y",s.overwrite="all",Q(n,c[0].toString(),s)),null!==c[1]&&"undefined"!=typeof c[1]&&"y"!==r.axis&&i.overflowed[1]&&(s.dir="x",s.overwrite="none",Q(n,c[1].toString(),s))},s.timeout)}})}},stop:function(){var t=f.call(this);return e(t).each(function(){var t=e(this);t.data(a)&&V(t)})},disable:function(t){var o=f.call(this);return e(o).each(function(){var o=e(this);o.data(a)&&(o.data(a),X.call(this,"remove"),M.call(this),t&&T.call(this),O.call(this,!0),o.addClass(d[3]))})},destroy:function(){var t=f.call(this);return e(t).each(function(){var n=e(this);if(n.data(a)){var i=n.data(a),r=i.opt,l=e("#mCSB_"+i.idx),s=e("#mCSB_"+i.idx+"_container"),c=e(".mCSB_"+i.idx+"_scrollbar");r.live&&m(r.liveSelector||e(t).selector),X.call(this,"remove"),M.call(this),T.call(this),n.removeData(a),Z(this,"mcs"),c.remove(),s.find("img."+d[2]).removeClass(d[2]),l.replaceWith(s.contents()),n.removeClass(o+" _"+a+"_"+i.idx+" "+d[6]+" "+d[7]+" "+d[5]+" "+d[3]).addClass(d[4])}})}},f=function(){return"object"!=typeof e(this)||e(this).length<1?n:this},h=function(t){var o=["rounded","rounded-dark","rounded-dots","rounded-dots-dark"],a=["rounded-dots","rounded-dots-dark","3d","3d-dark","3d-thick","3d-thick-dark","inset","inset-dark","inset-2","inset-2-dark","inset-3","inset-3-dark"],n=["minimal","minimal-dark"],i=["minimal","minimal-dark"],r=["minimal","minimal-dark"];t.autoDraggerLength=e.inArray(t.theme,o)>-1?!1:t.autoDraggerLength,t.autoExpandScrollbar=e.inArray(t.theme,a)>-1?!1:t.autoExpandScrollbar,t.scrollButtons.enable=e.inArray(t.theme,n)>-1?!1:t.scrollButtons.enable,t.autoHideScrollbar=e.inArray(t.theme,i)>-1?!0:t.autoHideScrollbar,t.scrollbarPosition=e.inArray(t.theme,r)>-1?"outside":t.scrollbarPosition},m=function(e){l[e]&&(clearTimeout(l[e]),Z(l,e))},p=function(e){return"yx"===e||"xy"===e||"auto"===e?"yx":"x"===e||"horizontal"===e?"x":"y"},g=function(e){return"stepped"===e||"pixels"===e||"step"===e||"click"===e?"stepped":"stepless"},v=function(){var t=e(this),n=t.data(a),i=n.opt,r=i.autoExpandScrollbar?" "+d[1]+"_expand":"",l=["
","
"],s="yx"===i.axis?"mCSB_vertical_horizontal":"x"===i.axis?"mCSB_horizontal":"mCSB_vertical",c="yx"===i.axis?l[0]+l[1]:"x"===i.axis?l[1]:l[0],u="yx"===i.axis?"
":"",f=i.autoHideScrollbar?" "+d[6]:"",h="x"!==i.axis&&"rtl"===n.langDir?" "+d[7]:"";i.setWidth&&t.css("width",i.setWidth),i.setHeight&&t.css("height",i.setHeight),i.setLeft="y"!==i.axis&&"rtl"===n.langDir?"989999px":i.setLeft,t.addClass(o+" _"+a+"_"+n.idx+f+h).wrapInner("
");var m=e("#mCSB_"+n.idx),p=e("#mCSB_"+n.idx+"_container");"y"===i.axis||i.advanced.autoExpandHorizontalScroll||p.css("width",x(p.children())),"outside"===i.scrollbarPosition?("static"===t.css("position")&&t.css("position","relative"),t.css("overflow","visible"),m.addClass("mCSB_outside").after(c)):(m.addClass("mCSB_inside").append(c),p.wrap(u)),w.call(this);var g=[e("#mCSB_"+n.idx+"_dragger_vertical"),e("#mCSB_"+n.idx+"_dragger_horizontal")];g[0].css("min-height",g[0].height()),g[1].css("min-width",g[1].width())},x=function(t){return Math.max.apply(Math,t.map(function(){return e(this).outerWidth(!0)}).get())},_=function(){var t=e(this),o=t.data(a),n=o.opt,i=e("#mCSB_"+o.idx+"_container");n.advanced.autoExpandHorizontalScroll&&"y"!==n.axis&&i.css({position:"absolute",width:"auto"}).wrap("
").css({width:Math.ceil(i[0].getBoundingClientRect().right+.4)-Math.floor(i[0].getBoundingClientRect().left),position:"relative"}).unwrap()},w=function(){var t=e(this),o=t.data(a),n=o.opt,i=e(".mCSB_"+o.idx+"_scrollbar:first"),r=tt(n.scrollButtons.tabindex)?"tabindex='"+n.scrollButtons.tabindex+"'":"",l=["","","",""],s=["x"===n.axis?l[2]:l[0],"x"===n.axis?l[3]:l[1],l[2],l[3]];n.scrollButtons.enable&&i.prepend(s[0]).append(s[1]).next(".mCSB_scrollTools").prepend(s[2]).append(s[3])},S=function(){var t=e(this),o=t.data(a),n=e("#mCSB_"+o.idx),i=t.css("max-height")||"none",r=-1!==i.indexOf("%"),l=t.css("box-sizing");if("none"!==i){var s=r?t.parent().height()*parseInt(i)/100:parseInt(i);"border-box"===l&&(s-=t.innerHeight()-t.height()+(t.outerHeight()-t.innerHeight())),n.css("max-height",Math.round(s))}},b=function(){var t=e(this),o=t.data(a),n=e("#mCSB_"+o.idx),i=e("#mCSB_"+o.idx+"_container"),r=[e("#mCSB_"+o.idx+"_dragger_vertical"),e("#mCSB_"+o.idx+"_dragger_horizontal")],l=[n.height()/i.outerHeight(!1),n.width()/i.outerWidth(!1)],c=[parseInt(r[0].css("min-height")),Math.round(l[0]*r[0].parent().height()),parseInt(r[1].css("min-width")),Math.round(l[1]*r[1].parent().width())],d=s&&c[1]n.height(),l>n.width()]},T=function(){var t=e(this),o=t.data(a),n=o.opt,i=e("#mCSB_"+o.idx),r=e("#mCSB_"+o.idx+"_container"),l=[e("#mCSB_"+o.idx+"_dragger_vertical"),e("#mCSB_"+o.idx+"_dragger_horizontal")];if(V(t),("x"!==n.axis&&!o.overflowed[0]||"y"===n.axis&&o.overflowed[0])&&(l[0].add(r).css("top",0),Q(t,"_resetY")),"y"!==n.axis&&!o.overflowed[1]||"x"===n.axis&&o.overflowed[1]){var s=dx=0;"rtl"===o.langDir&&(s=i.width()-r.outerWidth(!1),dx=Math.abs(s/o.scrollRatio.x)),r.css("left",s),l[1].css("left",dx),Q(t,"_resetX")}},k=function(){function t(){r=setTimeout(function(){e.event.special.mousewheel?(clearTimeout(r),W.call(o[0])):t()},100)}var o=e(this),n=o.data(a),i=n.opt;if(!n.bindEvents){if(R.call(this),i.contentTouchScroll&&E.call(this),D.call(this),i.mouseWheel.enable){var r;t()}P.call(this),H.call(this),i.advanced.autoScrollOnFocus&&z.call(this),i.scrollButtons.enable&&U.call(this),i.keyboard.enable&&q.call(this),n.bindEvents=!0}},M=function(){var t=e(this),o=t.data(a),n=o.opt,i=a+"_"+o.idx,r=".mCSB_"+o.idx+"_scrollbar",l=e("#mCSB_"+o.idx+",#mCSB_"+o.idx+"_container,#mCSB_"+o.idx+"_container_wrapper,"+r+" ."+d[12]+",#mCSB_"+o.idx+"_dragger_vertical,#mCSB_"+o.idx+"_dragger_horizontal,"+r+">a"),s=e("#mCSB_"+o.idx+"_container"); -n.advanced.releaseDraggableSelectors&&l.add(e(n.advanced.releaseDraggableSelectors)),o.bindEvents&&(e(document).unbind("."+i),l.each(function(){e(this).unbind("."+i)}),clearTimeout(t[0]._focusTimeout),Z(t[0],"_focusTimeout"),clearTimeout(o.sequential.step),Z(o.sequential,"step"),clearTimeout(s[0].onCompleteTimeout),Z(s[0],"onCompleteTimeout"),o.bindEvents=!1)},O=function(t){var o=e(this),n=o.data(a),i=n.opt,r=e("#mCSB_"+n.idx+"_container_wrapper"),l=r.length?r:e("#mCSB_"+n.idx+"_container"),s=[e("#mCSB_"+n.idx+"_scrollbar_vertical"),e("#mCSB_"+n.idx+"_scrollbar_horizontal")],c=[s[0].find(".mCSB_dragger"),s[1].find(".mCSB_dragger")];"x"!==i.axis&&(n.overflowed[0]&&!t?(s[0].add(c[0]).add(s[0].children("a")).css("display","block"),l.removeClass(d[8]+" "+d[10])):(i.alwaysShowScrollbar?(2!==i.alwaysShowScrollbar&&c[0].css("display","none"),l.removeClass(d[10])):(s[0].css("display","none"),l.addClass(d[10])),l.addClass(d[8]))),"y"!==i.axis&&(n.overflowed[1]&&!t?(s[1].add(c[1]).add(s[1].children("a")).css("display","block"),l.removeClass(d[9]+" "+d[11])):(i.alwaysShowScrollbar?(2!==i.alwaysShowScrollbar&&c[1].css("display","none"),l.removeClass(d[11])):(s[1].css("display","none"),l.addClass(d[11])),l.addClass(d[9]))),n.overflowed[0]||n.overflowed[1]?o.removeClass(d[5]):o.addClass(d[5])},I=function(e){var t=e.type;switch(t){case"pointerdown":case"MSPointerDown":case"pointermove":case"MSPointerMove":case"pointerup":case"MSPointerUp":return e.target.ownerDocument!==document?[e.originalEvent.screenY,e.originalEvent.screenX,!1]:[e.originalEvent.pageY,e.originalEvent.pageX,!1];case"touchstart":case"touchmove":case"touchend":var o=e.originalEvent.touches[0]||e.originalEvent.changedTouches[0],a=e.originalEvent.touches.length||e.originalEvent.changedTouches.length;return e.target.ownerDocument!==document?[o.screenY,o.screenX,a>1]:[o.pageY,o.pageX,a>1];default:return[e.pageY,e.pageX,!1]}},R=function(){function t(e){var t=m.find("iframe");if(t.length){var o=e?"auto":"none";t.css("pointer-events",o)}}function o(e,t,o,a){if(m[0].idleTimer=u.scrollInertia<233?250:0,n.attr("id")===h[1])var i="x",r=(n[0].offsetLeft-t+a)*d.scrollRatio.x;else var i="y",r=(n[0].offsetTop-e+o)*d.scrollRatio.y;Q(l,r.toString(),{dir:i,drag:!0})}var n,i,r,l=e(this),d=l.data(a),u=d.opt,f=a+"_"+d.idx,h=["mCSB_"+d.idx+"_dragger_vertical","mCSB_"+d.idx+"_dragger_horizontal"],m=e("#mCSB_"+d.idx+"_container"),p=e("#"+h[0]+",#"+h[1]),g=u.advanced.releaseDraggableSelectors?p.add(e(u.advanced.releaseDraggableSelectors)):p;p.bind("mousedown."+f+" touchstart."+f+" pointerdown."+f+" MSPointerDown."+f,function(o){if(o.stopImmediatePropagation(),o.preventDefault(),$(o)){c=!0,s&&(document.onselectstart=function(){return!1}),t(!1),V(l),n=e(this);var a=n.offset(),d=I(o)[0]-a.top,f=I(o)[1]-a.left,h=n.height()+a.top,m=n.width()+a.left;h>d&&d>0&&m>f&&f>0&&(i=d,r=f),y(n,"active",u.autoExpandScrollbar)}}).bind("touchmove."+f,function(e){e.stopImmediatePropagation(),e.preventDefault();var t=n.offset(),a=I(e)[0]-t.top,l=I(e)[1]-t.left;o(i,r,a,l)}),e(document).bind("mousemove."+f+" pointermove."+f+" MSPointerMove."+f,function(e){if(n){var t=n.offset(),a=I(e)[0]-t.top,l=I(e)[1]-t.left;if(i===a)return;o(i,r,a,l)}}).add(g).bind("mouseup."+f+" touchend."+f+" pointerup."+f+" MSPointerUp."+f,function(){n&&(y(n,"active",u.autoExpandScrollbar),n=null),c=!1,s&&(document.onselectstart=null),t(!0)})},E=function(){function o(e){if(!et(e)||c||I(e)[2])return void(t=0);t=1,S=0,b=0;var o=M.offset();d=I(e)[0]-o.top,u=I(e)[1]-o.left,A=[I(e)[0],I(e)[1]]}function n(e){if(et(e)&&!c&&!I(e)[2]&&(e.stopImmediatePropagation(),!b||S)){p=J();var t=k.offset(),o=I(e)[0]-t.top,a=I(e)[1]-t.left,n="mcsLinearOut";if(R.push(o),E.push(a),A[2]=Math.abs(I(e)[0]-A[0]),A[3]=Math.abs(I(e)[1]-A[1]),y.overflowed[0])var i=O[0].parent().height()-O[0].height(),r=d-o>0&&o-d>-(i*y.scrollRatio.y)&&(2*A[3]0&&a-u>-(l*y.scrollRatio.x)&&(2*A[2]30)){x=1e3/(g-m);var n="mcsEaseOut",i=2.5>x,r=i?[R[R.length-2],E[E.length-2]]:[0,0];v=i?[o-r[0],a-r[1]]:[o-f,a-h];var d=[Math.abs(v[0]),Math.abs(v[1])];x=i?[Math.abs(v[0]/4),Math.abs(v[1]/4)]:[x,x];var u=[Math.abs(M[0].offsetTop)-v[0]*l(d[0]/x[0],x[0]),Math.abs(M[0].offsetLeft)-v[1]*l(d[1]/x[1],x[1])];_="yx"===B.axis?[u[0],u[1]]:"x"===B.axis?[null,u[1]]:[u[0],null],w=[4*d[0]+B.scrollInertia,4*d[1]+B.scrollInertia];var C=parseInt(B.contentTouchScroll)||0;_[0]=d[0]>C?_[0]:0,_[1]=d[1]>C?_[1]:0,y.overflowed[0]&&s(_[0],w[0],n,"y",W,!1),y.overflowed[1]&&s(_[1],w[1],n,"x",W,!1)}}}function l(e,t){var o=[1.5*t,2*t,t/1.5,t/2];return e>90?t>4?o[0]:o[3]:e>60?t>3?o[3]:o[2]:e>30?t>8?o[1]:t>6?o[0]:t>4?t:o[2]:t>8?t:o[3]}function s(e,t,o,a,n,i){e&&Q(C,e.toString(),{dur:t,scrollEasing:o,dir:a,overwrite:n,drag:i})}var d,u,f,h,m,p,g,v,x,_,w,S,b,C=e(this),y=C.data(a),B=y.opt,T=a+"_"+y.idx,k=e("#mCSB_"+y.idx),M=e("#mCSB_"+y.idx+"_container"),O=[e("#mCSB_"+y.idx+"_dragger_vertical"),e("#mCSB_"+y.idx+"_dragger_horizontal")],R=[],E=[],D=0,W="yx"===B.axis?"none":"all",A=[],P=M.find("iframe"),z=["touchstart."+T+" pointerdown."+T+" MSPointerDown."+T,"touchmove."+T+" pointermove."+T+" MSPointerMove."+T,"touchend."+T+" pointerup."+T+" MSPointerUp."+T];M.bind(z[0],function(e){o(e)}).bind(z[1],function(e){n(e)}),k.bind(z[0],function(e){i(e)}).bind(z[2],function(e){r(e)}),P.length&&P.each(function(){e(this).load(function(){L(this)&&e(this.contentDocument||this.contentWindow.document).bind(z[0],function(e){o(e),i(e)}).bind(z[1],function(e){n(e)}).bind(z[2],function(e){r(e)})})})},D=function(){function o(){return window.getSelection?window.getSelection().toString():document.selection&&"Control"!=document.selection.type?document.selection.createRange().text:0}function n(e,t,o){d.type=o&&i?"stepped":"stepless",d.scrollAmount=10,F(r,e,t,"mcsLinearOut",o?60:null)}var i,r=e(this),l=r.data(a),s=l.opt,d=l.sequential,u=a+"_"+l.idx,f=e("#mCSB_"+l.idx+"_container"),h=f.parent();f.bind("mousedown."+u,function(){t||i||(i=1,c=!0)}).add(document).bind("mousemove."+u,function(e){if(!t&&i&&o()){var a=f.offset(),r=I(e)[0]-a.top+f[0].offsetTop,c=I(e)[1]-a.left+f[0].offsetLeft;r>0&&r0&&cr?n("on",38):r>h.height()&&n("on",40)),"y"!==s.axis&&l.overflowed[1]&&(0>c?n("on",37):c>h.width()&&n("on",39)))}}).bind("mouseup."+u,function(){t||(i&&(i=0,n("off",null)),c=!1)})},W=function(){function t(t,a){if(V(o),!A(o,t.target)){var r="auto"!==i.mouseWheel.deltaFactor?parseInt(i.mouseWheel.deltaFactor):s&&t.deltaFactor<100?100:t.deltaFactor||100;if("x"===i.axis||"x"===i.mouseWheel.axis)var d="x",u=[Math.round(r*n.scrollRatio.x),parseInt(i.mouseWheel.scrollAmount)],f="auto"!==i.mouseWheel.scrollAmount?u[1]:u[0]>=l.width()?.9*l.width():u[0],h=Math.abs(e("#mCSB_"+n.idx+"_container")[0].offsetLeft),m=c[1][0].offsetLeft,p=c[1].parent().width()-c[1].width(),g=t.deltaX||t.deltaY||a;else var d="y",u=[Math.round(r*n.scrollRatio.y),parseInt(i.mouseWheel.scrollAmount)],f="auto"!==i.mouseWheel.scrollAmount?u[1]:u[0]>=l.height()?.9*l.height():u[0],h=Math.abs(e("#mCSB_"+n.idx+"_container")[0].offsetTop),m=c[0][0].offsetTop,p=c[0].parent().height()-c[0].height(),g=t.deltaY||a;"y"===d&&!n.overflowed[0]||"x"===d&&!n.overflowed[1]||(i.mouseWheel.invert&&(g=-g),i.mouseWheel.normalizeDelta&&(g=0>g?-1:1),(g>0&&0!==m||0>g&&m!==p||i.mouseWheel.preventDefault)&&(t.stopImmediatePropagation(),t.preventDefault()),Q(o,(h-g*f).toString(),{dir:d}))}}var o=e(this),n=o.data(a),i=n.opt,r=a+"_"+n.idx,l=e("#mCSB_"+n.idx),c=[e("#mCSB_"+n.idx+"_dragger_vertical"),e("#mCSB_"+n.idx+"_dragger_horizontal")],d=e("#mCSB_"+n.idx+"_container").find("iframe");n&&(d.length&&d.each(function(){e(this).load(function(){L(this)&&e(this.contentDocument||this.contentWindow.document).bind("mousewheel."+r,function(e,o){t(e,o)})})}),l.bind("mousewheel."+r,function(e,o){t(e,o)}))},L=function(e){var t=null;try{var o=e.contentDocument||e.contentWindow.document;t=o.body.innerHTML}catch(a){}return null!==t},A=function(t,o){var n=o.nodeName.toLowerCase(),i=t.data(a).opt.mouseWheel.disableOver,r=["select","textarea"];return e.inArray(n,i)>-1&&!(e.inArray(n,r)>-1&&!e(o).is(":focus"))},P=function(){var t=e(this),o=t.data(a),n=a+"_"+o.idx,i=e("#mCSB_"+o.idx+"_container"),r=i.parent(),l=e(".mCSB_"+o.idx+"_scrollbar ."+d[12]);l.bind("touchstart."+n+" pointerdown."+n+" MSPointerDown."+n,function(){c=!0}).bind("touchend."+n+" pointerup."+n+" MSPointerUp."+n,function(){c=!1}).bind("click."+n,function(a){if(e(a.target).hasClass(d[12])||e(a.target).hasClass("mCSB_draggerRail")){V(t);var n=e(this),l=n.find(".mCSB_dragger");if(n.parent(".mCSB_scrollTools_horizontal").length>0){if(!o.overflowed[1])return;var s="x",c=a.pageX>l.offset().left?-1:1,u=Math.abs(i[0].offsetLeft)-.9*c*r.width()}else{if(!o.overflowed[0])return;var s="y",c=a.pageY>l.offset().top?-1:1,u=Math.abs(i[0].offsetTop)-.9*c*r.height()}Q(t,u.toString(),{dir:s,scrollEasing:"mcsEaseInOut"})}})},z=function(){var t=e(this),o=t.data(a),n=o.opt,i=a+"_"+o.idx,r=e("#mCSB_"+o.idx+"_container"),l=r.parent();r.bind("focusin."+i,function(){var o=e(document.activeElement),a=r.find(".mCustomScrollBox").length,i=0;o.is(n.advanced.autoScrollOnFocus)&&(V(t),clearTimeout(t[0]._focusTimeout),t[0]._focusTimer=a?(i+17)*a:0,t[0]._focusTimeout=setTimeout(function(){var e=[ot(o)[0],ot(o)[1]],a=[r[0].offsetTop,r[0].offsetLeft],s=[a[0]+e[0]>=0&&a[0]+e[0]=0&&a[0]+e[1]a");s.bind("mousedown."+r+" touchstart."+r+" pointerdown."+r+" MSPointerDown."+r+" mouseup."+r+" touchend."+r+" pointerup."+r+" MSPointerUp."+r+" mouseout."+r+" pointerout."+r+" MSPointerOut."+r+" click."+r,function(a){function r(e,o){i.scrollAmount=n.snapAmount||n.scrollButtons.scrollAmount,F(t,e,o)}if(a.preventDefault(),$(a)){var l=e(this).attr("class");switch(i.type=n.scrollButtons.scrollType,a.type){case"mousedown":case"touchstart":case"pointerdown":case"MSPointerDown":if("stepped"===i.type)return;c=!0,o.tweenRunning=!1,r("on",l);break;case"mouseup":case"touchend":case"pointerup":case"MSPointerUp":case"mouseout":case"pointerout":case"MSPointerOut":if("stepped"===i.type)return;c=!1,i.dir&&r("off",l);break;case"click":if("stepped"!==i.type||o.tweenRunning)return;r("on",l)}}})},q=function(){function t(t){function a(e,t){r.type=i.keyboard.scrollType,r.scrollAmount=i.snapAmount||i.keyboard.scrollAmount,"stepped"===r.type&&n.tweenRunning||F(o,e,t)}switch(t.type){case"blur":n.tweenRunning&&r.dir&&a("off",null);break;case"keydown":case"keyup":var l=t.keyCode?t.keyCode:t.which,s="on";if("x"!==i.axis&&(38===l||40===l)||"y"!==i.axis&&(37===l||39===l)){if((38===l||40===l)&&!n.overflowed[0]||(37===l||39===l)&&!n.overflowed[1])return;"keyup"===t.type&&(s="off"),e(document.activeElement).is(u)||(t.preventDefault(),t.stopImmediatePropagation(),a(s,l))}else if(33===l||34===l){if((n.overflowed[0]||n.overflowed[1])&&(t.preventDefault(),t.stopImmediatePropagation()),"keyup"===t.type){V(o);var f=34===l?-1:1;if("x"===i.axis||"yx"===i.axis&&n.overflowed[1]&&!n.overflowed[0])var h="x",m=Math.abs(c[0].offsetLeft)-.9*f*d.width();else var h="y",m=Math.abs(c[0].offsetTop)-.9*f*d.height();Q(o,m.toString(),{dir:h,scrollEasing:"mcsEaseInOut"})}}else if((35===l||36===l)&&!e(document.activeElement).is(u)&&((n.overflowed[0]||n.overflowed[1])&&(t.preventDefault(),t.stopImmediatePropagation()),"keyup"===t.type)){if("x"===i.axis||"yx"===i.axis&&n.overflowed[1]&&!n.overflowed[0])var h="x",m=35===l?Math.abs(d.width()-c.outerWidth(!1)):0;else var h="y",m=35===l?Math.abs(d.height()-c.outerHeight(!1)):0;Q(o,m.toString(),{dir:h,scrollEasing:"mcsEaseInOut"})}}}var o=e(this),n=o.data(a),i=n.opt,r=n.sequential,l=a+"_"+n.idx,s=e("#mCSB_"+n.idx),c=e("#mCSB_"+n.idx+"_container"),d=c.parent(),u="input,textarea,select,datalist,keygen,[contenteditable='true']",f=c.find("iframe"),h=["blur."+l+" keydown."+l+" keyup."+l];f.length&&f.each(function(){e(this).load(function(){L(this)&&e(this.contentDocument||this.contentWindow.document).bind(h[0],function(e){t(e)})})}),s.attr("tabindex","0").bind(h[0],function(e){t(e)})},F=function(t,o,n,i,r){function l(e){var o="stepped"!==f.type,a=r?r:e?o?p/1.5:g:1e3/60,n=e?o?7.5:40:2.5,s=[Math.abs(h[0].offsetTop),Math.abs(h[0].offsetLeft)],d=[c.scrollRatio.y>10?10:c.scrollRatio.y,c.scrollRatio.x>10?10:c.scrollRatio.x],u="x"===f.dir[0]?s[1]+f.dir[1]*d[1]*n:s[0]+f.dir[1]*d[0]*n,m="x"===f.dir[0]?s[1]+f.dir[1]*parseInt(f.scrollAmount):s[0]+f.dir[1]*parseInt(f.scrollAmount),v="auto"!==f.scrollAmount?m:u,x=i?i:e?o?"mcsLinearOut":"mcsEaseInOut":"mcsLinear",_=e?!0:!1;return e&&17>a&&(v="x"===f.dir[0]?s[1]:s[0]),Q(t,v.toString(),{dir:f.dir[0],scrollEasing:x,dur:a,onComplete:_}),e?void(f.dir=!1):(clearTimeout(f.step),void(f.step=setTimeout(function(){l()},a)))}function s(){clearTimeout(f.step),Z(f,"step"),V(t)}var c=t.data(a),u=c.opt,f=c.sequential,h=e("#mCSB_"+c.idx+"_container"),m="stepped"===f.type?!0:!1,p=u.scrollInertia<26?26:u.scrollInertia,g=u.scrollInertia<1?17:u.scrollInertia;switch(o){case"on":if(f.dir=[n===d[16]||n===d[15]||39===n||37===n?"x":"y",n===d[13]||n===d[15]||38===n||37===n?-1:1],V(t),tt(n)&&"stepped"===f.type)return;l(m);break;case"off":s(),(m||c.tweenRunning&&f.dir)&&l(!0)}},Y=function(t){var o=e(this).data(a).opt,n=[];return"function"==typeof t&&(t=t()),t instanceof Array?n=t.length>1?[t[0],t[1]]:"x"===o.axis?[null,t[0]]:[t[0],null]:(n[0]=t.y?t.y:t.x||"x"===o.axis?null:t,n[1]=t.x?t.x:t.y||"y"===o.axis?null:t),"function"==typeof n[0]&&(n[0]=n[0]()),"function"==typeof n[1]&&(n[1]=n[1]()),n},j=function(t,o){if(null!=t&&"undefined"!=typeof t){var n=e(this),i=n.data(a),r=i.opt,l=e("#mCSB_"+i.idx+"_container"),s=l.parent(),c=typeof t;o||(o="x"===r.axis?"x":"y");var d="x"===o?l.outerWidth(!1):l.outerHeight(!1),f="x"===o?l[0].offsetLeft:l[0].offsetTop,h="x"===o?"left":"top";switch(c){case"function":return t();case"object":var m=t.jquery?t:e(t);if(!m.length)return;return"x"===o?ot(m)[1]:ot(m)[0];case"string":case"number":if(tt(t))return Math.abs(t);if(-1!==t.indexOf("%"))return Math.abs(d*parseInt(t)/100);if(-1!==t.indexOf("-="))return Math.abs(f-parseInt(t.split("-=")[1]));if(-1!==t.indexOf("+=")){var p=f+parseInt(t.split("+=")[1]);return p>=0?0:Math.abs(p)}if(-1!==t.indexOf("px")&&tt(t.split("px")[0]))return Math.abs(t.split("px")[0]);if("top"===t||"left"===t)return 0;if("bottom"===t)return Math.abs(s.height()-l.outerHeight(!1));if("right"===t)return Math.abs(s.width()-l.outerWidth(!1));if("first"===t||"last"===t){var m=l.find(":"+t);return"x"===o?ot(m)[1]:ot(m)[0]}return e(t).length?"x"===o?ot(e(t))[1]:ot(e(t))[0]:(l.css(h,t),void u.update.call(null,n[0]))}}},X=function(t){function o(){clearTimeout(h[0].autoUpdate),h[0].autoUpdate=setTimeout(function(){return f.advanced.updateOnSelectorChange&&(m=r(),m!==w)?(l(3),void(w=m)):(f.advanced.updateOnContentResize&&(p=[h.outerHeight(!1),h.outerWidth(!1),v.height(),v.width(),_()[0],_()[1]],(p[0]!==S[0]||p[1]!==S[1]||p[2]!==S[2]||p[3]!==S[3]||p[4]!==S[4]||p[5]!==S[5])&&(l(p[0]!==S[0]||p[1]!==S[1]),S=p)),f.advanced.updateOnImageLoad&&(g=n(),g!==b&&(h.find("img").each(function(){i(this)}),b=g)),void((f.advanced.updateOnSelectorChange||f.advanced.updateOnContentResize||f.advanced.updateOnImageLoad)&&o()))},60)}function n(){var e=0;return f.advanced.updateOnImageLoad&&(e=h.find("img").length),e}function i(t){function o(e,t){return function(){return t.apply(e,arguments)}}function a(){this.onload=null,e(t).addClass(d[2]),l(2)}if(e(t).hasClass(d[2]))return void l();var n=new Image;n.onload=o(n,a),n.src=t.src}function r(){f.advanced.updateOnSelectorChange===!0&&(f.advanced.updateOnSelectorChange="*");var t=0,o=h.find(f.advanced.updateOnSelectorChange);return f.advanced.updateOnSelectorChange&&o.length>0&&o.each(function(){t+=e(this).height()+e(this).width()}),t}function l(e){clearTimeout(h[0].autoUpdate),u.update.call(null,s[0],e)}var s=e(this),c=s.data(a),f=c.opt,h=e("#mCSB_"+c.idx+"_container");if(t)return clearTimeout(h[0].autoUpdate),void Z(h[0],"autoUpdate");var m,p,g,v=h.parent(),x=[e("#mCSB_"+c.idx+"_scrollbar_vertical"),e("#mCSB_"+c.idx+"_scrollbar_horizontal")],_=function(){return[x[0].is(":visible")?x[0].outerHeight(!0):0,x[1].is(":visible")?x[1].outerWidth(!0):0]},w=r(),S=[h.outerHeight(!1),h.outerWidth(!1),v.height(),v.width(),_()[0],_()[1]],b=n();o()},N=function(e,t,o){return Math.round(e/t)*t-o},V=function(t){var o=t.data(a),n=e("#mCSB_"+o.idx+"_container,#mCSB_"+o.idx+"_container_wrapper,#mCSB_"+o.idx+"_dragger_vertical,#mCSB_"+o.idx+"_dragger_horizontal");n.each(function(){K.call(this)})},Q=function(t,o,n){function i(e){return s&&c.callbacks[e]&&"function"==typeof c.callbacks[e]}function r(){return[c.callbacks.alwaysTriggerOffsets||_>=w[0]+b,c.callbacks.alwaysTriggerOffsets||-C>=_]}function l(){var e=[h[0].offsetTop,h[0].offsetLeft],o=[v[0].offsetTop,v[0].offsetLeft],a=[h.outerHeight(!1),h.outerWidth(!1)],i=[f.height(),f.width()];t[0].mcs={content:h,top:e[0],left:e[1],draggerTop:o[0],draggerLeft:o[1],topPct:Math.round(100*Math.abs(e[0])/(Math.abs(a[0])-i[0])),leftPct:Math.round(100*Math.abs(e[1])/(Math.abs(a[1])-i[1])),direction:n.dir}}var s=t.data(a),c=s.opt,d={trigger:"internal",dir:"y",scrollEasing:"mcsEaseOut",drag:!1,dur:c.scrollInertia,overwrite:"all",callbacks:!0,onStart:!0,onUpdate:!0,onComplete:!0},n=e.extend(d,n),u=[n.dur,n.drag?0:n.dur],f=e("#mCSB_"+s.idx),h=e("#mCSB_"+s.idx+"_container"),m=h.parent(),p=c.callbacks.onTotalScrollOffset?Y.call(t,c.callbacks.onTotalScrollOffset):[0,0],g=c.callbacks.onTotalScrollBackOffset?Y.call(t,c.callbacks.onTotalScrollBackOffset):[0,0];if(s.trigger=n.trigger,(0!==m.scrollTop()||0!==m.scrollLeft())&&(e(".mCSB_"+s.idx+"_scrollbar").css("visibility","visible"),m.scrollTop(0).scrollLeft(0)),"_resetY"!==o||s.contentReset.y||(i("onOverflowYNone")&&c.callbacks.onOverflowYNone.call(t[0]),s.contentReset.y=1),"_resetX"!==o||s.contentReset.x||(i("onOverflowXNone")&&c.callbacks.onOverflowXNone.call(t[0]),s.contentReset.x=1),"_resetY"!==o&&"_resetX"!==o){switch(!s.contentReset.y&&t[0].mcs||!s.overflowed[0]||(i("onOverflowY")&&c.callbacks.onOverflowY.call(t[0]),s.contentReset.x=null),!s.contentReset.x&&t[0].mcs||!s.overflowed[1]||(i("onOverflowX")&&c.callbacks.onOverflowX.call(t[0]),s.contentReset.x=null),c.snapAmount&&(o=N(o,c.snapAmount,c.snapOffset)),n.dir){case"x":var v=e("#mCSB_"+s.idx+"_dragger_horizontal"),x="left",_=h[0].offsetLeft,w=[f.width()-h.outerWidth(!1),v.parent().width()-v.width()],S=[o,0===o?0:o/s.scrollRatio.x],b=p[1],C=g[1],B=b>0?b/s.scrollRatio.x:0,T=C>0?C/s.scrollRatio.x:0;break;case"y":var v=e("#mCSB_"+s.idx+"_dragger_vertical"),x="top",_=h[0].offsetTop,w=[f.height()-h.outerHeight(!1),v.parent().height()-v.height()],S=[o,0===o?0:o/s.scrollRatio.y],b=p[0],C=g[0],B=b>0?b/s.scrollRatio.y:0,T=C>0?C/s.scrollRatio.y:0}S[1]<0||0===S[0]&&0===S[1]?S=[0,0]:S[1]>=w[1]?S=[w[0],w[1]]:S[0]=-S[0],t[0].mcs||(l(),i("onInit")&&c.callbacks.onInit.call(t[0])),clearTimeout(h[0].onCompleteTimeout),(s.tweenRunning||!(0===_&&S[0]>=0||_===w[0]&&S[0]<=w[0]))&&(G(v[0],x,Math.round(S[1]),u[1],n.scrollEasing),G(h[0],x,Math.round(S[0]),u[0],n.scrollEasing,n.overwrite,{onStart:function(){n.callbacks&&n.onStart&&!s.tweenRunning&&(i("onScrollStart")&&(l(),c.callbacks.onScrollStart.call(t[0])),s.tweenRunning=!0,y(v),s.cbOffsets=r())},onUpdate:function(){n.callbacks&&n.onUpdate&&i("whileScrolling")&&(l(),c.callbacks.whileScrolling.call(t[0]))},onComplete:function(){if(n.callbacks&&n.onComplete){"yx"===c.axis&&clearTimeout(h[0].onCompleteTimeout);var e=h[0].idleTimer||0;h[0].onCompleteTimeout=setTimeout(function(){i("onScroll")&&(l(),c.callbacks.onScroll.call(t[0])),i("onTotalScroll")&&S[1]>=w[1]-B&&s.cbOffsets[0]&&(l(),c.callbacks.onTotalScroll.call(t[0])),i("onTotalScrollBack")&&S[1]<=T&&s.cbOffsets[1]&&(l(),c.callbacks.onTotalScrollBack.call(t[0])),s.tweenRunning=!1,h[0].idleTimer=0,y(v,"hide")},e)}}}))}},G=function(e,t,o,a,n,i,r){function l(){S.stop||(x||m.call(),x=J()-v,s(),x>=S.time&&(S.time=x>S.time?x+f-(x-S.time):x+f-1,S.time0?(S.currVal=u(S.time,_,b,a,n),w[t]=Math.round(S.currVal)+"px"):w[t]=o+"px",p.call()}function c(){f=1e3/60,S.time=x+f,h=window.requestAnimationFrame?window.requestAnimationFrame:function(e){return s(),setTimeout(e,.01)},S.id=h(l)}function d(){null!=S.id&&(window.requestAnimationFrame?window.cancelAnimationFrame(S.id):clearTimeout(S.id),S.id=null)}function u(e,t,o,a,n){switch(n){case"linear":case"mcsLinear":return o*e/a+t;case"mcsLinearOut":return e/=a,e--,o*Math.sqrt(1-e*e)+t;case"easeInOutSmooth":return e/=a/2,1>e?o/2*e*e+t:(e--,-o/2*(e*(e-2)-1)+t);case"easeInOutStrong":return e/=a/2,1>e?o/2*Math.pow(2,10*(e-1))+t:(e--,o/2*(-Math.pow(2,-10*e)+2)+t);case"easeInOut":case"mcsEaseInOut":return e/=a/2,1>e?o/2*e*e*e+t:(e-=2,o/2*(e*e*e+2)+t);case"easeOutSmooth":return e/=a,e--,-o*(e*e*e*e-1)+t;case"easeOutStrong":return o*(-Math.pow(2,-10*e/a)+1)+t;case"easeOut":case"mcsEaseOut":default:var i=(e/=a)*e,r=i*e;return t+o*(.499999999999997*r*i+-2.5*i*i+5.5*r+-6.5*i+4*e)}}e._mTween||(e._mTween={top:{},left:{}});var f,h,r=r||{},m=r.onStart||function(){},p=r.onUpdate||function(){},g=r.onComplete||function(){},v=J(),x=0,_=e.offsetTop,w=e.style,S=e._mTween[t];"left"===t&&(_=e.offsetLeft);var b=o-_;S.stop=0,"none"!==i&&d(),c()},J=function(){return window.performance&&window.performance.now?window.performance.now():window.performance&&window.performance.webkitNow?window.performance.webkitNow():Date.now?Date.now():(new Date).getTime()},K=function(){var e=this;e._mTween||(e._mTween={top:{},left:{}});for(var t=["top","left"],o=0;o=0&&a[0]+ot(n)[0]=0&&a[1]+ot(n)[1]i;i++)callback.call(null,i,obj[i])}function setAuthQueryString(){authQueryString="?sentry_version=4&sentry_client=raven-js/"+Raven.VERSION+"&sentry_key="+globalKey}function handleStackInfo(stackInfo,options){var frames=[];stackInfo.stack&&stackInfo.stack.length&&each(stackInfo.stack,function(i,stack){var frame=normalizeFrame(stack);frame&&frames.push(frame)}),triggerEvent("handle",{stackInfo:stackInfo,options:options}),processException(stackInfo.name,stackInfo.message,stackInfo.url,stackInfo.lineno,frames,options)}function normalizeFrame(frame){if(frame.url){var i,normalized={filename:frame.url,lineno:frame.line,colno:frame.column,"function":frame.func||"?"},context=extractContextFromFrame(frame);if(context){var keys=["pre_context","context_line","post_context"];for(i=3;i--;)normalized[keys[i]]=context[i]}return normalized.in_app=!(!globalOptions.includePaths.test(normalized.filename)||/(Raven|TraceKit)\./.test(normalized["function"])||/raven\.(min\.)?js$/.test(normalized.filename)),normalized}}function extractContextFromFrame(frame){if(frame.context&&globalOptions.fetchContext){for(var context=frame.context,pivot=~~(context.length/2),i=context.length,isMinified=!1;i--;)if(context[i].length>300){isMinified=!0;break}if(isMinified){if(isUndefined(frame.column))return;return[[],context[pivot].substr(frame.column,50),[]]}return[context.slice(0,pivot),context[pivot],context.slice(pivot+1)]}}function processException(type,message,fileurl,lineno,frames,options){var stacktrace,label;message+="",("Error"!==type||message)&&(globalOptions.ignoreErrors.test(message)||(frames&&frames.length?(fileurl=frames[0].filename||fileurl,frames.reverse(),stacktrace={frames:frames}):fileurl&&(stacktrace={frames:[{filename:fileurl,lineno:lineno,in_app:!0}]}),message=truncate(message,globalOptions.maxMessageLength),globalOptions.ignoreUrls&&globalOptions.ignoreUrls.test(fileurl)||(!globalOptions.whitelistUrls||globalOptions.whitelistUrls.test(fileurl))&&(label=lineno?message+" at "+lineno:message,send(objectMerge({exception:{type:type,value:message},stacktrace:stacktrace,culprit:fileurl,message:label},options)))))}function objectMerge(obj1,obj2){return obj2?(each(obj2,function(key,value){obj1[key]=value}),obj1):obj1}function truncate(str,max){return str.length<=max?str:str.substr(0,max)+"…"}function now(){return+new Date}function getHttpData(){var http={url:document.location.href,headers:{"User-Agent":navigator.userAgent}};return document.referrer&&(http.headers.Referer=document.referrer),http}function send(data){isSetup()&&(data=objectMerge({project:globalProject,logger:globalOptions.logger,platform:"javascript",request:getHttpData()},data),data.tags=objectMerge(objectMerge({},globalOptions.tags),data.tags),data.extra=objectMerge(objectMerge({},globalOptions.extra),data.extra),data.extra=objectMerge({"session:duration":now()-startTime},data.extra),isEmptyObject(data.tags)&&delete data.tags,globalUser&&(data.user=globalUser),globalOptions.release&&(data.release=globalOptions.release),isFunction(globalOptions.dataCallback)&&(data=globalOptions.dataCallback(data)),(!isFunction(globalOptions.shouldSendCallback)||globalOptions.shouldSendCallback(data))&&(lastEventId=data.event_id||(data.event_id=uuid4()),makeRequest(data)))}function makeRequest(data){var img=new Image,src=globalServer+authQueryString+"&sentry_data="+encodeURIComponent(JSON.stringify(data));img.crossOrigin="anonymous",img.onload=function(){triggerEvent("success",{data:data,src:src})},img.onerror=img.onabort=function(){triggerEvent("failure",{data:data,src:src})},img.src=src}function isSetup(){return hasJSON?globalServer?!0:(logDebug("error","Error: Raven has not been configured."),!1):!1}function joinRegExp(patterns){for(var pattern,sources=[],i=0,len=patterns.length;len>i;i++)pattern=patterns[i],isString(pattern)?sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")):pattern&&pattern.source&&sources.push(pattern.source);return new RegExp(sources.join("|"),"i")}function uuid4(){return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(c){var r=16*Math.random()|0,v="x"==c?r:3&r|8;return v.toString(16)})}function logDebug(level,message){window.console&&console[level]&&Raven.debug&&console[level](message)}function afterLoad(){var RavenConfig=window.RavenConfig;RavenConfig&&Raven.config(RavenConfig.dsn,RavenConfig.config).install()}var TraceKit={remoteFetching:!1,collectWindowErrors:!0,linesOfContext:7},_slice=[].slice,UNKNOWN_FUNCTION="?";TraceKit.wrap=function(func){function wrapped(){try{return func.apply(this,arguments)}catch(e){throw TraceKit.report(e),e}}return wrapped},TraceKit.report=function(){function subscribe(handler){installGlobalHandler(),handlers.push(handler)}function unsubscribe(handler){for(var i=handlers.length-1;i>=0;--i)handlers[i]===handler&&handlers.splice(i,1)}function unsubscribeAll(){uninstallGlobalHandler(),handlers=[]}function notifyHandlers(stack,isWindowError){var exception=null;if(!isWindowError||TraceKit.collectWindowErrors){for(var i in handlers)if(hasKey(handlers,i))try{handlers[i].apply(null,[stack].concat(_slice.call(arguments,2)))}catch(inner){exception=inner}if(exception)throw exception}}function traceKitWindowOnError(message,url,lineNo,colNo,ex){var stack=null;if(lastExceptionStack)TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack,url,lineNo,message),processLastException();else if(ex)stack=TraceKit.computeStackTrace(ex),notifyHandlers(stack,!0);else{var location={url:url,line:lineNo,column:colNo};location.func=TraceKit.computeStackTrace.guessFunctionName(location.url,location.line),location.context=TraceKit.computeStackTrace.gatherContext(location.url,location.line),stack={message:message,url:document.location.href,stack:[location]},notifyHandlers(stack,!0)}return _oldOnerrorHandler?_oldOnerrorHandler.apply(this,arguments):!1}function installGlobalHandler(){_onErrorHandlerInstalled||(_oldOnerrorHandler=window.onerror,window.onerror=traceKitWindowOnError,_onErrorHandlerInstalled=!0)}function uninstallGlobalHandler(){_onErrorHandlerInstalled&&(window.onerror=_oldOnerrorHandler,_onErrorHandlerInstalled=!1,_oldOnerrorHandler=undefined)}function processLastException(){var _lastExceptionStack=lastExceptionStack,_lastArgs=lastArgs;lastArgs=null,lastExceptionStack=null,lastException=null,notifyHandlers.apply(null,[_lastExceptionStack,!1].concat(_lastArgs)) -}function report(ex,rethrow){var args=_slice.call(arguments,1);if(lastExceptionStack){if(lastException===ex)return;processLastException()}var stack=TraceKit.computeStackTrace(ex);if(lastExceptionStack=stack,lastException=ex,lastArgs=args,window.setTimeout(function(){lastException===ex&&processLastException()},stack.incomplete?2e3:0),rethrow!==!1)throw ex}var _oldOnerrorHandler,_onErrorHandlerInstalled,handlers=[],lastArgs=null,lastException=null,lastExceptionStack=null;return report.subscribe=subscribe,report.unsubscribe=unsubscribe,report.uninstall=unsubscribeAll,report}(),TraceKit.computeStackTrace=function(){function loadSource(url){if(!TraceKit.remoteFetching)return"";try{var getXHR=function(){try{return new window.XMLHttpRequest}catch(e){return new window.ActiveXObject("Microsoft.XMLHTTP")}},request=getXHR();return request.open("GET",url,!1),request.send(""),request.responseText}catch(e){return""}}function getSource(url){if(!isString(url))return[];if(!hasKey(sourceCache,url)){var source="";-1!==url.indexOf(document.domain)&&(source=loadSource(url)),sourceCache[url]=source?source.split("\n"):[]}return sourceCache[url]}function guessFunctionName(url,lineNo){var m,reFunctionArgNames=/function ([^(]*)\(([^)]*)\)/,reGuessFunction=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,line="",maxLines=10,source=getSource(url);if(!source.length)return UNKNOWN_FUNCTION;for(var i=0;maxLines>i;++i)if(line=source[lineNo-i]+line,!isUndefined(line)){if(m=reGuessFunction.exec(line))return m[1];if(m=reFunctionArgNames.exec(line))return m[1]}return UNKNOWN_FUNCTION}function gatherContext(url,line){var source=getSource(url);if(!source.length)return null;var context=[],linesBefore=Math.floor(TraceKit.linesOfContext/2),linesAfter=linesBefore+TraceKit.linesOfContext%2,start=Math.max(0,line-linesBefore-1),end=Math.min(source.length,line+linesAfter-1);line-=1;for(var i=start;end>i;++i)isUndefined(source[i])||context.push(source[i]);return context.length>0?context:null}function escapeRegExp(text){return text.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function escapeCodeAsRegExpForMatchingInsideHTML(body){return escapeRegExp(body).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function findSourceInUrls(re,urls){for(var source,m,i=0,j=urls.length;j>i;++i)if((source=getSource(urls[i])).length&&(source=source.join("\n"),m=re.exec(source)))return{url:urls[i],line:source.substring(0,m.index).split("\n").length,column:m.index-source.lastIndexOf("\n",m.index)-1};return null}function findSourceInLine(fragment,url,line){var m,source=getSource(url),re=new RegExp("\\b"+escapeRegExp(fragment)+"\\b");return line-=1,source&&source.length>line&&(m=re.exec(source[line]))?m.index:null}function findSourceByFunctionBody(func){for(var body,re,parts,result,urls=[window.location.href],scripts=document.getElementsByTagName("script"),code=""+func,codeRE=/^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,eventRE=/^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,i=0;ii;++i){if(parts=gecko.exec(lines[i]))element={url:parts[3],func:parts[1]||UNKNOWN_FUNCTION,args:parts[2]?parts[2].split(","):"",line:+parts[4],column:parts[5]?+parts[5]:null};else{if(!(parts=chrome.exec(lines[i])))continue;element={url:parts[2],func:parts[1]||UNKNOWN_FUNCTION,line:+parts[3],column:parts[4]?+parts[4]:null}}!element.func&&element.line&&(element.func=guessFunctionName(element.url,element.line)),element.line&&(element.context=gatherContext(element.url,element.line)),stack.push(element)}return stack.length?(stack[0].line&&!stack[0].column&&reference?stack[0].column=findSourceInLine(reference[1],stack[0].url,stack[0].line):stack[0].column||isUndefined(ex.columnNumber)||(stack[0].column=ex.columnNumber+1),{name:ex.name,message:ex.message,url:document.location.href,stack:stack}):null}function computeStackTraceFromStacktraceProp(ex){for(var parts,stacktrace=ex.stacktrace,testRE=/ line (\d+), column (\d+) in (?:]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,lines=stacktrace.split("\n"),stack=[],i=0,j=lines.length;j>i;i+=2)if(parts=testRE.exec(lines[i])){var element={line:+parts[1],column:+parts[2],func:parts[3]||parts[4],args:parts[5]?parts[5].split(","):[],url:parts[6]};if(!element.func&&element.line&&(element.func=guessFunctionName(element.url,element.line)),element.line)try{element.context=gatherContext(element.url,element.line)}catch(exc){}element.context||(element.context=[lines[i+1]]),stack.push(element)}return stack.length?{name:ex.name,message:ex.message,url:document.location.href,stack:stack}:null}function computeStackTraceFromOperaMultiLineMessage(ex){var lines=ex.message.split("\n");if(lines.length<4)return null;var parts,i,len,source,lineRE1=/^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,lineRE2=/^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,lineRE3=/^\s*Line (\d+) of function script\s*$/i,stack=[],scripts=document.getElementsByTagName("script"),inlineScriptBlocks=[];for(i in scripts)hasKey(scripts,i)&&!scripts[i].src&&inlineScriptBlocks.push(scripts[i]);for(i=2,len=lines.length;len>i;i+=2){var item=null;if(parts=lineRE1.exec(lines[i]))item={url:parts[2],func:parts[3],line:+parts[1]};else if(parts=lineRE2.exec(lines[i])){item={url:parts[3],func:parts[4]};var relativeLine=+parts[1],script=inlineScriptBlocks[parts[2]-1];if(script&&(source=getSource(item.url))){source=source.join("\n");var pos=source.indexOf(script.innerText);pos>=0&&(item.line=relativeLine+source.substring(0,pos).split("\n").length)}}else if(parts=lineRE3.exec(lines[i])){var url=window.location.href.replace(/#.*$/,""),line=parts[1],re=new RegExp(escapeCodeAsRegExpForMatchingInsideHTML(lines[i+1]));source=findSourceInUrls(re,[url]),item={url:url,line:source?source.line:line,func:""}}if(item){item.func||(item.func=guessFunctionName(item.url,item.line));var context=gatherContext(item.url,item.line),midline=context?context[Math.floor(context.length/2)]:null;item.context=context&&midline.replace(/^\s*/,"")===lines[i+1].replace(/^\s*/,"")?context:[lines[i+1]],stack.push(item)}}return stack.length?{name:ex.name,message:lines[0],url:document.location.href,stack:stack}:null}function augmentStackTraceWithInitialElement(stackInfo,url,lineNo,message){var initial={url:url,line:lineNo};if(initial.url&&initial.line){stackInfo.incomplete=!1,initial.func||(initial.func=guessFunctionName(initial.url,initial.line)),initial.context||(initial.context=gatherContext(initial.url,initial.line));var reference=/ '([^']+)' /.exec(message);if(reference&&(initial.column=findSourceInLine(reference[1],initial.url,initial.line)),stackInfo.stack.length>0&&stackInfo.stack[0].url===initial.url){if(stackInfo.stack[0].line===initial.line)return!1;if(!stackInfo.stack[0].line&&stackInfo.stack[0].func===initial.func)return stackInfo.stack[0].line=initial.line,stackInfo.stack[0].context=initial.context,!1}return stackInfo.stack.unshift(initial),stackInfo.partial=!0,!0}return stackInfo.incomplete=!0,!1}function computeStackTraceByWalkingCallerChain(ex,depth){for(var parts,item,source,functionName=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,stack=[],funcs={},recursion=!1,curr=computeStackTraceByWalkingCallerChain.caller;curr&&!recursion;curr=curr.caller)if(curr!==computeStackTrace&&curr!==TraceKit.report){if(item={url:null,func:UNKNOWN_FUNCTION,line:null,column:null},curr.name?item.func=curr.name:(parts=functionName.exec(curr.toString()))&&(item.func=parts[1]),source=findSourceByFunctionBody(curr)){item.url=source.url,item.line=source.line,item.func===UNKNOWN_FUNCTION&&(item.func=guessFunctionName(item.url,item.line));var reference=/ '([^']+)' /.exec(ex.message||ex.description);reference&&(item.column=findSourceInLine(reference[1],source.url,source.line))}funcs[""+curr]?recursion=!0:funcs[""+curr]=!0,stack.push(item)}depth&&stack.splice(0,depth);var result={name:ex.name,message:ex.message,url:document.location.href,stack:stack};return augmentStackTraceWithInitialElement(result,ex.sourceURL||ex.fileName,ex.line||ex.lineNumber,ex.message||ex.description),result}function computeStackTrace(ex,depth){var stack=null;depth=null==depth?0:+depth;try{if(stack=computeStackTraceFromStacktraceProp(ex))return stack}catch(e){if(debug)throw e}try{if(stack=computeStackTraceFromStackProp(ex))return stack}catch(e){if(debug)throw e}try{if(stack=computeStackTraceFromOperaMultiLineMessage(ex))return stack}catch(e){if(debug)throw e}try{if(stack=computeStackTraceByWalkingCallerChain(ex,depth+1))return stack}catch(e){if(debug)throw e}return{}}var debug=!1,sourceCache={};return computeStackTrace.augmentStackTraceWithInitialElement=augmentStackTraceWithInitialElement,computeStackTrace.computeStackTraceFromStackProp=computeStackTraceFromStackProp,computeStackTrace.guessFunctionName=guessFunctionName,computeStackTrace.gatherContext=gatherContext,computeStackTrace}();var lastCapturedException,lastEventId,globalServer,globalUser,globalKey,globalProject,authQueryString,_Raven=window.Raven,hasJSON=!("object"!=typeof JSON||!JSON.stringify),globalOptions={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],collectWindowErrors:!0,tags:{},maxMessageLength:100,extra:{}},isRavenInstalled=!1,objectPrototype=Object.prototype,startTime=now(),Raven={VERSION:"1.1.18",debug:!0,noConflict:function(){return window.Raven=_Raven,Raven},config:function(dsn,options){if(globalServer)return logDebug("error","Error: Raven has already been configured"),Raven;if(!dsn)return Raven;var uri=parseDSN(dsn),lastSlash=uri.path.lastIndexOf("/"),path=uri.path.substr(1,lastSlash);return options&&each(options,function(key,value){globalOptions[key]=value}),globalOptions.ignoreErrors.push(/^Script error\.?$/),globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/),globalOptions.ignoreErrors=joinRegExp(globalOptions.ignoreErrors),globalOptions.ignoreUrls=globalOptions.ignoreUrls.length?joinRegExp(globalOptions.ignoreUrls):!1,globalOptions.whitelistUrls=globalOptions.whitelistUrls.length?joinRegExp(globalOptions.whitelistUrls):!1,globalOptions.includePaths=joinRegExp(globalOptions.includePaths),globalKey=uri.user,globalProject=uri.path.substr(lastSlash+1),globalServer="//"+uri.host+(uri.port?":"+uri.port:"")+"/"+path+"api/"+globalProject+"/store/",uri.protocol&&(globalServer=uri.protocol+":"+globalServer),globalOptions.fetchContext&&(TraceKit.remoteFetching=!0),globalOptions.linesOfContext&&(TraceKit.linesOfContext=globalOptions.linesOfContext),TraceKit.collectWindowErrors=!!globalOptions.collectWindowErrors,setAuthQueryString(),Raven},install:function(){return isSetup()&&!isRavenInstalled&&(TraceKit.report.subscribe(handleStackInfo),isRavenInstalled=!0),Raven},context:function(options,func,args){return isFunction(options)&&(args=func||[],func=options,options=undefined),Raven.wrap(options,func).apply(this,args)},wrap:function(options,func){function wrapped(){for(var args=[],i=arguments.length,deep=!options||options&&options.deep!==!1;i--;)args[i]=deep?Raven.wrap(options,arguments[i]):arguments[i];try{return func.apply(this,args)}catch(e){throw Raven.captureException(e,options),e}}if(isUndefined(func)&&!isFunction(options))return options;if(isFunction(options)&&(func=options,options=undefined),!isFunction(func))return func;if(func.__raven__)return func;for(var property in func)hasKey(func,property)&&(wrapped[property]=func[property]);return wrapped.__raven__=!0,wrapped.__inner__=func,wrapped},uninstall:function(){return TraceKit.report.uninstall(),isRavenInstalled=!1,Raven},captureException:function(ex,options){if(!isError(ex))return Raven.captureMessage(ex,options);lastCapturedException=ex;try{TraceKit.report(ex,options)}catch(ex1){if(ex!==ex1)throw ex1}return Raven},captureMessage:function(msg,options){return globalOptions.ignoreErrors.test&&globalOptions.ignoreErrors.test(msg)?void 0:(send(objectMerge({message:msg+""},options)),Raven)},setUserContext:function(user){return globalUser=user,Raven},setExtraContext:function(extra){return globalOptions.extra=extra||{},Raven},setTagsContext:function(tags){return globalOptions.tags=tags||{},Raven},setReleaseContext:function(release){return globalOptions.release=release,Raven},lastException:function(){return lastCapturedException},lastEventId:function(){return lastEventId},isSetup:function(){return isSetup()}};Raven.setUser=Raven.setUserContext;var dsnKeys="source protocol user pass host port path".split(" "),dsnPattern=/^(?:(\w+):)?\/\/(\w+)(:\w+)?@([\w\.-]+)(?::(\d+))?(\/.*)/;RavenConfigError.prototype=new Error,RavenConfigError.prototype.constructor=RavenConfigError,afterLoad(),"function"==typeof define&&define.amd?(window.Raven=Raven,define("raven",[],function(){return Raven})):"object"==typeof module?module.exports=Raven:"object"==typeof exports?exports=Raven:window.Raven=Raven}(window),function(window,undefined){var gEval=function(js){(window.execScript||function(js){window.eval.call(window,js)})(js)},isA=function(a,b){return a instanceof(b||Array)},D=document,getElementsByTagName="getElementsByTagName",length="length",readyState="readyState",onreadystatechange="onreadystatechange",scripts=D[getElementsByTagName]("script"),scriptTag=scripts[scripts[length]-1],script=scriptTag.innerHTML.replace(/^\s+|\s+$/g,"");if(!window.ljs){var checkLoaded=scriptTag.src.match(/checkLoaded/)?1:0,header=D[getElementsByTagName]("head")[0]||D.documentElement,urlParse=function(url){var parts={};return parts.u=url.replace(/#(=)?([^#]*)?/g,function(m,a,b){return parts[a?"f":"i"]=b,""}),parts},appendElmt=function(type,attrs,cb){var i,e=D.createElement(type);cb&&(e[readyState]?e[onreadystatechange]=function(){("loaded"===e[readyState]||"complete"===e[readyState])&&(e[onreadystatechange]=null,cb())}:e.onload=cb);for(i in attrs)attrs[i]&&(e[i]=attrs[i]);header.appendChild(e)},load=function(url,cb){if(this.aliases&&this.aliases[url]){var args=this.aliases[url].slice(0);return isA(args)||(args=[args]),cb&&args.push(cb),this.load.apply(this,args)}if(isA(url)){for(var l=url[length];l--;)this.load(url[l]);return cb&&url.push(cb),this.load.apply(this,url)}return url.match(/\.css\b/)?this.loadcss(url,cb):this.loadjs(url,cb)},loaded={},loader={aliases:{},loadjs:function(url,cb){var parts=urlParse(url);return url=parts.u,loaded[url]===!0?(cb&&cb(),this):loaded[url]!==undefined?(cb&&(loaded[url]=function(ocb,cb){return function(){ocb&&ocb(),cb&&cb()}}(loaded[url],cb)),this):(loaded[url]=function(cb){return function(){loaded[url]=!0,cb&&cb()}}(cb),cb=function(){loaded[url]()},appendElmt("script",{type:"text/javascript",src:url,id:parts.i,onerror:function(error){if(parts.f){var c=error.currentTarget;c.parentNode.removeChild(c),appendElmt("script",{type:"text/javascript",src:parts.f,id:parts.i},cb)}}},cb),this)},loadcss:function(url,cb){var parts=urlParse(url);return url=parts.u,loaded[url]||appendElmt("link",{type:"text/css",rel:"stylesheet",href:url,id:parts.i}),loaded[url]=!0,cb&&cb(),this},load:function(){var argv=arguments,argc=argv[length];return 1===argc&&isA(argv[0],Function)?(argv[0](),this):(load.call(this,argv[0],1>=argc?undefined:function(){loader.load.apply(loader,[].slice.call(argv,1))}),this)},addAliases:function(aliases){for(var i in aliases)this.aliases[i]=isA(aliases[i])?aliases[i].slice(0):aliases[i];return this}};if(checkLoaded){var i,l,links,url;for(i=0,l=scripts[length];l>i;i++)(url=scripts[i].getAttribute("src"))&&(loaded[url.replace(/#.*$/,"")]=!0);for(links=D[getElementsByTagName]("link"),i=0,l=links[length];l>i;i++)("stylesheet"===links[i].rel||"text/css"===links[i].type)&&(loaded[links[i].getAttribute("href").replace(/#.*$/,"")]=!0)}window.ljs=loader}script&&gEval(script)}(window),MessageFormat.locale.af=function(n){return 1===n?"one":"other"},MessageFormat.locale.am=function(n){return 0===n||1==n?"one":"other"},MessageFormat.locale.ar=function(n){return 0===n?"zero":1==n?"one":2==n?"two":n%100>=3&&10>=n%100&&n==Math.floor(n)?"few":n%100>=11&&99>=n%100&&n==Math.floor(n)?"many":"other"},MessageFormat.locale.bg=function(n){return 1===n?"one":"other"},MessageFormat.locale.bn=function(n){return 1===n?"one":"other"},MessageFormat.locale.br=function(n){return 0===n?"zero":1==n?"one":2==n?"two":3==n?"few":6==n?"many":"other"},MessageFormat.locale.ca=function(n){return 1===n?"one":"other"},MessageFormat.locale.cs=function(n){return 1==n?"one":2==n||3==n||4==n?"few":"other"},MessageFormat.locale.cy=function(n){return 0===n?"zero":1==n?"one":2==n?"two":3==n?"few":6==n?"many":"other"},MessageFormat.locale.da=function(n){return 1===n?"one":"other"},MessageFormat.locale.de=function(n){return 1===n?"one":"other"},MessageFormat.locale.el=function(n){return 1===n?"one":"other"},MessageFormat.locale.en=function(n){return 1===n?"one":"other"},MessageFormat.locale.es=function(n){return 1===n?"one":"other"},MessageFormat.locale.et=function(n){return 1===n?"one":"other"},MessageFormat.locale.eu=function(n){return 1===n?"one":"other"},MessageFormat.locale.fa=function(){return"other"},MessageFormat.locale.fi=function(n){return 1===n?"one":"other"},MessageFormat.locale.fil=function(n){return 0===n||1==n?"one":"other"},MessageFormat.locale.fr=function(n){return 0===n||1==n?"one":"other"},MessageFormat.locale.ga=function(n){return 1==n?"one":2==n?"two":"other"},MessageFormat.locale.gl=function(n){return 1===n?"one":"other"},MessageFormat.locale.gsw=function(n){return 1===n?"one":"other"},MessageFormat.locale.gu=function(n){return 1===n?"one":"other"},MessageFormat.locale.he=function(n){return 1===n?"one":"other"},MessageFormat.locale.hi=function(n){return 0===n||1==n?"one":"other"},MessageFormat.locale.hr=function(n){return n%10==1&&n%100!=11?"one":n%10>=2&&4>=n%10&&(12>n%100||n%100>14)&&n==Math.floor(n)?"few":n%10===0||n%10>=5&&9>=n%10||n%100>=11&&14>=n%100&&n==Math.floor(n)?"many":"other"},MessageFormat.locale.hu=function(){return"other"},MessageFormat.locale.id=function(){return"other"},MessageFormat.locale["in"]=function(){return"other"},MessageFormat.locale.is=function(n){return 1===n?"one":"other"},MessageFormat.locale.it=function(n){return 1===n?"one":"other"},MessageFormat.locale.iw=function(n){return 1===n?"one":"other"},MessageFormat.locale.ja=function(){return"other"},MessageFormat.locale.kn=function(){return"other"},MessageFormat.locale.ko=function(){return"other"},MessageFormat.locale.lag=function(n){return 0===n?"zero":n>0&&2>n?"one":"other"},MessageFormat.locale.ln=function(n){return 0===n||1==n?"one":"other"},MessageFormat.locale.lt=function(n){return n%10==1&&(11>n%100||n%100>19)?"one":n%10>=2&&9>=n%10&&(11>n%100||n%100>19)&&n==Math.floor(n)?"few":"other"},MessageFormat.locale.lv=function(n){return 0===n?"zero":n%10==1&&n%100!=11?"one":"other"},MessageFormat.locale.mk=function(n){return n%10==1&&11!=n?"one":"other"},MessageFormat.locale.ml=function(n){return 1===n?"one":"other"},MessageFormat.locale.mo=function(n){return 1==n?"one":0===n||1!=n&&n%100>=1&&19>=n%100&&n==Math.floor(n)?"few":"other"},MessageFormat.locale.mr=function(n){return 1===n?"one":"other"},MessageFormat.locale.ms=function(){return"other"},MessageFormat.locale.mt=function(n){return 1==n?"one":0===n||n%100>=2&&4>=n%100&&n==Math.floor(n)?"few":n%100>=11&&19>=n%100&&n==Math.floor(n)?"many":"other"},MessageFormat.locale.nl=function(n){return 1===n?"one":"other"},MessageFormat.locale.no=function(n){return 1===n?"one":"other"},MessageFormat.locale.or=function(n){return 1===n?"one":"other"},MessageFormat.locale.pl=function(n){return 1==n?"one":n%10>=2&&4>=n%10&&(12>n%100||n%100>14)&&n==Math.floor(n)?"few":n%10===0||1!=n&&n%10==1||(n%10>=5&&9>=n%10||n%100>=12&&14>=n%100)&&n==Math.floor(n)?"many":"other"},MessageFormat.locale.pt=function(n){return 1===n?"one":"other"},MessageFormat.locale.ro=function(n){return 1==n?"one":0===n||1!=n&&n%100>=1&&19>=n%100&&n==Math.floor(n)?"few":"other"},MessageFormat.locale.ru=function(n){return n%10==1&&n%100!=11?"one":n%10>=2&&4>=n%10&&(12>n%100||n%100>14)&&n==Math.floor(n)?"few":n%10===0||n%10>=5&&9>=n%10||n%100>=11&&14>=n%100&&n==Math.floor(n)?"many":"other"},MessageFormat.locale.shi=function(n){return n>=0&&1>=n?"one":n>=2&&10>=n&&n==Math.floor(n)?"few":"other"},MessageFormat.locale.sk=function(n){return 1==n?"one":2==n||3==n||4==n?"few":"other"},MessageFormat.locale.sl=function(n){return n%100==1?"one":n%100==2?"two":n%100==3||n%100==4?"few":"other"},MessageFormat.locale.sq=function(n){return 1===n?"one":"other"},MessageFormat.locale.sr=function(n){return n%10==1&&n%100!=11?"one":n%10>=2&&4>=n%10&&(12>n%100||n%100>14)&&n==Math.floor(n)?"few":n%10===0||n%10>=5&&9>=n%10||n%100>=11&&14>=n%100&&n==Math.floor(n)?"many":"other"},MessageFormat.locale.sv=function(n){return 1===n?"one":"other"},MessageFormat.locale.sw=function(n){return 1===n?"one":"other"},MessageFormat.locale.ta=function(n){return 1===n?"one":"other"},MessageFormat.locale.te=function(n){return 1===n?"one":"other"},MessageFormat.locale.th=function(){return"other"},MessageFormat.locale.tl=function(n){return 0===n||1==n?"one":"other"},MessageFormat.locale.tr=function(){return"other"},MessageFormat.locale.uk=function(n){return n%10==1&&n%100!=11?"one":n%10>=2&&4>=n%10&&(12>n%100||n%100>14)&&n==Math.floor(n)?"few":n%10===0||n%10>=5&&9>=n%10||n%100>=11&&14>=n%100&&n==Math.floor(n)?"many":"other"},MessageFormat.locale.ur=function(n){return 1===n?"one":"other"},MessageFormat.locale.vi=function(){return"other"},MessageFormat.locale.zh=function(){return"other"}(function(factory){"function"==typeof define&&define.amd?define(["jquery"],factory):factory(jQuery)}(function($){function focusable(element,isTabIndexNotNaN){var map,mapName,img,nodeName=element.nodeName.toLowerCase();return"area"===nodeName?(map=element.parentNode,mapName=map.name,element.href&&mapName&&"map"===map.nodeName.toLowerCase()?(img=$("img[usemap=#"+mapName+"]")[0],!!img&&visible(img)):!1):(/input|select|textarea|button|object/.test(nodeName)?!element.disabled:"a"===nodeName?element.href||isTabIndexNotNaN:isTabIndexNotNaN)&&visible(element)}function visible(element){return $.expr.filters.visible(element)&&!$(element).parents().addBack().filter(function(){return"hidden"===$.css(this,"visibility")}).length}$.ui=$.ui||{},$.extend($.ui,{version:"@VERSION",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),$.fn.extend({scrollParent:function(){var position=this.css("position"),excludeStaticParent="absolute"===position,scrollParent=this.parents().filter(function(){var parent=$(this);return excludeStaticParent&&"static"===parent.css("position")?!1:/(auto|scroll)/.test(parent.css("overflow")+parent.css("overflow-y")+parent.css("overflow-x"))}).eq(0);return"fixed"!==position&&scrollParent.length?scrollParent:$(this[0].ownerDocument||document)},uniqueId:function(){var uuid=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++uuid)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&$(this).removeAttr("id")})}}),$.extend($.expr[":"],{data:$.expr.createPseudo?$.expr.createPseudo(function(dataName){return function(elem){return!!$.data(elem,dataName)}}):function(elem,i,match){return!!$.data(elem,match[3])},focusable:function(element){return focusable(element,!isNaN($.attr(element,"tabindex")))},tabbable:function(element){var tabIndex=$.attr(element,"tabindex"),isTabIndexNaN=isNaN(tabIndex);return(isTabIndexNaN||tabIndex>=0)&&focusable(element,!isTabIndexNaN)}}),$("").outerWidth(1).jquery||$.each(["Width","Height"],function(i,name){function reduce(elem,size,border,margin){return $.each(side,function(){size-=parseFloat($.css(elem,"padding"+this))||0,border&&(size-=parseFloat($.css(elem,"border"+this+"Width"))||0),margin&&(size-=parseFloat($.css(elem,"margin"+this))||0)}),size}var side="Width"===name?["Left","Right"]:["Top","Bottom"],type=name.toLowerCase(),orig={innerWidth:$.fn.innerWidth,innerHeight:$.fn.innerHeight,outerWidth:$.fn.outerWidth,outerHeight:$.fn.outerHeight};$.fn["inner"+name]=function(size){return void 0===size?orig["inner"+name].call(this):this.each(function(){$(this).css(type,reduce(this,size)+"px")})},$.fn["outer"+name]=function(size,margin){return"number"!=typeof size?orig["outer"+name].call(this,size):this.each(function(){$(this).css(type,reduce(this,size,!0,margin)+"px")})}}),$.fn.addBack||($.fn.addBack=function(selector){return this.add(null==selector?this.prevObject:this.prevObject.filter(selector))}),$("").data("a-b","a").removeData("a-b").data("a-b")&&($.fn.removeData=function(removeData){return function(key){return arguments.length?removeData.call(this,$.camelCase(key)):removeData.call(this)}}($.fn.removeData)),$.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),$.fn.extend({focus:function(orig){return function(delay,fn){return"number"==typeof delay?this.each(function(){var elem=this;setTimeout(function(){$(elem).focus(),fn&&fn.call(elem)},delay)}):orig.apply(this,arguments)}}($.fn.focus),disableSelection:function(){var eventType="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(eventType+".ui-disableSelection",function(event){event.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(zIndex){if(void 0!==zIndex)return this.css("zIndex",zIndex);if(this.length)for(var position,value,elem=$(this[0]);elem.length&&elem[0]!==document;){if(position=elem.css("position"),("absolute"===position||"relative"===position||"fixed"===position)&&(value=parseInt(elem.css("zIndex"),10),!isNaN(value)&&0!==value))return value;elem=elem.parent()}return 0}}),$.ui.plugin={add:function(module,option,set){var i,proto=$.ui[module].prototype;for(i in set)proto.plugins[i]=proto.plugins[i]||[],proto.plugins[i].push([option,set[i]])},call:function(instance,name,args,allowDisconnected){var i,set=instance.plugins[name];if(set&&(allowDisconnected||instance.element[0].parentNode&&11!==instance.element[0].parentNode.nodeType))for(i=0;iinputIndex;inputIndex++)for(key in input[inputIndex])value=input[inputIndex][key],input[inputIndex].hasOwnProperty(key)&&void 0!==value&&(target[key]=$.isPlainObject(value)?$.isPlainObject(target[key])?$.widget.extend({},target[key],value):$.widget.extend({},value):value);return target},$.widget.bridge=function(name,object){var fullName=object.prototype.widgetFullName||name;$.fn[name]=function(options){var isMethodCall="string"==typeof options,args=widget_slice.call(arguments,1),returnValue=this;return options=!isMethodCall&&args.length?$.widget.extend.apply(null,[options].concat(args)):options,this.each(isMethodCall?function(){var methodValue,instance=$.data(this,fullName);return"instance"===options?(returnValue=instance,!1):instance?$.isFunction(instance[options])&&"_"!==options.charAt(0)?(methodValue=instance[options].apply(instance,args),methodValue!==instance&&void 0!==methodValue?(returnValue=methodValue&&methodValue.jquery?returnValue.pushStack(methodValue.get()):methodValue,!1):void 0):$.error("no such method '"+options+"' for "+name+" widget instance"):$.error("cannot call methods on "+name+" prior to initialization; attempted to call method '"+options+"'")}:function(){var instance=$.data(this,fullName);instance?(instance.option(options||{}),instance._init&&instance._init()):$.data(this,fullName,new object(options,this))}),returnValue}},$.Widget=function(){},$.Widget._childConstructors=[],$.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(options,element){element=$(element||this.defaultElement||this)[0],this.element=$(element),this.uuid=widget_uuid++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=$.widget.extend({},this.options,this._getCreateOptions(),options),this.bindings=$(),this.hoverable=$(),this.focusable=$(),element!==this&&($.data(element,this.widgetFullName,this),this._on(!0,this.element,{remove:function(event){event.target===element&&this.destroy()}}),this.document=$(element.style?element.ownerDocument:element.document||element),this.window=$(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init() -},_getCreateOptions:$.noop,_getCreateEventData:$.noop,_create:$.noop,_init:$.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData($.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:$.noop,widget:function(){return this.element},option:function(key,value){var parts,curOption,i,options=key;if(0===arguments.length)return $.widget.extend({},this.options);if("string"==typeof key)if(options={},parts=key.split("."),key=parts.shift(),parts.length){for(curOption=options[key]=$.widget.extend({},this.options[key]),i=0;i=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})}),function(factory){"function"==typeof define&&define.amd?define(["jquery","./core","./mouse","./widget"],factory):factory(jQuery)}(function($){return $.widget("ui.draggable",$.ui.mouse,{version:"@VERSION",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._setHandleClassName(),this._mouseInit()},_setOption:function(key,value){this._super(key,value),"handle"===key&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?void(this.destroyOnClear=!0):(this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._removeHandleClassName(),void this._mouseDestroy())},_mouseCapture:function(event){var document=this.document[0],o=this.options;try{document.activeElement&&"body"!==document.activeElement.nodeName.toLowerCase()&&$(document.activeElement).blur()}catch(error){}return this.helper||o.disabled||$(event.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(event),this.handle?($(o.iframeFix===!0?"iframe":o.iframeFix).each(function(){$("
").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css($(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(event){var o=this.options;return this.helper=this._createHelper(event),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),$.ui.ddmanager&&($.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,$.extend(this.offset,{click:{left:event.pageX-this.offset.left,top:event.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(event,!1),this.originalPageX=event.pageX,this.originalPageY=event.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this._setContainment(),this._trigger("start",event)===!1?(this._clear(),!1):(this._cacheHelperProportions(),$.ui.ddmanager&&!o.dropBehaviour&&$.ui.ddmanager.prepareOffsets(this,event),this._mouseDrag(event,!0),$.ui.ddmanager&&$.ui.ddmanager.dragStart(this,event),!0)},_mouseDrag:function(event,noPropagation){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(event,!0),this.positionAbs=this._convertPositionTo("absolute"),!noPropagation){var ui=this._uiHash();if(this._trigger("drag",event,ui)===!1)return this._mouseUp({}),!1;this.position=ui.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",$.ui.ddmanager&&$.ui.ddmanager.drag(this,event),!1},_mouseStop:function(event){var that=this,dropped=!1;return $.ui.ddmanager&&!this.options.dropBehaviour&&(dropped=$.ui.ddmanager.drop(this,event)),this.dropped&&(dropped=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!dropped||"valid"===this.options.revert&&dropped||this.options.revert===!0||$.isFunction(this.options.revert)&&this.options.revert.call(this.element,dropped)?$(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){that._trigger("stop",event)!==!1&&that._clear()}):this._trigger("stop",event)!==!1&&this._clear(),!1},_mouseUp:function(event){return $("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),$.ui.ddmanager&&$.ui.ddmanager.dragStop(this,event),this.element.focus(),$.ui.mouse.prototype._mouseUp.call(this,event)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(event){return this.options.handle?!!$(event.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this.handleElement.addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.handleElement.removeClass("ui-draggable-handle")},_createHelper:function(event){var o=this.options,helper=$.isFunction(o.helper)?$(o.helper.apply(this.element[0],[event])):"clone"===o.helper?this.element.clone().removeAttr("id"):this.element;return helper.parents("body").length||helper.appendTo("parent"===o.appendTo?this.element[0].parentNode:o.appendTo),helper[0]===this.element[0]||/(fixed|absolute)/.test(helper.css("position"))||helper.css("position","absolute"),helper},_adjustOffsetFromHelper:function(obj){"string"==typeof obj&&(obj=obj.split(" ")),$.isArray(obj)&&(obj={left:+obj[0],top:+obj[1]||0}),"left"in obj&&(this.offset.click.left=obj.left+this.margins.left),"right"in obj&&(this.offset.click.left=this.helperProportions.width-obj.right+this.margins.left),"top"in obj&&(this.offset.click.top=obj.top+this.margins.top),"bottom"in obj&&(this.offset.click.top=this.helperProportions.height-obj.bottom+this.margins.top)},_isRootNode:function(element){return/(html|body)/i.test(element.tagName)||element===this.document[0]},_getParentOffset:function(){var po=this.offsetParent.offset(),document=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&$.contains(this.scrollParent[0],this.offsetParent[0])&&(po.left+=this.scrollParent.scrollLeft(),po.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(po={top:0,left:0}),{top:po.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:po.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var p=this.element.position(),scrollIsRootNode=this._isRootNode(this.scrollParent[0]);return{top:p.top-(parseInt(this.helper.css("top"),10)||0)+(scrollIsRootNode?0:this.scrollParent.scrollTop()),left:p.left-(parseInt(this.helper.css("left"),10)||0)+(scrollIsRootNode?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var over,c,ce,o=this.options,document=this.document[0];return this.relative_container=null,o.containment?"window"===o.containment?void(this.containment=[$(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,$(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,$(window).scrollLeft()+$(window).width()-this.helperProportions.width-this.margins.left,$(window).scrollTop()+($(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):"document"===o.containment?void(this.containment=[0,0,$(document).width()-this.helperProportions.width-this.margins.left,($(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):o.containment.constructor===Array?void(this.containment=o.containment):("parent"===o.containment&&(o.containment=this.helper[0].parentNode),c=$(o.containment),ce=c[0],void(ce&&(over="hidden"!==c.css("overflow"),this.containment=[(parseInt(c.css("borderLeftWidth"),10)||0)+(parseInt(c.css("paddingLeft"),10)||0),(parseInt(c.css("borderTopWidth"),10)||0)+(parseInt(c.css("paddingTop"),10)||0),(over?Math.max(ce.scrollWidth,ce.offsetWidth):ce.offsetWidth)-(parseInt(c.css("borderRightWidth"),10)||0)-(parseInt(c.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(over?Math.max(ce.scrollHeight,ce.offsetHeight):ce.offsetHeight)-(parseInt(c.css("borderBottomWidth"),10)||0)-(parseInt(c.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c))):void(this.containment=null)},_convertPositionTo:function(d,pos){pos||(pos=this.position);var mod="absolute"===d?1:-1,scrollIsRootNode=this._isRootNode(this.scrollParent[0]);return{top:pos.top+this.offset.relative.top*mod+this.offset.parent.top*mod-("fixed"===this.cssPosition?-this.offset.scroll.top:scrollIsRootNode?0:this.offset.scroll.top)*mod,left:pos.left+this.offset.relative.left*mod+this.offset.parent.left*mod-("fixed"===this.cssPosition?-this.offset.scroll.left:scrollIsRootNode?0:this.offset.scroll.left)*mod}},_generatePosition:function(event,constrainPosition){var containment,co,top,left,o=this.options,scrollIsRootNode=this._isRootNode(this.scrollParent[0]),pageX=event.pageX,pageY=event.pageY;return scrollIsRootNode&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),constrainPosition&&(this.containment&&(this.relative_container?(co=this.relative_container.offset(),containment=[this.containment[0]+co.left,this.containment[1]+co.top,this.containment[2]+co.left,this.containment[3]+co.top]):containment=this.containment,event.pageX-this.offset.click.leftcontainment[2]&&(pageX=containment[2]+this.offset.click.left),event.pageY-this.offset.click.top>containment[3]&&(pageY=containment[3]+this.offset.click.top)),o.grid&&(top=o.grid[1]?this.originalPageY+Math.round((pageY-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,pageY=containment?top-this.offset.click.top>=containment[1]||top-this.offset.click.top>containment[3]?top:top-this.offset.click.top>=containment[1]?top-o.grid[1]:top+o.grid[1]:top,left=o.grid[0]?this.originalPageX+Math.round((pageX-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,pageX=containment?left-this.offset.click.left>=containment[0]||left-this.offset.click.left>containment[2]?left:left-this.offset.click.left>=containment[0]?left-o.grid[0]:left+o.grid[0]:left),"y"===o.axis&&(pageX=this.originalPageX),"x"===o.axis&&(pageY=this.originalPageY)),{top:pageY-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:scrollIsRootNode?0:this.offset.scroll.top),left:pageX-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:scrollIsRootNode?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(type,event,ui){return ui=ui||this._uiHash(),$.ui.plugin.call(this,type,[event,ui,this],!0),"drag"===type&&(this.positionAbs=this._convertPositionTo("absolute")),$.Widget.prototype._trigger.call(this,type,event,ui)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),$.ui.plugin.add("draggable","connectToSortable",{start:function(event,ui,inst){var o=inst.options,uiSortable=$.extend({},ui,{item:inst.element});inst.sortables=[],$(o.connectToSortable).each(function(){var sortable=$(this).sortable("instance");sortable&&!sortable.options.disabled&&(inst.sortables.push({instance:sortable,shouldRevert:sortable.options.revert}),sortable.refreshPositions(),sortable._trigger("activate",event,uiSortable))})},stop:function(event,ui,inst){var uiSortable=$.extend({},ui,{item:inst.element});$.each(inst.sortables,function(){this.instance.isOver?(this.instance.isOver=0,inst.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(event),this.instance.options.helper=this.instance.options._helper,"original"===inst.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",event,uiSortable))})},drag:function(event,ui,inst){var that=this;$.each(inst.sortables,function(){var innermostIntersecting=!1,thisSortable=this;this.instance.positionAbs=inst.positionAbs,this.instance.helperProportions=inst.helperProportions,this.instance.offset.click=inst.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(innermostIntersecting=!0,$.each(inst.sortables,function(){return this.instance.positionAbs=inst.positionAbs,this.instance.helperProportions=inst.helperProportions,this.instance.offset.click=inst.offset.click,this!==thisSortable&&this.instance._intersectsWith(this.instance.containerCache)&&$.contains(thisSortable.instance.element[0],this.instance.element[0])&&(innermostIntersecting=!1),innermostIntersecting})),innermostIntersecting?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=$(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return ui.helper[0]},event.target=this.instance.currentItem[0],this.instance._mouseCapture(event,!0),this.instance._mouseStart(event,!0,!0),this.instance.offset.click.top=inst.offset.click.top,this.instance.offset.click.left=inst.offset.click.left,this.instance.offset.parent.left-=inst.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=inst.offset.parent.top-this.instance.offset.parent.top,inst._trigger("toSortable",event),inst.dropped=this.instance.element,inst.currentItem=inst.element,this.instance.fromOutside=inst),this.instance.currentItem&&this.instance._mouseDrag(event)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",event,this.instance._uiHash(this.instance)),this.instance._mouseStop(event,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),inst._trigger("fromSortable",event),inst.dropped=!1)})}}),$.ui.plugin.add("draggable","cursor",{start:function(event,ui,instance){var t=$("body"),o=instance.options;t.css("cursor")&&(o._cursor=t.css("cursor")),t.css("cursor",o.cursor)},stop:function(event,ui,instance){var o=instance.options;o._cursor&&$("body").css("cursor",o._cursor)}}),$.ui.plugin.add("draggable","opacity",{start:function(event,ui,instance){var t=$(ui.helper),o=instance.options;t.css("opacity")&&(o._opacity=t.css("opacity")),t.css("opacity",o.opacity)},stop:function(event,ui,instance){var o=instance.options;o._opacity&&$(ui.helper).css("opacity",o._opacity)}}),$.ui.plugin.add("draggable","scroll",{start:function(event,ui,i){i.scrollParent[0]!==i.document[0]&&"HTML"!==i.scrollParent[0].tagName&&(i.overflowOffset=i.scrollParent.offset())},drag:function(event,ui,i){var o=i.options,scrolled=!1,document=i.document[0];i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(o.axis&&"x"===o.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-event.pageY=0;i--)l=inst.snapElements[i].left,r=l+inst.snapElements[i].width,t=inst.snapElements[i].top,b=t+inst.snapElements[i].height,l-d>x2||x1>r+d||t-d>y2||y1>b+d||!$.contains(inst.snapElements[i].item.ownerDocument,inst.snapElements[i].item)?(inst.snapElements[i].snapping&&inst.options.snap.release&&inst.options.snap.release.call(inst.element,event,$.extend(inst._uiHash(),{snapItem:inst.snapElements[i].item})),inst.snapElements[i].snapping=!1):("inner"!==o.snapMode&&(ts=Math.abs(t-y2)<=d,bs=Math.abs(b-y1)<=d,ls=Math.abs(l-x2)<=d,rs=Math.abs(r-x1)<=d,ts&&(ui.position.top=inst._convertPositionTo("relative",{top:t-inst.helperProportions.height,left:0}).top-inst.margins.top),bs&&(ui.position.top=inst._convertPositionTo("relative",{top:b,left:0}).top-inst.margins.top),ls&&(ui.position.left=inst._convertPositionTo("relative",{top:0,left:l-inst.helperProportions.width}).left-inst.margins.left),rs&&(ui.position.left=inst._convertPositionTo("relative",{top:0,left:r}).left-inst.margins.left)),first=ts||bs||ls||rs,"outer"!==o.snapMode&&(ts=Math.abs(t-y1)<=d,bs=Math.abs(b-y2)<=d,ls=Math.abs(l-x1)<=d,rs=Math.abs(r-x2)<=d,ts&&(ui.position.top=inst._convertPositionTo("relative",{top:t,left:0}).top-inst.margins.top),bs&&(ui.position.top=inst._convertPositionTo("relative",{top:b-inst.helperProportions.height,left:0}).top-inst.margins.top),ls&&(ui.position.left=inst._convertPositionTo("relative",{top:0,left:l}).left-inst.margins.left),rs&&(ui.position.left=inst._convertPositionTo("relative",{top:0,left:r-inst.helperProportions.width}).left-inst.margins.left)),!inst.snapElements[i].snapping&&(ts||bs||ls||rs||first)&&inst.options.snap.snap&&inst.options.snap.snap.call(inst.element,event,$.extend(inst._uiHash(),{snapItem:inst.snapElements[i].item})),inst.snapElements[i].snapping=ts||bs||ls||rs||first)}}),$.ui.plugin.add("draggable","stack",{start:function(event,ui,instance){var min,o=instance.options,group=$.makeArray($(o.stack)).sort(function(a,b){return(parseInt($(a).css("zIndex"),10)||0)-(parseInt($(b).css("zIndex"),10)||0)});group.length&&(min=parseInt($(group[0]).css("zIndex"),10)||0,$(group).each(function(i){$(this).css("zIndex",min+i)}),this.css("zIndex",min+group.length))}}),$.ui.plugin.add("draggable","zIndex",{start:function(event,ui,instance){var t=$(ui.helper),o=instance.options;t.css("zIndex")&&(o._zIndex=t.css("zIndex")),t.css("zIndex",o.zIndex)},stop:function(event,ui,instance){var o=instance.options;o._zIndex&&$(ui.helper).css("zIndex",o._zIndex)}}),$.ui.draggable}),function(factory){"function"==typeof define&&define.amd?define(["jquery","./core","./widget","./mouse","./draggable"],factory):factory(jQuery)}(function($){return $.widget("ui.droppable",{version:"@VERSION",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var proportions,o=this.options,accept=o.accept;this.isover=!1,this.isout=!0,this.accept=$.isFunction(accept)?accept:function(d){return d.is(accept)},this.proportions=function(){return arguments.length?void(proportions=arguments[0]):proportions?proportions:proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(o.scope),o.addClasses&&this.element.addClass("ui-droppable")},_addToManager:function(scope){$.ui.ddmanager.droppables[scope]=$.ui.ddmanager.droppables[scope]||[],$.ui.ddmanager.droppables[scope].push(this)},_splice:function(drop){for(var i=0;i=reference&&reference+size>x -}return function(draggable,droppable,toleranceMode){if(!droppable.offset)return!1;var draggableLeft,draggableTop,x1=(draggable.positionAbs||draggable.position.absolute).left,y1=(draggable.positionAbs||draggable.position.absolute).top,x2=x1+draggable.helperProportions.width,y2=y1+draggable.helperProportions.height,l=droppable.offset.left,t=droppable.offset.top,r=l+droppable.proportions().width,b=t+droppable.proportions().height;switch(toleranceMode){case"fit":return x1>=l&&r>=x2&&y1>=t&&b>=y2;case"intersect":return l=t&&b>=y1||y2>=t&&b>=y2||t>y1&&y2>b)&&(x1>=l&&r>=x1||x2>=l&&r>=x2||l>x1&&x2>r);default:return!1}}}(),$.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,event){var i,j,m=$.ui.ddmanager.droppables[t.options.scope]||[],type=event?event.type:null,list=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();droppablesLoop:for(i=0;i0?!0:(el[scroll]=1,has=el[scroll]>0,el[scroll]=0,has)},_create:function(){var n,i,handle,axis,hname,that=this,o=this.options;if(this.element.addClass("ui-resizable"),$.extend(this,{_aspectRatio:!!o.aspectRatio,aspectRatio:o.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:o.helper||o.ghost||o.animate?o.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap($("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=o.handles||($(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),n=this.handles.split(","),this.handles={},i=0;i
"),axis.css({zIndex:o.zIndex}),"se"===handle&&axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[handle]=".ui-resizable-"+handle,this.element.append(axis);this._renderAxis=function(target){var i,axis,padPos,padWrapper;target=target||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=this.element.children(this.handles[i]).first().show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(axis=$(this.handles[i],this.element),padWrapper=/sw|ne|nw|se|n|s/.test(i)?axis.outerHeight():axis.outerWidth(),padPos=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),target.css(padPos,padWrapper),this._proportionallyResize()),$(this.handles[i]).length},this._renderAxis(this.element),this._handles=$(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){that.resizing||(this.className&&(axis=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),that.axis=axis&&axis[1]?axis[1]:"se")}),o.autoHide&&(this._handles.hide(),$(this.element).addClass("ui-resizable-autohide").mouseenter(function(){o.disabled||($(this).removeClass("ui-resizable-autohide"),that._handles.show())}).mouseleave(function(){o.disabled||that.resizing||($(this).addClass("ui-resizable-autohide"),that._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var wrapper,_destroy=function(exp){$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(_destroy(this.element),wrapper=this.element,this.originalElement.css({position:wrapper.css("position"),width:wrapper.outerWidth(),height:wrapper.outerHeight(),top:wrapper.css("top"),left:wrapper.css("left")}).insertAfter(wrapper),wrapper.remove()),this.originalElement.css("resize",this.originalResizeStyle),_destroy(this.originalElement),this},_mouseCapture:function(event){var i,handle,capture=!1;for(i in this.handles)handle=$(this.handles[i])[0],(handle===event.target||$.contains(handle,event.target))&&(capture=!0);return!this.options.disabled&&capture},_mouseStart:function(event){var curleft,curtop,cursor,o=this.options,el=this.element;return this.resizing=!0,this._renderProxy(),curleft=this._num(this.helper.css("left")),curtop=this._num(this.helper.css("top")),o.containment&&(curleft+=$(o.containment).scrollLeft()||0,curtop+=$(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:curleft,top:curtop},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:el.width(),height:el.height()},this.originalSize=this._helper?{width:el.outerWidth(),height:el.outerHeight()}:{width:el.width(),height:el.height()},this.originalPosition={left:curleft,top:curtop},this.sizeDiff={width:el.outerWidth()-el.width(),height:el.outerHeight()-el.height()},this.originalMousePosition={left:event.pageX,top:event.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,cursor=$(".ui-resizable-"+this.axis).css("cursor"),$("body").css("cursor","auto"===cursor?this.axis+"-resize":cursor),el.addClass("ui-resizable-resizing"),this._propagate("start",event),!0},_mouseDrag:function(event){var data,props,smp=this.originalMousePosition,a=this.axis,dx=event.pageX-smp.left||0,dy=event.pageY-smp.top||0,trigger=this._change[a];return this._updatePrevProperties(),trigger?(data=trigger.apply(this,[event,dx,dy]),this._updateVirtualBoundaries(event.shiftKey),(this._aspectRatio||event.shiftKey)&&(data=this._updateRatio(data,event)),data=this._respectSize(data,event),this._updateCache(data),this._propagate("resize",event),props=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),$.isEmptyObject(props)||(this._updatePrevProperties(),this._trigger("resize",event,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(event){this.resizing=!1;var pr,ista,soffseth,soffsetw,s,left,top,o=this.options,that=this;return this._helper&&(pr=this._proportionallyResizeElements,ista=pr.length&&/textarea/i.test(pr[0].nodeName),soffseth=ista&&this._hasScroll(pr[0],"left")?0:that.sizeDiff.height,soffsetw=ista?0:that.sizeDiff.width,s={width:that.helper.width()-soffsetw,height:that.helper.height()-soffseth},left=parseInt(that.element.css("left"),10)+(that.position.left-that.originalPosition.left)||null,top=parseInt(that.element.css("top"),10)+(that.position.top-that.originalPosition.top)||null,o.animate||this.element.css($.extend(s,{top:top,left:left})),that.helper.height(that.size.height),that.helper.width(that.size.width),this._helper&&!o.animate&&this._proportionallyResize()),$("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",event),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var props={};return this.position.top!==this.prevPosition.top&&(props.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(props.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(props.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(props.height=this.size.height+"px"),this.helper.css(props),props},_updateVirtualBoundaries:function(forceAspectRatio){var pMinWidth,pMaxWidth,pMinHeight,pMaxHeight,b,o=this.options;b={minWidth:this._isNumber(o.minWidth)?o.minWidth:0,maxWidth:this._isNumber(o.maxWidth)?o.maxWidth:1/0,minHeight:this._isNumber(o.minHeight)?o.minHeight:0,maxHeight:this._isNumber(o.maxHeight)?o.maxHeight:1/0},(this._aspectRatio||forceAspectRatio)&&(pMinWidth=b.minHeight*this.aspectRatio,pMinHeight=b.minWidth/this.aspectRatio,pMaxWidth=b.maxHeight*this.aspectRatio,pMaxHeight=b.maxWidth/this.aspectRatio,pMinWidth>b.minWidth&&(b.minWidth=pMinWidth),pMinHeight>b.minHeight&&(b.minHeight=pMinHeight),pMaxWidthdata.width,isminh=this._isNumber(data.height)&&o.minHeight&&o.minHeight>data.height,dw=this.originalPosition.left+this.originalSize.width,dh=this.position.top+this.size.height,cw=/sw|nw|w/.test(a),ch=/nw|ne|n/.test(a);return isminw&&(data.width=o.minWidth),isminh&&(data.height=o.minHeight),ismaxw&&(data.width=o.maxWidth),ismaxh&&(data.height=o.maxHeight),isminw&&cw&&(data.left=dw-o.minWidth),ismaxw&&cw&&(data.left=dw-o.maxWidth),isminh&&ch&&(data.top=dh-o.minHeight),ismaxh&&ch&&(data.top=dh-o.maxHeight),data.width||data.height||data.left||!data.top?data.width||data.height||data.top||!data.left||(data.left=null):data.top=null,data},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var i,j,borders,paddings,prel,element=this.helper||this.element;for(i=0;i
"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++o.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(event,dx){return{width:this.originalSize.width+dx}},w:function(event,dx){var cs=this.originalSize,sp=this.originalPosition;return{left:sp.left+dx,width:cs.width-dx}},n:function(event,dx,dy){var cs=this.originalSize,sp=this.originalPosition;return{top:sp.top+dy,height:cs.height-dy}},s:function(event,dx,dy){return{height:this.originalSize.height+dy}},se:function(event,dx,dy){return $.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[event,dx,dy]))},sw:function(event,dx,dy){return $.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[event,dx,dy]))},ne:function(event,dx,dy){return $.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[event,dx,dy]))},nw:function(event,dx,dy){return $.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[event,dx,dy]))}},_propagate:function(n,event){$.ui.plugin.call(this,n,[event,this.ui()]),"resize"!==n&&this._trigger(n,event,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),$.ui.plugin.add("resizable","animate",{stop:function(event){var that=$(this).resizable("instance"),o=that.options,pr=that._proportionallyResizeElements,ista=pr.length&&/textarea/i.test(pr[0].nodeName),soffseth=ista&&that._hasScroll(pr[0],"left")?0:that.sizeDiff.height,soffsetw=ista?0:that.sizeDiff.width,style={width:that.size.width-soffsetw,height:that.size.height-soffseth},left=parseInt(that.element.css("left"),10)+(that.position.left-that.originalPosition.left)||null,top=parseInt(that.element.css("top"),10)+(that.position.top-that.originalPosition.top)||null;that.element.animate($.extend(style,top&&left?{top:top,left:left}:{}),{duration:o.animateDuration,easing:o.animateEasing,step:function(){var data={width:parseInt(that.element.css("width"),10),height:parseInt(that.element.css("height"),10),top:parseInt(that.element.css("top"),10),left:parseInt(that.element.css("left"),10)};pr&&pr.length&&$(pr[0]).css({width:data.width,height:data.height}),that._updateCache(data),that._propagate("resize",event)}})}}),$.ui.plugin.add("resizable","containment",{start:function(){var element,p,co,ch,cw,width,height,that=$(this).resizable("instance"),o=that.options,el=that.element,oc=o.containment,ce=oc instanceof $?oc.get(0):/parent/.test(oc)?el.parent().get(0):oc;ce&&(that.containerElement=$(ce),/document/.test(oc)||oc===document?(that.containerOffset={left:0,top:0},that.containerPosition={left:0,top:0},that.parentData={element:$(document),left:0,top:0,width:$(document).width(),height:$(document).height()||document.body.parentNode.scrollHeight}):(element=$(ce),p=[],$(["Top","Right","Left","Bottom"]).each(function(i,name){p[i]=that._num(element.css("padding"+name))}),that.containerOffset=element.offset(),that.containerPosition=element.position(),that.containerSize={height:element.innerHeight()-p[3],width:element.innerWidth()-p[1]},co=that.containerOffset,ch=that.containerSize.height,cw=that.containerSize.width,width=that._hasScroll(ce,"left")?ce.scrollWidth:cw,height=that._hasScroll(ce)?ce.scrollHeight:ch,that.parentData={element:ce,left:co.left,top:co.top,width:width,height:height}))},resize:function(event){var woset,hoset,isParent,isOffsetRelative,that=$(this).resizable("instance"),o=that.options,co=that.containerOffset,cp=that.position,pRatio=that._aspectRatio||event.shiftKey,cop={top:0,left:0},ce=that.containerElement,continueResize=!0;ce[0]!==document&&/static/.test(ce.css("position"))&&(cop=co),cp.left<(that._helper?co.left:0)&&(that.size.width=that.size.width+(that._helper?that.position.left-co.left:that.position.left-cop.left),pRatio&&(that.size.height=that.size.width/that.aspectRatio,continueResize=!1),that.position.left=o.helper?co.left:0),cp.top<(that._helper?co.top:0)&&(that.size.height=that.size.height+(that._helper?that.position.top-co.top:that.position.top),pRatio&&(that.size.width=that.size.height*that.aspectRatio,continueResize=!1),that.position.top=that._helper?co.top:0),that.offset.left=that.parentData.left+that.position.left,that.offset.top=that.parentData.top+that.position.top,woset=Math.abs((that._helper?that.offset.left-cop.left:that.offset.left-co.left)+that.sizeDiff.width),hoset=Math.abs((that._helper?that.offset.top-cop.top:that.offset.top-co.top)+that.sizeDiff.height),isParent=that.containerElement.get(0)===that.element.parent().get(0),isOffsetRelative=/relative|absolute/.test(that.containerElement.css("position")),isParent&&isOffsetRelative&&(woset-=Math.abs(that.parentData.left)),woset+that.size.width>=that.parentData.width&&(that.size.width=that.parentData.width-woset,pRatio&&(that.size.height=that.size.width/that.aspectRatio,continueResize=!1)),hoset+that.size.height>=that.parentData.height&&(that.size.height=that.parentData.height-hoset,pRatio&&(that.size.width=that.size.height*that.aspectRatio,continueResize=!1)),continueResize||(that.position.left=that.prevPosition.left,that.position.top=that.prevPosition.top,that.size.width=that.prevSize.width,that.size.height=that.prevSize.height)},stop:function(){var that=$(this).resizable("instance"),o=that.options,co=that.containerOffset,cop=that.containerPosition,ce=that.containerElement,helper=$(that.helper),ho=helper.offset(),w=helper.outerWidth()-that.sizeDiff.width,h=helper.outerHeight()-that.sizeDiff.height;that._helper&&!o.animate&&/relative/.test(ce.css("position"))&&$(this).css({left:ho.left-cop.left-co.left,width:w,height:h}),that._helper&&!o.animate&&/static/.test(ce.css("position"))&&$(this).css({left:ho.left-cop.left-co.left,width:w,height:h})}}),$.ui.plugin.add("resizable","alsoResize",{start:function(){var that=$(this).resizable("instance"),o=that.options,_store=function(exp){$(exp).each(function(){var el=$(this);el.data("ui-resizable-alsoresize",{width:parseInt(el.width(),10),height:parseInt(el.height(),10),left:parseInt(el.css("left"),10),top:parseInt(el.css("top"),10)})})};"object"!=typeof o.alsoResize||o.alsoResize.parentNode?_store(o.alsoResize):o.alsoResize.length?(o.alsoResize=o.alsoResize[0],_store(o.alsoResize)):$.each(o.alsoResize,function(exp){_store(exp)})},resize:function(event,ui){var that=$(this).resizable("instance"),o=that.options,os=that.originalSize,op=that.originalPosition,delta={height:that.size.height-os.height||0,width:that.size.width-os.width||0,top:that.position.top-op.top||0,left:that.position.left-op.left||0},_alsoResize=function(exp,c){$(exp).each(function(){var el=$(this),start=$(this).data("ui-resizable-alsoresize"),style={},css=c&&c.length?c:el.parents(ui.originalElement[0]).length?["width","height"]:["width","height","top","left"];$.each(css,function(i,prop){var sum=(start[prop]||0)+(delta[prop]||0);sum&&sum>=0&&(style[prop]=sum||null)}),el.css(style)})};"object"!=typeof o.alsoResize||o.alsoResize.nodeType?_alsoResize(o.alsoResize):$.each(o.alsoResize,function(exp,c){_alsoResize(exp,c)})},stop:function(){$(this).removeData("resizable-alsoresize")}}),$.ui.plugin.add("resizable","ghost",{start:function(){var that=$(this).resizable("instance"),o=that.options,cs=that.size;that.ghost=that.originalElement.clone(),that.ghost.css({opacity:.25,display:"block",position:"relative",height:cs.height,width:cs.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof o.ghost?o.ghost:""),that.ghost.appendTo(that.helper)},resize:function(){var that=$(this).resizable("instance");that.ghost&&that.ghost.css({position:"relative",height:that.size.height,width:that.size.width})},stop:function(){var that=$(this).resizable("instance");that.ghost&&that.helper&&that.helper.get(0).removeChild(that.ghost.get(0))}}),$.ui.plugin.add("resizable","grid",{resize:function(){var that=$(this).resizable("instance"),o=that.options,cs=that.size,os=that.originalSize,op=that.originalPosition,a=that.axis,grid="number"==typeof o.grid?[o.grid,o.grid]:o.grid,gridX=grid[0]||1,gridY=grid[1]||1,ox=Math.round((cs.width-os.width)/gridX)*gridX,oy=Math.round((cs.height-os.height)/gridY)*gridY,newWidth=os.width+ox,newHeight=os.height+oy,isMaxWidth=o.maxWidth&&o.maxWidthnewWidth,isMinHeight=o.minHeight&&o.minHeight>newHeight;o.grid=grid,isMinWidth&&(newWidth+=gridX),isMinHeight&&(newHeight+=gridY),isMaxWidth&&(newWidth-=gridX),isMaxHeight&&(newHeight-=gridY),/^(se|s|e)$/.test(a)?(that.size.width=newWidth,that.size.height=newHeight):/^(ne)$/.test(a)?(that.size.width=newWidth,that.size.height=newHeight,that.position.top=op.top-oy):/^(sw)$/.test(a)?(that.size.width=newWidth,that.size.height=newHeight,that.position.left=op.left-ox):(newHeight-gridY>0?(that.size.height=newHeight,that.position.top=op.top-oy):(that.size.height=gridY,that.position.top=op.top+os.height-gridY),newWidth-gridX>0?(that.size.width=newWidth,that.position.left=op.left-ox):(that.size.width=gridX,that.position.left=op.left+os.width-gridX))}}),$.ui.resizable}),function(factory){"function"==typeof define&&define.amd?define(["jquery","./core","./mouse","./widget"],factory):factory(jQuery)}(function($){return $.widget("ui.selectable",$.ui.mouse,{version:"@VERSION",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var selectees,that=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){selectees=$(that.options.filter,that.element[0]),selectees.addClass("ui-selectee"),selectees.each(function(){var $this=$(this),pos=$this.offset();$.data(this,"selectable-item",{element:this,$element:$this,left:pos.left,top:pos.top,right:pos.left+$this.outerWidth(),bottom:pos.top+$this.outerHeight(),startselected:!1,selected:$this.hasClass("ui-selected"),selecting:$this.hasClass("ui-selecting"),unselecting:$this.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=selectees.addClass("ui-selectee"),this._mouseInit(),this.helper=$("
")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(event){var that=this,options=this.options;this.opos=[event.pageX,event.pageY],this.options.disabled||(this.selectees=$(options.filter,this.element[0]),this._trigger("start",event),$(options.appendTo).append(this.helper),this.helper.css({left:event.pageX,top:event.pageY,width:0,height:0}),options.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var selectee=$.data(this,"selectable-item");selectee.startselected=!0,event.metaKey||event.ctrlKey||(selectee.$element.removeClass("ui-selected"),selectee.selected=!1,selectee.$element.addClass("ui-unselecting"),selectee.unselecting=!0,that._trigger("unselecting",event,{unselecting:selectee.element}))}),$(event.target).parents().addBack().each(function(){var doSelect,selectee=$.data(this,"selectable-item");return selectee?(doSelect=!event.metaKey&&!event.ctrlKey||!selectee.$element.hasClass("ui-selected"),selectee.$element.removeClass(doSelect?"ui-unselecting":"ui-selected").addClass(doSelect?"ui-selecting":"ui-unselecting"),selectee.unselecting=!doSelect,selectee.selecting=doSelect,selectee.selected=doSelect,doSelect?that._trigger("selecting",event,{selecting:selectee.element}):that._trigger("unselecting",event,{unselecting:selectee.element}),!1):void 0}))},_mouseDrag:function(event){if(this.dragged=!0,!this.options.disabled){var tmp,that=this,options=this.options,x1=this.opos[0],y1=this.opos[1],x2=event.pageX,y2=event.pageY;return x1>x2&&(tmp=x2,x2=x1,x1=tmp),y1>y2&&(tmp=y2,y2=y1,y1=tmp),this.helper.css({left:x1,top:y1,width:x2-x1,height:y2-y1}),this.selectees.each(function(){var selectee=$.data(this,"selectable-item"),hit=!1;selectee&&selectee.element!==that.element[0]&&("touch"===options.tolerance?hit=!(selectee.left>x2||selectee.righty2||selectee.bottomx1&&selectee.righty1&&selectee.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(x,reference,size){return x>=reference&&reference+size>x},_isFloating:function(item){return/left|right/.test(item.css("float"))||/inline|table-cell/.test(item.css("display"))},_create:function(){var o=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===o.axis||this._isFloating(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(key,value){this._super(key,value),"handle"===key&&this._setHandleClassName()},_setHandleClassName:function(){this.element.find(".ui-sortable-handle").removeClass("ui-sortable-handle"),$.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").find(".ui-sortable-handle").removeClass("ui-sortable-handle"),this._mouseDestroy();for(var i=this.items.length-1;i>=0;i--)this.items[i].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(event,overrideHandle){var currentItem=null,validHandle=!1,that=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(event),$(event.target).parents().each(function(){return $.data(this,that.widgetName+"-item")===that?(currentItem=$(this),!1):void 0}),$.data(event.target,that.widgetName+"-item")===that&&(currentItem=$(event.target)),currentItem&&(!this.options.handle||overrideHandle||($(this.options.handle,currentItem).find("*").addBack().each(function(){this===event.target&&(validHandle=!0) -}),validHandle))?(this.currentItem=currentItem,this._removeCurrentsFromItems(),!0):!1)},_mouseStart:function(event,overrideHandle,noActivation){var i,body,o=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(event),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},$.extend(this.offset,{click:{left:event.pageX-this.offset.left,top:event.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(event),this.originalPageX=event.pageX,this.originalPageY=event.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(body=this.document.find("body"),this.storedCursor=body.css("cursor"),body.css("cursor",o.cursor),this.storedStylesheet=$("").appendTo(body)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",event,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!noActivation)for(i=this.containers.length-1;i>=0;i--)this.containers[i]._trigger("activate",event,this._uiHash(this));return $.ui.ddmanager&&($.ui.ddmanager.current=this),$.ui.ddmanager&&!o.dropBehaviour&&$.ui.ddmanager.prepareOffsets(this,event),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(event),!0},_mouseDrag:function(event){var i,item,itemElement,intersection,o=this.options,scrolled=!1;for(this.position=this._generatePosition(event),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-event.pageY=0;i--)if(item=this.items[i],itemElement=item.item[0],intersection=this._intersectsWithPointer(item),!item.item.data("dragMultipleActive")&&intersection&&item.instance===this.currentContainer&&itemElement!==this.currentItem[0]&&this.placeholder[1===intersection?"next":"prev"]()[0]!==itemElement&&!$.contains(this.placeholder[0],itemElement)&&("semi-dynamic"===this.options.type?!$.contains(this.element[0],itemElement):!0)){if(this.direction=1===intersection?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(item))break;this._rearrange(event,item),this._trigger("change",event,this._uiHash());break}return this._contactContainers(event),$.ui.ddmanager&&$.ui.ddmanager.drag(this,event),this._trigger("sort",event,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(event,noPropagation){if(event){if($.ui.ddmanager&&!this.options.dropBehaviour&&$.ui.ddmanager.drop(this,event),this.options.revert){var that=this,cur=this.placeholder.offset(),axis=this.options.axis,animation={};axis&&"x"!==axis||(animation.left=cur.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),axis&&"y"!==axis||(animation.top=cur.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,$(this.helper).animate(animation,parseInt(this.options.revert,10)||500,function(){that._clear(event)})}else this._clear(event,noPropagation);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var i=this.containers.length-1;i>=0;i--)this.containers[i]._trigger("deactivate",null,this._uiHash(this)),this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",null,this._uiHash(this)),this.containers[i].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),$.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?$(this.domPosition.prev).after(this.currentItem):$(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(o){var items=this._getItemsAsjQuery(o&&o.connected),str=[];return o=o||{},$(items).each(function(){var res=($(o.item||this).attr(o.attribute||"id")||"").match(o.expression||/(.+)[\-=_](.+)/);res&&str.push((o.key||res[1]+"[]")+"="+(o.key&&o.expression?res[1]:res[2]))}),!str.length&&o.key&&str.push(o.key+"="),str.join("&")},toArray:function(o){var items=this._getItemsAsjQuery(o&&o.connected),ret=[];return o=o||{},items.each(function(){ret.push($(o.item||this).attr(o.attribute||"id")||"")}),ret},_intersectsWith:function(item){var x1=this.positionAbs.left,x2=x1+this.helperProportions.width,y1=this.positionAbs.top,y2=y1+this.helperProportions.height,l=item.left,r=l+item.width,t=item.top,b=t+item.height,dyClick=this.offset.click.top,dxClick=this.offset.click.left,isOverElementHeight="x"===this.options.axis||y1+dyClick>t&&b>y1+dyClick,isOverElementWidth="y"===this.options.axis||x1+dxClick>l&&r>x1+dxClick,isOverElement=isOverElementHeight&&isOverElementWidth;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>item[this.floating?"width":"height"]?isOverElement:l0?"down":"up")},_getDragHorizontalDirection:function(){var delta=this.positionAbs.left-this.lastPositionAbs.left;return 0!==delta&&(delta>0?"right":"left")},refresh:function(event){return this._refreshItems(event),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var options=this.options;return options.connectWith.constructor===String?[options.connectWith]:options.connectWith},_getItemsAsjQuery:function(connected){function addItems(){items.push(this)}var i,j,cur,inst,items=[],queries=[],connectWith=this._connectWith();if(connectWith&&connected)for(i=connectWith.length-1;i>=0;i--)for(cur=$(connectWith[i]),j=cur.length-1;j>=0;j--)inst=$.data(cur[j],this.widgetFullName),inst&&inst!==this&&!inst.options.disabled&&queries.push([$.isFunction(inst.options.items)?inst.options.items.call(inst.element):$(inst.options.items,inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),inst]);for(queries.push([$.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):$(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),i=queries.length-1;i>=0;i--)queries[i][0].each(addItems);return $(items)},_removeCurrentsFromItems:function(){var list=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=$.grep(this.items,function(item){for(var j=0;j=0;i--)for(cur=$(connectWith[i]),j=cur.length-1;j>=0;j--)inst=$.data(cur[j],this.widgetFullName),inst&&inst!==this&&!inst.options.disabled&&(queries.push([$.isFunction(inst.options.items)?inst.options.items.call(inst.element[0],event,{item:this.currentItem}):$(inst.options.items,inst.element),inst]),this.containers.push(inst));for(i=queries.length-1;i>=0;i--)for(targetData=queries[i][1],_queries=queries[i][0],j=0,queriesLength=_queries.length;queriesLength>j;j++)item=$(_queries[j]),item.data(this.widgetName+"-item",targetData),items.push({item:item,instance:targetData,width:0,height:0,left:0,top:0})},refreshPositions:function(fast){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,item,t,p;for(i=this.items.length-1;i>=0;i--)item=this.items[i],$(item.item).data("dragMultipleActive")||item.instance!==this.currentContainer&&this.currentContainer&&item.item[0]!==this.currentItem[0]||(t=this.options.toleranceElement?$(this.options.toleranceElement,item.item):item.item,fast||(item.width=t.outerWidth(),item.height=t.outerHeight()),p=t.offset(),item.left=p.left,item.top=p.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)p=this.containers[i].element.offset(),this.containers[i].containerCache.left=p.left,this.containers[i].containerCache.top=p.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(that){that=that||this;var className,o=that.options;o.placeholder&&o.placeholder.constructor!==String||(className=o.placeholder,o.placeholder={element:function(){var nodeName=that.currentItem[0].nodeName.toLowerCase(),element=$("<"+nodeName+">",that.document[0]).addClass(className||that.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===nodeName?that.currentItem.children().each(function(){$(" ",that.document[0]).attr("colspan",$(this).attr("colspan")||1).appendTo(element)}):"img"===nodeName&&element.attr("src",that.currentItem.attr("src")),className||element.css("visibility","hidden"),element},update:function(container,p){(!className||o.forcePlaceholderSize)&&(p.height()||p.height(that.currentItem.innerHeight()-parseInt(that.currentItem.css("paddingTop")||0,10)-parseInt(that.currentItem.css("paddingBottom")||0,10)),p.width()||p.width(that.currentItem.innerWidth()-parseInt(that.currentItem.css("paddingLeft")||0,10)-parseInt(that.currentItem.css("paddingRight")||0,10)))}}),that.placeholder=$(o.placeholder.element.call(that.element,that.currentItem)),that.currentItem.after(that.placeholder),o.placeholder.update(that,that.placeholder)},_contactContainers:function(event){var i,j,dist,itemWithLeastDistance,posProperty,sizeProperty,cur,nearBottom,floating,axis,innermostContainer=null,innermostIndex=null;for(i=this.containers.length-1;i>=0;i--)if(!$.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(innermostContainer&&$.contains(this.containers[i].element[0],innermostContainer.element[0]))continue;innermostContainer=this.containers[i],innermostIndex=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",event,this._uiHash(this)),this.containers[i].containerCache.over=0);if(innermostContainer)if(1===this.containers.length)this.containers[innermostIndex].containerCache.over||(this.containers[innermostIndex]._trigger("over",event,this._uiHash(this)),this.containers[innermostIndex].containerCache.over=1);else{for(dist=1e4,itemWithLeastDistance=null,floating=innermostContainer.floating||this._isFloating(this.currentItem),posProperty=floating?"left":"top",sizeProperty=floating?"width":"height",axis=floating?"clientX":"clientY",j=this.items.length-1;j>=0;j--)$.contains(this.containers[innermostIndex].element[0],this.items[j].item[0])&&this.items[j].item[0]!==this.currentItem[0]&&(cur=this.items[j].item.offset()[posProperty],nearBottom=!1,event[axis]-cur>this.items[j][sizeProperty]/2&&(nearBottom=!0),Math.abs(event[axis]-cur)this.containment[2]&&(pageX=this.containment[2]+this.offset.click.left),event.pageY-this.offset.click.top>this.containment[3]&&(pageY=this.containment[3]+this.offset.click.top)),o.grid&&(top=this.originalPageY+Math.round((pageY-this.originalPageY)/o.grid[1])*o.grid[1],pageY=this.containment?top-this.offset.click.top>=this.containment[1]&&top-this.offset.click.top<=this.containment[3]?top:top-this.offset.click.top>=this.containment[1]?top-o.grid[1]:top+o.grid[1]:top,left=this.originalPageX+Math.round((pageX-this.originalPageX)/o.grid[0])*o.grid[0],pageX=this.containment?left-this.offset.click.left>=this.containment[0]&&left-this.offset.click.left<=this.containment[2]?left:left-this.offset.click.left>=this.containment[0]?left-o.grid[0]:left+o.grid[0]:left)),{top:pageY-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():scrollIsRootNode?0:scroll.scrollTop()),left:pageX-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():scrollIsRootNode?0:scroll.scrollLeft())}},_rearrange:function(event,i,a,hardRefresh){a?a[0].appendChild(this.placeholder[0]):i.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?i.item[0]:i.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var counter=this.counter;this._delay(function(){counter===this.counter&&this.refreshPositions(!hardRefresh)})},_clear:function(event,noPropagation){function delayEvent(type,instance,container){return function(event){container._trigger(type,event,instance._uiHash(instance))}}this.reverting=!1;var i,delayedTriggers=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)("auto"===this._storedCSS[i]||"static"===this._storedCSS[i])&&(this._storedCSS[i]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!noPropagation&&delayedTriggers.push(function(event){this._trigger("receive",event,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||noPropagation||delayedTriggers.push(function(event){this._trigger("update",event,this._uiHash())}),this!==this.currentContainer&&(noPropagation||(delayedTriggers.push(function(event){this._trigger("remove",event,this._uiHash())}),delayedTriggers.push(function(c){return function(event){c._trigger("receive",event,this._uiHash(this))}}.call(this,this.currentContainer)),delayedTriggers.push(function(c){return function(event){c._trigger("update",event,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;i>=0;i--)noPropagation||delayedTriggers.push(delayEvent("deactivate",this,this.containers[i])),this.containers[i].containerCache.over&&(delayedTriggers.push(delayEvent("out",this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!noPropagation){for(this._trigger("beforeStop",event,this._uiHash()),i=0;ivalue?0:type.max6*h?p+(q-p)*h*6:1>2*h?q:2>3*h?p+(q-p)*(2/3-h)*6:p}var colors,stepHooks="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",rplusequals=/^([\-+])=\s*(\d+\.?\d*)/,stringParsers=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(execResult){return[execResult[1],execResult[2],execResult[3],execResult[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(execResult){return[2.55*execResult[1],2.55*execResult[2],2.55*execResult[3],execResult[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(execResult){return[parseInt(execResult[1],16),parseInt(execResult[2],16),parseInt(execResult[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(execResult){return[parseInt(execResult[1]+execResult[1],16),parseInt(execResult[2]+execResult[2],16),parseInt(execResult[3]+execResult[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(execResult){return[execResult[1],execResult[2]/100,execResult[3]/100,execResult[4]]}}],color=jQuery.Color=function(color,green,blue,alpha){return new jQuery.Color.fn.parse(color,green,blue,alpha)},spaces={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},propTypes={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},support=color.support={},supportElem=jQuery("

")[0],each=jQuery.each;supportElem.style.cssText="background-color:rgba(1,1,1,.5)",support.rgba=supportElem.style.backgroundColor.indexOf("rgba")>-1,each(spaces,function(spaceName,space){space.cache="_"+spaceName,space.props.alpha={idx:3,type:"percent",def:1}}),color.fn=jQuery.extend(color.prototype,{parse:function(red,green,blue,alpha){if(red===undefined)return this._rgba=[null,null,null,null],this;(red.jquery||red.nodeType)&&(red=jQuery(red).css(green),green=undefined);var inst=this,type=jQuery.type(red),rgba=this._rgba=[];return green!==undefined&&(red=[red,green,blue,alpha],type="array"),"string"===type?this.parse(stringParse(red)||colors._default):"array"===type?(each(spaces.rgba.props,function(key,prop){rgba[prop.idx]=clamp(red[prop.idx],prop)}),this):"object"===type?(red instanceof color?each(spaces,function(spaceName,space){red[space.cache]&&(inst[space.cache]=red[space.cache].slice())}):each(spaces,function(spaceName,space){var cache=space.cache;each(space.props,function(key,prop){if(!inst[cache]&&space.to){if("alpha"===key||null==red[key])return;inst[cache]=space.to(inst._rgba)}inst[cache][prop.idx]=clamp(red[key],prop,!0)}),inst[cache]&&jQuery.inArray(null,inst[cache].slice(0,3))<0&&(inst[cache][3]=1,space.from&&(inst._rgba=space.from(inst[cache])))}),this):void 0},is:function(compare){var is=color(compare),same=!0,inst=this;return each(spaces,function(_,space){var localCache,isCache=is[space.cache];return isCache&&(localCache=inst[space.cache]||space.to&&space.to(inst._rgba)||[],each(space.props,function(_,prop){return null!=isCache[prop.idx]?same=isCache[prop.idx]===localCache[prop.idx]:void 0})),same}),same},_space:function(){var used=[],inst=this;return each(spaces,function(spaceName,space){inst[space.cache]&&used.push(spaceName)}),used.pop()},transition:function(other,distance){var end=color(other),spaceName=end._space(),space=spaces[spaceName],startColor=0===this.alpha()?color("transparent"):this,start=startColor[space.cache]||space.to(startColor._rgba),result=start.slice();return end=end[space.cache],each(space.props,function(key,prop){var index=prop.idx,startValue=start[index],endValue=end[index],type=propTypes[prop.type]||{};null!==endValue&&(null===startValue?result[index]=endValue:(type.mod&&(endValue-startValue>type.mod/2?startValue+=type.mod:startValue-endValue>type.mod/2&&(startValue-=type.mod)),result[index]=clamp((endValue-startValue)*distance+startValue,prop)))}),this[spaceName](result)},blend:function(opaque){if(1===this._rgba[3])return this;var rgb=this._rgba.slice(),a=rgb.pop(),blend=color(opaque)._rgba;return color(jQuery.map(rgb,function(v,i){return(1-a)*blend[i]+a*v}))},toRgbaString:function(){var prefix="rgba(",rgba=jQuery.map(this._rgba,function(v,i){return null==v?i>2?1:0:v});return 1===rgba[3]&&(rgba.pop(),prefix="rgb("),prefix+rgba.join()+")"},toHslaString:function(){var prefix="hsla(",hsla=jQuery.map(this.hsla(),function(v,i){return null==v&&(v=i>2?1:0),i&&3>i&&(v=Math.round(100*v)+"%"),v});return 1===hsla[3]&&(hsla.pop(),prefix="hsl("),prefix+hsla.join()+")"},toHexString:function(includeAlpha){var rgba=this._rgba.slice(),alpha=rgba.pop();return includeAlpha&&rgba.push(~~(255*alpha)),"#"+jQuery.map(rgba,function(v){return v=(v||0).toString(16),1===v.length?"0"+v:v}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),color.fn.parse.prototype=color.fn,spaces.hsla.to=function(rgba){if(null==rgba[0]||null==rgba[1]||null==rgba[2])return[null,null,null,rgba[3]];var h,s,r=rgba[0]/255,g=rgba[1]/255,b=rgba[2]/255,a=rgba[3],max=Math.max(r,g,b),min=Math.min(r,g,b),diff=max-min,add=max+min,l=.5*add;return h=min===max?0:r===max?60*(g-b)/diff+360:g===max?60*(b-r)/diff+120:60*(r-g)/diff+240,s=0===diff?0:.5>=l?diff/add:diff/(2-add),[Math.round(h)%360,s,l,null==a?1:a] -},spaces.hsla.from=function(hsla){if(null==hsla[0]||null==hsla[1]||null==hsla[2])return[null,null,null,hsla[3]];var h=hsla[0]/360,s=hsla[1],l=hsla[2],a=hsla[3],q=.5>=l?l*(1+s):l+s-l*s,p=2*l-q;return[Math.round(255*hue2rgb(p,q,h+1/3)),Math.round(255*hue2rgb(p,q,h)),Math.round(255*hue2rgb(p,q,h-1/3)),a]},each(spaces,function(spaceName,space){var props=space.props,cache=space.cache,to=space.to,from=space.from;color.fn[spaceName]=function(value){if(to&&!this[cache]&&(this[cache]=to(this._rgba)),value===undefined)return this[cache].slice();var ret,type=jQuery.type(value),arr="array"===type||"object"===type?value:arguments,local=this[cache].slice();return each(props,function(key,prop){var val=arr["object"===type?key:prop.idx];null==val&&(val=local[prop.idx]),local[prop.idx]=clamp(val,prop)}),from?(ret=color(from(local)),ret[cache]=local,ret):color(local)},each(props,function(key,prop){color.fn[key]||(color.fn[key]=function(value){var match,vtype=jQuery.type(value),fn="alpha"===key?this._hsla?"hsla":"rgba":spaceName,local=this[fn](),cur=local[prop.idx];return"undefined"===vtype?cur:("function"===vtype&&(value=value.call(this,cur),vtype=jQuery.type(value)),null==value&&prop.empty?this:("string"===vtype&&(match=rplusequals.exec(value),match&&(value=cur+parseFloat(match[2])*("+"===match[1]?1:-1))),local[prop.idx]=value,this[fn](local)))})})}),color.hook=function(hook){var hooks=hook.split(" ");each(hooks,function(i,hook){jQuery.cssHooks[hook]={set:function(elem,value){var parsed,curElem,backgroundColor="";if("transparent"!==value&&("string"!==jQuery.type(value)||(parsed=stringParse(value)))){if(value=color(parsed||value),!support.rgba&&1!==value._rgba[3]){for(curElem="backgroundColor"===hook?elem.parentNode:elem;(""===backgroundColor||"transparent"===backgroundColor)&&curElem&&curElem.style;)try{backgroundColor=jQuery.css(curElem,"backgroundColor"),curElem=curElem.parentNode}catch(e){}value=value.blend(backgroundColor&&"transparent"!==backgroundColor?backgroundColor:"_default")}value=value.toRgbaString()}try{elem.style[hook]=value}catch(e){}}},jQuery.fx.step[hook]=function(fx){fx.colorInit||(fx.start=color(fx.elem,hook),fx.end=color(fx.end),fx.colorInit=!0),jQuery.cssHooks[hook].set(fx.elem,fx.start.transition(fx.end,fx.pos))}})},color.hook(stepHooks),jQuery.cssHooks.borderColor={expand:function(value){var expanded={};return each(["Top","Right","Bottom","Left"],function(i,part){expanded["border"+part+"Color"]=value}),expanded}},colors=jQuery.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function getElementStyles(elem){var key,len,style=elem.ownerDocument.defaultView?elem.ownerDocument.defaultView.getComputedStyle(elem,null):elem.currentStyle,styles={};if(style&&style.length&&style[0]&&style[style[0]])for(len=style.length;len--;)key=style[len],"string"==typeof style[key]&&(styles[$.camelCase(key)]=style[key]);else for(key in style)"string"==typeof style[key]&&(styles[key]=style[key]);return styles}function styleDifference(oldStyle,newStyle){var name,value,diff={};for(name in newStyle)value=newStyle[name],oldStyle[name]!==value&&(shorthandStyles[name]||($.fx.step[name]||!isNaN(parseFloat(value)))&&(diff[name]=value));return diff}var classAnimationActions=["add","remove","toggle"],shorthandStyles={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};$.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(_,prop){$.fx.step[prop]=function(fx){("none"!==fx.end&&!fx.setAttr||1===fx.pos&&!fx.setAttr)&&(jQuery.style(fx.elem,prop,fx.end),fx.setAttr=!0)}}),$.fn.addBack||($.fn.addBack=function(selector){return this.add(null==selector?this.prevObject:this.prevObject.filter(selector))}),$.effects.animateClass=function(value,duration,easing,callback){var o=$.speed(duration,easing,callback);return this.queue(function(){var applyClassChange,animated=$(this),baseClass=animated.attr("class")||"",allAnimations=o.children?animated.find("*").addBack():animated;allAnimations=allAnimations.map(function(){var el=$(this);return{el:el,start:getElementStyles(this)}}),applyClassChange=function(){$.each(classAnimationActions,function(i,action){value[action]&&animated[action+"Class"](value[action])})},applyClassChange(),allAnimations=allAnimations.map(function(){return this.end=getElementStyles(this.el[0]),this.diff=styleDifference(this.start,this.end),this}),animated.attr("class",baseClass),allAnimations=allAnimations.map(function(){var styleInfo=this,dfd=$.Deferred(),opts=$.extend({},o,{queue:!1,complete:function(){dfd.resolve(styleInfo)}});return this.el.animate(this.diff,opts),dfd.promise()}),$.when.apply($,allAnimations.get()).done(function(){applyClassChange(),$.each(arguments,function(){var el=this.el;$.each(this.diff,function(key){el.css(key,"")})}),o.complete.call(animated[0])})})},$.fn.extend({addClass:function(orig){return function(classNames,speed,easing,callback){return speed?$.effects.animateClass.call(this,{add:classNames},speed,easing,callback):orig.apply(this,arguments)}}($.fn.addClass),removeClass:function(orig){return function(classNames,speed,easing,callback){return arguments.length>1?$.effects.animateClass.call(this,{remove:classNames},speed,easing,callback):orig.apply(this,arguments)}}($.fn.removeClass),toggleClass:function(orig){return function(classNames,force,speed,easing,callback){return"boolean"==typeof force||void 0===force?speed?$.effects.animateClass.call(this,force?{add:classNames}:{remove:classNames},speed,easing,callback):orig.apply(this,arguments):$.effects.animateClass.call(this,{toggle:classNames},force,speed,easing)}}($.fn.toggleClass),switchClass:function(remove,add,speed,easing,callback){return $.effects.animateClass.call(this,{add:add,remove:remove},speed,easing,callback)}})}(),function(){function _normalizeArguments(effect,options,speed,callback){return $.isPlainObject(effect)&&(options=effect,effect=effect.effect),effect={effect:effect},null==options&&(options={}),$.isFunction(options)&&(callback=options,speed=null,options={}),("number"==typeof options||$.fx.speeds[options])&&(callback=speed,speed=options,options={}),$.isFunction(speed)&&(callback=speed,speed=null),options&&$.extend(effect,options),speed=speed||options.duration,effect.duration=$.fx.off?0:"number"==typeof speed?speed:speed in $.fx.speeds?$.fx.speeds[speed]:$.fx.speeds._default,effect.complete=callback||options.complete,effect}function standardAnimationOption(option){return!option||"number"==typeof option||$.fx.speeds[option]?!0:"string"!=typeof option||$.effects.effect[option]?$.isFunction(option)?!0:"object"!=typeof option||option.effect?!1:!0:!0}$.extend($.effects,{version:"@VERSION",save:function(element,set){for(var i=0;i

").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),size={width:element.width(),height:element.height()},active=document.activeElement;try{active.id}catch(e){active=document.body}return element.wrap(wrapper),(element[0]===active||$.contains(element[0],active))&&$(active).focus(),wrapper=element.parent(),"static"===element.css("position")?(wrapper.css({position:"relative"}),element.css({position:"relative"})):($.extend(props,{position:element.css("position"),zIndex:element.css("z-index")}),$.each(["top","left","bottom","right"],function(i,pos){props[pos]=element.css(pos),isNaN(parseInt(props[pos],10))&&(props[pos]="auto")}),element.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),element.css(size),wrapper.css(props).show()},removeWrapper:function(element){var active=document.activeElement;return element.parent().is(".ui-effects-wrapper")&&(element.parent().replaceWith(element),(element[0]===active||$.contains(element[0],active))&&$(active).focus()),element},setTransition:function(element,list,factor,value){return value=value||{},$.each(list,function(i,x){var unit=element.cssUnit(x);unit[0]>0&&(value[x]=unit[0]*factor+unit[1])}),value}}),$.fn.extend({effect:function(){function run(next){function done(){$.isFunction(complete)&&complete.call(elem[0]),$.isFunction(next)&&next()}var elem=$(this),complete=args.complete,mode=args.mode;(elem.is(":hidden")?"hide"===mode:"show"===mode)?(elem[mode](),done()):effectMethod.call(elem[0],args,done)}var args=_normalizeArguments.apply(this,arguments),mode=args.mode,queue=args.queue,effectMethod=$.effects.effect[args.effect];return $.fx.off||!effectMethod?mode?this[mode](args.duration,args.complete):this.each(function(){args.complete&&args.complete.call(this)}):queue===!1?this.each(run):this.queue(queue||"fx",run)},show:function(orig){return function(option){if(standardAnimationOption(option))return orig.apply(this,arguments);var args=_normalizeArguments.apply(this,arguments);return args.mode="show",this.effect.call(this,args)}}($.fn.show),hide:function(orig){return function(option){if(standardAnimationOption(option))return orig.apply(this,arguments);var args=_normalizeArguments.apply(this,arguments);return args.mode="hide",this.effect.call(this,args)}}($.fn.hide),toggle:function(orig){return function(option){if(standardAnimationOption(option)||"boolean"==typeof option)return orig.apply(this,arguments);var args=_normalizeArguments.apply(this,arguments);return args.mode="toggle",this.effect.call(this,args)}}($.fn.toggle),cssUnit:function(key){var style=this.css(key),val=[];return $.each(["em","px","%","pt"],function(i,unit){style.indexOf(unit)>0&&(val=[parseFloat(style),unit])}),val}})}(),function(){var baseEasings={};$.each(["Quad","Cubic","Quart","Quint","Expo"],function(i,name){baseEasings[name]=function(p){return Math.pow(p,i+2)}}),$.extend(baseEasings,{Sine:function(p){return 1-Math.cos(p*Math.PI/2)},Circ:function(p){return 1-Math.sqrt(1-p*p)},Elastic:function(p){return 0===p||1===p?p:-Math.pow(2,8*(p-1))*Math.sin((80*(p-1)-7.5)*Math.PI/15)},Back:function(p){return p*p*(3*p-2)},Bounce:function(p){for(var pow2,bounce=4;p<((pow2=Math.pow(2,--bounce))-1)/11;);return 1/Math.pow(4,3-bounce)-7.5625*Math.pow((3*pow2-2)/22-p,2)}}),$.each(baseEasings,function(name,easeIn){$.easing["easeIn"+name]=easeIn,$.easing["easeOut"+name]=function(p){return 1-easeIn(1-p)},$.easing["easeInOut"+name]=function(p){return.5>p?easeIn(2*p)/2:1-easeIn(-2*p+2)/2}})}(),$.effects}),function(factory){"function"==typeof define&&define.amd?define(["jquery","./core","./widget"],factory):factory(jQuery)}(function($){return $.widget("ui.accordion",{version:"@VERSION",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var options=this.options;this.prevShow=this.prevHide=$(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),options.collapsible||options.active!==!1&&null!=options.active||(options.active=0),this._processPanels(),options.active<0&&(options.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():$()}},_createIcons:function(){var icons=this.options.icons;icons&&($("").addClass("ui-accordion-header-icon ui-icon "+icons.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(icons.header).addClass(icons.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var contents;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").removeUniqueId(),this._destroyIcons(),contents=this.headers.next().removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&contents.css("height","")},_setOption:function(key,value){return"active"===key?void this._activate(value):("event"===key&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(value)),this._super(key,value),"collapsible"!==key||value||this.options.active!==!1||this._activate(0),"icons"===key&&(this._destroyIcons(),value&&this._createIcons()),void("disabled"===key&&(this.element.toggleClass("ui-state-disabled",!!value).attr("aria-disabled",value),this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!value))))},_keydown:function(event){if(!event.altKey&&!event.ctrlKey){var keyCode=$.ui.keyCode,length=this.headers.length,currentIndex=this.headers.index(event.target),toFocus=!1;switch(event.keyCode){case keyCode.RIGHT:case keyCode.DOWN:toFocus=this.headers[(currentIndex+1)%length];break;case keyCode.LEFT:case keyCode.UP:toFocus=this.headers[(currentIndex-1+length)%length];break;case keyCode.SPACE:case keyCode.ENTER:this._eventHandler(event);break;case keyCode.HOME:toFocus=this.headers[0];break;case keyCode.END:toFocus=this.headers[length-1]}toFocus&&($(event.target).attr("tabIndex",-1),$(toFocus).attr("tabIndex",0),toFocus.focus(),event.preventDefault())}},_panelKeyDown:function(event){event.keyCode===$.ui.keyCode.UP&&event.ctrlKey&&$(event.currentTarget).prev().focus()},refresh:function(){var options=this.options;this._processPanels(),options.active===!1&&options.collapsible===!0||!this.headers.length?(options.active=!1,this.active=$()):options.active===!1?this._activate(0):this.active.length&&!$.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(options.active=!1,this.active=$()):this._activate(Math.max(0,options.active-1)):options.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var maxHeight,options=this.options,heightStyle=options.heightStyle,parent=this.element.parent();this.active=this._findActive(options.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(){var header=$(this),headerId=header.uniqueId().attr("id"),panel=header.next(),panelId=panel.uniqueId().attr("id");header.attr("aria-controls",panelId),panel.attr("aria-labelledby",headerId)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(options.event),"fill"===heightStyle?(maxHeight=parent.height(),this.element.siblings(":visible").each(function(){var elem=$(this),position=elem.css("position");"absolute"!==position&&"fixed"!==position&&(maxHeight-=elem.outerHeight(!0))}),this.headers.each(function(){maxHeight-=$(this).outerHeight(!0)}),this.headers.next().each(function(){$(this).height(Math.max(0,maxHeight-$(this).innerHeight()+$(this).height()))}).css("overflow","auto")):"auto"===heightStyle&&(maxHeight=0,this.headers.next().each(function(){maxHeight=Math.max(maxHeight,$(this).css("height","").height())}).height(maxHeight))},_activate:function(index){var active=this._findActive(index)[0];active!==this.active[0]&&(active=active||this.active[0],this._eventHandler({target:active,currentTarget:active,preventDefault:$.noop}))},_findActive:function(selector){return"number"==typeof selector?this.headers.eq(selector):$()},_setupEvents:function(event){var events={keydown:"_keydown"};event&&$.each(event.split(" "),function(index,eventName){events[eventName]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,events),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(event){var options=this.options,active=this.active,clicked=$(event.currentTarget),clickedIsActive=clicked[0]===active[0],collapsing=clickedIsActive&&options.collapsible,toShow=collapsing?$():clicked.next(),toHide=active.next(),eventData={oldHeader:active,oldPanel:toHide,newHeader:collapsing?$():clicked,newPanel:toShow};event.preventDefault(),clickedIsActive&&!options.collapsible||this._trigger("beforeActivate",event,eventData)===!1||(options.active=collapsing?!1:this.headers.index(clicked),this.active=clickedIsActive?$():clicked,this._toggle(eventData),active.removeClass("ui-accordion-header-active ui-state-active"),options.icons&&active.children(".ui-accordion-header-icon").removeClass(options.icons.activeHeader).addClass(options.icons.header),clickedIsActive||(clicked.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),options.icons&&clicked.children(".ui-accordion-header-icon").removeClass(options.icons.header).addClass(options.icons.activeHeader),clicked.next().addClass("ui-accordion-content-active")))},_toggle:function(data){var toShow=data.newPanel,toHide=this.prevShow.length?this.prevShow:data.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=toShow,this.prevHide=toHide,this.options.animate?this._animate(toShow,toHide,data):(toHide.hide(),toShow.show(),this._toggleComplete(data)),toHide.attr({"aria-hidden":"true"}),toHide.prev().attr("aria-selected","false"),toShow.length&&toHide.length?toHide.prev().attr({tabIndex:-1,"aria-expanded":"false"}):toShow.length&&this.headers.filter(function(){return 0===$(this).attr("tabIndex")}).attr("tabIndex",-1),toShow.attr("aria-hidden","false").prev().attr({"aria-selected":"true",tabIndex:0,"aria-expanded":"true"})},_animate:function(toShow,toHide,data){var total,easing,duration,that=this,adjust=0,down=toShow.length&&(!toHide.length||toShow.index()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var suppressKeyPress,suppressKeyPressRepeat,suppressInput,nodeName=this.element[0].nodeName.toLowerCase(),isTextarea="textarea"===nodeName,isInput="input"===nodeName;this.isMultiLine=isTextarea?!0:isInput?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[isTextarea||isInput?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(event){if(this.element.prop("readOnly"))return suppressKeyPress=!0,suppressInput=!0,void(suppressKeyPressRepeat=!0);suppressKeyPress=!1,suppressInput=!1,suppressKeyPressRepeat=!1;var keyCode=$.ui.keyCode;switch(event.keyCode){case keyCode.PAGE_UP:suppressKeyPress=!0,this._move("previousPage",event);break;case keyCode.PAGE_DOWN:suppressKeyPress=!0,this._move("nextPage",event);break;case keyCode.UP:suppressKeyPress=!0,this._keyEvent("previous",event);break;case keyCode.DOWN:suppressKeyPress=!0,this._keyEvent("next",event);break;case keyCode.ENTER:this.menu.active&&(suppressKeyPress=!0,event.preventDefault(),this.menu.select(event));break;case keyCode.TAB:this.menu.active&&this.menu.select(event);break;case keyCode.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(event),event.preventDefault());break;default:suppressKeyPressRepeat=!0,this._searchTimeout(event)}},keypress:function(event){if(suppressKeyPress)return suppressKeyPress=!1,void((!this.isMultiLine||this.menu.element.is(":visible"))&&event.preventDefault());if(!suppressKeyPressRepeat){var keyCode=$.ui.keyCode;switch(event.keyCode){case keyCode.PAGE_UP:this._move("previousPage",event);break;case keyCode.PAGE_DOWN:this._move("nextPage",event);break;case keyCode.UP:this._keyEvent("previous",event);break;case keyCode.DOWN:this._keyEvent("next",event)}}},input:function(event){return suppressInput?(suppressInput=!1,void event.preventDefault()):void this._searchTimeout(event)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(event){return this.cancelBlur?void delete this.cancelBlur:(clearTimeout(this.searching),this.close(event),void this._change(event))}}),this._initSource(),this.menu=$("